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

taosdata / TDengine / #4811

16 Oct 2025 11:40AM UTC coverage: 58.693% (+0.2%) from 58.518%
#4811

push

travis-ci

web-flow
fix(tref): increase TSDB_REF_OBJECTS from 100 to 2000 for improved reference handling (#33281)

139835 of 303532 branches covered (46.07%)

Branch coverage included in aggregate %.

211576 of 295200 relevant lines covered (71.67%)

16841075.92 hits per line

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

29.75
/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) {
×
37
  switch (type) {
×
38
    case DYN_QTYPE_STB_HASH:
×
39
      return "STable Join";
×
40
    default:
×
41
      break;
×
42
  }
43

44
  return "unknown task";
×
45
}
46

47
char* qExplainGetAsofOpStr(int32_t opType) {
×
48
  switch (opType) {
×
49
    case OP_TYPE_GREATER_THAN:
×
50
      return ">";
×
51
    case OP_TYPE_GREATER_EQUAL:
×
52
      return ">=";
×
53
    case OP_TYPE_LOWER_THAN:
×
54
      return "<";
×
55
    case OP_TYPE_LOWER_EQUAL:
×
56
      return "<=";
×
57
    case OP_TYPE_EQUAL:
×
58
      return "=";
×
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) {
1,707✔
74
  if (NULL == resNode) {
1,707!
75
    return;
×
76
  }
77

78
  taosArrayDestroy(resNode->pExecInfo);
1,707✔
79

80
  SNode *node = NULL;
1,707✔
81
  FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
2,607✔
82
  nodesClearList(resNode->pChildren);
1,707✔
83

84
  taosMemoryFreeClear(resNode);
1,707!
85
}
86

87
void qExplainFreeCtx(SExplainCtx *pCtx) {
8,222,831✔
88
  if (NULL == pCtx) {
8,222,831!
89
    return;
8,224,675✔
90
  }
91

92
  int32_t rowSize = taosArrayGetSize(pCtx->rows);
×
93
  for (int32_t i = 0; i < rowSize; ++i) {
3,110✔
94
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
2,743✔
95
    taosMemoryFreeClear(row->buf);
2,743!
96
  }
97

98
  if (EXPLAIN_MODE_ANALYZE == pCtx->mode && pCtx->groupHash) {
367!
99
    void *pIter = taosHashIterate(pCtx->groupHash, NULL);
×
100
    while (pIter) {
×
101
      SExplainGroup *group = (SExplainGroup *)pIter;
×
102
      if (group->nodeExecInfo) {
×
103
        int32_t num = taosArrayGetSize(group->nodeExecInfo);
×
104
        for (int32_t i = 0; i < num; ++i) {
×
105
          SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
×
106
          tFreeSExplainRsp(rsp);
×
107
        }
108
        taosArrayDestroy(group->nodeExecInfo);
×
109
      }
110

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

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

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

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

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

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

148
  *pCtx = ctx;
367✔
149

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

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

173
  SNode           *node = NULL;
1,707✔
174
  SExplainResNode *pResNode = NULL;
1,707✔
175
  FOREACH(node, pPhysiChildren) {
2,607✔
176
    QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
900!
177
    QRY_ERR_RET(nodesListAppend(*pChildren, (SNode *)pResNode));
900!
178
  }
179

180
  return TSDB_CODE_SUCCESS;
1,707✔
181
}
182

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

190
  SExplainRsp *rsp = NULL;
×
191
  if (group->singleChannel) {
×
192
    if (0 == group->physiPlanExecIdx) {
×
193
      group->nodeIdx = 0;
×
194
    }
195

196
    rsp = taosArrayGet(group->nodeExecInfo, group->nodeIdx++);
×
197
    if (group->physiPlanExecIdx >= rsp->numOfPlans) {
×
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;
×
203
  } else {
204
    for (int32_t i = 0; i < group->nodeNum; ++i) {
×
205
      rsp = taosArrayGet(group->nodeExecInfo, i);
×
206
      if (group->physiPlanExecIdx >= rsp->numOfPlans) {
×
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;
×
212
    }
213
  }
214

215
  ++group->physiPlanExecIdx;
×
216

217
  return TSDB_CODE_SUCCESS;
×
218
}
219

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

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

233
  int32_t code = 0;
1,707✔
234
  resNode->pNode = pNode;
1,707✔
235

236
  if (group->nodeExecInfo) {
1,707!
237
    QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(pNode, &resNode->pExecInfo, group));
×
238
  }
239

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

242
  *pResNode = resNode;
1,707✔
243

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

258
  for (int32_t i = 0; i < nodeNum; ++i) {
×
259
    SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
×
260
    if (execInfo->startupCost > maxExecInfo.startupCost) {
×
261
      maxExecInfo.startupCost = execInfo->startupCost;
×
262
    }
263
    if (execInfo->totalCost > maxExecInfo.totalCost) {
×
264
      maxExecInfo.totalCost = execInfo->totalCost;
×
265
    }
266
    if (execInfo->numOfRows > maxExecInfo.numOfRows) {
×
267
      maxExecInfo.numOfRows = execInfo->numOfRows;
×
268
    }
269
  }
270

271
  EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.numOfRows);
×
272

273
  *len = tlen;
×
274

275
  return TSDB_CODE_SUCCESS;
×
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) {
2,743✔
301
  SQueryExplainRowInfo row = {0};
2,743✔
302
  row.buf = taosMemoryMalloc(len);
2,743!
303
  if (NULL == row.buf) {
2,743!
304
    qError("taosMemoryMalloc %d failed", len);
×
305
    QRY_ERR_RET(terrno);
×
306
  }
307

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

313
  if (NULL == taosArrayPush(ctx->rows, &row)) {
5,486!
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;
2,743✔
320
}
321

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

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

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

343
  if ((isGroupByTbname && (pScan->groupSort || pScan->scan.groupOrderScan)) || (isGroupByTag && (pScan->groupSort || pScan->scan.groupOrderScan))) {
332!
344
    return "grp_order";
×
345
  }
346

347
  return "ts_order";
332✔
348
}
349

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

362
  return "unknown";
×
363
}
364

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

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

