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

taosdata / TDengine / #5050

12 May 2026 05:36AM UTC coverage: 73.398% (+0.09%) from 73.313%
#5050

push

travis-ci

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

90 of 101 new or added lines in 2 files covered. (89.11%)

489 existing lines in 125 files now uncovered.

281602 of 383662 relevant lines covered (73.4%)

138099127.08 hits per line

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

82.94
/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,317,937✔
50
  if (NULL == pDyn) {
1,317,937✔
51
    return "unknown task";
×
52
  }
53

54
  switch (pDyn->qType) {
1,317,937✔
55
    case DYN_QTYPE_STB_HASH:
835,297✔
56
      return "STable Join";
835,297✔
57
    case DYN_QTYPE_VTB_SCAN:
134,057✔
58
      return "Virtual Stable Scan";
134,057✔
59
    case DYN_QTYPE_VTB_WINDOW:
94,089✔
60
      return "Virtual Table Window";
94,089✔
61
    case DYN_QTYPE_VTB_INTERVAL:
4,938✔
62
      return "Virtual Stable Interval";
4,938✔
63
    case DYN_QTYPE_VTB_AGG:
228,992✔
64
      return "Virtual Stable Agg";
228,992✔
65
    case DYN_QTYPE_VTB_TS_SCAN:
20,564✔
66
      return "Virtual Stable Ts Scan";
20,564✔
67
    default:
×
68
      break;
×
69
  }
70

71
  return "unknown task";
×
72
}
73

74
char* qExplainGetAsofOpStr(int32_t opType) {
49,952✔
75
  switch (opType) {
49,952✔
76
    case OP_TYPE_GREATER_THAN:
1,784✔
77
      return ">";
1,784✔
78
    case OP_TYPE_GREATER_EQUAL:
8,028✔
79
      return ">=";
8,028✔
80
    case OP_TYPE_LOWER_THAN:
×
81
      return "<";
×
82
    case OP_TYPE_LOWER_EQUAL:
8,028✔
83
      return "<=";
8,028✔
84
    case OP_TYPE_EQUAL:
32,112✔
85
      return "=";
32,112✔
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
/*
101
 * Build comma-separated STATE_WINDOW key names with graceful truncation.
102
 * The output always remains NUL-terminated and ends with "..." when truncated.
103
 */
104
static void qExplainBuildStateKeyDesc(const SNodeList* pStateKeys, char* pDesc, int32_t descSize) {
1,774,607✔
105
  if (NULL == pDesc || descSize <= 0) {
1,774,607✔
106
    return;
×
107
  }
108

109
  pDesc[0] = '\0';
1,774,887✔
110
  if (NULL == pStateKeys || LIST_LENGTH(pStateKeys) <= 0) {
1,774,887✔
111
    tstrncpy(pDesc, "<unknown>", descSize);
×
112
    return;
×
113
  }
114

115
  size_t used = 0;
1,774,893✔
116
  bool   truncated = false;
1,774,893✔
117
  SNode* pKey = NULL;
1,774,893✔
118
  FOREACH(pKey, pStateKeys) {
3,570,292✔
119
    const char* pName = nodesGetNameFromColumnNode(pKey);
1,795,488✔
120
    if (NULL == pName || '\0' == pName[0]) {
1,795,398✔
121
      pName = "<unknown>";
1,420✔
122
    }
123

124
    bool   needSep = (used > 0);
1,795,398✔
125
    size_t sepLen = needSep ? 1 : 0;
1,795,398✔
126
    size_t nameLen = strlen(pName);
1,795,398✔
127
    size_t remain = (size_t)descSize - used;
1,795,398✔
128

129
    if (remain <= 1) {
1,795,398✔
130
      truncated = true;
×
131
      break;
×
132
    }
133

134
    if (sepLen + nameLen < remain) {
1,795,398✔
135
      if (needSep) {
1,795,399✔
136
        pDesc[used++] = ',';
20,601✔
137
      }
138
      (void)memcpy(pDesc + used, pName, nameLen);
1,795,399✔
139
      used += nameLen;
1,795,399✔
140
      pDesc[used] = '\0';
1,795,399✔
141
      continue;
1,795,399✔
142
    }
143

UNCOV
144
    if (needSep && remain > 1) {
×
145
      pDesc[used++] = ',';
×
146
      remain = (size_t)descSize - used;
×
147
    }
148

UNCOV
149
    if (remain <= 1) {
×
150
      truncated = true;
×
151
      break;
×
152
    }
153

UNCOV
154
    if (remain > 4) {
×
155
      size_t copyLen = remain - 4;
×
156
      (void)memcpy(pDesc + used, pName, copyLen);
×
157
      used += copyLen;
×
158
      (void)memcpy(pDesc + used, "...", 3);
×
159
      used += 3;
×
160
    } else {
UNCOV
161
      size_t dots = remain - 1;
×
UNCOV
162
      (void)memset(pDesc + used, '.', dots);
×
UNCOV
163
      used += dots;
×
164
    }
165

UNCOV
166
    pDesc[used] = '\0';
×
UNCOV
167
    truncated = true;
×
UNCOV
168
    break;
×
169
  }
170

171
  if ('\0' == pDesc[0]) {
1,774,803✔
172
    tstrncpy(pDesc, truncated ? "..." : "<unknown>", descSize);
×
173
  }
174
}
175

176
static bool qExplainRspMatchVgIds(const SExplainRsp* pRsp, const SArray* pVgIds) {
10,266,644✔
177
  if (NULL == pRsp || NULL == pVgIds || pRsp->numOfPlans <= 0 ||
10,266,644✔
178
      NULL == pRsp->subplanInfo) {
10,266,644✔
179
    return false;
×
180
  }
181

182
  int32_t vgCnt = (int32_t)taosArrayGetSize(pVgIds);
10,266,644✔
183
  for (int32_t subplanIdx = 0; subplanIdx < pRsp->numOfPlans; ++subplanIdx) {
16,774,712✔
184
    int32_t rspVgId = pRsp->subplanInfo[subplanIdx].vgId;
10,970,180✔
185
    for (int32_t vgIdx = 0; vgIdx < vgCnt; ++vgIdx) {
18,208,654✔
186
      const int32_t* pCurr = taosArrayGet(pVgIds, vgIdx);
11,700,586✔
187
      if (pCurr && *pCurr == rspVgId) {
11,700,586✔
188
        return true;
4,462,112✔
189
      }
190
    }
191
  }
192

193
  return false;
5,804,532✔
194
}
195

196
void qExplainFreeResNode(SExplainResNode *resNode) {
403,693,769✔
197
  if (NULL == resNode) {
403,693,769✔
198
    return;
×
199
  }
200

201
  taosArrayDestroy(resNode->pExecInfo);
403,693,769✔
202

203
  SNode *node = NULL;
403,698,164✔
204
  FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
624,882,704✔
205
  nodesClearList(resNode->pChildren);
403,701,450✔
206

207
  taosMemoryFreeClear(resNode);
403,696,167✔
208
}
209

210
void qExplainFreePlanCtx(SExplainPlanCtx* pCtx, bool isAnalyze) {
174,059,721✔
211
  if (isAnalyze && pCtx->groupHash) {
174,059,721✔
212
    void *pIter = taosHashIterate(pCtx->groupHash, NULL);
71,883,589✔
213
    while (pIter) {
180,035,915✔
214
      SExplainGroup *group = (SExplainGroup *)pIter;
108,153,318✔
215
      if (group->nodeExecInfo) {
108,153,318✔
216
        int32_t num = taosArrayGetSize(group->nodeExecInfo);
77,809,026✔
217
        for (int32_t i = 0; i < num; ++i) {
167,301,249✔
218
          SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
89,493,898✔
219
          tFreeSExplainRsp(rsp);
89,493,617✔
220
        }
221
        taosArrayDestroy(group->nodeExecInfo);
77,807,351✔
222
      }
223

224
      pIter = taosHashIterate(pCtx->groupHash, pIter);
108,153,131✔
225
    }
226
  }
227

228
  taosHashCleanup(pCtx->groupHash);
174,058,729✔
229
}
174,063,516✔
230

231
void qExplainFreeCtx(SExplainCtx *pCtx) {
1,288,026,415✔
232
  if (NULL == pCtx) {
1,288,026,415✔
233
    return;
1,234,232,085✔
234
  }
235

236
  int32_t rowSize = taosArrayGetSize(pCtx->rows);
53,794,330✔
237
  for (int32_t i = 0; i < rowSize; ++i) {
906,494,798✔
238
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
852,667,655✔
239
    taosMemoryFreeClear(row->buf);
852,676,483✔
240
  }
241

242
  qExplainFreePlanCtx(&pCtx->planCtx, EXPLAIN_MODE_ANALYZE == pCtx->mode);
53,827,143✔
243
  if (pCtx->subPlanCtxs) {
53,823,850✔
244
    int32_t subNum = taosArrayGetSize(pCtx->subPlanCtxs);
39,975,041✔
245
    for (int32_t i = 0; i < subNum; ++i) {
160,216,585✔
246
      SExplainPlanCtx *pSub = taosArrayGet(pCtx->subPlanCtxs, i);
120,240,791✔
247
      qExplainFreePlanCtx(pSub, EXPLAIN_MODE_ANALYZE == pCtx->mode);
120,240,700✔
248
    }
249
    taosArrayDestroy(pCtx->subPlanCtxs);
39,975,794✔
250
  }
251

252
  taosArrayDestroy(pCtx->rows);
53,824,603✔
253
  taosMemoryFreeClear(pCtx->tbuf);
53,825,071✔
254
  taosMemoryFree(pCtx);
53,824,617✔
255
}
256

257
static int32_t qExplainInitCtx(SExplainCtx **pCtx, bool verbose, double ratio, EExplainMode mode) {
53,796,760✔
258
  int32_t      code = 0;
53,796,760✔
259
  SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
53,796,760✔
260
  if (NULL == ctx) {
53,815,570✔
261
    qError("calloc SExplainCtx failed");
×
262
    QRY_ERR_JRET(terrno);
×
263
  }
264

265
  SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo));
53,815,570✔
266
  if (NULL == rows) {
53,815,366✔
267
    qError("taosArrayInit SQueryExplainRowInfo failed");
×
268
    QRY_ERR_JRET(terrno);
×
269
  }
270

271
  char *tbuf = taosMemoryMalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE);
53,815,366✔
272
  if (NULL == tbuf) {
53,824,155✔
273
    qError("malloc size %d failed", TSDB_EXPLAIN_RESULT_ROW_SIZE);
×
274
    QRY_ERR_JRET(terrno);
×
275
  }
276

277
  ctx->mode = mode;
53,824,155✔
278
  ctx->verbose = verbose;
53,824,155✔
279
  ctx->ratio = ratio;
53,824,155✔
280
  ctx->tbuf = tbuf;
53,824,155✔
281
  ctx->rows = rows;
53,824,155✔
282

283
  *pCtx = ctx;
53,824,155✔
284

285
  return TSDB_CODE_SUCCESS;
53,824,155✔
286

287
_return:
×
288

289
  taosArrayDestroy(rows);
×
290
  taosMemoryFree(ctx);
×
291

292
  QRY_RET(code);
×
293
}
294

295
static int32_t qExplainGenerateResChildren(SSubplan *plan, SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
403,709,402✔
296
  int32_t    tlen = 0;
403,709,402✔
297
  SNodeList *pPhysiChildren = pNode->pChildren;
403,709,402✔
298

299
  if (pPhysiChildren) {
403,709,402✔
300
    int32_t code = nodesMakeList(pChildren);
195,749,927✔
301
    if (NULL == *pChildren) {
195,753,258✔
302
      qError("nodesMakeList failed");
×
303
      QRY_ERR_RET(code);
26,454✔
304
    }
305
  }
306

307
  SNode           *node = NULL;
403,739,187✔
308
  SExplainResNode *pResNode = NULL;
403,739,187✔
309
  FOREACH(node, pPhysiChildren) {
624,934,641✔
310
    QRY_ERR_RET(qExplainGenerateResNode(plan, (SPhysiNode *)node, group, &pResNode));
221,188,598✔
311
    QRY_ERR_RET(nodesListAppend(*pChildren, (SNode *)pResNode));
221,185,088✔
312
  }
313

314
  return TSDB_CODE_SUCCESS;
403,746,043✔
315
}
316

317
static int32_t qExplainGenerateResNodeExecInfo(SPhysiNode *pNode, SArray **pExecInfo, SExplainGroup *group) {
7,440,649✔
318
  *pExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainExecInfo));
7,440,649✔
319
  if (NULL == (*pExecInfo)) {
7,440,649✔
320
    qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
321
    return terrno;
×
322
  }
323

324
  SExplainRsp *rsp = NULL;
7,440,649✔
325
  if (group->singleChannel) {
7,440,649✔
326
    if (0 == group->physiPlanExecIdx) {
×
327
      group->nodeIdx = 0;
×
328
    }
329

330
    rsp = taosArrayGet(group->nodeExecInfo, group->nodeIdx++);
×
331
    if (group->physiPlanExecIdx >= rsp->numOfPlans) {
×
332
      qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
×
333
      return TSDB_CODE_APP_ERROR;
×
334
    }
335

336
    if(taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx) == NULL) return terrno;
×
337
  } else {
338
    for (int32_t i = 0; i < group->nodeNum; ++i) {
15,416,414✔
339
      rsp = taosArrayGet(group->nodeExecInfo, i);
7,975,765✔
340
      if (group->physiPlanExecIdx >= rsp->numOfPlans) {
7,975,765✔
341
        qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
×
342
        return TSDB_CODE_APP_ERROR;
×
343
      }
344

345
      if(taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx) == NULL) return terrno;
15,951,530✔
346
    }
347
  }
348

349
  ++group->physiPlanExecIdx;
7,440,649✔
350

351
  return TSDB_CODE_SUCCESS;
7,440,649✔
352
}
353

354
static int32_t qExplainGenerateResNode(SSubplan *plan, SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pResNode) {
403,688,809✔
355
  if (NULL == pNode) {
403,688,809✔
356
    *pResNode = NULL;
×
357
    qError("physical node is NULL");
×
358
    return TSDB_CODE_APP_ERROR;
×
359
  }
360

361
  SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
403,688,809✔
362
  if (NULL == resNode) {
403,721,532✔
363
    qError("calloc SPhysiNodeExplainRes failed");
×
364
    return terrno;
×
365
  }
366

367
  int32_t code = 0;
403,721,532✔
368
  resNode->pNode = pNode;
403,721,532✔
369
  resNode->pPlan = plan;
403,721,532✔
370

371
  if (group->nodeExecInfo) {
403,721,532✔
372
    QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(pNode, &resNode->pExecInfo, group));
7,440,649✔
373
  }
374

375
  QRY_ERR_JRET(qExplainGenerateResChildren(plan, pNode, group, &resNode->pChildren));
403,721,532✔
376

377
  *pResNode = resNode;
403,706,797✔
378

379
  return TSDB_CODE_SUCCESS;
403,706,797✔
380

381
_return:
×
382

383
  qExplainFreeResNode(resNode);
×
384

385
  QRY_RET(code);
×
386
}
387

388
static int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf,
7,440,649✔
389
                                         int32_t *len, double* filterEfficiency) {
390
  int32_t          tlen = *len;
7,440,649✔
391
  size_t           nodeNum = taosArrayGetSize(pExecInfo);  // num of total nodes
7,440,649✔
392
  size_t           numNoData = 0;  // num of nodes with no data
7,440,649✔
393
  SExplainExecInfo execInfo = {0};
7,440,649✔
394
  SExplainExecInfo maxExecInfo = {0};
7,440,649✔
395

396
  for (int32_t i = 0; i < nodeNum; ++i) {
15,416,414✔
397
    const SExplainExecInfo *pExec = taosArrayGet(pExecInfo, i);
7,975,765✔
398
    execInfo.execFirstRow += pExec->execFirstRow;
7,975,765✔
399
    execInfo.execLastRow += pExec->execLastRow;
7,975,765✔
400
    execInfo.numOfRows += pExec->numOfRows;
7,975,765✔
401
    execInfo.inputRows += pExec->inputRows;
7,975,765✔
402

403
    maxExecInfo.execFirstRow = TMAX(maxExecInfo.execFirstRow, pExec->execFirstRow);
7,975,765✔
404
    maxExecInfo.execLastRow = TMAX(maxExecInfo.execLastRow, pExec->execLastRow);
7,975,765✔
405
    maxExecInfo.numOfRows = TMAX(maxExecInfo.numOfRows, pExec->numOfRows);
7,975,765✔
406
  }
407
  *filterEfficiency = execInfo.inputRows > 0 ?
7,454,473✔
408
                      (double)execInfo.numOfRows * 100.0 / (double)execInfo.inputRows : 100.0;
7,440,649✔
409

410
  if (nodeNum == 1 || numNoData == nodeNum) {
7,440,649✔
411
    EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execFirstRow),
6,935,847✔
412
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execLastRow), execInfo.numOfRows);
413
  } else if (nodeNum > 1) {
504,802✔
414
    EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT_EXT,
504,802✔
415
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execFirstRow) / nodeNum,
416
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execFirstRow),
417
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execLastRow) / nodeNum,
418
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execLastRow),
419
                       (double)execInfo.numOfRows / nodeNum,
