planLogicCreater.c 52.1 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;
22
  SLogicNode*   pCurrRoot;
23
  bool          hasScan;
X
Xiaoyu Wang 已提交
24 25
} SLogicPlanContext;

X
Xiaoyu Wang 已提交
26 27
typedef int32_t (*FCreateLogicNode)(SLogicPlanContext*, void*, SLogicNode**);
typedef int32_t (*FCreateSelectLogicNode)(SLogicPlanContext*, SSelectStmt*, SLogicNode**);
X
Xiaoyu Wang 已提交
28
typedef int32_t (*FCreateSetOpLogicNode)(SLogicPlanContext*, SSetOperator*, SLogicNode**);
X
Xiaoyu Wang 已提交
29
typedef int32_t (*FCreateDeleteLogicNode)(SLogicPlanContext*, SDeleteStmt*, SLogicNode**);
30
typedef int32_t (*FCreateInsertLogicNode)(SLogicPlanContext*, SInsertStmt*, SLogicNode**);
X
Xiaoyu Wang 已提交
31

X
Xiaoyu Wang 已提交
32 33
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                        SLogicNode** pLogicNode);
34
static int32_t createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt, SLogicNode** pLogicNode);
X
Xiaoyu Wang 已提交
35 36

typedef struct SRewriteExprCxt {
X
Xiaoyu Wang 已提交
37
  int32_t    errCode;
X
Xiaoyu Wang 已提交
38 39 40
  SNodeList* pExprs;
} SRewriteExprCxt;

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
static void setColumnInfo(SFunctionNode* pFunc, SColumnNode* pCol) {
  switch (pFunc->funcType) {
    case FUNCTION_TYPE_TBNAME:
      pCol->colType = COLUMN_TYPE_TBNAME;
      break;
    case FUNCTION_TYPE_WSTART:
    case FUNCTION_TYPE_WEND:
      pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
      pCol->colType = COLUMN_TYPE_WINDOW_PC;
      break;
    case FUNCTION_TYPE_WDURATION:
      pCol->colType = COLUMN_TYPE_WINDOW_PC;
      break;
    case FUNCTION_TYPE_GROUP_KEY:
      pCol->colType = COLUMN_TYPE_GROUP_KEY;
      break;
    default:
      break;
  }
}

X
Xiaoyu Wang 已提交
62 63 64 65 66 67
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 已提交
68 69
      SNode*           pExpr;
      int32_t          index = 0;
X
Xiaoyu Wang 已提交
70 71 72 73 74 75
      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 已提交
76 77 78
          if (NULL == pCol) {
            return DEAL_RES_ERROR;
          }
X
Xiaoyu Wang 已提交
79 80 81 82
          SExprNode* pToBeRewrittenExpr = (SExprNode*)(*pNode);
          pCol->node.resType = pToBeRewrittenExpr->resType;
          strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
          strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName);
X
Xiaoyu Wang 已提交
83
          if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
84
            setColumnInfo((SFunctionNode*)pExpr, pCol);
X
Xiaoyu Wang 已提交
85
          }
X
Xiaoyu Wang 已提交
86 87 88 89 90 91 92 93 94 95
          nodesDestroyNode(*pNode);
          *pNode = (SNode*)pCol;
          return DEAL_RES_IGNORE_CHILD;
        }
        ++index;
      }
      break;
    }
    default:
      break;
H
Haojun Liao 已提交
96 97
  }

X
Xiaoyu Wang 已提交
98
  return DEAL_RES_CONTINUE;
X
Xiaoyu Wang 已提交
99 100
}

X
Xiaoyu Wang 已提交
101 102 103 104 105
static EDealRes doNameExpr(SNode* pNode, void* pContext) {
  switch (nodeType(pNode)) {
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
106 107 108
      if ('\0' == ((SExprNode*)pNode)->aliasName[0]) {
        sprintf(((SExprNode*)pNode)->aliasName, "#expr_%p", pNode);
      }
X
Xiaoyu Wang 已提交
109
      return DEAL_RES_IGNORE_CHILD;
X
Xiaoyu Wang 已提交
110 111
    }
    default:
X
Xiaoyu Wang 已提交
112
      break;
X
Xiaoyu Wang 已提交
113
  }
114

X
Xiaoyu Wang 已提交
115
  return DEAL_RES_CONTINUE;
116 117
}

X
Xiaoyu Wang 已提交
118
static int32_t rewriteExprsForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
X
Xiaoyu Wang 已提交
119
  nodesWalkExprs(pExprs, doNameExpr, NULL);
X
Xiaoyu Wang 已提交
120
  SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
X
Xiaoyu Wang 已提交
121 122
  nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
  return cxt.errCode;
123 124
}

X
Xiaoyu Wang 已提交
125 126 127 128 129 130 131
static int32_t rewriteExpr(SNodeList* pExprs, SNode** pTarget) {
  nodesWalkExprs(pExprs, doNameExpr, NULL);
  SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
  nodesRewriteExpr(pTarget, doRewriteExpr, &cxt);
  return cxt.errCode;
}

X
Xiaoyu Wang 已提交
132
static int32_t rewriteExprs(SNodeList* pExprs, SNodeList* pTarget) {
X
Xiaoyu Wang 已提交
133
  nodesWalkExprs(pExprs, doNameExpr, NULL);
X
Xiaoyu Wang 已提交
134
  SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
X
Xiaoyu Wang 已提交
135 136 137 138
  nodesRewriteExprs(pTarget, doRewriteExpr, &cxt);
  return cxt.errCode;
}

139 140 141 142 143
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 已提交
144
    }
145
  }
146 147
  if (TSDB_CODE_SUCCESS != nodesListAppend(pNewRoot->pChildren, (SNode*)*pOldRoot)) {
    return TSDB_CODE_OUT_OF_MEMORY;
148 149
  }

150 151
  (*pOldRoot)->pParent = pNewRoot;
  *pOldRoot = pNewRoot;
152

153 154
  return TSDB_CODE_SUCCESS;
}
155

X
Xiaoyu Wang 已提交
156 157
static int32_t createRootLogicNode(SLogicPlanContext* pCxt, void* pStmt, uint8_t precision, FCreateLogicNode func,
                                   SLogicNode** pRoot) {
X
Xiaoyu Wang 已提交
158
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
159
  int32_t     code = func(pCxt, pStmt, &pNode);
X
Xiaoyu Wang 已提交
160
  if (TSDB_CODE_SUCCESS == code && NULL != pNode) {
X
Xiaoyu Wang 已提交
161
    pNode->precision = precision;
X
Xiaoyu Wang 已提交
162
    code = pushLogicNode(pCxt, pRoot, pNode);
163
    pCxt->pCurrRoot = pNode;
164
  }
X
Xiaoyu Wang 已提交
165
  if (TSDB_CODE_SUCCESS != code) {
166
    nodesDestroyNode((SNode*)pNode);
X
Xiaoyu Wang 已提交
167
  }
X
Xiaoyu Wang 已提交
168
  return code;
169 170
}

X
Xiaoyu Wang 已提交
171 172 173 174
static int32_t createSelectRootLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, FCreateSelectLogicNode func,
                                         SLogicNode** pRoot) {
  return createRootLogicNode(pCxt, pSelect, pSelect->precision, (FCreateLogicNode)func, pRoot);
}
175

176 177
static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanPseudoCols, SNodeList* pScanCols,
                             int8_t tableType) {
X
Xiaoyu Wang 已提交
178 179 180 181
  if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) {
    return SCAN_TYPE_STREAM;
  }

182 183 184 185
  if (TSDB_SYSTEM_TABLE == tableType) {
    return SCAN_TYPE_SYSTEM_TABLE;
  }

X
Xiaoyu Wang 已提交
186
  if (NULL == pScanCols) {
187 188 189 190
    return NULL == pScanPseudoCols
               ? SCAN_TYPE_TABLE
               : ((FUNCTION_TYPE_BLOCK_DIST_INFO == ((SFunctionNode*)nodesListGetNode(pScanPseudoCols, 0))->funcType)
                      ? SCAN_TYPE_BLOCK_INFO
191
                      : SCAN_TYPE_TABLE);
X
Xiaoyu Wang 已提交
192 193
  }

