plannerImpl.c 13.2 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 17
#include "plannerImpl.h"
#include "functionMgt.h"
18

X
Xiaoyu Wang 已提交
19 20
#define CHECK_ALLOC(p, res) \
  do { \
X
Xiaoyu Wang 已提交
21
    if (NULL == (p)) { \
X
Xiaoyu Wang 已提交
22
      printf("%s : %d\n", __FUNCTION__, __LINE__); \
X
Xiaoyu Wang 已提交
23
      pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
X
Xiaoyu Wang 已提交
24
      return (res); \
X
Xiaoyu Wang 已提交
25 26 27 28 29
    } \
  } while (0)

#define CHECK_CODE(exec, res) \
  do { \
X
Xiaoyu Wang 已提交
30
    int32_t code = (exec); \
X
Xiaoyu Wang 已提交
31
    if (TSDB_CODE_SUCCESS != code) { \
X
Xiaoyu Wang 已提交
32
      printf("%s : %d\n", __FUNCTION__, __LINE__); \
X
Xiaoyu Wang 已提交
33
      pCxt->errCode = code; \
X
Xiaoyu Wang 已提交
34
      return (res); \
X
Xiaoyu Wang 已提交
35 36 37 38 39 40 41 42
    } \
  } while (0)

typedef struct SPlanContext {
  int32_t errCode;
  int32_t planNodeId;
  SNodeList* pResource;
} SPlanContext;
X
Xiaoyu Wang 已提交
43

X
Xiaoyu Wang 已提交
44 45 46
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt);
static SLogicNode* createLogicNodeByTable(SPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable);

X
Xiaoyu Wang 已提交
47
typedef struct SRewriteExprCxt {
X
Xiaoyu Wang 已提交
48
  int32_t errCode;
X
Xiaoyu Wang 已提交
49
  SNodeList* pExprs;
X
Xiaoyu Wang 已提交
50 51 52
} SRewriteExprCxt;

static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
X
Xiaoyu Wang 已提交
53 54 55 56
  switch (nodeType(*pNode)) {
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
X
Xiaoyu Wang 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
      SRewriteExprCxt* pCxt = (SRewriteExprCxt*)pContext;
      SNode* pExpr;
      int32_t index = 0;
      FOREACH(pExpr, pCxt->pExprs) {
        if (nodesEqualNode(pExpr, *pNode)) {
          SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
          if (NULL == pCol) {
            pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
            return DEAL_RES_ERROR;
          }
          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;
      }
X
Xiaoyu Wang 已提交
77 78 79 80 81
      break;
    }
    default:
      break;
  }
X
Xiaoyu Wang 已提交
82

X
Xiaoyu Wang 已提交
83 84 85
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98
typedef struct SNameExprCxt {
  int32_t planNodeId;
  int32_t rewriteId;
} SNameExprCxt;

static EDealRes doNameExpr(SNode* pNode, void* pContext) {
  switch (nodeType(pNode)) {
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
      SNameExprCxt* pCxt = (SNameExprCxt*)pContext;
      sprintf(((SExprNode*)pNode)->aliasName, "#expr_%d_%d", pCxt->planNodeId, pCxt->rewriteId++);
      return DEAL_RES_IGNORE_CHILD;
X
Xiaoyu Wang 已提交
99
    }
X
Xiaoyu Wang 已提交
100 101
    default:
      break;
X
Xiaoyu Wang 已提交
102
  }
X
Xiaoyu Wang 已提交
103 104 105 106 107 108 109

  return DEAL_RES_CONTINUE;
}

static int32_t rewriteExpr(int32_t planNodeId, int32_t rewriteId, SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
  SNameExprCxt nameCxt = { .planNodeId = planNodeId, .rewriteId = rewriteId };
  nodesWalkList(pExprs, doNameExpr, &nameCxt);
X
Xiaoyu Wang 已提交
110
  SRewriteExprCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs };
X
Xiaoyu Wang 已提交
111 112
  nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
  return cxt.errCode;
X
Xiaoyu Wang 已提交
113 114
}

