planLogicCreater.c 30.5 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
}

X
Xiaoyu Wang 已提交
132 133 134 135 136
static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanCols, STableMeta* pMeta) {
  if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) {
    return SCAN_TYPE_STREAM;
  }

X
Xiaoyu Wang 已提交
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
  if (NULL == pScanCols) {
    // select count(*) from t
    return SCAN_TYPE_TABLE;
  }

  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;
}

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
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 已提交
178
  bool   found = false;
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
  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))) {
      nodesDestroyList(*pCols);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
196 197
static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable,
                                   SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
198
  SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
X
Xiaoyu Wang 已提交
199
  if (NULL == pScan) {
200
    return TSDB_CODE_OUT_OF_MEMORY;
201 202
  }

X
Xiaoyu Wang 已提交
203 204
  TSWAP(pScan->pMeta, pRealTable->pMeta, STableMeta*);
  TSWAP(pScan->pVgroupList, pRealTable->pVgroupList, SVgroupsInfo*);
X
Xiaoyu Wang 已提交
205 206
  pScan->scanSeq[0] = 1;
  pScan->scanSeq[1] = 0;
X
Xiaoyu Wang 已提交
207
  pScan->scanRange = TSWINDOW_INITIALIZER;
X
Xiaoyu Wang 已提交
208 209 210 211
  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 已提交
212
  pScan->showRewrite = pCxt->pPlanCxt->showRewrite;
213
  pScan->ratio = pRealTable->ratio;
214
  pScan->dataRequired = FUNC_DATA_REQUIRED_DATA_LOAD;
215

X
Xiaoyu Wang 已提交
216 217
  // set columns to scan
  SNodeList* pCols = NULL;
X
Xiaoyu Wang 已提交
218
  int32_t    code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, &pCols);
219 220 221 222 223
  if (TSDB_CODE_SUCCESS == code) {
    code = addPrimaryKeyCol(pScan->pMeta->uid, &pCols);
  }

  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
224
    pScan->pScanCols = nodesCloneList(pCols);
X
Xiaoyu Wang 已提交
225 226
    if (NULL == pScan) {
      code = TSDB_CODE_OUT_OF_MEMORY;
227
    }
228 229
  }

X
Xiaoyu Wang 已提交
230 231
  pScan->scanType = getScanType(pCxt, pCols, pScan->pMeta);

X
Xiaoyu Wang 已提交
232
  // set output
233
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
234
    pScan->node.pTargets = nodesCloneList(pCols);
X
Xiaoyu Wang 已提交
235 236 237
    if (NULL == pScan) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
238 239
  }

240 241
  nodesClearList(pCols);

X
Xiaoyu Wang 已提交
242 243 244 245 246
  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pScan;
  } else {
    nodesDestroyNode(pScan);
  }
247

X
Xiaoyu Wang 已提交
248
  return code;
X
Xiaoyu Wang 已提交
249
}
250

X
Xiaoyu Wang 已提交
251 252
static int32_t createSubqueryLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable,
                                       SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
253 254 255
  int32_t code = createQueryLogicNode(pCxt, pTable->pSubquery, pLogicNode);
  if (TSDB_CODE_SUCCESS == code) {
    SNode* pNode;
X
Xiaoyu Wang 已提交
256
    FOREACH(pNode, (*pLogicNode)->pTargets) { strcpy(((SColumnNode*)pNode)->tableAlias, pTable->table.tableAlias); }
257
  }
X
Xiaoyu Wang 已提交
258
  return code;
259 260
}

X
Xiaoyu Wang 已提交
261 262
static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable,
                                   SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
263
  SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
X
Xiaoyu Wang 已提交
264
  if (NULL == pJoin) {
265 266
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
267 268 269

  pJoin->joinType = pJoinTable->joinType;

270
  int32_t code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
271 272 273

  // set left and right node
  pJoin->node.pChildren = nodesMakeList();
X
Xiaoyu Wang 已提交
274
  if (NULL == pJoin->node.pChildren) {
275
    code = TSDB_CODE_OUT_OF_MEMORY;
276 277
  }

X
Xiaoyu Wang 已提交
278
  SLogicNode* pLeft = NULL;
279
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
280 281 282 283
    code = doCreateLogicNodeByTable(pCxt, pSelect, pJoinTable->pLeft, &pLeft);
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppend(pJoin->node.pChildren, (SNode*)pLeft);
    }
