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

taosdata / TDengine / #4999

22 Mar 2026 10:21AM UTC coverage: 72.31% (-0.03%) from 72.335%
#4999

push

travis-ci

web-flow
feat(subq/some): some/any/exists for stream subq (#34860)

50 of 68 new or added lines in 1 file covered. (73.53%)

701 existing lines in 132 files now uncovered.

253472 of 350536 relevant lines covered (72.31%)

131775367.32 hits per line

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

83.78
/source/libs/command/src/explain.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
// clang-format off
17
#include "commandInt.h"
18
#include "plannodes.h"
19
#include "query.h"
20
#include "taoserror.h"
21
#include "tcommon.h"
22
#include "tdatablock.h"
23
#include "systable.h"
24
#include "functionMgt.h"
25
#include "tmsg.h"
26
#include "ttime.h"
27
#include "tutil.h"
28

29
char *gJoinTypeStr[JOIN_TYPE_MAX_VALUE][JOIN_STYPE_MAX_VALUE] = {
30
           /* NONE                OUTER                  SEMI                  ANTI                   ASOF                   WINDOW */
31
/*INNER*/  {"Inner Join",         NULL,                  NULL,                 NULL,                  NULL,                  NULL},
32
/*LEFT*/   {"Left Join",          "Left Join",           "Left Semi Join",     "Left Anti Join",      "Left ASOF Join",      "Left Window Join"},
33
/*RIGHT*/  {"Right Join",         "Right Join",          "Right Semi Join",    "Right Anti Join",     "Right ASOF Join",     "Right Window Join"},
34
/*FULL*/   {"Full Join",          "Full Join",           NULL,                 NULL,                  NULL,                  NULL},
35
};
36

37
static int32_t qExplainGenerateResNode(SSubplan *plan, SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pResNode);
38
static int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t *level, bool singleChannel);
39
static int32_t qExplainAppendGroupResRowsByVgIds(void *pCtx, int32_t groupId, int32_t *level,
40
                                                 bool grpSingleChannel, const SArray* pVgIds);
41

42
/*
43
 * Convert dynamic-query control type to a printable explain label.
44
 *
45
 * @param pDyn Dynamic-query control physical node, can be NULL.
46
 *
47
 * @return Static string for explain output, or "unknown task" when type is unknown.
48
 */
49
char* qExplainGetDynQryCtrlType(const SDynQueryCtrlPhysiNode* pDyn) {
1,137,589✔
50
  if (NULL == pDyn) {
1,137,589✔
51
    return "unknown task";
×
52
  }
53

54
  switch (pDyn->qType) {
1,137,589✔
55
    case DYN_QTYPE_STB_HASH:
733,973✔
56
      return "STable Join";
733,973✔
57
    case DYN_QTYPE_VTB_SCAN:
112,611✔
58
      return "Virtual Stable Scan";
112,611✔
59
    case DYN_QTYPE_VTB_WINDOW:
65,368✔
60
      return "Virtual Table Window";
65,368✔
61
    case DYN_QTYPE_VTB_INTERVAL:
3,816✔
62
      return "Virtual Stable Interval";
3,816✔
63
    case DYN_QTYPE_VTB_AGG:
204,013✔
64
      return "Virtual Stable Agg";
204,013✔
65
    case DYN_QTYPE_VTB_TS_SCAN:
17,808✔
66
      return "Virtual Stable Ts Scan";
17,808✔
67
    default:
×
68
      break;
×
69
  }
70

71
  return "unknown task";
×
72
}
73

74
char* qExplainGetAsofOpStr(int32_t opType) {
43,568✔
75
  switch (opType) {
43,568✔
76
    case OP_TYPE_GREATER_THAN:
1,556✔
77
      return ">";
1,556✔
78
    case OP_TYPE_GREATER_EQUAL:
7,002✔
79
      return ">=";
7,002✔
80
    case OP_TYPE_LOWER_THAN:
×
81
      return "<";
×
82
    case OP_TYPE_LOWER_EQUAL:
7,002✔
83
      return "<=";
7,002✔
84
    case OP_TYPE_EQUAL:
28,008✔
85
      return "=";
28,008✔
86
    default:
×
87
      return "UNKNOWN";
×
88
  }
89
}
90

91
char* qExplainGetTimerangeTargetStr(int32_t target) {
×
92
  static char* targetName[] = {"", "Left", "Right", "Left/Right"};
93
  if (target <= 0 || target > 3) {
×
94
    return "Unknown";
×
95
  }
96

97
  return targetName[target];
×
98
}
99

100
static bool qExplainRspMatchVgIds(const SExplainRsp* pRsp, const SArray* pVgIds) {
8,752,780✔
101
  if (NULL == pRsp || NULL == pVgIds || pRsp->numOfPlans <= 0 ||
8,752,780✔
102
      NULL == pRsp->subplanInfo) {
8,752,780✔
103
    return false;
×
104
  }
105

106
  int32_t vgCnt = (int32_t)taosArrayGetSize(pVgIds);
8,752,780✔
107
  for (int32_t subplanIdx = 0; subplanIdx < pRsp->numOfPlans; ++subplanIdx) {
14,300,968✔
108
    int32_t rspVgId = pRsp->subplanInfo[subplanIdx].vgId;
9,313,552✔
109
    for (int32_t vgIdx = 0; vgIdx < vgCnt; ++vgIdx) {
15,477,878✔
110
      const int32_t* pCurr = taosArrayGet(pVgIds, vgIdx);
9,929,690✔
111
      if (pCurr && *pCurr == rspVgId) {
9,929,690✔
112
        return true;
3,765,364✔
113
      }
114
    }
115
  }
116

117
  return false;
4,987,416✔
118
}
119

120
void qExplainFreeResNode(SExplainResNode *resNode) {
347,223,336✔
121
  if (NULL == resNode) {
347,223,336✔
122
    return;
×
123
  }
124

125
  taosArrayDestroy(resNode->pExecInfo);
347,223,336✔
126

127
  SNode *node = NULL;
347,227,586✔
128
  FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
537,496,522✔
129
  nodesClearList(resNode->pChildren);
347,231,828✔
130

131
  taosMemoryFreeClear(resNode);
347,234,328✔
132
}
133

134
void qExplainFreePlanCtx(SExplainPlanCtx* pCtx, bool isAnalyze) {
147,603,658✔
135
  if (isAnalyze && pCtx->groupHash) {
147,603,658✔
136
    void *pIter = taosHashIterate(pCtx->groupHash, NULL);
59,610,758✔
137
    while (pIter) {
148,714,410✔
138
      SExplainGroup *group = (SExplainGroup *)pIter;
89,103,679✔
139
      if (group->nodeExecInfo) {
89,103,679✔
140
        int32_t num = taosArrayGetSize(group->nodeExecInfo);
64,158,936✔
141
        for (int32_t i = 0; i < num; ++i) {
137,747,108✔
142
          SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
73,587,932✔
143
          tFreeSExplainRsp(rsp);
73,587,932✔
144
        }
145
        taosArrayDestroy(group->nodeExecInfo);
64,159,176✔
146
      }
147

148
      pIter = taosHashIterate(pCtx->groupHash, pIter);
89,103,792✔
149
    }
150
  }
151

152
  taosHashCleanup(pCtx->groupHash);
147,603,631✔
153
}
147,607,969✔
154

155
void qExplainFreeCtx(SExplainCtx *pCtx) {
914,315,853✔
156
  if (NULL == pCtx) {
914,315,853✔
157
    return;
868,399,084✔
158
  }
159

160
  int32_t rowSize = taosArrayGetSize(pCtx->rows);
45,916,769✔
161
  for (int32_t i = 0; i < rowSize; ++i) {
777,828,828✔
162
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
731,909,412✔
163
    taosMemoryFreeClear(row->buf);
731,905,341✔
164
  }
165

166
  qExplainFreePlanCtx(&pCtx->planCtx, EXPLAIN_MODE_ANALYZE == pCtx->mode);
45,919,416✔
167
  if (pCtx->subPlanCtxs) {
45,927,436✔
168
    int32_t subNum = taosArrayGetSize(pCtx->subPlanCtxs);
33,880,621✔
169
    for (int32_t i = 0; i < subNum; ++i) {
135,562,017✔
170
      SExplainPlanCtx *pSub = taosArrayGet(pCtx->subPlanCtxs, i);
101,680,636✔
171
      qExplainFreePlanCtx(pSub, EXPLAIN_MODE_ANALYZE == pCtx->mode);
101,680,128✔
172
    }
173
    taosArrayDestroy(pCtx->subPlanCtxs);
33,881,381✔
174
  }
175

176
  taosArrayDestroy(pCtx->rows);
45,928,269✔
177
  taosMemoryFreeClear(pCtx->tbuf);
45,928,532✔
178
  taosMemoryFree(pCtx);
45,928,453✔
179
}
180

181
static int32_t qExplainInitCtx(SExplainCtx **pCtx, bool verbose, double ratio, EExplainMode mode) {
45,911,118✔
182
  int32_t      code = 0;
45,911,118✔
183
  SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
45,911,118✔
184
  if (NULL == ctx) {
45,922,359✔
185
    qError("calloc SExplainCtx failed");
×
186
    QRY_ERR_JRET(terrno);
×
187
  }
188

189
  SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo));
45,922,359✔
190
  if (NULL == rows) {
45,922,149✔
191
    qError("taosArrayInit SQueryExplainRowInfo failed");
×
192
    QRY_ERR_JRET(terrno);
×
193
  }
194

195
  char *tbuf = taosMemoryMalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE);
45,922,149✔
196
  if (NULL == tbuf) {
45,926,914✔
197
    qError("malloc size %d failed", TSDB_EXPLAIN_RESULT_ROW_SIZE);
×
198
    QRY_ERR_JRET(terrno);
×
199
  }
200

201
  ctx->mode = mode;
45,926,914✔
202
  ctx->verbose = verbose;
45,926,914✔
203
  ctx->ratio = ratio;
45,926,914✔
204
  ctx->tbuf = tbuf;
45,926,914✔
205
  ctx->rows = rows;
45,926,914✔
206

207
  *pCtx = ctx;
45,926,914✔
208

209
  return TSDB_CODE_SUCCESS;
45,926,914✔
210

211
_return:
×
212

213
  taosArrayDestroy(rows);
×
214
  taosMemoryFree(ctx);
×
215

216
  QRY_RET(code);
×
217
}
218

219
static int32_t qExplainGenerateResChildren(SSubplan *plan, SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
347,238,307✔
220
  int32_t    tlen = 0;
347,238,307✔
221
  SNodeList *pPhysiChildren = pNode->pChildren;
347,238,307✔
222

223
  if (pPhysiChildren) {
347,238,307✔
224
    int32_t code = nodesMakeList(pChildren);
168,046,622✔
225
    if (NULL == *pChildren) {
168,050,667✔
226
      qError("nodesMakeList failed");
×
227
      QRY_ERR_RET(code);
9,200✔
228
    }
229
  }
230

231
  SNode           *node = NULL;
347,251,552✔
232
  SExplainResNode *pResNode = NULL;
347,251,552✔
233
  FOREACH(node, pPhysiChildren) {
537,528,563✔
234
    QRY_ERR_RET(qExplainGenerateResNode(plan, (SPhysiNode *)node, group, &pResNode));
190,273,404✔
235
    QRY_ERR_RET(nodesListAppend(*pChildren, (SNode *)pResNode));
190,270,479✔
236
  }
237

238
  return TSDB_CODE_SUCCESS;
347,255,159✔
239
}
240

241
static int32_t qExplainGenerateResNodeExecInfo(SPhysiNode *pNode, SArray **pExecInfo, SExplainGroup *group) {
6,312,883✔
242
  *pExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainExecInfo));
6,312,883✔
243
  if (NULL == (*pExecInfo)) {
6,312,883✔
244
    qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
245
    return terrno;
×
246
  }
247

248
  SExplainRsp *rsp = NULL;
6,312,883✔
249
  if (group->singleChannel) {
6,312,883✔
250
    if (0 == group->physiPlanExecIdx) {
×
251
      group->nodeIdx = 0;
×
252
    }
253

254
    rsp = taosArrayGet(group->nodeExecInfo, group->nodeIdx++);
×
255
    if (group->physiPlanExecIdx >= rsp->numOfPlans) {
×
256
      qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
×
257
      return TSDB_CODE_APP_ERROR;
×
258
    }
259

260
    if(taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx) == NULL) return terrno;
×
261
  } else {
262
    for (int32_t i = 0; i < group->nodeNum; ++i) {
13,069,246✔
263
      rsp = taosArrayGet(group->nodeExecInfo, i);
6,756,363✔
264
      if (group->physiPlanExecIdx >= rsp->numOfPlans) {
6,756,363✔
265
        qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
×
266
        return TSDB_CODE_APP_ERROR;
×
267
      }
268

269
      if(taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx) == NULL) return terrno;
13,512,726✔
270
    }
271
  }
272

273
  ++group->physiPlanExecIdx;
6,312,883✔
274

275
  return TSDB_CODE_SUCCESS;
6,312,883✔
276
}
277

278
static int32_t qExplainGenerateResNode(SSubplan *plan, SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pResNode) {
347,229,228✔
279
  if (NULL == pNode) {
347,229,228✔
280
    *pResNode = NULL;
×
281
    qError("physical node is NULL");
×
282
    return TSDB_CODE_APP_ERROR;
×
283
  }
284

285
  SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
347,229,228✔
286
  if (NULL == resNode) {
347,243,484✔
287
    qError("calloc SPhysiNodeExplainRes failed");
×
288
    return terrno;
×
289
  }
290

291
  int32_t code = 0;
347,243,484✔
292
  resNode->pNode = pNode;
347,243,484✔
293
  resNode->pPlan = plan;
347,243,484✔
294

295
  if (group->nodeExecInfo) {
347,243,484✔
296
    QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(pNode, &resNode->pExecInfo, group));
6,312,883✔
297
  }
298

299
  QRY_ERR_JRET(qExplainGenerateResChildren(plan, pNode, group, &resNode->pChildren));
347,243,484✔
300

301
  *pResNode = resNode;
347,239,202✔
302

303
  return TSDB_CODE_SUCCESS;
347,239,202✔
304

305
_return:
×
306

307
  qExplainFreeResNode(resNode);
×
308

309
  QRY_RET(code);
×
310
}
311

312
static int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf,
6,312,883✔
313
                                         int32_t *len, double* filterEfficiency) {
314
  int32_t          tlen = *len;
6,312,883✔
315
  size_t           nodeNum = taosArrayGetSize(pExecInfo);  // num of total nodes
6,312,883✔
316
  size_t           numNoData = 0;  // num of nodes with no data
6,312,883✔
317
  SExplainExecInfo execInfo = {0};
6,312,883✔
318
  SExplainExecInfo maxExecInfo = {0};
6,312,883✔
319

320
  for (int32_t i = 0; i < nodeNum; ++i) {
13,069,246✔
321
    const SExplainExecInfo *pExec = taosArrayGet(pExecInfo, i);
6,756,363✔
322
    execInfo.execFirstRow += pExec->execFirstRow;
6,756,363✔
323
    execInfo.execLastRow += pExec->execLastRow;
6,756,363✔
324
    execInfo.numOfRows += pExec->numOfRows;
6,756,363✔
325
    execInfo.inputRows += pExec->inputRows;
6,756,363✔
326

327
    maxExecInfo.execFirstRow = TMAX(maxExecInfo.execFirstRow, pExec->execFirstRow);
6,756,363✔
328
    maxExecInfo.execLastRow = TMAX(maxExecInfo.execLastRow, pExec->execLastRow);
6,756,363✔
329
    maxExecInfo.numOfRows = TMAX(maxExecInfo.numOfRows, pExec->numOfRows);
6,756,363✔
330
  }
331
  *filterEfficiency = execInfo.inputRows > 0 ?
6,326,419✔
332
                      (double)execInfo.numOfRows * 100.0 / (double)execInfo.inputRows : 100.0;
6,312,883✔
333

334
  if (nodeNum == 1 || numNoData == nodeNum) {
6,312,883✔
335
    EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execFirstRow),
5,896,331✔
336
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execLastRow), execInfo.numOfRows);
337
  } else if (nodeNum > 1) {
416,552✔
338
    EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT_EXT,
416,552✔
339
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execFirstRow) / nodeNum,
340
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execFirstRow),
341
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execLastRow) / nodeNum,
342
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execLastRow),
343
                       (double)execInfo.numOfRows / nodeNum,
344
                       maxExecInfo.numOfRows);
345
  }
346

347
  *len = tlen;
6,312,883✔
348
  return TSDB_CODE_SUCCESS;
6,312,883✔
349
}
350

351
static int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
731,912,244✔
352
  SQueryExplainRowInfo row = {0};
731,912,244✔
353
  row.buf = taosMemoryMalloc(len);
731,912,244✔
354
  if (NULL == row.buf) {
731,941,195✔
355
    qError("taosMemoryMalloc %d failed", len);
×
356
    QRY_ERR_RET(terrno);
×
357
  }
