explain.c 38.0 KB
Newer Older
D
dapan1121 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "query.h"
D
dapan1121 已提交
17
#include "plannodes.h"
D
dapan1121 已提交
18
#include "commandInt.h"
D
dapan1121 已提交
19

D
dapan1121 已提交
20
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
D
dapan1121 已提交
21
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level);
D
dapan1121 已提交
22 23


D
dapan1121 已提交
24 25
void qExplainFreeResNode(SExplainResNode *resNode) {
  if (NULL == resNode) {
D
dapan1121 已提交
26 27 28
    return;
  }

D
dapan1121 已提交
29
  taosMemoryFreeClear(resNode->pExecInfo);
D
dapan1121 已提交
30 31

  SNode* node = NULL;
D
dapan1121 已提交
32 33
  FOREACH(node, resNode->pChildren) {
    qExplainFreeResNode((SExplainResNode *)node);
D
dapan1121 已提交
34
  }  
D
dapan1121 已提交
35
  nodesClearList(resNode->pChildren);
D
dapan1121 已提交
36
  
D
dapan1121 已提交
37
  taosMemoryFreeClear(resNode);
D
dapan1121 已提交
38 39
}

D
dapan1121 已提交
40 41
void qExplainFreeCtx(SExplainCtx *pCtx) {
  if (NULL == pCtx) {
D
dapan1121 已提交
42 43 44 45 46 47 48 49 50
    return;
  }

  int32_t rowSize = taosArrayGetSize(pCtx->rows);
  for (int32_t i = 0; i < rowSize; ++i) {
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
    taosMemoryFreeClear(row->buf);
  }

D
dapan1121 已提交
51 52 53 54
  if (EXPLAIN_MODE_ANALYZE == pCtx->mode && pCtx->groupHash) {
    void *pIter = taosHashIterate(pCtx->groupHash, NULL);
    while (pIter) {
      SExplainGroup *group = (SExplainGroup *)pIter;
D
dapan1121 已提交
55 56 57 58 59 60
      if (group->nodeExecInfo) {
        int32_t num = taosArrayGetSize(group->nodeExecInfo);
        for (int32_t i = 0; i < num; ++i) {
          SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
          taosMemoryFreeClear(rsp->subplanInfo);
        }
D
dapan1121 已提交
61 62 63 64 65 66
      }
      
      pIter = taosHashIterate(pCtx->groupHash, pIter);
    }
  }
  
D
dapan1121 已提交
67
  taosHashCleanup(pCtx->groupHash);
D
dapan1121 已提交
68 69
  taosArrayDestroy(pCtx->rows);
  taosMemoryFree(pCtx);
D
dapan1121 已提交
70 71
}

