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

taosdata / TDengine / #3543

29 Nov 2024 02:58AM UTC coverage: 60.842% (+0.02%) from 60.819%
#3543

push

travis-ci

web-flow
Merge pull request #28973 from taosdata/merge/mainto3.0

merge: from main to 3.0

120460 of 253224 branches covered (47.57%)

Branch coverage included in aggregate %.

706 of 908 new or added lines in 18 files covered. (77.75%)

2401 existing lines in 137 files now uncovered.

201633 of 276172 relevant lines covered (73.01%)

19045673.23 hits per line

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

58.51
/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,910✔
37
  switch (type) {
7,910!
38
    case DYN_QTYPE_STB_HASH:
7,910✔
39
      return "STable Join";
7,910✔
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) {
969,832✔
74
  if (NULL == resNode) {
969,832!
75
    return;
×
76
  }
77

78
  taosArrayDestroy(resNode->pExecInfo);
969,832✔
79

80
  SNode *node = NULL;
969,832✔
81
  FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
1,551,167✔
82
  nodesClearList(resNode->pChildren);
969,832✔
83

84
  taosMemoryFreeClear(resNode);
969,832!
85
}
86

87
void qExplainFreeCtx(SExplainCtx *pCtx) {
10,710,017✔
88
  if (NULL == pCtx) {
10,710,017✔
89
    return;
10,580,011✔
90
  }
91

92
  int32_t rowSize = taosArrayGetSize(pCtx->rows);
130,006✔
93
  for (int32_t i = 0; i < rowSize; ++i) {
1,576,274✔
94
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
1,444,702✔
95
    taosMemoryFreeClear(row->buf);
1,444,702!
96
  }
97

98
  if (EXPLAIN_MODE_ANALYZE == pCtx->mode && pCtx->groupHash) {
131,572!
99
    void *pIter = taosHashIterate(pCtx->groupHash, NULL);
12,259✔
100
    while (pIter) {
31,038✔
101
      SExplainGroup *group = (SExplainGroup *)pIter;
18,779✔
102
      if (group->nodeExecInfo) {
18,779✔
103
        int32_t num = taosArrayGetSize(group->nodeExecInfo);
18,771✔
104
        for (int32_t i = 0; i < num; ++i) {
42,336✔
105
          SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
23,565✔
106
          tFreeSExplainRsp(rsp);
23,565✔
107
        }
108
        taosArrayDestroy(group->nodeExecInfo);
18,771✔
109
      }
110

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

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

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

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

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

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

148
  *pCtx = ctx;
131,572✔
149

150
  return TSDB_CODE_SUCCESS;
131,572✔
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) {
969,832✔
162
  int32_t    tlen = 0;
969,832✔
163
  SNodeList *pPhysiChildren = pNode->pChildren;
969,832✔
164

165
  if (pPhysiChildren) {
969,832✔
166
    int32_t code = nodesMakeList(pChildren);
459,515✔
167
    if (NULL == *pChildren) {
459,515!
168
      qError("nodesMakeList failed");
×
169
      QRY_ERR_RET(code);
×
170
    }
171
  }
172

173
  SNode           *node = NULL;
969,832✔
174
  SExplainResNode *pResNode = NULL;
969,832✔
175
  FOREACH(node, pPhysiChildren) {
1,551,167✔
176
    QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
581,335!
177
    QRY_ERR_RET(nodesListAppend(*pChildren, (SNode *)pResNode));
581,335!
178
  }
179

180
  return TSDB_CODE_SUCCESS;
969,832✔
181
}
182

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

190
  SExplainRsp *rsp = NULL;
45,179✔
191
  if (group->singleChannel) {
45,179✔
192
    if (0 == group->physiPlanExecIdx) {
3,516✔
193
      group->nodeIdx = 0;
3,174✔
194
    }
195

196
    rsp = taosArrayGet(group->nodeExecInfo, group->nodeIdx++);
3,516✔
197
    if (group->physiPlanExecIdx >= rsp->numOfPlans) {
3,516!
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,032!
203
  } else {
204
    for (int32_t i = 0; i < group->nodeNum; ++i) {
88,392✔
205
      rsp = taosArrayGet(group->nodeExecInfo, i);
46,729✔
206
      if (group->physiPlanExecIdx >= rsp->numOfPlans) {
46,729!
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;
93,458!
212
    }
213
  }
214

215
  ++group->physiPlanExecIdx;
45,179✔
216

217
  return TSDB_CODE_SUCCESS;
45,179✔
218
}
219

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

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

233
  int32_t code = 0;
969,832✔
234
  resNode->pNode = pNode;
969,832✔
235

236
  if (group->nodeExecInfo) {
969,832✔
237
    QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(pNode, &resNode->pExecInfo, group));
45,179!
238
  }
239

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

242
  *pResNode = resNode;
969,832✔
243

244
  return TSDB_CODE_SUCCESS;
969,832✔
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) {
45,179✔
254
  int32_t          tlen = *len;
45,179✔
255
  int32_t          nodeNum = taosArrayGetSize(pExecInfo);
45,179✔
256
  SExplainExecInfo maxExecInfo = {0};
45,179✔
257

258
  for (int32_t i = 0; i < nodeNum; ++i) {
95,424✔
259
    SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
50,245✔
260
    if (execInfo->startupCost > maxExecInfo.startupCost) {
50,245✔
261
      maxExecInfo.startupCost = execInfo->startupCost;
31,593✔
262
    }
263
    if (execInfo->totalCost > maxExecInfo.totalCost) {
50,245✔
264
      maxExecInfo.totalCost = execInfo->totalCost;
46,989✔
265
    }
266
    if (execInfo->numOfRows > maxExecInfo.numOfRows) {
50,245✔
267
      maxExecInfo.numOfRows = execInfo->numOfRows;
43,277✔
268
    }
269
  }
270

271
  EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.numOfRows);
45,179✔
272

273
  *len = tlen;
45,179✔
274

275
  return TSDB_CODE_SUCCESS;
45,179✔
276
}
277

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

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

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

295
  *len = tlen;
×
296

297
  return TSDB_CODE_SUCCESS;
×
298
}
299

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

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

313
  if (NULL == taosArrayPush(ctx->rows, &row)) {
2,889,404!
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,444,702✔
320
}
321

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

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

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

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

347
  return "ts_order";
252,188✔
348
}
349

350
static char* qExplainGetScanDataLoad(STableScanPhysiNode* pScan) {
252,209✔
351
  switch (pScan->dataRequired) {
252,209!
352
    case FUNC_DATA_REQUIRED_DATA_LOAD:
240,701✔
353
      return "data";
240,701✔
354
    case FUNC_DATA_REQUIRED_SMA_LOAD:
10,834✔
355
      return "sma";
10,834✔
356
    case FUNC_DATA_REQUIRED_NOT_LOAD:
674✔
357
      return "no";
674✔
358
    default:
×
359
      break;
×
360
  }
361

362
  return "unknown";
×
363
}
364

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

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

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

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

413
        if (pTagScanNode->scan.node.pConditions) {
×
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,820✔
422
    }
423
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
252,209✔
424
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
425
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
426
      STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
252,209✔
427
      EXPLAIN_ROW_NEW(level,
252,209!
428
                      QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == pNode->type ? EXPLAIN_TBL_MERGE_SCAN_FORMAT
429
                                                                               : EXPLAIN_TBL_SCAN_FORMAT,
430
                      pTblScanNode->scan.tableName.tname);
431
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
252,209✔
432
      if (pResNode->pExecInfo) {
252,209✔
433
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
15,070!
434
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
435
      }
436

437
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
252,209✔
438
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
252,209✔
439
      if (pTblScanNode->scan.pScanPseudoCols) {
252,209✔
440
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTblScanNode->scan.pScanPseudoCols->length);
85,573✔
441
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
85,573✔
442
      }
443
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
252,209✔
444
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
252,209✔
445
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_ORDER_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
252,209✔
446
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
252,209✔
447
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_MODE_FORMAT, qExplainGetScanMode(pTblScanNode));
252,209✔
448
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
252,209✔
449
      EXPLAIN_ROW_APPEND(EXPLAIN_SCAN_DATA_LOAD_FORMAT, qExplainGetScanDataLoad(pTblScanNode));
252,209✔
450
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
252,209✔
451
      EXPLAIN_ROW_END();
252,209✔
452
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
252,209!
453

454
      // basic analyze output
455
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
252,209✔
456
        EXPLAIN_ROW_NEW(level + 1, "I/O: ");
15,070!
457

458
        int32_t                      nodeNum = taosArrayGetSize(pResNode->pExecInfo);
15,070✔
459
        struct STableScanAnalyzeInfo info = {0};
15,070✔
460

461
        int32_t maxIndex = 0;
15,070✔
462
        int32_t totalRows = 0;
15,070✔
463
        for (int32_t i = 0; i < nodeNum; ++i) {
32,527✔
464
          SExplainExecInfo      *execInfo = taosArrayGet(pResNode->pExecInfo, i);
17,457✔
465
          STableScanAnalyzeInfo *pScanInfo = (STableScanAnalyzeInfo *)execInfo->verboseInfo;
17,457✔
466

467
          info.totalBlocks += pScanInfo->totalBlocks;
17,457✔
468
          info.loadBlocks += pScanInfo->loadBlocks;
17,457✔
469
          info.totalRows += pScanInfo->totalRows;
17,457✔
470
          info.skipBlocks += pScanInfo->skipBlocks;
17,457✔
471
          info.filterTime += pScanInfo->filterTime;
17,457✔
472
          info.loadBlockStatis += pScanInfo->loadBlockStatis;
17,457✔
473
          info.totalCheckedRows += pScanInfo->totalCheckedRows;
17,457✔
474
          info.filterOutBlocks += pScanInfo->filterOutBlocks;
17,457✔
475

476
          if (pScanInfo->totalRows > totalRows) {
17,457✔
477
            totalRows = pScanInfo->totalRows;
14,418✔
478
            maxIndex = i;
14,418✔
479
          }
480
        }
