nodesTraverseFuncs.c 22.8 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/>.
 */

16
#include "plannodes.h"
X
Xiaoyu Wang 已提交
17
#include "querynodes.h"
18

19 20
typedef enum ETraversalOrder {
  TRAVERSAL_PREORDER = 1,
D
dapan1121 已提交
21 22
  TRAVERSAL_INORDER,
  TRAVERSAL_POSTORDER,
23
} ETraversalOrder;
24

25
typedef EDealRes (*FNodeDispatcher)(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext);
26

27 28 29 30 31
static EDealRes walkExpr(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext);
static EDealRes walkExprs(SNodeList* pNodeList, ETraversalOrder order, FNodeWalker walker, void* pContext);
static EDealRes walkPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext);
static EDealRes walkPhysiPlans(SNodeList* pNodeList, ETraversalOrder order, FNodeWalker walker, void* pContext);

X
Xiaoyu Wang 已提交
32 33
static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext,
                         FNodeDispatcher dispatcher) {
34
  if (NULL == pNode) {
35
    return DEAL_RES_CONTINUE;
36 37
  }

38 39 40 41 42 43 44
  EDealRes res = DEAL_RES_CONTINUE;

  if (TRAVERSAL_PREORDER == order) {
    res = walker(pNode, pContext);
    if (DEAL_RES_CONTINUE != res) {
      return res;
    }
45 46
  }

47 48 49 50 51 52 53 54 55 56 57 58
  res = dispatcher(pNode, order, walker, pContext);

  if (DEAL_RES_ERROR != res && DEAL_RES_END != res && TRAVERSAL_POSTORDER == order) {
    res = walker(pNode, pContext);
  }

  return res;
}

static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  EDealRes res = DEAL_RES_CONTINUE;

59 60 61
  switch (nodeType(pNode)) {
    case QUERY_NODE_COLUMN:
    case QUERY_NODE_VALUE:
62
    case QUERY_NODE_LIMIT:
63
      // these node types with no subnodes
64
      break;
65 66
    case QUERY_NODE_OPERATOR: {
      SOperatorNode* pOpNode = (SOperatorNode*)pNode;
67
      res = walkExpr(pOpNode->pLeft, order, walker, pContext);
68
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
69
        res = walkExpr(pOpNode->pRight, order, walker, pContext);
70
      }
71
      break;
72 73
    }
    case QUERY_NODE_LOGIC_CONDITION:
74
      res = walkExprs(((SLogicConditionNode*)pNode)->pParameterList, order, walker, pContext);
75
      break;
76
    case QUERY_NODE_FUNCTION:
77
      res = walkExprs(((SFunctionNode*)pNode)->pParameterList, order, walker, pContext);
78
      break;
79 80
    case QUERY_NODE_REAL_TABLE:
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
81
      break;  // todo
82 83
    case QUERY_NODE_JOIN_TABLE: {
      SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;
84
      res = walkExpr(pJoinTableNode->pLeft, order, walker, pContext);
85
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
86
        res = walkExpr(pJoinTableNode->pRight, order, walker, pContext);
87
      }
88
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
89
        res = walkExpr(pJoinTableNode->pOnCond, order, walker, pContext);
90
      }
91
      break;
92 93
    }
    case QUERY_NODE_GROUPING_SET:
94
      res = walkExprs(((SGroupingSetNode*)pNode)->pParameterList, order, walker, pContext);
95
      break;
96
    case QUERY_NODE_ORDER_BY_EXPR:
97
      res = walkExpr(((SOrderByExprNode*)pNode)->pExpr, order, walker, pContext);
98
      break;
99 100
    case QUERY_NODE_STATE_WINDOW: {
      SStateWindowNode* pState = (SStateWindowNode*)pNode;
101
      res = walkExpr(pState->pExpr, order, walker, pContext);
102
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
103
        res = walkExpr(pState->pCol, order, walker, pContext);
104
      }
105
      break;
106
    }