420
                       maxExecInfo.numOfRows);
421
  }
422

423
  *len = tlen;
7,440,649✔
424
  return TSDB_CODE_SUCCESS;
7,440,649✔
425
}
426

427
static int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
852,570,421✔
428
  SQueryExplainRowInfo row = {0};
852,570,421✔
429
  row.buf = taosMemoryMalloc(len);
852,570,421✔
430
  if (NULL == row.buf) {
852,609,951✔
431
    qError("taosMemoryMalloc %d failed", len);
×
432
    QRY_ERR_RET(terrno);
×
433
  }
434

435
  memcpy(row.buf, tbuf, len);
852,609,951✔
436
  row.level = level;
852,609,951✔
437
  row.len = len;
852,609,951✔
438
  ctx->dataSize += row.len;
852,609,951✔
439

440
  if (NULL == taosArrayPush(ctx->rows, &row)) {
1,705,153,317✔
441
    qError("taosArrayPush row to explain res rows failed");
×
442
    taosMemoryFree(row.buf);
×
443
    QRY_ERR_RET(terrno);
×
444
  }
445

446
  return TSDB_CODE_SUCCESS;
852,543,229✔
447
}
448

449
static int32_t qExplainAppendFilterRow(SExplainCtx *ctx, int32_t level,
171,769,896✔
450
                                       SNode *pConditions, int32_t *pLen,
451
                                       const double *pFilterEfficiency) {
452
  if (NULL == pConditions) {
171,769,896✔
453
    return TSDB_CODE_SUCCESS;
162,660,180✔
454
  }
455

456
  int32_t tlen = *pLen;
9,109,716✔
457
  char   *tbuf = ctx->tbuf;
9,109,716✔
458
  bool    isVerboseLine = true;
9,109,716✔
459

460
  EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
9,109,716✔
461
  EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
9,109,716✔
462
  QRY_ERR_RET(nodesNodeToSQL(pConditions, tbuf + VARSTR_HEADER_SIZE,
9,109,716✔
463
                             TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
464
  if (pFilterEfficiency != NULL) {
9,111,349✔
465
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
58,963✔
466
    EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_EFFICIENCY_FORMAT, *pFilterEfficiency);
58,963✔
467
  }
468
  EXPLAIN_ROW_END();
9,111,349✔
469

470
  *pLen = tlen;
9,111,349✔
471
  return qExplainResAppendRow(ctx, tbuf, tlen, level + 1);
9,111,349✔
472
}
473

474
static uint8_t qExplainGetIntervalPrecision(SIntervalPhysiNode *pIntNode) {
6,057,026✔
475
  return ((SColumnNode *)pIntNode->window.pTspk)->node.resType.precision;
6,057,026✔
476
}
477

478
static char* qExplainGetScanMode(STableScanPhysiNode* pScan) {
129,490,615✔
479
  bool isGroupByTbname = false;
129,490,615✔
480
  bool isGroupByTag = false;
129,490,615✔
481
  bool seq = false;
129,490,615✔
482
  bool groupOrder = false;
129,490,615✔
483
  if (pScan->pGroupTags && LIST_LENGTH(pScan->pGroupTags) == 1) {
129,490,615✔
484
    SNode* p = nodesListGetNode(pScan->pGroupTags, 0);
3,720,022✔
485
    if (QUERY_NODE_FUNCTION == nodeType(p) && (strcmp(((struct SFunctionNode*)p)->functionName, "tbname") == 0)) {
3,720,100✔
486
      isGroupByTbname = true;
3,555,991✔
487
    }
488
  }
489

490
  isGroupByTag = (NULL != pScan->pGroupTags) && !isGroupByTbname;
129,490,693✔
491
  if ((((!isGroupByTag) || isGroupByTbname) && pScan->groupSort) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
129,490,693✔
492
    return "seq_grp_order";
30,040✔
493
  }
494

495
  if ((isGroupByTbname && (pScan->groupSort || pScan->scan.groupOrderScan)) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
129,460,653✔
496
    return "grp_order";
2,325✔
497
  }
498

499
  return "ts_order";
129,458,328✔
500
}
501

502
static char* qExplainGetScanDataLoad(STableScanPhysiNode* pScan) {
129,495,874✔
503
  switch (pScan->dataRequired) {
129,495,874✔
504
    case FUNC_DATA_REQUIRED_DATA_LOAD:
120,958,375✔
505
      return "data";
120,958,375✔
506
    case FUNC_DATA_REQUIRED_SMA_LOAD:
6,629,309✔
507
      return "sma";
6,629,309✔
508
    case FUNC_DATA_REQUIRED_NOT_LOAD:
1,909,864✔
509
      return "no";
1,909,864✔
510
    default:
×
511
      break;
×
512
  }
513

514
  return "unknown";
×
515
}
516

517
static EDealRes qExplainVerifyIndex(SNode* pNode, void* pContext) {
162,052✔
518
  if (NULL == pNode) {
162,052✔
519
    return DEAL_RES_CONTINUE;
×
520
  }
521

522
  switch (nodeType(pNode)) {
162,052✔
523
    case QUERY_NODE_COLUMN:
99,708✔
524
    case QUERY_NODE_VALUE:
525
    case QUERY_NODE_LOGIC_CONDITION:
526
    case QUERY_NODE_NODE_LIST:
527
      break;
99,708✔
528
    case QUERY_NODE_OPERATOR: {
59,980✔
529
      SOperatorNode* pOp = (SOperatorNode*)pNode;
59,980✔
530
      if ((pOp->opType >= OP_TYPE_GREATER_THAN && pOp->opType <= OP_TYPE_EQUAL) || (OP_TYPE_IN == pOp->opType)) {
59,980✔
531
        break;
532
      }
533
      // fall through
534
    }
535
    default:
536
      *(bool*)pContext = false;
14,006✔
537
      return DEAL_RES_END;
14,006✔
538
  }
539

540
  return DEAL_RES_CONTINUE;
148,046✔
541
}
542

543
static bool qExplainCouldApplyTagIndex(SSubplan* pPlan) {
59,990,146✔
544
  if (NULL == pPlan->pTagIndexCond) {
59,990,146✔
545
    return false;
59,936,125✔
546
  }
547

548
  bool couldApply = true;
55,252✔
549
  nodesWalkExpr(pPlan->pTagIndexCond, qExplainVerifyIndex, &couldApply);
55,252✔
550

551
  return couldApply;
55,252✔
552
}
553

554
/**
555
 @brief Compare the execution time of two explain execution information
556
 by execElapsed in ascending order.
557
*/
558
static int32_t compareExecInfo(const void* p1, const void* p2) {
233,812✔
559
  const SExplainExecInfo* p11 = (const SExplainExecInfo*)p1;
233,812✔
560
  const SExplainExecInfo* p22 = (const SExplainExecInfo*)p2;
233,812✔
561

562
  return p11->execElapsed <= p22->execElapsed ? -1 : 1;
233,812✔
563
}
564

565
static int32_t qExplainExecAnalyze(const SExplainResNode *pResNode,
173,617,281✔
566
                                   SExplainCtx *ctx, int32_t level) {
567
  if (NULL == pResNode || NULL == pResNode->pExecInfo ||
179,108,106✔
568
      taosArrayGetSize(pResNode->pExecInfo) == 0) {
5,490,825✔
569
    return TSDB_CODE_SUCCESS;
168,128,963✔
570
  }
571

572
  bool    isVerboseLine = true;
5,488,318✔
573
  char   *tbuf = ctx->tbuf;
5,488,318✔
574
  int32_t tlen = 0;
5,488,318✔
575
  char    createAvgTs[32] = {0}; // 32 is enough for formatted ts: "%Y-%m-%d %H:%M:%S.ffffff"
5,488,318✔
576
  char    createMaxTs[32] = {0};
5,488,318✔
577
  EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EXEC_COST_FORMAT);
5,488,318✔
578

579
  int32_t nodeNum = (int32_t)taosArrayGetSize(pResNode->pExecInfo);
5,488,318✔
580
  SExplainExecInfo execInfo = {0};
5,490,825✔
581
  SExplainExecInfo maxExecInfo = {0};
5,490,825✔
582
  maxExecInfo.execCreate = INT64_MIN;
5,490,825✔
583
  maxExecInfo.execStart = INT64_MIN;
5,490,825✔
584

585
  for (int32_t i = 0; i < nodeNum; ++i) {
11,220,332✔
586
    const SExplainExecInfo *pExecInfo = taosArrayGet(pResNode->pExecInfo, i);
5,729,507✔
587
    if (pExecInfo == NULL) {
5,729,507✔
588
      qError("%s failed at line %d, execInfo is NULL",
×
589
             __func__, __LINE__);
590
      return TSDB_CODE_INVALID_PARA;
×
591
    }
592
    execInfo.execElapsed += pExecInfo->execElapsed;
5,729,507✔
593
    execInfo.execCreate += pExecInfo->execCreate;
5,729,507✔
594
    execInfo.execStart += pExecInfo->execStart;
5,729,507✔
595
    execInfo.execTimes += pExecInfo->execTimes;
5,729,507✔
596
    execInfo.inputWaitElapsed += pExecInfo->inputWaitElapsed;
5,729,507✔
597
    execInfo.outputWaitElapsed += pExecInfo->outputWaitElapsed;
5,729,507✔
598

599
    maxExecInfo.execElapsed = TMAX(maxExecInfo.execElapsed, pExecInfo->execElapsed);
5,729,507✔
600
    maxExecInfo.execCreate = TMAX(maxExecInfo.execCreate, pExecInfo->execCreate);
5,729,507✔
601
    maxExecInfo.execStart = TMAX(maxExecInfo.execStart, pExecInfo->execStart);
5,729,507✔
602
    maxExecInfo.execTimes = TMAX(maxExecInfo.execTimes, pExecInfo->execTimes);
5,729,507✔
603
    maxExecInfo.inputWaitElapsed = TMAX(maxExecInfo.inputWaitElapsed, pExecInfo->inputWaitElapsed);
5,729,507✔
604
    maxExecInfo.outputWaitElapsed = TMAX(maxExecInfo.outputWaitElapsed, pExecInfo->outputWaitElapsed);
5,729,507✔
605
  }
606

607
  if (nodeNum == 1) {
5,490,825✔
608
    if (formatTimestampLocal(createAvgTs, sizeof(createAvgTs), execInfo.execCreate,
5,268,691✔
609
                             TSDB_TIME_PRECISION_MICRO) == NULL) {
610
      /*
611
        If formatTimestampLocal fails, set the first char to '\0' to ensure
612
        createAvgTs is an empty string to avoid using uninitialized data.
613
      */
614
      createAvgTs[0] = '\0';
×
615
    }
616
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPUTE_FORMAT, EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execElapsed));
5,268,691✔
617
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,268,691✔
618
    EXPLAIN_ROW_APPEND(EXPLAIN_CREATE_TIME_FORMAT, createAvgTs);
5,268,691✔
619
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,268,691✔
620
    EXPLAIN_ROW_APPEND(EXPLAIN_START_FORMAT,
5,268,691✔
621
                       execInfo.execTimes > 0 ? EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execStart) : 0.0);
622
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,268,691✔
623
    EXPLAIN_ROW_APPEND(EXPLAIN_TIMES_FORMAT, (int64_t)execInfo.execTimes);
5,268,691✔
624
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,268,691✔
625
    EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_WAIT_ELAPSED_FORMAT,
5,268,691✔
626
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.inputWaitElapsed));
627
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,268,691✔
628
    EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_WAIT_ELAPSED_FORMAT,
5,268,691✔
629
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.outputWaitElapsed));
630
  } else if (nodeNum > 1) {
222,134✔
631
    int64_t createAvgUs = execInfo.execCreate / nodeNum;
222,134✔
632
    int64_t createMaxUs = maxExecInfo.execCreate;
222,134✔
633
    if (formatTimestampLocal(createAvgTs, sizeof(createAvgTs), createAvgUs,
222,134✔
634
                             TSDB_TIME_PRECISION_MICRO) == NULL) {
635
      createAvgTs[0] = '\0';
×
636
    }
637
    if (formatTimestampLocal(createMaxTs, sizeof(createMaxTs), createMaxUs,
222,134✔
638
                             TSDB_TIME_PRECISION_MICRO) == NULL) {
639
      createMaxTs[0] = '\0';
×
640
    }
641
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPUTE_FORMAT_EXT,
222,134✔
642
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execElapsed) / nodeNum,
643
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execElapsed));
644
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
222,134✔
645
    EXPLAIN_ROW_APPEND(EXPLAIN_CREATE_TIME_FORMAT_EXT, createAvgTs, createMaxTs);
222,134✔
646
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
222,134✔
647
    EXPLAIN_ROW_APPEND(EXPLAIN_START_FORMAT_EXT,
222,134✔
648
                       execInfo.execTimes > 0 ? EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.execStart) / nodeNum : 0.0,
649
                       maxExecInfo.execTimes > 0 ? EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.execStart) : 0.0);
650
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
222,134✔
651
    EXPLAIN_ROW_APPEND(EXPLAIN_TIMES_FORMAT_EXT,
222,134✔
652
                       (double)execInfo.execTimes / nodeNum, (int64_t)maxExecInfo.execTimes);
653
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
222,134✔
654
    EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_WAIT_ELAPSED_FORMAT_EXT,
222,134✔
655
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.inputWaitElapsed) / nodeNum,
656
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.inputWaitElapsed));
657
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
222,134✔
658
    EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_WAIT_ELAPSED_FORMAT_EXT,
222,134✔
659
                       EXPLAIN_CONVERT_TS_US_TO_MS(execInfo.outputWaitElapsed) / nodeNum,
660
                       EXPLAIN_CONVERT_TS_US_TO_MS(maxExecInfo.outputWaitElapsed));
661
  }
662
  EXPLAIN_ROW_END();
5,490,825✔
663
  QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+1));
5,490,825✔
664

665
  return TSDB_CODE_SUCCESS;
5,490,825✔
666
}
667

668
/**
669
  @brief Analyze the IO of the scan nodes and append the result to the
670
  explain results.
671
*/
672
static int32_t qExplainIOAnalyze(const SExplainResNode *pResNode,
1,843,264✔
673
                                 SExplainCtx *ctx, int32_t level) {
674
  bool    isVerboseLine = true;
1,843,264✔
675
  char    *tbuf = ctx->tbuf;
1,843,264✔
676
  int32_t tlen = 0;
1,843,264✔
677

678
  /* sort groups' ExecInfo according to compute time in asc order */
679
  taosArraySort(pResNode->pExecInfo, compareExecInfo);
1,843,264✔
680
  int32_t nodeNum = (int32_t)taosArrayGetSize(pResNode->pExecInfo);
1,843,264✔
681
  STableScanAnalyzeInfo analyzeInfo = {0};
1,843,264✔
682
  STableScanAnalyzeInfo maxAnalyzeInfo = {0};
1,843,264✔
683

684
  for (int32_t i = 0; i < nodeNum; ++i) {
3,802,624✔
685
    const SExplainExecInfo *pExecInfo = taosArrayGet(pResNode->pExecInfo, i);
1,959,360✔
686
    if (pExecInfo == NULL || pExecInfo->verboseInfo == NULL) {
1,959,360✔
687
      qError("%s failed at line %d, execInfo or verboseInfo is NULL",
×
688
             __func__, __LINE__);
689
      return TSDB_CODE_INVALID_PARA;
×
690
    }
691
    const STableScanAnalyzeInfo *pScanInfo = (STableScanAnalyzeInfo *)pExecInfo->verboseInfo;
1,959,360✔
692

693
    analyzeInfo.totalBlocks += pScanInfo->totalBlocks;
1,959,360✔
694
    analyzeInfo.fileLoadBlocks += pScanInfo->fileLoadBlocks;
1,959,360✔
695
    analyzeInfo.fileLoadElapsed += pScanInfo->fileLoadElapsed;
1,959,360✔
696
    analyzeInfo.sttLoadBlocks += pScanInfo->sttLoadBlocks;
1,959,360✔
697
    analyzeInfo.sttLoadElapsed += pScanInfo->sttLoadElapsed;
1,959,360✔
698
    analyzeInfo.memLoadBlocks += pScanInfo->memLoadBlocks;
1,959,360✔
699
    analyzeInfo.memLoadElapsed += pScanInfo->memLoadElapsed;
1,959,360✔
700
    analyzeInfo.smaLoadBlocks += pScanInfo->smaLoadBlocks;
1,959,360✔
701
    analyzeInfo.smaLoadElapsed += pScanInfo->smaLoadElapsed;
1,959,360✔
702
    analyzeInfo.composedBlocks += pScanInfo->composedBlocks;
1,959,360✔
703
    analyzeInfo.composedElapsed += pScanInfo->composedElapsed;
1,959,360✔
704
    analyzeInfo.checkRows += pScanInfo->checkRows;
1,959,360✔
705

706
    maxAnalyzeInfo.totalBlocks = TMAX(maxAnalyzeInfo.totalBlocks, pScanInfo->totalBlocks);
1,959,360✔
707
    maxAnalyzeInfo.fileLoadBlocks = TMAX(maxAnalyzeInfo.fileLoadBlocks, pScanInfo->fileLoadBlocks);
1,959,360✔
708
    maxAnalyzeInfo.fileLoadElapsed = TMAX(maxAnalyzeInfo.fileLoadElapsed, pScanInfo->fileLoadElapsed);
1,959,360✔
709
    maxAnalyzeInfo.sttLoadBlocks = TMAX(maxAnalyzeInfo.sttLoadBlocks, pScanInfo->sttLoadBlocks);
1,959,360✔
710
    maxAnalyzeInfo.sttLoadElapsed = TMAX(maxAnalyzeInfo.sttLoadElapsed, pScanInfo->sttLoadElapsed);
1,959,360✔
711
    maxAnalyzeInfo.memLoadBlocks = TMAX(maxAnalyzeInfo.memLoadBlocks, pScanInfo->memLoadBlocks);
1,959,360✔
712
    maxAnalyzeInfo.memLoadElapsed = TMAX(maxAnalyzeInfo.memLoadElapsed, pScanInfo->memLoadElapsed);
1,959,360✔
713
    maxAnalyzeInfo.smaLoadBlocks = TMAX(maxAnalyzeInfo.smaLoadBlocks, pScanInfo->smaLoadBlocks);
1,959,360✔
714
    maxAnalyzeInfo.smaLoadElapsed = TMAX(maxAnalyzeInfo.smaLoadElapsed, pScanInfo->smaLoadElapsed);
1,959,360✔
715
    maxAnalyzeInfo.composedBlocks = TMAX(maxAnalyzeInfo.composedBlocks, pScanInfo->composedBlocks);
1,959,360✔
716
    maxAnalyzeInfo.composedElapsed = TMAX(maxAnalyzeInfo.composedElapsed, pScanInfo->composedElapsed);
1,959,360✔
717
    maxAnalyzeInfo.checkRows = TMAX(maxAnalyzeInfo.checkRows, pScanInfo->checkRows);
1,959,360✔
718
  }
719

720
  EXPLAIN_ROW_NEW(level + 1, EXPLAIN_IO_FORMAT);
1,843,264✔
721
  if (nodeNum == 1) {
1,843,264✔
722
    EXPLAIN_ROW_APPEND(EXPLAIN_TOTAL_BLOCKS_FORMAT, analyzeInfo.totalBlocks);
1,733,082✔
723
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
724
    EXPLAIN_ROW_APPEND(EXPLAIN_FILE_LOAD_BLOCKS_FORMAT, analyzeInfo.fileLoadBlocks);
1,733,082✔
725
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
726
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_BLOCKS_FORMAT, analyzeInfo.sttLoadBlocks);
1,733,082✔
727
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
728
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_BLOCKS_FORMAT, analyzeInfo.memLoadBlocks);
1,733,082✔
729
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
730
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_BLOCKS_FORMAT, analyzeInfo.smaLoadBlocks);
1,733,082✔
731
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
732
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_BLOCKS_FORMAT, analyzeInfo.composedBlocks);
1,733,082✔
733
    EXPLAIN_ROW_END();