481

482
        EXPLAIN_ROW_APPEND("total_blocks=%.1f", ((double)info.totalBlocks) / nodeNum);
15,070✔
483
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
484

485
        EXPLAIN_ROW_APPEND("load_blocks=%.1f", ((double)info.loadBlocks) / nodeNum);
15,070✔
486
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
487

488
        EXPLAIN_ROW_APPEND("load_block_SMAs=%.1f", ((double)info.loadBlockStatis) / nodeNum);
15,070✔
489
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
490

491
        EXPLAIN_ROW_APPEND("total_rows=%.1f", ((double)info.totalRows) / nodeNum);
15,070✔
492
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
493

494
        EXPLAIN_ROW_APPEND("check_rows=%.1f", ((double)info.totalCheckedRows) / nodeNum);
15,070✔
495
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
496
        EXPLAIN_ROW_END();
15,070✔
497

498
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
15,070!
499

500
        // 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,
501
        // start offset by 1.470 ms.
502
        SExplainExecInfo      *execInfo = taosArrayGet(pResNode->pExecInfo, maxIndex);
15,070✔
503
        STableScanAnalyzeInfo *p1 = (STableScanAnalyzeInfo *)execInfo->verboseInfo;
15,070✔
504

505
        EXPLAIN_ROW_NEW(level + 1, " ");
15,070!
506
        EXPLAIN_ROW_APPEND("max_row_task=%d, total_rows:%" PRId64 ", ep:%s (cost=%.3f..%.3f)", maxIndex, p1->totalRows,
15,070✔
507
                           "tbd", execInfo->startupCost, execInfo->totalCost);
508
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,070✔
509
        EXPLAIN_ROW_END();
15,070✔
510

511
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
15,070!
512
      }
513

514
      if (verbose) {
252,209✔
515
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
63,014!
516
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
63,014✔
517
                           nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
518
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
63,014✔
519
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
63,014✔
520
        EXPLAIN_ROW_APPEND_LIMIT(pTblScanNode->scan.node.pLimit);
63,014!
521
        EXPLAIN_ROW_APPEND_SLIMIT(pTblScanNode->scan.node.pSlimit);
63,014!
522
        EXPLAIN_ROW_END();
63,014✔
523
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
63,014!
524

525
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey,
63,014!
526
                        pTblScanNode->scanRange.ekey);
527
        EXPLAIN_ROW_END();
63,014✔
528
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
63,014!
529

530
        if (NULL != pTblScanNode->pGroupTags) {
63,014✔
531
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
12,402!
532
          EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pTblScanNode->pGroupTags->length);
12,402✔
533
          EXPLAIN_ROW_END();
12,402✔
534
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
12,402!
535
        }
536

537
        if (pTblScanNode->scan.node.pConditions) {
63,014✔
538
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
1,351!
539
          QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
1,351!
540
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
541
          EXPLAIN_ROW_END();
1,351✔
542
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,351!
543
        }
544
      }
545
      break;
252,209✔
546
    }
547
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
30✔
548
      SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
30✔
549
      EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
30!
550
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
30✔
551
      if (pResNode->pExecInfo) {
30✔
552
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
15!
553
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15✔
554
      }
555
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
30✔
556
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
30✔
557
      if (pSTblScanNode->scan.pScanPseudoCols) {
30✔
558
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pSTblScanNode->scan.pScanPseudoCols->length);
1✔
559
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
560
      }
561
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
30✔
562
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
30✔
563
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
30✔
564
      EXPLAIN_ROW_END();
30✔
565
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
30!
566

567
      if (verbose) {
30✔
568
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
4!
569
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
4✔
570
                           nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
571
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4✔
572
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
4✔
573
        EXPLAIN_ROW_APPEND_LIMIT(pSTblScanNode->scan.node.pLimit);
4!
574
        EXPLAIN_ROW_APPEND_SLIMIT(pSTblScanNode->scan.node.pSlimit);
4!
575
        EXPLAIN_ROW_END();
4✔
576
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
4!
577

578
        if (pSTblScanNode->scan.node.pConditions) {
4✔
579
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
2!
580
          QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
2!
581
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
582
          EXPLAIN_ROW_END();
2✔
583
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
584
        }
585
      }
586
      break;
30✔
587
    }
588
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
166,368✔
589
      SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
166,368✔
590
      EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
166,368!
591
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
166,368✔
592
      if (pResNode->pExecInfo) {
166,368✔
593
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
12,294!
594
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,294✔
595
      }
596
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
166,368✔
597
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
166,368✔
598
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
166,368✔
599
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
166,368✔
600
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pPrjNode->node.inputTsOrder));
166,368✔
601
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
166,368✔
602
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
166,368✔
603
      EXPLAIN_ROW_END();
166,368✔
604
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
166,368!
605

606
      if (verbose) {
166,368✔
607
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
15,362!
608
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
15,362✔
609
                           nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
610
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
15,362✔
611
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
15,362✔
612
        EXPLAIN_ROW_APPEND_LIMIT(pPrjNode->node.pLimit);
15,362✔
613
        EXPLAIN_ROW_APPEND_SLIMIT(pPrjNode->node.pSlimit);
15,362✔
614
        EXPLAIN_ROW_END();
15,362✔
615
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
15,362!
616

617
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
15,362!
618
        EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pPrjNode->ignoreGroupId ? "true" : "false");
15,362✔
619
        EXPLAIN_ROW_END();
15,362✔
620
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
15,362!
621

622
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pPrjNode->mergeDataBlock? "True":"False");
15,362!
623
        EXPLAIN_ROW_END();
15,362✔
624
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
15,362!
625

626
        if (pPrjNode->node.pConditions) {
15,362!
627
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
628
          QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
629
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
630
          EXPLAIN_ROW_END();
×
631
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
632
        }
633
      }
634
      break;
166,368✔
635
    }
636
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
28,969✔
637
      SSortMergeJoinPhysiNode *pJoinNode = (SSortMergeJoinPhysiNode *)pNode;
28,969✔
638
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
28,969!
639
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
28,969✔
640
      if (pResNode->pExecInfo) {
28,969✔
641
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
603!
642
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
603✔
643
      }
644
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
28,969✔
645
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,969✔
646
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
28,969✔
647
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,969✔
648
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
28,969!
649
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
28,969✔
650
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Merge");
28,969✔
651
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
28,969✔
652
      EXPLAIN_ROW_END();
28,969✔
653
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
28,969!
654

655
      if (verbose) {
28,969✔
656
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
581!
657
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
581✔
658
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
659
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
581✔
660
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
581✔
661
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
581!
662
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
581!
663
        EXPLAIN_ROW_END();
581✔
664
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
581!
665

666
        if (IS_ASOF_JOIN(pJoinNode->subType) || IS_WINDOW_JOIN(pJoinNode->subType)) {
581✔
667
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_PARAM_FORMAT);
248!
668
          if (IS_ASOF_JOIN(pJoinNode->subType)) {
248✔
669
            EXPLAIN_ROW_APPEND(EXPLAIN_ASOF_OP_FORMAT, qExplainGetAsofOpStr(pJoinNode->asofOpType));
112✔
670
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
112✔
671
          }
672
          if (NULL != pJoinNode->pWindowOffset) {
248✔
673
            SWindowOffsetNode* pWinOffset = (SWindowOffsetNode*)pJoinNode->pWindowOffset;
136✔
674
            SValueNode* pStart = (SValueNode*)pWinOffset->pStartOffset;
136✔
675
            SValueNode* pEnd = (SValueNode*)pWinOffset->pEndOffset;
136✔
676
            EXPLAIN_ROW_APPEND(EXPLAIN_WIN_OFFSET_FORMAT, pStart->literal, pEnd->literal);
136✔
677
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
136✔
678
          }
679
          if (NULL != pJoinNode->pJLimit) {
248✔
680
            SLimitNode* pJLimit = (SLimitNode*)pJoinNode->pJLimit;
44✔
681
            EXPLAIN_ROW_APPEND(EXPLAIN_JLIMIT_FORMAT, pJLimit->limit);
44✔
682
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
44✔
683
          }
684
          if (IS_WINDOW_JOIN(pJoinNode->subType)) {
248✔
685
            EXPLAIN_ROW_APPEND(EXPLAIN_SEQ_WIN_GRP_FORMAT, pJoinNode->seqWinGroup);
136✔
686
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
136✔
687
          }
688

689
          EXPLAIN_ROW_APPEND(EXPLAIN_GRP_JOIN_FORMAT, pJoinNode->grpJoin);
248✔
690
          EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
248✔
691
          EXPLAIN_ROW_END();
248✔
692

693
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
248!
694
        }
695

696
        if (pJoinNode->node.pConditions) {
581✔
697
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
46!
698
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
46!
699
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
700
          EXPLAIN_ROW_END();
46✔
701
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
46!
702
        }
703

704
        if (NULL != pJoinNode->pPrimKeyCond) {
581✔
705
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PRIM_CONDITIONS_FORMAT);
409!
706
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
409!
707
          EXPLAIN_ROW_END();
409✔
708
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
409!
709
        }
710

711
        if (NULL != pJoinNode->pEqLeft && pJoinNode->pEqLeft->length > 0) {
581!
712
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_LEFT_FORMAT);
2!
713
          SNode* pCol = NULL;
