planLogicCreater.c 30.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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/>.
 */

X
Xiaoyu Wang 已提交
16
#include "planInt.h"
17

X
Xiaoyu Wang 已提交
18 19 20
#include "functionMgt.h"

typedef struct SLogicPlanContext {
21
  SPlanContext* pPlanCxt;
X
Xiaoyu Wang 已提交
22 23
} SLogicPlanContext;

X
Xiaoyu Wang 已提交
24
typedef int32_t (*FCreateLogicNode)(SLogicPlanContext*, SSelectStmt*, SLogicNode**);
X
Xiaoyu Wang 已提交
25
typedef int32_t (*FCreateSetOpLogicNode)(SLogicPlanContext*, SSetOperator*, SLogicNode**);
X
Xiaoyu Wang 已提交
26

X
Xiaoyu Wang 已提交
27 28
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                        SLogicNode** pLogicNode);
29
static int32_t createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt, SLogicNode** pLogicNode);
X
Xiaoyu Wang 已提交
30 31

typedef struct SRewriteExprCxt {
X
Xiaoyu Wang 已提交
32
  int32_t    errCode;
X
Xiaoyu Wang 已提交
33 34 35 36 37 38 39 40 41
  SNodeList* pExprs;
} SRewriteExprCxt;

static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
  switch (nodeType(*pNode)) {
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
      SRewriteExprCxt* pCxt = (SRewriteExprCxt*)pContext;
X
Xiaoyu Wang 已提交
42 43
      SNode*           pExpr;
      int32_t          index = 0;
X
Xiaoyu Wang 已提交
44 45 46 47 48 49
      FOREACH(pExpr, pCxt->pExprs) {
        if (QUERY_NODE_GROUPING_SET == nodeType(pExpr)) {
          pExpr = nodesListGetNode(((SGroupingSetNode*)pExpr)->pParameterList, 0);
        }
        if (nodesEqualNode(pExpr, *pNode)) {
          SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
X
Xiaoyu Wang 已提交
50 51 52
          if (NULL == pCol) {
            return DEAL_RES_ERROR;
          }
X
Xiaoyu Wang 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66
          SExprNode* pToBeRewrittenExpr = (SExprNode*)(*pNode);
          pCol->node.resType = pToBeRewrittenExpr->resType;
          strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
          strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName);
          nodesDestroyNode(*pNode);
          *pNode = (SNode*)pCol;
          return DEAL_RES_IGNORE_CHILD;
        }
        ++index;
      }
      break;
    }
    default:
      break;
H
Haojun Liao 已提交
67 68
  }

X
Xiaoyu Wang 已提交
69
  return DEAL_RES_CONTINUE;
X
Xiaoyu Wang 已提交
70 71
}

X
Xiaoyu Wang 已提交
72 73 74 75 76
static EDealRes doNameExpr(SNode* pNode, void* pContext) {
  switch (nodeType(pNode)) {
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
77 78 79
      if ('\0' == ((SExprNode*)pNode)->aliasName[0]) {
        sprintf(((SExprNode*)pNode)->aliasName, "#expr_%p", pNode);
      }
X
Xiaoyu Wang 已提交
80
      return DEAL_RES_IGNORE_CHILD;
X
Xiaoyu Wang 已提交
81 82
    }
    default:
X
Xiaoyu Wang 已提交
83
      break;
X
Xiaoyu Wang 已提交
84
  }
85

X
Xiaoyu Wang 已提交
86
  return DEAL_RES_CONTINUE;
87 88
}

X
Xiaoyu Wang 已提交
89
static int32_t rewriteExprForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
X
Xiaoyu Wang 已提交
90
  nodesWalkExprs(pExprs, doNameExpr, NULL);
X
Xiaoyu Wang 已提交
91
  SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
X
Xiaoyu Wang 已提交
92 93
  nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
  return cxt.errCode;
94 95
}

X
Xiaoyu Wang 已提交
96
static int32_t rewriteExprs(SNodeList* pExprs, SNodeList* pTarget) {
X
Xiaoyu Wang 已提交
97
  SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
X
Xiaoyu Wang 已提交
98 99 100 101
  nodesRewriteExprs(pTarget, doRewriteExpr, &cxt);
  return cxt.errCode;
}