D
dapan1121 已提交
72
int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio, EExplainMode mode) {
D
dapan1121 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
  int32_t code = 0;
  SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
  if (NULL == ctx) {
    qError("calloc SExplainCtx failed");
    QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }
  
  SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo));
  if (NULL == rows) {
    qError("taosArrayInit SQueryExplainRowInfo failed");
    QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

  char *tbuf = taosMemoryMalloc(TSDB_EXPLAIN_RESULT_ROW_SIZE);
  if (NULL == tbuf) {
    qError("malloc size %d failed", TSDB_EXPLAIN_RESULT_ROW_SIZE);
    QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

D
dapan1121 已提交
92
  ctx->mode = mode;
D
dapan1121 已提交
93
  ctx->verbose = verbose;
D
dapan1121 已提交
94
  ctx->ratio = ratio;
D
dapan1121 已提交
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
  ctx->tbuf = tbuf;
  ctx->rows = rows;
  ctx->groupHash = groupHash;
  
  *pCtx = ctx;

  return TSDB_CODE_SUCCESS;

_return:

  taosArrayDestroy(rows);
  taosHashCleanup(groupHash);
  taosMemoryFree(ctx);

  QRY_RET(code);
}

D
dapan1121 已提交
112
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
D
dapan1121 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
  int32_t tlen = 0;
  SNodeList *pPhysiChildren = NULL;
  
  switch (pNode->type) {
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
      STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
      pPhysiChildren = pTagScanNode->node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
      STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
      pPhysiChildren = pTblScanNode->scan.node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
      SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
      pPhysiChildren = pSTblScanNode->scan.node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
      SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
      pPhysiChildren = pPrjNode->node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
      SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
      pPhysiChildren = pJoinNode->node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_AGG:{
      SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
      pPhysiChildren = pAggNode->node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:{
      SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
      pPhysiChildren = pExchNode->node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SORT:{
      SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
      pPhysiChildren = pSortNode->node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
      SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
      pPhysiChildren = pIntNode->window.node.pChildren;
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
      SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
      pPhysiChildren = pSessNode->window.node.pChildren;
      break;
    }
    default:
      qError("not supported physical node type %d", pNode->type);
      QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
  }

  if (pPhysiChildren) {
    *pChildren = nodesMakeList();
    if (NULL == *pChildren) {
      qError("nodesMakeList failed");
      QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
    }
  }
D
dapan1121 已提交
180

D
dapan1121 已提交
181 182 183
  SNode* node = NULL;
  SExplainResNode *pResNode = NULL;
  FOREACH(node, pPhysiChildren) {
D
dapan1121 已提交
184
    QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
D
dapan1121 已提交
185 186 187 188
    QRY_ERR_RET(nodesListAppend(*pChildren, pResNode));
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
189 190
}

D
dapan1121 已提交
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
int32_t qExplainGenerateResNodeExecInfo(SArray **pExecInfo, SExplainGroup *group) {
  *pExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainExecInfo));
  if (NULL == (*pExecInfo)) {
    qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

  SExplainRsp *rsp = NULL;  
  for (int32_t i = 0; i < group->nodeNum; ++i) {
    rsp = taosArrayGet(group->nodeExecInfo, i);
    if (group->physiPlanExecIdx >= rsp->numOfPlans) {
      qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
      return TSDB_CODE_QRY_APP_ERROR;
    }
    
    taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx);
  }

  ++group->physiPlanExecIdx;

  return TSDB_CODE_SUCCESS;
}

int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pResNode) {
D
dapan1121 已提交
215
  if (NULL == pNode) {
D
dapan1121 已提交
216
    *pResNode = NULL;
D
dapan1121 已提交
217 218 219
    qError("physical node is NULL");
    return TSDB_CODE_QRY_APP_ERROR;
  }
D
dapan1121 已提交
220
  
D
dapan1121 已提交
221 222
  SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
  if (NULL == resNode) {
D
dapan1121 已提交
223 224 225 226 227
    qError("calloc SPhysiNodeExplainRes failed");
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

  int32_t code = 0;
D
dapan1121 已提交
228
  resNode->pNode = pNode;
D
dapan1121 已提交
229 230 231 232
  
  if (group->nodeExecInfo) {
    QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(&resNode->pExecInfo, group));
  }
D
dapan1121 已提交
233 234 235 236
  
  QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren));

  ++group->physiPlanNum;
D
dapan1121 已提交
237
  
D
dapan1121 已提交
238
  *pResNode = resNode;
D
dapan1121 已提交
239 240 241 242 243

  return TSDB_CODE_SUCCESS;

_return:

D
dapan1121 已提交
244
  qExplainFreeResNode(resNode);
D
dapan1121 已提交
245 246 247 248
  
  QRY_RET(code);
}

D
dapan1121 已提交
249
int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
D
dapan1121 已提交
250
  int32_t tlen = *len;
D
dapan1121 已提交
251 252
  int32_t nodeNum = taosArrayGetSize(pExecInfo);
  SExplainExecInfo maxExecInfo = {0};
D
dapan1121 已提交
253
  
D
dapan1121 已提交
254 255 256 257 258 259 260 261 262 263 264 265
  for (int32_t i = 0; i < nodeNum; ++i) {
    SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
    if (execInfo->startupCost > maxExecInfo.startupCost) {
      maxExecInfo.startupCost = execInfo->startupCost;
    }
    if (execInfo->totalCost > maxExecInfo.totalCost) {
      maxExecInfo.totalCost = execInfo->totalCost;
    }
    if (execInfo->numOfRows > maxExecInfo.numOfRows) {
      maxExecInfo.numOfRows = execInfo->numOfRows;
    }
  }