2✔
714
          FOREACH(pCol, pJoinNode->pEqLeft) {
4!
715
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
2✔
716
          }
717
          EXPLAIN_ROW_END();
2✔
718
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
719
        }
720

721
        if (NULL != pJoinNode->pEqRight && pJoinNode->pEqRight->length > 0) {
581!
722
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_JOIN_EQ_RIGHT_FORMAT);
2!
723
          SNode* pCol = NULL;
2✔
724
          FOREACH(pCol, pJoinNode->pEqRight) {
4!
725
            EXPLAIN_ROW_APPEND("`%s`.`%s` ", ((SColumnNode*)pCol)->tableAlias, ((SColumnNode*)pCol)->colName);
2✔
726
          }
727
          EXPLAIN_ROW_END();
2✔
728
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2!
729
        }
730

731
        if (NULL != pJoinNode->pFullOnCond) {
581✔
732
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
20!
733
          QRY_ERR_RET(
20!
734
                nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
735
          EXPLAIN_ROW_END();
20✔
736
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
20!
737
        }
738

739
        if (NULL != pJoinNode->pColOnCond) {
581✔
740
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COL_ON_CONDITIONS_FORMAT);
18!
741
          QRY_ERR_RET(
18!
742
                nodesNodeToSQL(pJoinNode->pColOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
743
          EXPLAIN_ROW_END();
18✔
744
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
18!
745
        }
746
      }
747
      break;
28,969✔
748
    }
749
    case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
105,244✔
750
      SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
105,244✔
751
      EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, (pAggNode->pGroupKeys ? "GroupAggregate" : "Aggregate"));
105,244!
752
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
105,244✔
753
      if (pResNode->pExecInfo) {
105,244✔
754
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
7,124!
755
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,124✔
756
      }
757
      if (pAggNode->pAggFuncs) {
105,244✔
758
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
76,113✔
759
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
76,113✔
760
      }
761
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
105,244✔
762
      if (pAggNode->pGroupKeys) {
105,244✔
763
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
31,297✔
764
        EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
31,297✔
765
      }
766
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
105,244✔
767
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pAggNode->node.inputTsOrder));
105,244✔
768
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
105,244✔
769
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
105,244✔
770
      EXPLAIN_ROW_END();
105,244✔
771
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
105,244!
772

773
      if (verbose) {
105,244✔
774
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
21,907!
775
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
21,907✔
776
                           nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
777
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
21,907✔
778
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
21,907✔
779
        EXPLAIN_ROW_APPEND_LIMIT(pAggNode->node.pLimit);
21,907!
780
        EXPLAIN_ROW_APPEND_SLIMIT(pAggNode->node.pSlimit);
21,907!
781
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
21,907✔
782
        EXPLAIN_ROW_APPEND(EXPLAIN_PLAN_BLOCKING, !pAggNode->node.forceCreateNonBlockingOptr);
21,907✔
783
        EXPLAIN_ROW_END();
21,907✔
784
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
21,907!
785

786
        if (pAggNode->node.pConditions) {
21,907✔
787
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
57!
788
          QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
57!
789
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
790
          EXPLAIN_ROW_END();
57✔
791
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
57!
792
        }
793

794
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pAggNode->mergeDataBlock? "True":"False");
21,907!
795
        EXPLAIN_ROW_END();
21,907✔
796
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
21,907!
797
      }
798
      break;
105,244✔
799
    }
800
    case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: {
12,109✔
801
      SIndefRowsFuncPhysiNode *pIndefNode = (SIndefRowsFuncPhysiNode *)pNode;
12,109✔
802
      EXPLAIN_ROW_NEW(level, EXPLAIN_INDEF_ROWS_FORMAT);
12,109!
803
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
12,109✔
804
      if (pResNode->pExecInfo) {
12,109✔
805
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
9!
806
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
9✔
807
      }
808
      if (pIndefNode->pFuncs) {
12,109!
809
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIndefNode->pFuncs->length);
12,109✔
810
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
12,109✔
811
      }
812
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->totalRowSize);
12,109✔
813
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
12,109✔
814
      EXPLAIN_ROW_END();
12,109✔
815
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
12,109!
816

817
      if (verbose) {
12,109✔
818
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,354!
819
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,354✔
820
                           nodesGetOutputNumFromSlotList(pIndefNode->node.pOutputDataBlockDesc->pSlots));
821
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,354✔
822
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->outputRowSize);
1,354✔
823
        EXPLAIN_ROW_APPEND_LIMIT(pIndefNode->node.pLimit);
1,354!
824
        EXPLAIN_ROW_APPEND_SLIMIT(pIndefNode->node.pSlimit);
1,354!
825
        EXPLAIN_ROW_END();
1,354✔
826
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,354!
827

828
        if (pIndefNode->node.pConditions) {
1,354!
829
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
830
          QRY_ERR_RET(nodesNodeToSQL(pIndefNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
831
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
832
          EXPLAIN_ROW_END();
×
833
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
834
        }
835
      }
836
      break;
12,109✔
837
    }
838
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
238,289✔
839
      SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
238,289✔
840
      int32_t nodeNum = 0;
238,289✔
841
      for (int32_t i = pExchNode->srcStartGroupId; i <= pExchNode->srcEndGroupId; ++i) {
495,222✔
842
        SExplainGroup      *group = taosHashGet(ctx->groupHash, &pExchNode->srcStartGroupId, sizeof(pExchNode->srcStartGroupId));
256,933✔
843
        if (NULL == group) {
256,933!
844
          qError("exchange src group %d not in groupHash", pExchNode->srcStartGroupId);
×
845
          QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
846
        }
847

848
        nodeNum += group->nodeNum;
256,933✔
849
      }
850

851
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, pExchNode->singleChannel ? 1 : nodeNum);
238,289!
852
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
238,289✔
853
      if (pResNode->pExecInfo) {
238,289✔
854
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
8,413!
855
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,413✔
856
      }
857
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
238,289✔
858
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
238,289✔
859
      EXPLAIN_ROW_END();
238,289✔
860
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
238,289!
861

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

873
        if (pExchNode->node.pConditions) {
58,833!
874
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
875
          QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
876
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
877
          EXPLAIN_ROW_END();
×
878
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
879
        }
880
      }
881

882
      for (int32_t i = pExchNode->srcStartGroupId; i <= pExchNode->srcEndGroupId; ++i) {
495,222✔
883
        QRY_ERR_RET(qExplainAppendGroupResRows(ctx, i, level + 1, pExchNode->singleChannel));
256,933!
884
      }
885
      break;
238,289✔
886
    }
887
    case QUERY_NODE_PHYSICAL_PLAN_SORT: {
36,302✔
888
      SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
36,302✔
889
      EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
36,302!
890
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
36,302✔
891
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.inputTsOrder));
36,302✔
892
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
36,302✔
893
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.outputTsOrder));
36,302✔
894
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
36,302✔
895
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
36,302✔
896
      if (pResNode->pExecInfo) {
36,302✔
897
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
201!
898
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
201✔
899
      }
900

901
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
36,302✔
902
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
36,302✔
903
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
36,302✔
904
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
36,302✔
905
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
36,302✔
906
      EXPLAIN_ROW_END();
36,302✔
907
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
36,302!
908

909
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
36,302✔
910
        // sort key
911
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
201!
912
        if (pResNode->pExecInfo) {
201!
913
          for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
402!
914
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
201✔
915
            EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
201✔
916
          }
917
        }
918

919
        EXPLAIN_ROW_END();
201✔
920
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
201!
921

922
        // sort method
923
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
201!
924

925
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
201✔
926
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
201✔
927
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
201✔
928
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
201✔
929
        if (pExecInfo->sortBuffer > 1024 * 1024) {
201✔
930
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
168✔
931
        } else if (pExecInfo->sortBuffer > 1024) {
33!
932
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
933
        } else {
934
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
33✔
935
        }
936

937
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
201✔
938
        EXPLAIN_ROW_END();
201✔
939
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
201!
940
      }
941

942
      if (verbose) {
36,302✔
943
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
13,964!
944
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
13,964✔
945
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
946
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
13,964✔
947
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
13,964✔
948
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
13,964!
949
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
13,964!
950
        EXPLAIN_ROW_END();
13,964✔
951
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
13,964!
952

953
        if (pSortNode->node.pConditions) {
13,964!
954
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
955
          QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
956
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
957
          EXPLAIN_ROW_END();
×
958
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
959
        }
960
      }
961
      break;
36,302✔
962
    }
963
    case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: {
22,236✔
964
      SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
22,236✔
965
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
22,236!
966
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
22,236✔
967
      if (pResNode->pExecInfo) {
22,236✔
968
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
10!
969
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
10✔
970
      }
971
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
22,236✔
972
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
22,236✔
973
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
22,236✔
974
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
22,236✔
975
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
22,236!
976
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
22,236✔
977
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
22,236!
978
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
22,236✔
979
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
22,236✔
980
      EXPLAIN_ROW_END();
22,236✔
981
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
22,236!
982

983
      if (verbose) {
22,236✔
984
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
19,812!
985
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
19,812✔
986
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
987
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
19,812✔
988
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
19,812✔
989
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
19,812!
990
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
19,812!
991
        EXPLAIN_ROW_END();
19,812✔
992
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
19,812!
993
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
19,812✔
994
        int64_t time1 = -1;
19,812✔
995
        int64_t time2 = -1;
19,812✔
996
        int32_t code = TSDB_CODE_SUCCESS;
19,812✔
997
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
19,812✔
998
        QRY_ERR_RET(code);
19,812!
999
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
19,812✔
1000
        QRY_ERR_RET(code);
19,812!
1001
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
19,812!
1002
                        time1,
1003
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1004
                        time2,
1005
                        pIntNode->slidingUnit);
1006
        EXPLAIN_ROW_END();
19,812✔
1007
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
19,812!
1008

1009
        if (pIntNode->window.node.pConditions) {
19,812!
1010
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1011
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1012
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1013
          EXPLAIN_ROW_END();
×
1014
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1015
        }
1016

1017
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
19,812!
1018
        EXPLAIN_ROW_END();
19,812✔
1019
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
19,812!
1020
      }