194
  return SCAN_TYPE_TABLE;
X
Xiaoyu Wang 已提交
195 196
}

197 198
static SNode* createPrimaryKeyCol(uint64_t tableId) {
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
199 200 201 202 203 204 205 206 207
  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");
208
  return (SNode*)pCol;
209 210 211 212 213 214 215 216 217 218
}

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 已提交
219
  bool   found = false;
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
  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 已提交
236 237
static int32_t makeScanLogicNode(SLogicPlanContext* pCxt, SRealTableNode* pRealTable, bool hasRepeatScanFuncs,
                                 SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
238
  SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
X
Xiaoyu Wang 已提交
239
  if (NULL == pScan) {
240
    return TSDB_CODE_OUT_OF_MEMORY;
241 242
  }

wafwerar's avatar
wafwerar 已提交
243
  TSWAP(pScan->pVgroupList, pRealTable->pVgroupList);
X
Xiaoyu Wang 已提交
244
  TSWAP(pScan->pSmaIndexes, pRealTable->pSmaIndexes);
X
Xiaoyu Wang 已提交
245
  pScan->tableId = pRealTable->pMeta->uid;
X
Xiaoyu Wang 已提交
246
  pScan->stableId = pRealTable->pMeta->suid;
X
Xiaoyu Wang 已提交
247 248
  pScan->tableType = pRealTable->pMeta->tableType;
  pScan->scanSeq[0] = hasRepeatScanFuncs ? 2 : 1;
X
Xiaoyu Wang 已提交
249
  pScan->scanSeq[1] = 0;
X
Xiaoyu Wang 已提交
250
  pScan->scanRange = TSWINDOW_INITIALIZER;
X
Xiaoyu Wang 已提交
251 252 253 254
  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 已提交
255
  pScan->showRewrite = pCxt->pPlanCxt->showRewrite;
256
  pScan->ratio = pRealTable->ratio;
257
  pScan->dataRequired = FUNC_DATA_REQUIRED_DATA_LOAD;
258
  pScan->cacheLastMode = pRealTable->cacheLastMode;
259

X
Xiaoyu Wang 已提交
260 261 262 263 264 265 266 267 268 269
  *pLogicNode = (SLogicNode*)pScan;

  return TSDB_CODE_SUCCESS;
}

static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable,
                                   SLogicNode** pLogicNode) {
  SScanLogicNode* pScan = NULL;
  int32_t         code = makeScanLogicNode(pCxt, pRealTable, pSelect->hasRepeatScanFuncs, (SLogicNode**)&pScan);

270 271 272
  pScan->node.groupAction = GROUP_ACTION_NONE;
  pScan->node.resultDataOrder = DATA_ORDER_LEVEL_IN_BLOCK;

X
Xiaoyu Wang 已提交
273
  // set columns to scan
X
Xiaoyu Wang 已提交
274 275 276 277
  if (TSDB_CODE_SUCCESS == code) {
    code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, COLLECT_COL_TYPE_COL,
                               &pScan->pScanCols);
  }
278

279
  if (TSDB_CODE_SUCCESS == code) {
280 281
    code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, COLLECT_COL_TYPE_TAG,
                               &pScan->pScanPseudoCols);
282 283 284
  }

  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
285
    code = nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
286 287
  }

288 289
  // rewrite the expression in subsequent clauses
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
290
    code = rewriteExprsForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM);
291 292
  }

293
  pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType);
X
Xiaoyu Wang 已提交
294

295 296 297 298
  if (NULL != pScan->pScanCols) {
    pScan->hasNormalCols = true;
  }

X
Xiaoyu Wang 已提交
299
  if (TSDB_CODE_SUCCESS == code && SCAN_TYPE_SYSTEM_TABLE != pScan->scanType) {
X
Xiaoyu Wang 已提交
300
    code = addPrimaryKeyCol(pScan->tableId, &pScan->pScanCols);
301 302
  }

303 304
  // set output
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
305
    code = createColumnByRewriteExprs(pScan->pScanCols, &pScan->node.pTargets);
306 307
  }
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
308
    code = createColumnByRewriteExprs(pScan->pScanPseudoCols, &pScan->node.pTargets);
309
  }
310

X
Xiaoyu Wang 已提交
311 312 313
  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pScan;
  } else {
314
    nodesDestroyNode((SNode*)pScan);
X
Xiaoyu Wang 已提交
315
  }
316

317 318
  pCxt->hasScan = true;

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

X
Xiaoyu Wang 已提交
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
static int32_t createColumnByLastRow(SNodeList* pFuncs, SNodeList** pOutput) {
  int32_t    code = TSDB_CODE_SUCCESS;
  SNodeList* pCols = NULL;
  SNode*     pFunc = NULL;
  FOREACH(pFunc, pFuncs) {
    SFunctionNode* pLastRow = (SFunctionNode*)pFunc;
    SColumnNode*   pCol = (SColumnNode*)nodesListGetNode(pLastRow->pParameterList, 0);
    snprintf(pCol->colName, sizeof(pCol->colName), "%s", pLastRow->node.aliasName);
    snprintf(pCol->node.aliasName, sizeof(pCol->colName), "%s", pLastRow->node.aliasName);
    NODES_CLEAR_LIST(pLastRow->pParameterList);
    code = nodesListMakeStrictAppend(&pCols, (SNode*)pCol);
    if (TSDB_CODE_SUCCESS != code) {
      break;
    }
  }
  if (TSDB_CODE_SUCCESS == code) {
    *pOutput = pCols;
  } else {
    nodesDestroyList(pCols);
  }
  return code;
}

X
Xiaoyu Wang 已提交
345 346
static int32_t createSubqueryLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable,
                                       SLogicNode** pLogicNode) {
347
  return createQueryLogicNode(pCxt, pTable->pSubquery, pLogicNode);
348 349
}

X
Xiaoyu Wang 已提交
350 351
static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable,
                                   SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
352
  SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
X
Xiaoyu Wang 已提交
353
  if (NULL == pJoin) {
354 355
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
356 357

  pJoin->joinType = pJoinTable->joinType;
X
Xiaoyu Wang 已提交
358
  pJoin->isSingleTableJoin = pJoinTable->table.singleTable;
359
  pJoin->inputTsOrder = ORDER_ASC;
360 361
  pJoin->node.groupAction = GROUP_ACTION_CLEAR;
  pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_GLOBAL;
362
  pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_GLOBAL;
X
Xiaoyu Wang 已提交
363

364
  int32_t code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
365 366 367

  // set left and right node
  pJoin->node.pChildren = nodesMakeList();
X
Xiaoyu Wang 已提交
368
  if (NULL == pJoin->node.pChildren) {
369
    code = TSDB_CODE_OUT_OF_MEMORY;
370 371
  }

X
Xiaoyu Wang 已提交
372
  SLogicNode* pLeft = NULL;
373
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
374 375 376 377
    code = doCreateLogicNodeByTable(pCxt, pSelect, pJoinTable->pLeft, &pLeft);
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppend(pJoin->node.pChildren, (SNode*)pLeft);
    }
378
  }
379

X
Xiaoyu Wang 已提交
380
  SLogicNode* pRight = NULL;
381
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
382 383 384 385 386
    code = doCreateLogicNodeByTable(pCxt, pSelect, pJoinTable->pRight, &pRight);
    if (TSDB_CODE_SUCCESS == code) {
      code = nodesListStrictAppend(pJoin->node.pChildren, (SNode*)pRight);
    }
  }
X
Xiaoyu Wang 已提交
387 388

  // set on conditions
X
Xiaoyu Wang 已提交
389
  if (TSDB_CODE_SUCCESS == code && NULL != pJoinTable->pOnCond) {
X
Xiaoyu Wang 已提交
390
    pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond);
X
Xiaoyu Wang 已提交
391 392 393
    if (NULL == pJoin->pOnConditions) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
394 395
  }

X
Xiaoyu Wang 已提交
396
  // set the output