102 103 104 105 106
static int32_t pushLogicNode(SLogicPlanContext* pCxt, SLogicNode** pOldRoot, SLogicNode* pNewRoot) {
  if (NULL == pNewRoot->pChildren) {
    pNewRoot->pChildren = nodesMakeList();
    if (NULL == pNewRoot->pChildren) {
      return TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
107
    }
108
  }
109 110
  if (TSDB_CODE_SUCCESS != nodesListAppend(pNewRoot->pChildren, (SNode*)*pOldRoot)) {
    return TSDB_CODE_OUT_OF_MEMORY;
111 112
  }

113 114
  (*pOldRoot)->pParent = pNewRoot;
  *pOldRoot = pNewRoot;
115

116 117
  return TSDB_CODE_SUCCESS;
}
118

X
Xiaoyu Wang 已提交
119 120
static int32_t createChildLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, FCreateLogicNode func,
                                    SLogicNode** pRoot) {
X
Xiaoyu Wang 已提交
121
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
122
  int32_t     code = func(pCxt, pSelect, &pNode);
X
Xiaoyu Wang 已提交
123
  if (TSDB_CODE_SUCCESS == code && NULL != pNode) {
X
Xiaoyu Wang 已提交
124
    code = pushLogicNode(pCxt, pRoot, pNode);
125
  }
X
Xiaoyu Wang 已提交
126 127
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyNode(pNode);
X
Xiaoyu Wang 已提交
128
  }
X
Xiaoyu Wang 已提交
129
  return code;
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 180 181 182 183 184
typedef struct SCreateColumnCxt {
  int32_t    errCode;
  SNodeList* pList;
} SCreateColumnCxt;

static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
  SCreateColumnCxt* pCxt = (SCreateColumnCxt*)pContext;
  switch (nodeType(pNode)) {
    case QUERY_NODE_COLUMN: {
      SNode* pCol = nodesCloneNode(pNode);
      if (NULL == pCol) {
        return DEAL_RES_ERROR;
      }
      return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
    }
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
      SExprNode*   pExpr = (SExprNode*)pNode;
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
      if (NULL == pCol) {
        return DEAL_RES_ERROR;
      }
      pCol->node.resType = pExpr->resType;
      strcpy(pCol->colName, pExpr->aliasName);
      return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
    }
    default:
      break;
  }

  return DEAL_RES_CONTINUE;
}

static int32_t createColumnByRewriteExps(SLogicPlanContext* pCxt, SNodeList* pExprs, SNodeList** pList) {
  SCreateColumnCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pList = (NULL == *pList ? nodesMakeList() : *pList)};
  if (NULL == cxt.pList) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  nodesWalkExprs(pExprs, doCreateColumn, &cxt);
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyList(cxt.pList);
    return cxt.errCode;
  }
  if (NULL == *pList) {
    *pList = cxt.pList;
  }
  return cxt.errCode;
}

static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanPseudoCols, SNodeList* pScanCols,
                             STableMeta* pMeta) {
X
Xiaoyu Wang 已提交
185 186 187 188
  if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) {
    return SCAN_TYPE_STREAM;
  }

X
Xiaoyu Wang 已提交
189 190
  if (NULL == pScanCols) {
    // select count(*) from t
191
    return NULL == pScanPseudoCols ? SCAN_TYPE_TABLE : SCAN_TYPE_TAG;
X
Xiaoyu Wang 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
  }

  if (TSDB_SYSTEM_TABLE == pMeta->tableType) {
    return SCAN_TYPE_SYSTEM_TABLE;
  }

  SNode* pCol = NULL;
  FOREACH(pCol, pScanCols) {
    if (COLUMN_TYPE_COLUMN == ((SColumnNode*)pCol)->colType) {
      return SCAN_TYPE_TABLE;
    }
  }

  return SCAN_TYPE_TAG;
}

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
static SNodeptr createPrimaryKeyCol(uint64_t tableId) {
  SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pCol) {
    return NULL;
  }
  pCol->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
  pCol->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
  pCol->tableId = tableId;
  pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
  pCol->colType = COLUMN_TYPE_COLUMN;
  strcpy(pCol->colName, "#primarykey");
  return pCol;
}

