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

taosdata / TDengine / #3660

15 Mar 2025 09:06AM UTC coverage: 62.039% (-1.3%) from 63.314%
#3660

push

travis-ci

web-flow
feat(stream): support stream processing for virtual tables (#30144)

* enh: add client processing

* enh: add mnode vtables processing

* enh: add mnode vtable processing

* enh: add normal child vtable support

* fix: compile issues

* fix: compile issues

* fix: create stream issues

* fix: multi stream scan issue

* fix: remove debug info

* fix: agg task and task level issues

* fix: correct task output type

* fix: split vtablescan from agg

* fix: memory leak issues

* fix: add limitations

* Update 09-error-code.md

* Update 09-error-code.md

* fix: remove usless case

* feat(stream): extract original table data in source scan task

Implemented functionality in the source task to extract data
corresponding to the virtual table from the original table using WAL.
The extracted data is then sent to the downstream merge task for further
processing.

* feat(stream): multi-way merge using loser tree in virtual merge task

Implemented multi-way merge in the merge task using a loser tree to
combine data from multiple original table into a single virtual table.
The merged virtual table data is then pushed downstream for further
processing.  Introduced memory limit handling during the merge process
with configurable behavior when the memory limit is reached.

* fix(test): remove useless cases

---------

Co-authored-by: dapan1121 <wpan@taosdata.com>
Co-authored-by: Pan Wei <72057773+dapan1121@users.noreply.github.com>

154078 of 317582 branches covered (48.52%)

Branch coverage included in aggregate %.

313 of 2391 new or added lines in 34 files covered. (13.09%)

26134 existing lines in 205 files now uncovered.

240261 of 318051 relevant lines covered (75.54%)

16655189.27 hits per line

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

56.85
/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 "tcommon.h"
21
#include "tdatablock.h"
22
#include "systable.h"
23
#include "functionMgt.h"
24

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

33
static int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
34
static int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level, bool singleChannel);
35

36
char *qExplainGetDynQryCtrlType(EDynQueryType type) {
7,912✔
37
  switch (type) {
7,912!
38
    case DYN_QTYPE_STB_HASH:
7,912✔
39
      return "STable Join";
7,912✔
40
    default:
×
41
      break;
×
42
  }
43

44
  return "unknown task";
×
45
}
46

47
char* qExplainGetAsofOpStr(int32_t opType) {
112✔
48
  switch (opType) {
112!
49
    case OP_TYPE_GREATER_THAN:
4✔
50
      return ">";
4✔
51
    case OP_TYPE_GREATER_EQUAL:
18✔
52
      return ">=";
18✔
53
    case OP_TYPE_LOWER_THAN:
×
54
      return "<";
×
55
    case OP_TYPE_LOWER_EQUAL:
18✔
56
      return "<=";
18✔
57
    case OP_TYPE_EQUAL:
72✔
58
      return "=";
72✔
59
    default:
×
60
      return "UNKNOWN";
×
61
  }
62
}
63

64
char* qExplainGetTimerangeTargetStr(int32_t target) {
×
65
  static char* targetName[] = {"", "Left", "Right", "Left/Right"};
66
  if (target <= 0 || target > 3) {
×
67
    return "Unknown";
×
68
  }
69

70
  return targetName[target];
×
71
}
72

73
void qExplainFreeResNode(SExplainResNode *resNode) {
840,648✔
74
  if (NULL == resNode) {
840,648!
75
    return;
×
76
  }
77

78
  taosArrayDestroy(resNode->pExecInfo);
840,648✔
79

80
  SNode *node = NULL;
840,648✔
81
  FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
1,350,291✔
82
  nodesClearList(resNode->pChildren);
840,648✔
83

84
  taosMemoryFreeClear(resNode);
840,648!
85
}
86

87
void qExplainFreeCtx(SExplainCtx *pCtx) {
10,607,063✔
88
  if (NULL == pCtx) {
10,607,063✔
89
    return;
10,499,851✔
90
  }
91

92
  int32_t rowSize = taosArrayGetSize(pCtx->rows);
107,212✔
93
  for (int32_t i = 0; i < rowSize; ++i) {
1,227,093✔
94
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
1,117,700✔
95
    taosMemoryFreeClear(row->buf);
1,117,700!
96
  }
97

98
  if (EXPLAIN_MODE_ANALYZE == pCtx->mode && pCtx->groupHash) {
109,393!
99
    void *pIter = taosHashIterate(pCtx->groupHash, NULL);
9,332✔
100
    while (pIter) {
24,627✔
101
      SExplainGroup *group = (SExplainGroup *)pIter;
15,295✔
102
      if (group->nodeExecInfo) {
15,295✔
103
        int32_t num = taosArrayGetSize(group->nodeExecInfo);
15,287✔
104
        for (int32_t i = 0; i < num; ++i) {
34,823✔
105
          SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
19,536✔
106
          tFreeSExplainRsp(rsp);
19,536✔
107
        }
108
        taosArrayDestroy(group->nodeExecInfo);
15,287✔
109
      }
110

111
      pIter = taosHashIterate(pCtx->groupHash, pIter);
15,295✔
112
    }
113
  }
114

115
  taosHashCleanup(pCtx->groupHash);
109,393✔
116
  taosArrayDestroy(pCtx->rows);
109,393✔
117
  taosMemoryFreeClear(pCtx->tbuf);
109,393!
118
  taosMemoryFree(pCtx);
109,393!
119
}
120

121
static int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio, EExplainMode mode) {
109,393✔
122
  int32_t      code = 0;
109,393✔
123
  SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
109,393!
124
  if (NULL == ctx) {
109,393!
125
    qError("calloc SExplainCtx failed");
×
126
    QRY_ERR_JRET(terrno);
×
127
  }
128

129
  SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo));
109,393✔
130
  if (NULL == rows) {
109,393!
131
    qError("taosArrayInit SQueryExplainRowInfo failed");
×
132
    QRY_ERR_JRET(terrno);
×
133
  }
134

135
  char *tbuf = taosMemoryMalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE);
109,393!
136
  if (NULL == tbuf) {
109,393!
137
    qError("malloc size %d failed", TSDB_EXPLAIN_RESULT_ROW_SIZE);
×
138
    QRY_ERR_JRET(terrno);
×
139
  }
140

141
  ctx->mode = mode;
109,393✔
142
  ctx->verbose = verbose;
109,393✔
143
  ctx->ratio = ratio;
109,393✔
144
  ctx->tbuf = tbuf;
109,393✔
145
  ctx->rows = rows;
109,393✔
146
  ctx->groupHash = groupHash;
109,393✔
147

148
  *pCtx = ctx;
109,393✔
149

150
  return TSDB_CODE_SUCCESS;
109,393✔
151

152
_return:
×
153

154
  taosArrayDestroy(rows);
×
155
  taosHashCleanup(groupHash);
×
156
  taosMemoryFree(ctx);
×
157

158
  QRY_RET(code);
×
159
}
160

161
static int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
840,648✔
162
  int32_t    tlen = 0;
840,648✔
163
  SNodeList *pPhysiChildren = pNode->pChildren;
840,648✔
164

165
  if (pPhysiChildren) {
840,648✔
166
    int32_t code = nodesMakeList(pChildren);
408,049✔
167
    if (NULL == *pChildren) {
408,049!
168
      qError("nodesMakeList failed");
×
169
      QRY_ERR_RET(code);
×
170
    }
171
  }
172

173
  SNode           *node = NULL;
840,648✔
174
  SExplainResNode *pResNode = NULL;
840,648✔
175
  FOREACH(node, pPhysiChildren) {
1,350,291✔
176
    QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
509,643!
177
    QRY_ERR_RET(nodesListAppend(*pChildren, (SNode *)pResNode));
509,643!
178
  }
179

180
  return TSDB_CODE_SUCCESS;
840,648✔
181
}
182

183
static int32_t qExplainGenerateResNodeExecInfo(SPhysiNode *pNode, SArray **pExecInfo, SExplainGroup *group) {
37,103✔
184
  *pExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainExecInfo));
37,103✔
185
  if (NULL == (*pExecInfo)) {
37,103!
186
    qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
187
    return terrno;
×
188
  }
189

190
  SExplainRsp *rsp = NULL;
37,103✔
191
  if (group->singleChannel) {
37,103✔
192
    if (0 == group->physiPlanExecIdx) {
3,545✔
193
      group->nodeIdx = 0;
3,201✔
194
    }
195

196
    rsp = taosArrayGet(group->nodeExecInfo, group->nodeIdx++);
3,545✔
197
    if (group->physiPlanExecIdx >= rsp->numOfPlans) {
3,545!
198
      qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
×
199
      return TSDB_CODE_APP_ERROR;
×
200
    }
201

202
    if(taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx) == NULL) return terrno;
7,090!
203
  } else {
204
    for (int32_t i = 0; i < group->nodeNum; ++i) {
71,046✔
205
      rsp = taosArrayGet(group->nodeExecInfo, i);
37,488✔
206
      if (group->physiPlanExecIdx >= rsp->numOfPlans) {
37,488!
207
        qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
×
208
        return TSDB_CODE_APP_ERROR;
×
209
      }
210

211
      if(taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx) == NULL) return terrno;
74,976!
212
    }
213
  }
214

215
  ++group->physiPlanExecIdx;
37,103✔
216

217
  return TSDB_CODE_SUCCESS;
37,103✔
218
}
219

220
static int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pResNode) {
840,648✔
221
  if (NULL == pNode) {
840,648!
222
    *pResNode = NULL;
×
223
    qError("physical node is NULL");
×
224
    return TSDB_CODE_APP_ERROR;
×
225
  }
226

227
  SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
840,648!
228
  if (NULL == resNode) {
840,648!
229
    qError("calloc SPhysiNodeExplainRes failed");
×
230
    return terrno;
×
231
  }
232

233
  int32_t code = 0;
840,648✔
234
  resNode->pNode = pNode;
840,648✔
235

236
  if (group->nodeExecInfo) {
840,648✔
237
    QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(pNode, &resNode->pExecInfo, group));
37,103!
238
  }
239

240
  QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren));
840,648!
241

242
  *pResNode = resNode;
840,648✔
243

244
  return TSDB_CODE_SUCCESS;
840,648✔
245

246
_return:
×
247

248
  qExplainFreeResNode(resNode);
×
249

250
  QRY_RET(code);
×
251
}
252

253
static int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
37,103✔
254
  int32_t          tlen = *len;
37,103✔
255
  int32_t          nodeNum = taosArrayGetSize(pExecInfo);
37,103✔
256
  SExplainExecInfo maxExecInfo = {0};
37,103✔
257

258
  for (int32_t i = 0; i < nodeNum; ++i) {
78,136✔
259
    SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
41,033✔
260
    if (execInfo->startupCost > maxExecInfo.startupCost) {
41,033✔
261
      maxExecInfo.startupCost = execInfo->startupCost;
26,255✔
262
    }
263
    if (execInfo->totalCost > maxExecInfo.totalCost) {
41,033✔
264
      maxExecInfo.totalCost = execInfo->totalCost;
38,574✔
265
    }
266
    if (execInfo->numOfRows > maxExecInfo.numOfRows) {
41,033✔
267
      maxExecInfo.numOfRows = execInfo->numOfRows;
34,111✔
268
    }
269
  }