X
Xiaoyu Wang 已提交
115 116 117 118 119
static SLogicNode* pushLogicNode(SPlanContext* pCxt, SLogicNode* pRoot, SLogicNode* pNode) {
  if (TSDB_CODE_SUCCESS != pCxt->errCode) {
    goto error;
  }

X
Xiaoyu Wang 已提交
120 121 122
  if (NULL == pRoot) {
    return pNode;
  }
X
Xiaoyu Wang 已提交
123

X
Xiaoyu Wang 已提交
124 125 126
  if (NULL == pNode) {
    return pRoot;
  }
X
Xiaoyu Wang 已提交
127

X
Xiaoyu Wang 已提交
128 129
  if (NULL == pNode->pChildren) {
    pNode->pChildren = nodesMakeList();
X
Xiaoyu Wang 已提交
130 131 132
    if (NULL == pNode->pChildren) {
      goto error;
    }
X
Xiaoyu Wang 已提交
133
  }
X
Xiaoyu Wang 已提交
134 135 136 137
  if (TSDB_CODE_SUCCESS != nodesListAppend(pNode->pChildren, (SNode*)pRoot)) {
    goto error;
  }
  pRoot->pParent = pNode;
X
Xiaoyu Wang 已提交
138
  return pNode;
X
Xiaoyu Wang 已提交
139 140 141
error:
  nodesDestroyNode((SNode*)pNode);
  return pRoot;
X
Xiaoyu Wang 已提交
142 143
}

X
Xiaoyu Wang 已提交
144
static SLogicNode* createScanLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable) {
X
Xiaoyu Wang 已提交
145
  SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
X
Xiaoyu Wang 已提交
146 147 148
  CHECK_ALLOC(pScan, NULL);
  pScan->node.id = pCxt->planNodeId++;

X
Xiaoyu Wang 已提交
149
  pScan->pMeta = pRealTable->pMeta;
X
Xiaoyu Wang 已提交
150 151 152

  // set columns to scan
  SNodeList* pCols = NULL;
X
Xiaoyu Wang 已提交
153
  CHECK_CODE(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, &pCols), (SLogicNode*)pScan);
X
Xiaoyu Wang 已提交
154 155 156 157
  if (NULL != pCols) {
    pScan->pScanCols = nodesCloneList(pCols);
    CHECK_ALLOC(pScan->pScanCols, (SLogicNode*)pScan);
  }
X
Xiaoyu Wang 已提交
158 159

  // set output
X
Xiaoyu Wang 已提交
160 161 162 163
  if (NULL != pCols) {
    pScan->node.pTargets = nodesCloneList(pCols);
    CHECK_ALLOC(pScan->node.pTargets, (SLogicNode*)pScan);
  }
X
Xiaoyu Wang 已提交
164

X
Xiaoyu Wang 已提交
165 166 167
  return (SLogicNode*)pScan;
}

X
Xiaoyu Wang 已提交
168
static SLogicNode* createSubqueryLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable) {
X
Xiaoyu Wang 已提交
169 170 171 172 173 174 175
  SLogicNode* pRoot = createQueryLogicNode(pCxt, pTable->pSubquery);
  CHECK_ALLOC(pRoot, NULL);
  SNode* pNode;
  FOREACH(pNode, pRoot->pTargets) {
    strcpy(((SColumnNode*)pNode)->tableAlias, pTable->table.tableAlias);
  }
  return pRoot;
X
Xiaoyu Wang 已提交
176 177
}