358

359
  memcpy(row.buf, tbuf, len);
731,941,195✔
360
  row.level = level;
731,941,195✔
361
  row.len = len;
731,941,195✔
362
  ctx->dataSize += row.len;
731,941,195✔
363

364
  if (NULL == taosArrayPush(ctx->rows, &row)) {
1,463,847,273✔
365
    qError("taosArrayPush row to explain res rows failed");
×
366
    taosMemoryFree(row.buf);
×
367
    QRY_ERR_RET(terrno);
×
368
  }
369

370
  return TSDB_CODE_SUCCESS;
731,904,637✔
371
}
372

373
static int32_t qExplainAppendFilterRow(SExplainCtx *ctx, int32_t level,
147,271,841✔
374
                                       SNode *pConditions, int32_t *pLen,
375
                                       const double *pFilterEfficiency) {
376
  if (NULL == pConditions) {
147,271,841✔
377
    return TSDB_CODE_SUCCESS;
139,455,271✔
378
  }
379

380
  int32_t tlen = *pLen;
7,816,570✔
381
  char   *tbuf = ctx->tbuf;
7,816,570✔
382
  bool    isVerboseLine = true;
7,816,570✔
383

384
  EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
7,816,570✔
385
  EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
7,816,570✔
386
  QRY_ERR_RET(nodesNodeToSQL(pConditions, tbuf + VARSTR_HEADER_SIZE,
7,816,570✔
387
                             TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
388
  if (pFilterEfficiency != NULL) {
7,819,008✔
389
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47,495✔
390
    EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_EFFICIENCY_FORMAT, *pFilterEfficiency);
47,495✔
391
  }
392
  EXPLAIN_ROW_END();
7,819,008✔
393

394
  *pLen = tlen;
7,819,008✔
395
  return qExplainResAppendRow(ctx, tbuf, tlen, level + 1);
7,819,008✔
396
}
397

398
static uint8_t qExplainGetIntervalPrecision(SIntervalPhysiNode *pIntNode) {
5,164,475✔
399
  return ((SColumnNode *)pIntNode->window.pTspk)->node.resType.precision;
5,164,475✔
400
}
401

402
static char* qExplainGetScanMode(STableScanPhysiNode* pScan) {
111,793,266✔
403
  bool isGroupByTbname = false;
111,793,266✔
404
  bool isGroupByTag = false;
111,793,266✔
405
  bool seq = false;
111,793,266✔
406
  bool groupOrder = false;
111,793,266✔
407
  if (pScan->pGroupTags && LIST_LENGTH(pScan->pGroupTags) == 1) {
111,793,266✔
408
    SNode* p = nodesListGetNode(pScan->pGroupTags, 0);
3,152,544✔
409
    if (QUERY_NODE_FUNCTION == nodeType(p) && (strcmp(((struct SFunctionNode*)p)->functionName, "tbname") == 0)) {
3,152,629✔
410
      isGroupByTbname = true;
3,049,839✔
411
    }
412
  }
413

414
  isGroupByTag = (NULL != pScan->pGroupTags) && !isGroupByTbname;
111,793,351✔
415
  if ((((!isGroupByTag) || isGroupByTbname) && pScan->groupSort) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
111,793,351✔
416
    return "seq_grp_order";
26,464✔
417
  }
418

419
  if ((isGroupByTbname && (pScan->groupSort || pScan->scan.groupOrderScan)) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
111,766,887✔
420
    return "grp_order";
1,526✔
421
  }
422

423
  return "ts_order";
111,765,361✔
424
}
425

426
static char* qExplainGetScanDataLoad(STableScanPhysiNode* pScan) {
111,797,782✔
427
  switch (pScan->dataRequired) {
111,797,782✔
428
    case FUNC_DATA_REQUIRED_DATA_LOAD:
104,991,018✔
429
      return "data";
104,991,018✔
430
    case FUNC_DATA_REQUIRED_SMA_LOAD:
5,270,364✔
431
      return "sma";
5,270,364✔
432
    case FUNC_DATA_REQUIRED_NOT_LOAD:
1,537,378✔
433
      return "no";
1,537,378✔
434
    default:
×
435
      break;
×
436
  }
437

438
  return "unknown";
×
439
}
440

441
static EDealRes qExplainVerifyIndex(SNode* pNode, void* pContext) {
88,615✔
442
  if (NULL == pNode) {
88,615✔
443
    return DEAL_RES_CONTINUE;
×
444
  }
445

446
  switch (nodeType(pNode)) {
88,615✔
447
    case QUERY_NODE_COLUMN:
54,341✔
448
    case QUERY_NODE_VALUE:
449
    case QUERY_NODE_LOGIC_CONDITION:
450
    case QUERY_NODE_NODE_LIST:
451
      break;
54,341✔
452
    case QUERY_NODE_OPERATOR: {
32,687✔
453
      SOperatorNode* pOp = (SOperatorNode*)pNode;
32,687✔
454
      if ((pOp->opType >= OP_TYPE_GREATER_THAN && pOp->opType <= OP_TYPE_EQUAL) || (OP_TYPE_IN == pOp->opType)) {
32,687✔
455
        break;
456
      }
457
      // fall through
458
    }
459
    default:
460
      *(bool*)pContext = false;
7,737✔
461
      return DEAL_RES_END;
7,737✔
462
  }
463

464
  return DEAL_RES_CONTINUE;
80,878✔
465
}
466

467
static bool qExplainCouldApplyTagIndex(SSubplan* pPlan) {
51,706,983✔
468
  if (NULL == pPlan->pTagIndexCond) {
51,706,983✔
469
    return false;
51,677,361✔
470
  }
471

472
  bool couldApply = true;
30,571✔
473
  nodesWalkExpr(pPlan->pTagIndexCond, qExplainVerifyIndex, &couldApply);
30,571✔
474

475
  return couldApply;
30,571✔
476
}
477

478
/**
479
 @brief Compare the execution time of two explain execution information
480
 by execElapsed in ascending order.
481
*/
482
static int32_t compareExecInfo(const void* p1, const void* p2) {
175,138✔
483
  const SExplainExecInfo* p11 = (const SExplainExecInfo*)p1;
175,138✔
484
  const SExplainExecInfo* p22 = (const SExplainExecInfo*)p2;
175,138✔
485

486
  return p11->execElapsed <= p22->execElapsed ? -1 : 1;
175,138✔
487
}
488

489
static int32_t qExplainExecAnalyze(const SExplainResNode *pResNode,
148,957,247✔
490
                                   SExplainCtx *ctx, int32_t level) {
491
  if (NULL == pResNode || NULL == pResNode->pExecInfo ||
153,531,374✔
492
      taosArrayGetSize(pResNode->pExecInfo) == 0) {
4,574,127✔
493
    return TSDB_CODE_SUCCESS;
144,384,420✔
494
  }
495

496
  bool    isVerboseLine = true;
4,572,827✔
497
  char   *tbuf = ctx->tbuf;
4,572,827✔
498
  int32_t tlen = 0;
4,572,827✔
499
  char    createAvgTs[32] = {0}; // 32 is enough for formatted ts: "%Y-%m-%d %H:%M:%S.ffffff"
4,572,827✔
500
  char    createMaxTs[32] = {0};
4,572,827✔
501
  EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EXEC_COST_FORMAT);
4,572,827✔
502

503
  int32_t nodeNum = (int32_t)taosArrayGetSize(pResNode->pExecInfo);
4,572,827✔
504
  SExplainExecInfo execInfo = {0};
4,574,127✔
505
  SExplainExecInfo maxExecInfo = {0};
4,574,127✔
506
  maxExecInfo.execCreate = INT64_MIN;
4,574,127✔
507
  maxExecInfo.execStart = INT64_MIN;
4,574,127✔
508

509
  for (int32_t i = 0; i < nodeNum; ++i) {
9,326,872✔
510
    const SExplainExecInfo *pExecInfo = taosArrayGet(pResNode->pExecInfo, i);
4,752,745✔
511
    if (pExecInfo == NULL) {
4,752,745✔
512
      qError("%s failed at line %d, execInfo is NULL",
×
513
             __func__, __LINE__);
514
      return TSDB_CODE_INVALID_PARA;
×
515
    }
516
    execInfo.execElapsed += pExecInfo->execElapsed;
4,752,745✔
517
    execInfo.execCreate += pExecInfo->execCreate;
4,752,745✔
518
    execInfo.execStart += pExecInfo->execStart;
4,752,745✔
519
    execInfo.execTimes += pExecInfo->execTimes;
4,752,745✔
520
    execInfo.inputWaitElapsed += pExecInfo->inputWaitElapsed;
4,752,745✔
521
    execInfo.outputWaitElapsed += pExecInfo->outputWaitElapsed;
4,752,745✔
522

523
    maxExecInfo.execElapsed = TMAX(maxExecInfo.execElapsed, pExecInfo->execElapsed);
4,752,745✔
524
    maxExecInfo.execCreate = TMAX(maxExecInfo.execCreate, pExecInfo->execCreate);
4,752,745✔
525
    maxExecInfo.execStart = TMAX(maxExecInfo.execStart, pExecInfo->execStart);
4,752,745✔
526
    maxExecInfo.execTimes = TMAX(maxExecInfo.execTimes, pExecInfo->execTimes);
4,752,745✔
527
    maxExecInfo.inputWaitElapsed = TMAX(maxExecInfo.inputWaitElapsed, pExecInfo->inputWaitElapsed);
4,752,745✔
528
    maxExecInfo.outputWaitElapsed = TMAX(maxExecInfo.outputWaitElapsed, pExecInfo->outputWaitElapsed);
4,752,745✔
529
  }
530

531
  if (nodeNum == 1) {
4,574,127✔
532
    if (formatTimestampLocal(createAvgTs, sizeof(createAvgTs), execInfo.execCreate,
4,410,193✔
533
                             TSDB_TIME_PRECISION_MICRO) == NULL) {
534
      /*
535
        If formatTimestampLocal fails, set the first char to '\0' to ensure
536
        createAvgTs is an empty string to avoid using uninitialized data.
537
      */
538
      createAvgTs[0] = '\0';
×
539
    }
540
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPUTE_FORMAT, EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execElapsed));
4,410,193✔
541
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,410,193✔
542
    EXPLAIN_ROW_APPEND(EXPLAIN_CREATE_TIME_FORMAT, createAvgTs);
4,410,193✔
543
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,410,193✔
544
    EXPLAIN_ROW_APPEND(EXPLAIN_START_FORMAT,
4,410,193✔
545
                       execInfo.execTimes > 0 ? EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execStart) : 0.0);
546
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,410,193✔
547
    EXPLAIN_ROW_APPEND(EXPLAIN_TIMES_FORMAT, (int64_t)execInfo.execTimes);
4,410,193✔
548
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,410,193✔
549
    EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_WAIT_ELAPSED_FORMAT,
4,410,193✔
550
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.inputWaitElapsed));
551
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,410,193✔
552
    EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_WAIT_ELAPSED_FORMAT,
4,410,193✔
553
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.outputWaitElapsed));
554
  } else if (nodeNum > 1) {
163,934✔
555
    int64_t createAvgUs = execInfo.execCreate / nodeNum;
163,934✔
556
    int64_t createMaxUs = maxExecInfo.execCreate;
163,934✔
557
    if (formatTimestampLocal(createAvgTs, sizeof(createAvgTs), createAvgUs,
163,934✔
558
                             TSDB_TIME_PRECISION_MICRO) == NULL) {
559
      createAvgTs[0] = '\0';
×
560
    }
561
    if (formatTimestampLocal(createMaxTs, sizeof(createMaxTs), createMaxUs,
163,934✔
562
                             TSDB_TIME_PRECISION_MICRO) == NULL) {
563
      createMaxTs[0] = '\0';
×
564
    }
565
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPUTE_FORMAT_EXT,
163,934✔
566
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execElapsed) / nodeNum,
567
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execElapsed));
568
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
163,934✔
569
    EXPLAIN_ROW_APPEND(EXPLAIN_CREATE_TIME_FORMAT_EXT, createAvgTs, createMaxTs);
163,934✔
570
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
163,934✔
571
    EXPLAIN_ROW_APPEND(EXPLAIN_START_FORMAT_EXT,
163,934✔
572
                       execInfo.execTimes > 0 ? EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execStart) / nodeNum : 0.0,
573
                       maxExecInfo.execTimes > 0 ? EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execStart) : 0.0);
574
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
163,934✔
575
    EXPLAIN_ROW_APPEND(EXPLAIN_TIMES_FORMAT_EXT,
163,934✔
576
                       (double)execInfo.execTimes / nodeNum, (int64_t)maxExecInfo.execTimes);
577
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
163,934✔
578
    EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_WAIT_ELAPSED_FORMAT_EXT,
163,934✔
579
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.inputWaitElapsed) / nodeNum,
580
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.inputWaitElapsed));
581
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
163,934✔
582
    EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_WAIT_ELAPSED_FORMAT_EXT,
163,934✔
583
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.outputWaitElapsed) / nodeNum,
584
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.outputWaitElapsed));
585
  }
586
  EXPLAIN_ROW_END();
4,574,127✔
587
  QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+1));
4,574,127✔
588

589
  return TSDB_CODE_SUCCESS;
4,574,127✔
590
}
591

592
/**
593
  @brief Analyze the IO of the scan nodes and append the result to the
594
  explain results.
595
*/
596
static int32_t qExplainIOAnalyze(const SExplainResNode *pResNode,
1,555,898✔
597
                                 SExplainCtx *ctx, int32_t level) {
598
  bool    isVerboseLine = true;
1,555,898✔
599
  char    *tbuf = ctx->tbuf;
1,555,898✔
600
  int32_t tlen = 0;
1,555,898✔
601

602
  /* sort groups' ExecInfo according to compute time in asc order */
603
  taosArraySort(pResNode->pExecInfo, compareExecInfo);
1,555,898✔
604
  int32_t nodeNum = (int32_t)taosArrayGetSize(pResNode->pExecInfo);
1,555,898✔
605
  STableScanAnalyzeInfo analyzeInfo = {0};
1,555,898✔
606
  STableScanAnalyzeInfo maxAnalyzeInfo = {0};
1,555,898✔
607

608
  for (int32_t i = 0; i < nodeNum; ++i) {
3,198,212✔
609
    const SExplainExecInfo *pExecInfo = taosArrayGet(pResNode->pExecInfo, i);
1,642,314✔
610
    if (pExecInfo == NULL || pExecInfo->verboseInfo == NULL) {
1,642,314✔
611
      qError("%s failed at line %d, execInfo or verboseInfo is NULL",
×
612
             __func__, __LINE__);
613
      return TSDB_CODE_INVALID_PARA;
×
614
    }
615
    const STableScanAnalyzeInfo *pScanInfo = (STableScanAnalyzeInfo *)pExecInfo->verboseInfo;
1,642,314✔
616

617
    analyzeInfo.totalBlocks += pScanInfo->totalBlocks;
1,642,314✔
618
    analyzeInfo.fileLoadBlocks += pScanInfo->fileLoadBlocks;
1,642,314✔
619
    analyzeInfo.fileLoadElapsed += pScanInfo->fileLoadElapsed;
1,642,314✔
620
    analyzeInfo.sttLoadBlocks += pScanInfo->sttLoadBlocks;
1,642,314✔
621
    analyzeInfo.sttLoadElapsed += pScanInfo->sttLoadElapsed;
1,642,314✔
622
    analyzeInfo.memLoadBlocks += pScanInfo->memLoadBlocks;
1,642,314✔
623
    analyzeInfo.memLoadElapsed += pScanInfo->memLoadElapsed;
1,642,314✔
624
    analyzeInfo.smaLoadBlocks += pScanInfo->smaLoadBlocks;
1,642,314✔
625
    analyzeInfo.smaLoadElapsed += pScanInfo->smaLoadElapsed;
1,642,314✔
626
    analyzeInfo.composedBlocks += pScanInfo->composedBlocks;
1,642,314✔
627
    analyzeInfo.composedElapsed += pScanInfo->composedElapsed;
1,642,314✔
628
    analyzeInfo.checkRows += pScanInfo->checkRows;
1,642,314✔
629

630
    maxAnalyzeInfo.totalBlocks = TMAX(maxAnalyzeInfo.totalBlocks, pScanInfo->totalBlocks);
1,642,314✔
631
    maxAnalyzeInfo.fileLoadBlocks = TMAX(maxAnalyzeInfo.fileLoadBlocks, pScanInfo->fileLoadBlocks);
1,642,314✔
632
    maxAnalyzeInfo.fileLoadElapsed = TMAX(maxAnalyzeInfo.fileLoadElapsed, pScanInfo->fileLoadElapsed);
1,642,314✔
633
    maxAnalyzeInfo.sttLoadBlocks = TMAX(maxAnalyzeInfo.sttLoadBlocks, pScanInfo->sttLoadBlocks);
1,642,314✔
634
    maxAnalyzeInfo.sttLoadElapsed = TMAX(maxAnalyzeInfo.sttLoadElapsed, pScanInfo->sttLoadElapsed);
1,642,314✔
635
    maxAnalyzeInfo.memLoadBlocks = TMAX(maxAnalyzeInfo.memLoadBlocks, pScanInfo->memLoadBlocks);
1,642,314✔
636
    maxAnalyzeInfo.memLoadElapsed = TMAX(maxAnalyzeInfo.memLoadElapsed, pScanInfo->memLoadElapsed);
1,642,314✔
637
    maxAnalyzeInfo.smaLoadBlocks = TMAX(maxAnalyzeInfo.smaLoadBlocks, pScanInfo->smaLoadBlocks);
1,642,314✔
638
    maxAnalyzeInfo.smaLoadElapsed = TMAX(maxAnalyzeInfo.smaLoadElapsed, pScanInfo->smaLoadElapsed);
1,642,314✔
639
    maxAnalyzeInfo.composedBlocks = TMAX(maxAnalyzeInfo.composedBlocks, pScanInfo->composedBlocks);
1,642,314✔
640
    maxAnalyzeInfo.composedElapsed = TMAX(maxAnalyzeInfo.composedElapsed, pScanInfo->composedElapsed);
1,642,314✔
641
    maxAnalyzeInfo.checkRows = TMAX(maxAnalyzeInfo.checkRows, pScanInfo->checkRows);
1,642,314✔
642
  }
643

644
  EXPLAIN_ROW_NEW(level + 1, EXPLAIN_IO_FORMAT);
1,555,898✔
645
  if (nodeNum == 1) {
1,555,898✔
646
    EXPLAIN_ROW_APPEND(EXPLAIN_TOTAL_BLOCKS_FORMAT, analyzeInfo.totalBlocks);
1,474,720✔
647
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
648
    EXPLAIN_ROW_APPEND(EXPLAIN_FILE_LOAD_BLOCKS_FORMAT, analyzeInfo.fileLoadBlocks);
1,474,720✔
649
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
650
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_BLOCKS_FORMAT, analyzeInfo.sttLoadBlocks);
1,474,720✔
651
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
652
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_BLOCKS_FORMAT, analyzeInfo.memLoadBlocks);
1,474,720✔
653
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
654
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_BLOCKS_FORMAT, analyzeInfo.smaLoadBlocks);
1,474,720✔
655
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
656
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_BLOCKS_FORMAT, analyzeInfo.composedBlocks);
1,474,720✔
657
    EXPLAIN_ROW_END();