284
  }
285

X
Xiaoyu Wang 已提交
286
  SLogicNode* pRight = NULL;
287
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
288 289 290 291 292
    code = doCreateLogicNodeByTable(pCxt, pSelect, pJoinTable->pRight, &pRight);
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppend(pJoin->node.pChildren, (SNode*)pRight);
    }
  }
X
Xiaoyu Wang 已提交
293 294

  // set on conditions
X
Xiaoyu Wang 已提交
295
  if (TSDB_CODE_SUCCESS == code && NULL != pJoinTable->pOnCond) {
X
Xiaoyu Wang 已提交
296
    pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond);
X
Xiaoyu Wang 已提交
297 298 299
    if (NULL == pJoin->pOnConditions) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
300 301
  }

X
Xiaoyu Wang 已提交
302
  // set the output
X
Xiaoyu Wang 已提交
303 304
  if (TSDB_CODE_SUCCESS == code) {
    pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
D
dapan1121 已提交
305
    if (NULL == pJoin->node.pTargets) {
X
Xiaoyu Wang 已提交
306 307 308 309 310 311 312 313 314
      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;
315
  } else {
X
Xiaoyu Wang 已提交
316
    nodesDestroyNode(pJoin);
317 318
  }

319
  return code;
X
Xiaoyu Wang 已提交
320
}
321

X
Xiaoyu Wang 已提交
322 323
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                        SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
324 325
  switch (nodeType(pTable)) {
    case QUERY_NODE_REAL_TABLE:
X
Xiaoyu Wang 已提交
326
      return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
327
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
328
      return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
329
    case QUERY_NODE_JOIN_TABLE:
X
Xiaoyu Wang 已提交
330
      return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
331 332
    default:
      break;
333
  }
X
Xiaoyu Wang 已提交
334 335 336
  return TSDB_CODE_FAILED;
}

X
Xiaoyu Wang 已提交
337 338
static int32_t createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                      SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
339
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
340
  int32_t     code = doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode);
X
Xiaoyu Wang 已提交
341 342 343 344 345 346 347 348 349 350 351
  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 已提交
352
static SColumnNode* createColumnByExpr(const char* pStmtName, SExprNode* pExpr) {
X
Xiaoyu Wang 已提交
353 354 355 356 357 358
  SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
  if (NULL == pCol) {
    return NULL;
  }
  pCol->node.resType = pExpr->resType;
  strcpy(pCol->colName, pExpr->aliasName);
X
Xiaoyu Wang 已提交
359 360 361
  if (NULL != pStmtName) {
    strcpy(pCol->tableAlias, pStmtName);
  }
X
Xiaoyu Wang 已提交
362
  return pCol;
363 364
}

X
Xiaoyu Wang 已提交
365
typedef struct SCreateColumnCxt {
X
Xiaoyu Wang 已提交
366
  int32_t    errCode;
X
Xiaoyu Wang 已提交
367 368 369 370 371 372 373 374
  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);
X
Xiaoyu Wang 已提交
375 376 377 378
      if (NULL == pCol) {
        return DEAL_RES_ERROR;
      }
      return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
379
    }
X
Xiaoyu Wang 已提交
380 381 382
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
X
Xiaoyu Wang 已提交
383
      SExprNode*   pExpr = (SExprNode*)pNode;
X
Xiaoyu Wang 已提交
384
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
X
Xiaoyu Wang 已提交
385 386 387
      if (NULL == pCol) {
        return DEAL_RES_ERROR;
      }
X
Xiaoyu Wang 已提交
388 389
      pCol->node.resType = pExpr->resType;
      strcpy(pCol->colName, pExpr->aliasName);
X
Xiaoyu Wang 已提交
390
      return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
391
    }
X
Xiaoyu Wang 已提交
392 393
    default:
      break;
394 395
  }

X
Xiaoyu Wang 已提交
396
  return DEAL_RES_CONTINUE;
397 398
}

399
static int32_t createColumnByRewriteExps(SLogicPlanContext* pCxt, SNodeList* pExprs, SNodeList** pList) {
X
Xiaoyu Wang 已提交
400
  SCreateColumnCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pList = (NULL == *pList ? nodesMakeList() : *pList)};