X
Xiaoyu Wang 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
static SLogicNode* createJoinLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable) {
  SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
  CHECK_ALLOC(pJoin, NULL);
  pJoin->node.id = pCxt->planNodeId++;

  pJoin->joinType = pJoinTable->joinType;

  // set left and right node
  pJoin->node.pChildren = nodesMakeList();
  CHECK_ALLOC(pJoin->node.pChildren, (SLogicNode*)pJoin);
  SLogicNode* pLeft = createLogicNodeByTable(pCxt, pSelect, pJoinTable->pLeft);
  CHECK_ALLOC(pLeft, (SLogicNode*)pJoin);
  CHECK_CODE(nodesListAppend(pJoin->node.pChildren, (SNode*)pLeft), (SLogicNode*)pJoin);
  SLogicNode* pRight = createLogicNodeByTable(pCxt, pSelect, pJoinTable->pRight);
  CHECK_ALLOC(pRight, (SLogicNode*)pJoin);
  CHECK_CODE(nodesListAppend(pJoin->node.pChildren, (SNode*)pRight), (SLogicNode*)pJoin);

  // set on conditions
X
Xiaoyu Wang 已提交
196 197 198 199
  if (NULL != pJoinTable->pOnCond) {
    pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond);
    CHECK_ALLOC(pJoin->pOnConditions, (SLogicNode*)pJoin);
  }
X
Xiaoyu Wang 已提交
200

X
Xiaoyu Wang 已提交
201 202
  // set the output
  pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
X
Xiaoyu Wang 已提交
203
  CHECK_ALLOC(pJoin->node.pTargets, (SLogicNode*)pJoin);
X
Xiaoyu Wang 已提交
204 205 206
  SNodeList* pTargets = nodesCloneList(pRight->pTargets);
  CHECK_ALLOC(pTargets, (SLogicNode*)pJoin);
  nodesListAppendList(pJoin->node.pTargets, pTargets);
X
Xiaoyu Wang 已提交
207 208 209 210

  return (SLogicNode*)pJoin;
}

X
Xiaoyu Wang 已提交
211
static SLogicNode* createLogicNodeByTable(SPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable) {
X
Xiaoyu Wang 已提交
212 213
  switch (nodeType(pTable)) {
    case QUERY_NODE_REAL_TABLE:
X
Xiaoyu Wang 已提交
214
      return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable);
X
Xiaoyu Wang 已提交
215
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
216
      return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable);
X
Xiaoyu Wang 已提交
217
    case QUERY_NODE_JOIN_TABLE:
X
Xiaoyu Wang 已提交
218
      return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable);
X
Xiaoyu Wang 已提交
219 220 221 222 223 224
    default:
      break;
  }
  return NULL;
}

X
Xiaoyu Wang 已提交
225
static SLogicNode* createWhereFilterLogicNode(SPlanContext* pCxt, SLogicNode* pChild, SSelectStmt* pSelect) {
X
Xiaoyu Wang 已提交
226
  if (NULL == pSelect->pWhere) {
X
Xiaoyu Wang 已提交
227 228
    return NULL;
  }
X
Xiaoyu Wang 已提交
229

X
Xiaoyu Wang 已提交
230
  SFilterLogicNode* pFilter = (SFilterLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILTER);
X
Xiaoyu Wang 已提交
231 232 233 234
  CHECK_ALLOC(pFilter, NULL);
  pFilter->node.id = pCxt->planNodeId++;

  // set filter conditions
X
Xiaoyu Wang 已提交
235
  pFilter->node.pConditions = nodesCloneNode(pSelect->pWhere);
X
Xiaoyu Wang 已提交
236 237
  CHECK_ALLOC(pFilter->node.pConditions, (SLogicNode*)pFilter);

X
Xiaoyu Wang 已提交
238 239
  // set the output
  pFilter->node.pTargets = nodesCloneList(pChild->pTargets);
X
Xiaoyu Wang 已提交
240 241
  CHECK_ALLOC(pFilter->node.pTargets, (SLogicNode*)pFilter);

X
Xiaoyu Wang 已提交
242 243 244
  return (SLogicNode*)pFilter;
}

X
Xiaoyu Wang 已提交
245 246 247 248 249 250 251 252 253
typedef struct SCreateColumnCxt {
  int32_t errCode;
  SNodeList* pList;
} SCreateColumnCxt;