X
Xiaoyu Wang 已提交
397 398
  if (TSDB_CODE_SUCCESS == code) {
    pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
D
dapan1121 已提交
399
    if (NULL == pJoin->node.pTargets) {
X
Xiaoyu Wang 已提交
400 401 402 403 404 405 406 407 408
      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;
409
  } else {
410
    nodesDestroyNode((SNode*)pJoin);
411 412
  }

413
  return code;
X
Xiaoyu Wang 已提交
414
}
415

X
Xiaoyu Wang 已提交
416 417
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                        SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
418 419
  switch (nodeType(pTable)) {
    case QUERY_NODE_REAL_TABLE:
420
      return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
421
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
422
      return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
423
    case QUERY_NODE_JOIN_TABLE:
X
Xiaoyu Wang 已提交
424
      return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable, pLogicNode);
X
Xiaoyu Wang 已提交
425 426
    default:
      break;
427
  }
X
Xiaoyu Wang 已提交
428 429 430
  return TSDB_CODE_FAILED;
}

X
Xiaoyu Wang 已提交
431 432
static int32_t createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
                                      SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
433
  SLogicNode* pNode = NULL;
X
Xiaoyu Wang 已提交
434
  int32_t     code = doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode);
X
Xiaoyu Wang 已提交
435 436 437
  if (TSDB_CODE_SUCCESS == code) {
    pNode->pConditions = nodesCloneNode(pSelect->pWhere);
    if (NULL != pSelect->pWhere && NULL == pNode->pConditions) {
438
      nodesDestroyNode((SNode*)pNode);
X
Xiaoyu Wang 已提交
439 440
      return TSDB_CODE_OUT_OF_MEMORY;
    }
441
    pNode->precision = pSelect->precision;
X
Xiaoyu Wang 已提交
442
    *pLogicNode = pNode;
443
    pCxt->pCurrRoot = pNode;
X
Xiaoyu Wang 已提交
444 445 446 447
  }
  return code;
}

X
Xiaoyu Wang 已提交
448
static SColumnNode* createColumnByExpr(const char* pStmtName, SExprNode* pExpr) {
449
  SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
X
Xiaoyu Wang 已提交
450 451 452 453 454
  if (NULL == pCol) {
    return NULL;
  }
  pCol->node.resType = pExpr->resType;
  strcpy(pCol->colName, pExpr->aliasName);
X
Xiaoyu Wang 已提交
455 456 457
  if (NULL != pStmtName) {
    strcpy(pCol->tableAlias, pStmtName);
  }
X
Xiaoyu Wang 已提交
458
  return pCol;
459 460
}

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
static SNode* createGroupingSetNode(SNode* pExpr) {
  SGroupingSetNode* pGroupingSet = (SGroupingSetNode*)nodesMakeNode(QUERY_NODE_GROUPING_SET);
  if (NULL == pGroupingSet) {
    return NULL;
  }
  pGroupingSet->groupingSetType = GP_TYPE_NORMAL;
  if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pGroupingSet->pParameterList, nodesCloneNode(pExpr))) {
    nodesDestroyNode((SNode*)pGroupingSet);
    return NULL;
  }
  return (SNode*)pGroupingSet;
}

static int32_t createGroupKeysFromPartKeys(SNodeList* pPartKeys, SNodeList** pOutput) {
  SNodeList* pGroupKeys = NULL;
  SNode*     pPartKey = NULL;
  FOREACH(pPartKey, pPartKeys) {
    int32_t code = nodesListMakeStrictAppend(&pGroupKeys, createGroupingSetNode(pPartKey));
    if (TSDB_CODE_SUCCESS != code) {
      nodesDestroyList(pGroupKeys);
      return code;
    }
  }
  *pOutput = pGroupKeys;
  return TSDB_CODE_SUCCESS;
}

488
static EGroupAction getGroupAction(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
X
Xiaoyu Wang 已提交
489 490
  return (pCxt->pPlanCxt->streamQuery || NULL != pSelect->pLimit || NULL != pSelect->pSlimit) ? GROUP_ACTION_KEEP
                                                                                              : GROUP_ACTION_NONE;
491 492
}

493 494 495 496 497
static EDataOrderLevel getRequireDataOrder(bool needTimeline, SSelectStmt* pSelect) {
  return needTimeline ? (NULL != pSelect->pPartitionByList ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_GLOBAL)
                      : DATA_ORDER_LEVEL_NONE;
}

498
static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
499
  if (!pSelect->hasAggFuncs && NULL == pSelect->pGroupByList) {
500
    return TSDB_CODE_SUCCESS;
501 502
  }

X
Xiaoyu Wang 已提交
503
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
504 505 506
  if (NULL == pAgg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
507

508
  pAgg->hasLastRow = pSelect->hasLastRowFunc;
509
  pAgg->hasTimeLineFunc = pSelect->hasTimeLineFunc;
510
  pAgg->onlyHasKeepOrderFunc = pSelect->onlyHasKeepOrderFunc;
511
  pAgg->node.groupAction = getGroupAction(pCxt, pSelect);
512 513
  pAgg->node.requireDataOrder = getRequireDataOrder(pAgg->hasTimeLineFunc, pSelect);
  pAgg->node.resultDataOrder = pAgg->onlyHasKeepOrderFunc ? pAgg->node.requireDataOrder : DATA_ORDER_LEVEL_NONE;
514

X
Xiaoyu Wang 已提交
515 516
  int32_t code = TSDB_CODE_SUCCESS;

X
Xiaoyu Wang 已提交
517
  // set grouyp keys, agg funcs and having conditions
518
  if (TSDB_CODE_SUCCESS == code) {
519 520 521
    code = nodesCollectFuncs(pSelect, SQL_CLAUSE_GROUP_BY, fmIsAggFunc, &pAgg->pAggFuncs);
  }

X
Xiaoyu Wang 已提交
522
  // rewrite the expression in subsequent clauses
523
  if (TSDB_CODE_SUCCESS == code && NULL != pAgg->pAggFuncs) {
524 525 526 527
    code = rewriteExprsForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
  }

  if (NULL != pSelect->pGroupByList) {
528 529 530 531 532 533 534
    if (NULL != pAgg->pGroupKeys) {
      code = nodesListStrictAppendList(pAgg->pGroupKeys, nodesCloneList(pSelect->pGroupByList));
    } else {
      pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
      if (NULL == pAgg->pGroupKeys) {
        code = TSDB_CODE_OUT_OF_MEMORY;
      }
535
    }
536
  }
X
Xiaoyu Wang 已提交
537 538

  // rewrite the expression in subsequent clauses
539
  if (TSDB_CODE_SUCCESS == code) {
540
    code = rewriteExprsForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY);
541
  }
542

543
  if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) {
X
Xiaoyu Wang 已提交
544
    pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving);
545 546 547
    if (NULL == pAgg->node.pConditions) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
X
Xiaoyu Wang 已提交
548
  }
549

X
Xiaoyu Wang 已提交
550
  // set the output
551
  if (TSDB_CODE_SUCCESS == code && NULL != pAgg->pGroupKeys) {
X
Xiaoyu Wang 已提交
552
    code = createColumnByRewriteExprs(pAgg->pGroupKeys, &pAgg->node.pTargets);
553 554
  }
  if (TSDB_CODE_SUCCESS == code && NULL != pAgg->pAggFuncs) {
X
Xiaoyu Wang 已提交
555
    code = createColumnByRewriteExprs(pAgg->pAggFuncs, &pAgg->node.pTargets);
556 557 558 559 560
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
561
    nodesDestroyNode((SNode*)pAgg);
562 563 564
  }

  return code;
X
Xiaoyu Wang 已提交
565
}
566

567 568
static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  // top/bottom are both an aggregate function and a indefinite rows function
569
  if (!pSelect->hasIndefiniteRowsFunc || pSelect->hasAggFuncs || NULL != pSelect->pWindow) {
570 571 572 573 574 575 576 577 578
    return TSDB_CODE_SUCCESS;
  }

  SIndefRowsFuncLogicNode* pIdfRowsFunc =
      (SIndefRowsFuncLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC);
  if (NULL == pIdfRowsFunc) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

