nodesTraverseFuncs.c 24.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

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;
X
Xiaoyu Wang 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    case QUERY_NODE_WHEN_THEN: {
      SWhenThenNode* pWhenThen = (SWhenThenNode*)pNode;
      res = walkExpr(pWhenThen->pWhen, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkExpr(pWhenThen->pThen, order, walker, pContext);
      }
      break;
    }
    case QUERY_NODE_CASE_WHEN: {
      SCaseWhenNode* pCaseWhen = (SCaseWhenNode*)pNode;
      res = walkExpr(pCaseWhen->pCase, order, walker, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkExpr(pCaseWhen->pElse, order, walker, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkExprs(pCaseWhen->pWhenThenList, order, walker, pContext);
      }
      break;
    }
168 169 170 171
    default:
      break;
  }

172 173 174
  return res;
}

175 176 177 178 179
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) {
180 181
  SNode* node;
  FOREACH(node, pNodeList) {
182
    EDealRes res = walkExpr(node, order, walker, pContext);
183 184
    if (DEAL_RES_ERROR == res || DEAL_RES_END == res) {
      return res;
185 186
    }
  }
187
  return DEAL_RES_CONTINUE;
188 189
}

190
void nodesWalkExpr(SNode* pNode, FNodeWalker walker, void* pContext) {
191
  (void)walkExpr(pNode, TRAVERSAL_PREORDER, walker, pContext);
192 193
}

X
Xiaoyu Wang 已提交
194
void nodesWalkExprs(SNodeList* pNodeList, FNodeWalker walker, void* pContext) {
195
  (void)walkExprs(pNodeList, TRAVERSAL_PREORDER, walker, pContext);
196 197
}

198
void nodesWalkExprPostOrder(SNode* pNode, FNodeWalker walker, void* pContext) {
199
  (void)walkExpr(pNode, TRAVERSAL_POSTORDER, walker, pContext);
200 201
}

X
Xiaoyu Wang 已提交
202
void nodesWalkExprsPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext) {
203
  (void)walkExprs(pList, TRAVERSAL_POSTORDER, walker, pContext);
204
}
205

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

208
static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewriter rewriter, void* pContext) {
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
  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;
231
      res = rewriteExpr(&(pOpNode->pLeft), order, rewriter, pContext);
232
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
233
        res = rewriteExpr(&(pOpNode->pRight), order, rewriter, pContext);
234 235 236 237
      }
      break;
    }
    case QUERY_NODE_LOGIC_CONDITION:
238
      res = rewriteExprs(((SLogicConditionNode*)pNode)->pParameterList, order, rewriter, pContext);
239 240
      break;
    case QUERY_NODE_FUNCTION:
241
      res = rewriteExprs(((SFunctionNode*)pNode)->pParameterList, order, rewriter, pContext);
242 243 244
      break;
    case QUERY_NODE_REAL_TABLE:
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
245
      break;  // todo
246 247
    case QUERY_NODE_JOIN_TABLE: {
      SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;
248
      res = rewriteExpr(&(pJoinTableNode->pLeft), order, rewriter, pContext);
249
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
250
        res = rewriteExpr(&(pJoinTableNode->pRight), order, rewriter, pContext);
251
      }
252
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
253
        res = rewriteExpr(&(pJoinTableNode->pOnCond), order, rewriter, pContext);
254 255 256 257
      }
      break;
    }
    case QUERY_NODE_GROUPING_SET:
258
      res = rewriteExprs(((SGroupingSetNode*)pNode)->pParameterList, order, rewriter, pContext);
259 260
      break;
    case QUERY_NODE_ORDER_BY_EXPR:
261
      res = rewriteExpr(&(((SOrderByExprNode*)pNode)->pExpr), order, rewriter, pContext);
262
      break;
263 264
    case QUERY_NODE_STATE_WINDOW: {
      SStateWindowNode* pState = (SStateWindowNode*)pNode;
265
      res = rewriteExpr(&pState->pExpr, order, rewriter, pContext);
266
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
267
        res = rewriteExpr(&pState->pCol, order, rewriter, pContext);
268
      }
269
      break;
270 271 272
    }
    case QUERY_NODE_SESSION_WINDOW: {
      SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
273
      res = rewriteExpr((SNode**)&pSession->pCol, order, rewriter, pContext);
274
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
275
        res = rewriteExpr((SNode**)&pSession->pGap, order, rewriter, pContext);
276
      }
277
      break;
278
    }
279 280
    case QUERY_NODE_INTERVAL_WINDOW: {
      SIntervalWindowNode* pInterval = (SIntervalWindowNode*)pNode;
281
      res = rewriteExpr(&(pInterval->pInterval), order, rewriter, pContext);
282
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
283
        res = rewriteExpr(&(pInterval->pOffset), order, rewriter, pContext);
284
      }