static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
  SCreateColumnCxt* pCxt = (SCreateColumnCxt*)pContext;
  switch (nodeType(pNode)) {
    case QUERY_NODE_COLUMN: {
X
Xiaoyu Wang 已提交
254
      SNode* pCol = nodesCloneNode(pNode);
X
Xiaoyu Wang 已提交
255 256 257
      if (NULL == pCol || TSDB_CODE_SUCCESS != nodesListAppend(pCxt->pList, pCol)) {
        pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
        return DEAL_RES_ERROR;
X
Xiaoyu Wang 已提交
258
      }
X
Xiaoyu Wang 已提交
259 260 261 262 263
      return DEAL_RES_IGNORE_CHILD;
    }
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_FUNCTION: {
X
Xiaoyu Wang 已提交
264 265 266
      SExprNode* pExpr = (SExprNode*)pNode;
      SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
      if (NULL == pCol) {
X
Xiaoyu Wang 已提交
267 268
        pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
        return DEAL_RES_ERROR;
X
Xiaoyu Wang 已提交
269 270 271
      }
      pCol->node.resType = pExpr->resType;
      strcpy(pCol->colName, pExpr->aliasName);
X
Xiaoyu Wang 已提交
272 273 274 275 276
      if (TSDB_CODE_SUCCESS != nodesListAppend(pCxt->pList, (SNode*)pCol)) {
        pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
        return DEAL_RES_ERROR;
      }
      return DEAL_RES_IGNORE_CHILD;
X
Xiaoyu Wang 已提交
277
    }
X
Xiaoyu Wang 已提交
278 279
    default:
      break;
X
Xiaoyu Wang 已提交
280
  }
X
Xiaoyu Wang 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295

  return DEAL_RES_CONTINUE;
}

static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) {
  SCreateColumnCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pList = nodesMakeList() };
  if (NULL == cxt.pList) {
    return NULL;
  }
  nodesWalkList(pExprs, doCreateColumn, &cxt);
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyList(cxt.pList);
    return NULL;
  }
  return cxt.pList;
X
Xiaoyu Wang 已提交
296 297
}

X
Xiaoyu Wang 已提交
298
static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
X
Xiaoyu Wang 已提交
299 300
  SNodeList* pAggFuncs = NULL;
  CHECK_CODE(nodesCollectFuncs(pSelect, fmIsAggFunc, &pAggFuncs), NULL);
X
Xiaoyu Wang 已提交
301
  if (NULL == pAggFuncs && NULL == pSelect->pGroupByList) {
X
Xiaoyu Wang 已提交
302 303
    return NULL;
  }
X
Xiaoyu Wang 已提交
304

X
Xiaoyu Wang 已提交
305
  SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
X
Xiaoyu Wang 已提交
306 307 308 309
  CHECK_ALLOC(pAgg, NULL);
  pAgg->node.id = pCxt->planNodeId++;

  // set grouyp keys, agg funcs and having conditions
X
Xiaoyu Wang 已提交
310 311 312 313 314 315 316 317
  if (NULL != pSelect->pGroupByList) {
    pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
    CHECK_ALLOC(pAgg->pGroupKeys, (SLogicNode*)pAgg);
  }
  if (NULL != pAggFuncs) {
    pAgg->pAggFuncs = nodesCloneList(pAggFuncs);
    CHECK_ALLOC(pAgg->pAggFuncs, (SLogicNode*)pAgg);
  }
X
Xiaoyu Wang 已提交
318 319 320 321 322

  // rewrite the expression in subsequent clauses
  CHECK_CODE(rewriteExpr(pAgg->node.id, 1, pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY), (SLogicNode*)pAgg);
  CHECK_CODE(rewriteExpr(pAgg->node.id, 1 + LIST_LENGTH(pAgg->pGroupKeys), pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY), (SLogicNode*)pAgg);

X
Xiaoyu Wang 已提交
323 324 325 326
  if (NULL != pSelect->pHaving) {
    pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving);
    CHECK_ALLOC(pAgg->node.pConditions, (SLogicNode*)pAgg);
  }
X
Xiaoyu Wang 已提交
327

X
Xiaoyu Wang 已提交
328
  // set the output
X
Xiaoyu Wang 已提交
329
  pAgg->node.pTargets = nodesMakeList();
X
Xiaoyu Wang 已提交
330
  CHECK_ALLOC(pAgg->node.pTargets, (SLogicNode*)pAgg);