1,474,720✔
658
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+1));
1,474,720✔
659

660
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_FILE_LOAD_ELAPSED_FORMAT, analyzeInfo.fileLoadElapsed);
1,474,720✔
661
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
662
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_ELAPSED_FORMAT, analyzeInfo.sttLoadElapsed);
1,474,720✔
663
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
664
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_ELAPSED_FORMAT, analyzeInfo.memLoadElapsed);
1,474,720✔
665
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
666
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_ELAPSED_FORMAT, analyzeInfo.smaLoadElapsed);
1,474,720✔
667
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,474,720✔
668
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_ELAPSED_FORMAT, analyzeInfo.composedElapsed);
1,474,720✔
669
    EXPLAIN_ROW_END();
1,474,720✔
670
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+2));
1,474,720✔
671

672
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_CHECK_ROWS_FORMAT, analyzeInfo.checkRows);
1,474,720✔
673
  } else if (nodeNum > 1) {
81,178✔
674
    EXPLAIN_ROW_APPEND(EXPLAIN_TOTAL_BLOCKS_FORMAT_EXT,
81,178✔
675
                       (double)analyzeInfo.totalBlocks / nodeNum, maxAnalyzeInfo.totalBlocks);
676
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
677
    EXPLAIN_ROW_APPEND(EXPLAIN_FILE_LOAD_BLOCKS_FORMAT_EXT,
81,178✔
678
                       (double)analyzeInfo.fileLoadBlocks / nodeNum, maxAnalyzeInfo.fileLoadBlocks);
679
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
680
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_BLOCKS_FORMAT_EXT,
81,178✔
681
                       (double)analyzeInfo.sttLoadBlocks / nodeNum, maxAnalyzeInfo.sttLoadBlocks);
682
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
683
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_BLOCKS_FORMAT_EXT,
81,178✔
684
                       (double)analyzeInfo.memLoadBlocks / nodeNum, maxAnalyzeInfo.memLoadBlocks);
685
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
686
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_BLOCKS_FORMAT_EXT,
81,178✔
687
                       (double)analyzeInfo.smaLoadBlocks / nodeNum, maxAnalyzeInfo.smaLoadBlocks);
688
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
689
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_BLOCKS_FORMAT_EXT,
81,178✔
690
                       (double)analyzeInfo.composedBlocks / nodeNum, maxAnalyzeInfo.composedBlocks);
691
    EXPLAIN_ROW_END();
81,178✔
692
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+1));
81,178✔
693

694
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_FILE_LOAD_ELAPSED_FORMAT_EXT,
81,178✔
695
                    (double)analyzeInfo.fileLoadElapsed / nodeNum, maxAnalyzeInfo.fileLoadElapsed);
696
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
697
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_ELAPSED_FORMAT_EXT,
81,178✔
698
                       (double)analyzeInfo.sttLoadElapsed / nodeNum, maxAnalyzeInfo.sttLoadElapsed);
699
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
700
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_ELAPSED_FORMAT_EXT,
81,178✔
701
                       (double)analyzeInfo.memLoadElapsed / nodeNum, maxAnalyzeInfo.memLoadElapsed);
702
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
703
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_ELAPSED_FORMAT_EXT,
81,178✔
704
                       (double)analyzeInfo.smaLoadElapsed / nodeNum, maxAnalyzeInfo.smaLoadElapsed);
705
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
706
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_ELAPSED_FORMAT_EXT,
81,178✔
707
                       (double)analyzeInfo.composedElapsed / nodeNum, maxAnalyzeInfo.composedElapsed);
708
    EXPLAIN_ROW_END();
81,178✔
709
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+2));
81,178✔
710

711
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_CHECK_ROWS_FORMAT_EXT,
81,178✔
712
                     (double)analyzeInfo.checkRows / nodeNum, maxAnalyzeInfo.checkRows);
713

714
    /* slowest query node information */
715
    const SExplainExecInfo* slowestExecInfo = taosArrayGetLast(pResNode->pExecInfo);
81,178✔
716
    if (slowestExecInfo) {
81,178✔
717
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
81,178✔
718
      int32_t midIndex = (nodeNum - 1) / 2;
81,178✔
719
      const SExplainExecInfo* midExecInfo = taosArrayGet(pResNode->pExecInfo, midIndex);
81,178✔
720
      const SExplainExecInfo* fastestExecInfo = taosArrayGet(pResNode->pExecInfo, 0);
81,178✔
721
      double slowDeviation = midExecInfo->execElapsed > 0 ?
83,058✔
722
        ((double)slowestExecInfo->execElapsed - (double)midExecInfo->execElapsed) * 100.0 /
81,178✔
723
        (double)midExecInfo->execElapsed : 0;
160,476✔
724
      double dataDeviation = midExecInfo->numOfRows > 0 ?
83,058✔
725
        ((double)slowestExecInfo->numOfRows - (double)midExecInfo->numOfRows) * 100.0 /
75,960✔
726
        (double)midExecInfo->numOfRows : 0;
155,634✔
727
      double costRatio = fastestExecInfo->execElapsed > 0 ?
83,058✔
728
        (double)slowestExecInfo->execElapsed / (double)fastestExecInfo->execElapsed : 0;
81,178✔
729
      EXPLAIN_ROW_APPEND(EXPLAIN_SLOWEST_NODE_FORMAT, slowestExecInfo->vgId,
81,178✔
730
                         slowDeviation, costRatio, dataDeviation);
731
    }
732
  }
733
  EXPLAIN_ROW_END();
1,555,898✔
734
  QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+2));
1,555,898✔
735

736
  return TSDB_CODE_SUCCESS;
1,555,898✔
737
}
738

739
static int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t *pLevel) {
347,222,727✔
740
  int32_t     tlen = 0;
347,222,727✔
741
  bool        isVerboseLine = false;
347,222,727✔
742
  char       *tbuf = ctx->tbuf;
347,222,727✔
743
  bool        verbose = ctx->verbose;
347,222,727✔
744
  SPhysiNode *pNode = pResNode->pNode;
347,222,727✔
745
  if (NULL == pNode) {
347,222,727✔
746
    qError("pyhsical node in explain res node is NULL");
×
747
    return TSDB_CODE_APP_ERROR;
×
748
  }
749

750
  if (0 == *pLevel && ctx->currPlanId >= 0) {
347,222,727✔
751
    EXPLAIN_SUB_PLAN_LINE(ctx->currPlanId + 1);
57,707,348✔
752
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, *pLevel + 1));
57,707,348✔
753
    *pLevel += 2;
57,705,314✔
754
  }
755

756
  int32_t level = *pLevel;
347,220,693✔
757
  double filterEfficiency = 100;
347,220,693✔
758
  bool   hasEfficiency = ctx->mode == EXPLAIN_MODE_ANALYZE && pResNode->pExecInfo;
347,220,693✔
759

760
  switch (pNode->type) {
347,220,693✔
761
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
4,231,344✔
762
      STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
4,231,344✔
763
      EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->scan.tableName.tname);
4,231,344✔
764
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
4,231,344✔
765
      if (pResNode->pExecInfo) {
4,231,344✔
766
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
3,660✔
767
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,660✔
768
      }
769
      if (pTagScanNode->scan.pScanPseudoCols) {
4,231,344✔
770
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTagScanNode->scan.pScanPseudoCols->length);
1,705,857✔
771
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,705,857✔
772
      }
773
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
4,231,344✔
774
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
4,231,344✔
775
      EXPLAIN_ROW_END();
4,231,344✔
776
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
4,231,344✔
777

778
      if (verbose) {
4,231,251✔
779
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,273,367✔
780
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,273,367✔
781
                           nodesGetOutputNumFromSlotList(pTagScanNode->scan.node.pOutputDataBlockDesc->pSlots));
782
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,273,367✔
783
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
1,273,367✔
784
        EXPLAIN_ROW_APPEND_LIMIT(pTagScanNode->scan.node.pLimit);
1,273,367✔
785
        EXPLAIN_ROW_APPEND_SLIMIT(pTagScanNode->scan.node.pSlimit);
1,273,367✔
786
        EXPLAIN_ROW_END();
1,273,367✔
787
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,273,367✔
788

789
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pTagScanNode->scan.node.pConditions,
1,273,367✔
790
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
791

792
        if (qExplainCouldApplyTagIndex(pResNode->pPlan)) {
1,273,460✔
793
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TAG_INDEX_FORMAT);
×
794
          EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
×
795
          QRY_ERR_RET(nodesNodeToSQL(pResNode->pPlan->pTagIndexCond, tbuf + VARSTR_HEADER_SIZE,
×
796
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
797
          EXPLAIN_ROW_END();
×
798
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
799
        }
800

801
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
1,273,367✔
802
      }
803
      break;
4,231,158✔
804
    }
805
    case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
127,295✔
806
      SVirtualScanPhysiNode *pVirtualTableScanNode = (SVirtualScanPhysiNode *)pNode;
127,295✔
807
      EXPLAIN_ROW_NEW(level, EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT, pVirtualTableScanNode->scan.tableName.tname);
127,295✔
808
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
127,295✔
809
      if (pResNode->pExecInfo) {
127,295✔
810
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,104✔
811
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,104✔
812
      }
813
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanCols->length);
127,295✔
814
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
127,295✔
815
      if (pVirtualTableScanNode->scan.pScanPseudoCols) {
127,295✔
816
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanPseudoCols->length);
49,797✔
817
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
49,797✔
818
      }
819
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
127,295✔
820
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
127,295✔
821
      EXPLAIN_ROW_END();
127,295✔
822
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
127,295✔
823

824
      if (verbose) {
127,295✔
825
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
83,432✔
826
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
83,432✔
827
                           nodesGetOutputNumFromSlotList(pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->pSlots));
828
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
83,432✔
829
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
83,432✔
830
        EXPLAIN_ROW_APPEND_LIMIT(pVirtualTableScanNode->scan.node.pLimit);
83,432✔
831
        EXPLAIN_ROW_APPEND_SLIMIT(pVirtualTableScanNode->scan.node.pSlimit);
83,432✔
832
        EXPLAIN_ROW_END();
83,432✔
833
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
83,432✔
834

835
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pVirtualTableScanNode->scan.node.pConditions,
83,432✔
836
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
837

838
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
83,432✔
839
      }
840
      break;
127,295✔
841
    }
842
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
111,793,713✔
843
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
844
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
845
      STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
111,793,713✔
846
      EXPLAIN_ROW_NEW(level,
111,793,713✔
847
                      QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == pNode->type ? EXPLAIN_TBL_MERGE_SCAN_FORMAT
848
                                                                               : EXPLAIN_TBL_SCAN_FORMAT,
849
                      pTblScanNode->scan.tableName.tname);
850
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
111,793,713✔
851
      if (pResNode->pExecInfo) {
111,793,713✔
852
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,156,581✔
853
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,156,581✔
854
      }
855

856
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
111,793,713✔
857
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
111,793,713✔
858
      if (pTblScanNode->scan.pScanPseudoCols) {
111,793,713✔
859
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTblScanNode->scan.pScanPseudoCols->length);
7,015,672✔
860
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,015,672✔
861
      }
862
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
111,793,713✔
863
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
111,793,713✔
864
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_ORDER_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
111,793,713✔
865
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
111,793,713✔
866
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_MODE_FORMAT, qExplainGetScanMode(pTblScanNode));
111,793,713✔
867
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
111,793,545✔
868
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_DATA_LOAD_FORMAT, qExplainGetScanDataLoad(pTblScanNode));
111,793,545✔
869
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
111,798,438✔
870
      EXPLAIN_ROW_END();
111,798,438✔
871
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
111,798,438✔
872

873
      if (verbose) {
111,796,166✔
874
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
50,432,053✔
875
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
50,432,053✔
876
                           nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
877
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
50,434,133✔
878
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
50,434,133✔
879
        EXPLAIN_ROW_APPEND_LIMIT(pTblScanNode->scan.node.pLimit);
50,434,133✔
880
        EXPLAIN_ROW_APPEND_SLIMIT(pTblScanNode->scan.node.pSlimit);
50,434,133✔
881
        EXPLAIN_ROW_END();
50,434,133✔
882
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
50,434,133✔
883

884
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey,
50,433,211✔
885
                        pTblScanNode->scanRange.ekey);
886
        EXPLAIN_ROW_END();
50,433,211✔
887
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
50,433,211✔
888

889
        if (NULL != pTblScanNode->pGroupTags) {
50,434,410✔
890
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
2,042,758✔
891
          EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pTblScanNode->pGroupTags->length);
2,042,758✔
892
          EXPLAIN_ROW_END();
2,042,758✔
893
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,042,758✔
894
        }
895

896
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pTblScanNode->scan.node.pConditions,
50,432,380✔
897
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
898

899
        if (pTblScanNode->pPrimaryCond) {
50,432,633✔
900
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PRIMARY_FILTER_FORMAT);
7,716✔
901
          QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->pPrimaryCond, tbuf + VARSTR_HEADER_SIZE,
7,716✔
902
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
903
          EXPLAIN_ROW_END();
7,716✔
904
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
7,716✔
905
        }
906

907
        if (qExplainCouldApplyTagIndex(pResNode->pPlan)) {
50,432,633✔
908
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TAG_INDEX_FORMAT);
22,834✔
909
          EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
22,834✔
910
          QRY_ERR_RET(nodesNodeToSQL(pResNode->pPlan->pTagIndexCond, tbuf + VARSTR_HEADER_SIZE,
22,834✔
911
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
912
          EXPLAIN_ROW_END();
22,834✔
913
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
22,834✔
914
        }
915

916
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
50,431,498✔
917

918
        if (EXPLAIN_MODE_ANALYZE == ctx->mode && pResNode->pExecInfo) {
50,431,881✔
919
          /* table scan I/O analyze information */
920
          QRY_ERR_RET(qExplainIOAnalyze(pResNode, ctx, level));
1,555,898✔
921
        }
922
      }
923
      break;
111,792,371✔
924
    }
925
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
423,433✔
926
      SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
423,433✔
927
      EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
423,433✔
928
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
423,433✔
929
      if (pResNode->pExecInfo) {
423,433✔
930
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
13,359✔
931
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
13,359✔
932
      }
933
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
423,433✔
934
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
423,433✔
935
      if (pSTblScanNode->scan.pScanPseudoCols) {
423,433✔
936
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pSTblScanNode->scan.pScanPseudoCols->length);
526✔
937
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
526✔
938
      }