270

271
  EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.numOfRows);
37,103✔
272

273
  *len = tlen;
37,103✔
274

275
  return TSDB_CODE_SUCCESS;
37,103✔
276
}
277

278
static int32_t qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
4✔
279
  int32_t          tlen = 0;
4✔
280
  bool             gotVerbose = false;
4✔
281
  int32_t          nodeNum = taosArrayGetSize(pExecInfo);
4✔
282
  SExplainExecInfo maxExecInfo = {0};
4✔
283

284
  for (int32_t i = 0; i < nodeNum; ++i) {
16✔
285
    SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
12✔
286
    if (execInfo->verboseInfo) {
12!
287
      gotVerbose = true;
×
288
    }
289
  }
290

291
  if (gotVerbose) {
4!
292
    EXPLAIN_ROW_APPEND("exec verbose info");
×
293
  }
294

295
  *len = tlen;
4✔
296

297
  return TSDB_CODE_SUCCESS;
4✔
298
}
299

300
static int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
1,117,700✔
301
  SQueryExplainRowInfo row = {0};
1,117,700✔
302
  row.buf = taosMemoryMalloc(len);
1,117,700!
303
  if (NULL == row.buf) {
1,117,700!
304
    qError("taosMemoryMalloc %d failed", len);
×
305
    QRY_ERR_RET(terrno);
×
306
  }
307

308
  memcpy(row.buf, tbuf, len);
1,117,700✔
309
  row.level = level;
1,117,700✔
310
  row.len = len;
1,117,700✔
311
  ctx->dataSize += row.len;
1,117,700✔
312

313
  if (NULL == taosArrayPush(ctx->rows, &row)) {
2,235,400!
314
    qError("taosArrayPush row to explain res rows failed");
×
315
    taosMemoryFree(row.buf);
×
316
    QRY_ERR_RET(terrno);
×
317
  }
318

319
  return TSDB_CODE_SUCCESS;
1,117,700✔
320
}
321

322
static uint8_t qExplainGetIntervalPrecision(SIntervalPhysiNode *pIntNode) {
15,183✔
323
  return ((SColumnNode *)pIntNode->window.pTspk)->node.resType.precision;
15,183✔
324
}
325

326
static char* qExplainGetScanMode(STableScanPhysiNode* pScan) {
212,378✔
327
  bool isGroupByTbname = false;
212,378✔
328
  bool isGroupByTag = false;
212,378✔
329
  bool seq = false;
212,378✔
330
  bool groupOrder = false;
212,378✔
331
  if (pScan->pGroupTags && LIST_LENGTH(pScan->pGroupTags) == 1) {
212,378!
332
    SNode* p = nodesListGetNode(pScan->pGroupTags, 0);
4,146✔
333
    if (QUERY_NODE_FUNCTION == nodeType(p) && (strcmp(((struct SFunctionNode*)p)->functionName, "tbname") == 0)) {
4,146✔
334
      isGroupByTbname = true;
1,065✔
335
    }
336
  }
337

338
  isGroupByTag = (NULL != pScan->pGroupTags) && !isGroupByTbname;
212,378✔
339
  if ((((!isGroupByTag) || isGroupByTbname) && pScan->groupSort) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
212,378!
340
    return "seq_grp_order";
×
341
  }
342

343
  if ((isGroupByTbname && (pScan->groupSort || pScan->scan.groupOrderScan)) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
212,378!
344
    return "grp_order";
37✔
345
  }
346

347
  return "ts_order";
212,341✔
348
}
349

350
static char* qExplainGetScanDataLoad(STableScanPhysiNode* pScan) {
212,378✔
351
  switch (pScan->dataRequired) {
212,378!
352
    case FUNC_DATA_REQUIRED_DATA_LOAD:
201,469✔
353
      return "data";
201,469✔
354
    case FUNC_DATA_REQUIRED_SMA_LOAD:
10,889✔
355
      return "sma";
10,889✔
356
    case FUNC_DATA_REQUIRED_NOT_LOAD:
20✔
357
      return "no";
20✔
358
    default:
×
359
      break;
×
360
  }
361

362
  return "unknown";
×
363
}
364

365
static int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
840,648✔
366
  int32_t     tlen = 0;
840,648✔
367
  bool        isVerboseLine = false;
840,648✔
368
  char       *tbuf = ctx->tbuf;
840,648✔
369
  bool        verbose = ctx->verbose;
840,648✔
370
  SPhysiNode *pNode = pResNode->pNode;
840,648✔
371
  if (NULL == pNode) {
840,648!
372
    qError("pyhsical node in explain res node is NULL");
×
373
    return TSDB_CODE_APP_ERROR;
×
374
  }
375

376
  switch (pNode->type) {
840,648!
377
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
15,824✔
378
      STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
15,824✔
379
      EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->scan.tableName.tname);
15,824!
380
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
15,824✔
381
      if (pResNode->pExecInfo) {
15,824✔
382
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
4!
383
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4✔
384
      }
385
      if (pTagScanNode->scan.pScanPseudoCols) {
15,824!
386
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTagScanNode->scan.pScanPseudoCols->length);
15,824✔
387
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,824✔
388
      }
389
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
15,824✔
390
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
15,824✔
391
      EXPLAIN_ROW_END();
15,824✔
392
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
15,824!
393

394
      if (verbose) {
15,824✔
395
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4!
396
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
4✔
397
                           nodesGetOutputNumFromSlotList(pTagScanNode->scan.node.pOutputDataBlockDesc->pSlots));
398
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4✔
399
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
4✔
400
        EXPLAIN_ROW_APPEND_LIMIT(pTagScanNode->scan.node.pLimit);
4!
401
        EXPLAIN_ROW_APPEND_SLIMIT(pTagScanNode->scan.node.pSlimit);
4!
402
        EXPLAIN_ROW_END();
4✔
403
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4!
404

405
        if (pResNode->pExecInfo) {
4!
406
          QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
4!
407
          if (tlen) {
4!
408
            EXPLAIN_ROW_END();
×
409
            QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
410
          }
411
        }
412

413
        if (pTagScanNode->scan.node.pConditions) {
4!
414
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
415
          QRY_ERR_RET(nodesNodeToSQL(pTagScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
416
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
417
          EXPLAIN_ROW_END();
×
418
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
419
        }
420
      }
421
      break;
15,824✔
422
    }
UNCOV
423
    case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
×
UNCOV
424
      SVirtualScanPhysiNode *pVirtualTableScanNode = (SVirtualScanPhysiNode *)pNode;
×
UNCOV
425
      EXPLAIN_ROW_NEW(level, EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT, pVirtualTableScanNode->scan.tableName.tname);
×
UNCOV
426
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
UNCOV
427
      if (pResNode->pExecInfo) {
×
UNCOV
428
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
429
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
430
      }
UNCOV
431
      if (pVirtualTableScanNode->scan.pScanPseudoCols) {
×
UNCOV
432
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanPseudoCols->length);
×
UNCOV
433
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
434
      }
UNCOV
435
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
×
UNCOV
436
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
UNCOV
437
      EXPLAIN_ROW_END();
×
UNCOV
438
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
439

UNCOV
440
      if (verbose) {
×
UNCOV
441
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
UNCOV
442
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
443
                           nodesGetOutputNumFromSlotList(pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->pSlots));
UNCOV
444
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
445
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
×
UNCOV
446
        EXPLAIN_ROW_APPEND_LIMIT(pVirtualTableScanNode->scan.node.pLimit);
×
UNCOV
447
        EXPLAIN_ROW_APPEND_SLIMIT(pVirtualTableScanNode->scan.node.pSlimit);
×
UNCOV
448
        EXPLAIN_ROW_END();
×
UNCOV
449
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
450

UNCOV
451
        if (pResNode->pExecInfo) {
×
UNCOV
452
          QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
453
          if (tlen) {
×
UNCOV
454
            EXPLAIN_ROW_END();
×
UNCOV
455
            QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
456
          }
457
        }
458

UNCOV
459
        if (pVirtualTableScanNode->scan.node.pConditions) {
×
UNCOV
460
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
461
          QRY_ERR_RET(nodesNodeToSQL(pVirtualTableScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
462
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
463
          EXPLAIN_ROW_END();
×
UNCOV
464
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
465
        }
466
      }
UNCOV
467
      break;
×
468
    }
469
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
212,378✔
470
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
471
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
472
      STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
212,378✔
473
      EXPLAIN_ROW_NEW(level,
212,378!
474
                      QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == pNode->type ? EXPLAIN_TBL_MERGE_SCAN_FORMAT
475
                                                                               : EXPLAIN_TBL_SCAN_FORMAT,
476
                      pTblScanNode->scan.tableName.tname);
477
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
212,378✔
478
      if (pResNode->pExecInfo) {
212,378✔
479
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
12,149!
480
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
481
      }
482

483
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
212,378✔
484
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
212,378✔
485
      if (pTblScanNode->scan.pScanPseudoCols) {
212,378✔
486
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTblScanNode->scan.pScanPseudoCols->length);
71,617✔
487
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
71,617✔
488
      }
489
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
212,378✔
490
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
212,378✔
491
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_ORDER_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
212,378✔
492
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
212,378✔
493
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_MODE_FORMAT, qExplainGetScanMode(pTblScanNode));
212,378✔
494
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
212,378✔
495
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_DATA_LOAD_FORMAT, qExplainGetScanDataLoad(pTblScanNode));
212,378✔
496
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
212,378✔
497
      EXPLAIN_ROW_END();
212,378✔
498
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
212,378!
499

500
      // basic analyze output
501
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
212,378✔
502
        EXPLAIN_ROW_NEW(level + 1, "I/O: ");
12,149!
503

504
        int32_t                      nodeNum = taosArrayGetSize(pResNode->pExecInfo);
12,149✔
505
        struct STableScanAnalyzeInfo info = {0};
12,149✔
506

507
        int32_t maxIndex = 0;
12,149✔
508
        int32_t totalRows = 0;
12,149✔
509
        for (int32_t i = 0; i < nodeNum; ++i) {
26,114✔
510
          SExplainExecInfo      *execInfo = taosArrayGet(pResNode->pExecInfo, i);
13,965✔
511
          STableScanAnalyzeInfo *pScanInfo = (STableScanAnalyzeInfo *)execInfo->verboseInfo;
13,965✔
512

513
          info.totalBlocks += pScanInfo->totalBlocks;
13,965✔
514
          info.loadBlocks += pScanInfo->loadBlocks;
13,965✔
515
          info.totalRows += pScanInfo->totalRows;
13,965✔
516
          info.skipBlocks += pScanInfo->skipBlocks;
13,965✔
517
          info.filterTime += pScanInfo->filterTime;
13,965✔
518
          info.loadBlockStatis += pScanInfo->loadBlockStatis;
13,965✔
519
          info.totalCheckedRows += pScanInfo->totalCheckedRows;
13,965✔
520
          info.filterOutBlocks += pScanInfo->filterOutBlocks;
13,965✔
521

522
          if (pScanInfo->totalRows > totalRows) {
13,965✔
523
            totalRows = pScanInfo->totalRows;
10,575✔
524
            maxIndex = i;
10,575✔
525
          }
526
        }
527