static int32_t addPrimaryKeyCol(uint64_t tableId, SNodeList** pCols) {
  if (NULL == *pCols) {
    *pCols = nodesMakeList();
    if (NULL == *pCols) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }

X
Xiaoyu Wang 已提交
230
  bool   found = false;
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
  SNode* pCol = NULL;
  FOREACH(pCol, *pCols) {
    if (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pCol)->colId) {
      found = true;
      break;
    }
  }

  if (!found) {
    if (TSDB_CODE_SUCCESS != nodesListStrictAppend(*pCols, createPrimaryKeyCol(tableId))) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
247 248
static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable,
                                   SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
249
  SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
X
Xiaoyu Wang 已提交
250
  if (NULL == pScan) {
251
    return TSDB_CODE_OUT_OF_MEMORY;
252 253
  }

wafwerar's avatar
wafwerar 已提交
254 255
  TSWAP(pScan->pMeta, pRealTable->pMeta);
  TSWAP(pScan->pVgroupList, pRealTable->pVgroupList);
X
Xiaoyu Wang 已提交
256 257
  pScan->scanSeq[0] = 1;
  pScan->scanSeq[1] = 0;
X
Xiaoyu Wang 已提交
258
  pScan->scanRange = TSWINDOW_INITIALIZER;
X
Xiaoyu Wang 已提交
259 260 261 262
  pScan->tableName.type = TSDB_TABLE_NAME_T;
  pScan->tableName.acctId = pCxt->pPlanCxt->acctId;
  strcpy(pScan->tableName.dbname, pRealTable->table.dbName);
  strcpy(pScan->tableName.tname, pRealTable->table.tableName);
D
dapan1121 已提交
263
  pScan->showRewrite = pCxt->pPlanCxt->showRewrite;
264
  pScan->ratio = pRealTable->ratio;
265
  pScan->dataRequired = FUNC_DATA_REQUIRED_DATA_LOAD;
266

X
Xiaoyu Wang 已提交
267
  // set columns to scan
268 269 270
  int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, COLLECT_COL_TYPE_COL,
                                     &pScan->pScanCols);

271
  if (TSDB_CODE_SUCCESS == code) {
272 273
    code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, COLLECT_COL_TYPE_TAG,
                               &pScan->pScanPseudoCols);
274 275 276
  }

  if (TSDB_CODE_SUCCESS == code) {
277
    code = nodesCollectFuncs(pSelect, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
278 279
  }

280
  pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->pMeta);
X
Xiaoyu Wang 已提交
281

282
  if (TSDB_CODE_SUCCESS == code) {
283
    code = addPrimaryKeyCol(pScan->pMeta->uid, &pScan->pScanCols);
284 285
  }

286 287 288 289 290 291 292
  // set output
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExps(pCxt, pScan->pScanCols, &pScan->node.pTargets);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExps(pCxt, pScan->pScanPseudoCols, &pScan->node.pTargets);
  }
293

X
Xiaoyu Wang 已提交
294 295 296 297 298
  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pScan;
  } else {
    nodesDestroyNode(pScan);
  }
299

X
Xiaoyu Wang 已提交
300
  return code;
X
Xiaoyu Wang 已提交
301
}
302

X
Xiaoyu Wang 已提交
303 304
static int32_t createSubqueryLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable,
                                       SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
305 306 307
  int32_t code = createQueryLogicNode(pCxt, pTable->pSubquery, pLogicNode);
  if (TSDB_CODE_SUCCESS == code) {
    SNode* pNode;
X
Xiaoyu Wang 已提交
308
    FOREACH(pNode, (*pLogicNode)->pTargets) { strcpy(((SColumnNode*)pNode)->tableAlias, pTable->table.tableAlias); }
309
  }
X
Xiaoyu Wang 已提交
310
  return code;
311 312
}

X
Xiaoyu Wang 已提交
313 314
static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable,
                                   SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
315
  SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
X
Xiaoyu Wang 已提交
316
  if (NULL == pJoin) {
317 318
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
319 320 321

  pJoin->joinType = pJoinTable->joinType;

322
  int32_t code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
323 324 325

  // set left and right node
  pJoin->node.pChildren = nodesMakeList();
X
Xiaoyu Wang 已提交
326
  if (NULL == pJoin->node.pChildren) {
327
    code = TSDB_CODE_OUT_OF_MEMORY;
328 329
  }

X
Xiaoyu Wang 已提交
330
  SLogicNode* pLeft = NULL;
331
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
332 333 334 335
    code = doCreateLogicNodeByTable(pCxt, pSelect, pJoinTable->pLeft, &pLeft);
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppend(pJoin->node.pChildren, (SNode*)pLeft);
    }
336
  }
337

X
Xiaoyu Wang 已提交
338
  SLogicNode* pRight = NULL;
339
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
340 341 342 343 344
    code = doCreateLogicNodeByTable(pCxt, pSelect, pJoinTable->pRight, &pRight);
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppend(pJoin->node.pChildren, (SNode*)pRight);
    }
  }
X
Xiaoyu Wang 已提交
345 346

  // set on conditions
X
Xiaoyu Wang 已提交
347
  if (TSDB_CODE_SUCCESS == code && NULL != pJoinTable->pOnCond) {
X
Xiaoyu Wang 已提交
348
    pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond);
X
Xiaoyu Wang 已提交
349 350 351
    if (NULL == pJoin->pOnConditions) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