939
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
423,433✔
940
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
423,433✔
941
      EXPLAIN_ROW_END();
423,433✔
942
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
423,433✔
943

944
      if (verbose) {
423,433✔
945
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
160,495✔
946
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
160,495✔
947
                           nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
948
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
160,495✔
949
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
160,495✔
950
        EXPLAIN_ROW_APPEND_LIMIT(pSTblScanNode->scan.node.pLimit);
160,495✔
951
        EXPLAIN_ROW_APPEND_SLIMIT(pSTblScanNode->scan.node.pSlimit);
160,495✔
952
        EXPLAIN_ROW_END();
160,495✔
953
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
160,495✔
954

955
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSTblScanNode->scan.node.pConditions,
160,495✔
956
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
957

958
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
160,495✔
959
      }
960
      break;
423,433✔
961
    }
962
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
68,382,449✔
963
      SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
68,382,449✔
964
      EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
68,382,449✔
965
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
68,382,449✔
966
      if (pResNode->pExecInfo) {
68,382,449✔
967
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,076,221✔
968
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,076,221✔
969
      }
970
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
68,382,449✔
971
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
68,382,449✔
972
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
68,382,449✔
973
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
68,382,449✔
974
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pPrjNode->node.inputTsOrder));
68,382,449✔
975
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
68,382,449✔
976
      EXPLAIN_ROW_END();
68,382,449✔
977
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
68,382,449✔
978

979
      if (verbose) {
68,382,020✔
980
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
28,310,167✔
981
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
28,310,167✔
982
                           nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
983
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,311,125✔
984
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
28,311,125✔
985
        EXPLAIN_ROW_APPEND_LIMIT(pPrjNode->node.pLimit);
28,311,125✔
986
        EXPLAIN_ROW_APPEND_SLIMIT(pPrjNode->node.pSlimit);
28,311,125✔
987
        EXPLAIN_ROW_END();
28,311,125✔
988
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
28,311,125✔
989

990
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
28,310,311✔
991
        EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pPrjNode->ignoreGroupId ? "true" : "false");
28,310,311✔
992
        EXPLAIN_ROW_END();
28,310,311✔
993
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
28,310,311✔
994

995
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pPrjNode->mergeDataBlock? "True":"False");
28,310,590✔
996
        EXPLAIN_ROW_END();
28,310,590✔
997
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
28,310,590✔
998

999
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pPrjNode->node.pConditions,
28,311,238✔
1000
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1001

1002
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
28,310,703✔
1003
      }
1004
      break;
68,387,280✔
1005
    }
1006
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
6,090,956✔
1007
      SSortMergeJoinPhysiNode *pJoinNode = (SSortMergeJoinPhysiNode *)pNode;
6,090,956✔
1008
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
6,090,956✔
1009
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
6,090,956✔
1010
      if (pResNode->pExecInfo) {
6,090,956✔
1011
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
228,594✔
1012
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
228,594✔
1013
      }
1014
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
6,090,956✔
1015
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,090,956✔
1016
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
6,090,956✔
1017
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,090,956✔
1018
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
6,090,956✔
1019
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,090,956✔
1020
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Merge");
6,090,956✔
1021
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
6,090,956✔
1022
      EXPLAIN_ROW_END();
6,090,956✔
1023
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
6,090,956✔
1024

1025
      if (verbose) {
6,090,956✔
1026
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,900,157✔
1027
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,900,157✔
1028
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
1029
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,900,157✔
1030
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
1,900,157✔
1031
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
1,900,157✔
1032
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
1,900,157✔
1033
        EXPLAIN_ROW_END();
1,900,157✔
1034
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,900,157✔
1035

1036
        if (IS_ASOF_JOIN(pJoinNode->subType) || IS_WINDOW_JOIN(pJoinNode->subType)) {
1,900,064✔
1037
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_PARAM_FORMAT);
96,472✔
1038
          if (IS_ASOF_JOIN(pJoinNode->subType)) {
96,472✔
1039
            EXPLAIN_ROW_APPEND(EXPLAIN_ASOF_OP_FORMAT, qExplainGetAsofOpStr(pJoinNode->asofOpType));
43,568✔
1040
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
43,568✔
1041
          }
1042
          if (NULL != pJoinNode->pWindowOffset) {
96,472✔
1043
            SWindowOffsetNode* pWinOffset = (SWindowOffsetNode*)pJoinNode->pWindowOffset;
52,904✔
1044
            SValueNode* pStart = (SValueNode*)pWinOffset->pStartOffset;
52,904✔
1045
            SValueNode* pEnd = (SValueNode*)pWinOffset->pEndOffset;
52,904✔
1046
            EXPLAIN_ROW_APPEND(EXPLAIN_WIN_OFFSET_FORMAT, pStart->literal, pEnd->literal);
52,904✔
1047
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
52,904✔
1048
          }
1049
          if (NULL != pJoinNode->pJLimit && NULL != ((SLimitNode*)pJoinNode->pJLimit)->limit) {
96,472✔
1050
            SLimitNode* pJLimit = (SLimitNode*)pJoinNode->pJLimit;
17,116✔
1051
            EXPLAIN_ROW_APPEND(EXPLAIN_JLIMIT_FORMAT, pJLimit->limit->datum.i);
17,116✔
1052
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
17,116✔
1053
          }
1054
          if (IS_WINDOW_JOIN(pJoinNode->subType)) {
96,472✔
1055
            EXPLAIN_ROW_APPEND(EXPLAIN_SEQ_WIN_GRP_FORMAT, pJoinNode->seqWinGroup);
52,904✔
1056
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
52,904✔
1057
          }
1058

1059
          EXPLAIN_ROW_APPEND(EXPLAIN_GRP_JOIN_FORMAT, pJoinNode->grpJoin);
96,472✔
1060
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
96,472✔
1061
          EXPLAIN_ROW_END();
96,472✔
1062

1063
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
96,472✔
1064
        }
1065

1066
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pJoinNode->node.pConditions,
1,900,064✔
1067
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1068

1069
        if (NULL != pJoinNode->pPrimKeyCond) {
1,900,064✔
1070
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PRIM_CONDITIONS_FORMAT);
1,833,249✔
1071
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1,833,249✔
1072
          EXPLAIN_ROW_END();
1,833,249✔
1073
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,833,249✔
1074
        }
1075

1076
        if (NULL != pJoinNode->pEqLeft && pJoinNode->pEqLeft->length > 0) {
1,900,064✔
1077
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_LEFT_FORMAT);
778✔
1078
          SNode* pCol = NULL;
778✔
1079
          FOREACH(pCol, pJoinNode->pEqLeft) {
1,556✔
1080
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
778✔
1081
          }
1082
          EXPLAIN_ROW_END();
778✔
1083
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
778✔
1084
        }
1085

1086
        if (NULL != pJoinNode->pEqRight && pJoinNode->pEqRight->length > 0) {
1,900,064✔
1087
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_RIGHT_FORMAT);
778✔
1088
          SNode* pCol = NULL;
778✔
1089
          FOREACH(pCol, pJoinNode->pEqRight) {
1,556✔
1090
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
778✔
1091
          }
1092
          EXPLAIN_ROW_END();
778✔
1093
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
778✔
1094
        }
1095

1096
        if (NULL != pJoinNode->pFullOnCond) {
1,900,064✔
1097
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
181,378✔
1098
          QRY_ERR_RET(
181,378✔
1099
                nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1100
          EXPLAIN_ROW_END();
181,378✔
1101
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
181,378✔
1102
        }
1103

1104
        if (NULL != pJoinNode->pColOnCond) {
1,900,157✔
1105
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COL_ON_CONDITIONS_FORMAT);
180,693✔
1106
          QRY_ERR_RET(
180,693✔
1107
                nodesNodeToSQL(pJoinNode->pColOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1108
          EXPLAIN_ROW_END();
180,693✔
1109
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
180,693✔
1110
        }
1111

1112
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
1,900,157✔
1113
      }
1114
      break;
6,090,770✔
1115
    }
1116
    case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
34,304,906✔
1117
      SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
34,304,906✔
1118
      EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, (pAggNode->pGroupKeys ? "GroupAggregate" : "Aggregate"));
34,304,906✔
1119
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
34,304,906✔
1120
      if (pResNode->pExecInfo) {
34,304,906✔
1121
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
548,519✔
1122
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
548,519✔
1123
      }
1124
      if (pAggNode->pAggFuncs) {
34,304,906✔
1125
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
24,434,724✔
1126
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
24,434,724✔
1127
      }
1128
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
34,304,906✔
1129
      if (pAggNode->pGroupKeys) {
34,304,906✔
1130
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
18,803,297✔
1131
        EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
18,803,297✔
1132
      }
1133
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
34,304,906✔
1134
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pAggNode->node.inputTsOrder));
34,304,906✔
1135
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
34,304,906✔
1136
      EXPLAIN_ROW_END();
34,304,906✔
1137
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
34,304,906✔
1138

1139
      if (verbose) {
34,305,837✔
1140
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
14,159,161✔
1141
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
14,159,161✔
1142
                           nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
1143
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,159,602✔
1144
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
14,159,602✔
1145
        EXPLAIN_ROW_APPEND_LIMIT(pAggNode->node.pLimit);
14,159,602✔
1146
        EXPLAIN_ROW_APPEND_SLIMIT(pAggNode->node.pSlimit);
14,159,602✔
1147
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,159,602✔
1148
        EXPLAIN_ROW_APPEND(EXPLAIN_PLAN_BLOCKING, !pAggNode->node.forceCreateNonBlockingOptr);
14,159,602✔
1149
        EXPLAIN_ROW_END();
14,159,602✔
1150
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
14,159,602✔
1151

1152
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pAggNode->node.pConditions,
14,158,426✔
1153
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1154

1155
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pAggNode->mergeDataBlock? "True":"False");
14,158,926✔
1156
        EXPLAIN_ROW_END();
14,158,926✔
1157
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
14,158,926✔
1158

1159
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
14,159,529✔
1160
      }
1161
      break;
34,306,597✔
1162
    }
1163
    case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: {
1,198,071✔
1164
      SIndefRowsFuncPhysiNode *pIndefNode = (SIndefRowsFuncPhysiNode *)pNode;
1,198,071✔
1165
      EXPLAIN_ROW_NEW(level, EXPLAIN_INDEF_ROWS_FORMAT);
1,198,071✔
1166
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,198,071✔
1167
      if (pResNode->pExecInfo) {
1,198,071✔
1168
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
3,638✔
1169
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,638✔
1170
      }
1171
      if (pIndefNode->pFuncs) {
1,198,071✔
1172
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIndefNode->pFuncs->length);
1,198,071✔
1173
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,198,071✔
1174
      }
1175
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->totalRowSize);
1,198,071✔
1176
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,198,071✔
1177
      EXPLAIN_ROW_END();
1,198,071✔
1178
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,198,071✔
1179

1180
      if (verbose) {
1,198,071✔
1181
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
224,916✔
1182
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
224,916✔
1183
                           nodesGetOutputNumFromSlotList(pIndefNode->node.pOutputDataBlockDesc->pSlots));
1184
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
224,916✔
1185
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->outputRowSize);
224,916✔
1186
        EXPLAIN_ROW_APPEND_LIMIT(pIndefNode->node.pLimit);
224,916✔
1187
        EXPLAIN_ROW_APPEND_SLIMIT(pIndefNode->node.pSlimit);
224,916✔
1188
        EXPLAIN_ROW_END();
224,916✔
1189
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
224,916✔
1190

1191
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIndefNode->node.pConditions,
224,916✔
1192
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1193

1194
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
224,916✔
1195
      }
1196
      break;
1,198,071✔
1197
    }
1198
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
58,481,478✔
1199
      SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
58,481,478✔
1200
      int32_t nodeNum = 0;
58,481,478✔
1201
      for (int32_t gid = pExchNode->srcStartGroupId; gid <= pExchNode->srcEndGroupId; ++gid) {
126,419,531✔
1202
        SExplainGroup *group = taosHashGet(ctx->pCurrPlanCtx->groupHash, &gid, sizeof(gid));
67,934,675✔
1203
        if (NULL == group) {
67,933,002✔
1204
          qError("exchange src group %d not in groupHash", gid);
×
1205
          QRY_ERR_RET(TSDB_CODE_APP_ERROR);
5,051✔
1206
        }
1207

1208
        if (pExchNode->childrenVgIds && group->nodeExecInfo) {
67,938,053✔
1209
          int32_t matchedCnt = 0;
1,650,729✔
1210
          int32_t rspCnt = (int32_t)taosArrayGetSize(group->nodeExecInfo);
1,650,729✔
1211
          for (int32_t j = 0; j < rspCnt; ++j) {
6,027,119✔
1212
            const SExplainRsp* pRsp = taosArrayGet(group->nodeExecInfo, j);
4,376,390✔
1213
            if (qExplainRspMatchVgIds(pRsp, pExchNode->childrenVgIds)) {
4,376,390✔
1214
              ++matchedCnt;
1,882,682✔
1215
            }
1216
          }
1217
          nodeNum += matchedCnt;
1,650,729✔
1218
          continue;
1,650,729✔
1219
        }
1220

1221
        nodeNum += group->nodeNum;
66,287,324✔
1222
      }
1223

1224
      int32_t srcCount = pExchNode->singleSrc ? 1 : nodeNum;
58,484,856✔
1225
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, srcCount);
58,484,856✔
1226
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
58,484,856✔
1227
      if (pResNode->pExecInfo) {
58,484,856✔
1228
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,578,271✔
1229
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,578,271✔
1230
      }
1231
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
58,484,856✔
1232
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
58,484,856✔
1233
      EXPLAIN_ROW_END();
58,484,856✔
1234
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
58,484,856✔
1235

1236
      if (verbose) {
58,482,671✔
1237
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
23,617,335✔
1238
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
23,617,335✔
1239
                           nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
1240
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
23,618,156✔
1241
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
23,618,156✔
1242
        EXPLAIN_ROW_APPEND_LIMIT(pExchNode->node.pLimit);
23,618,156✔
1243
        EXPLAIN_ROW_APPEND_SLIMIT(pExchNode->node.pSlimit);
23,618,156✔
1244
        EXPLAIN_ROW_END();
23,618,156✔
1245
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
23,618,156✔
1246

1247
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExchNode->node.pConditions,
23,617,877✔
1248
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1249

1250
        if (pResNode->pExecInfo) {
23,617,950✔
1251
          const SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
1,400,470✔
1252
          if (execInfo && execInfo->verboseInfo) {
1,400,470✔
1253
            const SExchangeExplainInfo *pExchInfo = (SExchangeExplainInfo *)execInfo->verboseInfo;
1,400,470✔
1254
            EXPLAIN_ROW_NEW(level + 1, EXPLAIN_NETWORK_FORMAT);
1,400,470✔
1255
            EXPLAIN_ROW_APPEND(EXPLAIN_EXCHANGE_MODE_FORMAT,
1,400,470✔
1256
              pExchInfo->mode == 0 ? EXPLAIN_EXCHANGE_MODE_CONCURRENT : EXPLAIN_EXCHANGE_MODE_SEQUENCE);
1257
            if (srcCount > 1) {
1,400,470✔
1258
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
148,174✔
1259
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_TIMES_FORMAT_EXT,
148,174✔
1260
                                pExchInfo->avgFetchTimes, pExchInfo->maxFetchTimes);
1261
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
148,174✔
1262
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_ROWS_FORMAT_EXT,
148,174✔
1263
                                pExchInfo->avgFetchRows, pExchInfo->maxFetchRows);
1264
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
148,174✔
1265
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_COST_FORMAT_EXT,
148,174✔
1266
                                EXPLAIN_CONVERT_TS_US_TO_MS(pExchInfo->avgFetchCost),
1267
                                EXPLAIN_CONVERT_TS_US_TO_MS(pExchInfo->maxFetchCost));
1268
            } else {
1269
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,252,296✔
1270
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_TIMES_FORMAT, (uint64_t)pExchInfo->avgFetchTimes);
1,252,296✔
1271
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,252,296✔
1272
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_ROWS_FORMAT, (uint64_t)pExchInfo->avgFetchRows);
1,252,296✔
1273
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,252,296✔
1274
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_COST_FORMAT,
1,252,296✔
1275
                                EXPLAIN_CONVERT_TS_US_TO_MS(pExchInfo->avgFetchCost));
1276
            }
1277
            EXPLAIN_ROW_END();
1,400,470✔
1278
            QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,400,470✔
1279
          }
1280
        }
1281

1282
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
23,617,950✔
1283
      }
1284

1285
      for (int32_t i = pExchNode->srcStartGroupId; i <= pExchNode->srcEndGroupId; ++i) {
126,421,498✔
1286
        int32_t nlevel = level + 1;
67,936,324✔
1287
        if (pExchNode->childrenVgIds) {
67,936,324✔
1288
          QRY_ERR_RET(qExplainAppendGroupResRowsByVgIds(ctx, i, &nlevel, pExchNode->grpSingleChannel,
1,650,729✔
1289
                                                        pExchNode->childrenVgIds));
1290
        } else {
1291
          QRY_ERR_RET(qExplainAppendGroupResRows(ctx, i, &nlevel, pExchNode->grpSingleChannel));
66,285,595✔
1292
        }
1293
      }