401 402 403
  if (NULL == cxt.pList) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
404

X
Xiaoyu Wang 已提交
405
  nodesWalkExprs(pExprs, doCreateColumn, &cxt);
X
Xiaoyu Wang 已提交
406 407
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyList(cxt.pList);
408
    return cxt.errCode;
409
  }
410 411
  if (NULL == *pList) {
    *pList = cxt.pList;
412
  }
413
  return cxt.errCode;
X
Xiaoyu Wang 已提交
414
}
415

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

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

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

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

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

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

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

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

X
Xiaoyu Wang 已提交
457
  // set the output
458 459 460 461 462 463 464 465 466 467 468 469 470 471
  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 已提交
472
}
473

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

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

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

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

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

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

  return code;
}

X
Xiaoyu Wang 已提交
502 503
static int32_t createWindowLogicNodeByState(SLogicPlanContext* pCxt, SStateWindowNode* pState, SSelectStmt* pSelect,
                                            SLogicNode** pLogicNode) {
504 505 506 507 508 509 510 511
  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);

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

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

X
Xiaoyu Wang 已提交
521 522
static int32_t createWindowLogicNodeBySession(SLogicPlanContext* pCxt, SSessionWindowNode* pSession,
                                              SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
523 524 525 526 527 528 529 530
  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;

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

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

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

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

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

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

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

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

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

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

X
Xiaoyu Wang 已提交
591 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;
  }

  SNodeList* pCols = NULL;
X
Xiaoyu Wang 已提交
602
  int32_t    code = nodesCollectColumns(pSelect, SQL_CLAUSE_ORDER_BY, NULL, &pCols);
X
Xiaoyu Wang 已提交
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
  if (TSDB_CODE_SUCCESS == code && NULL != pCols) {
    pSort->node.pTargets = nodesCloneList(pCols);
    if (NULL == pSort->node.pTargets) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  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 已提交
626 627
static int32_t createColumnByProjections(SLogicPlanContext* pCxt, const char* pStmtName, SNodeList* pExprs,
                                         SNodeList** pCols) {
X
Xiaoyu Wang 已提交
628
  SNodeList* pList = nodesMakeList();
X
Xiaoyu Wang 已提交
629
  if (NULL == pList) {
630 631 632
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
633
  SNode* pNode;
X
Xiaoyu Wang 已提交
634
  FOREACH(pNode, pExprs) {
X
Xiaoyu Wang 已提交
635
    if (TSDB_CODE_SUCCESS != nodesListAppend(pList, createColumnByExpr(pStmtName, (SExprNode*)pNode))) {
X
Xiaoyu Wang 已提交
636 637
      nodesDestroyList(pList);
      return TSDB_CODE_OUT_OF_MEMORY;
638 639
    }
  }
640

X
Xiaoyu Wang 已提交
641 642
  *pCols = pList;
  return TSDB_CODE_SUCCESS;
643 644
}

X
Xiaoyu Wang 已提交
645
static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
646
  SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
X
Xiaoyu Wang 已提交
647
  if (NULL == pProject) {
648 649 650
    return TSDB_CODE_OUT_OF_MEMORY;
  }

651
  if (NULL != pSelect->pLimit) {
X
Xiaoyu Wang 已提交
652 653
    pProject->limit = pSelect->pLimit->limit;
    pProject->offset = pSelect->pLimit->offset;
654 655 656 657 658 659 660 661 662 663 664 665 666
  } 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 已提交
667
  int32_t code = TSDB_CODE_SUCCESS;
668

X
Xiaoyu Wang 已提交
669
  pProject->pProjections = nodesCloneList(pSelect->pProjectionList);
X
Xiaoyu Wang 已提交
670 671
  if (NULL == pProject->pProjections) {
    code = TSDB_CODE_OUT_OF_MEMORY;
672
  }
X
Xiaoyu Wang 已提交
673
  strcpy(pProject->stmtName, pSelect->stmtName);
674 675

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

679
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
680 681 682
    *pLogicNode = (SLogicNode*)pProject;
  } else {
    nodesDestroyNode(pProject);
683
  }
684

685
  return code;
686 687
}

688 689 690 691 692 693 694 695 696 697
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;
  }