352 353
  }

X
Xiaoyu Wang 已提交
354
  // set the output
X
Xiaoyu Wang 已提交
355 356
  if (TSDB_CODE_SUCCESS == code) {
    pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
D
dapan1121 已提交
357
    if (NULL == pJoin->node.pTargets) {
X
Xiaoyu Wang 已提交
358 359 360 361 362 363 364 365 366
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppendList(pJoin->node.pTargets, nodesCloneList(pRight->pTargets));
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pJoin;
367
  } else {
X
Xiaoyu Wang 已提交
368
    nodesDestroyNode(pJoin);
369 370
  }

371
  return code;
X
Xiaoyu Wang 已提交
372
}
373

X
Xiaoyu Wang 已提交
374 375
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                        SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
376 377
  switch (nodeType(pTable)) {
    case QUERY_NODE_REAL_TABLE:
X
Xiaoyu Wang 已提交
378
      return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
379
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
380
      return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
381
    case QUERY_NODE_JOIN_TABLE:
X
Xiaoyu Wang 已提交
382
      return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
383 384
    default:
      break;
385
  }
X
Xiaoyu Wang 已提交
386 387 388
  return TSDB_CODE_FAILED;
}

X
Xiaoyu Wang 已提交
389 390
static int32_t createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                      SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
391
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
392
  int32_t     code = doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode);
X
Xiaoyu Wang 已提交
393 394 395 396 397 398 399 400 401 402 403
  if (TSDB_CODE_SUCCESS == code) {
    pNode->pConditions = nodesCloneNode(pSelect->pWhere);
    if (NULL != pSelect->pWhere && NULL == pNode->pConditions) {
      nodesDestroyNode(pNode);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
    *pLogicNode = pNode;
  }
  return code;
}

X
Xiaoyu Wang 已提交
404
static SColumnNode* createColumnByExpr(const char* pStmtName, SExprNode* pExpr) {
X
Xiaoyu Wang 已提交
405 406 407 408 409 410
  SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pCol) {
    return NULL;
  }
  pCol->node.resType = pExpr->resType;
  strcpy(pCol->colName, pExpr->aliasName);
X
Xiaoyu Wang 已提交
411 412 413
  if (NULL != pStmtName) {
    strcpy(pCol->tableAlias, pStmtName);
  }
X
Xiaoyu Wang 已提交
414
  return pCol;
415 416
}

417
static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
418
  if (!pSelect->hasAggFuncs && NULL == pSelect->pGroupByList) {
419
    return TSDB_CODE_SUCCESS;
420 421
  }

X
Xiaoyu Wang 已提交
422
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
423 424 425
  if (NULL == pAgg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
426

X
Xiaoyu Wang 已提交
427 428
  int32_t code = TSDB_CODE_SUCCESS;

X
Xiaoyu Wang 已提交
429 430 431
  // set grouyp keys, agg funcs and having conditions
  if (NULL != pSelect->pGroupByList) {
    pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
432 433 434
    if (NULL == pAgg->pGroupKeys) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
435 436
  }

X
Xiaoyu Wang 已提交
437
  // rewrite the expression in subsequent clauses
438
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
439
    code = rewriteExprForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY);
440
  }
X
Xiaoyu Wang 已提交
441 442 443 444 445 446

  if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
    code = nodesCollectFuncs(pSelect, fmIsAggFunc, &pAgg->pAggFuncs);
  }

  // rewrite the expression in subsequent clauses
447
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
448
    code = rewriteExprForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
449
  }
450

451
  if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) {
X
Xiaoyu Wang 已提交
452
    pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving);
453 454 455
    if (NULL == pAgg->node.pConditions) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
X
Xiaoyu Wang 已提交
456
  }
457

X
Xiaoyu Wang 已提交
458
  // set the output
459 460 461 462 463 464 465 466 467 468 469 470 471 472
  if (TSDB_CODE_SUCCESS == code && NULL != pAgg->pGroupKeys) {
    code = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys, &pAgg->node.pTargets);
  }
  if (TSDB_CODE_SUCCESS == code && NULL != pAgg->pAggFuncs) {
    code = createColumnByRewriteExps(pCxt, pAgg->pAggFuncs, &pAgg->node.pTargets);
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
    nodesDestroyNode(pAgg);
  }

  return code;
X
Xiaoyu Wang 已提交
473
}
474