1294
      break;
58,485,174✔
1295
    }
1296
    case QUERY_NODE_PHYSICAL_PLAN_SORT: {
23,559,566✔
1297
      SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
23,559,566✔
1298
      EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
23,559,566✔
1299
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
23,559,566✔
1300
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.inputTsOrder));
23,559,566✔
1301
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
23,559,566✔
1302
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.outputTsOrder));
23,559,566✔
1303
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
23,559,566✔
1304
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
23,559,566✔
1305
      if (pResNode->pExecInfo) {
23,559,566✔
1306
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
84,358✔
1307
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
84,358✔
1308
      }
1309

1310
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
23,559,566✔
1311
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
23,559,566✔
1312
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
23,562,136✔
1313
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
23,562,136✔
1314
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
23,562,136✔
1315
      EXPLAIN_ROW_END();
23,562,136✔
1316
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
23,562,136✔
1317

1318
      if (pResNode->pExecInfo) {
23,560,238✔
1319
        // sort key
1320
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
84,358✔
1321
        for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
170,820✔
1322
          SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
86,462✔
1323
          EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
86,462✔
1324
        }
1325

1326
        EXPLAIN_ROW_END();
84,358✔
1327
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
84,358✔
1328

1329
        // sort method
1330
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
84,358✔
1331

1332
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
84,358✔
1333
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
84,358✔
1334
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
84,358✔
1335
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
84,358✔
1336
        if (pExecInfo->sortBuffer > 1024 * 1024) {
84,358✔
1337
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
66,650✔
1338
        } else if (pExecInfo->sortBuffer > 1024) {
17,708✔
1339
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
1340
        } else {
1341
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
17,708✔
1342
        }
1343

1344
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
84,358✔
1345
        EXPLAIN_ROW_END();
84,358✔
1346
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
84,358✔
1347
      }
1348

1349
      if (verbose) {
23,560,238✔
1350
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
11,579,496✔
1351
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
11,579,496✔
1352
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
1353
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
11,580,360✔
1354
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
11,580,360✔
1355
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
11,580,360✔
1356
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
11,580,360✔
1357
        EXPLAIN_ROW_END();
11,580,360✔
1358
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
11,580,360✔
1359

1360
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSortNode->node.pConditions,
11,579,735✔
1361
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1362

1363
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
11,579,919✔
1364
      }
1365
      break;
23,561,620✔
1366
    }
1367
    case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: {
8,024,392✔
1368
      SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
8,024,392✔
1369
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
8,024,392✔
1370
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
8,024,654✔
1371
      if (pResNode->pExecInfo) {
8,024,654✔
1372
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
15,006✔
1373
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,994✔
1374
      }
1375
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pIntNode->window.pFuncs));
8,024,800✔
1376
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,024,800✔
1377
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
8,024,800✔
1378
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,024,800✔
1379
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
8,024,800✔
1380
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,024,800✔
1381
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
8,024,800✔
1382
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
8,024,800✔
1383
      EXPLAIN_ROW_END();
8,024,800✔
1384
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
8,024,800✔
1385

1386
      if (verbose) {
8,025,344✔
1387
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4,441,809✔
1388
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
4,441,809✔
1389
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1390
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,441,716✔
1391
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
4,441,716✔
1392
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
4,441,716✔
1393
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
4,441,716✔
1394
        EXPLAIN_ROW_END();
4,441,716✔
1395
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,441,716✔
1396
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pIntNode->timeRange.skey, pIntNode->timeRange.ekey);
4,441,716✔
1397
        EXPLAIN_ROW_END();
4,441,716✔
1398
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,441,716✔
1399
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
4,441,809✔
1400
        int64_t time1 = -1;
4,441,809✔
1401
        int64_t time2 = -1;
4,441,809✔
1402
        int32_t code = TSDB_CODE_SUCCESS;
4,441,809✔
1403
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
4,441,809✔
1404
        QRY_ERR_RET(code);
4,441,288✔
1405
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
4,441,288✔
1406
        QRY_ERR_RET(code);
4,441,644✔
1407
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
4,441,644✔
1408
                        time1,
1409
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1410
                        time2,
1411
                        pIntNode->slidingUnit);
1412
        EXPLAIN_ROW_END();
4,441,282✔
1413
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,441,282✔
1414

1415
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIntNode->window.node.pConditions,
4,441,643✔
1416
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1417

1418
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
4,441,287✔
1419
        EXPLAIN_ROW_END();
4,441,287✔
1420
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,441,287✔
1421

1422
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
4,441,724✔
1423
      }
1424
      break;
8,025,081✔
1425
    }
1426
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: {
1,275,720✔
1427
      SMergeAlignedIntervalPhysiNode *pIntNode = (SMergeAlignedIntervalPhysiNode *)pNode;
1,275,720✔
1428
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
1,275,720✔
1429
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,275,898✔
1430
      if (pResNode->pExecInfo) {
1,275,898✔
1431
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
5,281✔
1432
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,281✔
1433
      }
1434
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pIntNode->window.pFuncs));
1,275,898✔
1435
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,275,898✔
1436
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,275,898✔
1437
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,275,898✔
1438
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
1,275,898✔
1439
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,275,898✔
1440
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
1,275,898✔
1441
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,275,898✔
1442
      EXPLAIN_ROW_END();
1,275,898✔
1443
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,275,898✔
1444

1445
      if (verbose) {
1,275,898✔
1446
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
722,666✔
1447
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
722,666✔
1448
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1449
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
722,759✔
1450
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
722,759✔
1451
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
722,759✔
1452
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
722,759✔
1453
        EXPLAIN_ROW_END();
722,759✔
1454
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
722,759✔
1455
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
722,666✔
1456
        int64_t time1 = -1;
722,666✔
1457
        int64_t time2 = -1;
722,666✔
1458
        int32_t code = TSDB_CODE_SUCCESS;
722,666✔
1459
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
722,666✔
1460
        QRY_ERR_RET(code);
722,759✔
1461
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
722,759✔
1462
        QRY_ERR_RET(code);
722,759✔
1463
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
722,759✔
1464
                        time1,
1465
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1466
                        time2,
1467
                        pIntNode->slidingUnit);
1468
        EXPLAIN_ROW_END();
722,759✔
1469
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
722,759✔
1470

1471
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIntNode->window.node.pConditions,
722,666✔
1472
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1473

1474
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
722,759✔
1475
        EXPLAIN_ROW_END();
722,759✔
1476
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
722,759✔
1477

1478
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
722,759✔
1479
      }
1480
      break;
1,275,898✔
1481
    }
1482
    case QUERY_NODE_PHYSICAL_PLAN_FILL: {
5,846✔
1483
      SFillPhysiNode *pFillNode = (SFillPhysiNode *)pNode;
5,846✔
1484
      EXPLAIN_ROW_NEW(level, EXPLAIN_FILL_FORMAT);
5,846✔
1485
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
5,846✔
1486
      if (pResNode->pExecInfo) {
5,846✔
1487
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,125✔
1488
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,125✔
1489
      }
1490
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pFillNode->mode));
5,846✔
1491
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,846✔
1492
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->totalRowSize);
5,846✔
1493
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,846✔
1494
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pFillNode->node.inputTsOrder));
5,846✔
1495
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
5,846✔
1496
      EXPLAIN_ROW_END();
5,846✔
1497
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
5,846✔
1498

1499
      if (verbose) {
5,846✔
1500
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
5,825✔
1501
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
5,825✔
1502
                           nodesGetOutputNumFromSlotList(pFillNode->node.pOutputDataBlockDesc->pSlots));
1503
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,825✔
1504
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->outputRowSize);
5,825✔
1505
        EXPLAIN_ROW_APPEND_LIMIT(pFillNode->node.pLimit);
5,825✔
1506
        EXPLAIN_ROW_APPEND_SLIMIT(pFillNode->node.pSlimit);
5,825✔
1507
        EXPLAIN_ROW_END();
5,825✔
1508
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,825✔
1509
        if (pFillNode->pValues) {
5,825✔
1510
          SNodeListNode *pValues = (SNodeListNode *)pFillNode->pValues;
547✔
1511
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
547✔
1512
          SNode  *tNode = NULL;
547✔
1513
          int32_t i = 0;
547✔
1514
          FOREACH(tNode, pValues->pNodeList) {
1,178✔
1515
            if (i) {
631✔
1516
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
84✔
1517
            }
1518
            SValueNode *tValue = (SValueNode *)tNode;
631✔
1519
            char       *value = nodesGetStrValueFromNode(tValue);
631✔
1520
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
631✔
1521
            taosMemoryFree(value);
631✔
1522
            ++i;
631✔
1523
          }
1524

1525
          EXPLAIN_ROW_END();
547✔
1526
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
547✔
1527
        }
1528

1529
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pFillNode->timeRange.skey, pFillNode->timeRange.ekey);
5,825✔
1530
        EXPLAIN_ROW_END();
5,825✔
1531
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,825✔
1532

1533
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pFillNode->node.pConditions,
5,825✔
1534
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1535

1536
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
5,825✔
1537
      }
1538
      break;
5,846✔
1539
    }
1540
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: {
2,184,175✔
1541
      SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
2,184,175✔
1542
      EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
2,184,175✔
1543
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
2,184,175✔
1544
      if (pResNode->pExecInfo) {
2,184,175✔
1545
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,104✔
1546
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,104✔
1547
      }
1548
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pSessNode->window.pFuncs));
2,184,175✔
1549
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,184,175✔
1550
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
2,184,175✔
1551
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
2,184,175✔
1552
      EXPLAIN_ROW_END();
2,184,175✔
1553
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
2,184,175✔
1554

1555
      if (verbose) {
2,184,610✔
1556
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,111,792✔
1557
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,111,792✔
1558
                           nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
1559
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,111,885✔
1560
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
1,111,885✔
1561
        EXPLAIN_ROW_APPEND_LIMIT(pSessNode->window.node.pLimit);
1,111,885✔
1562
        EXPLAIN_ROW_APPEND_SLIMIT(pSessNode->window.node.pSlimit);
1,111,885✔
1563
        EXPLAIN_ROW_END();
1,111,885✔
1564
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,111,885✔
1565

1566
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_WINDOW_FORMAT, pSessNode->gap);
1,111,893✔
1567
        EXPLAIN_ROW_END();
1,111,893✔
1568
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,111,893✔
1569

1570
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSessNode->window.node.pConditions,
1,111,799✔
1571
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1572

1573
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
1,111,892✔
1574
      }
1575
      break;
2,184,439✔
1576
    }
1577
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE: {
1,506,753✔
1578
      SStateWindowPhysiNode *pStateNode = (SStateWindowPhysiNode *)pNode;
1,506,753✔
1579

1580
      EXPLAIN_ROW_NEW(level, EXPLAIN_STATE_WINDOW_FORMAT,
1,506,753✔
1581
                      nodesGetNameFromColumnNode(pStateNode->pStateKey));
1582
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,507,206✔
1583
      if (pResNode->pExecInfo) {
1,507,206✔
1584
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,153✔
1585
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,052✔
1586
      }
1587

1588
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pStateNode->window.pFuncs));
1,507,109✔
1589
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,507,109✔
1590
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,507,109✔
1591
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,507,109✔
1592
      EXPLAIN_ROW_END();
1,507,109✔
1593
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,507,109✔
1594

1595
      if (verbose) {
1,507,127✔
1596
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
774,470✔
1597
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
774,470✔
1598
                           nodesGetOutputNumFromSlotList(pStateNode->window.node.pOutputDataBlockDesc->pSlots));
1599
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
774,549✔
1600
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->outputRowSize);
774,549✔
1601
        EXPLAIN_ROW_APPEND_LIMIT(pStateNode->window.node.pLimit);
774,549✔
1602
        EXPLAIN_ROW_APPEND_SLIMIT(pStateNode->window.node.pSlimit);
774,549✔
1603
        EXPLAIN_ROW_END();
774,549✔
1604
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
774,549✔
1605

1606
        EXPLAIN_ROW_END();
774,549✔
1607
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
774,549✔
1608

1609
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pStateNode->window.node.pConditions,
774,391✔
1610
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1611

1612
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
774,391✔
1613
      }
1614
      break;
1,507,125✔
1615
    }
1616
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
7,257,979✔
1617
      SPartitionPhysiNode *pPartNode = (SPartitionPhysiNode *)pNode;
7,257,979✔
1618

1619
      SNode *p = nodesListGetNode(pPartNode->pPartitionKeys, 0);
7,257,979✔
1620
      EXPLAIN_ROW_NEW(level, EXPLAIN_PARITION_FORMAT, nodesGetNameFromColumnNode(p));
7,258,414✔
1621
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,259,037✔
1622
      if (pResNode->pExecInfo) {
7,259,037✔
1623
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
132,394✔
1624
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
132,394✔
1625
      }
1626
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->totalRowSize);
7,259,037✔
1627

1628
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,259,037✔
1629
      EXPLAIN_ROW_END();
7,259,037✔
1630
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,259,037✔
1631

1632
      if (verbose) {
7,259,053✔
1633
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
3,354,630✔
1634
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
3,354,630✔
1635
                           nodesGetOutputNumFromSlotList(pPartNode->node.pOutputDataBlockDesc->pSlots));
1636
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,354,808✔
1637
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->outputRowSize);
3,354,808✔
1638
        EXPLAIN_ROW_APPEND_LIMIT(pPartNode->node.pLimit);
3,354,808✔
1639
        EXPLAIN_ROW_APPEND_SLIMIT(pPartNode->node.pSlimit);
3,354,808✔
1640
        EXPLAIN_ROW_END();
3,354,808✔
1641
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,354,808✔
1642

1643
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
3,354,729✔
1644
        EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pPartNode->pPartitionKeys->length);
3,354,729✔
1645
        EXPLAIN_ROW_END();
3,354,729✔
1646
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,354,729✔
1647

1648
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pPartNode->node.pConditions,
3,354,715✔
1649
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1650

1651
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
3,354,808✔
1652
      }
1653
      break;
7,258,814✔
1654
    }
1655
    case QUERY_NODE_PHYSICAL_PLAN_MERGE: {
12,261,524✔
1656
      SMergePhysiNode *pMergeNode = (SMergePhysiNode *)pNode;
12,261,524✔
1657
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_FORMAT);
12,261,524✔
1658
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
12,261,524✔
1659
      if (pResNode->pExecInfo) {
12,261,524✔
1660
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
446,248✔
1661
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
446,248✔
1662
      }
1663

1664
      SDataBlockDescNode *pDescNode = pMergeNode->node.pOutputDataBlockDesc;
12,261,524✔
1665
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
12,261,524✔
1666
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,261,993✔
1667
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
12,261,993✔
1668
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,261,993✔
1669
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.inputTsOrder));
12,261,993✔
1670
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,261,993✔
1671
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.outputTsOrder));
12,261,993✔
1672
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,261,993✔
1673
      EXPLAIN_ROW_APPEND(EXPLAIN_MERGE_MODE_FORMAT, EXPLAIN_MERGE_MODE_STRING(pMergeNode->type));
12,261,993✔
1674
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
12,261,993✔
1675
      EXPLAIN_ROW_END();
12,261,993✔
1676
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
12,261,993✔
1677

1678
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
12,261,966✔
1679
        if (MERGE_TYPE_SORT == pMergeNode->type) {
446,248✔
1680
          // sort method
1681
          EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
446,248✔
1682

1683
          int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
446,248✔
1684
          SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
446,248✔
1685
          SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
446,248✔
1686
          EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
446,248✔
1687
          if (pExecInfo->sortBuffer > 1024 * 1024) {
446,248✔
1688
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1689
          } else if (pExecInfo->sortBuffer > 1024) {
446,248✔
1690
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
446,248✔
1691
          } else {
1692
            EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1693
          }
1694

1695
          EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
446,248✔
1696
          EXPLAIN_ROW_END();
446,248✔
1697
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
446,248✔
1698
        }
1699
      }
1700

1701
      if (verbose) {
12,261,966✔
1702
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4,725,417✔
1703
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
4,725,417✔
1704
                           nodesGetOutputNumFromSlotList(pMergeNode->node.pOutputDataBlockDesc->pSlots));
1705
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,725,696✔
1706
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pMergeNode->node.pOutputDataBlockDesc->outputRowSize);
4,725,696✔
1707
        EXPLAIN_ROW_APPEND_LIMIT(pMergeNode->node.pLimit);
4,725,696✔
1708
        EXPLAIN_ROW_APPEND_SLIMIT(pMergeNode->node.pSlimit);
4,725,696✔
1709
        EXPLAIN_ROW_END();
4,725,696✔
1710
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,725,696✔
1711