528
        EXPLAIN_ROW_APPEND("total_blocks=%.1f", ((double)info.totalBlocks) / nodeNum);
12,149✔
529
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
530

531
        EXPLAIN_ROW_APPEND("load_blocks=%.1f", ((double)info.loadBlocks) / nodeNum);
12,149✔
532
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
533

534
        EXPLAIN_ROW_APPEND("load_block_SMAs=%.1f", ((double)info.loadBlockStatis) / nodeNum);
12,149✔
535
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
536

537
        EXPLAIN_ROW_APPEND("total_rows=%.1f", ((double)info.totalRows) / nodeNum);
12,149✔
538
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
539

540
        EXPLAIN_ROW_APPEND("check_rows=%.1f", ((double)info.totalCheckedRows) / nodeNum);
12,149✔
541
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
542
        EXPLAIN_ROW_END();
12,149✔
543

544
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,149!
545

546
        // Rows out: Avg 4166.7 rows x 24 workers. Max 4187 rows (seg7) with 0.220 ms to first row, 1.738 ms to end,
547
        // start offset by 1.470 ms.
548
        SExplainExecInfo      *execInfo = taosArrayGet(pResNode->pExecInfo, maxIndex);
12,149✔
549
        STableScanAnalyzeInfo *p1 = (STableScanAnalyzeInfo *)execInfo->verboseInfo;
12,149✔
550

551
        EXPLAIN_ROW_NEW(level + 1, " ");
12,149!
552
        EXPLAIN_ROW_APPEND("max_row_task=%d, total_rows:%" PRId64 ", ep:%s (cost=%.3f..%.3f)", maxIndex, p1->totalRows,
12,149✔
553
                           "tbd", execInfo->startupCost, execInfo->totalCost);
554
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,149✔
555
        EXPLAIN_ROW_END();
12,149✔
556

557
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,149!
558
      }
559

560
      if (verbose) {
212,378✔
561
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
28,451!
562
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
28,451✔
563
                           nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
564
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,451✔
565
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
28,451✔
566
        EXPLAIN_ROW_APPEND_LIMIT(pTblScanNode->scan.node.pLimit);
28,451!
567
        EXPLAIN_ROW_APPEND_SLIMIT(pTblScanNode->scan.node.pSlimit);
28,451!
568
        EXPLAIN_ROW_END();
28,451✔
569
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
28,451!
570

571
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey,
28,451!
572
                        pTblScanNode->scanRange.ekey);
573
        EXPLAIN_ROW_END();
28,451✔
574
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
28,451!
575

576
        if (NULL != pTblScanNode->pGroupTags) {
28,451✔
577
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
7,581!
578
          EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pTblScanNode->pGroupTags->length);
7,581✔
579
          EXPLAIN_ROW_END();
7,581✔
580
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
7,581!
581
        }
582

583
        if (pTblScanNode->scan.node.pConditions) {
28,451✔
584
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
1,385!
585
          QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
1,385!
586
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
587
          EXPLAIN_ROW_END();
1,385✔
588
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,385!
589
        }
590
      }
591
      break;
212,378✔
592
    }
593
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
47✔
594
      SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
47✔
595
      EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
47!
596
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
47✔
597
      if (pResNode->pExecInfo) {
47✔
598
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
25!
599
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
25✔
600
      }
601
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
47✔
602
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47✔
603
      if (pSTblScanNode->scan.pScanPseudoCols) {
47✔
604
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pSTblScanNode->scan.pScanPseudoCols->length);
1✔
605
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
606
      }
607
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
47✔
608
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47✔
609
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
47✔
610
      EXPLAIN_ROW_END();
47✔
611
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
47!
612

613
      if (verbose) {
47✔
614
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
7!
615
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
7✔
616
                           nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
617
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7✔
618
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
7✔
619
        EXPLAIN_ROW_APPEND_LIMIT(pSTblScanNode->scan.node.pLimit);
7!
620
        EXPLAIN_ROW_APPEND_SLIMIT(pSTblScanNode->scan.node.pSlimit);
7!
621
        EXPLAIN_ROW_END();
7✔
622
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
7!
623

624
        if (pSTblScanNode->scan.node.pConditions) {
7✔
625
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
3!
626
          QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
3!
627
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
628
          EXPLAIN_ROW_END();
3✔
629
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3!
630
        }
631
      }
632
      break;
47✔
633
    }
634
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
156,436✔
635
      SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
156,436✔
636
      EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
156,436!
637
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
156,436✔
638
      if (pResNode->pExecInfo) {
156,436✔
639
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
9,398!
640
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9,398✔
641
      }
642
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
156,436✔
643
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
156,436✔
644
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
156,436✔
645
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
156,436✔
646
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pPrjNode->node.inputTsOrder));
156,436✔
647
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
156,436✔
648
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
156,436✔
649
      EXPLAIN_ROW_END();
156,436✔
650
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
156,436!
651

652
      if (verbose) {
156,436✔
653
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
10,086!
654
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
10,086✔
655
                           nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
656
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10,086✔
657
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
10,086✔
658
        EXPLAIN_ROW_APPEND_LIMIT(pPrjNode->node.pLimit);
10,086!
659
        EXPLAIN_ROW_APPEND_SLIMIT(pPrjNode->node.pSlimit);
10,086!
660
        EXPLAIN_ROW_END();
10,086✔
661
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10,086!
662

663
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
10,086!
664
        EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pPrjNode->ignoreGroupId ? "true" : "false");
10,086✔
665
        EXPLAIN_ROW_END();
10,086✔
666
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10,086!
667

668
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pPrjNode->mergeDataBlock? "True":"False");
10,086!
669
        EXPLAIN_ROW_END();
10,086✔
670
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10,086!
671

672
        if (pPrjNode->node.pConditions) {
10,086!
UNCOV
673
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
674
          QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
675
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
676
          EXPLAIN_ROW_END();
×
UNCOV
677
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
678
        }
679
      }
680
      break;
156,436✔
681
    }
682
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
28,959✔
683
      SSortMergeJoinPhysiNode *pJoinNode = (SSortMergeJoinPhysiNode *)pNode;
28,959✔
684
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
28,959!
685
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
28,959✔
686
      if (pResNode->pExecInfo) {
28,959✔
687
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
599!
688
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
599✔
689
      }
690
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
28,959✔
691
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,959✔
692
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
28,959✔
693
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,959✔
694
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
28,959!
695
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,959✔
696
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Merge");
28,959✔
697
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
28,959✔
698
      EXPLAIN_ROW_END();
28,959✔
699
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
28,959!
700

701
      if (verbose) {
28,959✔
702
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
575!
703
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
575✔
704
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
705
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
575✔
706
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
575✔
707
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
575!
708
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
575!
709
        EXPLAIN_ROW_END();
575✔
710
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
575!
711

712
        if (IS_ASOF_JOIN(pJoinNode->subType) || IS_WINDOW_JOIN(pJoinNode->subType)) {
575✔
713
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_PARAM_FORMAT);
248!
714
          if (IS_ASOF_JOIN(pJoinNode->subType)) {
248✔
715
            EXPLAIN_ROW_APPEND(EXPLAIN_ASOF_OP_FORMAT, qExplainGetAsofOpStr(pJoinNode->asofOpType));
112✔
716
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
112✔
717
          }
718
          if (NULL != pJoinNode->pWindowOffset) {
248✔
719
            SWindowOffsetNode* pWinOffset = (SWindowOffsetNode*)pJoinNode->pWindowOffset;
136✔
720
            SValueNode* pStart = (SValueNode*)pWinOffset->pStartOffset;
136✔
721
            SValueNode* pEnd = (SValueNode*)pWinOffset->pEndOffset;
136✔
722
            EXPLAIN_ROW_APPEND(EXPLAIN_WIN_OFFSET_FORMAT, pStart->literal, pEnd->literal);
136✔
723
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
136✔
724
          }
725
          if (NULL != pJoinNode->pJLimit && NULL != ((SLimitNode*)pJoinNode->pJLimit)->limit) {
248!
726
            SLimitNode* pJLimit = (SLimitNode*)pJoinNode->pJLimit;
44✔
727
            EXPLAIN_ROW_APPEND(EXPLAIN_JLIMIT_FORMAT, pJLimit->limit->datum.i);
44✔
728
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
44✔
729
          }
730
          if (IS_WINDOW_JOIN(pJoinNode->subType)) {
248✔
731
            EXPLAIN_ROW_APPEND(EXPLAIN_SEQ_WIN_GRP_FORMAT, pJoinNode->seqWinGroup);
136✔
732
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
136✔
733
          }
734

735
          EXPLAIN_ROW_APPEND(EXPLAIN_GRP_JOIN_FORMAT, pJoinNode->grpJoin);
248✔
736
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
248✔
737
          EXPLAIN_ROW_END();
248✔
738

739
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
248!
740
        }
741

742
        if (pJoinNode->node.pConditions) {
575✔
743
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
46!
744
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
46!
745
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
746
          EXPLAIN_ROW_END();
46✔
747
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
46!
748
        }
749

750
        if (NULL != pJoinNode->pPrimKeyCond) {
575✔
751
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PRIM_CONDITIONS_FORMAT);
403!
752
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
403!
753
          EXPLAIN_ROW_END();
403✔
754
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
403!
755
        }
756

757
        if (NULL != pJoinNode->pEqLeft && pJoinNode->pEqLeft->length > 0) {
575!
758
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_LEFT_FORMAT);
2!
759
          SNode* pCol = NULL;
2✔
760
          FOREACH(pCol, pJoinNode->pEqLeft) {
4!
761
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
2✔
762
          }
763
          EXPLAIN_ROW_END();
2✔
764
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
765
        }
766

767
        if (NULL != pJoinNode->pEqRight && pJoinNode->pEqRight->length > 0) {
575!
768
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_RIGHT_FORMAT);
2!
769
          SNode* pCol = NULL;
2✔
770
          FOREACH(pCol, pJoinNode->pEqRight) {
4!
771
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
2✔
772
          }
773
          EXPLAIN_ROW_END();
2✔
774
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
775
        }
776

777
        if (NULL != pJoinNode->pFullOnCond) {
575✔
778
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
20!
779
          QRY_ERR_RET(
20!
780
                nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
781
          EXPLAIN_ROW_END();
20✔
782
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
20!
783
        }
784

785
        if (NULL != pJoinNode->pColOnCond) {
575✔
786
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COL_ON_CONDITIONS_FORMAT);
18!
787
          QRY_ERR_RET(
18!
788
                nodesNodeToSQL(pJoinNode->pColOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
789
          EXPLAIN_ROW_END();
18✔
790
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
18!
791
        }
792
      }
793
      break;
28,959✔
794
    }
795
    case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
90,558✔
796
      SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
90,558✔
797
      EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, (pAggNode->pGroupKeys ? "GroupAggregate" : "Aggregate"));
90,558!
798
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
90,558✔
799
      if (pResNode->pExecInfo) {
90,558✔
800
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
5,385!
801
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,385✔
802
      }
803
      if (pAggNode->pAggFuncs) {
90,558✔
804
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
65,419✔
805
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
65,419✔
806
      }
807
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
90,558✔
808
      if (pAggNode->pGroupKeys) {
90,558✔
809
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
25,847✔
810
        EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
25,847✔
811
      }