X
Xiaoyu Wang 已提交
475 476
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
                                             SLogicNode** pLogicNode) {
477
  int32_t code = nodesCollectFuncs(pSelect, fmIsWindowClauseFunc, &pWindow->pFuncs);
X
Xiaoyu Wang 已提交
478

X
Xiaoyu Wang 已提交
479 480 481 482 483
  if (pCxt->pPlanCxt->streamQuery) {
    pWindow->triggerType = pCxt->pPlanCxt->triggerType;
    pWindow->watermark = pCxt->pPlanCxt->watermark;
  }

X
Xiaoyu Wang 已提交
484
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
485
    code = rewriteExprForSelect(pWindow->pFuncs, pSelect, SQL_CLAUSE_WINDOW);
X
Xiaoyu Wang 已提交
486 487 488 489 490 491
  }

  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExps(pCxt, pWindow->pFuncs, &pWindow->node.pTargets);
  }

X
Xiaoyu Wang 已提交
492 493
  pSelect->hasAggFuncs = false;

X
Xiaoyu Wang 已提交
494 495 496 497 498 499 500 501 502
  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pWindow;
  } else {
    nodesDestroyNode(pWindow);
  }

  return code;
}

X
Xiaoyu Wang 已提交
503 504
static int32_t createWindowLogicNodeByState(SLogicPlanContext* pCxt, SStateWindowNode* pState, SSelectStmt* pSelect,
                                            SLogicNode** pLogicNode) {
505 506 507 508 509 510 511 512
  SWindowLogicNode* pWindow = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
  if (NULL == pWindow) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  pWindow->winType = WINDOW_TYPE_STATE;
  pWindow->pStateExpr = nodesCloneNode(pState->pExpr);

513 514 515 516 517 518
  pWindow->pTspk = nodesCloneNode(pState->pCol);
  if (NULL == pWindow->pTspk) {
    nodesDestroyNode(pWindow);
    return TSDB_CODE_OUT_OF_MEMORY;
  }

519 520 521
  return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
}