698
  SNodeList* pCols = NULL;
X
Xiaoyu Wang 已提交
699
  int32_t    code = nodesCollectColumns(pSelect, SQL_CLAUSE_PARTITION_BY, NULL, &pCols);
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
  if (TSDB_CODE_SUCCESS == code && NULL != pCols) {
    pPartition->node.pTargets = nodesCloneList(pCols);
    if (NULL == pPartition->node.pTargets) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  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;
721 722 723 724 725 726 727
}

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

728 729 730 731 732 733 734 735 736 737 738 739 740 741
  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 已提交
742
    code = rewriteExprForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_DISTINCT);
743 744 745 746 747 748 749 750 751 752 753 754 755 756
  }

  // 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;
757 758
}

759 760
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
761
  int32_t     code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
762 763
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
764
  }
765 766 767
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
  }
768 769
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
770
  }
771 772 773
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
  }
X
Xiaoyu Wang 已提交
774 775 776
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
  }
777 778
  if (TSDB_CODE_SUCCESS == code) {
    code = createChildLogicNode(pCxt, pSelect, createProjectLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
779
  }
780 781 782 783 784

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = pRoot;
  } else {
    nodesDestroyNode(pRoot);
X
Xiaoyu Wang 已提交
785
  }
786 787

  return code;
788 789
}

X
Xiaoyu Wang 已提交
790 791
static int32_t createSetOpChildLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                         FCreateSetOpLogicNode func, SLogicNode** pRoot) {
X
Xiaoyu Wang 已提交
792
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
793
  int32_t     code = func(pCxt, pSetOperator, &pNode);
X
Xiaoyu Wang 已提交
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 824 825 826 827 828 829 830 831 832 833 834 835
  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 已提交
836 837
static int32_t createSetOpProjectLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                           SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
  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 已提交
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901
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 已提交
902 903
static int32_t createSetOpLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, SLogicNode** pLogicNode) {
  SLogicNode* pSetOp = NULL;
X
Xiaoyu Wang 已提交
904
  int32_t     code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
905 906 907 908
  switch (pSetOperator->opType) {
    case SET_OP_TYPE_UNION_ALL:
      code = createSetOpProjectLogicNode(pCxt, pSetOperator, &pSetOp);
      break;
X
Xiaoyu Wang 已提交
909 910 911
    case SET_OP_TYPE_UNION:
      code = createSetOpAggLogicNode(pCxt, pSetOperator, &pSetOp);
      break;
X
Xiaoyu Wang 已提交
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
    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 已提交
941 942
static int32_t createSetOperatorLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                          SLogicNode** pLogicNode) {
943
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
944
  int32_t     code = createSetOpLogicNode(pCxt, pSetOperator, &pRoot);
945
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
946
    code = createSetOpChildLogicNode(pCxt, pSetOperator, createSetOpSortLogicNode, &pRoot);
947 948 949 950 951 952 953 954 955 956 957
  }

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

  return code;
}

958
static int32_t getMsgType(ENodeType sqlType) {
X
Xiaoyu Wang 已提交
959 960 961
  return (QUERY_NODE_CREATE_TABLE_STMT == sqlType || QUERY_NODE_CREATE_MULTI_TABLE_STMT == sqlType)
             ? TDMT_VND_CREATE_TABLE
             : TDMT_VND_SUBMIT;
962 963
}

964 965 966 967 968
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;
  }
X
bugfix  
Xiaoyu Wang 已提交
969
  TSWAP(pModif->pDataBlocks, pStmt->pDataBlocks, SArray*);
970
  pModif->msgType = getMsgType(pStmt->sqlNodeType);
971 972
  *pLogicNode = (SLogicNode*)pModif;
  return TSDB_CODE_SUCCESS;
973 974
}

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

X
Xiaoyu Wang 已提交
991
int32_t createLogicPlan(SPlanContext* pCxt, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
992 993
  SLogicPlanContext cxt = {.pPlanCxt = pCxt};
  int32_t           code = createQueryLogicNode(&cxt, pCxt->pAstRoot, pLogicNode);
994 995
  if (TSDB_CODE_SUCCESS != code) {
    return code;
X
Xiaoyu Wang 已提交
996 997
  }
  return TSDB_CODE_SUCCESS;
998
}