812
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
90,558✔
813
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pAggNode->node.inputTsOrder));
90,558✔
814
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
90,558✔
815
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
90,558✔
816
      EXPLAIN_ROW_END();
90,558✔
817
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
90,558!
818

819
      if (verbose) {
90,558✔
820
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
12,328!
821
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
12,328✔
822
                           nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
823
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,328✔
824
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
12,328✔
825
        EXPLAIN_ROW_APPEND_LIMIT(pAggNode->node.pLimit);
12,328!
826
        EXPLAIN_ROW_APPEND_SLIMIT(pAggNode->node.pSlimit);
12,328!
827
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,328✔
828
        EXPLAIN_ROW_APPEND(EXPLAIN_PLAN_BLOCKING, !pAggNode->node.forceCreateNonBlockingOptr);
12,328✔
829
        EXPLAIN_ROW_END();
12,328✔
830
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,328!
831

832
        if (pAggNode->node.pConditions) {
12,328✔
833
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
49!
834
          QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
49!
835
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
836
          EXPLAIN_ROW_END();
49✔
837
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
49!
838
        }
839

840
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pAggNode->mergeDataBlock? "True":"False");
12,328!
841
        EXPLAIN_ROW_END();
12,328✔
842
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,328!
843
      }
844
      break;
90,558✔
845
    }
846
    case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: {
10,765✔
847
      SIndefRowsFuncPhysiNode *pIndefNode = (SIndefRowsFuncPhysiNode *)pNode;
10,765✔
848
      EXPLAIN_ROW_NEW(level, EXPLAIN_INDEF_ROWS_FORMAT);
10,765!
849
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
10,765✔
850
      if (pResNode->pExecInfo) {
10,765✔
851
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
9!
852
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9✔
853
      }
854
      if (pIndefNode->pFuncs) {
10,765!
855
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIndefNode->pFuncs->length);
10,765✔
856
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10,765✔
857
      }
858
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->totalRowSize);
10,765✔
859
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
10,765✔
860
      EXPLAIN_ROW_END();
10,765✔
861
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
10,765!
862

863
      if (verbose) {
10,765✔
864
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
10!
865
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
10✔
866
                           nodesGetOutputNumFromSlotList(pIndefNode->node.pOutputDataBlockDesc->pSlots));
867
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10✔
868
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->outputRowSize);
10✔
869
        EXPLAIN_ROW_APPEND_LIMIT(pIndefNode->node.pLimit);
10!
870
        EXPLAIN_ROW_APPEND_SLIMIT(pIndefNode->node.pSlimit);
10!
871
        EXPLAIN_ROW_END();
10✔
872
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10!
873

874
        if (pIndefNode->node.pConditions) {
10!
875
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
876
          QRY_ERR_RET(nodesNodeToSQL(pIndefNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
877
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
878
          EXPLAIN_ROW_END();
×
UNCOV
879
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
880
        }
881
      }
882
      break;
10,765✔
883
    }
884
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
202,954✔
885
      SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
202,954✔
886
      int32_t nodeNum = 0;
202,954✔
887
      for (int32_t i = pExchNode->srcStartGroupId; i <= pExchNode->srcEndGroupId; ++i) {
424,574✔
888
        SExplainGroup      *group = taosHashGet(ctx->groupHash, &pExchNode->srcStartGroupId, sizeof(pExchNode->srcStartGroupId));
221,620✔
889
        if (NULL == group) {
221,620!
UNCOV
890
          qError("exchange src group %d not in groupHash", pExchNode->srcStartGroupId);
×
UNCOV
891
          QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
892
        }
893

894
        nodeNum += group->nodeNum;
221,620✔
895
      }
896

897
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, pExchNode->singleChannel ? 1 : nodeNum);
202,954!
898
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
202,954✔
899
      if (pResNode->pExecInfo) {
202,954✔
900
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
7,860!
901
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,860✔
902
      }
903
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
202,954✔
904
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
202,954✔
905
      EXPLAIN_ROW_END();
202,954✔
906
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
202,954!
907

908
      if (verbose) {
202,954✔
909
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
26,333!
910
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
26,333✔
911
                           nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
912
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
26,333✔
913
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
26,333✔
914
        EXPLAIN_ROW_APPEND_LIMIT(pExchNode->node.pLimit);
26,333!
915
        EXPLAIN_ROW_APPEND_SLIMIT(pExchNode->node.pSlimit);
26,333!
916
        EXPLAIN_ROW_END();
26,333✔
917
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
26,333!
918

919
        if (pExchNode->node.pConditions) {
26,333!
UNCOV
920
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
921
          QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
922
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
923
          EXPLAIN_ROW_END();
×
UNCOV
924
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
925
        }
926
      }
927

928
      for (int32_t i = pExchNode->srcStartGroupId; i <= pExchNode->srcEndGroupId; ++i) {
424,574✔
929
        QRY_ERR_RET(qExplainAppendGroupResRows(ctx, i, level + 1, pExchNode->singleChannel));
221,620!
930
      }
931
      break;
202,954✔
932
    }
933
    case QUERY_NODE_PHYSICAL_PLAN_SORT: {
25,291✔
934
      SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
25,291✔
935
      EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
25,291!
936
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
25,291✔
937
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.inputTsOrder));
25,291✔
938
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
25,291✔
939
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.outputTsOrder));
25,291✔
940
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
25,291✔
941
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
25,291✔
942
      if (pResNode->pExecInfo) {
25,291✔
943
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
203!
944
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
203✔
945
      }
946

947
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
25,291✔
948
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
25,291✔
949
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
25,291✔
950
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
25,291✔
951
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
25,291✔
952
      EXPLAIN_ROW_END();
25,291✔
953
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
25,291!
954

955
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
25,291✔
956
        // sort key
957
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
203!
958
        if (pResNode->pExecInfo) {
203!
959
          for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
406!
960
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
203✔
961
            EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
203✔
962
          }
963
        }
964

965
        EXPLAIN_ROW_END();
203✔
966
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
203!
967

968
        // sort method
969
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
203!
970

971
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
203✔
972
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
203✔
973
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
203✔
974
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
203✔
975
        if (pExecInfo->sortBuffer > 1024 * 1024) {
203✔
976
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
170✔
977
        } else if (pExecInfo->sortBuffer > 1024) {
33!
UNCOV
978
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
979
        } else {
980
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
33✔
981
        }
982

983
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
203✔
984
        EXPLAIN_ROW_END();
203✔
985
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
203!
986
      }
987

988
      if (verbose) {
25,291✔
989
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
3,013!
990
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
3,013✔
991
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
992
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,013✔
993
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
3,013✔
994
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
3,013!
995
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
3,013!
996
        EXPLAIN_ROW_END();
3,013✔
997
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,013!
998

999
        if (pSortNode->node.pConditions) {
3,013!
UNCOV
1000
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1001
          QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1002
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1003
          EXPLAIN_ROW_END();
×
UNCOV
1004
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1005
        }
1006
      }
1007
      break;
25,291✔
1008
    }
1009
    case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: {
14,941✔
1010
      SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
14,941✔
1011
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
14,941!
1012
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
14,941✔
1013
      if (pResNode->pExecInfo) {
14,941✔
1014
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
14!
1015
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14✔
1016
      }
1017
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
14,941✔
1018
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,941✔
1019
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
14,941✔
1020
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,941✔
1021
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
14,941!
1022
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,941✔
1023
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
14,941!
1024
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
14,941✔
1025
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
14,941✔
1026
      EXPLAIN_ROW_END();
14,941✔
1027
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
14,941!
1028

1029
      if (verbose) {
14,941✔
1030
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
12,511!
1031
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
12,511✔
1032
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1033
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,511✔
1034
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
12,511✔
1035
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
12,511!
1036
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
12,511!
1037
        EXPLAIN_ROW_END();
12,511✔
1038
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,511!
1039
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pIntNode->timeRange.skey, pIntNode->timeRange.ekey);
12,511!
1040
        EXPLAIN_ROW_END();
12,511✔
1041
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,511!
1042
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
12,511✔
1043
        int64_t time1 = -1;
12,511✔
1044
        int64_t time2 = -1;
12,511✔
1045
        int32_t code = TSDB_CODE_SUCCESS;
12,511✔
1046
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
12,511✔
1047
        QRY_ERR_RET(code);
12,511!
1048
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
12,511✔
1049
        QRY_ERR_RET(code);
12,511!
1050
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
12,511!
1051
                        time1,
1052
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1053
                        time2,
1054
                        pIntNode->slidingUnit);
1055
        EXPLAIN_ROW_END();
12,511✔
1056
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,511!
1057

1058
        if (pIntNode->window.node.pConditions) {
12,511!
UNCOV
1059
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1060
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1061
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1062
          EXPLAIN_ROW_END();
×
UNCOV
1063
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1064
        }
1065

1066
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
12,511!
1067
        EXPLAIN_ROW_END();
12,511✔
1068
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,511!
1069
      }
1070
      break;
14,941✔
1071
    }
1072
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: {
2,844✔
1073
      SMergeAlignedIntervalPhysiNode *pIntNode = (SMergeAlignedIntervalPhysiNode *)pNode;
2,844✔
1074
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
2,844!
1075
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
2,844✔
1076
      if (pResNode->pExecInfo) {
2,844✔
1077
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
3!
1078
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3✔
1079
      }
1080
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
2,844✔
1081
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,844✔
1082
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
2,844✔
1083
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,844✔
1084
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
2,844!
1085
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,844✔
1086
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
2,844!
1087
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
2,844✔
1088
      EXPLAIN_ROW_END();
2,844✔
1089
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
2,844!
1090

1091
      if (verbose) {
2,844✔
1092
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2,672!
1093
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2,672✔
1094
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1095
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,672✔
1096
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
2,672✔
1097
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
2,672!
1098
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
2,672!
1099
        EXPLAIN_ROW_END();
2,672✔
1100
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,672!
1101
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
2,672✔
1102
        int64_t time1 = -1;
2,672✔
1103
        int64_t time2 = -1;
2,672✔
1104
        int32_t code = TSDB_CODE_SUCCESS;
2,672✔
1105
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
2,672✔
1106
        QRY_ERR_RET(code);
2,672!
1107
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
2,672✔
1108
        QRY_ERR_RET(code);
2,672!
1109
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
2,672!
1110
                        time1,
1111
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1112
                        time2,
1113
                        pIntNode->slidingUnit);
1114
        EXPLAIN_ROW_END();
2,672✔
1115
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,672!
1116

1117
        if (pIntNode->window.node.pConditions) {
2,672✔
1118
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
6!
1119
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
6!
1120
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1121
          EXPLAIN_ROW_END();
6✔
1122
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
6!
1123
        }
1124

1125
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
2,672!
1126
        EXPLAIN_ROW_END();
2,672✔
1127
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,672!
1128
      }
1129
      break;
2,844✔
1130
    }
1131
    case QUERY_NODE_PHYSICAL_PLAN_FILL: {
10✔
1132
      SFillPhysiNode *pFillNode = (SFillPhysiNode *)pNode;
10✔
1133
      EXPLAIN_ROW_NEW(level, EXPLAIN_FILL_FORMAT);
10!
1134
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
10✔
1135
      if (pResNode->pExecInfo) {
10✔
1136
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1137
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1138
      }
1139
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pFillNode->mode));
10✔
1140
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10✔
1141
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->totalRowSize);
10✔
1142
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10✔
1143
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pFillNode->node.inputTsOrder));
10!
1144
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10✔
1145
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
10✔
1146
      EXPLAIN_ROW_END();