X
Xiaoyu Wang 已提交
331 332 333 334 335 336 337 338 339 340
  if (NULL != pAgg->pGroupKeys) {
    SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys);
    CHECK_ALLOC(pAgg->node.pTargets, (SLogicNode*)pAgg);
    nodesListAppendList(pAgg->node.pTargets, pTargets);
  }
  if (NULL != pAgg->pAggFuncs) {
    SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pAggFuncs);
    CHECK_ALLOC(pTargets, (SLogicNode*)pAgg);
    nodesListAppendList(pAgg->node.pTargets, pTargets);
  }
X
Xiaoyu Wang 已提交
341
  
X
Xiaoyu Wang 已提交
342 343 344
  return (SLogicNode*)pAgg;
}

X
Xiaoyu Wang 已提交
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
static SNodeList* createColumnByProjections(SPlanContext* pCxt, SNodeList* pExprs) {
  SNodeList* pList = nodesMakeList();
  CHECK_ALLOC(pList, NULL);
  SNode* pNode;
  FOREACH(pNode, pExprs) {
    SExprNode* pExpr = (SExprNode*)pNode;
    SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
    if (NULL == pCol) {
      goto error;
    }
    pCol->node.resType = pExpr->resType;
    strcpy(pCol->colName, pExpr->aliasName);
    if (TSDB_CODE_SUCCESS != nodesListAppend(pList, (SNode*)pCol)) {
      goto error;
    }
  }
  return pList;
error:
  nodesDestroyList(pList);
  return NULL;
}

X
Xiaoyu Wang 已提交
367 368 369 370 371
static SLogicNode* createProjectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
  SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
  CHECK_ALLOC(pProject, NULL);
  pProject->node.id = pCxt->planNodeId++;

X
Xiaoyu Wang 已提交
372 373 374
  pProject->pProjections = nodesCloneList(pSelect->pProjectionList);

  pProject->node.pTargets = createColumnByProjections(pCxt,pSelect->pProjectionList);
X
Xiaoyu Wang 已提交
375 376 377 378 379
  CHECK_ALLOC(pProject->node.pTargets, (SLogicNode*)pProject);

  return (SLogicNode*)pProject;
}

X
Xiaoyu Wang 已提交
380 381 382
static SLogicNode* createSelectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
  SLogicNode* pRoot = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable);
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
X
Xiaoyu Wang 已提交
383
    pRoot = pushLogicNode(pCxt, pRoot, createWhereFilterLogicNode(pCxt, pRoot, pSelect));
X
Xiaoyu Wang 已提交
384 385 386
  }
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
    pRoot = pushLogicNode(pCxt, pRoot, createAggLogicNode(pCxt, pSelect));
X
Xiaoyu Wang 已提交
387 388
  }
  if (TSDB_CODE_SUCCESS == pCxt->errCode) {
X
Xiaoyu Wang 已提交
389
    pRoot = pushLogicNode(pCxt, pRoot, createProjectLogicNode(pCxt, pSelect));
X
Xiaoyu Wang 已提交
390
  }
X
Xiaoyu Wang 已提交
391 392 393
  return pRoot;
}

X
Xiaoyu Wang 已提交
394
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt) {
X
Xiaoyu Wang 已提交
395 396
  switch (nodeType(pStmt)) {
    case QUERY_NODE_SELECT_STMT:
X
Xiaoyu Wang 已提交
397
      return createSelectLogicNode(pCxt, (SSelectStmt*)pStmt);    
X
Xiaoyu Wang 已提交
398 399 400 401 402 403
    default:
      break;
  }
}

int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) {
X
Xiaoyu Wang 已提交
404
  SPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 1 };
X
Xiaoyu Wang 已提交
405 406 407 408 409 410
  SLogicNode* pRoot = createQueryLogicNode(&cxt, pNode);
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyNode((SNode*)pRoot);
    return cxt.errCode;
  }
  *pLogicNode = pRoot;
X
Xiaoyu Wang 已提交
411 412
  return TSDB_CODE_SUCCESS;
}