285
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
286
        res = rewriteExpr(&(pInterval->pSliding), order, rewriter, pContext);
287
      }
288
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
289
        res = rewriteExpr(&(pInterval->pFill), order, rewriter, pContext);
290
      }
291
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
292
        res = rewriteExpr(&(pInterval->pCol), order, rewriter, pContext);
X
bugfix  
Xiaoyu Wang 已提交
293
      }
294 295 296
      break;
    }
    case QUERY_NODE_NODE_LIST:
297
      res = rewriteExprs(((SNodeListNode*)pNode)->pNodeList, order, rewriter, pContext);
298
      break;
X
Xiaoyu Wang 已提交
299 300 301 302 303 304
    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);
      }
305
      break;
X
Xiaoyu Wang 已提交
306
    }
307
    case QUERY_NODE_RAW_EXPR:
308
      res = rewriteExpr(&(((SRawExprNode*)pNode)->pNode), order, rewriter, pContext);
309
      break;
D
dapan1121 已提交
310
    case QUERY_NODE_TARGET:
311
      res = rewriteExpr(&(((STargetNode*)pNode)->pExpr), order, rewriter, pContext);
D
dapan1121 已提交
312
      break;
X
Xiaoyu Wang 已提交
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
    case QUERY_NODE_WHEN_THEN: {
      SWhenThenNode* pWhenThen = (SWhenThenNode*)pNode;
      res = rewriteExpr(&pWhenThen->pWhen, order, rewriter, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = rewriteExpr(&pWhenThen->pThen, order, rewriter, pContext);
      }
      break;
    }
    case QUERY_NODE_CASE_WHEN: {
      SCaseWhenNode* pCaseWhen = (SCaseWhenNode*)pNode;
      res = rewriteExpr(&pCaseWhen->pCase, order, rewriter, pContext);
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = rewriteExpr(&pCaseWhen->pElse, order, rewriter, pContext);
      }
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = rewriteExprs(pCaseWhen->pWhenThenList, order, rewriter, pContext);
      }
      break;
    }
332 333 334 335
    default:
      break;
  }

336
  if (DEAL_RES_ERROR != res && DEAL_RES_END != res && TRAVERSAL_POSTORDER == order) {
337 338 339 340 341 342
    res = rewriter(pRawNode, pContext);
  }

  return res;
}

343
static EDealRes rewriteExprs(SNodeList* pNodeList, ETraversalOrder order, FNodeRewriter rewriter, void* pContext) {
344 345
  SNode** pNode;
  FOREACH_FOR_REWRITE(pNode, pNodeList) {
346
    EDealRes res = rewriteExpr(pNode, order, rewriter, pContext);
347 348
    if (DEAL_RES_ERROR == res || DEAL_RES_END == res) {
      return res;
349 350 351 352 353
    }
  }
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
354
void nodesRewriteExpr(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
355
  (void)rewriteExpr(pNode, TRAVERSAL_PREORDER, rewriter, pContext);
356 357
}

X
Xiaoyu Wang 已提交
358
void nodesRewriteExprs(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
359
  (void)rewriteExprs(pList, TRAVERSAL_PREORDER, rewriter, pContext);
360 361
}

X
Xiaoyu Wang 已提交
362
void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
363
  (void)rewriteExpr(pNode, TRAVERSAL_POSTORDER, rewriter, pContext);
364 365
}

X
Xiaoyu Wang 已提交
366
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
367
  (void)rewriteExprs(pList, TRAVERSAL_POSTORDER, rewriter, pContext);
368
}
X
Xiaoyu Wang 已提交
369 370 371 372 373 374 375 376

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

  switch (clause) {
    case SQL_CLAUSE_FROM:
X
Xiaoyu Wang 已提交
377 378
      nodesWalkExpr(pSelect->pFromTable, walker, pContext);
      nodesWalkExpr(pSelect->pWhere, walker, pContext);
X
Xiaoyu Wang 已提交
379
    case SQL_CLAUSE_WHERE:
X
Xiaoyu Wang 已提交
380
      nodesWalkExprs(pSelect->pPartitionByList, walker, pContext);
381 382
      nodesWalkExprs(pSelect->pTags, walker, pContext);
      nodesWalkExpr(pSelect->pSubtable, walker, pContext);
X
Xiaoyu Wang 已提交
383
    case SQL_CLAUSE_PARTITION_BY:
X
Xiaoyu Wang 已提交
384
      nodesWalkExpr(pSelect->pWindow, walker, pContext);
X
Xiaoyu Wang 已提交
385
    case SQL_CLAUSE_WINDOW:
X
Xiaoyu Wang 已提交
386 387 388
      if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
        nodesWalkExpr(((SIntervalWindowNode*)pSelect->pWindow)->pFill, walker, pContext);
      }