D
dapan1121 已提交
266
  
D
dapan1121 已提交
267 268
  EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.numOfRows);

D
dapan1121 已提交
269 270 271
  *len = tlen;
  
  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
272 273
}

D
dapan1121 已提交
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
int32_t qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
  int32_t tlen = 0;
  bool gotVerbose = false;
  int32_t nodeNum = taosArrayGetSize(pExecInfo);
  SExplainExecInfo maxExecInfo = {0};
  
  for (int32_t i = 0; i < nodeNum; ++i) {
    SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
    if (execInfo->verboseInfo) {
      gotVerbose = true;
    }
  }

  if (gotVerbose) {
    EXPLAIN_ROW_APPEND("exec verbose info");
  }

  *len = tlen;
  
  return TSDB_CODE_SUCCESS;
}


D
dapan1121 已提交
297
int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
D
dapan1121 已提交
298
  SQueryExplainRowInfo row = {0};
D
dapan1121 已提交
299
  row.buf = taosMemoryMalloc(len);
D
dapan1121 已提交
300
  if (NULL == row.buf) {
D
dapan1121 已提交
301
    qError("taosMemoryMalloc %d failed", len);
D
dapan1121 已提交
302 303 304
    QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

D
dapan1121 已提交
305
  memcpy(row.buf, tbuf, len);
D
dapan1121 已提交
306 307
  row.level = level;
  row.len = len;
D
dapan1121 已提交
308
  ctx->dataSize += len;
D
dapan1121 已提交
309

D
dapan1121 已提交
310
  if (NULL == taosArrayPush(ctx->rows, &row)) {
D
dapan1121 已提交
311 312 313 314 315 316 317 318
    qError("taosArrayPush row to explain res rows failed");
    taosMemoryFree(row.buf);
    QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
319 320 321
static uint8_t getIntervalPrecision(SIntervalPhysiNode* pIntNode) {
  return ((SColumnNode*)pIntNode->window.pTspk)->node.resType.precision;
}
D
dapan1121 已提交
322

D
dapan1121 已提交
323
int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
D
dapan1121 已提交
324
  int32_t tlen = 0;
D
dapan1121 已提交
325 326 327
  bool isVerboseLine = false;
  char *tbuf = ctx->tbuf;
  bool verbose = ctx->verbose;
D
dapan1121 已提交
328 329 330 331 332 333 334 335 336
  SPhysiNode* pNode = pResNode->pNode;
  if (NULL == pNode) {
    qError("pyhsical node in explain res node is NULL");
    return TSDB_CODE_QRY_APP_ERROR;
  }
  
  switch (pNode->type) {
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
      STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
D
dapan1121 已提交
337 338
      EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->tableName.tname);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
339
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
340
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
341 342 343 344 345 346
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTagScanNode->pScanCols->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
347
      EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pTagScanNode->count);
D
dapan1121 已提交
348
      if (pTagScanNode->reverse) {
D
dapan1121 已提交
349
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
350
        EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTagScanNode->reverse);
D
dapan1121 已提交
351
      }
D
dapan1121 已提交
352
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
353 354
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
355 356

      if (verbose) {
D
dapan1121 已提交
357 358 359 360 361 362 363
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        
D
dapan1121 已提交
364 365 366
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pTagScanNode->order));
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
D
dapan1121 已提交
367 368 369 370 371 372 373 374

        if (pResNode->pExecInfo) {
          QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
          if (tlen) {
            EXPLAIN_ROW_END();
            QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
          }
        }      
D
dapan1121 已提交
375
      }
D
dapan1121 已提交
376
      break;
D
dapan1121 已提交
377 378
    }
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
D
dapan1121 已提交
379 380
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
      STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
D
dapan1121 已提交
381 382
      EXPLAIN_ROW_NEW(level, EXPLAIN_TBL_SCAN_FORMAT, pTblScanNode->scan.tableName.tname);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
383
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
384
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
385 386 387 388 389 390
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
391
      EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pTblScanNode->scan.count);
D
dapan1121 已提交
392
      if (pTblScanNode->scan.reverse) {
D
dapan1121 已提交
393
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
394
        EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTblScanNode->scan.reverse);