1021
      break;
22,236✔
1022
    }
1023
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: {
3,678✔
1024
      SMergeAlignedIntervalPhysiNode *pIntNode = (SMergeAlignedIntervalPhysiNode *)pNode;
3,678✔
1025
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
3,678!
1026
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
3,678✔
1027
      if (pResNode->pExecInfo) {
3,678✔
1028
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1029
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1030
      }
1031
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
3,678✔
1032
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,678✔
1033
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
3,678✔
1034
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,678✔
1035
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder));
3,678!
1036
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,678✔
1037
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder));
3,678!
1038
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
3,678✔
1039
      EXPLAIN_ROW_END();
3,678✔
1040
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
3,678!
1041

1042
      if (verbose) {
3,678✔
1043
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
3,507!
1044
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
3,507✔
1045
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1046
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
3,507✔
1047
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
3,507✔
1048
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
3,507!
1049
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
3,507!
1050
        EXPLAIN_ROW_END();
3,507✔
1051
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,507!
1052
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
3,507✔
1053
        int64_t time1 = -1;
3,507✔
1054
        int64_t time2 = -1;
3,507✔
1055
        int32_t code = TSDB_CODE_SUCCESS;
3,507✔
1056
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
3,507✔
1057
        QRY_ERR_RET(code);
3,507!
1058
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
3,507✔
1059
        QRY_ERR_RET(code);
3,507!
1060
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
3,507!
1061
                        time1,
1062
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1063
                        time2,
1064
                        pIntNode->slidingUnit);
1065
        EXPLAIN_ROW_END();
3,507✔
1066
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,507!
1067

1068
        if (pIntNode->window.node.pConditions) {
3,507✔
1069
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
6!
1070
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
6!
1071
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1072
          EXPLAIN_ROW_END();
6✔
1073
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
6!
1074
        }
1075

1076
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
3,507!
1077
        EXPLAIN_ROW_END();
3,507✔
1078
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
3,507!
1079
      }
1080
      break;
3,678✔
1081
    }
1082
    case QUERY_NODE_PHYSICAL_PLAN_FILL: {
8✔
1083
      SFillPhysiNode *pFillNode = (SFillPhysiNode *)pNode;
8✔
1084
      EXPLAIN_ROW_NEW(level, EXPLAIN_FILL_FORMAT);
8!
1085
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
8✔
1086
      if (pResNode->pExecInfo) {
8✔
1087
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1!
1088
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
1089
      }
1090
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pFillNode->mode));
8✔
1091
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1092
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->totalRowSize);
8✔
1093
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1094
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pFillNode->node.inputTsOrder));
8!
1095
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1096
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
8✔
1097
      EXPLAIN_ROW_END();
8✔
1098
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
8!
1099

1100
      if (verbose) {
8!
1101
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
8!
1102
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
8✔
1103
                           nodesGetOutputNumFromSlotList(pFillNode->node.pOutputDataBlockDesc->pSlots));
1104
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1105
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->outputRowSize);
8✔
1106
        EXPLAIN_ROW_APPEND_LIMIT(pFillNode->node.pLimit);
8!
1107
        EXPLAIN_ROW_APPEND_SLIMIT(pFillNode->node.pSlimit);
8!
1108
        EXPLAIN_ROW_END();
8✔
1109
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8!
1110
        if (pFillNode->pValues) {
8!
1111
          SNodeListNode *pValues = (SNodeListNode *)pFillNode->pValues;
×
1112
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
×
1113
          SNode  *tNode = NULL;
×
1114
          int32_t i = 0;
×
1115
          FOREACH(tNode, pValues->pNodeList) {
×
1116
            if (i) {
×
1117
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1118
            }
1119
            SValueNode *tValue = (SValueNode *)tNode;
×
1120
            char       *value = nodesGetStrValueFromNode(tValue);
×
1121
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
×
1122
            taosMemoryFree(value);
×
1123
            ++i;
×
1124
          }
1125

1126
          EXPLAIN_ROW_END();
×
1127
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1128
        }
1129

1130
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pFillNode->timeRange.skey, pFillNode->timeRange.ekey);
8!
1131
        EXPLAIN_ROW_END();
8✔
1132
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8!
1133

1134
        if (pFillNode->node.pConditions) {
8!
1135
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1136
          QRY_ERR_RET(nodesNodeToSQL(pFillNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1137
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1138
          EXPLAIN_ROW_END();
×
1139
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1140
        }
1141
      }
1142
      break;
8✔
1143
    }
1144
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: {
1,906✔
1145
      SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
1,906✔
1146
      EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
1,906!
1147
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,906✔
1148
      if (pResNode->pExecInfo) {
1,906!
1149
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1150
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1151
      }
1152
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length);
1,906✔
1153
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,906✔
1154
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
1,906✔
1155
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,906✔
1156
      EXPLAIN_ROW_END();
1,906✔
1157
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,906!
1158

1159
      if (verbose) {
1,906✔
1160
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
586!
1161
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
586✔
1162
                           nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
1163
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
586✔
1164
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
586✔
1165
        EXPLAIN_ROW_APPEND_LIMIT(pSessNode->window.node.pLimit);
586!
1166
        EXPLAIN_ROW_APPEND_SLIMIT(pSessNode->window.node.pSlimit);
586!
1167
        EXPLAIN_ROW_END();
586✔
1168
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
586!
1169

1170
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_WINDOW_FORMAT, pSessNode->gap);
586!
1171
        EXPLAIN_ROW_END();
586✔
1172
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
586!
1173

1174
        if (pSessNode->window.node.pConditions) {
586!
1175
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1176
          QRY_ERR_RET(nodesNodeToSQL(pSessNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1177
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1178
          EXPLAIN_ROW_END();
×
1179
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1180
        }
1181
      }
1182
      break;
1,906✔
1183
    }
1184
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE: {
936✔
1185
      SStateWinodwPhysiNode *pStateNode = (SStateWinodwPhysiNode *)pNode;
936✔
1186

1187
      EXPLAIN_ROW_NEW(level, EXPLAIN_STATE_WINDOW_FORMAT,
936!
1188
                      nodesGetNameFromColumnNode(pStateNode->pStateKey));
1189
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
936✔
1190
      if (pResNode->pExecInfo) {
936!
1191
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1192
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1193
      }
1194

1195
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pStateNode->window.pFuncs->length);
936✔
1196
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
936✔
1197
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->totalRowSize);
936✔
1198
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
936✔
1199
      EXPLAIN_ROW_END();
936✔
1200
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
936!
1201

1202
      if (verbose) {
936✔
1203
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
296!
1204
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
296✔
1205
                           nodesGetOutputNumFromSlotList(pStateNode->window.node.pOutputDataBlockDesc->pSlots));
1206
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
296✔
1207
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pStateNode->window.node.pOutputDataBlockDesc->outputRowSize);
296✔
1208
        EXPLAIN_ROW_APPEND_LIMIT(pStateNode->window.node.pLimit);
296!
1209
        EXPLAIN_ROW_APPEND_SLIMIT(pStateNode->window.node.pSlimit);
296!
1210
        EXPLAIN_ROW_END();
296✔
1211
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
296!
1212

1213
        EXPLAIN_ROW_END();
296✔
1214
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
296!
1215

1216
        if (pStateNode->window.node.pConditions) {
296!
1217
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1218
          QRY_ERR_RET(nodesNodeToSQL(pStateNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1219
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1220
          EXPLAIN_ROW_END();
×
1221
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1222
        }
1223
      }
1224
      break;
936✔
1225
    }
1226
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
5,790✔
1227
      SPartitionPhysiNode *pPartNode = (SPartitionPhysiNode *)pNode;
5,790✔
1228

1229
      SNode *p = nodesListGetNode(pPartNode->pPartitionKeys, 0);
5,790✔
1230
      EXPLAIN_ROW_NEW(level, EXPLAIN_PARITION_FORMAT, nodesGetNameFromColumnNode(p));
5,790!
1231
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
5,790✔
1232
      if (pResNode->pExecInfo) {
5,790✔
1233
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
338!
1234
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
338✔
1235
      }
1236
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->totalRowSize);
5,790✔
1237

1238
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
5,790✔
1239
      EXPLAIN_ROW_END();
5,790✔
1240
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
5,790!
1241

1242
      if (verbose) {
5,790✔
1243
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
352!
1244
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
352✔
1245
                           nodesGetOutputNumFromSlotList(pPartNode->node.pOutputDataBlockDesc->pSlots));
1246
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
352✔
1247
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPartNode->node.pOutputDataBlockDesc->outputRowSize);
352✔
1248
        EXPLAIN_ROW_APPEND_LIMIT(pPartNode->node.pLimit);
352!
1249
        EXPLAIN_ROW_APPEND_SLIMIT(pPartNode->node.pSlimit);
352!
1250
        EXPLAIN_ROW_END();
352✔
1251
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
352!
1252

1253
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
352!
1254
        EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pPartNode->pPartitionKeys->length);
352✔
1255
        EXPLAIN_ROW_END();
352✔
1256
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
352!
1257