X
Xiaoyu Wang 已提交
107 108
    case QUERY_NODE_SESSION_WINDOW: {
      SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
109
      res = walkExpr((SNode*)pSession->pCol, order, walker, pContext);
110
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
111
        res = walkExpr((SNode*)pSession->pGap, order, walker, pContext);
X
Xiaoyu Wang 已提交
112
      }
113
      break;
X
Xiaoyu Wang 已提交
114
    }
115 116
    case QUERY_NODE_INTERVAL_WINDOW: {
      SIntervalWindowNode* pInterval = (SIntervalWindowNode*)pNode;
117
      res = walkExpr(pInterval->pInterval, order, walker, pContext);
118
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
119
        res = walkExpr(pInterval->pOffset, order, walker, pContext);
120
      }
121
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
122
        res = walkExpr(pInterval->pSliding, order, walker, pContext);
123
      }
124
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
125
        res = walkExpr(pInterval->pFill, order, walker, pContext);
126
      }
127
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
128
        res = walkExpr(pInterval->pCol, order, walker, pContext);
X
bugfix  
Xiaoyu Wang 已提交
129
      }
130 131 132
      break;
    }
    case QUERY_NODE_NODE_LIST:
133
      res = walkExprs(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext);
134
      break;
X
Xiaoyu Wang 已提交
135 136 137 138 139 140
    case QUERY_NODE_FILL: {
      SFillNode* pFill = (SFillNode*)pNode;
      res = walkExpr(pFill->pValues, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkExpr(pFill->pWStartTs, order, walker, pContext);
      }
141
      break;
X
Xiaoyu Wang 已提交
142
    }
143
    case QUERY_NODE_RAW_EXPR:
144
      res = walkExpr(((SRawExprNode*)pNode)->pNode, order, walker, pContext);
145
      break;
D
dapan1121 已提交
146
    case QUERY_NODE_TARGET:
147
      res = walkExpr(((STargetNode*)pNode)->pExpr, order, walker, pContext);
D
dapan1121 已提交
148
      break;
149 150 151 152
    default:
      break;
  }

153 154 155
  return res;
}

156 157 158 159 160
static EDealRes walkExpr(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  return walkNode(pNode, order, walker, pContext, dispatchExpr);
}

static EDealRes walkExprs(SNodeList* pNodeList, ETraversalOrder order, FNodeWalker walker, void* pContext) {
161 162
  SNode* node;
  FOREACH(node, pNodeList) {
163
    EDealRes res = walkExpr(node, order, walker, pContext);
164 165
    if (DEAL_RES_ERROR == res || DEAL_RES_END == res) {
      return res;
166 167
    }
  }
168
  return DEAL_RES_CONTINUE;
169 170
}

171
void nodesWalkExpr(SNode* pNode, FNodeWalker walker, void* pContext) {
172
  (void)walkExpr(pNode, TRAVERSAL_PREORDER, walker, pContext);
173 174
}

X
Xiaoyu Wang 已提交
175
void nodesWalkExprs(SNodeList* pNodeList, FNodeWalker walker, void* pContext) {
176
  (void)walkExprs(pNodeList, TRAVERSAL_PREORDER, walker, pContext);
177 178
}

179
void nodesWalkExprPostOrder(SNode* pNode, FNodeWalker walker, void* pContext) {
180
  (void)walkExpr(pNode, TRAVERSAL_POSTORDER, walker, pContext);
181 182
}

X
Xiaoyu Wang 已提交
183
void nodesWalkExprsPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext) {
184
  (void)walkExprs(pList, TRAVERSAL_POSTORDER, walker, pContext);
185
}
186

187
static EDealRes rewriteExprs(SNodeList* pNodeList, ETraversalOrder order, FNodeRewriter rewriter, void* pContext);
188