1712
        if (MERGE_TYPE_SORT == pMergeNode->type) {
4,725,603✔
1713
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4,684,311✔
1714
          EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pMergeNode->ignoreGroupId ? "true" : "false");
4,684,311✔
1715
          EXPLAIN_ROW_END();
4,684,311✔
1716
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,684,311✔
1717

1718
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGE_KEYS_FORMAT);
4,684,404✔
1719
          if (pMergeNode->groupSort) {
4,684,404✔
1720
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, "_group_id asc");
2,138,708✔
1721
            if (LIST_LENGTH(pMergeNode->pMergeKeys) > 0) {
2,138,708✔
1722
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
1,843,494✔
1723
            }
1724
          }
1725
          for (int32_t i = 0; i < LIST_LENGTH(pMergeNode->pMergeKeys); ++i) {
9,572,806✔
1726
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pMergeNode->pMergeKeys, i);
4,888,123✔
1727
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, nodesGetNameFromColumnNode(ptn->pExpr));
4,888,216✔
1728
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,888,402✔
1729
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, EXPLAIN_ORDER_STRING(ptn->order));
4,888,402✔
1730
            if (i != LIST_LENGTH(pMergeNode->pMergeKeys) - 1) {
4,888,402✔
1731
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
499,026✔
1732
            }
1733
          }
1734
          EXPLAIN_ROW_END();
4,684,683✔
1735
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,684,683✔
1736
        }
1737

1738
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pMergeNode->node.pConditions,
4,725,510✔
1739
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1740

1741
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
4,725,603✔
1742
      }
1743
      break;
12,262,106✔
1744
    }
1745
    case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: {
×
1746
      SBlockDistScanPhysiNode *pDistScanNode = (SBlockDistScanPhysiNode *)pNode;
×
1747
      EXPLAIN_ROW_NEW(level, EXPLAIN_DISTBLK_SCAN_FORMAT, pDistScanNode->tableName.tname);
×
1748
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
1749
      if (pResNode->pExecInfo) {
×
1750
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
1751
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1752
      }
1753
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDistScanNode->pScanCols->length);
×
1754
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1755
      if (pDistScanNode->pScanPseudoCols) {
×
1756
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pDistScanNode->pScanPseudoCols->length);
×
1757
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1758
      }
1759
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->totalRowSize);
×
1760
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1761
      EXPLAIN_ROW_END();
×
1762
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1763

1764
      if (verbose) {
×
1765
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1766
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1767
                           nodesGetOutputNumFromSlotList(pDistScanNode->node.pOutputDataBlockDesc->pSlots));
1768
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1769
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->outputRowSize);
×
1770
        EXPLAIN_ROW_APPEND_LIMIT(pDistScanNode->node.pLimit);
×
1771
        EXPLAIN_ROW_APPEND_SLIMIT(pDistScanNode->node.pSlimit);
×
1772
        EXPLAIN_ROW_END();
×
1773
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1774

1775
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pDistScanNode->node.pConditions,
×
1776
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1777

1778
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
1779
      }
1780
      break;
×
1781
    }
1782
    case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: {
82,602✔
1783
      SLastRowScanPhysiNode *pLastRowNode = (SLastRowScanPhysiNode *)pNode;
82,602✔
1784
      EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->scan.tableName.tname);
82,602✔
1785
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
82,602✔
1786
      if (pResNode->pExecInfo) {
82,602✔
1787
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,052✔
1788
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,052✔
1789
      }
1790
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->scan.pScanCols->length);
82,602✔
1791
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
82,602✔
1792
      if (pLastRowNode->scan.pScanPseudoCols) {
82,602✔
1793
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
6,344✔
1794
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,344✔
1795
      }
1796
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
82,602✔
1797
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
82,602✔
1798
      EXPLAIN_ROW_END();
82,602✔
1799
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
82,602✔
1800

1801
      if (verbose) {
82,602✔
1802
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2,104✔
1803
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2,104✔
1804
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1805
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,104✔
1806
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
2,104✔
1807
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
2,104✔
1808
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
2,104✔
1809
        EXPLAIN_ROW_END();
2,104✔
1810
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,104✔
1811

1812
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pLastRowNode->scan.node.pConditions,
2,104✔
1813
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1814

1815
        if (qExplainCouldApplyTagIndex(pResNode->pPlan)) {
2,104✔
1816
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TAG_INDEX_FORMAT);
×
1817
          EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
×
1818
          QRY_ERR_RET(nodesNodeToSQL(pResNode->pPlan->pTagIndexCond, tbuf + VARSTR_HEADER_SIZE,
×
1819
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1820
          EXPLAIN_ROW_END();
×
1821
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1822
        }
1823
      }
1824
      break;
82,602✔
1825
    }
1826
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
6,826✔
1827
      STableCountScanPhysiNode *pLastRowNode = (STableCountScanPhysiNode *)pNode;
6,826✔
1828
      char *dbname = pLastRowNode->scan.tableName.dbname;
6,826✔
1829
      char *tbname = pLastRowNode->scan.tableName.tname;
6,826✔
1830
      if (dbname[0] != '\0' && tbname[0] != '\0') {
7,013✔
1831
        char name[TSDB_TABLE_FNAME_LEN];
187✔
1832
        snprintf(name, sizeof(name), "%s.%s", dbname, tbname);
187✔
1833
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, name);
187✔
1834
      } else if (dbname[0] != '\0') {
6,639✔
1835
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, dbname);
187✔
1836
      } else if (tbname[0] != '\0') {
6,452✔
1837
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, tbname);
187✔
1838
      } else {
1839
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, TSDB_INS_TABLE_TABLES);
6,265✔
1840
      }
1841
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
6,826✔
1842
      if (pResNode->pExecInfo) {
6,826✔
1843
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,104✔
1844
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,104✔
1845
      }
1846
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, LIST_LENGTH(pLastRowNode->scan.pScanCols));
6,826✔
1847
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,826✔
1848
      if (pLastRowNode->scan.pScanPseudoCols) {
6,826✔
1849
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
6,826✔
1850
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,826✔
1851
      }
1852
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
6,826✔
1853
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
6,826✔
1854
      EXPLAIN_ROW_END();
6,826✔
1855
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
6,826✔
1856

1857
      if (verbose) {
6,826✔
1858
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4,208✔
1859
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
4,208✔
1860
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1861
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,208✔
1862
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
4,208✔
1863
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
4,208✔
1864
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
4,208✔
1865
        EXPLAIN_ROW_END();
4,208✔
1866
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,208✔
1867

1868
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pLastRowNode->scan.node.pConditions,
4,208✔
1869
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1870

1871
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
4,208✔
1872
      }
1873
      break;
6,826✔
1874
    }
1875
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
41,628✔
1876
      SGroupSortPhysiNode *pSortNode = (SGroupSortPhysiNode *)pNode;
41,628✔
1877
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_SORT_FORMAT);
41,628✔
1878
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
41,628✔
1879
      if (pResNode->pExecInfo) {
41,628✔
1880
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
1881
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1882
      }
1883

1884
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
41,628✔
1885
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
41,628✔
1886
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
41,628✔
1887
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
41,628✔
1888
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
41,628✔
1889
      EXPLAIN_ROW_END();
41,628✔
1890
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
41,628✔
1891

1892
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
41,628✔
1893
        // sort key
1894
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
×
1895
        if (pResNode->pExecInfo) {
×
1896
          for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
×
1897
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
×
1898
            EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
×
1899
          }
1900
        }
1901

1902
        EXPLAIN_ROW_END();
×
1903
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1904

1905
        // sort method
1906
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
×
1907

1908
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
×
1909
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
×
1910
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
×
1911
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
×
1912
        if (pExecInfo->sortBuffer > 1024 * 1024) {
×
1913
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1914
        } else if (pExecInfo->sortBuffer > 1024) {
×
1915
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
1916
        } else {
1917
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1918
        }
1919

1920
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
×
1921
        EXPLAIN_ROW_END();
×
1922
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1923
      }
1924

1925
      if (verbose) {
41,628✔
1926
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1927
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1928
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
1929
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1930
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
×
1931
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
×
1932
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
×
1933
        EXPLAIN_ROW_END();
×
1934
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1935

1936
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSortNode->node.pConditions,
×
1937
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1938

1939
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
1940
      }
1941
      break;
41,628✔
1942
    }
1943
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: {
×
1944
      SMergeIntervalPhysiNode *pIntNode = (SMergeIntervalPhysiNode *)pNode;
×
1945
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
×
1946
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
1947
      if (pResNode->pExecInfo) {
×
1948
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
1949
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1950
      }
1951
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pIntNode->window.pFuncs));
×
1952
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1953
      EXPLAIN_ROW_END();
×
1954
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1955

1956
      if (verbose) {
×
1957
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1958
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1959
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1960
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1961
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
×
1962
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
×
1963
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
×
1964
        EXPLAIN_ROW_END();
×
1965
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1966
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
×
1967
        int64_t time1 = -1;
×
1968
        int64_t time2 = -1;
×
1969
        int32_t code = TSDB_CODE_SUCCESS;
×
1970
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
×
1971
        QRY_ERR_RET(code);
×
1972
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
×
1973
        QRY_ERR_RET(code);
×
1974
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
×
1975
                        time1,
1976
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1977
                        time2,
1978
                        pIntNode->slidingUnit);
1979
        EXPLAIN_ROW_END();
×
1980
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1981

1982
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIntNode->window.node.pConditions,
×
1983
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1984

1985
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
1986
      }
1987
      break;
×
1988
    }
1989
    case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
169,750✔
1990
      SInterpFuncPhysiNode *pInterpNode = (SInterpFuncPhysiNode *)pNode;
169,750✔
1991
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERP_FORMAT);
169,750✔
1992
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
169,750✔
1993
      if (pResNode->pExecInfo) {
169,750✔
1994
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
3,156✔
1995
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,156✔
1996
      }
1997
      if (pInterpNode->pFuncs) {
169,750✔
1998
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pInterpNode->pFuncs->length);
169,750✔
1999
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
169,750✔
2000
      }
2001

2002
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pInterpNode->fillMode));
169,750✔
2003

2004
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
169,750✔
2005
      EXPLAIN_ROW_END();
169,750✔
2006
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
169,750✔
2007

2008
      if (verbose) {
169,750✔
2009
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
169,750✔
2010
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
169,750✔
2011
                           nodesGetOutputNumFromSlotList(pInterpNode->node.pOutputDataBlockDesc->pSlots));
2012
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
169,750✔
2013
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pInterpNode->node.pOutputDataBlockDesc->outputRowSize);
169,750✔
2014
        EXPLAIN_ROW_APPEND_LIMIT(pInterpNode->node.pLimit);
169,750✔
2015
        EXPLAIN_ROW_APPEND_SLIMIT(pInterpNode->node.pSlimit);
169,750✔
2016
        EXPLAIN_ROW_END();
169,750✔
2017
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
169,750✔
2018
        if (pInterpNode->pFillValues) {
169,750✔
2019
          SNodeListNode *pValues = (SNodeListNode *)pInterpNode->pFillValues;
40,066✔
2020
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
40,066✔
2021
          SNode  *tNode = NULL;
40,066✔
2022
          int32_t i = 0;
40,066✔
2023
          FOREACH(tNode, pValues->pNodeList) {
80,132✔
2024
            if (i) {
40,066✔
2025
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2026
            }
2027
            SValueNode *tValue = (SValueNode *)tNode;
40,066✔
2028
            char       *value = nodesGetStrValueFromNode(tValue);
40,066✔
2029
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
40,066✔
2030
            taosMemoryFree(value);
40,066✔
2031
            ++i;
40,066✔
2032
          }
2033

2034
          EXPLAIN_ROW_END();
40,066✔
2035
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
40,066✔
2036
        }
2037

2038
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_INTERVAL_VALUE_FORMAT, pInterpNode->interval, pInterpNode->intervalUnit);
169,750✔
2039
        EXPLAIN_ROW_END();
169,750✔
2040

2041
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pInterpNode->timeRange.skey, pInterpNode->timeRange.ekey);
169,750✔
2042
        EXPLAIN_ROW_END();
169,750✔
2043
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
169,750✔
2044

2045
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pInterpNode->node.pConditions,
169,750✔
2046
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2047

2048
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
169,750✔
2049
      }
2050
      break;
169,750✔
2051
    }
2052
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT: {
1,672,393✔
2053
      SEventWinodwPhysiNode *pEventNode = (SEventWinodwPhysiNode *)pNode;
1,672,393✔
2054
      EXPLAIN_ROW_NEW(level, EXPLAIN_EVENT_FORMAT);
1,672,393✔
2055
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,672,393✔
2056
      if (pResNode->pExecInfo) {
1,672,393✔
2057
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,578✔
2058
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,578✔
2059
      }
2060
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pEventNode->window.pFuncs));
1,672,393✔
2061
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,672,393✔
2062
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pEventNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,672,393✔
2063
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,672,393✔
2064
      EXPLAIN_ROW_END();
1,672,393✔
2065
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,672,393✔
2066

2067
      if (verbose) {
1,673,010✔
2068
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_START_FORMAT);
900,312✔
2069
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pStartCond, tbuf + VARSTR_HEADER_SIZE,
900,312✔
2070
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2071
        EXPLAIN_ROW_END();
900,413✔
2072
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
900,413✔
2073

2074
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_END_FORMAT);
900,684✔
2075
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pEndCond, tbuf + VARSTR_HEADER_SIZE,
900,684✔
2076
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2077
        EXPLAIN_ROW_END();
900,836✔
2078
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
900,836✔
2079

2080
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
900,836✔
2081
      }
2082
      break;
1,672,755✔
2083
    }
2084
    case QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN:{
733,973✔
2085
      SHashJoinPhysiNode *pJoinNode = (SHashJoinPhysiNode *)pNode;
733,973✔
2086
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
733,973✔
2087
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
733,973✔
2088
      if (pResNode->pExecInfo) {
733,973✔
2089
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
778✔
2090
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
778✔
2091
      }
2092
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
733,973✔
2093
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2094
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
733,973✔
2095
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2096
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
733,973✔
2097
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2098
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Hash");
733,973✔
2099
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
733,973✔
2100
      EXPLAIN_ROW_END();
733,973✔
2101
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
733,973✔
2102

2103
      if (verbose) {
733,973✔
2104
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
778✔
2105
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
778✔
2106
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
2107
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
778✔
2108
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
778✔
2109
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
778✔
2110
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
778✔
2111
        EXPLAIN_ROW_END();
778✔
2112
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
778✔
2113

2114
        if (pJoinNode->node.pConditions) {
778✔
2115
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
2116
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
2117
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2118

2119
          EXPLAIN_ROW_END();
×
2120
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2121
        }
2122

2123
        bool conditionsGot = false;
778✔
2124
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
778✔
2125
        if (pJoinNode->pPrimKeyCond) {
778✔
2126
          QRY_ERR_RET(
×
2127
              nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2128
          conditionsGot = true;
×
2129
        }
2130
        if (pJoinNode->pColEqCond) {
778✔
2131
          if (conditionsGot) {
×
2132
            EXPLAIN_ROW_APPEND(" AND ");
×
2133
          }
2134
          QRY_ERR_RET(
×
2135
              nodesNodeToSQL(pJoinNode->pColEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2136
          conditionsGot = true;
×
2137
        }
2138
        if (pJoinNode->pTagEqCond) {
778✔
2139
          if (conditionsGot) {
778✔
2140
            EXPLAIN_ROW_APPEND(" AND ");
×
2141
          }
2142
          QRY_ERR_RET(
778✔
2143
              nodesNodeToSQL(pJoinNode->pTagEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2144
          conditionsGot = true;
778✔
2145
        }
2146
        if (pJoinNode->pFullOnCond) {
778✔
2147
          if (conditionsGot) {
×
2148
            EXPLAIN_ROW_APPEND(" AND ");
×
2149
          }
2150
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE,
×
2151
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2152
        }
2153
        EXPLAIN_ROW_END();
778✔
2154
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
778✔
2155

2156
        if (pJoinNode->timeRangeTarget) {
778✔
2157
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TABLE_TIMERANGE_FORMAT, qExplainGetTimerangeTargetStr(pJoinNode->timeRangeTarget), pJoinNode->timeRange.skey, pJoinNode->timeRange.ekey);
×
2158
          EXPLAIN_ROW_END();
×
2159
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2160
        }
2161

2162
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
778✔
2163
      }
2164
      break;
733,973✔
2165
    }
2166
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE:{
733,973✔
2167
      SGroupCachePhysiNode *pGroupCache = (SGroupCachePhysiNode *)pNode;
733,973✔
2168
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_CACHE_FORMAT);
733,973✔
2169
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
733,973✔
2170
      if (pResNode->pExecInfo) {
733,973✔
2171
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
778✔
2172
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
778✔
2173
      }
2174
      EXPLAIN_ROW_APPEND(EXPLAIN_GLOBAL_GROUP_FORMAT, pGroupCache->globalGrp);
733,973✔
2175
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2176
      EXPLAIN_ROW_APPEND(EXPLAIN_GROUP_BY_UID_FORMAT, pGroupCache->grpByUid);
733,973✔
2177
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2178
      EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pGroupCache->batchFetch);
733,973✔
2179
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2180
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->totalRowSize);
733,973✔
2181
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2182
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pGroupCache->node.inputTsOrder));
733,973✔
2183
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
733,973✔
2184
      EXPLAIN_ROW_END();
