nodesTraverseFuncs.c 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * 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/>.
 */

#include "nodes.h"

18 19 20 21
typedef enum ETraversalOrder {
  TRAVERSAL_PREORDER = 1,
  TRAVERSAL_POSTORDER
} ETraversalOrder;
22

23
static bool walkList(SNodeList* pNodeList, ETraversalOrder order, FQueryNodeWalker walker, void* pContext);
24

25
static bool walkNode(SNode* pNode, ETraversalOrder order, FQueryNodeWalker walker, void* pContext) {
26 27 28 29
  if (NULL == pNode) {
    return true;
  }

30
  if (TRAVERSAL_PREORDER == order && !walker(pNode, pContext)) {
31 32 33
    return false;
  }

34
  bool res = true;
35 36 37
  switch (nodeType(pNode)) {
    case QUERY_NODE_COLUMN:
    case QUERY_NODE_VALUE:
38
    case QUERY_NODE_LIMIT:
39
      // these node types with no subnodes
40
      break;
41 42
    case QUERY_NODE_OPERATOR: {
      SOperatorNode* pOpNode = (SOperatorNode*)pNode;
43 44 45
      res = walkNode(pOpNode->pLeft, order, walker, pContext);
      if (res) {
        res = walkNode(pOpNode->pRight, order, walker, pContext);
46
      }
47
      break;
48 49
    }
    case QUERY_NODE_LOGIC_CONDITION:
50 51
      res = walkList(((SLogicConditionNode*)pNode)->pParameterList, order, walker, pContext);
      break;
52
    case QUERY_NODE_IS_NULL_CONDITION:
53 54
      res = walkNode(((SIsNullCondNode*)pNode)->pExpr, order, walker, pContext);
      break;
55
    case QUERY_NODE_FUNCTION:
56 57
      res = walkList(((SFunctionNode*)pNode)->pParameterList, order, walker, pContext);
      break;
58 59
    case QUERY_NODE_REAL_TABLE:
    case QUERY_NODE_TEMP_TABLE:
60
      break; // todo
61 62
    case QUERY_NODE_JOIN_TABLE: {
      SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;
63 64 65
      res = walkNode(pJoinTableNode->pLeft, order, walker, pContext);
      if (res) {
        res = walkNode(pJoinTableNode->pRight, order, walker, pContext);
66
      }
67 68
      if (res) {
        res = walkNode(pJoinTableNode->pOnCond, order, walker, pContext);
69
      }
70
      break;
71 72
    }
    case QUERY_NODE_GROUPING_SET:
73 74
      res = walkList(((SGroupingSetNode*)pNode)->pParameterList, order, walker, pContext);
      break;
75
    case QUERY_NODE_ORDER_BY_EXPR:
76 77
      res = walkNode(((SOrderByExprNode*)pNode)->pExpr, order, walker, pContext);
      break;
78 79 80 81
    default:
      break;
  }

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  if (res && TRAVERSAL_POSTORDER == order) {
    res = walker(pNode, pContext);
  }

  return res;
}

static bool walkList(SNodeList* pNodeList, ETraversalOrder order, FQueryNodeWalker walker, void* pContext) {
  SNode* node;
  FOREACH(node, pNodeList) {
    if (!walkNode(node, order, walker, pContext)) {
      return false;
    }
  }
  return true;
}

void nodesWalkNode(SNode* pNode, FQueryNodeWalker walker, void* pContext) {
  (void)walkNode(pNode, TRAVERSAL_PREORDER, walker, pContext);
}

void nodesWalkList(SNodeList* pNodeList, FQueryNodeWalker walker, void* pContext) {
  (void)walkList(pNodeList, TRAVERSAL_PREORDER, walker, pContext);
}

void nodesWalkNodePostOrder(SNode* pNode, FQueryNodeWalker walker, void* pContext) {
  (void)walkNode(pNode, TRAVERSAL_POSTORDER, walker, pContext);
}

void nodesWalkListPostOrder(SNodeList* pList, FQueryNodeWalker walker, void* pContext) {
  (void)walkList(pList, TRAVERSAL_PREORDER, walker, pContext);
113 114
}

115
bool nodesWalkStmt(SNode* pNode, FQueryNodeWalker walker, void* pContext) {
116 117

}