1,733,082✔
734
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+1));
1,733,082✔
735

736
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_FILE_LOAD_ELAPSED_FORMAT, analyzeInfo.fileLoadElapsed);
1,733,082✔
737
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
738
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_ELAPSED_FORMAT, analyzeInfo.sttLoadElapsed);
1,733,082✔
739
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
740
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_ELAPSED_FORMAT, analyzeInfo.memLoadElapsed);
1,733,082✔
741
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
742
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_ELAPSED_FORMAT, analyzeInfo.smaLoadElapsed);
1,733,082✔
743
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,733,082✔
744
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_ELAPSED_FORMAT, analyzeInfo.composedElapsed);
1,733,082✔
745
    EXPLAIN_ROW_END();
1,733,082✔
746
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+2));
1,733,082✔
747

748
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_CHECK_ROWS_FORMAT, analyzeInfo.checkRows);
1,733,082✔
749
  } else if (nodeNum > 1) {
110,182✔
750
    EXPLAIN_ROW_APPEND(EXPLAIN_TOTAL_BLOCKS_FORMAT_EXT,
110,182✔
751
                       (double)analyzeInfo.totalBlocks / nodeNum, maxAnalyzeInfo.totalBlocks);
752
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
753
    EXPLAIN_ROW_APPEND(EXPLAIN_FILE_LOAD_BLOCKS_FORMAT_EXT,
110,182✔
754
                       (double)analyzeInfo.fileLoadBlocks / nodeNum, maxAnalyzeInfo.fileLoadBlocks);
755
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
756
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_BLOCKS_FORMAT_EXT,
110,182✔
757
                       (double)analyzeInfo.sttLoadBlocks / nodeNum, maxAnalyzeInfo.sttLoadBlocks);
758
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
759
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_BLOCKS_FORMAT_EXT,
110,182✔
760
                       (double)analyzeInfo.memLoadBlocks / nodeNum, maxAnalyzeInfo.memLoadBlocks);
761
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
762
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_BLOCKS_FORMAT_EXT,
110,182✔
763
                       (double)analyzeInfo.smaLoadBlocks / nodeNum, maxAnalyzeInfo.smaLoadBlocks);
764
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
765
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_BLOCKS_FORMAT_EXT,
110,182✔
766
                       (double)analyzeInfo.composedBlocks / nodeNum, maxAnalyzeInfo.composedBlocks);
767
    EXPLAIN_ROW_END();
110,182✔
768
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+1));
110,182✔
769

770
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_FILE_LOAD_ELAPSED_FORMAT_EXT,
110,182✔
771
                    (double)analyzeInfo.fileLoadElapsed / nodeNum, maxAnalyzeInfo.fileLoadElapsed);
772
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
773
    EXPLAIN_ROW_APPEND(EXPLAIN_STT_LOAD_ELAPSED_FORMAT_EXT,
110,182✔
774
                       (double)analyzeInfo.sttLoadElapsed / nodeNum, maxAnalyzeInfo.sttLoadElapsed);
775
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
776
    EXPLAIN_ROW_APPEND(EXPLAIN_MEM_LOAD_ELAPSED_FORMAT_EXT,
110,182✔
777
                       (double)analyzeInfo.memLoadElapsed / nodeNum, maxAnalyzeInfo.memLoadElapsed);
778
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
779
    EXPLAIN_ROW_APPEND(EXPLAIN_SMA_LOAD_ELAPSED_FORMAT_EXT,
110,182✔
780
                       (double)analyzeInfo.smaLoadElapsed / nodeNum, maxAnalyzeInfo.smaLoadElapsed);
781
    EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
782
    EXPLAIN_ROW_APPEND(EXPLAIN_COMPOSED_ELAPSED_FORMAT_EXT,
110,182✔
783
                       (double)analyzeInfo.composedElapsed / nodeNum, maxAnalyzeInfo.composedElapsed);
784
    EXPLAIN_ROW_END();
110,182✔
785
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+2));
110,182✔
786

787
    EXPLAIN_ROW_NEW(level+2, EXPLAIN_CHECK_ROWS_FORMAT_EXT,
110,182✔
788
                     (double)analyzeInfo.checkRows / nodeNum, maxAnalyzeInfo.checkRows);
789

790
    /* slowest query node information */
791
    const SExplainExecInfo* slowestExecInfo = taosArrayGetLast(pResNode->pExecInfo);
110,182✔
792
    if (slowestExecInfo) {
110,182✔
793
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,182✔
794
      int32_t midIndex = (nodeNum - 1) / 2;
110,182✔
795
      const SExplainExecInfo* midExecInfo = taosArrayGet(pResNode->pExecInfo, midIndex);
110,182✔
796
      const SExplainExecInfo* fastestExecInfo = taosArrayGet(pResNode->pExecInfo, 0);
110,182✔
797
      double slowDeviation = midExecInfo->execElapsed > 0 ?
112,102✔
798
        ((double)slowestExecInfo->execElapsed - (double)midExecInfo->execElapsed) * 100.0 /
110,182✔
799
        (double)midExecInfo->execElapsed : 0;
218,444✔
800
      double dataDeviation = midExecInfo->numOfRows > 0 ?
112,102✔
801
        ((double)slowestExecInfo->numOfRows - (double)midExecInfo->numOfRows) * 100.0 /
89,745✔
802
        (double)midExecInfo->numOfRows : 0;
198,295✔
803
      double costRatio = fastestExecInfo->execElapsed > 0 ?
112,102✔
804
        (double)slowestExecInfo->execElapsed / (double)fastestExecInfo->execElapsed : 0;
110,182✔
805
      EXPLAIN_ROW_APPEND(EXPLAIN_SLOWEST_NODE_FORMAT, slowestExecInfo->vgId,
110,182✔
806
                         slowDeviation, costRatio, dataDeviation);
807
    }
808
  }
809
  EXPLAIN_ROW_END();
1,843,264✔
810
  QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level+2));
1,843,264✔
811

812
  return TSDB_CODE_SUCCESS;
1,843,264✔
813
}
814

815
static int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t *pLevel) {
403,666,941✔
816
  int32_t     tlen = 0;
403,666,941✔
817
  bool        isVerboseLine = false;
403,666,941✔
818
  char       *tbuf = ctx->tbuf;
403,666,941✔
819
  bool        verbose = ctx->verbose;
403,666,941✔
820
  SPhysiNode *pNode = pResNode->pNode;
403,666,941✔
821
  if (NULL == pNode) {
403,666,941✔
822
    qError("pyhsical node in explain res node is NULL");
×
823
    return TSDB_CODE_APP_ERROR;
×
824
  }
825

826
  if (0 == *pLevel && ctx->currPlanId >= 0) {
403,666,941✔
827
    EXPLAIN_SUB_PLAN_LINE(ctx->currPlanId + 1);
67,161,173✔
828
    QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, *pLevel + 1));
67,161,173✔
829
    *pLevel += 2;
67,157,936✔
830
  }
831

832
  int32_t level = *pLevel;
403,663,704✔
833
  double filterEfficiency = 100;
403,663,704✔
834
  bool   hasEfficiency = ctx->mode == EXPLAIN_MODE_ANALYZE && pResNode->pExecInfo;
403,663,704✔
835

836
  switch (pNode->type) {
403,663,704✔
837
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
4,892,477✔
838
      STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
4,892,477✔
839
      EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->scan.tableName.tname);
4,892,477✔
840
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
4,892,477✔
841
      if (pResNode->pExecInfo) {
4,892,477✔
842
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
4,144✔
843
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,144✔
844
      }
845
      if (pTagScanNode->scan.pScanPseudoCols) {
4,892,477✔
846
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTagScanNode->scan.pScanPseudoCols->length);
1,938,161✔
847
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,938,161✔
848
      }
849
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
4,892,477✔
850
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
4,892,477✔
851
      EXPLAIN_ROW_END();
4,892,477✔
852
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
4,892,477✔
853

854
      if (verbose) {
4,892,667✔
855
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,491,330✔
856
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,491,330✔
857
                           nodesGetOutputNumFromSlotList(pTagScanNode->scan.node.pOutputDataBlockDesc->pSlots));
858
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,491,330✔
859
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
1,491,330✔
860
        EXPLAIN_ROW_APPEND_LIMIT(pTagScanNode->scan.node.pLimit);
1,491,330✔
861
        EXPLAIN_ROW_APPEND_SLIMIT(pTagScanNode->scan.node.pSlimit);
1,491,330✔
862
        EXPLAIN_ROW_END();
1,491,330✔
863
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,491,330✔
864

865
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pTagScanNode->scan.node.pConditions,
1,491,235✔
866
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
867

868
        if (qExplainCouldApplyTagIndex(pResNode->pPlan)) {
1,491,235✔
869
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TAG_INDEX_FORMAT);
×
870
          EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
×
871
          QRY_ERR_RET(nodesNodeToSQL(pResNode->pPlan->pTagIndexCond, tbuf + VARSTR_HEADER_SIZE,
×
872
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
873
          EXPLAIN_ROW_END();
×
874
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
875
        }
876

877
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
1,491,235✔
878
      }
879
      break;
4,892,483✔
880
    }
881
    case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
167,483✔
882
      SVirtualScanPhysiNode *pVirtualTableScanNode = (SVirtualScanPhysiNode *)pNode;
167,483✔
883
      EXPLAIN_ROW_NEW(level, EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT, pVirtualTableScanNode->scan.tableName.tname);
167,483✔
884
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
167,483✔
885
      if (pResNode->pExecInfo) {
167,483✔
886
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,360✔
887
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,360✔
888
      }
889
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanCols->length);
167,483✔
890
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
167,483✔
891
      if (pVirtualTableScanNode->scan.pScanPseudoCols) {
167,483✔
892
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanPseudoCols->length);
57,007✔
893
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
57,007✔
894
      }
895
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
167,483✔
896
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
167,483✔
897
      EXPLAIN_ROW_END();
167,483✔
898
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
167,483✔
899

900
      if (verbose) {
167,483✔
901
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
118,535✔
902
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
118,535✔
903
                           nodesGetOutputNumFromSlotList(pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->pSlots));
904
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
118,535✔
905
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
118,535✔
906
        EXPLAIN_ROW_APPEND_LIMIT(pVirtualTableScanNode->scan.node.pLimit);
118,535✔
907
        EXPLAIN_ROW_APPEND_SLIMIT(pVirtualTableScanNode->scan.node.pSlimit);
118,535✔
908
        EXPLAIN_ROW_END();
118,535✔
909
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
118,535✔
910

911
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pVirtualTableScanNode->scan.node.pConditions,
118,535✔
912
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
913

914
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
118,535✔
915
      }
916
      break;
167,483✔
917
    }
918
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
129,489,137✔
919
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
920
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
921
      STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
129,489,137✔
922
      EXPLAIN_ROW_NEW(level,
129,489,137✔
923
                      QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == pNode->type ? EXPLAIN_TBL_MERGE_SCAN_FORMAT
924
                                                                               : EXPLAIN_TBL_SCAN_FORMAT,
925
                      pTblScanNode->scan.tableName.tname);
926
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
129,489,137✔
927
      if (pResNode->pExecInfo) {
129,489,137✔
928
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,516,812✔
929
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,516,812✔
930
      }
931

932
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
129,489,137✔
933
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
129,489,137✔
934
      if (pTblScanNode->scan.pScanPseudoCols) {
129,489,137✔
935
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTblScanNode->scan.pScanPseudoCols->length);
8,130,624✔
936
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,130,624✔
937
      }
938
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
129,489,137✔
939
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
129,489,137✔
940
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_ORDER_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
129,489,137✔
941
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
129,489,137✔
942
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_MODE_FORMAT, qExplainGetScanMode(pTblScanNode));
129,489,137✔
943
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
129,490,189✔
944
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_DATA_LOAD_FORMAT, qExplainGetScanDataLoad(pTblScanNode));
129,490,189✔
945
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
129,496,987✔
946
      EXPLAIN_ROW_END();
129,496,987✔
947
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
129,496,987✔
948

949
      if (verbose) {
129,491,740✔
950
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
58,407,111✔
951
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
58,407,111✔
952
                           nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
953
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
58,409,166✔
954
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
58,409,166✔
955
        EXPLAIN_ROW_APPEND_LIMIT(pTblScanNode->scan.node.pLimit);
58,409,166✔
956
        EXPLAIN_ROW_APPEND_SLIMIT(pTblScanNode->scan.node.pSlimit);
58,409,166✔
957
        EXPLAIN_ROW_END();
58,409,166✔
958
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
58,409,166✔
959

960
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey,
58,407,688✔
961
                        pTblScanNode->scanRange.ekey);
962
        EXPLAIN_ROW_END();
58,407,688✔
963
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
58,407,688✔
964

965
        if (NULL != pTblScanNode->pGroupTags) {
58,408,885✔
966
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
2,420,650✔
967
          EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pTblScanNode->pGroupTags->length);
2,420,650✔
968
          EXPLAIN_ROW_END();
2,420,650✔
969
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,420,650✔
970
        }
971

972
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pTblScanNode->scan.node.pConditions,
58,407,121✔
973
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
974

975
        if (pTblScanNode->pPrimaryCond) {
58,407,667✔
976
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PRIMARY_FILTER_FORMAT);
8,604✔
977
          QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->pPrimaryCond, tbuf + VARSTR_HEADER_SIZE,
8,604✔
978
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
979
          EXPLAIN_ROW_END();
8,604✔
980
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8,604✔
981
        }
982

983
        if (qExplainCouldApplyTagIndex(pResNode->pPlan)) {
58,407,667✔
984
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TAG_INDEX_FORMAT);
41,246✔
985
          EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
41,246✔
986
          QRY_ERR_RET(nodesNodeToSQL(pResNode->pPlan->pTagIndexCond, tbuf + VARSTR_HEADER_SIZE,
41,246✔
987
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
988
          EXPLAIN_ROW_END();
41,246✔
989
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
41,246✔
990
        }
991

992
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
58,407,025✔
993

994
        if (EXPLAIN_MODE_ANALYZE == ctx->mode && pResNode->pExecInfo) {
58,405,621✔
995
          /* table scan I/O analyze information */
996
          QRY_ERR_RET(qExplainIOAnalyze(pResNode, ctx, level));
1,843,264✔
997
        }
998
      }
999
      break;
129,490,372✔
1000
    }
1001
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
489,368✔
1002
      SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
489,368✔
1003
      EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
489,368✔
1004
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
489,368✔
1005
      if (pResNode->pExecInfo) {
489,368✔
1006
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
15,072✔
1007
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,072✔
1008
      }