10✔
1147
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
10!
1148

1149
      if (verbose) {
10✔
1150
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
9!
1151
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
9✔
1152
                           nodesGetOutputNumFromSlotList(pFillNode->node.pOutputDataBlockDesc->pSlots));
1153
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9✔
1154
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->outputRowSize);
9✔
1155
        EXPLAIN_ROW_APPEND_LIMIT(pFillNode->node.pLimit);
9!
1156
        EXPLAIN_ROW_APPEND_SLIMIT(pFillNode->node.pSlimit);
9!
1157
        EXPLAIN_ROW_END();
9✔
1158
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
9!
1159
        if (pFillNode->pValues) {
9✔
1160
          SNodeListNode *pValues = (SNodeListNode *)pFillNode->pValues;
1✔
1161
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
1!
1162
          SNode  *tNode = NULL;
1✔
1163
          int32_t i = 0;
1✔
1164
          FOREACH(tNode, pValues->pNodeList) {
6!
1165
            if (i) {
5✔
1166
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4✔
1167
            }
1168
            SValueNode *tValue = (SValueNode *)tNode;
5✔
1169
            char       *value = nodesGetStrValueFromNode(tValue);
5✔
1170
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
5✔
1171
            taosMemoryFree(value);
5!
1172
            ++i;
5✔
1173
          }
1174

1175
          EXPLAIN_ROW_END();
1✔
1176
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1!
1177
        }
1178

1179
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pFillNode->timeRange.skey, pFillNode->timeRange.ekey);
9!
1180
        EXPLAIN_ROW_END();
9✔
1181
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
9!
1182

1183
        if (pFillNode->node.pConditions) {
9!
UNCOV
1184
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1185
          QRY_ERR_RET(nodesNodeToSQL(pFillNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1186
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1187
          EXPLAIN_ROW_END();
×
UNCOV
1188
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1189
        }
1190
      }
1191
      break;
10✔
1192
    }
1193
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: {
1,330✔
1194
      SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
1,330✔
1195
      EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
1,330!
1196
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,330✔
1197
      if (pResNode->pExecInfo) {
1,330!
UNCOV
1198
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
1199
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1200
      }
1201
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length);
1,330✔
1202
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,330✔
1203
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,330✔
1204
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,330✔
1205
      EXPLAIN_ROW_END();
1,330✔
1206
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,330!
1207

1208
      if (verbose) {
1,330✔
1209
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
10!
1210
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
10✔
1211
                           nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
1212
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10✔
1213
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
10✔
1214
        EXPLAIN_ROW_APPEND_LIMIT(pSessNode->window.node.pLimit);
10!
1215
        EXPLAIN_ROW_APPEND_SLIMIT(pSessNode->window.node.pSlimit);
10!
1216
        EXPLAIN_ROW_END();
10✔
1217
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10!
1218

1219
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_WINDOW_FORMAT, pSessNode->gap);
10!
1220
        EXPLAIN_ROW_END();
10✔
1221
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
10!
1222

1223
        if (pSessNode->window.node.pConditions) {
10!
1224
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1225
          QRY_ERR_RET(nodesNodeToSQL(pSessNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1226
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1227
          EXPLAIN_ROW_END();
×
UNCOV
1228
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1229
        }
1230
      }
1231
      break;
1,330✔
1232
    }
1233
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE: {
648✔
1234
      SStateWinodwPhysiNode *pStateNode = (SStateWinodwPhysiNode *)pNode;
648✔
1235

1236
      EXPLAIN_ROW_NEW(level, EXPLAIN_STATE_WINDOW_FORMAT,
648!
1237
                      nodesGetNameFromColumnNode(pStateNode->pStateKey));
1238
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
648✔
1239
      if (pResNode->pExecInfo) {
648!
UNCOV
1240
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
1241
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1242
      }
1243

1244
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pStateNode->window.pFuncs->length);
648✔
1245
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
648✔
1246
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->totalRowSize);
648✔
1247
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
648✔
1248
      EXPLAIN_ROW_END();
648✔
1249
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
648!
1250

1251
      if (verbose) {
648✔
1252
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
8!
1253
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
8✔
1254
                           nodesGetOutputNumFromSlotList(pStateNode->window.node.pOutputDataBlockDesc->pSlots));
1255
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1256
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->outputRowSize);
8✔
1257
        EXPLAIN_ROW_APPEND_LIMIT(pStateNode->window.node.pLimit);
8!
1258
        EXPLAIN_ROW_APPEND_SLIMIT(pStateNode->window.node.pSlimit);
8!
1259
        EXPLAIN_ROW_END();
8✔
1260
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8!
1261

1262
        EXPLAIN_ROW_END();
8✔
1263
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8!
1264

1265
        if (pStateNode->window.node.pConditions) {
8!
1266
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1267
          QRY_ERR_RET(nodesNodeToSQL(pStateNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1268
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1269
          EXPLAIN_ROW_END();
×
UNCOV
1270
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1271
        }
1272
      }
1273
      break;
648✔
1274
    }
1275
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
5,794✔
1276
      SPartitionPhysiNode *pPartNode = (SPartitionPhysiNode *)pNode;
5,794✔
1277

1278
      SNode *p = nodesListGetNode(pPartNode->pPartitionKeys, 0);
5,794✔
1279
      EXPLAIN_ROW_NEW(level, EXPLAIN_PARITION_FORMAT, nodesGetNameFromColumnNode(p));
5,794!
1280
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
5,794✔
1281
      if (pResNode->pExecInfo) {
5,794✔
1282
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
339!
1283
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
339✔
1284
      }
1285
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->totalRowSize);
5,794✔
1286

1287
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
5,794✔
1288
      EXPLAIN_ROW_END();
5,794✔
1289
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
5,794!
1290

1291
      if (verbose) {
5,794✔
1292
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
348!
1293
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
348✔
1294
                           nodesGetOutputNumFromSlotList(pPartNode->node.pOutputDataBlockDesc->pSlots));
1295
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
348✔
1296
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->outputRowSize);
348✔
1297
        EXPLAIN_ROW_APPEND_LIMIT(pPartNode->node.pLimit);
348!
1298
        EXPLAIN_ROW_APPEND_SLIMIT(pPartNode->node.pSlimit);
348!
1299
        EXPLAIN_ROW_END();
348✔
1300
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
348!
1301

1302
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
348!
1303
        EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pPartNode->pPartitionKeys->length);
348✔
1304
        EXPLAIN_ROW_END();
348✔
1305
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
348!
1306

1307
        if (pPartNode->node.pConditions) {
348!
1308
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1309
          QRY_ERR_RET(nodesNodeToSQL(pPartNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1310
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1311
          EXPLAIN_ROW_END();
×
UNCOV
1312
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1313
        }
1314
      }
1315
      break;
5,794✔
1316
    }
1317
    case QUERY_NODE_PHYSICAL_PLAN_MERGE: {
47,763✔
1318
      SMergePhysiNode *pMergeNode = (SMergePhysiNode *)pNode;
47,763✔
1319
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_FORMAT);
47,763!
1320
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
47,763✔
1321
      if (pResNode->pExecInfo) {
47,763✔
1322
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1,103!
1323
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,103✔
1324
      }
1325

1326
      SDataBlockDescNode *pDescNode = pMergeNode->node.pOutputDataBlockDesc;
47,763✔
1327
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
47,763✔
1328
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47,763✔
1329
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
47,763✔
1330
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47,763✔
1331
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.inputTsOrder));
47,763✔
1332
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47,763✔
1333
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.outputTsOrder));
47,763✔
1334
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
47,763✔
1335
      EXPLAIN_ROW_APPEND(EXPLAIN_MERGE_MODE_FORMAT, EXPLAIN_MERGE_MODE_STRING(pMergeNode->type));
47,763✔
1336
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
47,763✔
1337
      EXPLAIN_ROW_END();
47,763✔
1338
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
47,763!
1339

1340
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
47,763✔
1341
        if (MERGE_TYPE_SORT == pMergeNode->type) {
1,103!
1342
          // sort method
1343
          EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
1,103!
1344

1345
          int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
1,103✔
1346
          SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
1,103✔
1347
          SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
1,103✔
1348
          EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
1,103!
1349
          if (pExecInfo->sortBuffer > 1024 * 1024) {
1,103!
UNCOV
1350
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1351
          } else if (pExecInfo->sortBuffer > 1024) {
1,103!
1352
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
1,103✔
1353
          } else {
UNCOV
1354
            EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1355
          }
1356

1357
          EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
1,103✔
1358
          EXPLAIN_ROW_END();
1,103✔
1359
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,103!
1360
        }
1361
      }
1362

1363
      if (verbose) {
47,763✔
1364
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
5,125!
1365
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
5,125✔
1366
                           nodesGetOutputNumFromSlotList(pMergeNode->node.pOutputDataBlockDesc->pSlots));
1367
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
5,125✔
1368
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pMergeNode->node.pOutputDataBlockDesc->outputRowSize);
5,125✔
1369
        EXPLAIN_ROW_APPEND_LIMIT(pMergeNode->node.pLimit);
5,125!
1370
        EXPLAIN_ROW_APPEND_SLIMIT(pMergeNode->node.pSlimit);
5,125!
1371
        EXPLAIN_ROW_END();
5,125✔
1372
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
5,125!
1373

1374
        if (MERGE_TYPE_SORT == pMergeNode->type) {
5,125✔
1375
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
3,799!
1376
          EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pMergeNode->ignoreGroupId ? "true" : "false");
3,799!
1377
          EXPLAIN_ROW_END();
3,799✔
1378
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,799!
1379

1380
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGE_KEYS_FORMAT);
3,799!
1381
          if (pMergeNode->groupSort) {
3,799✔
1382
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, "_group_id asc");
2,825✔
1383
            if (LIST_LENGTH(pMergeNode->pMergeKeys) > 0) {
2,825!
1384
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
2,813✔
1385
            }
1386
          }
1387
          for (int32_t i = 0; i < LIST_LENGTH(pMergeNode->pMergeKeys); ++i) {
7,590✔
1388
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pMergeNode->pMergeKeys, i);
3,791✔
1389
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, nodesGetNameFromColumnNode(ptn->pExpr));
3,791✔
1390
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,791✔
1391
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, EXPLAIN_ORDER_STRING(ptn->order));
3,791!
1392
            if (i != LIST_LENGTH(pMergeNode->pMergeKeys) - 1) {
3,791!
1393
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
4✔
1394
            }
1395
          }
1396
          EXPLAIN_ROW_END();
3,799✔
1397
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,799!
1398
        }
1399

1400
        if (pMergeNode->node.pConditions) {
5,125!
UNCOV
1401
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1402
          QRY_ERR_RET(nodesNodeToSQL(pMergeNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1403
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1404
          EXPLAIN_ROW_END();
×
UNCOV
1405
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1406
        }
1407
      }
1408
      break;
47,763✔
1409
    }