394
      if (verbose) {
×
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;
×
422
    }
423
    case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
×
424
      SVirtualScanPhysiNode *pVirtualTableScanNode = (SVirtualScanPhysiNode *)pNode;
×
425
      EXPLAIN_ROW_NEW(level, EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT, pVirtualTableScanNode->scan.tableName.tname);
×
426
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
×
427
      if (pResNode->pExecInfo) {
×
428
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
×
429
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
430
      }
431
      if (pVirtualTableScanNode->scan.pScanPseudoCols) {
×
432
        EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanPseudoCols->length);
×
433
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
×
434
      }
435
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
×
436
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
437
      EXPLAIN_ROW_END();
×
438
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
439

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

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

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

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

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

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

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

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

522
          if (pScanInfo->totalRows > totalRows) {
×
523
            totalRows = pScanInfo->totalRows;
×
524
            maxIndex = i;
×
525
          }
526
        }
527

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

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

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

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

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

544
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
×
545

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

894
        nodeNum += group->nodeNum;
440✔
895
      }
896

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

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

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

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

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

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

965
        EXPLAIN_ROW_END();
×
966
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
967

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1287
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
×
1288
      EXPLAIN_ROW_END();
×
1289
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
×
1290

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1949
  return TSDB_CODE_SUCCESS;
1,707✔
1950
}
1951

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

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

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

1964
  return TSDB_CODE_SUCCESS;
1,707✔
1965
}
1966

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

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

1978
  group->singleChannel = singleChannel;
807✔
1979
  group->physiPlanExecIdx = 0;
807✔
1980

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

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

1985
_return:
807✔
1986

1987
  qExplainFreeResNode(node);
807✔
1988

1989
  QRY_RET(code);
807!
1990
}
1991

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

2002
  code = createDataBlock(&pBlock);
367✔
2003
  QRY_ERR_JRET(code);
367!
2004

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

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

2011
  for (int32_t i = 0; i < rowNum; ++i) {
3,110✔
2012
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
2,743✔
2013
    QRY_ERR_JRET(colDataSetVal(pInfoData, i, row->buf, false));
2,743!
2014
  }
2015

2016
  pBlock->info.rows = rowNum;
367✔
2017

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

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

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

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

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

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

2042
_return:
367✔
2043
  blockDataDestroy(pBlock);
367✔
2044

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

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

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

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

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

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

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

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

2090
    SSubplan *plan = NULL;
733✔
2091
    for (int32_t n = 0; n < taskNum; ++n) {
1,864✔
2092
      plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
1,131✔
2093
      pGroup = taosHashGet(groupHash, &plan->id.groupId, sizeof(plan->id.groupId));
1,131✔
2094
      if (pGroup) {
1,131✔
2095
        ++pGroup->nodeNum;
381✔
2096
        continue;
381✔
2097
      }
2098

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

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

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

2115
      ctx->rootGroupId = plan->id.groupId;
367✔
2116
    }
2117

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

2121
  *pCtx = ctx;
367✔
2122

2123
  return TSDB_CODE_SUCCESS;
367✔
2124

2125
_return:
×
2126

2127
  qExplainFreeCtx(ctx);
×
2128

2129
  QRY_RET(code);
×
2130
}
2131

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

2137
  int32_t tlen = 0;
×
2138
  char   *tbuf = pCtx->tbuf;
×
2139

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

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

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

2152
  return TSDB_CODE_SUCCESS;
×
2153
}
2154

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

2160
  return TSDB_CODE_SUCCESS;
367✔
2161
}
2162

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

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

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

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

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

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

2207
  groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
×
2208

2209
  taosWUnLockLatch(&group->lock);
×
2210

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

2220
  return TSDB_CODE_SUCCESS;
×
2221

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

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

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

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

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

2245
  (*pCtx)->reqStartTs = startTs;
×
2246
  (*pCtx)->jobStartTs = taosGetTimestampUs();
×
2247

2248
  return TSDB_CODE_SUCCESS;
×
2249
}
2250

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

2256
  atomic_store_8((int8_t *)&pCtx->execDone, true);
×
2257

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

2265
  return TSDB_CODE_SUCCESS;
×
2266
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc