nodesTraverseFuncs.c 4.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 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
    case QUERY_NODE_STATE_WINDOW:
      res = walkNode(((SStateWindowNode*)pNode)->pCol, order, walker, pContext);
      break;
    case QUERY_NODE_SESSION_WINDOW:
      res = walkNode(((SSessionWindowNode*)pNode)->pCol, order, walker, pContext);
      break;
    case QUERY_NODE_INTERVAL_WINDOW: {
      SIntervalWindowNode* pInterval = (SIntervalWindowNode*)pNode;
      res = walkNode(pInterval->pInterval, order, walker, pContext);
      if (res) {
        res = walkNode(pInterval->pOffset, order, walker, pContext);
      }
      if (res) {
        res = walkNode(pInterval->pSliding, order, walker, pContext);
      }
      if (res) {
        res = walkNode(pInterval->pFill, order, walker, pContext);
      }
      break;
    }
    case QUERY_NODE_NODE_LIST:
      res = walkList(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext);
      break;
    case QUERY_NODE_FILL:
      res = walkNode(((SFillNode*)pNode)->pValues, order, walker, pContext);
      break;
    case QUERY_NODE_RAW_EXPR:
      res = walkNode(((SRawExprNode*)pNode)->pNode, order, walker, pContext);
      break;
107 108 109 110
    default:
      break;
  }

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
  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) {
141
  (void)walkList(pList, TRAVERSAL_POSTORDER, walker, pContext);
142 143
}

144
bool nodesWalkStmt(SNode* pNode, FQueryNodeWalker walker, void* pContext) {
145 146

}