1009
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
489,368✔
1010
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
489,368✔
1011
      if (pSTblScanNode->scan.pScanPseudoCols) {
489,368✔
1012
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pSTblScanNode->scan.pScanPseudoCols->length);
590✔
1013
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
590✔
1014
      }
1015
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
489,368✔
1016
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
489,368✔
1017
      EXPLAIN_ROW_END();
489,368✔
1018
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
489,368✔
1019

1020
      if (verbose) {
489,368✔
1021
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
195,800✔
1022
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
195,800✔
1023
                           nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
1024
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
195,800✔
1025
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
195,800✔
1026
        EXPLAIN_ROW_APPEND_LIMIT(pSTblScanNode->scan.node.pLimit);
195,800✔
1027
        EXPLAIN_ROW_APPEND_SLIMIT(pSTblScanNode->scan.node.pSlimit);
195,800✔
1028
        EXPLAIN_ROW_END();
195,800✔
1029
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
195,800✔
1030

1031
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSTblScanNode->scan.node.pConditions,
195,800✔
1032
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1033

1034
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
195,800✔
1035
      }
1036
      break;
489,368✔
1037
    }
1038
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
79,149,609✔
1039
      SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
79,149,609✔
1040
      EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
79,149,609✔
1041
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
79,149,609✔
1042
      if (pResNode->pExecInfo) {
79,149,609✔
1043
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,249,284✔
1044
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,249,284✔
1045
      }
1046
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
79,149,609✔
1047
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
79,149,609✔
1048
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
79,149,609✔
1049
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
79,149,609✔
1050
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pPrjNode->node.inputTsOrder));
79,149,609✔
1051
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
79,149,609✔
1052
      EXPLAIN_ROW_END();
79,149,609✔
1053
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
79,149,609✔
1054

1055
      if (verbose) {
79,148,886✔
1056
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
32,956,829✔
1057
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
32,956,829✔
1058
                           nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
1059
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
32,957,654✔
1060
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
32,957,654✔
1061
        EXPLAIN_ROW_APPEND_LIMIT(pPrjNode->node.pLimit);
32,957,654✔
1062
        EXPLAIN_ROW_APPEND_SLIMIT(pPrjNode->node.pSlimit);
32,957,654✔
1063
        EXPLAIN_ROW_END();
32,957,654✔
1064
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
32,957,654✔
1065

1066
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
32,957,087✔
1067
        EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pPrjNode->ignoreGroupId ? "true" : "false");
32,957,087✔
1068
        EXPLAIN_ROW_END();
32,957,087✔
1069
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
32,957,087✔
1070

1071
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pPrjNode->mergeDataBlock? "True":"False");
32,957,459✔
1072
        EXPLAIN_ROW_END();
32,957,459✔
1073
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
32,957,459✔
1074

1075
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pPrjNode->node.pConditions,
32,957,930✔
1076
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1077

1078
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
32,957,278✔
1079
      }
1080
      break;
79,157,159✔
1081
    }
1082
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
6,974,774✔
1083
      SSortMergeJoinPhysiNode *pJoinNode = (SSortMergeJoinPhysiNode *)pNode;
6,974,774✔
1084
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
6,974,774✔
1085
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
6,974,774✔
1086
      if (pResNode->pExecInfo) {
6,974,774✔
1087
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
264,064✔
1088
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
264,064✔
1089
      }
1090
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
6,974,774✔
1091
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,974,774✔
1092
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
6,974,774✔
1093
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,974,774✔
1094
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
6,974,774✔
1095
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
6,974,774✔
1096
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Merge");
6,974,774✔
1097
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
6,974,774✔
1098
      EXPLAIN_ROW_END();
6,974,774✔
1099
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
6,974,774✔
1100

1101
      if (verbose) {
6,974,774✔
1102
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2,187,392✔
1103
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2,187,392✔
1104
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
1105
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,187,392✔
1106
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
2,187,392✔
1107
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
2,187,392✔
1108
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
2,187,392✔
1109
        EXPLAIN_ROW_END();
2,187,392✔
1110
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,187,392✔
1111

1112
        if (IS_ASOF_JOIN(pJoinNode->subType) || IS_WINDOW_JOIN(pJoinNode->subType)) {
2,187,392✔
1113
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_PARAM_FORMAT);
110,608✔
1114
          if (IS_ASOF_JOIN(pJoinNode->subType)) {
110,608✔
1115
            EXPLAIN_ROW_APPEND(EXPLAIN_ASOF_OP_FORMAT, qExplainGetAsofOpStr(pJoinNode->asofOpType));
49,952✔
1116
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
49,952✔
1117
          }
1118
          if (NULL != pJoinNode->pWindowOffset) {
110,608✔
1119
            SWindowOffsetNode* pWinOffset = (SWindowOffsetNode*)pJoinNode->pWindowOffset;
60,656✔
1120
            SValueNode* pStart = (SValueNode*)pWinOffset->pStartOffset;
60,656✔
1121
            SValueNode* pEnd = (SValueNode*)pWinOffset->pEndOffset;
60,656✔
1122
            EXPLAIN_ROW_APPEND(EXPLAIN_WIN_OFFSET_FORMAT, pStart->literal, pEnd->literal);
60,656✔
1123
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
60,656✔
1124
          }
1125
          if (NULL != pJoinNode->pJLimit && NULL != ((SLimitNode*)pJoinNode->pJLimit)->limit) {
110,608✔
1126
            SLimitNode* pJLimit = (SLimitNode*)pJoinNode->pJLimit;
19,624✔
1127
            EXPLAIN_ROW_APPEND(EXPLAIN_JLIMIT_FORMAT, pJLimit->limit->datum.i);
19,624✔
1128
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
19,624✔
1129
          }
1130
          if (IS_WINDOW_JOIN(pJoinNode->subType)) {
110,608✔
1131
            EXPLAIN_ROW_APPEND(EXPLAIN_SEQ_WIN_GRP_FORMAT, pJoinNode->seqWinGroup);
60,656✔
1132
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
60,656✔
1133
          }
1134

1135
          EXPLAIN_ROW_APPEND(EXPLAIN_GRP_JOIN_FORMAT, pJoinNode->grpJoin);
110,608✔
1136
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,608✔
1137
          EXPLAIN_ROW_END();
110,608✔
1138

1139
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
110,608✔
1140
        }
1141

1142
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pJoinNode->node.pConditions,
2,187,392✔
1143
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1144

1145
        if (NULL != pJoinNode->pPrimKeyCond) {
2,187,392✔
1146
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PRIM_CONDITIONS_FORMAT);
2,110,680✔
1147
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2,110,680✔
1148
          EXPLAIN_ROW_END();
2,110,680✔
1149
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,110,680✔
1150
        }
1151

1152
        if (NULL != pJoinNode->pEqLeft && pJoinNode->pEqLeft->length > 0) {
2,187,392✔
1153
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_LEFT_FORMAT);
892✔
1154
          SNode* pCol = NULL;
892✔
1155
          FOREACH(pCol, pJoinNode->pEqLeft) {
1,784✔
1156
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
892✔
1157
          }
1158
          EXPLAIN_ROW_END();
892✔
1159
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
892✔
1160
        }
1161

1162
        if (NULL != pJoinNode->pEqRight && pJoinNode->pEqRight->length > 0) {
2,187,392✔
1163
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_RIGHT_FORMAT);
892✔
1164
          SNode* pCol = NULL;
892✔
1165
          FOREACH(pCol, pJoinNode->pEqRight) {
1,784✔
1166
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
892✔
1167
          }
1168
          EXPLAIN_ROW_END();
892✔
1169
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
892✔
1170
        }
1171

1172
        if (NULL != pJoinNode->pFullOnCond) {
2,187,392✔
1173
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
211,590✔
1174
          QRY_ERR_RET(
211,590✔
1175
                nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1176
          EXPLAIN_ROW_END();
211,590✔
1177
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
211,590✔
1178
        }
1179

1180
        if (NULL != pJoinNode->pColOnCond) {
2,187,392✔
1181
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COL_ON_CONDITIONS_FORMAT);
210,698✔
1182
          QRY_ERR_RET(
210,698✔
1183
                nodesNodeToSQL(pJoinNode->pColOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1184
          EXPLAIN_ROW_END();
210,698✔
1185
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
210,698✔
1186
        }
1187

1188
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
2,187,392✔
1189
      }
1190
      break;
6,974,679✔
1191
    }
1192
    case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
40,237,572✔
1193
      SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
40,237,572✔
1194
      EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, (pAggNode->pGroupKeys ? "GroupAggregate" : "Aggregate"));
40,237,572✔
1195
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
40,237,572✔
1196
      if (pResNode->pExecInfo) {
40,237,572✔
1197
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
624,582✔
1198
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
624,582✔
1199
      }
1200
      if (pAggNode->pAggFuncs) {
40,237,572✔
1201
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
28,749,717✔
1202
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,749,717✔
1203
      }
1204
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
40,237,572✔
1205
      if (pAggNode->pGroupKeys) {
40,237,572✔
1206
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
21,874,045✔
1207
        EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
21,874,045✔
1208
      }
1209
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
40,237,572✔
1210
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pAggNode->node.inputTsOrder));
40,237,572✔
1211
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
40,237,572✔
1212
      EXPLAIN_ROW_END();
40,237,572✔
1213
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
40,237,572✔
1214

1215
      if (verbose) {
40,240,324✔
1216
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
16,775,732✔
1217
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
16,775,732✔
1218
                           nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
1219
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
16,776,389✔
1220
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
16,776,389✔
1221
        EXPLAIN_ROW_APPEND_LIMIT(pAggNode->node.pLimit);
16,776,389✔
1222
        EXPLAIN_ROW_APPEND_SLIMIT(pAggNode->node.pSlimit);
16,776,389✔
1223
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
16,776,389✔
1224
        EXPLAIN_ROW_APPEND(EXPLAIN_PLAN_BLOCKING, !pAggNode->node.forceCreateNonBlockingOptr);
16,776,389✔
1225
        EXPLAIN_ROW_END();
16,776,389✔
1226
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
16,776,389✔
1227

1228
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pAggNode->node.pConditions,
16,775,009✔
1229
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1230

1231
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pAggNode->mergeDataBlock? "True":"False");
16,775,930✔
1232
        EXPLAIN_ROW_END();
16,775,930✔
1233
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
16,775,930✔
1234

1235
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
16,776,033✔
1236
      }
1237
      break;
40,240,464✔
1238
    }
1239
    case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: {
1,357,691✔
1240
      SIndefRowsFuncPhysiNode *pIndefNode = (SIndefRowsFuncPhysiNode *)pNode;
1,357,691✔
1241
      EXPLAIN_ROW_NEW(level, EXPLAIN_INDEF_ROWS_FORMAT);
1,357,691✔
1242
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,357,691✔
1243
      if (pResNode->pExecInfo) {
1,357,691✔
1244
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
4,158✔
1245
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,158✔
1246
      }
1247
      if (pIndefNode->pFuncs) {
1,357,691✔
1248
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIndefNode->pFuncs->length);
1,357,691✔
1249
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,357,691✔
1250
      }
1251
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->totalRowSize);
1,357,691✔
1252
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,357,691✔
1253
      EXPLAIN_ROW_END();
1,357,691✔
1254
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,357,691✔
1255

1256
      if (verbose) {
1,357,691✔
1257
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
250,676✔
1258
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
250,676✔
1259
                           nodesGetOutputNumFromSlotList(pIndefNode->node.pOutputDataBlockDesc->pSlots));
1260
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
250,676✔
1261
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->outputRowSize);
250,676✔
1262
        EXPLAIN_ROW_APPEND_LIMIT(pIndefNode->node.pLimit);
250,676✔
1263
        EXPLAIN_ROW_APPEND_SLIMIT(pIndefNode->node.pSlimit);
250,676✔
1264
        EXPLAIN_ROW_END();
250,676✔
1265
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
250,676✔
1266

1267
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIndefNode->node.pConditions,
250,676✔
1268
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1269

1270
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
250,676✔
1271
      }
1272
      break;
1,357,691✔
1273
    }
1274
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
68,121,344✔
1275
      SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
68,121,344✔
1276
      int32_t nodeNum = 0;
68,121,344✔
1277
      for (int32_t gid = pExchNode->srcStartGroupId; gid <= pExchNode->srcEndGroupId; ++gid) {
147,274,385✔
1278
        SExplainGroup *group = taosHashGet(ctx->pCurrPlanCtx->groupHash, &gid, sizeof(gid));
79,150,008✔
1279
        if (NULL == group) {
79,153,774✔
1280
          qError("exchange src group %d not in groupHash", gid);
×
UNCOV
1281
          QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
1282
        }
1283

1284
        if (pExchNode->childrenVgIds && group->nodeExecInfo) {
79,153,041✔
1285
          int32_t matchedCnt = 0;
1,951,965✔
1286
          int32_t rspCnt = (int32_t)taosArrayGetSize(group->nodeExecInfo);
1,951,965✔
1287
          for (int32_t j = 0; j < rspCnt; ++j) {
7,085,287✔
1288
            const SExplainRsp* pRsp = taosArrayGet(group->nodeExecInfo, j);
5,133,322✔
1289
            if (qExplainRspMatchVgIds(pRsp, pExchNode->childrenVgIds)) {
5,133,322✔
1290
              ++matchedCnt;
2,231,056✔
1291
            }
1292
          }
1293
          nodeNum += matchedCnt;
1,951,965✔
1294
          continue;
1,951,965✔
1295
        }
1296

1297
        nodeNum += group->nodeNum;
77,201,076✔
1298
      }
1299

1300
      int32_t srcCount = pExchNode->singleSrc ? 1 : nodeNum;
68,124,377✔
1301
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, srcCount);
68,124,377✔
1302
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
68,124,377✔
1303
      if (pResNode->pExecInfo) {
68,124,377✔
1304
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,867,980✔
1305
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,867,980✔
1306
      }
1307
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
68,124,377✔
1308
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
68,124,377✔
1309
      EXPLAIN_ROW_END();
68,124,377✔
1310
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
68,124,377✔
1311

1312
      if (verbose) {
68,125,255✔
1313
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
27,568,048✔
1314
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
27,568,048✔
1315
                           nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
1316
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
27,568,758✔
1317
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
27,568,758✔
1318
        EXPLAIN_ROW_APPEND_LIMIT(pExchNode->node.pLimit);
27,568,758✔
1319
        EXPLAIN_ROW_APPEND_SLIMIT(pExchNode->node.pSlimit);
27,568,758✔
1320
        EXPLAIN_ROW_END();
27,568,758✔
1321
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
27,568,758✔
1322

1323
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExchNode->node.pConditions,
27,568,057✔
1324
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1325

1326
        if (pResNode->pExecInfo) {
27,567,962✔
1327
          const SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
1,668,680✔
1328
          if (execInfo && execInfo->verboseInfo) {
1,668,680✔
1329
            const SExchangeExplainInfo *pExchInfo = (SExchangeExplainInfo *)execInfo->verboseInfo;
1,668,680✔
1330
            EXPLAIN_ROW_NEW(level + 1, EXPLAIN_NETWORK_FORMAT);
1,668,680✔
1331
            EXPLAIN_ROW_APPEND(EXPLAIN_EXCHANGE_MODE_FORMAT,
1,668,680✔
1332
              pExchInfo->mode == 0 ? EXPLAIN_EXCHANGE_MODE_CONCURRENT : EXPLAIN_EXCHANGE_MODE_SEQUENCE);
1333
            if (srcCount > 1) {
1,668,680✔
1334
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
188,020✔
1335
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_TIMES_FORMAT_EXT,
188,020✔
1336
                                pExchInfo->avgFetchTimes, pExchInfo->maxFetchTimes);
1337
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
188,020✔
1338
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_ROWS_FORMAT_EXT,
188,020✔
1339
                                pExchInfo->avgFetchRows, pExchInfo->maxFetchRows);
1340
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
188,020✔
1341
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_COST_FORMAT_EXT,
188,020✔
1342
                                EXPLAIN_CONVERT_TS_US_TO_MS(pExchInfo->avgFetchCost),
1343
                                EXPLAIN_CONVERT_TS_US_TO_MS(pExchInfo->maxFetchCost));
1344
            } else {
1345
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,480,660✔
1346
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_TIMES_FORMAT, (uint64_t)pExchInfo->avgFetchTimes);
1,480,660✔
1347
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,480,660✔
1348
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_ROWS_FORMAT, (uint64_t)pExchInfo->avgFetchRows);
1,480,660✔
1349
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,480,660✔
1350
              EXPLAIN_ROW_APPEND(EXPLAIN_FETCH_COST_FORMAT,
1,480,660✔
1351
                                EXPLAIN_CONVERT_TS_US_TO_MS(pExchInfo->avgFetchCost));
1352
            }
1353
            EXPLAIN_ROW_END();
1,668,680✔
1354
            QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,668,680✔
1355
          }
1356
        }
1357

1358
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
27,567,962✔
1359
      }
1360