189
static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewriter rewriter, void* pContext) {
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
  if (NULL == pRawNode || NULL == *pRawNode) {
    return DEAL_RES_CONTINUE;
  }

  EDealRes res = DEAL_RES_CONTINUE;

  if (TRAVERSAL_PREORDER == order) {
    res = rewriter(pRawNode, pContext);
    if (DEAL_RES_CONTINUE != res) {
      return res;
    }
  }

  SNode* pNode = *pRawNode;
  switch (nodeType(pNode)) {
    case QUERY_NODE_COLUMN:
    case QUERY_NODE_VALUE:
    case QUERY_NODE_LIMIT:
      // these node types with no subnodes
      break;
    case QUERY_NODE_OPERATOR: {
      SOperatorNode* pOpNode = (SOperatorNode*)pNode;
212
      res = rewriteExpr(&(pOpNode->pLeft), order, rewriter, pContext);
213
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
214
        res = rewriteExpr(&(pOpNode->pRight), order, rewriter, pContext);
215 216 217 218
      }
      break;
    }
    case QUERY_NODE_LOGIC_CONDITION:
219
      res = rewriteExprs(((SLogicConditionNode*)pNode)->pParameterList, order, rewriter, pContext);
220 221
      break;
    case QUERY_NODE_FUNCTION:
222
      res = rewriteExprs(((SFunctionNode*)pNode)->pParameterList, order, rewriter, pContext);
223 224 225
      break;
    case QUERY_NODE_REAL_TABLE:
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
226
      break;  // todo
227 228
    case QUERY_NODE_JOIN_TABLE: {
      SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;
229
      res = rewriteExpr(&(pJoinTableNode->pLeft), order, rewriter, pContext);
230
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
231
        res = rewriteExpr(&(pJoinTableNode->pRight), order, rewriter, pContext);
232
      }
233
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
234
        res = rewriteExpr(&(pJoinTableNode->pOnCond), order, rewriter, pContext);
235 236 237 238
      }
      break;
    }
    case QUERY_NODE_GROUPING_SET:
239
      res = rewriteExprs(((SGroupingSetNode*)pNode)->pParameterList, order, rewriter, pContext);
240 241
      break;
    case QUERY_NODE_ORDER_BY_EXPR:
242
      res = rewriteExpr(&(((SOrderByExprNode*)pNode)->pExpr), order, rewriter, pContext);
243
      break;
244 245
    case QUERY_NODE_STATE_WINDOW: {
      SStateWindowNode* pState = (SStateWindowNode*)pNode;
246
      res = rewriteExpr(&pState->pExpr, order, rewriter, pContext);
247
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
248
        res = rewriteExpr(&pState->pCol, order, rewriter, pContext);
249
      }
250
      break;
251 252 253
    }
    case QUERY_NODE_SESSION_WINDOW: {
      SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
254
      res = rewriteExpr((SNode**)&pSession->pCol, order, rewriter, pContext);
255
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
256
        res = rewriteExpr((SNode**)&pSession->pGap, order, rewriter, pContext);
257
      }
258
      break;
259
    }
260 261
    case QUERY_NODE_INTERVAL_WINDOW: {
      SIntervalWindowNode* pInterval = (SIntervalWindowNode*)pNode;
262
      res = rewriteExpr(&(pInterval->pInterval), order, rewriter, pContext);
263
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
264
        res = rewriteExpr(&(pInterval->pOffset), order, rewriter, pContext);
265
      }
266
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
267
        res = rewriteExpr(&(pInterval->pSliding), order, rewriter, pContext);
268
      }
269
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
270
        res = rewriteExpr(&(pInterval->pFill), order, rewriter, pContext);
271
      }
272
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
273
        res = rewriteExpr(&(pInterval->pCol), order, rewriter, pContext);
X
bugfix  
Xiaoyu Wang 已提交
274
      }
275 276 277
      break;
    }
    case QUERY_NODE_NODE_LIST:
278
      res = rewriteExprs(((SNodeListNode*)pNode)->pNodeList, order, rewriter, pContext);
279
      break;
X
Xiaoyu Wang 已提交
280 281 282 283 284 285
    case QUERY_NODE_FILL: {
      SFillNode* pFill = (SFillNode*)pNode;
      res = rewriteExpr(&pFill->pValues, order, rewriter, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = rewriteExpr(&(pFill->pWStartTs), order, rewriter, pContext);
      }
286
      break;
X
Xiaoyu Wang 已提交
287
    }