1258
        if (pPartNode->node.pConditions) {
352!
1259
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1260
          QRY_ERR_RET(nodesNodeToSQL(pPartNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1261
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1262
          EXPLAIN_ROW_END();
×
1263
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1264
        }
1265
      }
1266
      break;
5,790✔
1267
    }
1268
    case QUERY_NODE_PHYSICAL_PLAN_MERGE: {
51,085✔
1269
      SMergePhysiNode *pMergeNode = (SMergePhysiNode *)pNode;
51,085✔
1270
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_FORMAT);
51,085!
1271
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
51,085✔
1272
      if (pResNode->pExecInfo) {
51,085✔
1273
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1,091!
1274
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,091✔
1275
      }
1276

1277
      SDataBlockDescNode *pDescNode = pMergeNode->node.pOutputDataBlockDesc;
51,085✔
1278
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
51,085✔
1279
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
51,085✔
1280
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
51,085✔
1281
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
51,085✔
1282
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.inputTsOrder));
51,085✔
1283
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
51,085✔
1284
      EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.outputTsOrder));
51,085✔
1285
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
51,085✔
1286
      EXPLAIN_ROW_APPEND(EXPLAIN_MERGE_MODE_FORMAT, EXPLAIN_MERGE_MODE_STRING(pMergeNode->type));
51,085✔
1287
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
51,085✔
1288
      EXPLAIN_ROW_END();
51,085✔
1289
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
51,085!
1290

1291
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
51,085✔
1292
        if (MERGE_TYPE_SORT == pMergeNode->type) {
1,091!
1293
          // sort method
1294
          EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
1,091!
1295

1296
          int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
1,091✔
1297
          SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
1,091✔
1298
          SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
1,091✔
1299
          EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
1,091!
1300
          if (pExecInfo->sortBuffer > 1024 * 1024) {
1,091!
1301
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1302
          } else if (pExecInfo->sortBuffer > 1024) {
1,091!
1303
            EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
1,091✔
1304
          } else {
1305
            EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1306
          }
1307

1308
          EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
1,091✔
1309
          EXPLAIN_ROW_END();
1,091✔
1310
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,091!
1311
        }
1312
      }
1313

1314
      if (verbose) {
51,085✔
1315
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
8,343!
1316
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
8,343✔
1317
                           nodesGetOutputNumFromSlotList(pMergeNode->node.pOutputDataBlockDesc->pSlots));
1318
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,343✔
1319
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pMergeNode->node.pOutputDataBlockDesc->outputRowSize);
8,343✔
1320
        EXPLAIN_ROW_APPEND_LIMIT(pMergeNode->node.pLimit);
8,343!
1321
        EXPLAIN_ROW_APPEND_SLIMIT(pMergeNode->node.pSlimit);
8,343!
1322
        EXPLAIN_ROW_END();
8,343✔
1323
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8,343!
1324

1325
        if (MERGE_TYPE_SORT == pMergeNode->type) {
8,343✔
1326
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
6,882!
1327
          EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pMergeNode->ignoreGroupId ? "true" : "false");
6,882!
1328
          EXPLAIN_ROW_END();
6,882✔
1329
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
6,882!
1330

1331
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGE_KEYS_FORMAT);
6,882!
1332
          if (pMergeNode->groupSort) {
6,882✔
1333
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, "_group_id asc");
5,330✔
1334
            if (LIST_LENGTH(pMergeNode->pMergeKeys) > 0) {
5,330!
1335
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
5,316✔
1336
            }
1337
          }
1338
          for (int32_t i = 0; i < LIST_LENGTH(pMergeNode->pMergeKeys); ++i) {
15,570✔
1339
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pMergeNode->pMergeKeys, i);
8,688✔
1340
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, nodesGetNameFromColumnNode(ptn->pExpr));
8,688✔
1341
            EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8,688✔
1342
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, EXPLAIN_ORDER_STRING(ptn->order));
8,688!
1343
            if (i != LIST_LENGTH(pMergeNode->pMergeKeys) - 1) {
8,688!
1344
              EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
1,820✔
1345
            }
1346
          }
1347
          EXPLAIN_ROW_END();
6,882✔
1348
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
6,882!
1349
        }
1350

1351
        if (pMergeNode->node.pConditions) {
8,343!
1352
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1353
          QRY_ERR_RET(nodesNodeToSQL(pMergeNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1354
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1355
          EXPLAIN_ROW_END();
×
1356
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1357
        }
1358
      }
1359
      break;
51,085✔
1360
    }
1361
    case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: {
×
1362
      SBlockDistScanPhysiNode *pDistScanNode = (SBlockDistScanPhysiNode *)pNode;
×
1363
      EXPLAIN_ROW_NEW(level, EXPLAIN_DISTBLK_SCAN_FORMAT, pDistScanNode->tableName.tname);
×
1364
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
1365
      if (pResNode->pExecInfo) {
×
1366
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1367
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1368
      }
1369
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDistScanNode->pScanCols->length);
×
1370
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1371
      if (pDistScanNode->pScanPseudoCols) {
×
1372
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pDistScanNode->pScanPseudoCols->length);
×
1373
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1374
      }
1375
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->totalRowSize);
×
1376
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1377
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1378
      EXPLAIN_ROW_END();
×
1379
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1380

1381
      if (verbose) {
×
1382
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1383
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1384
                           nodesGetOutputNumFromSlotList(pDistScanNode->node.pOutputDataBlockDesc->pSlots));
1385
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1386
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->outputRowSize);
×
1387
        EXPLAIN_ROW_APPEND_LIMIT(pDistScanNode->node.pLimit);
×
1388
        EXPLAIN_ROW_APPEND_SLIMIT(pDistScanNode->node.pSlimit);
×
1389
        EXPLAIN_ROW_END();
×
1390
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1391

1392
        if (pDistScanNode->node.pConditions) {
×
1393
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1394
          QRY_ERR_RET(nodesNodeToSQL(pDistScanNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1395
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1396
          EXPLAIN_ROW_END();
×
1397
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1398
        }
1399
      }
1400
      break;
×
1401
    }
1402
    case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: {
2,801✔
1403
      SLastRowScanPhysiNode *pLastRowNode = (SLastRowScanPhysiNode *)pNode;
2,801✔
1404
      EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->scan.tableName.tname);
2,801!
1405
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
2,801✔
1406
      if (pResNode->pExecInfo) {
2,801✔
1407
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
2!
1408
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2✔
1409
      }
1410
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->scan.pScanCols->length);
2,801✔
1411
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,801✔
1412
      if (pLastRowNode->scan.pScanPseudoCols) {
2,801✔
1413
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
526✔
1414
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
526✔
1415
      }
1416
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
2,801✔
1417
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,801✔
1418
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
2,801✔
1419
      EXPLAIN_ROW_END();
2,801✔
1420
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
2,801!
1421

1422
      if (verbose) {
2,801✔
1423
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
2,123!
1424
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
2,123✔
1425
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1426
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
2,123✔
1427
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
2,123✔
1428
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
2,123!
1429
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
2,123!
1430
        EXPLAIN_ROW_END();
2,123✔
1431
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
2,123!
1432

1433
        if (pLastRowNode->scan.node.pConditions) {
2,123!
1434
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1435
          QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1436
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1437
          EXPLAIN_ROW_END();
×
1438
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1439
        }
1440
      }
1441
      break;
2,801✔
1442
    }
1443
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
8✔
1444
      STableCountScanPhysiNode *pLastRowNode = (STableCountScanPhysiNode *)pNode;
8✔
1445
      EXPLAIN_ROW_NEW(level, EXPLAIN_TABLE_COUNT_SCAN_FORMAT,
8!
1446
                      ('\0' != pLastRowNode->scan.tableName.tname[0] ? pLastRowNode->scan.tableName.tname : TSDB_INS_TABLE_TABLES));
1447
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
8✔
1448
      if (pResNode->pExecInfo) {
8✔
1449
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
4!
1450
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
4✔
1451
      }
1452
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, LIST_LENGTH(pLastRowNode->scan.pScanCols));
8!
1453
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1454
      if (pLastRowNode->scan.pScanPseudoCols) {
8!
1455
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length);
8✔
1456
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1457
      }
1458
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize);
8✔
1459
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1460
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
8✔
1461
      EXPLAIN_ROW_END();
8✔
1462
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
8!
1463

1464
      if (verbose) {
8!
1465
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
8!
1466
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
8✔
1467
                           nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots));
1468
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
8✔
1469
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize);
8✔
1470
        EXPLAIN_ROW_APPEND_LIMIT(pLastRowNode->scan.node.pLimit);
8!
1471
        EXPLAIN_ROW_APPEND_SLIMIT(pLastRowNode->scan.node.pSlimit);
8!
1472
        EXPLAIN_ROW_END();
8✔
1473
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
8!
1474

1475
        if (pLastRowNode->scan.node.pConditions) {
8!
1476
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1477
          QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1478
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1479
          EXPLAIN_ROW_END();
×
1480
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1481
        }
1482
      }
1483
      break;
8✔
1484
    }
1485
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
145✔
1486
      SGroupSortPhysiNode *pSortNode = (SGroupSortPhysiNode *)pNode;
145✔
1487
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_SORT_FORMAT);
145!
1488
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
145✔
1489
      if (pResNode->pExecInfo) {
145!
1490
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1491
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1492
      }
1493

1494
      SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc;
145✔
1495
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots));
145✔
1496
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
145✔
1497
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize);
145✔
1498
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
145✔
1499
      EXPLAIN_ROW_END();
145✔
1500
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
145!
1501

1502
      if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
145!
1503
        // sort key
1504
        EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
×
1505
        if (pResNode->pExecInfo) {
×
1506
          for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
×
1507
            SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i);