D
dapan1121 已提交
395
      }
D
dapan1121 已提交
396
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);      
D
dapan1121 已提交
397 398
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
399

D
dapan1121 已提交
400
      if (verbose) {      
D
dapan1121 已提交
401 402 403 404 405 406 407
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

D
dapan1121 已提交
408
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pTblScanNode->scan.order));
D
dapan1121 已提交
409 410
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
D
dapan1121 已提交
411 412 413 414 415 416 417
        
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey, pTblScanNode->scanRange.ekey);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

        if (pTblScanNode->scan.node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
D
dapan1121 已提交
418
          QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
419 420 421
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
422 423 424 425 426
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
      SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
D
dapan1121 已提交
427 428
      EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
429
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
430
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
431 432 433 434 435 436
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
437
      EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pSTblScanNode->scan.count);
D
dapan1121 已提交
438
      if (pSTblScanNode->scan.reverse) {
D
dapan1121 已提交
439
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
440
        EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pSTblScanNode->scan.reverse);
D
dapan1121 已提交
441
      }
D
dapan1121 已提交
442
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);      
D
dapan1121 已提交
443 444
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
445 446

      if (verbose) {            
D
dapan1121 已提交
447 448 449 450 451 452 453
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

D
dapan1121 已提交
454 455
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSTblScanNode->scan.order));
        EXPLAIN_ROW_END();
D
dapan1121 已提交
456 457 458 459 460 461 462 463 464
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));   

        if (pSTblScanNode->scan.node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
          QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
        
D
dapan1121 已提交
465
      }
D
dapan1121 已提交
466 467 468 469
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
      SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
D
dapan1121 已提交
470 471
      EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
472
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
473
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
474 475 476 477 478 479
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);      
D
dapan1121 已提交
480 481
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
482

D
dapan1121 已提交
483
      if (verbose) {
D
dapan1121 已提交
484 485 486 487 488 489 490
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
      
D
dapan1121 已提交
491 492
        if (pPrjNode->node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
493
          QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
494 495 496
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
497 498 499 500 501
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
      SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
D
dapan1121 已提交
502 503
      EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, EXPLAIN_JOIN_STRING(pJoinNode->joinType));
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
504
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
505
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
506 507 508 509 510 511
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);      
D
dapan1121 已提交
512 513
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
514