288
    case QUERY_NODE_RAW_EXPR:
289
      res = rewriteExpr(&(((SRawExprNode*)pNode)->pNode), order, rewriter, pContext);
290
      break;
D
dapan1121 已提交
291
    case QUERY_NODE_TARGET:
292
      res = rewriteExpr(&(((STargetNode*)pNode)->pExpr), order, rewriter, pContext);
D
dapan1121 已提交
293
      break;
294 295 296 297
    default:
      break;
  }

298
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res && TRAVERSAL_POSTORDER == order) {
299 300 301 302 303 304
    res = rewriter(pRawNode, pContext);
  }

  return res;
}

305
static EDealRes rewriteExprs(SNodeList* pNodeList, ETraversalOrder order, FNodeRewriter rewriter, void* pContext) {
306 307
  SNode** pNode;
  FOREACH_FOR_REWRITE(pNode, pNodeList) {
308
    EDealRes res = rewriteExpr(pNode, order, rewriter, pContext);
309 310
    if (DEAL_RES_ERROR == res || DEAL_RES_END == res) {
      return res;
311 312 313 314 315
    }
  }
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
316
void nodesRewriteExpr(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
317
  (void)rewriteExpr(pNode, TRAVERSAL_PREORDER, rewriter, pContext);
318 319
}

X
Xiaoyu Wang 已提交
320
void nodesRewriteExprs(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
321
  (void)rewriteExprs(pList, TRAVERSAL_PREORDER, rewriter, pContext);
322 323
}

X
Xiaoyu Wang 已提交
324
void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
325
  (void)rewriteExpr(pNode, TRAVERSAL_POSTORDER, rewriter, pContext);
326 327
}

X
Xiaoyu Wang 已提交
328
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
329
  (void)rewriteExprs(pList, TRAVERSAL_POSTORDER, rewriter, pContext);
330
}
X
Xiaoyu Wang 已提交
331 332 333 334 335 336 337 338

void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext) {
  if (NULL == pSelect) {
    return;
  }

  switch (clause) {
    case SQL_CLAUSE_FROM:
X
Xiaoyu Wang 已提交
339 340
      nodesWalkExpr(pSelect->pFromTable, walker, pContext);
      nodesWalkExpr(pSelect->pWhere, walker, pContext);
X
Xiaoyu Wang 已提交
341
    case SQL_CLAUSE_WHERE:
X
Xiaoyu Wang 已提交
342
      nodesWalkExprs(pSelect->pPartitionByList, walker, pContext);
X
Xiaoyu Wang 已提交
343
    case SQL_CLAUSE_PARTITION_BY:
X
Xiaoyu Wang 已提交
344
      nodesWalkExpr(pSelect->pWindow, walker, pContext);
X
Xiaoyu Wang 已提交
345
    case SQL_CLAUSE_WINDOW:
X
Xiaoyu Wang 已提交
346 347 348
      if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
        nodesWalkExpr(((SIntervalWindowNode*)pSelect->pWindow)->pFill, walker, pContext);
      }
349
    case SQL_CLAUSE_FILL:
X
Xiaoyu Wang 已提交
350
      nodesWalkExprs(pSelect->pGroupByList, walker, pContext);
X
Xiaoyu Wang 已提交
351
    case SQL_CLAUSE_GROUP_BY:
X
Xiaoyu Wang 已提交
352
      nodesWalkExpr(pSelect->pHaving, walker, pContext);
X
Xiaoyu Wang 已提交
353
    case SQL_CLAUSE_HAVING:
354
    case SQL_CLAUSE_SELECT:
X
Xiaoyu Wang 已提交
355
    case SQL_CLAUSE_DISTINCT:
356
      nodesWalkExprs(pSelect->pOrderByList, walker, pContext);
X
Xiaoyu Wang 已提交
357
    case SQL_CLAUSE_ORDER_BY:
X
Xiaoyu Wang 已提交
358
      nodesWalkExprs(pSelect->pProjectionList, walker, pContext);
X
Xiaoyu Wang 已提交
359 360 361 362 363 364 365 366 367 368 369 370 371 372
    default:
      break;
  }

  return;
}