1361
      for (int32_t i = pExchNode->srcStartGroupId; i <= pExchNode->srcEndGroupId; ++i) {
147,278,245✔
1362
        int32_t nlevel = level + 1;
79,151,038✔
1363
        if (pExchNode->childrenVgIds) {
79,151,038✔
1364
          QRY_ERR_RET(qExplainAppendGroupResRowsByVgIds(ctx, i, &nlevel, pExchNode->grpSingleChannel,
1,951,965✔
1365
                                                        pExchNode->childrenVgIds));
1366
        } else {
1367
          QRY_ERR_RET(qExplainAppendGroupResRows(ctx, i, &nlevel, pExchNode->grpSingleChannel));
77,199,073✔
1368
        }
1369
      }
1370
      break;
68,127,207✔
1371
    }
1372
    case QUERY_NODE_PHYSICAL_PLAN_SORT: {
27,342,867✔
1373
      SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
27,342,867✔
1374
      EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
27,342,867✔
1375
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
27,342,867✔
1376
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.inputTsOrder));
27,342,867✔
1377
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
27,342,867✔
1378
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.outputTsOrder));
27,342,867✔
1379
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
27,342,867✔
1380
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
27,342,867✔
1381
      if (pResNode->pExecInfo) {
27,342,867✔
1382
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
110,121✔
1383
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
110,121✔
1384
      }
1385

1386
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
27,342,867✔
1387
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
27,342,867✔
1388
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
27,346,277✔
1389
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
27,346,277✔
1390
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
27,346,277✔
1391
      EXPLAIN_ROW_END();
27,346,277✔
1392
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
27,346,277✔
1393

1394
      if (pResNode->pExecInfo) {
27,343,774✔
1395
        // sort key
1396
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
110,121✔
1397
        for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
222,602✔
1398
          SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
112,481✔
1399
          EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
112,481✔
1400
        }
1401

1402
        EXPLAIN_ROW_END();
110,121✔
1403
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
110,121✔
1404

1405
        // sort method
1406
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
110,121✔
1407

1408
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
110,121✔
1409
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
110,121✔
1410
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
110,121✔
1411
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
110,121✔
1412
        if (pExecInfo->sortBuffer > 1024 * 1024) {
110,121✔
1413
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
89,358✔
1414
        } else if (pExecInfo->sortBuffer > 1024) {
20,763✔
1415
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
1416
        } else {
1417
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
20,763✔
1418
        }
1419

1420
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
110,121✔
1421
        EXPLAIN_ROW_END();
110,121✔
1422
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
110,121✔
1423
      }
1424

1425
      if (verbose) {
27,343,774✔
1426
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
13,316,188✔
1427
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
13,316,188✔
1428
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
1429
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
13,317,561✔
1430
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
13,317,561✔
1431
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
13,317,561✔
1432
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
13,317,561✔
1433
        EXPLAIN_ROW_END();
13,317,561✔
1434
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
13,317,561✔
1435

1436
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSortNode->node.pConditions,
13,316,270✔
1437
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1438

1439
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
13,316,466✔
1440
      }
1441
      break;
27,345,275✔
1442
    }
1443
    case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: {
9,435,674✔
1444
      SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
9,435,674✔
1445
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
9,435,674✔
1446
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
9,436,604✔
1447
      if (pResNode->pExecInfo) {
9,436,604✔
1448
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
48,869✔
1449
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
48,780✔
1450
      }
1451
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pIntNode->window.pFuncs));
9,436,523✔
1452
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9,436,523✔
1453
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
9,436,523✔
1454
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9,436,523✔
1455
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
9,436,523✔
1456
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9,436,523✔
1457
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
9,436,523✔
1458
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
9,436,523✔
1459
      EXPLAIN_ROW_END();
9,436,523✔
1460
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
9,436,523✔
1461

1462
      if (verbose) {
9,437,927✔
1463
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
5,139,498✔
1464
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
5,139,498✔
1465
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1466
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,139,688✔
1467
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
5,139,688✔
1468
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
5,139,688✔
1469
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
5,139,688✔
1470
        EXPLAIN_ROW_END();
5,139,688✔
1471
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,139,688✔
1472
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pIntNode->timeRange.skey, pIntNode->timeRange.ekey);
5,139,308✔
1473
        EXPLAIN_ROW_END();
5,139,308✔
1474
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,139,308✔
1475
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
5,139,688✔
1476
        int64_t time1 = -1;
5,139,688✔
1477
        int64_t time2 = -1;
5,139,688✔
1478
        int32_t code = TSDB_CODE_SUCCESS;
5,139,688✔
1479
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
5,139,688✔
1480
        QRY_ERR_RET(code);
5,139,036✔
1481
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
5,139,036✔
1482
        QRY_ERR_RET(code);
5,139,593✔
1483
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
5,139,593✔
1484
                        time1,
1485
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1486
                        time2,
1487
                        pIntNode->slidingUnit);
1488
        EXPLAIN_ROW_END();
5,138,751✔
1489
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,138,751✔
1490

1491
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIntNode->window.node.pConditions,
5,139,514✔
1492
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1493

1494
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
5,138,847✔
1495
        EXPLAIN_ROW_END();
5,138,847✔
1496
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,138,847✔
1497

1498
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
5,139,688✔
1499
      }
1500
      break;
9,437,546✔
1501
    }
1502
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: {
1,602,021✔
1503
      SMergeAlignedIntervalPhysiNode *pIntNode = (SMergeAlignedIntervalPhysiNode *)pNode;
1,602,021✔
1504
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
1,602,021✔
1505
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,602,292✔
1506
      if (pResNode->pExecInfo) {
1,602,292✔
1507
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
20,311✔
1508
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
20,126✔
1509
      }
1510
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pIntNode->window.pFuncs));
1,602,107✔
1511
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,602,107✔
1512
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,602,107✔
1513
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,602,107✔
1514
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
1,602,107✔
1515
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,602,107✔
1516
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
1,602,107✔
1517
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,602,107✔
1518
      EXPLAIN_ROW_END();
1,602,107✔
1519
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,602,107✔
1520

1521
      if (verbose) {
1,602,292✔
1522
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
917,338✔
1523
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
917,338✔
1524
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1525
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
917,338✔
1526
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
917,338✔
1527
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
917,338✔
1528
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
917,338✔
1529
        EXPLAIN_ROW_END();
917,338✔
1530
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
917,338✔
1531
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
917,338✔
1532
        int64_t time1 = -1;
917,433✔
1533
        int64_t time2 = -1;
917,433✔
1534
        int32_t code = TSDB_CODE_SUCCESS;
917,433✔
1535
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
917,433✔
1536
        QRY_ERR_RET(code);
917,433✔
1537
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
917,433✔
1538
        QRY_ERR_RET(code);
917,433✔
1539
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
917,433✔
1540
                        time1,
1541
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1542
                        time2,
1543
                        pIntNode->slidingUnit);
1544
        EXPLAIN_ROW_END();
917,338✔
1545
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
917,338✔
1546

1547
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIntNode->window.node.pConditions,
917,338✔
1548
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1549

1550
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
917,338✔
1551
        EXPLAIN_ROW_END();
917,338✔
1552
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
917,338✔
1553

1554
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
917,433✔
1555
      }
1556
      break;
1,602,387✔
1557
    }
1558
    case QUERY_NODE_PHYSICAL_PLAN_FILL: {
10,126✔
1559
      SFillPhysiNode *pFillNode = (SFillPhysiNode *)pNode;
10,126✔
1560
      EXPLAIN_ROW_NEW(level, EXPLAIN_FILL_FORMAT);
10,126✔
1561
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
10,126✔
1562
      if (pResNode->pExecInfo) {
10,126✔
1563
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
5,948✔
1564
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,948✔
1565
      }
1566
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pFillNode->mode));
10,126✔
1567
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10,126✔
1568
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->totalRowSize);
10,126✔
1569
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10,126✔
1570
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pFillNode->node.inputTsOrder));
10,126✔
1571
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
10,126✔
1572
      EXPLAIN_ROW_END();
10,126✔
1573
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
10,126✔
1574

1575
      if (verbose) {
10,126✔
1576
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
10,084✔
1577
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
10,084✔
1578
                           nodesGetOutputNumFromSlotList(pFillNode->node.pOutputDataBlockDesc->pSlots));
1579
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10,084✔
1580
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->outputRowSize);
10,084✔
1581
        EXPLAIN_ROW_APPEND_LIMIT(pFillNode->node.pLimit);
10,084✔
1582
        EXPLAIN_ROW_APPEND_SLIMIT(pFillNode->node.pSlimit);
10,084✔
1583
        EXPLAIN_ROW_END();
10,084✔
1584
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10,084✔
1585
        if (pFillNode->pValues) {
10,084✔
1586
          SNodeListNode *pValues = (SNodeListNode *)pFillNode->pValues;
632✔
1587
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
632✔
1588
          SNode  *tNode = NULL;
632✔
1589
          int32_t i = 0;
632✔
1590
          FOREACH(tNode, pValues->pNodeList) {
1,432✔
1591
            if (i) {
800✔
1592
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
168✔
1593
            }
1594
            SValueNode *tValue = (SValueNode *)tNode;
800✔
1595
            char       *value = nodesGetStrValueFromNode(tValue);
800✔
1596
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
800✔
1597
            taosMemoryFree(value);
800✔
1598
            ++i;
800✔
1599
          }
1600

1601
          EXPLAIN_ROW_END();
632✔
1602
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
632✔
1603
        }
1604

1605
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pFillNode->timeRange.skey, pFillNode->timeRange.ekey);
10,084✔
1606
        EXPLAIN_ROW_END();
10,084✔
1607
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10,084✔
1608

1609
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pFillNode->node.pConditions,
10,084✔
1610
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1611

1612
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
10,084✔
1613
      }
1614
      break;
10,126✔
1615
    }
1616
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: {
2,538,153✔
1617
      SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
2,538,153✔
1618
      EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
2,538,153✔
1619
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
2,538,153✔
1620
      if (pResNode->pExecInfo) {
2,538,153✔
1621
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
5,315✔
1622
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,315✔
1623
      }
1624
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pSessNode->window.pFuncs));
2,538,153✔
1625
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,538,153✔
1626
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
2,538,153✔
1627
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
2,538,153✔
1628
      EXPLAIN_ROW_END();
2,538,153✔
1629
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
2,538,153✔
1630

1631
      if (verbose) {
2,538,430✔
1632
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,292,080✔
1633
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,292,080✔
1634
                           nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
1635
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,292,175✔
1636
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
1,292,175✔
1637
        EXPLAIN_ROW_APPEND_LIMIT(pSessNode->window.node.pLimit);
1,292,175✔
1638
        EXPLAIN_ROW_APPEND_SLIMIT(pSessNode->window.node.pSlimit);
1,292,175✔
1639
        EXPLAIN_ROW_END();
1,292,175✔
1640
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,292,175✔
1641

1642
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_WINDOW_FORMAT, pSessNode->gap);
1,292,175✔
1643
        EXPLAIN_ROW_END();
1,292,175✔
1644
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,292,175✔
1645

1646
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSessNode->window.node.pConditions,
1,292,080✔
1647
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1648

1649
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
1,292,080✔
1650
      }
1651
      break;
2,538,439✔
1652
    }
1653
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE: {
1,774,247✔
1654
      SStateWindowPhysiNode *pStateNode = (SStateWindowPhysiNode *)pNode;
1,774,247✔
1655
      char                  stateKeyDesc[TSDB_EXPLAIN_RESULT_ROW_SIZE] = {0};
1,774,247✔
1656
      /* Reserve trailing space for row suffix such as function count / width / exec info. */
1657
      int32_t stateKeyDescCap = (int32_t)sizeof(stateKeyDesc) - EXPLAIN_STATE_KEY_DESC_RESERVED_SIZE;
1,774,247✔
1658
      if (stateKeyDescCap < 128) {
1,774,247✔
1659
        stateKeyDescCap = (int32_t)sizeof(stateKeyDesc);
×
1660
      }
1661
      qExplainBuildStateKeyDesc(pStateNode->pStateKeys, stateKeyDesc, stateKeyDescCap);
1,774,247✔
1662

1663
      EXPLAIN_ROW_NEW(level, EXPLAIN_STATE_WINDOW_FORMAT, stateKeyDesc);
1,774,433✔
1664
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,774,433✔
1665
      if (pResNode->pExecInfo) {
1,774,433✔
1666
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,180✔
1667
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,180✔
1668
      }
1669

1670
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pStateNode->window.pFuncs));
1,774,433✔
1671
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,774,433✔
1672
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,774,433✔
1673
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,774,433✔
1674
      EXPLAIN_ROW_END();
1,774,433✔
1675
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,774,433✔
1676

1677
      if (verbose) {
1,774,528✔
1678
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
926,734✔
1679
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
926,734✔
1680
                           nodesGetOutputNumFromSlotList(pStateNode->window.node.pOutputDataBlockDesc->pSlots));
1681
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
926,820✔
1682
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->outputRowSize);
926,820✔
1683
        EXPLAIN_ROW_APPEND_LIMIT(pStateNode->window.node.pLimit);
926,820✔
1684
        EXPLAIN_ROW_APPEND_SLIMIT(pStateNode->window.node.pSlimit);
926,820✔
1685
        EXPLAIN_ROW_END();
926,820✔
1686
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
926,820✔
1687

1688
        EXPLAIN_ROW_END();
926,820✔
1689
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
926,820✔
1690

1691
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pStateNode->window.node.pConditions,
926,734✔
1692
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1693

1694
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
926,734✔
1695
      }
1696
      break;
1,774,992✔
1697
    }
1698
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
8,481,265✔
1699
      SPartitionPhysiNode *pPartNode = (SPartitionPhysiNode *)pNode;
8,481,265✔
1700

1701
      SNode *p = nodesListGetNode(pPartNode->pPartitionKeys, 0);
8,481,265✔
1702
      EXPLAIN_ROW_NEW(level, EXPLAIN_PARITION_FORMAT, nodesGetNameFromColumnNode(p));
8,482,012✔
1703
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
8,482,301✔
1704
      if (pResNode->pExecInfo) {
8,482,301✔
1705
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
151,757✔
1706
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
151,757✔
1707
      }
1708
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->totalRowSize);
8,482,301✔
1709

1710
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
8,482,301✔
1711
      EXPLAIN_ROW_END();
8,482,301✔
1712
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
8,482,301✔
1713

1714
      if (verbose) {
8,482,028✔
1715
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
3,932,885✔
1716
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
3,932,885✔
1717
                           nodesGetOutputNumFromSlotList(pPartNode->node.pOutputDataBlockDesc->pSlots));
1718
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,933,068✔
1719
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->outputRowSize);
3,933,068✔
1720
        EXPLAIN_ROW_APPEND_LIMIT(pPartNode->node.pLimit);
3,933,068✔
1721
        EXPLAIN_ROW_APPEND_SLIMIT(pPartNode->node.pSlimit);
3,933,068✔
1722
        EXPLAIN_ROW_END();
3,933,068✔
1723
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,933,068✔
1724

1725
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
3,932,878✔
1726
        EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pPartNode->pPartitionKeys->length);
3,932,878✔
1727
        EXPLAIN_ROW_END();
3,932,878✔
1728
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,932,878✔
1729

1730
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pPartNode->node.pConditions,
3,932,973✔
1731
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1732

1733
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
3,932,783✔
1734
      }
1735
      break;
8,481,557✔
1736
    }
1737
    case QUERY_NODE_PHYSICAL_PLAN_MERGE: {
14,490,036✔
1738
      SMergePhysiNode *pMergeNode = (SMergePhysiNode *)pNode;
14,490,036✔
1739
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_FORMAT);
14,490,036✔
1740
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
14,490,036✔
1741
      if (pResNode->pExecInfo) {
14,490,036✔
1742
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
533,900✔
1743
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
533,900✔
1744
      }
1745

1746
      SDataBlockDescNode *pDescNode = pMergeNode->node.pOutputDataBlockDesc;
14,490,036✔
1747
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
14,490,036✔
1748
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,490,127✔
1749
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
14,490,127✔
1750
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,490,127✔
1751
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.inputTsOrder));
14,490,127✔
1752
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,490,127✔
1753
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.outputTsOrder));
14,490,127✔
1754
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,490,127✔
1755
      EXPLAIN_ROW_APPEND(EXPLAIN_MERGE_MODE_FORMAT, EXPLAIN_MERGE_MODE_STRING(pMergeNode->type));
14,490,127✔
1756
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
14,490,127✔
1757
      EXPLAIN_ROW_END();
14,490,127✔
1758
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
14,490,127✔
1759

1760
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
14,490,033✔
1761
        if (MERGE_TYPE_SORT == pMergeNode->type) {
533,900✔
1762
          // sort method
1763
          EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
533,900✔
1764

1765
          int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
533,900✔
1766
          SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
533,900✔
1767
          SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
533,900✔
1768
          EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
533,900✔
1769
          if (pExecInfo->sortBuffer > 1024 * 1024) {
533,900✔
1770
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1771
          } else if (pExecInfo->sortBuffer > 1024) {
533,900✔
1772
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
533,900✔
1773
          } else {
1774
            EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1775
          }
1776

1777
          EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
533,900✔
1778
          EXPLAIN_ROW_END();
533,900✔
1779
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
533,900✔
1780
        }
1781
      }
1782

1783
      if (verbose) {
14,490,033✔
1784
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
5,683,677✔
1785
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
5,683,677✔
1786
                           nodesGetOutputNumFromSlotList(pMergeNode->node.pOutputDataBlockDesc->pSlots));