733,973✔
2185
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
733,973✔
2186

2187
      if (verbose) {
733,973✔
2188
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
778✔
2189
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
778✔
2190
                           nodesGetOutputNumFromSlotList(pGroupCache->node.pOutputDataBlockDesc->pSlots));
2191
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
778✔
2192
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->outputRowSize);
778✔
2193
        EXPLAIN_ROW_APPEND_LIMIT(pGroupCache->node.pLimit);
778✔
2194
        EXPLAIN_ROW_APPEND_SLIMIT(pGroupCache->node.pSlimit);
778✔
2195
        EXPLAIN_ROW_END();
778✔
2196
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
778✔
2197
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pGroupCache->node.pConditions,
778✔
2198
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2199

2200
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
778✔
2201
      }
2202
      break;
733,973✔
2203
    }
2204
    case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:{
1,137,589✔
2205
      SDynQueryCtrlPhysiNode *pDyn = (SDynQueryCtrlPhysiNode *)pNode;
1,137,589✔
2206
      EXPLAIN_ROW_NEW(level, EXPLAIN_DYN_QRY_CTRL_FORMAT, qExplainGetDynQryCtrlType(pDyn));
1,137,589✔
2207
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,137,589✔
2208
      if (pResNode->pExecInfo) {
1,137,589✔
2209
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,882✔
2210
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,882✔
2211
      }
2212
      switch (pDyn->qType) {
1,137,589✔
2213
        case DYN_QTYPE_STB_HASH: {
733,973✔
2214
          EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pDyn->stbJoin.batchFetch);
733,973✔
2215
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2216
          EXPLAIN_ROW_APPEND(EXPLAIN_VGROUP_SLOT_FORMAT, pDyn->stbJoin.vgSlot[0], pDyn->stbJoin.vgSlot[1]);
733,973✔
2217
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2218
          EXPLAIN_ROW_APPEND(EXPLAIN_UID_SLOT_FORMAT, pDyn->stbJoin.uidSlot[0], pDyn->stbJoin.uidSlot[1]);
733,973✔
2219
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2220
          EXPLAIN_ROW_APPEND(EXPLAIN_SRC_SCAN_FORMAT, pDyn->stbJoin.srcScan[0], pDyn->stbJoin.srcScan[1]);
733,973✔
2221
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2222
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
733,973✔
2223
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
733,973✔
2224
          EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
733,973✔
2225
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
733,973✔
2226
          break;
733,973✔
2227
        }
2228
        case DYN_QTYPE_VTB_INTERVAL:
207,829✔
2229
        case DYN_QTYPE_VTB_AGG: {
2230
          EXPLAIN_ROW_APPEND(EXPLAIN_HAS_PARTITION_FORMAT, pDyn->vtbScan.hasPartition);
207,829✔
2231
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
207,829✔
2232
          EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_PROCESS_CHILD_FORMAT, pDyn->vtbScan.batchProcessChild);
207,829✔
2233
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
207,829✔
2234
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
207,829✔
2235
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
207,829✔
2236
          break;
207,829✔
2237
        }
2238
        case DYN_QTYPE_VTB_TS_SCAN:
130,419✔
2239
        case DYN_QTYPE_VTB_SCAN: {
2240
          EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDyn->vtbScan.pScanCols->length);
130,419✔
2241
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
130,419✔
2242
          EXPLAIN_ROW_APPEND(EXPLAIN_ORIGIN_VGROUP_NUM_FORMAT, pDyn->vtbScan.pOrgVgIds->length);
130,419✔
2243
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
130,419✔
2244
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
130,419✔
2245
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
130,419✔
2246
          EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
130,419✔
2247
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
130,419✔
2248
          break;
130,419✔
2249
        }
2250
        case DYN_QTYPE_VTB_WINDOW: {
65,368✔
2251
          EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDyn->vtbWindow.pTargets->length);
65,368✔
2252
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,368✔
2253
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
65,368✔
2254
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,368✔
2255
          EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
65,368✔
2256
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
65,368✔
2257
          break;
65,368✔
2258
        }
2259
        default:
×
2260
          break;
×
2261
      }
2262

2263
      EXPLAIN_ROW_END();
1,137,589✔
2264
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,137,589✔
2265

2266
      if (verbose) {
1,137,589✔
2267
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
156,518✔
2268
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
156,518✔
2269
                           nodesGetOutputNumFromSlotList(pDyn->node.pOutputDataBlockDesc->pSlots));
2270
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
156,518✔
2271
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->outputRowSize);
156,518✔
2272
        EXPLAIN_ROW_APPEND_LIMIT(pDyn->node.pLimit);
156,518✔
2273
        EXPLAIN_ROW_APPEND_SLIMIT(pDyn->node.pSlimit);
156,518✔
2274
        EXPLAIN_ROW_END();
156,518✔
2275
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
156,518✔
2276

2277
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pDyn->node.pConditions,
156,518✔
2278
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2279

2280
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
156,518✔
2281
      }
2282
      break;
1,137,589✔
2283
    }
2284
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT: {
1,477,091✔
2285
      SCountWindowPhysiNode *pCountNode = (SCountWindowPhysiNode *)pNode;
1,477,091✔
2286
      EXPLAIN_ROW_NEW(level, EXPLAIN_COUNT_FORMAT);
1,477,091✔
2287
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,477,091✔
2288
      if (pResNode->pExecInfo) {
1,477,091✔
2289
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,052✔
2290
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,052✔
2291
      }
2292
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pCountNode->window.pFuncs));
1,477,091✔
2293
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,477,091✔
2294
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pCountNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,477,091✔
2295
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,477,091✔
2296
      EXPLAIN_ROW_END();
1,477,091✔
2297
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,477,091✔
2298

2299
      if (verbose) {
1,476,998✔
2300
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_NUM_FORMAT, pCountNode->windowCount);
785,834✔
2301
        EXPLAIN_ROW_END();
785,834✔
2302
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
785,834✔
2303
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_SLIDING_FORMAT, pCountNode->windowSliding);
785,834✔
2304
        EXPLAIN_ROW_END();
785,834✔
2305
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
785,834✔
2306

2307
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
785,927✔
2308
      }
2309
      break;
1,476,998✔
2310
    }
2311
    case QUERY_NODE_PHYSICAL_PLAN_EXTERNAL_WINDOW: {
×
2312
      SExternalWindowPhysiNode *pExternal = (SExternalWindowPhysiNode *)pNode;
×
2313
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXTERNAL_FORMAT, nodesGetNameFromColumnNode(pExternal->window.pTspk));
×
2314
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
2315
      if (pResNode->pExecInfo) {
×
2316
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2317
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2318
      }
2319
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pExternal->window.pFuncs));
×
2320
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2321
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->totalRowSize);
×
2322
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2323
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.inputTsOrder));
×
2324
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2325
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.outputTsOrder));
×
2326
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
2327
      EXPLAIN_ROW_END();
×
2328
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
2329

2330
      if (verbose) {
×
2331
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
2332
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
2333
                           nodesGetOutputNumFromSlotList(pExternal->window.node.pOutputDataBlockDesc->pSlots));
2334
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2335
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->outputRowSize);
×
2336
        EXPLAIN_ROW_APPEND_LIMIT(pExternal->window.node.pLimit);
×
2337
        EXPLAIN_ROW_APPEND_SLIMIT(pExternal->window.node.pSlimit);
×
2338
        EXPLAIN_ROW_END();
×
2339
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2340
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pExternal->timeRange.skey, pExternal->timeRange.ekey);
×
2341
        EXPLAIN_ROW_END();
×
2342
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2343

2344
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExternal->window.node.pConditions,
×
2345
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2346

2347
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pExternal->window.mergeDataBlock? "True":"False");
×
2348
        EXPLAIN_ROW_END();
×
2349
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2350

2351
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
2352
      }
2353
      break;
×
2354
    }
2355
    case QUERY_NODE_PHYSICAL_PLAN_HASH_EXTERNAL: {
65,368✔
2356
      SExternalWindowPhysiNode *pExternal = (SExternalWindowPhysiNode *)pNode;
65,368✔
2357
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXTERNAL_FORMAT, nodesGetNameFromColumnNode(pExternal->window.pTspk));
65,368✔
2358
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
65,368✔
2359
      if (pResNode->pExecInfo) {
65,368✔
2360
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2361
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2362
      }
2363
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pExternal->window.pFuncs));
65,368✔
2364
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,368✔
2365
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->totalRowSize);
65,368✔
2366
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,368✔
2367
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.inputTsOrder));
65,368✔
2368
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,368✔
2369
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.outputTsOrder));
65,368✔
2370
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
65,368✔
2371
      EXPLAIN_ROW_END();
65,368✔
2372
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
65,368✔
2373

2374
      if (verbose) {
65,368✔
2375
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
65,368✔
2376
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
65,368✔
2377
                           nodesGetOutputNumFromSlotList(pExternal->window.node.pOutputDataBlockDesc->pSlots));
2378
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,368✔
2379
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->outputRowSize);
65,368✔
2380
        EXPLAIN_ROW_APPEND_LIMIT(pExternal->window.node.pLimit);
65,368✔
2381
        EXPLAIN_ROW_APPEND_SLIMIT(pExternal->window.node.pSlimit);
65,368✔
2382
        EXPLAIN_ROW_END();
65,368✔
2383
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
65,368✔
2384
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pExternal->timeRange.skey, pExternal->timeRange.ekey);
65,368✔
2385
        EXPLAIN_ROW_END();
65,368✔
2386
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
65,368✔
2387

2388
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExternal->window.node.pConditions,
65,368✔
2389
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2390

2391
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pExternal->window.mergeDataBlock? "True":"False");
65,368✔
2392
        EXPLAIN_ROW_END();
65,368✔
2393
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
65,368✔
2394

2395
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
65,368✔
2396
      }
2397
      break;
65,368✔
2398
    }
2399
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_EXTERNAL: {
×
2400
      SExternalWindowPhysiNode *pExternal = (SExternalWindowPhysiNode *)pNode;
×
2401
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_EXTERNAL_FORMAT, nodesGetNameFromColumnNode(pExternal->window.pTspk));
×
2402
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
2403
      if (pResNode->pExecInfo) {
×
2404
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2405
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2406
      }
2407
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pExternal->window.pFuncs));
×
2408
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2409
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->totalRowSize);
×
2410
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2411
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.inputTsOrder));
×
2412
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2413
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.outputTsOrder));
×
2414
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
2415
      EXPLAIN_ROW_END();
×
2416
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
2417

2418
      if (verbose) {
×
2419
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
2420
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
2421
                           nodesGetOutputNumFromSlotList(pExternal->window.node.pOutputDataBlockDesc->pSlots));
2422
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2423
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->outputRowSize);
×
2424
        EXPLAIN_ROW_APPEND_LIMIT(pExternal->window.node.pLimit);
×
2425
        EXPLAIN_ROW_APPEND_SLIMIT(pExternal->window.node.pSlimit);
×
2426
        EXPLAIN_ROW_END();
×
2427
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2428

2429
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExternal->window.node.pConditions,
×
2430
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2431

2432
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pExternal->window.mergeDataBlock? "True":"False");
×
2433
        EXPLAIN_ROW_END();
×
2434
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2435

2436
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
2437
      }
2438
      break;
×
2439
    }
2440
    default:
×
2441
      qError("not supported physical node type %d", pNode->type);
×
2442
      return TSDB_CODE_APP_ERROR;
×
2443
  }
2444

2445
  return TSDB_CODE_SUCCESS;
347,244,540✔
2446
}
2447

2448
static int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t *level) {
347,219,807✔
2449
  if (NULL == pResNode) {
347,219,807✔
2450
    qError("explain res node is NULL");
×
2451
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2452
  }
2453

2454
  int32_t code = 0;
347,219,807✔
2455
  QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
347,219,807✔
2456

2457
  SNode *pNode = NULL;
347,233,891✔
2458
  FOREACH(pNode, pResNode->pChildren) { 
537,501,646✔
2459
    int32_t nlevel = *level + 1;
190,266,570✔
2460
    QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, &nlevel)); 
190,266,570✔
2461
  }
2462

2463
  return TSDB_CODE_SUCCESS;
347,235,076✔
2464
}
2465

2466
static int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t *level, bool grpSingleChannel) {
155,315,004✔
2467
  SExplainResNode *node = NULL;
155,315,004✔
2468
  int32_t          code = 0;
155,315,004✔
2469
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
155,315,004✔
2470

2471
  SExplainGroup *group = taosHashGet(ctx->pCurrPlanCtx->groupHash, &groupId, sizeof(groupId));
155,315,004✔
2472
  if (NULL == group) {
155,329,845✔
2473
    qError("group %d not in groupHash", groupId);
×
2474
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2475
  }
2476

2477
  group->singleChannel = grpSingleChannel;
155,329,845✔
2478
  group->physiPlanExecIdx = 0;
155,329,845✔
2479

2480
  QRY_ERR_RET(qExplainGenerateResNode(group->plan, group->plan->pNode, group, &node));
155,329,845✔
2481

2482
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
155,328,114✔
2483

2484
_return:
155,321,859✔
2485

2486
  qExplainFreeResNode(node);
155,321,859✔
2487

2488
  QRY_RET(code);
155,328,546✔
2489
}
2490

2491
/**
2492
  @brief Append explain rows for one group filtered by exchange children vgIds.
2493
*/
2494
static int32_t qExplainAppendGroupResRowsByVgIds(void *pCtx, int32_t groupId, int32_t *level,
1,650,729✔
2495
                                                 bool grpSingleChannel, const SArray* pVgIds) {
2496
  SExplainResNode *node = NULL;
1,650,729✔
2497
  int32_t          code = 0;
1,650,729✔
2498
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
1,650,729✔
2499
  SExplainGroup    filtered = {0};
1,650,729✔
2500

2501
  SExplainGroup *group = taosHashGet(ctx->pCurrPlanCtx->groupHash, &groupId, sizeof(groupId));
1,650,729✔
2502
  if (NULL == group) {
1,650,729✔
2503
    qError("%s failed at line %d, group %d not in groupHash",
×
2504
           __func__, __LINE__, groupId);
2505
    QRY_ERR_RET(TSDB_CODE_INTERNAL_ERROR);
×
2506
  }
2507

2508
  filtered.plan = group->plan;
1,650,729✔
2509
  filtered.singleChannel = false;
1,650,729✔
2510
  filtered.physiPlanExecIdx = 0;
1,650,729✔
2511

2512
  if (group->nodeExecInfo && pVgIds) {
1,650,729✔
2513
    int32_t rspCnt = (int32_t)taosArrayGetSize(group->nodeExecInfo);
1,650,729✔
2514
    filtered.nodeExecInfo = taosArrayInit(rspCnt, sizeof(SExplainRsp));
1,650,729✔
2515
    if (NULL == filtered.nodeExecInfo) {
1,650,729✔
2516
      QRY_ERR_RET(terrno);
×
2517
    }
2518

2519
    for (int32_t i = 0; i < rspCnt; ++i) {
6,027,119✔
2520
      const SExplainRsp *pRsp = taosArrayGet(group->nodeExecInfo, i);
4,376,390✔
2521
      if (!qExplainRspMatchVgIds(pRsp, pVgIds)) {
4,376,390✔
2522
        continue;
2,493,708✔
2523
      }
2524
      if (NULL == taosArrayPush(filtered.nodeExecInfo, pRsp)) {
3,765,364✔
2525
        QRY_ERR_JRET(terrno);
×
2526
      }
2527
    }
2528

2529
    filtered.nodeNum = (int32_t)taosArrayGetSize(filtered.nodeExecInfo);
1,650,729✔
2530
  } else {
2531
    filtered.nodeNum = group->nodeNum;
×
2532
    filtered.nodeExecInfo = group->nodeExecInfo;
×
2533
    filtered.singleChannel = grpSingleChannel;
×
2534
  }
2535

2536
  if (filtered.nodeNum <= 0) {
1,650,729✔
2537
    goto _return;
×
2538
  }
2539

2540
  QRY_ERR_RET(qExplainGenerateResNode(filtered.plan, filtered.plan->pNode, &filtered, &node));
1,650,729✔
2541
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
1,650,729✔
2542

2543
_return:
1,650,729✔
2544
  qExplainFreeResNode(node);
1,650,729✔
2545
  if (filtered.nodeExecInfo != group->nodeExecInfo) {
1,650,729✔
2546
    taosArrayDestroy(filtered.nodeExecInfo);
1,650,729✔
2547
  }
2548
  QRY_RET(code);
1,650,729✔
2549
}
2550