UNCOV
1410
    case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: {
×
UNCOV
1411
      SBlockDistScanPhysiNode *pDistScanNode = (SBlockDistScanPhysiNode *)pNode;
×
UNCOV
1412
      EXPLAIN_ROW_NEW(level, EXPLAIN_DISTBLK_SCAN_FORMAT, pDistScanNode->tableName.tname);
×
UNCOV
1413
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
UNCOV
1414
      if (pResNode->pExecInfo) {
×
UNCOV
1415
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
1416
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1417
      }
UNCOV
1418
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDistScanNode->pScanCols->length);
×
UNCOV
1419
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
1420
      if (pDistScanNode->pScanPseudoCols) {
×
UNCOV
1421
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pDistScanNode->pScanPseudoCols->length);
×
UNCOV
1422
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1423
      }
UNCOV
1424
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->totalRowSize);
×
UNCOV
1425
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
1426
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
UNCOV
1427
      EXPLAIN_ROW_END();
×
UNCOV
1428
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1429

UNCOV
1430
      if (verbose) {
×
UNCOV
1431
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
UNCOV
1432
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1433
                           nodesGetOutputNumFromSlotList(pDistScanNode->node.pOutputDataBlockDesc->pSlots));
UNCOV
1434
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
1435
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->outputRowSize);
×
UNCOV
1436
        EXPLAIN_ROW_APPEND_LIMIT(pDistScanNode->node.pLimit);
×
1437
        EXPLAIN_ROW_APPEND_SLIMIT(pDistScanNode->node.pSlimit);
×
1438
        EXPLAIN_ROW_END();
×
UNCOV
1439
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1440

1441
        if (pDistScanNode->node.pConditions) {
×
UNCOV
1442
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1443
          QRY_ERR_RET(nodesNodeToSQL(pDistScanNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1444
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1445
          EXPLAIN_ROW_END();
×
1446
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1447
        }
1448
      }
UNCOV
1449
      break;
×
1450
    }
1451
    case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: {
216✔
1452
      SLastRowScanPhysiNode *pLastRowNode = (SLastRowScanPhysiNode *)pNode;
216✔
1453
      EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->scan.tableName.tname);
216!
1454
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
216✔
1455
      if (pResNode->pExecInfo) {
216✔
1456
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1457
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1458
      }
1459
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->scan.pScanCols->length);
216✔
1460
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
216✔
1461
      if (pLastRowNode->scan.pScanPseudoCols) {
216✔
1462
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
70✔
1463
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
70✔
1464
      }
1465
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
216✔
1466
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
216✔
1467
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
216✔
1468
      EXPLAIN_ROW_END();
216✔
1469
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
216!
1470

1471
      if (verbose) {
216✔
1472
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
192!
1473
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
192✔
1474
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1475
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
192✔
1476
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
192✔
1477
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
192!
1478
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
192!
1479
        EXPLAIN_ROW_END();
192✔
1480
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
192!
1481

1482
        if (pLastRowNode->scan.node.pConditions) {
192!
1483
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1484
          QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1485
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1486
          EXPLAIN_ROW_END();
×
UNCOV
1487
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1488
        }
1489
      }
1490
      break;
216✔
1491
    }
UNCOV
1492
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
×
1493
      STableCountScanPhysiNode *pLastRowNode = (STableCountScanPhysiNode *)pNode;
×
1494
      EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT,
×
1495
                      ('\0' != pLastRowNode->scan.tableName.tname[0] ? pLastRowNode->scan.tableName.tname : TSDB_INS_TABLE_TABLES));
UNCOV
1496
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
UNCOV
1497
      if (pResNode->pExecInfo) {
×
UNCOV
1498
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
1499
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1500
      }
UNCOV
1501
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, LIST_LENGTH(pLastRowNode->scan.pScanCols));
×
UNCOV
1502
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
1503
      if (pLastRowNode->scan.pScanPseudoCols) {
×
UNCOV
1504
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
×
UNCOV
1505
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1506
      }
1507
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
×
1508
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1509
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1510
      EXPLAIN_ROW_END();
×
1511
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1512

UNCOV
1513
      if (verbose) {
×
UNCOV
1514
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1515
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1516
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
UNCOV
1517
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
1518
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
×
1519
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
×
UNCOV
1520
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
×
1521
        EXPLAIN_ROW_END();
×
1522
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1523

1524
        if (pLastRowNode->scan.node.pConditions) {
×
1525
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1526
          QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1527
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1528
          EXPLAIN_ROW_END();
×
UNCOV
1529
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1530
        }
1531
      }
UNCOV
1532
      break;
×
1533
    }
1534
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
145✔
1535
      SGroupSortPhysiNode *pSortNode = (SGroupSortPhysiNode *)pNode;
145✔
1536
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_SORT_FORMAT);
145!
1537
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
145✔
1538
      if (pResNode->pExecInfo) {
145!
1539
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1540
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1541
      }
1542

1543
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
145✔
1544
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
145✔
1545
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
145✔
1546
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
145✔
1547
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
145✔
1548
      EXPLAIN_ROW_END();
145✔
1549
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
145!
1550

1551
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
145!
1552
        // sort key
1553
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
×
1554
        if (pResNode->pExecInfo) {
×
UNCOV
1555
          for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
×
UNCOV
1556
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
×
UNCOV
1557
            EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
×
1558
          }
1559
        }
1560

1561
        EXPLAIN_ROW_END();
×
1562
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1563

1564
        // sort method
1565
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
×
1566

1567
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
×
1568
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
×
1569
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
×
1570
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
×
UNCOV
1571
        if (pExecInfo->sortBuffer > 1024 * 1024) {
×
1572
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1573
        } else if (pExecInfo->sortBuffer > 1024) {
×
1574
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
1575
        } else {
1576
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1577
        }
1578

1579
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
×
1580
        EXPLAIN_ROW_END();
×
1581
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1582
      }
1583

1584
      if (verbose) {
145!
1585
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1586
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1587
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
1588
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1589
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
×
1590
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
×
UNCOV
1591
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
×
UNCOV
1592
        EXPLAIN_ROW_END();
×
UNCOV
1593
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1594

1595
        if (pSortNode->node.pConditions) {
×
1596
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1597
          QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1598
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1599
          EXPLAIN_ROW_END();
×
1600
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1601
        }
1602
      }
1603
      break;
145✔
1604
    }
UNCOV
1605
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: {
×
1606
      SMergeIntervalPhysiNode *pIntNode = (SMergeIntervalPhysiNode *)pNode;
×
UNCOV
1607
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
×
UNCOV
1608
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
UNCOV
1609
      if (pResNode->pExecInfo) {
×
UNCOV
1610
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
1611
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1612
      }
UNCOV
1613
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
×
UNCOV
1614
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
UNCOV
1615
      EXPLAIN_ROW_END();
×
UNCOV
1616
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1617

UNCOV
1618
      if (verbose) {
×
UNCOV
1619
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
UNCOV
1620
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1621
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
UNCOV
1622
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
UNCOV
1623
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
×
UNCOV
1624
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
×
UNCOV
1625
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
×
UNCOV
1626
        EXPLAIN_ROW_END();
×
UNCOV
1627
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
UNCOV
1628
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
×
UNCOV
1629
        int64_t time1 = -1;
×
UNCOV
1630
        int64_t time2 = -1;
×
UNCOV
1631
        int32_t code = TSDB_CODE_SUCCESS;
×
UNCOV
1632
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
×
UNCOV
1633
        QRY_ERR_RET(code);
×
UNCOV
1634
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
×
UNCOV
1635
        QRY_ERR_RET(code);
×
UNCOV
1636
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
×
1637
                        time1,
1638
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1639
                        time2,
1640
                        pIntNode->slidingUnit);
1641
        EXPLAIN_ROW_END();
×
1642
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1643

1644
        if (pIntNode->window.node.pConditions) {
×
1645
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1646
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1647
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1648
          EXPLAIN_ROW_END();
×
1649
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1650
        }
1651
      }
UNCOV
1652
      break;
×
1653
    }
1654
    case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
2✔
1655
      SInterpFuncPhysiNode *pInterpNode = (SInterpFuncPhysiNode *)pNode;
2✔
1656
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERP_FORMAT);
2!
1657
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
2✔
1658
      if (pResNode->pExecInfo) {
2✔
1659
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1!
1660
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
1661
      }
1662
      if (pInterpNode->pFuncs) {
2!
1663
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pInterpNode->pFuncs->length);
2✔
1664
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1665
      }
1666

1667
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pInterpNode->fillMode));
2✔
1668
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1669

1670
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
2✔
1671
      EXPLAIN_ROW_END();
2✔
1672
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
2!
1673

1674
      if (verbose) {
2!
1675
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2!
1676
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2✔
1677
                           nodesGetOutputNumFromSlotList(pInterpNode->node.pOutputDataBlockDesc->pSlots));
1678
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1679
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pInterpNode->node.pOutputDataBlockDesc->outputRowSize);
2✔
1680
        EXPLAIN_ROW_APPEND_LIMIT(pInterpNode->node.pLimit);
2!
1681
        EXPLAIN_ROW_APPEND_SLIMIT(pInterpNode->node.pSlimit);
2!
1682
        EXPLAIN_ROW_END();
2✔
1683
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
1684
        if (pInterpNode->pFillValues) {
2!
UNCOV
1685
          SNodeListNode *pValues = (SNodeListNode *)pInterpNode->pFillValues;
×
UNCOV
1686
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
×
UNCOV
1687
          SNode  *tNode = NULL;
×
UNCOV
1688
          int32_t i = 0;
×
UNCOV
1689
          FOREACH(tNode, pValues->pNodeList) {
×
UNCOV
1690
            if (i) {
×
UNCOV
1691
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1692
            }
UNCOV
1693
            SValueNode *tValue = (SValueNode *)tNode;
×
UNCOV
1694
            char       *value = nodesGetStrValueFromNode(tValue);
×
UNCOV
1695
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
×
UNCOV
1696
            taosMemoryFree(value);
×
UNCOV
1697
            ++i;
×
1698
          }
1699

UNCOV
1700
          EXPLAIN_ROW_END();
×
UNCOV
1701
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1702
        }
1703

1704
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_INTERVAL_VALUE_FORMAT, pInterpNode->interval, pInterpNode->intervalUnit);
2!
1705
        EXPLAIN_ROW_END();
2✔
1706

1707
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pInterpNode->timeRange.skey, pInterpNode->timeRange.ekey);
2!
1708
        EXPLAIN_ROW_END();
2✔
1709
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
1710

1711
        if (pInterpNode->node.pConditions) {
2!
UNCOV
1712
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1713
          QRY_ERR_RET(nodesNodeToSQL(pInterpNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1714
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1715
          EXPLAIN_ROW_END();
×
UNCOV
1716
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1717
        }
1718
      }
1719
      break;
2✔
1720
    }
1721
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT: {
7✔
1722
      SEventWinodwPhysiNode *pEventNode = (SEventWinodwPhysiNode *)pNode;
7✔
1723
      EXPLAIN_ROW_NEW(level, EXPLAIN_EVENT_FORMAT);
7!
1724
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7✔
1725
      if (pResNode->pExecInfo) {
7✔
1726
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1!
1727
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
1728
      }
1729
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pEventNode->window.pFuncs->length);
7✔
1730
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7✔
1731
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pEventNode->window.node.pOutputDataBlockDesc->totalRowSize);
7✔
1732
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7✔
1733
      EXPLAIN_ROW_END();