1787
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,683,772✔
1788
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pMergeNode->node.pOutputDataBlockDesc->outputRowSize);
5,683,772✔
1789
        EXPLAIN_ROW_APPEND_LIMIT(pMergeNode->node.pLimit);
5,683,772✔
1790
        EXPLAIN_ROW_APPEND_SLIMIT(pMergeNode->node.pSlimit);
5,683,772✔
1791
        EXPLAIN_ROW_END();
5,683,772✔
1792
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,683,772✔
1793

1794
        if (MERGE_TYPE_SORT == pMergeNode->type) {
5,683,596✔
1795
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
5,608,731✔
1796
          EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pMergeNode->ignoreGroupId ? "true" : "false");
5,608,731✔
1797
          EXPLAIN_ROW_END();
5,608,731✔
1798
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,608,731✔
1799

1800
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGE_KEYS_FORMAT);
5,609,002✔
1801
          if (pMergeNode->groupSort) {
5,609,002✔
1802
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, "_group_id asc");
2,578,643✔
1803
            if (LIST_LENGTH(pMergeNode->pMergeKeys) > 0) {
2,578,643✔
1804
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
2,225,240✔
1805
            }
1806
          }
1807
          for (int32_t i = 0; i < LIST_LENGTH(pMergeNode->pMergeKeys); ++i) {
11,471,272✔
1808
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pMergeNode->pMergeKeys, i);
5,862,089✔
1809
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, nodesGetNameFromColumnNode(ptn->pExpr));
5,862,089✔
1810
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,862,270✔
1811
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, EXPLAIN_ORDER_STRING(ptn->order));
5,862,270✔
1812
            if (i != LIST_LENGTH(pMergeNode->pMergeKeys) - 1) {
5,862,270✔
1813
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
606,766✔
1814
            }
1815
          }
1816
          EXPLAIN_ROW_END();
5,609,183✔
1817
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,609,183✔
1818
        }
1819

1820
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pMergeNode->node.pConditions,
5,683,591✔
1821
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1822

1823
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
5,683,496✔
1824
      }
1825
      break;
14,490,491✔
1826
    }
1827
    case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: {
×
1828
      SBlockDistScanPhysiNode *pDistScanNode = (SBlockDistScanPhysiNode *)pNode;
×
1829
      EXPLAIN_ROW_NEW(level, EXPLAIN_DISTBLK_SCAN_FORMAT, pDistScanNode->tableName.tname);
×
1830
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
1831
      if (pResNode->pExecInfo) {
×
1832
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
1833
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1834
      }
1835
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDistScanNode->pScanCols->length);
×
1836
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1837
      if (pDistScanNode->pScanPseudoCols) {
×
1838
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pDistScanNode->pScanPseudoCols->length);
×
1839
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1840
      }
1841
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->totalRowSize);
×
1842
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1843
      EXPLAIN_ROW_END();
×
1844
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1845

1846
      if (verbose) {
×
1847
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1848
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1849
                           nodesGetOutputNumFromSlotList(pDistScanNode->node.pOutputDataBlockDesc->pSlots));
1850
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1851
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->outputRowSize);
×
1852
        EXPLAIN_ROW_APPEND_LIMIT(pDistScanNode->node.pLimit);
×
1853
        EXPLAIN_ROW_APPEND_SLIMIT(pDistScanNode->node.pSlimit);
×
1854
        EXPLAIN_ROW_END();
×
1855
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1856

1857
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pDistScanNode->node.pConditions,
×
1858
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1859

1860
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
1861
      }
1862
      break;
×
1863
    }
1864
    case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: {
186,334✔
1865
      SLastRowScanPhysiNode *pLastRowNode = (SLastRowScanPhysiNode *)pNode;
186,334✔
1866
      EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->scan.tableName.tname);
186,334✔
1867
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
186,334✔
1868
      if (pResNode->pExecInfo) {
186,334✔
1869
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,180✔
1870
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,180✔
1871
      }
1872
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->scan.pScanCols->length);
186,334✔
1873
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
186,334✔
1874
      if (pLastRowNode->scan.pScanPseudoCols) {
186,334✔
1875
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
7,180✔
1876
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,180✔
1877
      }
1878
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
186,334✔
1879
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
186,334✔
1880
      EXPLAIN_ROW_END();
186,334✔
1881
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
186,334✔
1882

1883
      if (verbose) {
186,334✔
1884
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
93,004✔
1885
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
93,004✔
1886
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1887
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
93,004✔
1888
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
93,004✔
1889
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
93,004✔
1890
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
93,004✔
1891
        EXPLAIN_ROW_END();
93,004✔
1892
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
93,004✔
1893

1894
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pLastRowNode->scan.node.pConditions,
93,004✔
1895
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1896

1897
        if (qExplainCouldApplyTagIndex(pResNode->pPlan)) {
93,004✔
1898
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TAG_INDEX_FORMAT);
×
1899
          EXPLAIN_ROW_APPEND(EXPLAIN_FILTER_CONDITIONS_FORMAT);
×
1900
          QRY_ERR_RET(nodesNodeToSQL(pResNode->pPlan->pTagIndexCond, tbuf + VARSTR_HEADER_SIZE,
×
1901
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1902
          EXPLAIN_ROW_END();
×
1903
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1904
        }
1905
      }
1906
      break;
186,334✔
1907
    }
1908
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
7,842✔
1909
      STableCountScanPhysiNode *pLastRowNode = (STableCountScanPhysiNode *)pNode;
7,842✔
1910
      char *dbname = pLastRowNode->scan.tableName.dbname;
7,842✔
1911
      char *tbname = pLastRowNode->scan.tableName.tname;
7,842✔
1912
      if (dbname[0] != '\0' && tbname[0] != '\0') {
8,065✔
1913
        char name[TSDB_TABLE_FNAME_LEN];
223✔
1914
        snprintf(name, sizeof(name), "%s.%s", dbname, tbname);
223✔
1915
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, name);
223✔
1916
      } else if (dbname[0] != '\0') {
7,619✔
1917
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, dbname);
223✔
1918
      } else if (tbname[0] != '\0') {
7,396✔
1919
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, tbname);
223✔
1920
      } else {
1921
        EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT, TSDB_INS_TABLE_TABLES);
7,173✔
1922
      }
1923
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,842✔
1924
      if (pResNode->pExecInfo) {
7,842✔
1925
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
2,360✔
1926
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,360✔
1927
      }
1928
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, LIST_LENGTH(pLastRowNode->scan.pScanCols));
7,842✔
1929
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,842✔
1930
      if (pLastRowNode->scan.pScanPseudoCols) {
7,842✔
1931
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
7,842✔
1932
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,842✔
1933
      }
1934
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
7,842✔
1935
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,842✔
1936
      EXPLAIN_ROW_END();
7,842✔
1937
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,842✔
1938

1939
      if (verbose) {
7,842✔
1940
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4,720✔
1941
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
4,720✔
1942
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1943
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4,720✔
1944
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
4,720✔
1945
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
4,720✔
1946
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
4,720✔
1947
        EXPLAIN_ROW_END();
4,720✔
1948
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4,720✔
1949

1950
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pLastRowNode->scan.node.pConditions,
4,720✔
1951
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
1952

1953
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
4,720✔
1954
      }
1955
      break;
7,842✔
1956
    }
1957
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
47,200✔
1958
      SGroupSortPhysiNode *pSortNode = (SGroupSortPhysiNode *)pNode;
47,200✔
1959
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_SORT_FORMAT);
47,200✔
1960
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
47,200✔
1961
      if (pResNode->pExecInfo) {
47,200✔
1962
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
1963
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1964
      }
1965

1966
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
47,200✔
1967
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
47,200✔
1968
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47,200✔
1969
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
47,200✔
1970
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
47,200✔
1971
      EXPLAIN_ROW_END();
47,200✔
1972
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
47,200✔
1973

1974
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
47,200✔
1975
        // sort key
1976
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
×
1977
        if (pResNode->pExecInfo) {
×
1978
          for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
×
1979
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
×
1980
            EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
×
1981
          }
1982
        }
1983

1984
        EXPLAIN_ROW_END();
×
1985
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1986

1987
        // sort method
1988
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
×
1989

1990
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
×
1991
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
×
1992
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
×
1993
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
×
1994
        if (pExecInfo->sortBuffer > 1024 * 1024) {
×
1995
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1996
        } else if (pExecInfo->sortBuffer > 1024) {
×
1997
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
1998
        } else {
1999
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
2000
        }
2001

2002
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
×
2003
        EXPLAIN_ROW_END();
×
2004
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
2005
      }
2006

2007
      if (verbose) {
47,200✔
2008
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
2009
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
2010
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
2011
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2012
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
×
2013
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
×
2014
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
×
2015
        EXPLAIN_ROW_END();
×
2016
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2017

2018
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pSortNode->node.pConditions,
×
2019
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2020

2021
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
2022
      }
2023
      break;
47,200✔
2024
    }
2025
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: {
×
2026
      SMergeIntervalPhysiNode *pIntNode = (SMergeIntervalPhysiNode *)pNode;
×
2027
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
×
2028
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
2029
      if (pResNode->pExecInfo) {
×
2030
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2031
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2032
      }
2033
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pIntNode->window.pFuncs));
×
2034
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
2035
      EXPLAIN_ROW_END();
×
2036
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
2037

2038
      if (verbose) {
×
2039
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
2040
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
2041
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
2042
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2043
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
×
2044
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
×
2045
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
×
2046
        EXPLAIN_ROW_END();
×
2047
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2048
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
×
2049
        int64_t time1 = -1;
×
2050
        int64_t time2 = -1;
×
2051
        int32_t code = TSDB_CODE_SUCCESS;
×
2052
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
×
2053
        QRY_ERR_RET(code);
×
2054
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
×
2055
        QRY_ERR_RET(code);
×
2056
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
×
2057
                        time1,
2058
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
2059
                        time2,
2060
                        pIntNode->slidingUnit);
2061
        EXPLAIN_ROW_END();
×
2062
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2063

2064
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pIntNode->window.node.pConditions,
×
2065
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2066

2067
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
2068
      }
2069
      break;
×
2070
    }
2071
    case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
188,594✔
2072
      SInterpFuncPhysiNode *pInterpNode = (SInterpFuncPhysiNode *)pNode;
188,594✔
2073
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERP_FORMAT);
188,594✔
2074
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
188,594✔
2075
      if (pResNode->pExecInfo) {
188,594✔
2076
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
3,540✔
2077
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,540✔
2078
      }
2079
      if (pInterpNode->pFuncs) {
188,594✔
2080
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pInterpNode->pFuncs->length);
188,594✔
2081
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
188,594✔
2082
      }
2083

2084
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pInterpNode->fillMode));
188,594✔
2085

2086
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
188,594✔
2087
      EXPLAIN_ROW_END();
188,594✔
2088
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
188,594✔
2089

2090
      if (verbose) {
188,594✔
2091
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
188,594✔
2092
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
188,594✔
2093
                           nodesGetOutputNumFromSlotList(pInterpNode->node.pOutputDataBlockDesc->pSlots));
2094
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
188,594✔
2095
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pInterpNode->node.pOutputDataBlockDesc->outputRowSize);
188,594✔
2096
        EXPLAIN_ROW_APPEND_LIMIT(pInterpNode->node.pLimit);
188,594✔
2097
        EXPLAIN_ROW_APPEND_SLIMIT(pInterpNode->node.pSlimit);
188,594✔
2098
        EXPLAIN_ROW_END();
188,594✔
2099
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
188,594✔
2100
        if (pInterpNode->pFillValues) {
188,594✔
2101
          SNodeListNode *pValues = (SNodeListNode *)pInterpNode->pFillValues;
44,510✔
2102
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
44,510✔
2103
          SNode  *tNode = NULL;
44,510✔
2104
          int32_t i = 0;
44,510✔
2105
          FOREACH(tNode, pValues->pNodeList) {
89,020✔
2106
            if (i) {
44,510✔
2107
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2108
            }
2109
            SValueNode *tValue = (SValueNode *)tNode;
44,510✔
2110
            char       *value = nodesGetStrValueFromNode(tValue);
44,510✔
2111
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
44,510✔
2112
            taosMemoryFree(value);
44,510✔
2113
            ++i;
44,510✔
2114
          }
2115

2116
          EXPLAIN_ROW_END();
44,510✔
2117
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
44,510✔
2118
        }
2119

2120
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_INTERVAL_VALUE_FORMAT, pInterpNode->interval, pInterpNode->intervalUnit);
188,594✔
2121
        EXPLAIN_ROW_END();
188,594✔
2122

2123
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pInterpNode->timeRange.skey, pInterpNode->timeRange.ekey);
188,594✔
2124
        EXPLAIN_ROW_END();
188,594✔
2125
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
188,594✔
2126

2127
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pInterpNode->node.pConditions,
188,594✔
2128
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2129

2130
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
188,594✔
2131
      }
2132
      break;
188,594✔
2133
    }
2134
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT: {
1,913,255✔
2135
      SEventWinodwPhysiNode *pEventNode = (SEventWinodwPhysiNode *)pNode;
1,913,255✔
2136
      EXPLAIN_ROW_NEW(level, EXPLAIN_EVENT_FORMAT);
1,913,255✔
2137
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,913,255✔
2138
      if (pResNode->pExecInfo) {
1,913,255✔
2139
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,770✔
2140
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,770✔
2141
      }
2142
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pEventNode->window.pFuncs));
1,913,255✔
2143
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,913,255✔
2144
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pEventNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,913,255✔
2145
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,913,255✔
2146
      EXPLAIN_ROW_END();
1,913,255✔
2147
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,913,255✔
2148

2149
      if (verbose) {
1,913,541✔
2150
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_START_FORMAT);
1,029,206✔
2151
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pStartCond, tbuf + VARSTR_HEADER_SIZE,
1,029,206✔
2152
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2153
        EXPLAIN_ROW_END();
1,029,207✔
2154
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,029,207✔
2155

2156
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_END_FORMAT);
1,029,302✔
2157
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pEndCond, tbuf + VARSTR_HEADER_SIZE,
1,029,302✔
2158
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2159
        EXPLAIN_ROW_END();
1,029,302✔
2160
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,029,302✔
2161

2162
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
1,029,206✔
2163
      }
2164
      break;
1,913,447✔
2165
    }
2166
    case QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN:{
835,297✔
2167
      SHashJoinPhysiNode *pJoinNode = (SHashJoinPhysiNode *)pNode;
835,297✔
2168
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
835,297✔
2169
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
835,297✔
2170
      if (pResNode->pExecInfo) {
835,297✔
2171
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
892✔
2172
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
892✔
2173
      }
2174
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
835,297✔
2175
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2176
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
835,297✔
2177
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2178
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
835,297✔
2179
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2180
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Hash");
835,297✔
2181
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
835,297✔
2182
      EXPLAIN_ROW_END();
835,297✔
2183
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
835,297✔
2184

2185
      if (verbose) {
835,297✔
2186
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
892✔
2187
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
892✔
2188
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
2189
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
892✔
2190
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
892✔
2191
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
892✔
2192
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
892✔
2193
        EXPLAIN_ROW_END();
892✔
2194
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
892✔
2195

2196
        if (pJoinNode->node.pConditions) {
892✔
2197
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
2198
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
2199
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2200

2201
          EXPLAIN_ROW_END();
×
2202
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2203
        }
2204

2205
        bool conditionsGot = false;
892✔
2206
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
892✔
2207
        if (pJoinNode->pPrimKeyCond) {
892✔
2208
          QRY_ERR_RET(
×
2209
              nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2210
          conditionsGot = true;
×
2211
        }
2212
        if (pJoinNode->pColEqCond) {
892✔
2213
          if (conditionsGot) {
×
2214
            EXPLAIN_ROW_APPEND(" AND ");
×
2215
          }
2216
          QRY_ERR_RET(
×
2217
              nodesNodeToSQL(pJoinNode->pColEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2218
          conditionsGot = true;
×
2219
        }
2220
        if (pJoinNode->pTagEqCond) {
892✔
2221
          if (conditionsGot) {
892✔
2222
            EXPLAIN_ROW_APPEND(" AND ");
×
2223
          }
2224
          QRY_ERR_RET(
892✔
2225
              nodesNodeToSQL(pJoinNode->pTagEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2226
          conditionsGot = true;
892✔
2227
        }
2228
        if (pJoinNode->pFullOnCond) {
892✔
2229
          if (conditionsGot) {
×
2230
            EXPLAIN_ROW_APPEND(" AND ");
×
2231
          }
2232
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE,
×
2233
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
2234
        }
2235
        EXPLAIN_ROW_END();
892✔
2236
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
892✔
2237

2238
        if (pJoinNode->timeRangeTarget) {
892✔
2239
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TABLE_TIMERANGE_FORMAT, qExplainGetTimerangeTargetStr(pJoinNode->timeRangeTarget), pJoinNode->timeRange.skey, pJoinNode->timeRange.ekey);
×
2240
          EXPLAIN_ROW_END();
×
2241
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2242
        }
2243

2244
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
892✔
2245
      }
2246
      break;
835,297✔
2247
    }
2248
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE:{
835,297✔
2249
      SGroupCachePhysiNode *pGroupCache = (SGroupCachePhysiNode *)pNode;
835,297✔
2250
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_CACHE_FORMAT);
835,297✔
2251
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
835,297✔
2252
      if (pResNode->pExecInfo) {
835,297✔
2253
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
892✔
2254
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
892✔
2255
      }
2256
      EXPLAIN_ROW_APPEND(EXPLAIN_GLOBAL_GROUP_FORMAT, pGroupCache->globalGrp);
835,297✔
2257
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2258
      EXPLAIN_ROW_APPEND(EXPLAIN_GROUP_BY_UID_FORMAT, pGroupCache->grpByUid);
835,297✔
2259
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2260
      EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pGroupCache->batchFetch);
835,297✔
2261
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2262
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->totalRowSize);
835,297✔
2263
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2264
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pGroupCache->node.inputTsOrder));
835,297✔
2265
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
835,297✔
2266
      EXPLAIN_ROW_END();