×
1508
            EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr));
×
1509
          }
1510
        }
1511

1512
        EXPLAIN_ROW_END();
×
1513
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1514

1515
        // sort method
1516
        EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
×
1517

1518
        int32_t           nodeNum = taosArrayGetSize(pResNode->pExecInfo);
×
1519
        SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
×
1520
        SSortExecInfo    *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo;
×
1521
        EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort");
×
1522
        if (pExecInfo->sortBuffer > 1024 * 1024) {
×
1523
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0));
×
1524
        } else if (pExecInfo->sortBuffer > 1024) {
×
1525
          EXPLAIN_ROW_APPEND("  Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0));
×
1526
        } else {
1527
          EXPLAIN_ROW_APPEND("  Buffers:%d b", pExecInfo->sortBuffer);
×
1528
        }
1529

1530
        EXPLAIN_ROW_APPEND("  loops:%d", pExecInfo->loops);
×
1531
        EXPLAIN_ROW_END();
×
1532
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1533
      }
1534

1535
      if (verbose) {
145!
1536
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1537
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1538
                           nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
1539
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1540
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
×
1541
        EXPLAIN_ROW_APPEND_LIMIT(pSortNode->node.pLimit);
×
1542
        EXPLAIN_ROW_APPEND_SLIMIT(pSortNode->node.pSlimit);
×
1543
        EXPLAIN_ROW_END();
×
1544
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1545

1546
        if (pSortNode->node.pConditions) {
×
1547
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1548
          QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1549
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1550
          EXPLAIN_ROW_END();
×
1551
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1552
        }
1553
      }
1554
      break;
145✔
1555
    }
1556
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: {
×
1557
      SMergeIntervalPhysiNode *pIntNode = (SMergeIntervalPhysiNode *)pNode;
×
1558
      EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
×
1559
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
1560
      if (pResNode->pExecInfo) {
×
1561
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1562
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1563
      }
1564
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
×
1565
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1566
      EXPLAIN_ROW_END();
×
1567
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1568

1569
      if (verbose) {
×
1570
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1571
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1572
                           nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
1573
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1574
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
×
1575
        EXPLAIN_ROW_APPEND_LIMIT(pIntNode->window.node.pLimit);
×
1576
        EXPLAIN_ROW_APPEND_SLIMIT(pIntNode->window.node.pSlimit);
×
1577
        EXPLAIN_ROW_END();
×
1578
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1579
        uint8_t precision = qExplainGetIntervalPrecision(pIntNode);
×
1580
        int64_t time1 = -1;
×
1581
        int64_t time2 = -1;
×
1582
        int32_t code = TSDB_CODE_SUCCESS;
×
1583
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision, time1);
×
1584
        QRY_ERR_RET(code);
×
1585
        INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision, time2);
×
1586
        QRY_ERR_RET(code);
×
1587
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
×
1588
                        time1,
1589
                        pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
1590
                        time2,
1591
                        pIntNode->slidingUnit);
1592
        EXPLAIN_ROW_END();
×
1593
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1594

1595
        if (pIntNode->window.node.pConditions) {
×
1596
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1597
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.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;
×
1604
    }
1605
    case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
1,010✔
1606
      SInterpFuncPhysiNode *pInterpNode = (SInterpFuncPhysiNode *)pNode;
1,010✔
1607
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERP_FORMAT);
1,010!
1608
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
1,010✔
1609
      if (pResNode->pExecInfo) {
1,010✔
1610
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1!
1611
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
1612
      }
1613
      if (pInterpNode->pFuncs) {
1,010!
1614
        EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pInterpNode->pFuncs->length);
1,010✔
1615
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,010✔
1616
      }
1617

1618
      EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pInterpNode->fillMode));
1,010✔
1619
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,010✔
1620

1621
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
1,010✔
1622
      EXPLAIN_ROW_END();
1,010✔
1623
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
1,010!
1624

1625
      if (verbose) {
1,010!
1626
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
1,010!
1627
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
1,010✔
1628
                           nodesGetOutputNumFromSlotList(pInterpNode->node.pOutputDataBlockDesc->pSlots));
1629
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1,010✔
1630
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pInterpNode->node.pOutputDataBlockDesc->outputRowSize);
1,010✔
1631
        EXPLAIN_ROW_APPEND_LIMIT(pInterpNode->node.pLimit);
1,010!
1632
        EXPLAIN_ROW_APPEND_SLIMIT(pInterpNode->node.pSlimit);
1,010!
1633
        EXPLAIN_ROW_END();
1,010✔
1634
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,010!
1635
        if (pInterpNode->pFillValues) {
1,010✔
1636
          SNodeListNode *pValues = (SNodeListNode *)pInterpNode->pFillValues;
240✔
1637
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT);
240!
1638
          SNode  *tNode = NULL;
240✔
1639
          int32_t i = 0;
240✔
1640
          FOREACH(tNode, pValues->pNodeList) {
480!
1641
            if (i) {
240!
1642
              EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1643
            }
1644
            SValueNode *tValue = (SValueNode *)tNode;
240✔
1645
            char       *value = nodesGetStrValueFromNode(tValue);
240✔
1646
            EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value);
240✔
1647
            taosMemoryFree(value);
240✔
1648
            ++i;
240✔
1649
          }
1650

1651
          EXPLAIN_ROW_END();
240✔
1652
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
240!
1653
        }
1654

1655
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_INTERVAL_VALUE_FORMAT, pInterpNode->interval, pInterpNode->intervalUnit);
1,010!
1656
        EXPLAIN_ROW_END();
1,010✔
1657

1658
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pInterpNode->timeRange.skey, pInterpNode->timeRange.ekey);
1,010!
1659
        EXPLAIN_ROW_END();
1,010✔
1660
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
1,010!
1661

1662
        if (pInterpNode->node.pConditions) {
1,010!
1663
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1664
          QRY_ERR_RET(nodesNodeToSQL(pInterpNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1665
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1666
          EXPLAIN_ROW_END();
×
1667
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1668
        }
1669
      }
1670
      break;
1,010✔
1671
    }
1672
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT: {
583✔
1673
      SEventWinodwPhysiNode *pEventNode = (SEventWinodwPhysiNode *)pNode;
583✔
1674
      EXPLAIN_ROW_NEW(level, EXPLAIN_EVENT_FORMAT);
583!
1675
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
583✔
1676
      if (pResNode->pExecInfo) {
583✔
1677
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
1!
1678
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
1✔
1679
      }
1680
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pEventNode->window.pFuncs->length);
583✔
1681
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
583✔
1682
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pEventNode->window.node.pOutputDataBlockDesc->totalRowSize);
583✔
1683
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
583✔
1684
      EXPLAIN_ROW_END();
583✔
1685
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
583!
1686

1687
      if (verbose) {
583!
1688
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_START_FORMAT);
583!
1689
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pStartCond, tbuf + VARSTR_HEADER_SIZE,
583!
1690
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1691
        EXPLAIN_ROW_END();
583✔
1692
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
583!
1693

1694
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_END_FORMAT);
583!
1695
        QRY_ERR_RET(nodesNodeToSQL(pEventNode->pEndCond, tbuf + VARSTR_HEADER_SIZE,
583!
1696
                                    TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1697
        EXPLAIN_ROW_END();
583✔
1698
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
583!
1699
      }
1700
      break;
583✔
1701
    }
1702
    case QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN:{
7,910✔
1703
      SHashJoinPhysiNode *pJoinNode = (SHashJoinPhysiNode *)pNode;
7,910✔
1704
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, gJoinTypeStr[pJoinNode->joinType][pJoinNode->subType]);
7,910!
1705
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,910✔
1706
      if (pResNode->pExecInfo) {
7,910!
1707
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1708
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1709
      }
1710
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
7,910✔
1711
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1712
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
7,910✔
1713
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1714
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder));
7,910!
1715
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1716
      EXPLAIN_ROW_APPEND(EXPLAIN_JOIN_ALGO, "Hash");
7,910✔
1717
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,910✔
1718
      EXPLAIN_ROW_END();
7,910✔
1719
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,910!
1720