389
    case SQL_CLAUSE_FILL:
X
Xiaoyu Wang 已提交
390
      nodesWalkExprs(pSelect->pGroupByList, walker, pContext);
X
Xiaoyu Wang 已提交
391
    case SQL_CLAUSE_GROUP_BY:
X
Xiaoyu Wang 已提交
392
      nodesWalkExpr(pSelect->pHaving, walker, pContext);
X
Xiaoyu Wang 已提交
393
    case SQL_CLAUSE_HAVING:
394
    case SQL_CLAUSE_SELECT:
X
Xiaoyu Wang 已提交
395
    case SQL_CLAUSE_DISTINCT:
396
      nodesWalkExprs(pSelect->pOrderByList, walker, pContext);
X
Xiaoyu Wang 已提交
397
    case SQL_CLAUSE_ORDER_BY:
X
Xiaoyu Wang 已提交
398
      nodesWalkExprs(pSelect->pProjectionList, walker, pContext);
X
Xiaoyu Wang 已提交
399 400 401 402 403 404 405 406 407 408 409 410 411 412
    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 已提交
413 414
      nodesRewriteExpr(&(pSelect->pFromTable), rewriter, pContext);
      nodesRewriteExpr(&(pSelect->pWhere), rewriter, pContext);
X
Xiaoyu Wang 已提交
415
    case SQL_CLAUSE_WHERE:
X
Xiaoyu Wang 已提交
416
      nodesRewriteExprs(pSelect->pPartitionByList, rewriter, pContext);
417 418
      nodesRewriteExprs(pSelect->pTags, rewriter, pContext);
      nodesRewriteExpr(&(pSelect->pSubtable), rewriter, pContext);
X
Xiaoyu Wang 已提交
419
    case SQL_CLAUSE_PARTITION_BY:
X
Xiaoyu Wang 已提交
420
      nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext);
X
Xiaoyu Wang 已提交
421
    case SQL_CLAUSE_WINDOW:
X
Xiaoyu Wang 已提交
422 423 424
      if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
        nodesRewriteExpr(&(((SIntervalWindowNode*)pSelect->pWindow)->pFill), rewriter, pContext);
      }
425
    case SQL_CLAUSE_FILL:
X
Xiaoyu Wang 已提交
426
      nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext);
X
Xiaoyu Wang 已提交
427
    case SQL_CLAUSE_GROUP_BY:
X
Xiaoyu Wang 已提交
428
      nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext);
X
Xiaoyu Wang 已提交
429
    case SQL_CLAUSE_HAVING:
430
    case SQL_CLAUSE_SELECT:
X
Xiaoyu Wang 已提交
431
    case SQL_CLAUSE_DISTINCT:
X
Xiaoyu Wang 已提交
432
      nodesRewriteExprs(pSelect->pOrderByList, rewriter, pContext);
X
Xiaoyu Wang 已提交
433
    case SQL_CLAUSE_ORDER_BY:
X
Xiaoyu Wang 已提交
434
      nodesRewriteExprs(pSelect->pProjectionList, rewriter, pContext);
X
Xiaoyu Wang 已提交
435 436 437 438 439 440
    default:
      break;
  }

  return;
}
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460

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 已提交
461 462
static EDealRes walkTableScanPhysi(STableScanPhysiNode* pScan, ETraversalOrder order, FNodeWalker walker,
                                   void* pContext) {
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
  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 已提交
488 489 490
    case QUERY_NODE_NODE_LIST:
      res = walkPhysiPlans(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext);
      break;
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
    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;
    }
514
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
515
      SSortMergeJoinPhysiNode* pJoin = (SSortMergeJoinPhysiNode*)pNode;
516
      res = walkPhysiNode((SPhysiNode*)pNode, order, walker, pContext);
517 518 519
      if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
        res = walkPhysiPlan(pJoin->pMergeCondition, order, walker, pContext);
      }
520 521 522 523 524 525 526 527
      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;
    }
528
    case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
      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;
    }
550 551
    case QUERY_NODE_PHYSICAL_PLAN_SORT:
    case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
552 553 554 555 556 557 558 559 560 561 562 563 564
      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 已提交
565
    case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL:
X
Xiaoyu Wang 已提交
566
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
567 568
      res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
      break;
569 570
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION:
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION:
571 572
      res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
      break;
573 574
    case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE:
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: {
575 576 577 578 579 580 581
      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;
    }
582 583
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: {
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
      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 已提交
605
      res = walkPhysiPlans(pSubplan->pChildren, order, walker, pContext);
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
      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);
}