835,297✔
2267
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
835,297✔
2268

2269
      if (verbose) {
835,297✔
2270
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
892✔
2271
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
892✔
2272
                           nodesGetOutputNumFromSlotList(pGroupCache->node.pOutputDataBlockDesc->pSlots));
2273
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
892✔
2274
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->outputRowSize);
892✔
2275
        EXPLAIN_ROW_APPEND_LIMIT(pGroupCache->node.pLimit);
892✔
2276
        EXPLAIN_ROW_APPEND_SLIMIT(pGroupCache->node.pSlimit);
892✔
2277
        EXPLAIN_ROW_END();
892✔
2278
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
892✔
2279
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pGroupCache->node.pConditions,
892✔
2280
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2281

2282
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
892✔
2283
      }
2284
      break;
835,297✔
2285
    }
2286
    case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:{
1,317,937✔
2287
      SDynQueryCtrlPhysiNode *pDyn = (SDynQueryCtrlPhysiNode *)pNode;
1,317,937✔
2288
      EXPLAIN_ROW_NEW(level, EXPLAIN_DYN_QRY_CTRL_FORMAT, qExplainGetDynQryCtrlType(pDyn));
1,317,937✔
2289
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,317,937✔
2290
      if (pResNode->pExecInfo) {
1,317,937✔
2291
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
3,252✔
2292
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,252✔
2293
      }
2294
      switch (pDyn->qType) {
1,317,937✔
2295
        case DYN_QTYPE_STB_HASH: {
835,297✔
2296
          EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pDyn->stbJoin.batchFetch);
835,297✔
2297
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2298
          EXPLAIN_ROW_APPEND(EXPLAIN_VGROUP_SLOT_FORMAT, pDyn->stbJoin.vgSlot[0], pDyn->stbJoin.vgSlot[1]);
835,297✔
2299
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2300
          EXPLAIN_ROW_APPEND(EXPLAIN_UID_SLOT_FORMAT, pDyn->stbJoin.uidSlot[0], pDyn->stbJoin.uidSlot[1]);
835,297✔
2301
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2302
          EXPLAIN_ROW_APPEND(EXPLAIN_SRC_SCAN_FORMAT, pDyn->stbJoin.srcScan[0], pDyn->stbJoin.srcScan[1]);
835,297✔
2303
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2304
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
835,297✔
2305
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
835,297✔
2306
          EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
835,297✔
2307
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
835,297✔
2308
          break;
835,297✔
2309
        }
2310
        case DYN_QTYPE_VTB_INTERVAL:
233,930✔
2311
        case DYN_QTYPE_VTB_AGG: {
2312
          EXPLAIN_ROW_APPEND(EXPLAIN_HAS_PARTITION_FORMAT, pDyn->vtbScan.hasPartition);
233,930✔
2313
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
233,930✔
2314
          EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_PROCESS_CHILD_FORMAT, pDyn->vtbScan.batchProcessChild);
233,930✔
2315
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
233,930✔
2316
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
233,930✔
2317
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
233,930✔
2318
          break;
233,930✔
2319
        }
2320
        case DYN_QTYPE_VTB_TS_SCAN:
154,621✔
2321
        case DYN_QTYPE_VTB_SCAN: {
2322
          EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDyn->vtbScan.pScanCols->length);
154,621✔
2323
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
154,621✔
2324
          EXPLAIN_ROW_APPEND(EXPLAIN_ORIGIN_VGROUP_NUM_FORMAT, pDyn->vtbScan.pOrgVgIds->length);
154,621✔
2325
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
154,621✔
2326
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
154,621✔
2327
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
154,621✔
2328
          EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
154,621✔
2329
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
154,621✔
2330
          break;
154,621✔
2331
        }
2332
        case DYN_QTYPE_VTB_WINDOW: {
94,089✔
2333
          EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDyn->vtbWindow.pTargets->length);
94,089✔
2334
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
94,089✔
2335
          EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
94,089✔
2336
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
94,089✔
2337
          EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
94,089✔
2338
          EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
94,089✔
2339
          break;
94,089✔
2340
        }
2341
        default:
×
2342
          break;
×
2343
      }
2344

2345
      EXPLAIN_ROW_END();
1,317,937✔
2346
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,317,937✔
2347

2348
      if (verbose) {
1,317,937✔
2349
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
206,960✔
2350
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
206,960✔
2351
                           nodesGetOutputNumFromSlotList(pDyn->node.pOutputDataBlockDesc->pSlots));
2352
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
206,960✔
2353
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->outputRowSize);
206,960✔
2354
        EXPLAIN_ROW_APPEND_LIMIT(pDyn->node.pLimit);
206,960✔
2355
        EXPLAIN_ROW_APPEND_SLIMIT(pDyn->node.pSlimit);
206,960✔
2356
        EXPLAIN_ROW_END();
206,960✔
2357
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
206,960✔
2358

2359
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pDyn->node.pConditions,
206,960✔
2360
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2361

2362
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
206,960✔
2363
      }
2364
      break;
1,317,937✔
2365
    }
2366
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT: {
1,709,711✔
2367
      SCountWindowPhysiNode *pCountNode = (SCountWindowPhysiNode *)pNode;
1,709,711✔
2368
      EXPLAIN_ROW_NEW(level, EXPLAIN_COUNT_FORMAT);
1,709,711✔
2369
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,709,711✔
2370
      if (pResNode->pExecInfo) {
1,709,711✔
2371
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
1,180✔
2372
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,180✔
2373
      }
2374
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pCountNode->window.pFuncs));
1,709,711✔
2375
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,709,711✔
2376
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pCountNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,709,711✔
2377
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,709,711✔
2378
      EXPLAIN_ROW_END();
1,709,711✔
2379
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,709,711✔
2380

2381
      if (verbose) {
1,710,081✔
2382
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_NUM_FORMAT, pCountNode->windowCount);
909,266✔
2383
        EXPLAIN_ROW_END();
909,266✔
2384
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
909,266✔
2385
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_SLIDING_FORMAT, pCountNode->windowSliding);
909,178✔
2386
        EXPLAIN_ROW_END();
909,178✔
2387
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
909,178✔
2388

2389
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
909,266✔
2390
      }
2391
      break;
1,709,933✔
2392
    }
2393
    case QUERY_NODE_PHYSICAL_PLAN_EXTERNAL_WINDOW: {
×
2394
      SExternalWindowPhysiNode *pExternal = (SExternalWindowPhysiNode *)pNode;
×
2395
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXTERNAL_FORMAT, nodesGetNameFromColumnNode(pExternal->window.pTspk));
×
2396
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
2397
      if (pResNode->pExecInfo) {
×
2398
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2399
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2400
      }
2401
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pExternal->window.pFuncs));
×
2402
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2403
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->totalRowSize);
×
2404
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2405
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.inputTsOrder));
×
2406
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2407
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.outputTsOrder));
×
2408
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
2409
      EXPLAIN_ROW_END();
×
2410
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
2411

2412
      if (verbose) {
×
2413
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
2414
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
2415
                           nodesGetOutputNumFromSlotList(pExternal->window.node.pOutputDataBlockDesc->pSlots));
2416
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2417
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->outputRowSize);
×
2418
        EXPLAIN_ROW_APPEND_LIMIT(pExternal->window.node.pLimit);
×
2419
        EXPLAIN_ROW_APPEND_SLIMIT(pExternal->window.node.pSlimit);
×
2420
        EXPLAIN_ROW_END();
×
2421
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2422
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pExternal->timeRange.skey, pExternal->timeRange.ekey);
×
2423
        EXPLAIN_ROW_END();
×
2424
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2425

2426
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExternal->window.node.pConditions,
×
2427
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2428

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

2433
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
2434
      }
2435
      break;
×
2436
    }
2437
    case QUERY_NODE_PHYSICAL_PLAN_HASH_EXTERNAL: {
115,389✔
2438
      SExternalWindowPhysiNode *pExternal = (SExternalWindowPhysiNode *)pNode;
115,389✔
2439
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXTERNAL_FORMAT, nodesGetNameFromColumnNode(pExternal->window.pTspk));
115,389✔
2440
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
115,389✔
2441
      if (pResNode->pExecInfo) {
115,389✔
2442
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2443
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2444
      }
2445
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pExternal->window.pFuncs));
115,389✔
2446
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
115,389✔
2447
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->totalRowSize);
115,389✔
2448
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
115,389✔
2449
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.inputTsOrder));
115,389✔
2450
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
115,389✔
2451
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.outputTsOrder));
115,389✔
2452
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
115,389✔
2453
      EXPLAIN_ROW_END();
115,389✔
2454
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
115,389✔
2455

2456
      if (verbose) {
115,389✔
2457
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
115,389✔
2458
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
115,389✔
2459
                           nodesGetOutputNumFromSlotList(pExternal->window.node.pOutputDataBlockDesc->pSlots));
2460
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
115,389✔
2461
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->outputRowSize);
115,389✔
2462
        EXPLAIN_ROW_APPEND_LIMIT(pExternal->window.node.pLimit);
115,389✔
2463
        EXPLAIN_ROW_APPEND_SLIMIT(pExternal->window.node.pSlimit);
115,389✔
2464
        EXPLAIN_ROW_END();
115,389✔
2465
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
115,389✔
2466
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pExternal->timeRange.skey, pExternal->timeRange.ekey);
115,389✔
2467
        EXPLAIN_ROW_END();
115,389✔
2468
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
115,389✔
2469

2470
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExternal->window.node.pConditions,
115,389✔
2471
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2472

2473
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pExternal->window.mergeDataBlock? "True":"False");
115,389✔
2474
        EXPLAIN_ROW_END();
115,389✔
2475
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
115,389✔
2476

2477
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
115,389✔
2478
      }
2479
      break;
115,389✔
2480
    }
2481
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_EXTERNAL: {
×
2482
      SExternalWindowPhysiNode *pExternal = (SExternalWindowPhysiNode *)pNode;
×
2483
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_EXTERNAL_FORMAT, nodesGetNameFromColumnNode(pExternal->window.pTspk));
×
2484
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
2485
      if (pResNode->pExecInfo) {
×
2486
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen, &filterEfficiency));
×
2487
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2488
      }
2489
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, LIST_LENGTH(pExternal->window.pFuncs));
×
2490
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2491
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->totalRowSize);
×
2492
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2493
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.inputTsOrder));
×
2494
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2495
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pExternal->window.node.outputTsOrder));
×
2496
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
2497
      EXPLAIN_ROW_END();
×
2498
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
2499

2500
      if (verbose) {
×
2501
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
2502
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
2503
                           nodesGetOutputNumFromSlotList(pExternal->window.node.pOutputDataBlockDesc->pSlots));
2504
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
2505
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExternal->window.node.pOutputDataBlockDesc->outputRowSize);
×
2506
        EXPLAIN_ROW_APPEND_LIMIT(pExternal->window.node.pLimit);
×
2507
        EXPLAIN_ROW_APPEND_SLIMIT(pExternal->window.node.pSlimit);
×
2508
        EXPLAIN_ROW_END();
×
2509
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2510

2511
        QRY_ERR_RET(qExplainAppendFilterRow(ctx, level, pExternal->window.node.pConditions,
×
2512
                                            &tlen, hasEfficiency ? &filterEfficiency : NULL));
2513

2514
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pExternal->window.mergeDataBlock? "True":"False");
×
2515
        EXPLAIN_ROW_END();
×
2516
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
2517

2518
        QRY_ERR_RET(qExplainExecAnalyze(pResNode, ctx, level));
×
2519
      }
2520
      break;
×
2521
    }
2522
    default:
×
2523
      qError("not supported physical node type %d", pNode->type);
×
2524
      return TSDB_CODE_APP_ERROR;
×
2525
  }
2526

2527
  return TSDB_CODE_SUCCESS;
403,734,989✔
2528
}
2529

2530
static int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t *level) {
403,666,051✔
2531
  if (NULL == pResNode) {
403,666,051✔
2532
    qError("explain res node is NULL");
×
2533
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2534
  }
2535

2536
  int32_t code = 0;
403,666,051✔
2537
  QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
403,666,051✔
2538

2539
  SNode *pNode = NULL;
403,721,734✔
2540
  FOREACH(pNode, pResNode->pChildren) { 
624,910,250✔
2541
    int32_t nlevel = *level + 1;
221,182,773✔
2542
    QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, &nlevel)); 
221,182,773✔
2543
  }
2544

2545
  return TSDB_CODE_SUCCESS;
403,727,477✔
2546
}
2547

2548
static int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t *level, bool grpSingleChannel) {
180,576,191✔
2549
  SExplainResNode *node = NULL;
180,576,191✔
2550
  int32_t          code = 0;
180,576,191✔
2551
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
180,576,191✔
2552

2553
  SExplainGroup *group = taosHashGet(ctx->pCurrPlanCtx->groupHash, &groupId, sizeof(groupId));
180,576,191✔
2554
  if (NULL == group) {
180,595,475✔
2555
    qError("group %d not in groupHash", groupId);
×
2556
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2557
  }
2558

2559
  group->singleChannel = grpSingleChannel;
180,595,475✔
2560
  group->physiPlanExecIdx = 0;
180,595,475✔
2561

2562
  QRY_ERR_RET(qExplainGenerateResNode(group->plan, group->plan->pNode, group, &node));
180,595,475✔
2563

2564
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
180,590,884✔
2565

2566
_return:
180,589,630✔
2567

2568
  qExplainFreeResNode(node);
180,589,630✔
2569

2570
  QRY_RET(code);
180,600,060✔
2571
}
2572

2573
/**
2574
  @brief Append explain rows for one group filtered by exchange children vgIds.
2575
*/
2576
static int32_t qExplainAppendGroupResRowsByVgIds(void *pCtx, int32_t groupId, int32_t *level,
1,951,965✔
2577
                                                 bool grpSingleChannel, const SArray* pVgIds) {
2578
  SExplainResNode *node = NULL;
1,951,965✔
2579
  int32_t          code = 0;
1,951,965✔
2580
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
1,951,965✔
2581
  SExplainGroup    filtered = {0};
1,951,965✔
2582

2583
  SExplainGroup *group = taosHashGet(ctx->pCurrPlanCtx->groupHash, &groupId, sizeof(groupId));
1,951,965✔
2584
  if (NULL == group) {
1,951,965✔
2585
    qError("%s failed at line %d, group %d not in groupHash",
×
2586
           __func__, __LINE__, groupId);
2587
    QRY_ERR_RET(TSDB_CODE_INTERNAL_ERROR);
×
2588
  }
2589

2590
  filtered.plan = group->plan;
1,951,965✔
2591
  filtered.singleChannel = false;
1,951,965✔
2592
  filtered.physiPlanExecIdx = 0;
1,951,965✔
2593

2594
  if (group->nodeExecInfo && pVgIds) {
1,951,965✔
2595
    int32_t rspCnt = (int32_t)taosArrayGetSize(group->nodeExecInfo);
1,951,965✔
2596
    filtered.nodeExecInfo = taosArrayInit(rspCnt, sizeof(SExplainRsp));
1,951,965✔
2597
    if (NULL == filtered.nodeExecInfo) {
1,951,965✔
2598
      QRY_ERR_RET(terrno);
×
2599
    }
2600

2601
    for (int32_t i = 0; i < rspCnt; ++i) {
7,085,287✔
2602
      const SExplainRsp *pRsp = taosArrayGet(group->nodeExecInfo, i);
5,133,322✔
2603
      if (!qExplainRspMatchVgIds(pRsp, pVgIds)) {
5,133,322✔
2604
        continue;
2,902,266✔
2605
      }
2606
      if (NULL == taosArrayPush(filtered.nodeExecInfo, pRsp)) {
4,462,112✔
2607
        QRY_ERR_JRET(terrno);
×
2608
      }
2609
    }
2610

2611
    filtered.nodeNum = (int32_t)taosArrayGetSize(filtered.nodeExecInfo);
1,951,965✔
2612
  } else {
2613
    filtered.nodeNum = group->nodeNum;
×
2614
    filtered.nodeExecInfo = group->nodeExecInfo;
×
2615
    filtered.singleChannel = grpSingleChannel;
×
2616
  }
2617

2618
  if (filtered.nodeNum <= 0) {
1,951,965✔
2619
    goto _return;
×
2620
  }
2621

2622
  QRY_ERR_RET(qExplainGenerateResNode(filtered.plan, filtered.plan->pNode, &filtered, &node));
1,951,965✔
2623
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
1,951,965✔
2624

2625
_return:
1,951,965✔
2626
  qExplainFreeResNode(node);
1,951,965✔
2627
  if (filtered.nodeExecInfo != group->nodeExecInfo) {
1,951,965✔
2628
    taosArrayDestroy(filtered.nodeExecInfo);
1,951,965✔
2629
  }
2630
  QRY_RET(code);
1,951,965✔
2631
}
2632