7✔
1734
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7!
1735

1736
      if (verbose) {
7!
1737
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_START_FORMAT);
7!
1738
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pStartCond, tbuf + VARSTR_HEADER_SIZE,
7!
1739
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1740
        EXPLAIN_ROW_END();
7✔
1741
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
7!
1742

1743
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_END_FORMAT);
7!
1744
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pEndCond, tbuf + VARSTR_HEADER_SIZE,
7!
1745
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1746
        EXPLAIN_ROW_END();
7✔
1747
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
7!
1748
      }
1749
      break;
7✔
1750
    }
1751
    case QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN:{
7,912✔
1752
      SHashJoinPhysiNode *pJoinNode = (SHashJoinPhysiNode *)pNode;
7,912✔
1753
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
7,912!
1754
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,912✔
1755
      if (pResNode->pExecInfo) {
7,912✔
1756
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1757
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1758
      }
1759
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
7,912✔
1760
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1761
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
7,912✔
1762
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1763
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
7,912!
1764
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1765
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Hash");
7,912✔
1766
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,912✔
1767
      EXPLAIN_ROW_END();
7,912✔
1768
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,912!
1769

1770
      if (verbose) {
7,912✔
1771
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2!
1772
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2✔
1773
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
1774
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1775
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
2✔
1776
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
2!
1777
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
2!
1778
        EXPLAIN_ROW_END();
2✔
1779
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
1780

1781
        if (pJoinNode->node.pConditions) {
2!
UNCOV
1782
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1783
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1784
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1785

UNCOV
1786
          EXPLAIN_ROW_END();
×
UNCOV
1787
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1788
        }
1789

1790
        bool conditionsGot = false;
2✔
1791
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
2!
1792
        if (pJoinNode->pPrimKeyCond) {
2!
UNCOV
1793
          QRY_ERR_RET(
×
1794
              nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1795
          conditionsGot = true;
×
1796
        }
1797
        if (pJoinNode->pColEqCond) {
2!
UNCOV
1798
          if (conditionsGot) {
×
UNCOV
1799
            EXPLAIN_ROW_APPEND(" AND ");
×
1800
          }
UNCOV
1801
          QRY_ERR_RET(
×
1802
              nodesNodeToSQL(pJoinNode->pColEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1803
          conditionsGot = true;
×
1804
        }
1805
        if (pJoinNode->pTagEqCond) {
2!
1806
          if (conditionsGot) {
2!
UNCOV
1807
            EXPLAIN_ROW_APPEND(" AND ");
×
1808
          }
1809
          QRY_ERR_RET(
2!
1810
              nodesNodeToSQL(pJoinNode->pTagEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1811
          conditionsGot = true;
2✔
1812
        }
1813
        if (pJoinNode->pFullOnCond) {
2!
UNCOV
1814
          if (conditionsGot) {
×
UNCOV
1815
            EXPLAIN_ROW_APPEND(" AND ");
×
1816
          }
UNCOV
1817
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE,
×
1818
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1819
        }
1820
        EXPLAIN_ROW_END();
2✔
1821
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
1822

1823
        if (pJoinNode->timeRangeTarget) {
2!
UNCOV
1824
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TABLE_TIMERANGE_FORMAT, qExplainGetTimerangeTargetStr(pJoinNode->timeRangeTarget), pJoinNode->timeRange.skey, pJoinNode->timeRange.ekey);
×
UNCOV
1825
          EXPLAIN_ROW_END();
×
UNCOV
1826
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1827
        }
1828
      }
1829
      break;
7,912✔
1830
    }
1831
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE:{
7,912✔
1832
      SGroupCachePhysiNode *pGroupCache = (SGroupCachePhysiNode *)pNode;
7,912✔
1833
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_CACHE_FORMAT);
7,912!
1834
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,912✔
1835
      if (pResNode->pExecInfo) {
7,912✔
1836
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1837
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1838
      }
1839
      EXPLAIN_ROW_APPEND(EXPLAIN_GLOBAL_GROUP_FORMAT, pGroupCache->globalGrp);
7,912✔
1840
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1841
      EXPLAIN_ROW_APPEND(EXPLAIN_GROUP_BY_UID_FORMAT, pGroupCache->grpByUid);
7,912✔
1842
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1843
      EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pGroupCache->batchFetch);
7,912✔
1844
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1845
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->totalRowSize);
7,912✔
1846
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1847
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pGroupCache->node.inputTsOrder));
7,912!
1848
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1849
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,912✔
1850
      EXPLAIN_ROW_END();
7,912✔
1851
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,912!
1852

1853
      if (verbose) {
7,912✔
1854
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2!
1855
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2✔
1856
                           nodesGetOutputNumFromSlotList(pGroupCache->node.pOutputDataBlockDesc->pSlots));
1857
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1858
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->outputRowSize);
2✔
1859
        EXPLAIN_ROW_APPEND_LIMIT(pGroupCache->node.pLimit);
2!
1860
        EXPLAIN_ROW_APPEND_SLIMIT(pGroupCache->node.pSlimit);
2!
1861
        EXPLAIN_ROW_END();
2✔
1862
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
1863

1864
        if (pGroupCache->node.pConditions) {
2!
1865
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1866
          QRY_ERR_RET(nodesNodeToSQL(pGroupCache->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1867
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1868
          EXPLAIN_ROW_END();
×
UNCOV
1869
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1870
        }
1871
      }
1872
      break;
7,912✔
1873
    }
1874
    case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:{
7,912✔
1875
      SDynQueryCtrlPhysiNode *pDyn = (SDynQueryCtrlPhysiNode *)pNode;
7,912✔
1876
      EXPLAIN_ROW_NEW(level, EXPLAIN_DYN_QRY_CTRL_FORMAT, qExplainGetDynQryCtrlType(pDyn->qType));
7,912!
1877
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,912✔
1878
      if (pResNode->pExecInfo) {
7,912✔
1879
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1880
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1881
      }
1882
      EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pDyn->stbJoin.batchFetch);
7,912✔
1883
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1884
      EXPLAIN_ROW_APPEND(EXPLAIN_VGROUP_SLOT_FORMAT, pDyn->stbJoin.vgSlot[0], pDyn->stbJoin.vgSlot[1]);
7,912✔
1885
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1886
      EXPLAIN_ROW_APPEND(EXPLAIN_UID_SLOT_FORMAT, pDyn->stbJoin.uidSlot[0], pDyn->stbJoin.uidSlot[1]);
7,912✔
1887
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1888
      EXPLAIN_ROW_APPEND(EXPLAIN_SRC_SCAN_FORMAT, pDyn->stbJoin.srcScan[0], pDyn->stbJoin.srcScan[1]);
7,912✔
1889
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1890
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
7,912✔
1891
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1892
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
7,912!
1893
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,912✔
1894
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,912✔
1895
      EXPLAIN_ROW_END();
7,912✔
1896
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,912!
1897

1898
      if (verbose) {
7,912✔
1899
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2!
1900
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2✔
1901
                           nodesGetOutputNumFromSlotList(pDyn->node.pOutputDataBlockDesc->pSlots));
1902
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1903
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->outputRowSize);
2✔
1904
        EXPLAIN_ROW_APPEND_LIMIT(pDyn->node.pLimit);
2!
1905
        EXPLAIN_ROW_APPEND_SLIMIT(pDyn->node.pSlimit);
2!
1906
        EXPLAIN_ROW_END();
2✔
1907
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
1908

1909
        if (pDyn->node.pConditions) {
2!
UNCOV
1910
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
UNCOV
1911
          QRY_ERR_RET(nodesNodeToSQL(pDyn->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1912
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
UNCOV
1913
          EXPLAIN_ROW_END();
×
UNCOV
1914
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1915
        }
1916
      }
1917
      break;
7,912✔
1918
    }
UNCOV
1919
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT: {
×
UNCOV
1920
      SCountWinodwPhysiNode *pCountNode = (SCountWinodwPhysiNode *)pNode;
×
UNCOV
1921
      EXPLAIN_ROW_NEW(level, EXPLAIN_COUNT_FORMAT);
×
UNCOV
1922
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
UNCOV
1923
      if (pResNode->pExecInfo) {
×
UNCOV
1924
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
UNCOV
1925
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1926
      }
UNCOV
1927
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pCountNode->window.pFuncs->length);
×
1928
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1929
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pCountNode->window.node.pOutputDataBlockDesc->totalRowSize);
×
UNCOV
1930
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
UNCOV
1931
      EXPLAIN_ROW_END();
×
UNCOV
1932
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1933

UNCOV
1934
      if (verbose) {
×
UNCOV
1935
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_NUM_FORMAT, pCountNode->windowCount);
×
UNCOV
1936
        EXPLAIN_ROW_END();
×
UNCOV
1937
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
UNCOV
1938
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_SLIDING_FORMAT, pCountNode->windowSliding);
×
UNCOV
1939
        EXPLAIN_ROW_END();
×
UNCOV
1940
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1941
      }
UNCOV
1942
      break;
×
1943
    }
UNCOV
1944
    default:
×
UNCOV
1945
      qError("not supported physical node type %d", pNode->type);
×
UNCOV
1946
      return TSDB_CODE_APP_ERROR;
×
1947
  }
1948

1949
  return TSDB_CODE_SUCCESS;
840,648✔
1950
}
1951

1952
static int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
840,648✔
1953
  if (NULL == pResNode) {
840,648!
UNCOV
1954
    qError("explain res node is NULL");
×
UNCOV
1955
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
1956
  }
1957

1958
  int32_t code = 0;
840,648✔
1959
  QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
840,648!
1960

1961
  SNode *pNode = NULL;
840,648✔
1962
  FOREACH(pNode, pResNode->pChildren) { QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1)); }
1,350,291!
1963

1964
  return TSDB_CODE_SUCCESS;
840,648✔
1965
}
1966

1967
static int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level, bool singleChannel) {
331,005✔
1968
  SExplainResNode *node = NULL;
331,005✔
1969
  int32_t          code = 0;
331,005✔
1970
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
331,005✔
1971

1972
  SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
331,005✔
1973
  if (NULL == group) {
331,005!
UNCOV
1974
    qError("group %d not in groupHash", groupId);
×
UNCOV
1975
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
1976
  }
1977

1978
  group->singleChannel = singleChannel;
331,005✔
1979
  group->physiPlanExecIdx = 0;
331,005✔
1980

1981
  QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));
331,005!
1982

1983
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
331,005!
1984

1985
_return:
331,005✔
1986

1987
  qExplainFreeResNode(node);
331,005✔
1988

1989
  QRY_RET(code);
331,005!
1990
}
1991

1992
static int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
109,385✔
1993
  int32_t      code = 0;
109,385✔
1994
  SSDataBlock *pBlock = NULL;
109,385✔
1995
  SExplainCtx *pCtx = (SExplainCtx *)ctx;
109,385✔
1996
  int32_t      rowNum = taosArrayGetSize(pCtx->rows);
109,385✔
1997
  if (rowNum <= 0) {
109,385!
UNCOV
1998
    qError("empty explain res rows");
×
UNCOV
1999
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2000
  }
2001

2002
  code = createDataBlock(&pBlock);