X
Xiaoyu Wang 已提交
522 523
static int32_t createWindowLogicNodeBySession(SLogicPlanContext* pCxt, SSessionWindowNode* pSession,
                                              SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
524 525 526 527 528 529 530 531
  SWindowLogicNode* pWindow = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
  if (NULL == pWindow) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  pWindow->winType = WINDOW_TYPE_SESSION;
  pWindow->sessionGap = ((SValueNode*)pSession->pGap)->datum.i;

532 533 534 535 536 537
  pWindow->pTspk = nodesCloneNode(pSession->pCol);
  if (NULL == pWindow->pTspk) {
    nodesDestroyNode(pWindow);
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
538 539 540
  return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
}

X
Xiaoyu Wang 已提交
541 542
static int32_t createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SIntervalWindowNode* pInterval,
                                               SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
543
  SWindowLogicNode* pWindow = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
544 545 546
  if (NULL == pWindow) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
547 548 549

  pWindow->winType = WINDOW_TYPE_INTERVAL;
  pWindow->interval = ((SValueNode*)pInterval->pInterval)->datum.i;
X
Xiaoyu Wang 已提交
550
  pWindow->intervalUnit = ((SValueNode*)pInterval->pInterval)->unit;
X
Xiaoyu Wang 已提交
551
  pWindow->offset = (NULL != pInterval->pOffset ? ((SValueNode*)pInterval->pOffset)->datum.i : 0);
552
  pWindow->sliding = (NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->datum.i : pWindow->interval);
X
Xiaoyu Wang 已提交
553 554
  pWindow->slidingUnit =
      (NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->unit : pWindow->intervalUnit);
555

X
bugfix  
Xiaoyu Wang 已提交
556 557 558 559 560 561
  pWindow->pTspk = nodesCloneNode(pInterval->pCol);
  if (NULL == pWindow->pTspk) {
    nodesDestroyNode(pWindow);
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
562 563
  if (NULL != pInterval->pFill) {
    pWindow->pFill = nodesCloneNode(pInterval->pFill);
564
    if (NULL == pWindow->pFill) {
X
Xiaoyu Wang 已提交
565 566
      nodesDestroyNode(pWindow);
      return TSDB_CODE_OUT_OF_MEMORY;
567
    }
X
Xiaoyu Wang 已提交
568 569
  }

X
Xiaoyu Wang 已提交
570
  return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
X
Xiaoyu Wang 已提交
571 572
}

573
static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
574
  if (NULL == pSelect->pWindow) {
575
    return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
576 577 578
  }

  switch (nodeType(pSelect->pWindow)) {
579 580
    case QUERY_NODE_STATE_WINDOW:
      return createWindowLogicNodeByState(pCxt, (SStateWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
X
Xiaoyu Wang 已提交
581 582
    case QUERY_NODE_SESSION_WINDOW:
      return createWindowLogicNodeBySession(pCxt, (SSessionWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
X
Xiaoyu Wang 已提交
583
    case QUERY_NODE_INTERVAL_WINDOW:
X
Xiaoyu Wang 已提交
584
      return createWindowLogicNodeByInterval(pCxt, (SIntervalWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
X
Xiaoyu Wang 已提交
585 586 587 588
    default:
      break;
  }

589
  return TSDB_CODE_FAILED;
X
Xiaoyu Wang 已提交
590 591
}

X
Xiaoyu Wang 已提交
592 593 594 595 596 597 598 599 600 601
static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (NULL == pSelect->pOrderByList) {
    return TSDB_CODE_SUCCESS;
  }

  SSortLogicNode* pSort = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SORT);
  if (NULL == pSort) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

602
  int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_ORDER_BY, NULL, COLLECT_COL_TYPE_ALL, &pSort->node.pTargets);
X
Xiaoyu Wang 已提交
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619

  if (TSDB_CODE_SUCCESS == code) {
    pSort->pSortKeys = nodesCloneList(pSelect->pOrderByList);
    if (NULL == pSort->pSortKeys) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pSort;
  } else {
    nodesDestroyNode(pSort);
  }

  return code;
}

X
Xiaoyu Wang 已提交
620 621
static int32_t createColumnByProjections(SLogicPlanContext* pCxt, const char* pStmtName, SNodeList* pExprs,
                                         SNodeList** pCols) {
X
Xiaoyu Wang 已提交
622
  SNodeList* pList = nodesMakeList();
X
Xiaoyu Wang 已提交
623
  if (NULL == pList) {
624 625 626
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
627
  SNode* pNode;
X
Xiaoyu Wang 已提交
628
  FOREACH(pNode, pExprs) {
X
Xiaoyu Wang 已提交
629
    if (TSDB_CODE_SUCCESS != nodesListAppend(pList, createColumnByExpr(pStmtName, (SExprNode*)pNode))) {
X
Xiaoyu Wang 已提交
630 631
      nodesDestroyList(pList);
      return TSDB_CODE_OUT_OF_MEMORY;
632 633
    }
  }
634

X
Xiaoyu Wang 已提交
635 636
  *pCols = pList;
  return TSDB_CODE_SUCCESS;
637 638
}

X
Xiaoyu Wang 已提交
639
static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
640
  SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
X
Xiaoyu Wang 已提交
641
  if (NULL == pProject) {
642 643 644
    return TSDB_CODE_OUT_OF_MEMORY;
  }

645
  if (NULL != pSelect->pLimit) {
X
Xiaoyu Wang 已提交
646 647
    pProject->limit = pSelect->pLimit->limit;
    pProject->offset = pSelect->pLimit->offset;
648 649 650 651 652 653 654 655 656 657 658 659 660
  } else {
    pProject->limit = -1;
    pProject->offset = -1;
  }

  if (NULL != pSelect->pSlimit) {
    pProject->slimit = ((SLimitNode*)pSelect->pSlimit)->limit;
    pProject->soffset = ((SLimitNode*)pSelect->pSlimit)->offset;
  } else {
    pProject->slimit = -1;
    pProject->soffset = -1;
  }

X
Xiaoyu Wang 已提交
661
  int32_t code = TSDB_CODE_SUCCESS;
662

X
Xiaoyu Wang 已提交
663
  pProject->pProjections = nodesCloneList(pSelect->pProjectionList);
X
Xiaoyu Wang 已提交
664 665
  if (NULL == pProject->pProjections) {
    code = TSDB_CODE_OUT_OF_MEMORY;
666
  }
X
Xiaoyu Wang 已提交
667
  strcpy(pProject->stmtName, pSelect->stmtName);
668 669

  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
670
    code = createColumnByProjections(pCxt, pSelect->stmtName, pSelect->pProjectionList, &pProject->node.pTargets);
671
  }
672

673
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
674 675 676
    *pLogicNode = (SLogicNode*)pProject;
  } else {
    nodesDestroyNode(pProject);
677
  }
678

679
  return code;
680 681
}

682 683 684 685 686 687 688 689 690 691
static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (NULL == pSelect->pPartitionByList) {
    return TSDB_CODE_SUCCESS;
  }

  SPartitionLogicNode* pPartition = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PARTITION);
  if (NULL == pPartition) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