D
dapan1121 已提交
515
      if (verbose) {
D
dapan1121 已提交
516 517 518 519 520 521 522
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

D
dapan1121 已提交
523 524
        if (pJoinNode->node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
525
          QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
526 527 528 529 530
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
        
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);      
D
dapan1121 已提交
531
        QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pOnConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
532 533
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
D
dapan1121 已提交
534 535 536 537 538
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_AGG:{
      SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
D
dapan1121 已提交
539 540
      EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
541
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
542
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
543 544 545 546 547 548 549 550
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
      if (pAggNode->pGroupKeys) {
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
D
dapan1121 已提交
551
      }
D
dapan1121 已提交
552
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);      
D
dapan1121 已提交
553 554
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
555

D
dapan1121 已提交
556
      if (verbose) {
D
dapan1121 已提交
557 558 559 560 561 562 563
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

D
dapan1121 已提交
564 565
        if (pAggNode->node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
566
          QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
567 568 569
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
570 571 572 573 574
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:{
      SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
D
dapan1121 已提交
575 576 577 578 579 580
      SExplainGroup *group = taosHashGet(ctx->groupHash, &pExchNode->srcGroupId, sizeof(pExchNode->srcGroupId));
      if (NULL == group) {
        qError("exchange src group %d not in groupHash", pExchNode->srcGroupId);
        QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
      }
      
D
dapan1121 已提交
581 582
      EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, group->nodeNum);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
583
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
584
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
585
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
D
dapan1121 已提交
586 587 588
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);      
D
dapan1121 已提交
589 590
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
591

D
dapan1121 已提交
592
      if (verbose) {
D
dapan1121 已提交
593 594 595 596 597 598 599
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

D
dapan1121 已提交
600 601
        if (pExchNode->node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
602
          QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
603 604 605
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
606
      }
D
dapan1121 已提交
607

D
dapan1121 已提交
608
      QRY_ERR_RET(qExplainAppendGroupResRows(ctx, pExchNode->srcGroupId, level + 1));
D
dapan1121 已提交
609 610 611 612
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SORT:{
      SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
D
dapan1121 已提交
613 614
      EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
615
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
616
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
617 618 619 620 621 622
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSortNode->pSortKeys->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
623 624
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
625

D
dapan1121 已提交
626
      if (verbose) {
D
dapan1121 已提交
627 628 629 630 631 632 633
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

D
dapan1121 已提交
634 635
        if (pSortNode->node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
636
          QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
637 638 639
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
640 641 642 643 644
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
      SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
645
      EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
D
dapan1121 已提交
646
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
647
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
648
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
649 650 651 652 653
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
D
dapan1121 已提交
654 655
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
656

D
dapan1121 已提交
657
      if (verbose) {
D
dapan1121 已提交
658 659 660 661 662 663
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
X
Xiaoyu Wang 已提交
664 665 666 667
        uint8_t precision = getIntervalPrecision(pIntNode);
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),  
              pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision), 
              INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision), pIntNode->slidingUnit);
D
dapan1121 已提交
668 669 670
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        
D
dapan1121 已提交
671
        if (pIntNode->pFill) {
D
dapan1121 已提交
672
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_FORMAT, getFillModeString(pIntNode->pFill->mode));      
D
dapan1121 已提交
673 674 675 676 677 678
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }

        if (pIntNode->window.node.pConditions) {
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
679
          QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
680 681 682
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
683 684 685 686
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
D
dapan1121 已提交
687 688 689
      SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
      EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
690
      if (pResNode->pExecInfo) {
D
dapan1121 已提交
691
        QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
D
dapan1121 已提交
692 693 694 695 696 697
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      }      
      EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length);
      EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
      EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
      EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
D
dapan1121 已提交
698 699
      EXPLAIN_ROW_END();
      QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
D
dapan1121 已提交
700

D
dapan1121 已提交
701

D
dapan1121 已提交
702
      if (verbose) {
D
dapan1121 已提交
703 704 705 706 707 708 709 710 711 712 713 714
        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
        EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
        EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

        EXPLAIN_ROW_NEW(level + 1, EXPLAIN_WINDOW_FORMAT, pSessNode->gap);
        EXPLAIN_ROW_END();
        QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));

        if (pSessNode->window.node.pConditions) {
D
dapan1121 已提交
715
          EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);      
D
dapan1121 已提交
716
          QRY_ERR_RET(nodesNodeToSQL(pSessNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); 
D
dapan1121 已提交
717 718 719
          EXPLAIN_ROW_END();
          QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
        }
D
dapan1121 已提交
720 721 722
      }
      break;
    }
D
dapan1121 已提交
723 724 725 726 727 728 729 730 731
    default:
      qError("not supported physical node type %d", pNode->type);
      return TSDB_CODE_QRY_APP_ERROR;
  }

  return TSDB_CODE_SUCCESS;
}


D
dapan1121 已提交
732
int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
D
dapan1121 已提交
733 734 735 736 737 738
  if (NULL == pResNode) {
    qError("explain res node is NULL");
    QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
  }

  int32_t code = 0;
D
dapan1121 已提交
739
  QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
D
dapan1121 已提交
740 741 742

  SNode* pNode = NULL;
  FOREACH(pNode, pResNode->pChildren) {
D
dapan1121 已提交
743
    QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1));
D
dapan1121 已提交
744 745 746 747 748
  }

  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
749
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level) {
D
dapan1121 已提交
750 751
  SExplainResNode *node = NULL;
  int32_t code = 0;
D
dapan1121 已提交
752
  SExplainCtx *ctx = (SExplainCtx *)pCtx;
D
dapan1121 已提交
753

D
dapan1121 已提交
754 755 756 757
  SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
  if (NULL == group) {
    qError("group %d not in groupHash", groupId);
    QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
D
dapan1121 已提交
758
  }
D
dapan1121 已提交
759
  
D
dapan1121 已提交
760 761
  QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));