2551
static int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
31,336,780✔
2552
  int32_t      code = 0;
31,336,780✔
2553
  SSDataBlock *pBlock = NULL;
31,336,780✔
2554
  SExplainCtx *pCtx = (SExplainCtx *)ctx;
31,336,780✔
2555
  int32_t      rowNum = taosArrayGetSize(pCtx->rows);
31,336,780✔
2556
  if (rowNum <= 0) {
31,337,412✔
2557
    qError("empty explain res rows");
×
2558
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2559
  }
2560

2561
  code = createDataBlock(&pBlock);
31,337,412✔
2562
  QRY_ERR_JRET(code);
31,337,414✔
2563

2564
  SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, TSDB_EXPLAIN_RESULT_ROW_SIZE, 1);
31,337,414✔
2565
  QRY_ERR_JRET(blockDataAppendColInfo(pBlock, &infoData));
31,336,638✔
2566
  QRY_ERR_JRET(blockDataEnsureCapacity(pBlock, rowNum));
31,336,433✔
2567

2568
  SColumnInfoData *pInfoData = taosArrayGet(pBlock->pDataBlock, 0);
31,334,707✔
2569

2570
  for (int32_t i = 0; i < rowNum; ++i) {
763,204,522✔
2571
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
731,869,450✔
2572
    QRY_ERR_JRET(colDataSetVal(pInfoData, i, row->buf, false));
731,871,331✔
2573
  }
2574

2575
  pBlock->info.rows = rowNum;
31,335,072✔
2576

2577
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
31,335,072✔
2578
  int32_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
31,333,944✔
2579

2580
  SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
31,333,944✔
2581
  if (NULL == rsp) {
31,335,418✔
2582
    qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
×
2583
    QRY_ERR_JRET(terrno);
×
2584
  }
2585

2586
  rsp->completed = 1;
31,335,418✔
2587
  rsp->numOfRows = htobe64((int64_t)rowNum);
31,335,418✔
2588

2589
  int32_t len = blockEncode(pBlock, rsp->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, taosArrayGetSize(pBlock->pDataBlock));
31,336,519✔
2590
  if(len < 0) {
31,332,350✔
2591
    qError("qExplainGetRspFromCtx: blockEncode failed");
×
2592
    QRY_ERR_JRET(terrno);
×
2593
  }
2594

2595
  rsp->compLen = htonl(len);
31,333,141✔
2596
  rsp->payloadLen = htonl(len);
31,333,141✔
2597
  rsp->compressed = 0;
31,333,141✔
2598

2599
  SET_PAYLOAD_LEN(rsp->data, len, len);
31,333,141✔
2600

2601
_return:
31,333,141✔
2602
  blockDataDestroy(pBlock);
31,333,141✔
2603

2604
  *pRsp = rsp;
31,336,592✔
2605
  QRY_RET(code);
31,336,592✔
2606
}
2607

2608
static int32_t qExplainBuildPlanCtx(SQueryPlan *pDag, SExplainPlanCtx *pCtx) {
147,593,627✔
2609
  int32_t        code = 0;
147,593,627✔
2610
  SNodeListNode *plans = NULL;
147,593,627✔
2611
  int32_t        taskNum = 0;
147,593,627✔
2612
  SExplainGroup *pGroup = NULL;
147,593,627✔
2613

2614
  if (pDag->numOfSubplans <= 0) {
147,593,627✔
2615
    qError("invalid subplan num:%d", pDag->numOfSubplans);
×
2616
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
2,984✔
2617
  }
2618

2619
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
147,596,611✔
2620
  if (levelNum <= 0) {
147,596,611✔
2621
    qError("invalid level num:%d", levelNum);
×
2622
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2623
  }
2624

2625
  pCtx->groupHash = taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT),
147,596,611✔
2626
                                 false, HASH_NO_LOCK);
2627
  if (NULL == pCtx->groupHash) {
147,606,030✔
2628
    qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
×
2629
    QRY_ERR_RET(terrno);
×
2630
  }
2631

2632
  int32_t i = 0;
147,603,692✔
2633
  SNode*  levelNode = NULL;
147,603,692✔
2634
  FOREACH(levelNode, pDag->pSubplans) {
353,136,471✔
2635
    plans = (SNodeListNode *)levelNode;
205,528,354✔
2636
    if (NULL == plans) {
205,528,354✔
2637
      qError("empty level plan, level:%d", i);
×
2638
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2639
    }
2640

2641
    taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
205,525,514✔
2642
    if (taskNum <= 0) {
205,525,514✔
2643
      qError("invalid level plan number:%d, level:%d", taskNum, i);
×
2644
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2645
    }
2646

2647
    SSubplan *plan = NULL;
205,521,625✔
2648
    int32_t   n = 0;
205,521,625✔
2649
    SNode*    taskNode = NULL;
205,521,625✔
2650
    FOREACH(taskNode, plans->pNodeList) {
485,271,592✔
2651
      plan = (SSubplan *)taskNode;
279,730,699✔
2652
      pGroup = taosHashGet(pCtx->groupHash, &plan->id.groupId, sizeof(plan->id.groupId));
279,730,699✔
2653
      if (pGroup) {
279,734,778✔
2654
        ++pGroup->nodeNum;
49,215,205✔
2655
        ++n;
49,215,205✔
2656
        continue;
49,215,205✔
2657
      }
2658

2659
      SExplainGroup group = {0};
230,519,573✔
2660
      group.nodeNum = 1;
230,519,573✔
2661
      group.plan = plan;
230,519,573✔
2662

2663
      if (0 != taosHashPut(pCtx->groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
230,519,573✔
2664
        qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
×
2665
        QRY_ERR_JRET(terrno);
×
2666
      }
2667
      ++n;
230,534,762✔
2668
    }
2669

2670
    if (0 == i) {
205,540,893✔
2671
      if (taskNum > 1) {
147,605,865✔
2672
        qError("invalid taskNum %d for level 0", taskNum);
×
UNCOV
2673
        QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2674
      }
2675

2676
      pCtx->rootGroupId = plan->id.groupId;
147,604,014✔
2677
    }
2678

2679
    qDebug("level %d group handled, taskNum:%d", i, taskNum);
205,539,042✔
2680
    ++i;
205,532,779✔
2681
  }
2682

2683
  pCtx->groupNum = taosHashGetSize(pCtx->groupHash);
147,608,117✔
2684

2685
  return TSDB_CODE_SUCCESS;
147,602,474✔
2686

2687
_return:
×
2688

2689
  if (code) {
×
2690
    qError("QID:0x%" PRIx64 " %s failed since %s", pDag->queryId, __func__, tstrerror(code));
×
2691
  }
2692
  
2693
  QRY_RET(code);
×
2694
}
2695

2696
static int32_t qExplainBuildCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
45,911,924✔
2697
  int32_t        code = 0;
45,911,924✔
2698
  SNodeListNode *plans = NULL;
45,911,924✔
2699
  int32_t        taskNum = 0;
45,911,924✔
2700
  SExplainGroup *pGroup = NULL;
45,911,924✔
2701
  SExplainCtx   *ctx = NULL;
45,911,924✔
2702

2703
  if (pDag->numOfSubplans <= 0) {
45,911,924✔
2704
    qError("invalid subplan num:%d", pDag->numOfSubplans);
×
2705
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
43✔
2706
  }
2707

2708
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
45,911,894✔
2709
  if (levelNum <= 0) {
45,911,894✔
2710
    qError("invalid level num:%d", levelNum);
×
2711
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2712
  }
2713

2714
  QRY_ERR_JRET(qExplainInitCtx(&ctx, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
45,911,894✔
2715

2716
  QRY_ERR_JRET(qExplainBuildPlanCtx(pDag, &ctx->planCtx));
45,926,139✔
2717
  ctx->groupNum = ctx->planCtx.groupNum;
45,916,327✔
2718

2719
  if (pDag->pChildren && pDag->pChildren->length > 0) {
45,916,327✔
2720
    ctx->subPlanCtxs = taosArrayInit_s(sizeof(SExplainPlanCtx), pDag->pChildren->length);
33,865,124✔
2721
    if (NULL == ctx->subPlanCtxs) {
33,880,712✔
2722
      qError("taosArrayInit %d explainPlanCtx failed, error:%s", pDag->pChildren->length, tstrerror(terrno));
×
2723
      QRY_ERR_JRET(terrno);
×
2724
    }
2725
    
2726
    SNode* pNode = NULL;
33,871,667✔
2727
    int32_t i = 0;
33,871,667✔
2728
    FOREACH(pNode, pDag->pChildren) {
135,552,392✔
2729
      SExplainPlanCtx* pSub = taosArrayGet(ctx->subPlanCtxs, i);
101,675,365✔
2730
      QRY_ERR_JRET(qExplainBuildPlanCtx((SQueryPlan*)pNode, pSub));
101,674,035✔
2731
      ctx->groupNum += pSub->groupNum;
101,680,725✔
2732
      i++;
101,680,725✔
2733
    }
2734
  }
2735

2736
  *pCtx = ctx;
45,928,230✔
2737

2738
  return TSDB_CODE_SUCCESS;
45,928,230✔
2739

2740
_return:
×
2741

2742
  qExplainFreeCtx(ctx);
×
2743

2744
  QRY_RET(code);
×
2745
}
2746

2747
static int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
31,337,737✔
2748
  if (EXPLAIN_MODE_ANALYZE != pCtx->mode) {
31,337,737✔
2749
    return TSDB_CODE_SUCCESS;
30,314,733✔
2750
  }
2751

2752
  int32_t tlen = 0;
1,023,004✔
2753
  char   *tbuf = pCtx->tbuf;
1,023,004✔
2754

2755
  // NOTE: remove comment after RATIO is implemented
2756
  // EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
2757
  // EXPLAIN_SUM_ROW_END();
2758
  // QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
2759

2760
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_PLANNING_TIME_FORMAT,
1,023,004✔
2761
    EXPLAIN_CONVERT_TS_US_TO_MS(pCtx->jobStartTs - pCtx->reqStartTs));
2762
  EXPLAIN_SUM_ROW_END();
1,023,004✔
2763
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
1,023,004✔
2764

2765
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_EXEC_TIME_FORMAT,
1,023,004✔
2766
    EXPLAIN_CONVERT_TS_US_TO_MS(pCtx->jobDoneTs - pCtx->jobStartTs));
2767
  EXPLAIN_SUM_ROW_END();
1,023,004✔
2768
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
1,023,004✔
2769

2770
  return TSDB_CODE_SUCCESS;
1,023,004✔
2771
}
2772

2773
static int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
31,333,952✔
2774
  int32_t level = 0;
31,333,952✔
2775
  
2776
  pCtx->currPlanId = -1;
31,333,952✔
2777
  pCtx->pCurrPlanCtx = &pCtx->planCtx;
31,333,952✔
2778
  QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->pCurrPlanCtx->rootGroupId, &level, false));
31,333,952✔
2779
  
2780
  if (pCtx->subPlanCtxs) {
31,336,295✔
2781
    int32_t subNum = taosArrayGetSize(pCtx->subPlanCtxs);
19,292,177✔
2782
    for (pCtx->currPlanId = subNum - 1; pCtx->currPlanId >= 0; --pCtx->currPlanId) {
76,998,117✔
2783
      pCtx->pCurrPlanCtx = taosArrayGet(pCtx->subPlanCtxs, pCtx->currPlanId);
57,701,189✔
2784
      level = 0;
57,701,042✔
2785
      QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->pCurrPlanCtx->rootGroupId, &level, false));
57,701,042✔
2786
    }
2787
  }
2788
  QRY_ERR_RET(qExplainAppendPlanRows(pCtx));
31,341,046✔
2789
  QRY_ERR_RET(qExplainGetRspFromCtx(pCtx, pRsp));
31,337,737✔
2790

2791
  return TSDB_CODE_SUCCESS;
31,335,145✔
2792
}
2793

2794
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainPlanCtx *pCurrPlanCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
73,573,846✔
2795
  if (!pCtx || !pCurrPlanCtx || !pRspMsg || !pRsp) return TSDB_CODE_INVALID_PARA;
73,573,846✔
2796
  SExplainResNode *node = NULL;
73,582,822✔
2797
  int32_t          code = 0;
73,582,822✔
2798
  bool             groupDone = false;
73,582,822✔
2799

2800
  SExplainGroup *group = taosHashGet(pCurrPlanCtx->groupHash, &groupId, sizeof(groupId));
73,582,822✔
2801
  if (NULL == group) {
73,585,917✔
2802
    qError("group %d not in groupHash", groupId);
×
2803
    tFreeSExplainRsp(pRspMsg);
×
2804
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2805
  }
2806

2807
  taosWLockLatch(&group->lock);
73,585,917✔
2808
  if (NULL == group->nodeExecInfo) {
73,587,617✔
2809
    group->nodeExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainRsp));
64,158,967✔
2810
    if (NULL == group->nodeExecInfo) {
64,156,841✔
2811
      qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
2812
      code = terrno;
×
2813
      TAOS_CHECK_ERRNO(code);
×
2814
    }
2815

2816
    group->physiPlanExecNum = pRspMsg->numOfPlans;
64,155,807✔
2817
  } else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
9,428,650✔
2818
    qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo),
×
2819
           group->nodeNum);
2820
    code = TSDB_CODE_APP_ERROR;
×
2821
    TAOS_CHECK_ERRNO(code);
×
2822
  }
2823

2824
  if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
73,584,880✔
2825
    qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum,
×
2826
           groupId);
2827
    code = TSDB_CODE_APP_ERROR;
×
2828
    TAOS_CHECK_ERRNO(code);
×
2829
  }
2830

2831
  if(taosArrayPush(group->nodeExecInfo, pRspMsg) == NULL)
147,165,876✔
2832
  {
2833
    code = terrno;
×
2834
    TAOS_CHECK_ERRNO(code);
×
2835
  }
2836

2837
  groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
73,581,385✔
2838

2839
  taosWUnLockLatch(&group->lock);
73,578,307✔
2840

2841
  if (groupDone && (pCtx->groupNum == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
73,586,601✔
2842
    if (atomic_load_8((int8_t *)&pCtx->execDone)) {
9,030,528✔
2843
      if (0 == taosWTryLockLatch(&pCtx->lock)) {
4,460✔
2844
        QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
4,460✔
2845
        // LEAVE LOCK THERE
2846
      }
2847
    }
2848
  }
2849

2850
  return TSDB_CODE_SUCCESS;
73,583,994✔
2851

2852
_exit:
×
2853
  tFreeSExplainRsp(pRspMsg);
×
2854
  taosWUnLockLatch(&group->lock);
×
2855
  return code;
×
2856
}
2857

2858
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
30,301,537✔
2859
  if (!pDag || !pRsp) return TSDB_CODE_INVALID_PARA;
30,301,537✔
2860
  int32_t      code = 0;
30,309,619✔
2861
  SExplainCtx *pCtx = NULL;
30,309,619✔
2862

2863
  QRY_ERR_RET(qExplainBuildCtx(pDag, &pCtx));
30,309,619✔
2864
  QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
30,314,756✔
2865

2866
_return:
30,311,791✔
2867
  qExplainFreeCtx(pCtx);
30,311,791✔
2868
  QRY_RET(code);
30,314,814✔
2869
}
2870

2871
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
15,610,466✔
2872
  if(!pDag || !pCtx) return TSDB_CODE_INVALID_PARA;
15,610,466✔
2873
  QRY_ERR_RET(qExplainBuildCtx(pDag, pCtx));
15,612,694✔
2874

2875
  (*pCtx)->reqStartTs = startTs;
15,613,784✔
2876
  (*pCtx)->jobStartTs = taosGetTimestampUs();
16,638,396✔
2877

2878
  return TSDB_CODE_SUCCESS;
15,613,486✔
2879
}
2880

2881
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
1,023,004✔
2882
  if(!pCtx || !pRsp) {
1,023,004✔
2883
    return TSDB_CODE_INVALID_PARA;
×
2884
  }
2885
  
2886
  int32_t code = 0;
1,023,004✔
2887
  pCtx->jobDoneTs = taosGetTimestampUs();
1,023,004✔
2888

2889
  atomic_store_8((int8_t *)&pCtx->execDone, true);
1,023,004✔
2890

2891
  if (pCtx->groupNum == atomic_load_32(&pCtx->groupDoneNum)) {
1,023,004✔
2892
    if (0 == taosWTryLockLatch(&pCtx->lock)) {
1,018,544✔
2893
      QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
1,018,544✔
2894
      // LEAVE LOCK THERE
2895
    }
2896
  }
2897

2898
  return TSDB_CODE_SUCCESS;
1,023,004✔
2899
}
2900

2901
SExplainPlanCtx* qExplainGetCurrPlan(SExplainCtx *pCtx, int32_t subJobId) {
73,571,551✔
2902
  return EXPLAIN_GET_CUR_PLAN_CTX(pCtx, subJobId);
73,571,551✔
2903
}
2904

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