579
  pIdfRowsFunc->isTailFunc = pSelect->hasTailFunc;
580
  pIdfRowsFunc->isUniqueFunc = pSelect->hasUniqueFunc;
581
  pIdfRowsFunc->isTimeLineFunc = pSelect->hasTimeLineFunc;
582
  pIdfRowsFunc->node.groupAction = getGroupAction(pCxt, pSelect);
583
  pIdfRowsFunc->node.requireDataOrder = getRequireDataOrder(pIdfRowsFunc->isTimeLineFunc, pSelect);
584
  pIdfRowsFunc->node.resultDataOrder = pIdfRowsFunc->node.requireDataOrder;
585

X
Xiaoyu Wang 已提交
586 587
  // indefinite rows functions and _select_values functions
  int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pFuncs);
588
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
589
    code = rewriteExprsForSelect(pIdfRowsFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT);
590 591 592 593
  }

  // set the output
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
594
    code = createColumnByRewriteExprs(pIdfRowsFunc->pFuncs, &pIdfRowsFunc->node.pTargets);
595 596 597 598 599
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pIdfRowsFunc;
  } else {
600
    nodesDestroyNode((SNode*)pIdfRowsFunc);
601 602 603 604 605
  }

  return code;
}

X
Xiaoyu Wang 已提交
606 607 608 609 610 611 612 613 614 615
static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (!pSelect->hasInterpFunc) {
    return TSDB_CODE_SUCCESS;
  }

  SInterpFuncLogicNode* pInterpFunc = (SInterpFuncLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_INTERP_FUNC);
  if (NULL == pInterpFunc) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

616
  pInterpFunc->node.groupAction = getGroupAction(pCxt, pSelect);
617
  pInterpFunc->node.requireDataOrder = getRequireDataOrder(true, pSelect);
618 619
  pInterpFunc->node.resultDataOrder = pInterpFunc->node.requireDataOrder;

X
Xiaoyu Wang 已提交
620 621 622 623 624
  int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsInterpFunc, &pInterpFunc->pFuncs);
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteExprsForSelect(pInterpFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT);
  }

X
Xiaoyu Wang 已提交
625 626 627 628 629 630 631 632 633
  if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pFill) {
    SFillNode* pFill = (SFillNode*)pSelect->pFill;
    pInterpFunc->timeRange = pFill->timeRange;
    pInterpFunc->fillMode = pFill->mode;
    pInterpFunc->pTimeSeries = nodesCloneNode(pFill->pWStartTs);
    pInterpFunc->pFillValues = nodesCloneNode(pFill->pValues);
    if (NULL == pInterpFunc->pTimeSeries || (NULL != pFill->pValues && NULL == pInterpFunc->pFillValues)) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
X
Xiaoyu Wang 已提交
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
  }

  if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pEvery) {
    pInterpFunc->interval = ((SValueNode*)pSelect->pEvery)->datum.i;
  }

  // set the output
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExprs(pInterpFunc->pFuncs, &pInterpFunc->node.pTargets);
  }

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

  return code;
}

X
Xiaoyu Wang 已提交
654 655
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
                                             SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
656 657 658
  if (pCxt->pPlanCxt->streamQuery) {
    pWindow->triggerType = pCxt->pPlanCxt->triggerType;
    pWindow->watermark = pCxt->pPlanCxt->watermark;
659
    pWindow->igExpired = pCxt->pPlanCxt->igExpired;
5
54liuyao 已提交
660
  }
661
  pWindow->inputTsOrder = ORDER_ASC;
X
Xiaoyu Wang 已提交
662
  pWindow->outputTsOrder = ORDER_ASC;
5
54liuyao 已提交
663

664
  int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs);
X
Xiaoyu Wang 已提交
665
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
666
    code = rewriteExprsForSelect(pWindow->pFuncs, pSelect, SQL_CLAUSE_WINDOW);
X
Xiaoyu Wang 已提交
667 668 669
  }

  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
670
    code = createColumnByRewriteExprs(pWindow->pFuncs, &pWindow->node.pTargets);
X
Xiaoyu Wang 已提交
671 672
  }

X
Xiaoyu Wang 已提交
673 674
  pSelect->hasAggFuncs = false;

X
Xiaoyu Wang 已提交
675 676 677
  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pWindow;
  } else {
678
    nodesDestroyNode((SNode*)pWindow);
X
Xiaoyu Wang 已提交
679 680 681 682 683
  }

  return code;
}

X
Xiaoyu Wang 已提交
684 685
static int32_t createWindowLogicNodeByState(SLogicPlanContext* pCxt, SStateWindowNode* pState, SSelectStmt* pSelect,
                                            SLogicNode** pLogicNode) {
686
  SWindowLogicNode* pWindow = (SWindowLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
687 688 689 690 691
  if (NULL == pWindow) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  pWindow->winType = WINDOW_TYPE_STATE;
692
  pWindow->node.groupAction = getGroupAction(pCxt, pSelect);
693 694 695 696
  pWindow->node.requireDataOrder =
      pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : getRequireDataOrder(true, pSelect);
  pWindow->node.resultDataOrder =
      pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : pWindow->node.requireDataOrder;
697
  pWindow->pStateExpr = nodesCloneNode(pState->pExpr);
698
  pWindow->pTspk = nodesCloneNode(pState->pCol);
699
  if (NULL == pWindow->pStateExpr || NULL == pWindow->pTspk) {
700
    nodesDestroyNode((SNode*)pWindow);
701 702 703
    return TSDB_CODE_OUT_OF_MEMORY;
  }

704 705 706
  return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
}

X
Xiaoyu Wang 已提交
707 708
static int32_t createWindowLogicNodeBySession(SLogicPlanContext* pCxt, SSessionWindowNode* pSession,
                                              SSelectStmt* pSelect, SLogicNode** pLogicNode) {
709
  SWindowLogicNode* pWindow = (SWindowLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
X
Xiaoyu Wang 已提交
710 711 712 713 714 715
  if (NULL == pWindow) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  pWindow->winType = WINDOW_TYPE_SESSION;
  pWindow->sessionGap = ((SValueNode*)pSession->pGap)->datum.i;
716
  pWindow->windowAlgo = pCxt->pPlanCxt->streamQuery ? SESSION_ALGO_STREAM_SINGLE : SESSION_ALGO_MERGE;
717
  pWindow->node.groupAction = getGroupAction(pCxt, pSelect);
718 719 720 721
  pWindow->node.requireDataOrder =
      pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : getRequireDataOrder(true, pSelect);
  pWindow->node.resultDataOrder =
      pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : pWindow->node.requireDataOrder;
X
Xiaoyu Wang 已提交
722

723
  pWindow->pTspk = nodesCloneNode((SNode*)pSession->pCol);
724
  if (NULL == pWindow->pTspk) {
725
    nodesDestroyNode((SNode*)pWindow);
726 727
    return TSDB_CODE_OUT_OF_MEMORY;
  }
5
54liuyao 已提交
728
  pWindow->pTsEnd = nodesCloneNode((SNode*)pSession->pCol);
729

X
Xiaoyu Wang 已提交
730 731 732
  return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
}

X
Xiaoyu Wang 已提交
733 734
static int32_t createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SIntervalWindowNode* pInterval,
                                               SSelectStmt* pSelect, SLogicNode** pLogicNode) {
735
  SWindowLogicNode* pWindow = (SWindowLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
736 737 738
  if (NULL == pWindow) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
739 740 741

  pWindow->winType = WINDOW_TYPE_INTERVAL;
  pWindow->interval = ((SValueNode*)pInterval->pInterval)->datum.i;
X
Xiaoyu Wang 已提交
742
  pWindow->intervalUnit = ((SValueNode*)pInterval->pInterval)->unit;
X
Xiaoyu Wang 已提交
743
  pWindow->offset = (NULL != pInterval->pOffset ? ((SValueNode*)pInterval->pOffset)->datum.i : 0);
744
  pWindow->sliding = (NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->datum.i : pWindow->interval);
X
Xiaoyu Wang 已提交
745 746
  pWindow->slidingUnit =
      (NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->unit : pWindow->intervalUnit);
747
  pWindow->windowAlgo = pCxt->pPlanCxt->streamQuery ? INTERVAL_ALGO_STREAM_SINGLE : INTERVAL_ALGO_HASH;
748
  pWindow->node.groupAction = (NULL != pInterval->pFill ? GROUP_ACTION_KEEP : getGroupAction(pCxt, pSelect));
749 750 751 752 753 754
  pWindow->node.requireDataOrder =
      pCxt->pPlanCxt->streamQuery
          ? DATA_ORDER_LEVEL_IN_BLOCK
          : (pSelect->hasTimeLineFunc ? getRequireDataOrder(true, pSelect) : DATA_ORDER_LEVEL_IN_BLOCK);
  pWindow->node.resultDataOrder =
      pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : getRequireDataOrder(true, pSelect);
755

X
bugfix  
Xiaoyu Wang 已提交
756 757
  pWindow->pTspk = nodesCloneNode(pInterval->pCol);
  if (NULL == pWindow->pTspk) {
758
    nodesDestroyNode((SNode*)pWindow);
X
bugfix  
Xiaoyu Wang 已提交
759 760 761
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
762
  return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
X
Xiaoyu Wang 已提交
763 764
}

765
static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
766
  if (NULL == pSelect->pWindow) {
767
    return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
768 769 770
  }

  switch (nodeType(pSelect->pWindow)) {
771 772
    case QUERY_NODE_STATE_WINDOW:
      return createWindowLogicNodeByState(pCxt, (SStateWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
X
Xiaoyu Wang 已提交
773 774
    case QUERY_NODE_SESSION_WINDOW:
      return createWindowLogicNodeBySession(pCxt, (SSessionWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
X
Xiaoyu Wang 已提交
775
    case QUERY_NODE_INTERVAL_WINDOW:
X
Xiaoyu Wang 已提交
776
      return createWindowLogicNodeByInterval(pCxt, (SIntervalWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
X
Xiaoyu Wang 已提交
777 778 779 780
    default:
      break;
  }

781
  return TSDB_CODE_FAILED;
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
static EDealRes needFillValueImpl(SNode* pNode, void* pContext) {
  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
    SColumnNode* pCol = (SColumnNode*)pNode;
    if (COLUMN_TYPE_WINDOW_PC != pCol->colType && COLUMN_TYPE_GROUP_KEY != pCol->colType) {
      *(bool*)pContext = true;
      return DEAL_RES_END;
    }
  }
  return DEAL_RES_CONTINUE;
}

static bool needFillValue(SNode* pNode) {
  bool hasFillCol = false;
  nodesWalkExpr(pNode, needFillValueImpl, &hasFillCol);
  return hasFillCol;
}

static int32_t partFillExprs(SNodeList* pProjectionList, SNodeList** pFillExprs, SNodeList** pNotFillExprs) {
  int32_t code = TSDB_CODE_SUCCESS;
  SNode*  pProject = NULL;
  FOREACH(pProject, pProjectionList) {
    if (needFillValue(pProject)) {
      code = nodesListMakeStrictAppend(pFillExprs, nodesCloneNode(pProject));
    } else {
      code = nodesListMakeStrictAppend(pNotFillExprs, nodesCloneNode(pProject));
    }
    if (TSDB_CODE_SUCCESS != code) {
      NODES_DESTORY_LIST(*pFillExprs);
      NODES_DESTORY_LIST(*pNotFillExprs);
      break;
    }
  }
  return code;
}

X
Xiaoyu Wang 已提交
819 820 821 822 823 824 825
static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) ||
      NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) {
    return TSDB_CODE_SUCCESS;
  }

  SFillNode* pFillNode = (SFillNode*)(((SIntervalWindowNode*)pSelect->pWindow)->pFill);
826 827 828
  if (FILL_MODE_NONE == pFillNode->mode) {
    return TSDB_CODE_SUCCESS;
  }
X
Xiaoyu Wang 已提交
829

830
  SFillLogicNode* pFill = (SFillLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILL);
X
Xiaoyu Wang 已提交
831 832 833 834
  if (NULL == pFill) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

835
  pFill->node.groupAction = getGroupAction(pCxt, pSelect);
836 837
  pFill->node.requireDataOrder = getRequireDataOrder(true, pSelect);
  pFill->node.resultDataOrder = pFill->node.requireDataOrder;
X
Xiaoyu Wang 已提交
838
  pFill->inputTsOrder = ORDER_ASC;
839

840 841 842 843 844 845 846 847 848 849 850 851
  int32_t code = partFillExprs(pSelect->pProjectionList, &pFill->pFillExprs, &pFill->pNotFillExprs);
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteExprsForSelect(pFill->pFillExprs, pSelect, SQL_CLAUSE_FILL);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteExprsForSelect(pFill->pNotFillExprs, pSelect, SQL_CLAUSE_FILL);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExprs(pFill->pFillExprs, &pFill->node.pTargets);
  }
  if (TSDB_CODE_SUCCESS == code) {
    code = createColumnByRewriteExprs(pFill->pNotFillExprs, &pFill->node.pTargets);
852
  }
X
Xiaoyu Wang 已提交
853 854

  pFill->mode = pFillNode->mode;
X
Xiaoyu Wang 已提交
855
  pFill->timeRange = pFillNode->timeRange;
X
Xiaoyu Wang 已提交
856 857 858 859 860 861 862 863 864
  pFill->pValues = nodesCloneNode(pFillNode->pValues);
  pFill->pWStartTs = nodesCloneNode(pFillNode->pWStartTs);
  if ((NULL != pFillNode->pValues && NULL == pFill->pValues) || NULL == pFill->pWStartTs) {
    code = TSDB_CODE_OUT_OF_MEMORY;
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pFill;
  } else {
865
    nodesDestroyNode((SNode*)pFill);
X
Xiaoyu Wang 已提交
866 867 868 869 870
  }

  return code;
}

871 872 873 874 875 876 877 878
static bool isPrimaryKeySort(SNodeList* pOrderByList) {
  SNode* pExpr = ((SOrderByExprNode*)nodesListGetNode(pOrderByList, 0))->pExpr;
  if (QUERY_NODE_COLUMN != nodeType(pExpr)) {
    return false;
  }
  return PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId;
}

X
Xiaoyu Wang 已提交
879 880 881 882 883
static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (NULL == pSelect->pOrderByList) {
    return TSDB_CODE_SUCCESS;
  }

884
  SSortLogicNode* pSort = (SSortLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SORT);
X
Xiaoyu Wang 已提交
885 886 887 888
  if (NULL == pSort) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

889
  pSort->groupSort = pSelect->groupSort;
890 891
  pSort->node.groupAction = pSort->groupSort ? GROUP_ACTION_KEEP : GROUP_ACTION_CLEAR;
  pSort->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
892 893 894
  pSort->node.resultDataOrder = isPrimaryKeySort(pSelect->pOrderByList)
                                    ? (pSort->groupSort ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_GLOBAL)
                                    : DATA_ORDER_LEVEL_NONE;
895

896
  int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_ORDER_BY, NULL, COLLECT_COL_TYPE_ALL, &pSort->node.pTargets);
897 898 899 900
  if (TSDB_CODE_SUCCESS == code && NULL == pSort->node.pTargets) {
    code = nodesListMakeStrictAppend(&pSort->node.pTargets,
                                     nodesCloneNode(nodesListGetNode(pCxt->pCurrRoot->pTargets, 0)));
  }
X
Xiaoyu Wang 已提交
901 902 903 904 905 906 907 908 909 910 911

  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 {
912
    nodesDestroyNode((SNode*)pSort);
X
Xiaoyu Wang 已提交
913 914 915 916 917
  }

  return code;
}

X
Xiaoyu Wang 已提交
918 919
static int32_t createColumnByProjections(SLogicPlanContext* pCxt, const char* pStmtName, SNodeList* pExprs,
                                         SNodeList** pCols) {
X
Xiaoyu Wang 已提交
920
  SNodeList* pList = nodesMakeList();
X
Xiaoyu Wang 已提交
921
  if (NULL == pList) {
922 923 924
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
925
  SNode* pNode;
X
Xiaoyu Wang 已提交
926
  FOREACH(pNode, pExprs) {
927
    if (TSDB_CODE_SUCCESS != nodesListAppend(pList, (SNode*)createColumnByExpr(pStmtName, (SExprNode*)pNode))) {
X
Xiaoyu Wang 已提交
928 929
      nodesDestroyList(pList);
      return TSDB_CODE_OUT_OF_MEMORY;
930 931
    }
  }
932

X
Xiaoyu Wang 已提交
933 934
  *pCols = pList;
  return TSDB_CODE_SUCCESS;
935 936
}

X
Xiaoyu Wang 已提交
937
static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
938
  SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
X
Xiaoyu Wang 已提交
939
  if (NULL == pProject) {
940 941 942
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
943 944
  TSWAP(pProject->node.pLimit, pSelect->pLimit);
  TSWAP(pProject->node.pSlimit, pSelect->pSlimit);
945
  pProject->ignoreGroupId = (NULL == pSelect->pPartitionByList);
946 947
  pProject->node.groupAction =
      (!pSelect->isSubquery && pCxt->pPlanCxt->streamQuery) ? GROUP_ACTION_KEEP : GROUP_ACTION_CLEAR;
948 949
  pProject->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
  pProject->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
950

X
Xiaoyu Wang 已提交
951
  int32_t code = TSDB_CODE_SUCCESS;
952

X
Xiaoyu Wang 已提交
953
  pProject->pProjections = nodesCloneList(pSelect->pProjectionList);
X
Xiaoyu Wang 已提交
954 955
  if (NULL == pProject->pProjections) {
    code = TSDB_CODE_OUT_OF_MEMORY;
956
  }
X
Xiaoyu Wang 已提交
957
  strcpy(pProject->stmtName, pSelect->stmtName);
958 959

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

963
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
964 965
    *pLogicNode = (SLogicNode*)pProject;
  } else {
966
    nodesDestroyNode((SNode*)pProject);
967
  }
968

969
  return code;
970 971
}

972
static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
973
  if (NULL == pSelect->pPartitionByList) {
974 975 976
    return TSDB_CODE_SUCCESS;
  }

977
  SPartitionLogicNode* pPartition = (SPartitionLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PARTITION);
978 979 980 981
  if (NULL == pPartition) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

982 983 984 985
  pPartition->node.groupAction = GROUP_ACTION_SET;
  pPartition->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
  pPartition->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;

986 987
  int32_t code =
      nodesCollectColumns(pSelect, SQL_CLAUSE_PARTITION_BY, NULL, COLLECT_COL_TYPE_ALL, &pPartition->node.pTargets);
988 989 990
  if (TSDB_CODE_SUCCESS == code && NULL == pPartition->node.pTargets) {
    code = nodesListMakeStrictAppend(&pPartition->node.pTargets, nodesListGetNode(pCxt->pCurrRoot->pTargets, 0));
  }
991 992 993 994 995 996 997 998 999 1000 1001

  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 {
1002
    nodesDestroyNode((SNode*)pPartition);
1003 1004 1005
  }

  return code;
1006 1007 1008 1009 1010 1011 1012
}

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

1013 1014 1015 1016 1017
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
  if (NULL == pAgg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

1018
  pAgg->node.groupAction = GROUP_ACTION_CLEAR;
1019 1020 1021
  pAgg->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
  pAgg->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;

1022 1023
  int32_t code = TSDB_CODE_SUCCESS;
  // set grouyp keys, agg funcs and having conditions
1024
  SNodeList* pGroupKeys = NULL;
1025
  SNode*     pProjection = NULL;
1026 1027 1028 1029 1030 1031 1032 1033 1034
  FOREACH(pProjection, pSelect->pProjectionList) {
    code = nodesListMakeStrictAppend(&pGroupKeys, createGroupingSetNode(pProjection));
    if (TSDB_CODE_SUCCESS != code) {
      nodesDestroyList(pGroupKeys);
      break;
    }
  }
  if (TSDB_CODE_SUCCESS == code) {
    pAgg->pGroupKeys = pGroupKeys;
1035 1036 1037 1038
  }

  // rewrite the expression in subsequent clauses
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1039
    code = rewriteExprsForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_DISTINCT);
1040 1041 1042 1043
  }

  // set the output
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1044
    code = createColumnByRewriteExprs(pAgg->pGroupKeys, &pAgg->node.pTargets);
1045 1046 1047 1048 1049
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
1050
    nodesDestroyNode((SNode*)pAgg);
1051 1052 1053
  }

  return code;
1054 1055
}

1056 1057 1058 1059 1060 1061
static int32_t createSelectWithoutFromLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
                                                SLogicNode** pLogicNode) {
  return createProjectLogicNode(pCxt, pSelect, pLogicNode);
}

static int32_t createSelectFromLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
1062
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
1063
  int32_t     code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
1064
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1065
    code = createSelectRootLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
1066
  }
1067
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1068
    code = createSelectRootLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
1069
  }
X
Xiaoyu Wang 已提交
1070
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1071
    code = createSelectRootLogicNode(pCxt, pSelect, createFillLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
1072
  }
1073
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1074
    code = createSelectRootLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
1075
  }
1076
  if (TSDB_CODE_SUCCESS == code) {
1077
    code = createSelectRootLogicNode(pCxt, pSelect, createIndefRowsFuncLogicNode, &pRoot);
1078
  }
X
Xiaoyu Wang 已提交
1079 1080 1081
  if (TSDB_CODE_SUCCESS == code) {
    code = createSelectRootLogicNode(pCxt, pSelect, createInterpFuncLogicNode, &pRoot);
  }
1082
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1083
    code = createSelectRootLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
1084
  }
X
Xiaoyu Wang 已提交
1085
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1086
    code = createSelectRootLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
1087
  }
1088
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1089
    code = createSelectRootLogicNode(pCxt, pSelect, createProjectLogicNode, &pRoot);
X
Xiaoyu Wang 已提交
1090
  }
1091 1092 1093 1094

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = pRoot;
  } else {
1095
    nodesDestroyNode((SNode*)pRoot);
X
Xiaoyu Wang 已提交
1096
  }
1097 1098

  return code;
1099 1100
}

1101 1102 1103 1104 1105 1106 1107 1108
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
  if (NULL == pSelect->pFromTable) {
    return createSelectWithoutFromLogicNode(pCxt, pSelect, pLogicNode);
  } else {
    return createSelectFromLogicNode(pCxt, pSelect, pLogicNode);
  }
}

X
Xiaoyu Wang 已提交
1109 1110 1111
static int32_t createSetOpRootLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, FCreateSetOpLogicNode func,
                                        SLogicNode** pRoot) {
  return createRootLogicNode(pCxt, pSetOperator, pSetOperator->precision, (FCreateLogicNode)func, pRoot);
X
Xiaoyu Wang 已提交
1112 1113 1114 1115 1116 1117 1118
}

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

1119
  SSortLogicNode* pSort = (SSortLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SORT);
X
Xiaoyu Wang 已提交
1120 1121 1122 1123
  if (NULL == pSort) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

X
Xiaoyu Wang 已提交
1124
  TSWAP(pSort->node.pLimit, pSetOperator->pLimit);
1125

X
Xiaoyu Wang 已提交
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
  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 {
1143
    nodesDestroyNode((SNode*)pSort);
X
Xiaoyu Wang 已提交
1144 1145 1146 1147 1148
  }

  return code;
}

X
Xiaoyu Wang 已提交
1149 1150
static int32_t createSetOpProjectLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                           SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
1151 1152 1153 1154 1155
  SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
  if (NULL == pProject) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

1156
  if (NULL == pSetOperator->pOrderByList) {
X
Xiaoyu Wang 已提交
1157
    TSWAP(pProject->node.pLimit, pSetOperator->pLimit);
X
Xiaoyu Wang 已提交
1158
  }