692 693
  int32_t code =
      nodesCollectColumns(pSelect, SQL_CLAUSE_PARTITION_BY, NULL, COLLECT_COL_TYPE_ALL, &pPartition->node.pTargets);
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708

  if (TSDB_CODE_SUCCESS == code) {
    pPartition->pPartitionKeys = nodesCloneList(pSelect->pPartitionByList);
    if (NULL == pPartition->pPartitionKeys) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pPartition;
  } else {
    nodesDestroyNode(pPartition);
  }

  return code;
709 710 711 712 713 714 715
}

static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (!pSelect->isDistinct) {
    return TSDB_CODE_SUCCESS;
  }

716 717 718 719 720 721 722 723 724 725 726 727 728 729
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
  if (NULL == pAgg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  int32_t code = TSDB_CODE_SUCCESS;
  // set grouyp keys, agg funcs and having conditions
  pAgg->pGroupKeys = nodesCloneList(pSelect->pProjectionList);
  if (NULL == pAgg->pGroupKeys) {
    code = TSDB_CODE_OUT_OF_MEMORY;
  }

  // rewrite the expression in subsequent clauses
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
730
    code = rewriteExprForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_DISTINCT);
731 732 733 734 735 736 737 738 739 740 741 742 743 744
  }

  // set the output
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys, &pAgg->node.pTargets);
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
    nodesDestroyNode(pAgg);
  }

  return code;
745 746
}

747 748
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
749
  int32_t     code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
750 751
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
752
  }
753 754 755
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
  }
756 757
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
758
  }
759 760 761
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
  }
X
Xiaoyu Wang 已提交
762 763 764
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
  }
765 766
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createProjectLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
767
  }
768 769 770 771 772

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = pRoot;
  } else {
    nodesDestroyNode(pRoot);
X
Xiaoyu Wang 已提交
773
  }
774 775

  return code;
776 777
}

X
Xiaoyu Wang 已提交
778 779
static int32_t createSetOpChildLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                         FCreateSetOpLogicNode func, SLogicNode** pRoot) {
X
Xiaoyu Wang 已提交
780
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
781
  int32_t     code = func(pCxt, pSetOperator, &pNode);
X
Xiaoyu Wang 已提交
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
  if (TSDB_CODE_SUCCESS == code && NULL != pNode) {
    code = pushLogicNode(pCxt, pRoot, pNode);
  }
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyNode(pNode);
  }
  return code;
}

static int32_t createSetOpSortLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, SLogicNode** pLogicNode) {
  if (NULL == pSetOperator->pOrderByList) {
    return TSDB_CODE_SUCCESS;
  }

  SSortLogicNode* pSort = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SORT);
  if (NULL == pSort) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  int32_t code = TSDB_CODE_SUCCESS;

  pSort->node.pTargets = nodesCloneList(pSetOperator->pProjectionList);
  if (NULL == pSort->node.pTargets) {
    code = TSDB_CODE_OUT_OF_MEMORY;
  }

  if (TSDB_CODE_SUCCESS == code) {
    pSort->pSortKeys = nodesCloneList(pSetOperator->pOrderByList);
    if (NULL == pSort->pSortKeys) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pSort;
  } else {
    nodesDestroyNode(pSort);
  }

  return code;
}

X
Xiaoyu Wang 已提交
824 825
static int32_t createSetOpProjectLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                           SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
  SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
  if (NULL == pProject) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  if (NULL != pSetOperator->pLimit) {
    pProject->limit = ((SLimitNode*)pSetOperator->pLimit)->limit;
    pProject->offset = ((SLimitNode*)pSetOperator->pLimit)->offset;
  } else {
    pProject->limit = -1;
    pProject->offset = -1;
  }

  int32_t code = TSDB_CODE_SUCCESS;

  pProject->pProjections = nodesCloneList(pSetOperator->pProjectionList);
  if (NULL == pProject->pProjections) {
    code = TSDB_CODE_OUT_OF_MEMORY;
  }

  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByProjections(pCxt, NULL, pSetOperator->pProjectionList, &pProject->node.pTargets);
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pProject;
  } else {
    nodesDestroyNode(pProject);
  }

  return code;
}

X
Xiaoyu Wang 已提交
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
static int32_t createSetOpAggLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, SLogicNode** pLogicNode) {
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
  if (NULL == pAgg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  int32_t code = TSDB_CODE_SUCCESS;
  pAgg->pGroupKeys = nodesCloneList(pSetOperator->pProjectionList);
  if (NULL == pAgg->pGroupKeys) {
    code = TSDB_CODE_OUT_OF_MEMORY;
  }

  // rewrite the expression in subsequent clauses
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteExprs(pAgg->pGroupKeys, pSetOperator->pOrderByList);
  }

  // set the output
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys, &pAgg->node.pTargets);
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
    nodesDestroyNode(pAgg);
  }

  return code;
}