D
dapan1121 已提交
762
  if ((EXPLAIN_MODE_ANALYZE == ctx->mode) && (group->physiPlanNum != group->physiPlanExecNum)) {
D
dapan1121 已提交
763 764 765
    qError("physiPlanNum %d mismatch with physiExecNum %d in group %d", group->physiPlanNum, group->physiPlanExecNum, groupId);
    QRY_ERR_JRET(TSDB_CODE_QRY_APP_ERROR);
  }
D
dapan1121 已提交
766

D
dapan1121 已提交
767
  QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
D
dapan1121 已提交
768 769 770

_return:

D
dapan1121 已提交
771
  qExplainFreeResNode(node);
D
dapan1121 已提交
772
  
D
dapan1121 已提交
773 774 775 776
  QRY_RET(code);
}


D
dapan1121 已提交
777
int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
D
dapan1121 已提交
778
  SExplainCtx *pCtx = (SExplainCtx *)ctx;
D
dapan1121 已提交
779 780 781 782 783 784 785
  int32_t rowNum = taosArrayGetSize(pCtx->rows);
  if (rowNum <= 0) {
    qError("empty explain res rows");
    QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
  }
  
  int32_t colNum = 1;
D
dapan1121 已提交
786
  int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
D
dapan1121 已提交
787 788 789 790 791 792 793
  SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
  if (NULL == rsp) {
    qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
    QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

  rsp->completed = 1;
D
dapan1121 已提交
794
  rsp->numOfRows = htonl(rowNum);
D
dapan1121 已提交
795

D
dapan1121 已提交
796
  *(int32_t *)rsp->data = htonl(pCtx->dataSize);
D
dapan1121 已提交
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812

  int32_t *offset = (int32_t *)((char *)rsp->data + sizeof(int32_t));
  char *data = (char *)(offset + rowNum);
  int32_t tOffset = 0;
  
  for (int32_t i = 0; i < rowNum; ++i) {
    SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
    *offset = tOffset;
    tOffset += row->len;

    memcpy(data, row->buf, row->len);
    
    ++offset;
    data += row->len;
  }

D
dapan1121 已提交
813 814
  *pRsp = rsp;

D
dapan1121 已提交
815 816 817
  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
818 819

int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
D
dapan1121 已提交
820 821 822 823
  int32_t code = 0;
  SNodeListNode *plans = NULL;
  int32_t        taskNum = 0;
  SExplainGroup *pGroup = NULL;
D
dapan1121 已提交
824
  SExplainCtx *ctx = NULL;
D
dapan1121 已提交
825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842

  if (pDag->numOfSubplans <= 0) {
    qError("invalid subplan num:%d", pDag->numOfSubplans);
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
  if (levelNum <= 0) {
    qError("invalid level num:%d", levelNum);
    QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

  SHashObj *groupHash = taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
  if (NULL == groupHash) {
    qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
    QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

D
dapan1121 已提交
843
  QRY_ERR_JRET(qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
D
dapan1121 已提交
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866

  for (int32_t i = 0; i < levelNum; ++i) {
    plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
    if (NULL == plans) {
      qError("empty level plan, level:%d", i);
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
    }

    taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
    if (taskNum <= 0) {
      qError("invalid level plan number:%d, level:%d", taskNum, i);
      QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
    }

    SSubplan *plan = NULL;
    for (int32_t n = 0; n < taskNum; ++n) {
      plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
      pGroup = taosHashGet(groupHash, &plan->id.groupId, sizeof(plan->id.groupId));
      if (pGroup) {
        ++pGroup->nodeNum;
        continue;
      }

D
dapan1121 已提交
867 868 869 870
      SExplainGroup group = {0};
      group.nodeNum = 1;
      group.plan = plan;
      
D
dapan1121 已提交
871 872 873 874 875 876 877 878 879 880 881 882
      if (0 != taosHashPut(groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
        qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
        QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
      }
    }

    if (0 == i) {
      if (taskNum > 1) {
        qError("invalid taskNum %d for level 0", taskNum);
        QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
      }

D
dapan1121 已提交
883
      ctx->rootGroupId = plan->id.groupId;
D
dapan1121 已提交
884 885 886 887 888
    }

    qDebug("level %d group handled, taskNum:%d", i, taskNum);
  }

D
dapan1121 已提交
889 890 891 892 893 894 895 896 897 898 899
  *pCtx = ctx;

  return TSDB_CODE_SUCCESS;
  
_return:

  qExplainFreeCtx(ctx);

  QRY_RET(code);
}

D
dapan1121 已提交
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
  if (EXPLAIN_MODE_ANALYZE != pCtx->mode) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t tlen = 0;
  char *tbuf = pCtx->tbuf;

  EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
  EXPLAIN_SUM_ROW_END();
  QRY_ERR_RET(qExplainResAppendRow(pCtx, tbuf, tlen, 0));

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

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

  return TSDB_CODE_SUCCESS;
}
D
dapan1121 已提交
922

D
dapan1121 已提交
923 924
int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
  QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->rootGroupId, 0));
D
dapan1121 已提交
925 926

  QRY_ERR_RET(qExplainAppendPlanRows(pCtx));
D
dapan1121 已提交
927 928 929 930 931 932
  
  QRY_ERR_RET(qExplainGetRspFromCtx(pCtx, pRsp));

  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
933
int32_t qExplainUpdateExecInfo(SExplainCtx        *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
D
dapan1121 已提交
934 935 936 937
  SExplainResNode *node = NULL;
  int32_t code = 0;
  bool groupDone = false;
  SExplainCtx *ctx = (SExplainCtx *)pCtx;
D
dapan1121 已提交
938

D
dapan1121 已提交
939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
  SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
  if (NULL == group) {
    qError("group %d not in groupHash", groupId);
    taosMemoryFreeClear(pRspMsg->subplanInfo);
    QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
  }

  taosWLockLatch(&group->lock);
  if (NULL == group->nodeExecInfo) {
    group->nodeExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainRsp));
    if (NULL == group->nodeExecInfo) {
      qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
      taosMemoryFreeClear(pRspMsg->subplanInfo);
      taosWUnLockLatch(&group->lock);
      
      QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
    }

    group->physiPlanExecNum = pRspMsg->numOfPlans;
  } else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
    qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo), group->nodeNum);
    taosMemoryFreeClear(pRspMsg->subplanInfo);
    taosWUnLockLatch(&group->lock);
    
    QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
  }

  if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
    qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum, groupId);
    taosMemoryFreeClear(pRspMsg->subplanInfo);
    taosWUnLockLatch(&group->lock);
    
    QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
  }

  taosArrayPush(group->nodeExecInfo, pRspMsg);
  groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
  
  taosWUnLockLatch(&group->lock);

  if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
    if (atomic_load_8((int8_t *)&pCtx->execDone)) {
      if (0 == taosWTryLockLatch(&pCtx->lock)) {
        QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
        // LEAVE LOCK THERE
      }
    }
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
989 990 991 992 993 994 995 996
}