109,385✔
2003
  QRY_ERR_JRET(code);
109,385!
2004

2005
  SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, TSDB_EXPLAIN_RESULT_ROW_SIZE, 1);
109,385✔
2006
  QRY_ERR_JRET(blockDataAppendColInfo(pBlock, &infoData));
109,385!
2007
  QRY_ERR_JRET(blockDataEnsureCapacity(pBlock, rowNum));
109,385!
2008

2009
  SColumnInfoData *pInfoData = taosArrayGet(pBlock->pDataBlock, 0);
109,385✔
2010

2011
  for (int32_t i = 0; i < rowNum; ++i) {
1,227,085✔
2012
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
1,117,700✔
2013
    QRY_ERR_JRET(colDataSetVal(pInfoData, i, row->buf, false));
1,117,700!
2014
  }
2015

2016
  pBlock->info.rows = rowNum;
109,385✔
2017

2018
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
109,385✔
2019
  int32_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
109,385✔
2020

2021
  SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
109,385!
2022
  if (NULL == rsp) {
109,385!
UNCOV
2023
    qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
×
2024
    QRY_ERR_JRET(terrno);
×
2025
  }
2026

2027
  rsp->completed = 1;
109,385✔
2028
  rsp->numOfRows = htobe64((int64_t)rowNum);
109,385✔
2029

2030
  int32_t len = blockEncode(pBlock, rsp->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, taosArrayGetSize(pBlock->pDataBlock));
109,385✔
2031
  if(len < 0) {
109,385!
UNCOV
2032
    qError("qExplainGetRspFromCtx: blockEncode failed");
×
UNCOV
2033
    QRY_ERR_JRET(terrno);
×
2034
  }
2035

2036
  rsp->compLen = htonl(len);
109,385✔
2037
  rsp->payloadLen = htonl(len);
109,385✔
2038
  rsp->compressed = 0;
109,385✔
2039

2040
  SET_PAYLOAD_LEN(rsp->data, len, len);
109,385✔
2041

2042
_return:
109,385✔
2043
  blockDataDestroy(pBlock);
109,385✔
2044

2045
  *pRsp = rsp;
109,385✔
2046
  QRY_RET(code);
109,385!
2047
}
2048

2049
static int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
109,393✔
2050
  int32_t        code = 0;
109,393✔
2051
  SNodeListNode *plans = NULL;
109,393✔
2052
  int32_t        taskNum = 0;
109,393✔
2053
  SExplainGroup *pGroup = NULL;
109,393✔
2054
  SExplainCtx   *ctx = NULL;
109,393✔
2055

2056
  if (pDag->numOfSubplans <= 0) {
109,393!
UNCOV
2057
    qError("invalid subplan num:%d", pDag->numOfSubplans);
×
2058
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2059
  }
2060

2061
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
109,393!
2062
  if (levelNum <= 0) {
109,393!
UNCOV
2063
    qError("invalid level num:%d", levelNum);
×
UNCOV
2064
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2065
  }
2066

2067
  SHashObj *groupHash =
2068
      taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
109,393✔
2069
  if (NULL == groupHash) {
109,393!
UNCOV
2070
    qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
×
UNCOV
2071
    QRY_ERR_RET(terrno);
×
2072
  }
2073

2074
  QRY_ERR_JRET(
109,393!
2075
      qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
2076

2077
  for (int32_t i = 0; i < levelNum; ++i) {
318,890✔
2078
    plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
209,497✔
2079
    if (NULL == plans) {
209,497!
UNCOV
2080
      qError("empty level plan, level:%d", i);
×
2081
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2082
    }
2083

2084
    taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
209,497!
2085
    if (taskNum <= 0) {
209,497!
UNCOV
2086
      qError("invalid level plan number:%d, level:%d", taskNum, i);
×
UNCOV
2087
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2088
    }
2089

2090
    SSubplan *plan = NULL;
209,497✔
2091
    for (int32_t n = 0; n < taskNum; ++n) {
596,593✔
2092
      plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
387,096✔
2093
      pGroup = taosHashGet(groupHash, &plan->id.groupId, sizeof(plan->id.groupId));
387,096✔
2094
      if (pGroup) {
387,096✔
2095
        ++pGroup->nodeNum;
112,183✔
2096
        continue;
112,183✔
2097
      }
2098

2099
      SExplainGroup group = {0};
274,913✔
2100
      group.nodeNum = 1;
274,913✔
2101
      group.plan = plan;
274,913✔
2102

2103
      if (0 != taosHashPut(groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
274,913!
UNCOV
2104
        qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
×
UNCOV
2105
        QRY_ERR_JRET(terrno);
×
2106
      }
2107
    }
2108

2109
    if (0 == i) {
209,497✔
2110
      if (taskNum > 1) {
109,393!
UNCOV
2111
        qError("invalid taskNum %d for level 0", taskNum);
×
UNCOV
2112
        QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2113
      }
2114

2115
      ctx->rootGroupId = plan->id.groupId;
109,393✔
2116
    }
2117

2118
    qDebug("level %d group handled, taskNum:%d", i, taskNum);
209,497✔
2119
  }
2120

2121
  *pCtx = ctx;
109,393✔
2122

2123
  return TSDB_CODE_SUCCESS;
109,393✔
2124

UNCOV
2125
_return:
×
2126

2127
  qExplainFreeCtx(ctx);
×
2128

UNCOV
2129
  QRY_RET(code);
×
2130
}
2131

2132
static int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
109,385✔
2133
  if (EXPLAIN_MODE_ANALYZE != pCtx->mode) {
109,385✔
2134
    return TSDB_CODE_SUCCESS;
100,061✔
2135
  }
2136

2137
  int32_t tlen = 0;
9,324✔
2138
  char   *tbuf = pCtx->tbuf;
9,324✔
2139

2140
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
9,324✔
2141
  EXPLAIN_SUM_ROW_END();
9,324✔
2142
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
9,324!
2143

2144
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_PLANNING_TIME_FORMAT, (double)(pCtx->jobStartTs - pCtx->reqStartTs) / 1000.0);
9,324✔
2145
  EXPLAIN_SUM_ROW_END();
9,324✔
2146
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
9,324!
2147

2148
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_EXEC_TIME_FORMAT, (double)(pCtx->jobDoneTs - pCtx->jobStartTs) / 1000.0);
9,324✔
2149
  EXPLAIN_SUM_ROW_END();
9,324✔
2150
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
9,324!
2151

2152
  return TSDB_CODE_SUCCESS;
9,324✔
2153
}
2154

2155
static int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
109,385✔
2156
  QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->rootGroupId, 0, false));
109,385!
2157
  QRY_ERR_RET(qExplainAppendPlanRows(pCtx));
109,385!
2158
  QRY_ERR_RET(qExplainGetRspFromCtx(pCtx, pRsp));
109,385!
2159

2160
  return TSDB_CODE_SUCCESS;
109,385✔
2161
}
2162

2163
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
19,536✔
2164
  if(!pCtx || !pRspMsg || !pRsp) return TSDB_CODE_INVALID_PARA;
19,536!
2165
  SExplainResNode *node = NULL;
19,536✔
2166
  int32_t          code = 0;
19,536✔
2167
  bool             groupDone = false;
19,536✔
2168
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
19,536✔
2169

2170
  SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
19,536✔
2171
  if (NULL == group) {
19,536!
UNCOV
2172
    qError("group %d not in groupHash", groupId);
×
UNCOV
2173
    tFreeSExplainRsp(pRspMsg);
×
UNCOV
2174
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2175
  }
2176

2177
  taosWLockLatch(&group->lock);
19,536✔
2178
  if (NULL == group->nodeExecInfo) {
19,536✔
2179
    group->nodeExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainRsp));
15,287✔
2180
    if (NULL == group->nodeExecInfo) {
15,287!
UNCOV
2181
      qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
UNCOV
2182
      code = terrno;
×
UNCOV
2183
      TAOS_CHECK_ERRNO(code);
×
2184
    }
2185

2186
    group->physiPlanExecNum = pRspMsg->numOfPlans;
15,287✔
2187
  } else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
4,249!
UNCOV
2188
    qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo),
×
2189
           group->nodeNum);
UNCOV
2190
    code = TSDB_CODE_APP_ERROR;
×
UNCOV
2191
    TAOS_CHECK_ERRNO(code);
×
2192
  }
2193

2194
  if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
19,536!
UNCOV
2195
    qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum,
×
2196
           groupId);
UNCOV
2197
    code = TSDB_CODE_APP_ERROR;
×
UNCOV
2198
    TAOS_CHECK_ERRNO(code);
×
2199
  }
2200

2201
  if(taosArrayPush(group->nodeExecInfo, pRspMsg) == NULL)
39,072!
2202
  {
UNCOV
2203
    code = terrno;
×
UNCOV
2204
    TAOS_CHECK_ERRNO(code);
×
2205
  }
2206

2207
  groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
19,536✔
2208

2209
  taosWUnLockLatch(&group->lock);
19,536✔
2210

2211
  if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
19,536✔
2212
    if (atomic_load_8((int8_t *)&pCtx->execDone)) {
9,324✔
2213
      if (0 == taosWTryLockLatch(&pCtx->lock)) {
2!
2214
        QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
2!
2215
        // LEAVE LOCK THERE
2216
      }
2217
    }
2218
  }
2219

2220
  return TSDB_CODE_SUCCESS;
19,536✔
2221

UNCOV
2222
_exit:
×
UNCOV
2223
  tFreeSExplainRsp(pRspMsg);
×
UNCOV
2224
  taosWUnLockLatch(&group->lock);
×
UNCOV
2225
  return code;
×
2226
}
2227

2228
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
100,061✔
2229
  if (!pDag || !pRsp) return TSDB_CODE_INVALID_PARA;
100,061!
2230
  int32_t      code = 0;
100,061✔
2231
  SExplainCtx *pCtx = NULL;
100,061✔
2232

2233
  QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
100,061!
2234
  QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
100,061!
2235

2236
_return:
100,061✔
2237
  qExplainFreeCtx(pCtx);
100,061✔
2238
  QRY_RET(code);
100,061!
2239
}
2240

2241
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
9,332✔
2242
  if(!pDag || !pCtx) return TSDB_CODE_INVALID_PARA;
9,332!
2243
  QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx));
9,332!
2244

2245
  (*pCtx)->reqStartTs = startTs;
9,332✔
2246
  (*pCtx)->jobStartTs = taosGetTimestampUs();
9,332✔
2247

2248
  return TSDB_CODE_SUCCESS;
9,332✔
2249
}
2250

2251
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
9,324✔
2252
  if(!pCtx || !pRsp) return TSDB_CODE_INVALID_PARA;
9,324!
2253
  int32_t code = 0;
9,324✔
2254
  pCtx->jobDoneTs = taosGetTimestampUs();
9,324✔
2255

2256
  atomic_store_8((int8_t *)&pCtx->execDone, true);
9,324✔
2257

2258
  if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) {
9,324✔
2259
    if (0 == taosWTryLockLatch(&pCtx->lock)) {
9,322!
2260
      QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
9,322!
2261
      // LEAVE LOCK THERE
2262
    }
2263
  }
2264

2265
  return TSDB_CODE_SUCCESS;
9,324✔
2266
}
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