2633
static int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
36,239,210✔
2634
  int32_t      code = 0;
36,239,210✔
2635
  SSDataBlock *pBlock = NULL;
36,239,210✔
2636
  SExplainCtx *pCtx = (SExplainCtx *)ctx;
36,239,210✔
2637
  int32_t      rowNum = taosArrayGetSize(pCtx->rows);
36,239,210✔
2638
  if (rowNum <= 0) {
36,239,310✔
2639
    qError("empty explain res rows");
×
2640
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2641
  }
2642

2643
  code = createDataBlock(&pBlock);
36,239,310✔
2644
  QRY_ERR_JRET(code);
36,239,440✔
2645

2646
  SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, TSDB_EXPLAIN_RESULT_ROW_SIZE, 1);
36,239,440✔
2647
  QRY_ERR_JRET(blockDataAppendColInfo(pBlock, &infoData));
36,239,171✔
2648
  QRY_ERR_JRET(blockDataEnsureCapacity(pBlock, rowNum));
36,238,886✔
2649

2650
  SColumnInfoData *pInfoData = taosArrayGet(pBlock->pDataBlock, 0);
36,237,783✔
2651

2652
  for (int32_t i = 0; i < rowNum; ++i) {
888,805,918✔
2653
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
852,575,894✔
2654
    QRY_ERR_JRET(colDataSetVal(pInfoData, i, row->buf, false));
852,569,279✔
2655
  }
2656

2657
  pBlock->info.rows = rowNum;
36,230,024✔
2658

2659
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
36,230,024✔
2660
  int32_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
36,236,554✔
2661

2662
  SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
36,236,554✔
2663
  if (NULL == rsp) {
36,237,283✔
2664
    qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
×
2665
    QRY_ERR_JRET(terrno);
×
2666
  }
2667

2668
  rsp->completed = 1;
36,237,283✔
2669
  rsp->numOfRows = htobe64((int64_t)rowNum);
36,237,283✔
2670

2671
  int32_t len = blockEncode(pBlock, rsp->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, taosArrayGetSize(pBlock->pDataBlock));
36,238,691✔
2672
  if(len < 0) {
36,233,290✔
2673
    qError("qExplainGetRspFromCtx: blockEncode failed");
×
2674
    QRY_ERR_JRET(terrno);
×
2675
  }
2676

2677
  rsp->compLen = htonl(len);
36,234,411✔
2678
  rsp->payloadLen = htonl(len);
36,234,411✔
2679
  rsp->compressed = 0;
36,234,411✔
2680

2681
  SET_PAYLOAD_LEN(rsp->data, len, len);
36,234,411✔
2682

2683
_return:
36,234,411✔
2684
  blockDataDestroy(pBlock);
36,234,411✔
2685

2686
  *pRsp = rsp;
36,239,253✔
2687
  QRY_RET(code);
36,239,253✔
2688
}
2689

2690
static int32_t qExplainBuildPlanCtx(SQueryPlan *pDag, SExplainPlanCtx *pCtx) {
174,040,238✔
2691
  int32_t        code = 0;
174,040,238✔
2692
  SNodeListNode *plans = NULL;
174,040,238✔
2693
  int32_t        taskNum = 0;
174,040,238✔
2694
  SExplainGroup *pGroup = NULL;
174,040,238✔
2695

2696
  if (pDag->numOfSubplans <= 0) {
174,040,238✔
2697
    qError("invalid subplan num:%d", pDag->numOfSubplans);
×
2698
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
3,988✔
2699
  }
2700

2701
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
174,044,226✔
2702
  if (levelNum <= 0) {
174,044,226✔
2703
    qError("invalid level num:%d", levelNum);
×
2704
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2705
  }
2706

2707
  pCtx->groupHash = taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT),
174,044,226✔
2708
                                 false, HASH_NO_LOCK);
2709
  if (NULL == pCtx->groupHash) {
174,054,147✔
2710
    qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
×
2711
    QRY_ERR_RET(terrno);
×
2712
  }
2713

2714
  int32_t i = 0;
174,051,692✔
2715
  SNode*  levelNode = NULL;
174,051,692✔
2716
  FOREACH(levelNode, pDag->pSubplans) {
417,350,118✔
2717
    plans = (SNodeListNode *)levelNode;
243,289,292✔
2718
    if (NULL == plans) {
243,289,292✔
2719
      qError("empty level plan, level:%d", i);
×
2720
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2721
    }
2722

2723
    taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
243,282,754✔
2724
    if (taskNum <= 0) {
243,282,754✔
2725
      qError("invalid level plan number:%d, level:%d", taskNum, i);
×
2726
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2727
    }
2728

2729
    SSubplan *plan = NULL;
243,277,816✔
2730
    int32_t   n = 0;
243,277,816✔
2731
    SNode*    taskNode = NULL;
243,277,816✔
2732
    FOREACH(taskNode, plans->pNodeList) {
573,735,853✔
2733
      plan = (SSubplan *)taskNode;
330,412,410✔
2734
      pGroup = taosHashGet(pCtx->groupHash, &plan->id.groupId, sizeof(plan->id.groupId));
330,412,410✔
2735
      if (pGroup) {
330,415,497✔
2736
        ++pGroup->nodeNum;
57,531,978✔
2737
        ++n;
57,531,978✔
2738
        continue;
57,531,978✔
2739
      }
2740

2741
      SExplainGroup group = {0};
272,883,519✔
2742
      group.nodeNum = 1;
272,883,519✔
2743
      group.plan = plan;
272,883,519✔
2744

2745
      if (0 != taosHashPut(pCtx->groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
272,883,519✔
2746
        qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
×
2747
        QRY_ERR_JRET(terrno);
×
2748
      }
2749
      ++n;
272,926,059✔
2750
    }
2751

2752
    if (0 == i) {
243,323,443✔
2753
      if (taskNum > 1) {
174,064,349✔
2754
        qError("invalid taskNum %d for level 0", taskNum);
×
2755
        QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2756
      }
2757

2758
      pCtx->rootGroupId = plan->id.groupId;
174,060,289✔
2759
    }
2760

2761
    qDebug("level %d group handled, taskNum:%d", i, taskNum);
243,319,383✔
2762
    ++i;
243,298,426✔
2763
  }
2764

2765
  pCtx->groupNum = taosHashGetSize(pCtx->groupHash);
174,060,826✔
2766

2767
  return TSDB_CODE_SUCCESS;
174,046,575✔
2768

2769
_return:
×
2770

2771
  if (code) {
×
2772
    qError("QID:0x%" PRIx64 " %s failed since %s", pDag->queryId, __func__, tstrerror(code));
×
2773
  }
2774
  
2775
  QRY_RET(code);
×
2776
}
2777

2778
static int32_t qExplainBuildCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
53,799,102✔
2779
  int32_t        code = 0;
53,799,102✔
2780
  SNodeListNode *plans = NULL;
53,799,102✔
2781
  int32_t        taskNum = 0;
53,799,102✔
2782
  SExplainGroup *pGroup = NULL;
53,799,102✔
2783
  SExplainCtx   *ctx = NULL;
53,799,102✔
2784

2785
  if (pDag->numOfSubplans <= 0) {
53,799,102✔
2786
    qError("invalid subplan num:%d", pDag->numOfSubplans);
×
2787
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
203✔
2788
  }
2789

2790
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
53,799,305✔
2791
  if (levelNum <= 0) {
53,799,305✔
2792
    qError("invalid level num:%d", levelNum);
×
2793
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2794
  }
2795

2796
  QRY_ERR_JRET(qExplainInitCtx(&ctx, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
53,799,305✔
2797

2798
  QRY_ERR_JRET(qExplainBuildPlanCtx(pDag, &ctx->planCtx));
53,822,275✔
2799
  ctx->groupNum = ctx->planCtx.groupNum;
53,812,424✔
2800

2801
  if (pDag->pChildren && pDag->pChildren->length > 0) {
53,812,424✔
2802
    ctx->subPlanCtxs = taosArrayInit_s(sizeof(SExplainPlanCtx), pDag->pChildren->length);
39,953,656✔
2803
    if (NULL == ctx->subPlanCtxs) {
39,973,650✔
2804
      qError("taosArrayInit %d explainPlanCtx failed, error:%s", pDag->pChildren->length, tstrerror(terrno));
×
2805
      QRY_ERR_JRET(terrno);
×
2806
    }
2807
    
2808
    SNode* pNode = NULL;
39,960,844✔
2809
    int32_t i = 0;
39,960,844✔
2810
    FOREACH(pNode, pDag->pChildren) {
160,200,724✔
2811
      SExplainPlanCtx* pSub = taosArrayGet(ctx->subPlanCtxs, i);
120,234,788✔
2812
      QRY_ERR_JRET(qExplainBuildPlanCtx((SQueryPlan*)pNode, pSub));
120,228,249✔
2813
      ctx->groupNum += pSub->groupNum;
120,239,880✔
2814
      i++;
120,239,880✔
2815
    }
2816
  }
2817

2818
  *pCtx = ctx;
53,824,704✔
2819

2820
  return TSDB_CODE_SUCCESS;
53,824,704✔
2821

2822
_return:
×
2823

2824
  qExplainFreeCtx(ctx);
×
2825

2826
  QRY_RET(code);
×
2827
}
2828

2829
static int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
36,239,837✔
2830
  if (EXPLAIN_MODE_ANALYZE != pCtx->mode) {
36,239,837✔
2831
    return TSDB_CODE_SUCCESS;
35,046,850✔
2832
  }
2833

2834
  int32_t tlen = 0;
1,192,987✔
2835
  char   *tbuf = pCtx->tbuf;
1,192,987✔
2836

2837
  // NOTE: remove comment after RATIO is implemented
2838
  // EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
2839
  // EXPLAIN_SUM_ROW_END();
2840
  // QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
2841

2842
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_PLANNING_TIME_FORMAT,
1,192,987✔
2843
    EXPLAIN_CONVERT_TS_US_TO_MS(pCtx->jobStartTs - pCtx->reqStartTs));
2844
  EXPLAIN_SUM_ROW_END();
1,192,987✔
2845
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
1,192,987✔
2846

2847
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_EXEC_TIME_FORMAT,
1,192,986✔
2848
    EXPLAIN_CONVERT_TS_US_TO_MS(pCtx->jobDoneTs - pCtx->jobStartTs));
2849
  EXPLAIN_SUM_ROW_END();
1,192,986✔
2850
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
1,192,986✔
2851

2852
  return TSDB_CODE_SUCCESS;
1,192,986✔
2853
}
2854

2855
static int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
36,233,250✔
2856
  int32_t level = 0;
36,233,250✔
2857
  
2858
  pCtx->currPlanId = -1;
36,233,250✔
2859
  pCtx->pCurrPlanCtx = &pCtx->planCtx;
36,233,250✔
2860
  QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->pCurrPlanCtx->rootGroupId, &level, false));
36,233,250✔
2861
  
2862
  if (pCtx->subPlanCtxs) {
36,238,813✔
2863
    int32_t subNum = taosArrayGetSize(pCtx->subPlanCtxs);
22,400,968✔
2864
    for (pCtx->currPlanId = subNum - 1; pCtx->currPlanId >= 0; --pCtx->currPlanId) {
89,559,436✔
2865
      pCtx->pCurrPlanCtx = taosArrayGet(pCtx->subPlanCtxs, pCtx->currPlanId);
67,153,171✔
2866
      level = 0;
67,154,039✔
2867
      QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->pCurrPlanCtx->rootGroupId, &level, false));
67,154,039✔
2868
    }
2869
  }
2870
  QRY_ERR_RET(qExplainAppendPlanRows(pCtx));
36,244,110✔
2871
  QRY_ERR_RET(qExplainGetRspFromCtx(pCtx, pRsp));
36,240,121✔
2872

2873
  return TSDB_CODE_SUCCESS;
36,237,788✔
2874
}
2875

2876
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainPlanCtx *pCurrPlanCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
89,477,240✔
2877
  if (!pCtx || !pCurrPlanCtx || !pRspMsg || !pRsp) return TSDB_CODE_INVALID_PARA;
89,477,240✔
2878
  SExplainResNode *node = NULL;
89,489,148✔
2879
  int32_t          code = 0;
89,489,148✔
2880
  bool             groupDone = false;
89,489,148✔
2881

2882
  SExplainGroup *group = taosHashGet(pCurrPlanCtx->groupHash, &groupId, sizeof(groupId));
89,489,148✔
2883
  if (NULL == group) {
89,490,914✔
2884
    qError("group %d not in groupHash", groupId);
×
2885
    tFreeSExplainRsp(pRspMsg);
×
2886
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2887
  }
2888

2889
  taosWLockLatch(&group->lock);
89,490,914✔
2890
  if (NULL == group->nodeExecInfo) {
89,493,270✔
2891
    group->nodeExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainRsp));
77,808,566✔
2892
    if (NULL == group->nodeExecInfo) {
77,807,357✔
2893
      qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
2894
      code = terrno;
×
2895
      TAOS_CHECK_ERRNO(code);
×
2896
    }
2897

2898
    group->physiPlanExecNum = pRspMsg->numOfPlans;
77,805,094✔
2899
  } else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
11,683,812✔
2900
    qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo),
×
2901
           group->nodeNum);
2902
    code = TSDB_CODE_APP_ERROR;
×
2903
    TAOS_CHECK_ERRNO(code);
×
2904
  }
2905

2906
  if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
89,490,172✔
2907
    qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum,
×
2908
           groupId);
2909
    code = TSDB_CODE_APP_ERROR;
×
2910
    TAOS_CHECK_ERRNO(code);
×
2911
  }
2912

2913
  if(taosArrayPush(group->nodeExecInfo, pRspMsg) == NULL)
178,971,849✔
2914
  {
2915
    code = terrno;
×
2916
    TAOS_CHECK_ERRNO(code);
×
2917
  }
2918

2919
  groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
89,481,231✔
2920

2921
  taosWUnLockLatch(&group->lock);
89,479,338✔
2922

2923
  if (groupDone && (pCtx->groupNum == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
89,493,352✔
2924
    if (atomic_load_8((int8_t *)&pCtx->execDone)) {
10,893,228✔
2925
      if (0 == taosWTryLockLatch(&pCtx->lock)) {
3,252✔
2926
        QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
3,252✔
2927
        // LEAVE LOCK THERE
2928
      }
2929
    }
2930
  }
2931

2932
  return TSDB_CODE_SUCCESS;
89,488,458✔
2933

2934
_exit:
×
2935
  tFreeSExplainRsp(pRspMsg);
×
2936
  taosWUnLockLatch(&group->lock);
×
2937
  return code;
×
2938
}
2939

2940
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
35,025,961✔
2941
  if (!pDag || !pRsp) return TSDB_CODE_INVALID_PARA;
35,025,961✔
2942
  int32_t      code = 0;
35,039,199✔
2943
  SExplainCtx *pCtx = NULL;
35,039,199✔
2944

2945
  QRY_ERR_RET(qExplainBuildCtx(pDag, &pCtx));
35,039,199✔
2946
  QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
35,046,917✔
2947

2948
_return:
35,043,404✔
2949
  qExplainFreeCtx(pCtx);
35,043,404✔
2950
  QRY_RET(code);
35,047,114✔
2951
}
2952

2953
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
18,771,260✔
2954
  if(!pDag || !pCtx) return TSDB_CODE_INVALID_PARA;
18,771,260✔
2955
  QRY_ERR_RET(qExplainBuildCtx(pDag, pCtx));
18,775,659✔
2956

2957
  (*pCtx)->reqStartTs = startTs;
18,777,863✔
2958
  (*pCtx)->jobStartTs = taosGetTimestampUs();
19,980,564✔
2959

2960
  return TSDB_CODE_SUCCESS;
18,776,670✔
2961
}
2962

2963
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
1,192,986✔
2964
  if(!pCtx || !pRsp) {
1,192,986✔
2965
    return TSDB_CODE_INVALID_PARA;
×
2966
  }
2967
  
2968
  int32_t code = 0;
1,192,986✔
2969
  pCtx->jobDoneTs = taosGetTimestampUs();
1,192,986✔
2970

2971
  atomic_store_8((int8_t *)&pCtx->execDone, true);
1,192,986✔
2972

2973
  if (pCtx->groupNum == atomic_load_32(&pCtx->groupDoneNum)) {
1,192,986✔
2974
    if (0 == taosWTryLockLatch(&pCtx->lock)) {
1,189,734✔
2975
      QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
1,189,734✔
2976
      // LEAVE LOCK THERE
2977
    }
2978
  }
2979

2980
  return TSDB_CODE_SUCCESS;
1,192,986✔
2981
}
2982

2983
SExplainPlanCtx* qExplainGetCurrPlan(SExplainCtx *pCtx, int32_t subJobId) {
89,474,334✔
2984
  return EXPLAIN_GET_CUR_PLAN_CTX(pCtx, subJobId);
89,474,334✔
2985
}
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