void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext) {
  if (NULL == pSelect) {
    return;
  }

  switch (clause) {
    case SQL_CLAUSE_FROM:
X
Xiaoyu Wang 已提交
373 374
      nodesRewriteExpr(&(pSelect->pFromTable), rewriter, pContext);
      nodesRewriteExpr(&(pSelect->pWhere), rewriter, pContext);
X
Xiaoyu Wang 已提交
375
    case SQL_CLAUSE_WHERE:
X
Xiaoyu Wang 已提交
376
      nodesRewriteExprs(pSelect->pPartitionByList, rewriter, pContext);
X
Xiaoyu Wang 已提交
377
    case SQL_CLAUSE_PARTITION_BY:
X
Xiaoyu Wang 已提交
378
      nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext);
X
Xiaoyu Wang 已提交
379
    case SQL_CLAUSE_WINDOW:
X
Xiaoyu Wang 已提交
380 381 382
      if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
        nodesRewriteExpr(&(((SIntervalWindowNode*)pSelect->pWindow)->pFill), rewriter, pContext);
      }
383
    case SQL_CLAUSE_FILL:
X
Xiaoyu Wang 已提交
384
      nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext);
X
Xiaoyu Wang 已提交
385
    case SQL_CLAUSE_GROUP_BY:
X
Xiaoyu Wang 已提交
386
      nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext);
X
Xiaoyu Wang 已提交
387
    case SQL_CLAUSE_HAVING:
388
    case SQL_CLAUSE_SELECT:
X
Xiaoyu Wang 已提交
389
    case SQL_CLAUSE_DISTINCT:
X
Xiaoyu Wang 已提交
390
      nodesRewriteExprs(pSelect->pOrderByList, rewriter, pContext);
X
Xiaoyu Wang 已提交
391
    case SQL_CLAUSE_ORDER_BY:
X
Xiaoyu Wang 已提交
392
      nodesRewriteExprs(pSelect->pProjectionList, rewriter, pContext);
X
Xiaoyu Wang 已提交
393 394 395 396 397 398
    default:
      break;
  }

  return;
}
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418

static EDealRes walkPhysiNode(SPhysiNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  EDealRes res = walkPhysiPlan((SNode*)pNode->pOutputDataBlockDesc, order, walker, pContext);
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlan(pNode->pConditions, order, walker, pContext);
  }
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlans(pNode->pChildren, order, walker, pContext);
  }
  return res;
}

static EDealRes walkScanPhysi(SScanPhysiNode* pScan, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  EDealRes res = walkPhysiNode((SPhysiNode*)pScan, order, walker, pContext);
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlans(pScan->pScanCols, order, walker, pContext);
  }
  return res;
}

X
Xiaoyu Wang 已提交
419 420
static EDealRes walkTableScanPhysi(STableScanPhysiNode* pScan, ETraversalOrder order, FNodeWalker walker,
                                   void* pContext) {
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
  EDealRes res = walkScanPhysi((SScanPhysiNode*)pScan, order, walker, pContext);
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlans(pScan->pDynamicScanFuncs, order, walker, pContext);
  }
  return res;
}

static EDealRes walkWindowPhysi(SWinodwPhysiNode* pWindow, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  EDealRes res = walkPhysiNode((SPhysiNode*)pWindow, order, walker, pContext);
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlans(pWindow->pExprs, order, walker, pContext);
  }
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlans(pWindow->pFuncs, order, walker, pContext);
  }
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
    res = walkPhysiPlan(pWindow->pTspk, order, walker, pContext);
  }
  return res;
}