X
Xiaoyu Wang 已提交
890 891
static int32_t createSetOpLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, SLogicNode** pLogicNode) {
  SLogicNode* pSetOp = NULL;
X
Xiaoyu Wang 已提交
892
  int32_t     code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
893 894 895 896
  switch (pSetOperator->opType) {
    case SET_OP_TYPE_UNION_ALL:
      code = createSetOpProjectLogicNode(pCxt, pSetOperator, &pSetOp);
      break;
X
Xiaoyu Wang 已提交
897 898 899
    case SET_OP_TYPE_UNION:
      code = createSetOpAggLogicNode(pCxt, pSetOperator, &pSetOp);
      break;
X
Xiaoyu Wang 已提交
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
    default:
      code = -1;
      break;
  }

  SLogicNode* pLeft = NULL;
  if (TSDB_CODE_SUCCESS == code) {
    code = createQueryLogicNode(pCxt, pSetOperator->pLeft, &pLeft);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = nodesListMakeStrictAppend(&pSetOp->pChildren, (SNode*)pLeft);
  }
  SLogicNode* pRight = NULL;
  if (TSDB_CODE_SUCCESS == code) {
    code = createQueryLogicNode(pCxt, pSetOperator->pRight, &pRight);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = nodesListStrictAppend(pSetOp->pChildren, (SNode*)pRight);
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pSetOp;
  } else {
    nodesDestroyNode(pSetOp);
  }

  return code;
}

X
Xiaoyu Wang 已提交
929 930
static int32_t createSetOperatorLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                          SLogicNode** pLogicNode) {
931
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
932
  int32_t     code = createSetOpLogicNode(pCxt, pSetOperator, &pRoot);
933
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
934
    code = createSetOpChildLogicNode(pCxt, pSetOperator, createSetOpSortLogicNode, &pRoot);
935 936 937 938 939 940 941 942 943 944 945
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = pRoot;
  } else {
    nodesDestroyNode(pRoot);
  }

  return code;
}

946
static int32_t getMsgType(ENodeType sqlType) {
X
Xiaoyu Wang 已提交
947 948 949 950 951 952 953 954 955 956
  switch (sqlType) {
    case QUERY_NODE_CREATE_TABLE_STMT:
    case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
      return TDMT_VND_CREATE_TABLE;
    case QUERY_NODE_DROP_TABLE_STMT:
      return TDMT_VND_DROP_TABLE;
    default:
      break;
  }
  return TDMT_VND_SUBMIT;
957 958
}

959 960 961 962 963
static int32_t createVnodeModifLogicNode(SLogicPlanContext* pCxt, SVnodeModifOpStmt* pStmt, SLogicNode** pLogicNode) {
  SVnodeModifLogicNode* pModif = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_VNODE_MODIF);
  if (NULL == pModif) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
wafwerar's avatar
wafwerar 已提交
964
  TSWAP(pModif->pDataBlocks, pStmt->pDataBlocks);
965
  pModif->msgType = getMsgType(pStmt->sqlNodeType);
966 967
  *pLogicNode = (SLogicNode*)pModif;
  return TSDB_CODE_SUCCESS;
968 969
}

970
static int32_t createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
971 972
  switch (nodeType(pStmt)) {
    case QUERY_NODE_SELECT_STMT:
973
      return createSelectLogicNode(pCxt, (SSelectStmt*)pStmt, pLogicNode);
974
    case QUERY_NODE_VNODE_MODIF_STMT:
975
      return createVnodeModifLogicNode(pCxt, (SVnodeModifOpStmt*)pStmt, pLogicNode);
976 977
    case QUERY_NODE_EXPLAIN_STMT:
      return createQueryLogicNode(pCxt, ((SExplainStmt*)pStmt)->pQuery, pLogicNode);
978 979
    case QUERY_NODE_SET_OPERATOR:
      return createSetOperatorLogicNode(pCxt, (SSetOperator*)pStmt, pLogicNode);
X
Xiaoyu Wang 已提交
980 981 982
    default:
      break;
  }
983
  return TSDB_CODE_FAILED;
984 985
}

X
Xiaoyu Wang 已提交
986
int32_t createLogicPlan(SPlanContext* pCxt, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
987 988
  SLogicPlanContext cxt = {.pPlanCxt = pCxt};
  int32_t           code = createQueryLogicNode(&cxt, pCxt->pAstRoot, pLogicNode);
989 990
  if (TSDB_CODE_SUCCESS != code) {
    return code;
X
Xiaoyu Wang 已提交
991 992
  }
  return TSDB_CODE_SUCCESS;
993
}