int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
  int32_t code = 0;
  SExplainCtx *pCtx = NULL;

  QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
D
dapan1121 已提交
997
  
D
dapan1121 已提交
998
  QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
D
dapan1121 已提交
999 1000 1001
  
_return:

D
dapan1121 已提交
1002
  qExplainFreeCtx(pCtx);
D
dapan1121 已提交
1003 1004 1005 1006

  QRY_RET(code);
}

D
dapan1121 已提交
1007
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
D
dapan1121 已提交
1008 1009 1010
  QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx));
  
  (*pCtx)->reqStartTs = startTs;
D
dapan1121 已提交
1011
  (*pCtx)->jobStartTs = taosGetTimestampUs();
D
dapan1121 已提交
1012 1013 1014 1015

  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
1016 1017
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
  int32_t code = 0;
D
dapan1121 已提交
1018
  pCtx->jobDoneTs = taosGetTimestampUs();
D
dapan1121 已提交
1019 1020 1021
  
  atomic_store_8((int8_t *)&pCtx->execDone, true);

D
dapan1121 已提交
1022 1023 1024 1025 1026 1027 1028
  if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) {
    if (0 == taosWTryLockLatch(&pCtx->lock)) {
      QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
      // LEAVE LOCK THERE
    }
  }

D
dapan1121 已提交
1029 1030 1031
  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
1032 1033