1721
      if (verbose) {
7,910!
1722
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1723
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1724
                           nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
1725
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1726
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
×
1727
        EXPLAIN_ROW_APPEND_LIMIT(pJoinNode->node.pLimit);
×
1728
        EXPLAIN_ROW_APPEND_SLIMIT(pJoinNode->node.pSlimit);
×
1729
        EXPLAIN_ROW_END();
×
1730
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1731

1732
        if (pJoinNode->node.pConditions) {
×
1733
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1734
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1735
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1736

1737
          EXPLAIN_ROW_END();
×
1738
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1739
        }
1740

1741
        bool conditionsGot = false;
×
1742
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
×
1743
        if (pJoinNode->pPrimKeyCond) {
×
1744
          QRY_ERR_RET(
×
1745
              nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1746
          conditionsGot = true;
×
1747
        }
1748
        if (pJoinNode->pColEqCond) {
×
1749
          if (conditionsGot) {
×
1750
            EXPLAIN_ROW_APPEND(" AND ");
×
1751
          }
1752
          QRY_ERR_RET(
×
1753
              nodesNodeToSQL(pJoinNode->pColEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1754
          conditionsGot = true;
×
1755
        }
1756
        if (pJoinNode->pTagEqCond) {
×
1757
          if (conditionsGot) {
×
1758
            EXPLAIN_ROW_APPEND(" AND ");
×
1759
          }
1760
          QRY_ERR_RET(
×
1761
              nodesNodeToSQL(pJoinNode->pTagEqCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1762
          conditionsGot = true;
×
1763
        }
1764
        if (pJoinNode->pFullOnCond) {
×
1765
          if (conditionsGot) {
×
1766
            EXPLAIN_ROW_APPEND(" AND ");
×
1767
          }
1768
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE,
×
1769
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1770
        }
1771
        EXPLAIN_ROW_END();
×
1772
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1773

1774
        if (pJoinNode->timeRangeTarget) {
×
1775
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TABLE_TIMERANGE_FORMAT, qExplainGetTimerangeTargetStr(pJoinNode->timeRangeTarget), pJoinNode->timeRange.skey, pJoinNode->timeRange.ekey);
×
1776
          EXPLAIN_ROW_END();
×
1777
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1778
        }
1779
      }
1780
      break;
7,910✔
1781
    }
1782
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE:{
7,910✔
1783
      SGroupCachePhysiNode *pGroupCache = (SGroupCachePhysiNode *)pNode;
7,910✔
1784
      EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_CACHE_FORMAT);
7,910!
1785
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,910✔
1786
      if (pResNode->pExecInfo) {
7,910!
1787
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1788
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1789
      }
1790
      EXPLAIN_ROW_APPEND(EXPLAIN_GLOBAL_GROUP_FORMAT, pGroupCache->globalGrp);
7,910✔
1791
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1792
      EXPLAIN_ROW_APPEND(EXPLAIN_GROUP_BY_UID_FORMAT, pGroupCache->grpByUid);
7,910✔
1793
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1794
      EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pGroupCache->batchFetch);
7,910✔
1795
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1796
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->totalRowSize);
7,910✔
1797
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1798
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pGroupCache->node.inputTsOrder));
7,910!
1799
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1800
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,910✔
1801
      EXPLAIN_ROW_END();
7,910✔
1802
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,910!
1803

1804
      if (verbose) {
7,910!
1805
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1806
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1807
                           nodesGetOutputNumFromSlotList(pGroupCache->node.pOutputDataBlockDesc->pSlots));
1808
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1809
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pGroupCache->node.pOutputDataBlockDesc->outputRowSize);
×
1810
        EXPLAIN_ROW_APPEND_LIMIT(pGroupCache->node.pLimit);
×
1811
        EXPLAIN_ROW_APPEND_SLIMIT(pGroupCache->node.pSlimit);
×
1812
        EXPLAIN_ROW_END();
×
1813
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1814

1815
        if (pGroupCache->node.pConditions) {
×
1816
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1817
          QRY_ERR_RET(nodesNodeToSQL(pGroupCache->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1818
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1819
          EXPLAIN_ROW_END();
×
1820
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1821
        }
1822
      }
1823
      break;
7,910✔
1824
    }
1825
    case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:{
7,910✔
1826
      SDynQueryCtrlPhysiNode *pDyn = (SDynQueryCtrlPhysiNode *)pNode;
7,910✔
1827
      EXPLAIN_ROW_NEW(level, EXPLAIN_DYN_QRY_CTRL_FORMAT, qExplainGetDynQryCtrlType(pDyn->qType));
7,910!
1828
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
7,910✔
1829
      if (pResNode->pExecInfo) {
7,910!
1830
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1831
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1832
      }
1833
      EXPLAIN_ROW_APPEND(EXPLAIN_BATCH_SCAN_FORMAT, pDyn->stbJoin.batchFetch);
7,910✔
1834
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1835
      EXPLAIN_ROW_APPEND(EXPLAIN_VGROUP_SLOT_FORMAT, pDyn->stbJoin.vgSlot[0], pDyn->stbJoin.vgSlot[1]);
7,910✔
1836
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1837
      EXPLAIN_ROW_APPEND(EXPLAIN_UID_SLOT_FORMAT, pDyn->stbJoin.uidSlot[0], pDyn->stbJoin.uidSlot[1]);
7,910✔
1838
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1839
      EXPLAIN_ROW_APPEND(EXPLAIN_SRC_SCAN_FORMAT, pDyn->stbJoin.srcScan[0], pDyn->stbJoin.srcScan[1]);
7,910✔
1840
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1841
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->totalRowSize);
7,910✔
1842
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1843
      EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pDyn->node.inputTsOrder));
7,910!
1844
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
7,910✔
1845
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
7,910✔
1846
      EXPLAIN_ROW_END();
7,910✔
1847
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
7,910!
1848

1849
      if (verbose) {
7,910!
1850
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
×
1851
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
×
1852
                           nodesGetOutputNumFromSlotList(pDyn->node.pOutputDataBlockDesc->pSlots));
1853
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1854
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDyn->node.pOutputDataBlockDesc->outputRowSize);
×
1855
        EXPLAIN_ROW_APPEND_LIMIT(pDyn->node.pLimit);
×
1856
        EXPLAIN_ROW_APPEND_SLIMIT(pDyn->node.pSlimit);
×
1857
        EXPLAIN_ROW_END();
×
1858
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1859

1860
        if (pDyn->node.pConditions) {
×
1861
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
×
1862
          QRY_ERR_RET(nodesNodeToSQL(pDyn->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
×
1863
                                     TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
1864
          EXPLAIN_ROW_END();
×
1865
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
1866
        }
1867
      }
1868
      break;
7,910✔
1869
    }
1870
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT: {
576✔
1871
      SCountWinodwPhysiNode *pCountNode = (SCountWinodwPhysiNode *)pNode;
576✔
1872
      EXPLAIN_ROW_NEW(level, EXPLAIN_COUNT_FORMAT);
576!
1873
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
576✔
1874
      if (pResNode->pExecInfo) {
576!
1875
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
1876
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
1877
      }
1878
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pCountNode->window.pFuncs->length);
576✔
1879
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
576✔
1880
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pCountNode->window.node.pOutputDataBlockDesc->totalRowSize);
576✔
1881
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
576✔
1882
      EXPLAIN_ROW_END();
576✔
1883
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
576!
1884

1885
      if (verbose) {
576!
1886
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_NUM_FORMAT, pCountNode->windowCount);
576!
1887
        EXPLAIN_ROW_END();
576✔
1888
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
576!
1889
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_SLIDING_FORMAT, pCountNode->windowSliding);
576!
1890
        EXPLAIN_ROW_END();
576✔
1891
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
576!
1892
      }
1893
      break;
576✔
1894
    }
1895
    default:
×
1896
      qError("not supported physical node type %d", pNode->type);
×
1897
      return TSDB_CODE_APP_ERROR;
×
1898
  }
1899

1900
  return TSDB_CODE_SUCCESS;
969,832✔
1901
}
1902

1903
static int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
969,832✔
1904
  if (NULL == pResNode) {
969,832!
1905
    qError("explain res node is NULL");
×
1906
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
1907
  }
1908

1909
  int32_t code = 0;
969,832✔
1910
  QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
969,832!
1911

1912
  SNode *pNode = NULL;
969,832✔
1913
  FOREACH(pNode, pResNode->pChildren) { QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1)); }
1,551,167!
1914

1915
  return TSDB_CODE_SUCCESS;
969,832✔
1916
}
1917

1918
static int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level, bool singleChannel) {
388,497✔
1919
  SExplainResNode *node = NULL;
388,497✔
1920
  int32_t          code = 0;
388,497✔
1921
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
388,497✔
1922

1923
  SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
388,497✔
1924
  if (NULL == group) {
388,497!
1925
    qError("group %d not in groupHash", groupId);
×
1926
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
1927
  }
1928

1929
  group->singleChannel = singleChannel;
388,497✔
1930
  group->physiPlanExecIdx = 0;
388,497✔
1931

1932
  QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));
388,497!
1933

1934
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
388,497!
1935

1936
_return:
388,497✔
1937

1938
  qExplainFreeResNode(node);
388,497✔
1939

1940
  QRY_RET(code);
388,497!
1941
}
1942

1943
static int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
131,564✔
1944
  int32_t      code = 0;
131,564✔
1945
  SSDataBlock *pBlock = NULL;
131,564✔
1946
  SExplainCtx *pCtx = (SExplainCtx *)ctx;
131,564✔
1947
  int32_t      rowNum = taosArrayGetSize(pCtx->rows);
131,564✔
1948
  if (rowNum <= 0) {
131,564!
1949
    qError("empty explain res rows");
×
1950
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
1951
  }
1952

1953
  code = createDataBlock(&pBlock);
131,564✔
1954
  QRY_ERR_JRET(code);
131,564!
1955

1956
  SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, TSDB_EXPLAIN_RESULT_ROW_SIZE, 1);
131,564✔
1957
  QRY_ERR_JRET(blockDataAppendColInfo(pBlock, &infoData));
131,564!
1958
  QRY_ERR_JRET(blockDataEnsureCapacity(pBlock, rowNum));
131,564!
1959

1960
  SColumnInfoData *pInfoData = taosArrayGet(pBlock->pDataBlock, 0);
131,564✔
1961

1962
  for (int32_t i = 0; i < rowNum; ++i) {
1,576,266✔
1963
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
1,444,702✔
1964
    QRY_ERR_JRET(colDataSetVal(pInfoData, i, row->buf, false));
1,444,702!
1965
  }
1966

1967
  pBlock->info.rows = rowNum;
131,564✔
1968

1969
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
131,564✔
1970
  int32_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
131,564✔
1971

1972
  SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
131,564✔
1973
  if (NULL == rsp) {
131,564!
1974
    qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
×
1975
    QRY_ERR_JRET(terrno);
×
1976
  }
1977

1978
  rsp->completed = 1;
131,564✔
1979
  rsp->numOfRows = htobe64((int64_t)rowNum);
131,564✔
1980

1981
  int32_t len = blockEncode(pBlock, rsp->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, taosArrayGetSize(pBlock->pDataBlock));