1159
  pProject->ignoreGroupId = true;
X
Xiaoyu Wang 已提交
1160 1161 1162 1163 1164 1165 1166 1167 1168

  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) {
1169 1170
    code = createColumnByProjections(pCxt, pSetOperator->stmtName, pSetOperator->pProjectionList,
                                     &pProject->node.pTargets);
X
Xiaoyu Wang 已提交
1171 1172 1173 1174 1175
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pProject;
  } else {
1176
    nodesDestroyNode((SNode*)pProject);
X
Xiaoyu Wang 已提交
1177 1178 1179 1180 1181
  }

  return code;
}

X
Xiaoyu Wang 已提交
1182 1183 1184 1185 1186 1187
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;
  }

1188
  if (NULL == pSetOperator->pOrderByList) {
X
Xiaoyu Wang 已提交
1189
    TSWAP(pAgg->node.pSlimit, pSetOperator->pLimit);
1190 1191
  }

X
Xiaoyu Wang 已提交
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
  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) {
X
Xiaoyu Wang 已提交
1205
    code = createColumnByRewriteExprs(pAgg->pGroupKeys, &pAgg->node.pTargets);
X
Xiaoyu Wang 已提交
1206 1207 1208 1209 1210
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
1211
    nodesDestroyNode((SNode*)pAgg);
X
Xiaoyu Wang 已提交
1212 1213 1214 1215 1216
  }

  return code;
}

X
Xiaoyu Wang 已提交
1217 1218
static int32_t createSetOpLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, SLogicNode** pLogicNode) {
  SLogicNode* pSetOp = NULL;
X
Xiaoyu Wang 已提交
1219
  int32_t     code = TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
1220 1221 1222 1223
  switch (pSetOperator->opType) {
    case SET_OP_TYPE_UNION_ALL:
      code = createSetOpProjectLogicNode(pCxt, pSetOperator, &pSetOp);
      break;
X
Xiaoyu Wang 已提交
1224 1225 1226
    case SET_OP_TYPE_UNION:
      code = createSetOpAggLogicNode(pCxt, pSetOperator, &pSetOp);
      break;
X
Xiaoyu Wang 已提交
1227
    default:
1228
      code = TSDB_CODE_FAILED;
X
Xiaoyu Wang 已提交
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
      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 {
1250
    nodesDestroyNode((SNode*)pSetOp);
X
Xiaoyu Wang 已提交
1251 1252 1253 1254 1255
  }

  return code;
}

X
Xiaoyu Wang 已提交
1256 1257
static int32_t createSetOperatorLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
                                          SLogicNode** pLogicNode) {
1258
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
1259
  int32_t     code = createSetOpLogicNode(pCxt, pSetOperator, &pRoot);
1260
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1261
    code = createSetOpRootLogicNode(pCxt, pSetOperator, createSetOpSortLogicNode, &pRoot);
1262 1263 1264 1265 1266
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = pRoot;
  } else {
1267
    nodesDestroyNode((SNode*)pRoot);
1268 1269 1270 1271 1272
  }

  return code;
}

1273
static int32_t getMsgType(ENodeType sqlType) {
X
Xiaoyu Wang 已提交
1274 1275 1276 1277 1278 1279
  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;
X
Xiaoyu Wang 已提交
1280 1281
    case QUERY_NODE_ALTER_TABLE_STMT:
      return TDMT_VND_ALTER_TABLE;
X
Xiaoyu Wang 已提交
1282 1283
    case QUERY_NODE_FLUSH_DATABASE_STMT:
      return TDMT_VND_COMMIT;
X
Xiaoyu Wang 已提交
1284 1285 1286 1287
    default:
      break;
  }
  return TDMT_VND_SUBMIT;
1288 1289
}

1290
static int32_t createVnodeModifLogicNode(SLogicPlanContext* pCxt, SVnodeModifOpStmt* pStmt, SLogicNode** pLogicNode) {
1291
  SVnodeModifyLogicNode* pModif = (SVnodeModifyLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_VNODE_MODIFY);
1292 1293 1294
  if (NULL == pModif) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
X
Xiaoyu Wang 已提交
1295
  pModif->modifyType = MODIFY_TABLE_TYPE_INSERT;
wafwerar's avatar
wafwerar 已提交
1296
  TSWAP(pModif->pDataBlocks, pStmt->pDataBlocks);
1297
  pModif->msgType = getMsgType(pStmt->sqlNodeType);
1298 1299
  *pLogicNode = (SLogicNode*)pModif;
  return TSDB_CODE_SUCCESS;
1300 1301
}

X
Xiaoyu Wang 已提交
1302 1303 1304 1305 1306 1307
static int32_t createDeleteRootLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, FCreateDeleteLogicNode func,
                                         SLogicNode** pRoot) {
  return createRootLogicNode(pCxt, pDelete, pDelete->precision, (FCreateLogicNode)func, pRoot);
}

static int32_t createDeleteScanLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
1308 1309 1310 1311 1312 1313
  SScanLogicNode* pScan = NULL;
  int32_t         code = makeScanLogicNode(pCxt, (SRealTableNode*)pDelete->pFromTable, false, (SLogicNode**)&pScan);

  // set columns to scan
  if (TSDB_CODE_SUCCESS == code) {
    pScan->scanType = SCAN_TYPE_TABLE;
D
dapan1121 已提交
1314
    pScan->scanRange = pDelete->timeRange;
X
Xiaoyu Wang 已提交
1315 1316 1317 1318 1319 1320
    pScan->pScanCols = nodesCloneList(((SFunctionNode*)pDelete->pCountFunc)->pParameterList);
    if (NULL == pScan->pScanCols) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

X
Xiaoyu Wang 已提交
1321 1322
  if (TSDB_CODE_SUCCESS == code && NULL != pDelete->pTagCond) {
    pScan->pTagCond = nodesCloneNode(pDelete->pTagCond);
X
Xiaoyu Wang 已提交
1323 1324 1325 1326 1327 1328 1329
    if (NULL == pScan->pTagCond) {
      code = TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  // set output
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1330
    code = createColumnByRewriteExprs(pScan->pScanCols, &pScan->node.pTargets);
X
Xiaoyu Wang 已提交
1331 1332 1333 1334 1335
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pScan;
  } else {
1336
    nodesDestroyNode((SNode*)pScan);
X
Xiaoyu Wang 已提交
1337 1338 1339
  }

  return code;
X
Xiaoyu Wang 已提交
1340 1341 1342
}

static int32_t createDeleteAggLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
  if (NULL == pAgg) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  int32_t code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, nodesCloneNode(pDelete->pCountFunc));
  if (TSDB_CODE_SUCCESS == code) {
    code = rewriteExpr(pAgg->pAggFuncs, &pDelete->pCountFunc);
  }
  // set the output
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1354
    code = createColumnByRewriteExprs(pAgg->pAggFuncs, &pAgg->node.pTargets);
X
Xiaoyu Wang 已提交
1355 1356 1357 1358 1359
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = (SLogicNode*)pAgg;
  } else {
1360
    nodesDestroyNode((SNode*)pAgg);
X
Xiaoyu Wang 已提交
1361 1362 1363
  }

  return code;
X
Xiaoyu Wang 已提交
1364 1365
}

