nodes.h 4.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * 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/>.
 */

#ifndef _TD_NODES_H_
#define _TD_NODES_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "tdef.h"

25 26 27 28 29 30 31 32
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
#define setNodeType(nodeptr, type) (((SNode*)(nodeptr))->type = (type))

#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)

#define FOREACH(node, list)	\
  for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)

33
// only be use in FOREACH
34
#define ERASE_NODE(list) cell = nodesListErase(list, cell);
35 36 37

#define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode)

38 39 40 41 42
#define FORBOTH(node1, list1, node2, list2) \
  for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : NULL), *cell2 = (NULL != (list2) ? (list2)->pHead : NULL); \
    (NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), (NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), (node1 != NULL && node2 != NULL); \
    cell1 = cell1->pNext, cell2 = cell2->pNext)

43 44 45
#define FOREACH_FOR_REWRITE(node, list)	\
  for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext)

46
typedef enum ENodeType {
47
  // Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN, VALUE, OPERATOR, FUNCTION and so on.
48 49 50 51 52 53 54 55 56 57
  QUERY_NODE_COLUMN = 1,
  QUERY_NODE_VALUE,
  QUERY_NODE_OPERATOR,
  QUERY_NODE_LOGIC_CONDITION,
  QUERY_NODE_FUNCTION,
  QUERY_NODE_REAL_TABLE,
  QUERY_NODE_TEMP_TABLE,
  QUERY_NODE_JOIN_TABLE,
  QUERY_NODE_GROUPING_SET,
  QUERY_NODE_ORDER_BY_EXPR,
58
  QUERY_NODE_LIMIT,
59 60 61
  QUERY_NODE_STATE_WINDOW,
  QUERY_NODE_SESSION_WINDOW,
  QUERY_NODE_INTERVAL_WINDOW,
62 63
  QUERY_NODE_NODE_LIST,
  QUERY_NODE_FILL,
X
Xiaoyu Wang 已提交
64
  QUERY_NODE_RAW_EXPR, // Only be used in parser module.
X
Xiaoyu Wang 已提交
65
  QUERY_NODE_COLUMN_REF,
X
Xiaoyu Wang 已提交
66
  QUERY_NODE_TARGET,
X
Xiaoyu Wang 已提交
67 68
  QUERY_NODE_TUPLE_DESC,
  QUERY_NODE_SLOT_DESC,
69

70
  // Statement nodes are used in parser and planner module.
71
  QUERY_NODE_SET_OPERATOR,
72
  QUERY_NODE_SELECT_STMT,
X
Xiaoyu Wang 已提交
73 74
  QUERY_NODE_SHOW_STMT,

X
Xiaoyu Wang 已提交
75
  // logic plan node
X
Xiaoyu Wang 已提交
76
  QUERY_NODE_LOGIC_PLAN_SCAN,
X
Xiaoyu Wang 已提交
77 78
  QUERY_NODE_LOGIC_PLAN_JOIN,
  QUERY_NODE_LOGIC_PLAN_AGG,
X
Xiaoyu Wang 已提交
79 80 81 82 83 84
  QUERY_NODE_LOGIC_PLAN_PROJECT,

  // physical plan node
  QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN,
  QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN,
  QUERY_NODE_PHYSICAL_PLAN_PROJECT
85 86 87 88 89 90 91 92 93 94
} ENodeType;

/**
 * The first field of a node of any type is guaranteed to be the ENodeType.
 * Hence the type of any node can be gotten by casting it to SNode. 
 */
typedef struct SNode {
  ENodeType type;
} SNode;

95
typedef struct SListCell {
96
  struct SListCell* pPrev;
97
  struct SListCell* pNext;
98
  SNode* pNode;
99 100 101
} SListCell;

typedef struct SNodeList {
X
Xiaoyu Wang 已提交
102
  int32_t length;
103 104
  SListCell* pHead;
  SListCell* pTail;
105 106
} SNodeList;

107 108 109 110
SNode* nodesMakeNode(ENodeType type);
void nodesDestroyNode(SNode* pNode);

SNodeList* nodesMakeList();
X
Xiaoyu Wang 已提交
111
int32_t nodesListAppend(SNodeList* pList, SNode* pNode);
X
Xiaoyu Wang 已提交
112
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc);
113
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell);
114
SNode* nodesListGetNode(SNodeList* pList, int32_t index);
115 116
void nodesDestroyList(SNodeList* pList);

117 118 119 120 121
typedef enum EDealRes {
  DEAL_RES_CONTINUE = 1,
  DEAL_RES_IGNORE_CHILD,
  DEAL_RES_ERROR,
} EDealRes;
122

123 124 125 126 127 128 129 130 131 132 133
typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext);
void nodesWalkNode(SNode* pNode, FNodeWalker walker, void* pContext);
void nodesWalkList(SNodeList* pList, FNodeWalker walker, void* pContext);
void nodesWalkNodePostOrder(SNode* pNode, FNodeWalker walker, void* pContext);
void nodesWalkListPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext);

typedef EDealRes (*FNodeRewriter)(SNode** pNode, void* pContext);
void nodesRewriteNode(SNode** pNode, FNodeRewriter rewriter, void* pContext);
void nodesRewriteList(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
void nodesRewriteNodePostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext);
void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
134

135
bool nodesEqualNode(const SNode* a, const SNode* b);
136

X
Xiaoyu Wang 已提交
137 138
SNode* nodesCloneNode(const SNode* pNode);
SNodeList* nodesCloneList(const SNodeList* pList);
139

X
Xiaoyu Wang 已提交
140
int32_t nodesNodeToString(const SNode* pNode, bool format, char** pStr, int32_t* pLen);
141
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
142 143 144 145 146 147

#ifdef __cplusplus
}
#endif

#endif /*_TD_NODES_H_*/