131,564✔
1982
  if(len < 0) {
131,564!
1983
    qError("qExplainGetRspFromCtx: blockEncode failed");
×
1984
    QRY_ERR_JRET(terrno);
×
1985
  }
1986

1987
  rsp->compLen = htonl(len);
131,564✔
1988
  rsp->payloadLen = htonl(len);
131,564✔
1989
  rsp->compressed = 0;
131,564✔
1990

1991
  SET_PAYLOAD_LEN(rsp->data, len, len);
131,564✔
1992

1993
_return:
131,564✔
1994
  blockDataDestroy(pBlock);
131,564✔
1995

1996
  *pRsp = rsp;
131,564✔
1997
  QRY_RET(code);
131,564!
1998
}
1999

2000
static int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
131,572✔
2001
  int32_t        code = 0;
131,572✔
2002
  SNodeListNode *plans = NULL;
131,572✔
2003
  int32_t        taskNum = 0;
131,572✔
2004
  SExplainGroup *pGroup = NULL;
131,572✔
2005
  SExplainCtx   *ctx = NULL;
131,572✔
2006

2007
  if (pDag->numOfSubplans <= 0) {
131,572!
2008
    qError("invalid subplan num:%d", pDag->numOfSubplans);
×
2009
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2010
  }
2011

2012
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
131,572!
2013
  if (levelNum <= 0) {
131,572!
2014
    qError("invalid level num:%d", levelNum);
×
2015
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
×
2016
  }
2017

2018
  SHashObj *groupHash =
2019
      taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
131,572✔
2020
  if (NULL == groupHash) {
131,572!
2021
    qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
×
2022
    QRY_ERR_RET(terrno);
×
2023
  }
2024

2025
  QRY_ERR_JRET(
131,572!
2026
      qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
2027

2028
  for (int32_t i = 0; i < levelNum; ++i) {
376,854✔
2029
    plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
245,282✔
2030
    if (NULL == plans) {
245,282!
2031
      qError("empty level plan, level:%d", i);
×
2032
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2033
    }
2034

2035
    taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
245,282!
2036
    if (taskNum <= 0) {
245,282!
2037
      qError("invalid level plan number:%d, level:%d", taskNum, i);
×
2038
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2039
    }
2040

2041
    SSubplan *plan = NULL;
245,282✔
2042
    for (int32_t n = 0; n < taskNum; ++n) {
724,737✔
2043
      plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
479,455✔
2044
      pGroup = taosHashGet(groupHash, &plan->id.groupId, sizeof(plan->id.groupId));
479,455✔
2045
      if (pGroup) {
479,455✔
2046
        ++pGroup->nodeNum;
168,614✔
2047
        continue;
168,614✔
2048
      }
2049

2050
      SExplainGroup group = {0};
310,841✔
2051
      group.nodeNum = 1;
310,841✔
2052
      group.plan = plan;
310,841✔
2053

2054
      if (0 != taosHashPut(groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
310,841!
2055
        qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
×
2056
        QRY_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
×
2057
      }
2058
    }
2059

2060
    if (0 == i) {
245,282✔
2061
      if (taskNum > 1) {
131,572!
2062
        qError("invalid taskNum %d for level 0", taskNum);
×
2063
        QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
×
2064
      }
2065

2066
      ctx->rootGroupId = plan->id.groupId;
131,572✔
2067
    }
2068

2069
    qDebug("level %d group handled, taskNum:%d", i, taskNum);
245,282✔
2070
  }
2071

2072
  *pCtx = ctx;
131,572✔
2073

2074
  return TSDB_CODE_SUCCESS;
131,572✔
2075

2076
_return:
×
2077

2078
  qExplainFreeCtx(ctx);
×
2079

2080
  QRY_RET(code);
×
2081
}
2082

2083
static int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
131,564✔
2084
  if (EXPLAIN_MODE_ANALYZE != pCtx->mode) {
131,564✔
2085
    return TSDB_CODE_SUCCESS;
119,313✔
2086
  }
2087

2088
  int32_t tlen = 0;
12,251✔
2089
  char   *tbuf = pCtx->tbuf;
12,251✔
2090

2091
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
12,251✔
2092
  EXPLAIN_SUM_ROW_END();
12,251✔
2093
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
12,251!
2094

2095
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_PLANNING_TIME_FORMAT, (double)(pCtx->jobStartTs - pCtx->reqStartTs) / 1000.0);
12,251✔
2096
  EXPLAIN_SUM_ROW_END();
12,251✔
2097
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
12,251!
2098

2099
  EXPLAIN_SUM_ROW_NEW(EXPLAIN_EXEC_TIME_FORMAT, (double)(pCtx->jobDoneTs - pCtx->jobStartTs) / 1000.0);
12,251✔
2100
  EXPLAIN_SUM_ROW_END();
12,251✔
2101
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));
12,251!
2102

2103
  return TSDB_CODE_SUCCESS;
12,251✔
2104
}
2105

2106
static int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
131,564✔
2107
  QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->rootGroupId, 0, false));
131,564!
2108
  QRY_ERR_RET(qExplainAppendPlanRows(pCtx));
131,564!
2109
  QRY_ERR_RET(qExplainGetRspFromCtx(pCtx, pRsp));
131,564!
2110

2111
  return TSDB_CODE_SUCCESS;
131,564✔
2112
}
2113

2114
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
23,565✔
2115
  if(!pCtx || !pRspMsg || !pRsp) return TSDB_CODE_INVALID_PARA;
23,565!
2116
  SExplainResNode *node = NULL;
23,565✔
2117
  int32_t          code = 0;
23,565✔
2118
  bool             groupDone = false;
23,565✔
2119
  SExplainCtx     *ctx = (SExplainCtx *)pCtx;
23,565✔
2120

2121
  SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
23,565✔
2122
  if (NULL == group) {
23,565!
2123
    qError("group %d not in groupHash", groupId);
×
2124
    tFreeSExplainRsp(pRspMsg);
×
2125
    QRY_ERR_RET(TSDB_CODE_APP_ERROR);
×
2126
  }
2127

2128
  taosWLockLatch(&group->lock);
23,565✔
2129
  if (NULL == group->nodeExecInfo) {
23,565✔
2130
    group->nodeExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainRsp));
18,771✔
2131
    if (NULL == group->nodeExecInfo) {
18,771!
2132
      qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
×
2133
      code = terrno;
×
2134
      TAOS_CHECK_ERRNO(code);
×
2135
    }
2136

2137
    group->physiPlanExecNum = pRspMsg->numOfPlans;
18,771✔
2138
  } else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
4,794!
2139
    qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo),
×
2140
           group->nodeNum);
2141
    code = TSDB_CODE_APP_ERROR;
×
2142
    TAOS_CHECK_ERRNO(code);
×
2143
  }
2144

2145
  if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
23,565!
2146
    qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum,
×
2147
           groupId);
2148
    code = TSDB_CODE_APP_ERROR;
×
2149
    TAOS_CHECK_ERRNO(code);
×
2150
  }
2151

2152
  if(taosArrayPush(group->nodeExecInfo, pRspMsg) == NULL)
47,130!
2153
  {
2154
    code = terrno;
×
2155
    TAOS_CHECK_ERRNO(code);
×
2156
  }
2157

2158
  groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
23,565✔
2159

2160
  taosWUnLockLatch(&group->lock);
23,565✔
2161

2162
  if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
23,565✔
2163
    if (atomic_load_8((int8_t *)&pCtx->execDone)) {
12,251!
UNCOV
2164
      if (0 == taosWTryLockLatch(&pCtx->lock)) {
×
UNCOV
2165
        QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
×
2166
        // LEAVE LOCK THERE
2167
      }
2168
    }
2169
  }
2170

2171
  return TSDB_CODE_SUCCESS;
23,565✔
2172

2173
_exit:
×
2174
  tFreeSExplainRsp(pRspMsg);
×
2175
  taosWUnLockLatch(&group->lock);
×
2176
  return code;
×
2177
}
2178

2179
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
119,313✔
2180
  if (!pDag || !pRsp) return TSDB_CODE_INVALID_PARA;
119,313!
2181
  int32_t      code = 0;
119,313✔
2182
  SExplainCtx *pCtx = NULL;
119,313✔
2183

2184
  QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
119,313!
2185
  QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
119,313!
2186

2187
_return:
119,313✔
2188
  qExplainFreeCtx(pCtx);
119,313✔
2189
  QRY_RET(code);
119,313!
2190
}
2191

2192
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
12,259✔
2193
  if(!pDag || !pCtx) return TSDB_CODE_INVALID_PARA;
12,259!
2194
  QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx));
12,259!
2195

2196
  (*pCtx)->reqStartTs = startTs;
12,259✔
2197
  (*pCtx)->jobStartTs = taosGetTimestampUs();
12,259✔
2198

2199
  return TSDB_CODE_SUCCESS;
12,259✔
2200
}
2201

2202
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
12,251✔
2203
  if(!pCtx || !pRsp) return TSDB_CODE_INVALID_PARA;
12,251!
2204
  int32_t code = 0;
12,251✔
2205
  pCtx->jobDoneTs = taosGetTimestampUs();
12,251✔
2206

2207
  atomic_store_8((int8_t *)&pCtx->execDone, true);
12,251✔
2208

2209
  if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) {
12,251!
2210
    if (0 == taosWTryLockLatch(&pCtx->lock)) {
12,251!
2211
      QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
12,251!
2212
      // LEAVE LOCK THERE
2213
    }
2214
  }
2215

2216
  return TSDB_CODE_SUCCESS;
12,251✔
2217
}
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

© 2025 Coveralls, Inc