X
Xiaoyu Wang 已提交
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377
static int32_t createVnodeModifLogicNodeByDelete(SLogicPlanContext* pCxt, SDeleteStmt* pDelete,
                                                 SLogicNode** pLogicNode) {
  SVnodeModifyLogicNode* pModify = (SVnodeModifyLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_VNODE_MODIFY);
  if (NULL == pModify) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  SRealTableNode* pRealTable = (SRealTableNode*)pDelete->pFromTable;

  pModify->modifyType = MODIFY_TABLE_TYPE_DELETE;
  pModify->tableId = pRealTable->pMeta->uid;
  pModify->tableType = pRealTable->pMeta->tableType;
1378
  snprintf(pModify->tableName, sizeof(pModify->tableName), "%s", pRealTable->table.tableName);
1379
  strcpy(pModify->tsColName, pRealTable->pMeta->schema->name);
X
Xiaoyu Wang 已提交
1380
  pModify->deleteTimeRange = pDelete->timeRange;
X
Xiaoyu Wang 已提交
1381 1382
  pModify->pAffectedRows = nodesCloneNode(pDelete->pCountFunc);
  if (NULL == pModify->pAffectedRows) {
1383
    nodesDestroyNode((SNode*)pModify);
X
Xiaoyu Wang 已提交
1384 1385 1386 1387 1388
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  *pLogicNode = (SLogicNode*)pModify;
  return TSDB_CODE_SUCCESS;
X
Xiaoyu Wang 已提交
1389 1390 1391 1392
}

static int32_t createDeleteLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, SLogicNode** pLogicNode) {
  SLogicNode* pRoot = NULL;
X
Xiaoyu Wang 已提交
1393
  int32_t     code = createDeleteScanLogicNode(pCxt, pDelete, &pRoot);
X
Xiaoyu Wang 已提交
1394 1395 1396 1397
  if (TSDB_CODE_SUCCESS == code) {
    code = createDeleteRootLogicNode(pCxt, pDelete, createDeleteAggLogicNode, &pRoot);
  }
  if (TSDB_CODE_SUCCESS == code) {
X
Xiaoyu Wang 已提交
1398
    code = createDeleteRootLogicNode(pCxt, pDelete, createVnodeModifLogicNodeByDelete, &pRoot);
X
Xiaoyu Wang 已提交
1399 1400 1401 1402 1403
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicNode = pRoot;
  } else {
1404
    nodesDestroyNode((SNode*)pRoot);
X
Xiaoyu Wang 已提交
1405 1406 1407 1408 1409
  }

  return code;
}

1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
static int32_t creatInsertRootLogicNode(SLogicPlanContext* pCxt, SInsertStmt* pInsert, FCreateInsertLogicNode func,
                                        SLogicNode** pRoot) {
  return createRootLogicNode(pCxt, pInsert, pInsert->precision, (FCreateLogicNode)func, pRoot);
}

static int32_t createVnodeModifLogicNodeByInsert(SLogicPlanContext* pCxt, SInsertStmt* pInsert,
                                                 SLogicNode** pLogicNode) {
  SVnodeModifyLogicNode* pModify = (SVnodeModifyLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_VNODE_MODIFY);
  if (NULL == pModify) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  SRealTableNode* pRealTable = (SRealTableNode*)pInsert->pTable;

  pModify->modifyType = MODIFY_TABLE_TYPE_INSERT;
  pModify->tableId = pRealTable->pMeta->uid;
1426
  pModify->stableId = pRealTable->pMeta->suid;
1427
  pModify->tableType = pRealTable->pMeta->tableType;
1428
  snprintf(pModify->tableName, sizeof(pModify->tableName), "%s", pRealTable->table.tableName);
1429
  TSWAP(pModify->pVgroupList, pRealTable->pVgroupList);
1430 1431 1432 1433 1434
  pModify->pInsertCols = nodesCloneList(pInsert->pCols);
  if (NULL == pModify->pInsertCols) {
    nodesDestroyNode((SNode*)pModify);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455

  *pLogicNode = (SLogicNode*)pModify;
  return TSDB_CODE_SUCCESS;
}

static int32_t createInsertLogicNode(SLogicPlanContext* pCxt, SInsertStmt* pInsert, SLogicNode** pLogicNode) {
  SLogicNode* pRoot = NULL;
  int32_t     code = createQueryLogicNode(pCxt, pInsert->pQuery, &pRoot);
  if (TSDB_CODE_SUCCESS == code) {
    code = creatInsertRootLogicNode(pCxt, pInsert, createVnodeModifLogicNodeByInsert, &pRoot);
  }

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

  return code;
}

1456
static int32_t createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
1457 1458
  switch (nodeType(pStmt)) {
    case QUERY_NODE_SELECT_STMT:
1459
      return createSelectLogicNode(pCxt, (SSelectStmt*)pStmt, pLogicNode);
1460
    case QUERY_NODE_VNODE_MODIF_STMT:
1461
      return createVnodeModifLogicNode(pCxt, (SVnodeModifOpStmt*)pStmt, pLogicNode);
1462 1463
    case QUERY_NODE_EXPLAIN_STMT:
      return createQueryLogicNode(pCxt, ((SExplainStmt*)pStmt)->pQuery, pLogicNode);
1464 1465
    case QUERY_NODE_SET_OPERATOR:
      return createSetOperatorLogicNode(pCxt, (SSetOperator*)pStmt, pLogicNode);
X
Xiaoyu Wang 已提交
1466 1467
    case QUERY_NODE_DELETE_STMT:
      return createDeleteLogicNode(pCxt, (SDeleteStmt*)pStmt, pLogicNode);
1468 1469
    case QUERY_NODE_INSERT_STMT:
      return createInsertLogicNode(pCxt, (SInsertStmt*)pStmt, pLogicNode);
X
Xiaoyu Wang 已提交
1470 1471 1472
    default:
      break;
  }
1473
  return TSDB_CODE_FAILED;
1474 1475
}

X
Xiaoyu Wang 已提交
1476 1477 1478 1479 1480 1481 1482 1483
static void doSetLogicNodeParent(SLogicNode* pNode, SLogicNode* pParent) {
  pNode->pParent = pParent;
  SNode* pChild;
  FOREACH(pChild, pNode->pChildren) { doSetLogicNodeParent((SLogicNode*)pChild, pNode); }
}

static void setLogicNodeParent(SLogicNode* pNode) { doSetLogicNodeParent(pNode, NULL); }

1484
static void setLogicSubplanType(bool hasScan, SLogicSubplan* pSubplan) {
1485
  if (QUERY_NODE_LOGIC_PLAN_VNODE_MODIFY != nodeType(pSubplan->pNode)) {
1486
    pSubplan->subplanType = hasScan ? SUBPLAN_TYPE_SCAN : SUBPLAN_TYPE_MERGE;
1487 1488 1489 1490 1491 1492 1493 1494
  } else {
    SVnodeModifyLogicNode* pModify = (SVnodeModifyLogicNode*)pSubplan->pNode;
    pSubplan->subplanType = (MODIFY_TABLE_TYPE_INSERT == pModify->modifyType && NULL != pModify->node.pChildren)
                                ? SUBPLAN_TYPE_SCAN
                                : SUBPLAN_TYPE_MODIFY;
  }
}

X
Xiaoyu Wang 已提交
1495
int32_t createLogicPlan(SPlanContext* pCxt, SLogicSubplan** pLogicSubplan) {
1496
  SLogicPlanContext cxt = {.pPlanCxt = pCxt, .pCurrRoot = NULL, .hasScan = false};
X
Xiaoyu Wang 已提交
1497 1498 1499 1500

  SLogicSubplan* pSubplan = (SLogicSubplan*)nodesMakeNode(QUERY_NODE_LOGIC_SUBPLAN);
  if (NULL == pSubplan) {
    return TSDB_CODE_OUT_OF_MEMORY;
X
Xiaoyu Wang 已提交
1501
  }
X
Xiaoyu Wang 已提交
1502 1503 1504 1505 1506 1507 1508
  pSubplan->id.queryId = pCxt->queryId;
  pSubplan->id.groupId = 1;
  pSubplan->id.subplanId = 1;

  int32_t code = createQueryLogicNode(&cxt, pCxt->pAstRoot, &pSubplan->pNode);
  if (TSDB_CODE_SUCCESS == code) {
    setLogicNodeParent(pSubplan->pNode);
1509
    setLogicSubplanType(cxt.hasScan, pSubplan);
1510
    code = adjustLogicNodeDataRequirement(pSubplan->pNode, DATA_ORDER_LEVEL_NONE);
X
Xiaoyu Wang 已提交
1511 1512 1513 1514 1515
  }

  if (TSDB_CODE_SUCCESS == code) {
    *pLogicSubplan = pSubplan;
  } else {
1516
    nodesDestroyNode((SNode*)pSubplan);
X
Xiaoyu Wang 已提交
1517 1518 1519
  }

  return code;
1520
}