static EDealRes dispatchPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  EDealRes res = DEAL_RES_CONTINUE;

  switch (nodeType(pNode)) {
D
dapan1121 已提交
446 447 448
    case QUERY_NODE_NODE_LIST:
      res = walkPhysiPlans(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext);
      break;
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
      res = walkScanPhysi((SScanPhysiNode*)pNode, order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
      res = walkTableScanPhysi((STableScanPhysiNode*)pNode, order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
      res = walkTableScanPhysi((STableScanPhysiNode*)pNode, order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
      res = walkScanPhysi((SScanPhysiNode*)pNode, order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
      res = walkScanPhysi((SScanPhysiNode*)pNode, order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
      SProjectPhysiNode* pProject = (SProjectPhysiNode*)pNode;
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pProject->pProjections, order, walker, pContext);
      }
      break;
    }
472
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
473
      SSortMergeJoinPhysiNode* pJoin = (SSortMergeJoinPhysiNode*)pNode;
474
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
475 476 477
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlan(pJoin->pMergeCondition, order, walker, pContext);
      }
478 479 480 481 482 483 484 485
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlan(pJoin->pOnConditions, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pJoin->pTargets, order, walker, pContext);
      }
      break;
    }
486
    case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
      SAggPhysiNode* pAgg = (SAggPhysiNode*)pNode;
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pAgg->pExprs, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pAgg->pGroupKeys, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pAgg->pAggFuncs, order, walker, pContext);
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pNode;
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pExchange->pSrcEndPoints, order, walker, pContext);
      }
      break;
    }
508 509
    case QUERY_NODE_PHYSICAL_PLAN_SORT:
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
510 511 512 513 514 515 516 517 518 519 520 521 522
      SSortPhysiNode* pSort = (SSortPhysiNode*)pNode;
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pSort->pExprs, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pSort->pSortKeys, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pSort->pTargets, order, walker, pContext);
      }
      break;
    }
X
Xiaoyu Wang 已提交
523
    case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL:
X
Xiaoyu Wang 已提交
524
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
525 526
      res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
      break;
527 528
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION:
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION:
529 530
      res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
      break;
531 532
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE:
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: {
533 534 535 536 537 538 539
      SStateWinodwPhysiNode* pState = (SStateWinodwPhysiNode*)pNode;
      res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlan(pState->pStateKey, order, walker, pContext);
      }
      break;
    }
540 541
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: {
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
      SPartitionPhysiNode* pPart = (SPartitionPhysiNode*)pNode;
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pPart->pExprs, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pPart->pPartitionKeys, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlans(pPart->pTargets, order, walker, pContext);
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
      res = walkPhysiPlan((SNode*)(((SDataSinkNode*)pNode)->pInputDataBlockDesc), order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_INSERT:
      res = walkPhysiPlan((SNode*)(((SDataSinkNode*)pNode)->pInputDataBlockDesc), order, walker, pContext);
      break;
    case QUERY_NODE_PHYSICAL_SUBPLAN: {
      SSubplan* pSubplan = (SSubplan*)pNode;
D
dapan1121 已提交
563
      res = walkPhysiPlans(pSubplan->pChildren, order, walker, pContext);
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlan((SNode*)pSubplan->pNode, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlan((SNode*)pSubplan->pDataSink, order, walker, pContext);
      }
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN: {
      SQueryPlan* pPlan = (SQueryPlan*)pNode;
      if (NULL != pPlan->pSubplans) {
        // only need to walk the top-level subplans, because they will recurse to all the subplans below
        walkPhysiPlan(nodesListGetNode(pPlan->pSubplans, 0), order, walker, pContext);
      }
      break;
    }
    default:
      res = dispatchExpr(pNode, order, walker, pContext);
      break;
  }

  return res;
}

static EDealRes walkPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  return walkNode(pNode, order, walker, pContext, dispatchPhysiPlan);
}

static EDealRes walkPhysiPlans(SNodeList* pNodeList, ETraversalOrder order, FNodeWalker walker, void* pContext) {
  SNode* node;
  FOREACH(node, pNodeList) {
    EDealRes res = walkPhysiPlan(node, order, walker, pContext);
    if (DEAL_RES_ERROR == res || DEAL_RES_END == res) {
      return res;
    }
  }
  return DEAL_RES_CONTINUE;
}

void nodesWalkPhysiPlan(SNode* pNode, FNodeWalker walker, void* pContext) {
  (void)walkPhysiPlan(pNode, TRAVERSAL_PREORDER, walker, pContext);
}