nodesUtilFuncs.c 39.5 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 "cmdnodes.h"
X
Xiaoyu Wang 已提交
17
#include "nodesUtil.h"
X
Xiaoyu Wang 已提交
18
#include "plannodes.h"
19
#include "querynodes.h"
X
Xiaoyu Wang 已提交
20
#include "taos.h"
21
#include "taoserror.h"
X
Xiaoyu Wang 已提交
22
#include "thash.h"
23

24
static SNode* makeNode(ENodeType type, size_t size) {
wafwerar's avatar
wafwerar 已提交
25
  SNode* p = taosMemoryCalloc(1, size);
26 27 28
  if (NULL == p) {
    return NULL;
  }
29 30 31
  setNodeType(p, type);
  return p;
}
32

X
Xiaoyu Wang 已提交
33
SNodeptr nodesMakeNode(ENodeType type) {
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
  switch (type) {
    case QUERY_NODE_COLUMN:
      return makeNode(type, sizeof(SColumnNode));
    case QUERY_NODE_VALUE:
      return makeNode(type, sizeof(SValueNode));
    case QUERY_NODE_OPERATOR:
      return makeNode(type, sizeof(SOperatorNode));
    case QUERY_NODE_LOGIC_CONDITION:
      return makeNode(type, sizeof(SLogicConditionNode));
    case QUERY_NODE_FUNCTION:
      return makeNode(type, sizeof(SFunctionNode));
    case QUERY_NODE_REAL_TABLE:
      return makeNode(type, sizeof(SRealTableNode));
    case QUERY_NODE_TEMP_TABLE:
      return makeNode(type, sizeof(STempTableNode));
    case QUERY_NODE_JOIN_TABLE:
      return makeNode(type, sizeof(SJoinTableNode));
    case QUERY_NODE_GROUPING_SET:
      return makeNode(type, sizeof(SGroupingSetNode));
    case QUERY_NODE_ORDER_BY_EXPR:
      return makeNode(type, sizeof(SOrderByExprNode));
    case QUERY_NODE_LIMIT:
      return makeNode(type, sizeof(SLimitNode));
    case QUERY_NODE_STATE_WINDOW:
      return makeNode(type, sizeof(SStateWindowNode));
    case QUERY_NODE_SESSION_WINDOW:
      return makeNode(type, sizeof(SSessionWindowNode));
    case QUERY_NODE_INTERVAL_WINDOW:
      return makeNode(type, sizeof(SIntervalWindowNode));
63 64 65 66 67 68
    case QUERY_NODE_NODE_LIST:
      return makeNode(type, sizeof(SNodeListNode));
    case QUERY_NODE_FILL:
      return makeNode(type, sizeof(SFillNode));
    case QUERY_NODE_RAW_EXPR:
      return makeNode(type, sizeof(SRawExprNode));
69 70 71 72 73 74 75 76
    case QUERY_NODE_TARGET:
      return makeNode(type, sizeof(STargetNode));
    case QUERY_NODE_DATABLOCK_DESC:
      return makeNode(type, sizeof(SDataBlockDescNode));
    case QUERY_NODE_SLOT_DESC:
      return makeNode(type, sizeof(SSlotDescNode));
    case QUERY_NODE_COLUMN_DEF:
      return makeNode(type, sizeof(SColumnDefNode));
X
Xiaoyu Wang 已提交
77 78
    case QUERY_NODE_DOWNSTREAM_SOURCE:
      return makeNode(type, sizeof(SDownstreamSourceNode));
X
Xiaoyu Wang 已提交
79 80 81 82 83 84
    case QUERY_NODE_DATABASE_OPTIONS:
      return makeNode(type, sizeof(SDatabaseOptions));
    case QUERY_NODE_TABLE_OPTIONS:
      return makeNode(type, sizeof(STableOptions));
    case QUERY_NODE_INDEX_OPTIONS:
      return makeNode(type, sizeof(SIndexOptions));
85 86
    case QUERY_NODE_EXPLAIN_OPTIONS:
      return makeNode(type, sizeof(SExplainOptions));
87 88
    case QUERY_NODE_STREAM_OPTIONS:
      return makeNode(type, sizeof(SStreamOptions));
X
Xiaoyu Wang 已提交
89 90
    case QUERY_NODE_TOPIC_OPTIONS:
      return makeNode(type, sizeof(STopicOptions));
91 92 93 94
    case QUERY_NODE_SET_OPERATOR:
      return makeNode(type, sizeof(SSetOperator));
    case QUERY_NODE_SELECT_STMT:
      return makeNode(type, sizeof(SSelectStmt));
95 96 97 98
    case QUERY_NODE_VNODE_MODIF_STMT:
      return makeNode(type, sizeof(SVnodeModifOpStmt));
    case QUERY_NODE_CREATE_DATABASE_STMT:
      return makeNode(type, sizeof(SCreateDatabaseStmt));
99
    case QUERY_NODE_DROP_DATABASE_STMT:
X
Xiaoyu Wang 已提交
100
      return makeNode(type, sizeof(SDropDatabaseStmt));
101 102
    case QUERY_NODE_ALTER_DATABASE_STMT:
      return makeNode(type, sizeof(SAlterDatabaseStmt));
103 104
    case QUERY_NODE_CREATE_TABLE_STMT:
      return makeNode(type, sizeof(SCreateTableStmt));
105 106
    case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
      return makeNode(type, sizeof(SCreateSubTableClause));
107 108
    case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
      return makeNode(type, sizeof(SCreateMultiTableStmt));
109 110 111 112
    case QUERY_NODE_DROP_TABLE_CLAUSE:
      return makeNode(type, sizeof(SDropTableClause));
    case QUERY_NODE_DROP_TABLE_STMT:
      return makeNode(type, sizeof(SDropTableStmt));
113 114
    case QUERY_NODE_DROP_SUPER_TABLE_STMT:
      return makeNode(type, sizeof(SDropSuperTableStmt));
115 116 117 118 119 120
    case QUERY_NODE_CREATE_USER_STMT:
      return makeNode(type, sizeof(SCreateUserStmt));
    case QUERY_NODE_ALTER_USER_STMT:
      return makeNode(type, sizeof(SAlterUserStmt));
    case QUERY_NODE_DROP_USER_STMT:
      return makeNode(type, sizeof(SDropUserStmt));
121 122
    case QUERY_NODE_USE_DATABASE_STMT:
      return makeNode(type, sizeof(SUseDatabaseStmt));
123 124 125 126
    case QUERY_NODE_CREATE_DNODE_STMT:
      return makeNode(type, sizeof(SCreateDnodeStmt));
    case QUERY_NODE_DROP_DNODE_STMT:
      return makeNode(type, sizeof(SDropDnodeStmt));
127 128
    case QUERY_NODE_ALTER_DNODE_STMT:
      return makeNode(type, sizeof(SAlterDnodeStmt));
X
Xiaoyu Wang 已提交
129 130
    case QUERY_NODE_CREATE_INDEX_STMT:
      return makeNode(type, sizeof(SCreateIndexStmt));
131 132
    case QUERY_NODE_DROP_INDEX_STMT:
      return makeNode(type, sizeof(SDropIndexStmt));
X
Xiaoyu Wang 已提交
133
    case QUERY_NODE_CREATE_QNODE_STMT:
134 135 136 137
    case QUERY_NODE_CREATE_BNODE_STMT:
    case QUERY_NODE_CREATE_SNODE_STMT:
    case QUERY_NODE_CREATE_MNODE_STMT:
      return makeNode(type, sizeof(SCreateComponentNodeStmt));
138
    case QUERY_NODE_DROP_QNODE_STMT:
139 140 141 142
    case QUERY_NODE_DROP_BNODE_STMT:
    case QUERY_NODE_DROP_SNODE_STMT:
    case QUERY_NODE_DROP_MNODE_STMT:
      return makeNode(type, sizeof(SDropComponentNodeStmt));
143 144 145 146
    case QUERY_NODE_CREATE_TOPIC_STMT:
      return makeNode(type, sizeof(SCreateTopicStmt));
    case QUERY_NODE_DROP_TOPIC_STMT:
      return makeNode(type, sizeof(SDropTopicStmt));
147 148
    case QUERY_NODE_EXPLAIN_STMT:
      return makeNode(type, sizeof(SExplainStmt));
149 150 151 152
    case QUERY_NODE_DESCRIBE_STMT:
      return makeNode(type, sizeof(SDescribeStmt));
    case QUERY_NODE_RESET_QUERY_CACHE_STMT:
      return makeNode(type, sizeof(SNode));
153
    case QUERY_NODE_COMPACT_STMT:
154
      break;
155
    case QUERY_NODE_CREATE_FUNCTION_STMT:
156
      return makeNode(type, sizeof(SCreateFunctionStmt));
157 158 159 160 161 162 163 164 165 166 167
    case QUERY_NODE_DROP_FUNCTION_STMT:
      break;
    case QUERY_NODE_CREATE_STREAM_STMT:
      return makeNode(type, sizeof(SCreateStreamStmt));
    case QUERY_NODE_DROP_STREAM_STMT:
      return makeNode(type, sizeof(SDropStreamStmt));
    case QUERY_NODE_MERGE_VGROUP_STMT:
    case QUERY_NODE_REDISTRIBUTE_VGROUP_STMT:
    case QUERY_NODE_SPLIT_VGROUP_STMT:
    case QUERY_NODE_SYNCDB_STMT:
      break;
168
    case QUERY_NODE_SHOW_DNODES_STMT:
X
Xiaoyu Wang 已提交
169
    case QUERY_NODE_SHOW_MNODES_STMT:
X
Xiaoyu Wang 已提交
170 171
    case QUERY_NODE_SHOW_MODULES_STMT:
    case QUERY_NODE_SHOW_QNODES_STMT:
172 173
    case QUERY_NODE_SHOW_SNODES_STMT:
    case QUERY_NODE_SHOW_BNODES_STMT:
174
    case QUERY_NODE_SHOW_CLUSTER_STMT:
175
    case QUERY_NODE_SHOW_DATABASES_STMT:
X
Xiaoyu Wang 已提交
176 177
    case QUERY_NODE_SHOW_FUNCTIONS_STMT:
    case QUERY_NODE_SHOW_INDEXES_STMT:
178
    case QUERY_NODE_SHOW_STABLES_STMT:
X
Xiaoyu Wang 已提交
179
    case QUERY_NODE_SHOW_STREAMS_STMT:
180 181
    case QUERY_NODE_SHOW_TABLES_STMT:
    case QUERY_NODE_SHOW_USERS_STMT:
S
Shengliang Guan 已提交
182
    case QUERY_NODE_SHOW_LICENCE_STMT:
183
    case QUERY_NODE_SHOW_VGROUPS_STMT:
S
Shengliang Guan 已提交
184
    case QUERY_NODE_SHOW_TOPICS_STMT:
185 186 187 188 189 190 191
    case QUERY_NODE_SHOW_CONSUMERS_STMT:
    case QUERY_NODE_SHOW_SUBSCRIBES_STMT:
    case QUERY_NODE_SHOW_TRANS_STMT:
    case QUERY_NODE_SHOW_SMAS_STMT:
    case QUERY_NODE_SHOW_CONFIGS_STMT:
    case QUERY_NODE_SHOW_QUERIES_STMT:
    case QUERY_NODE_SHOW_VNODES_STMT:
192 193 194 195 196 197
    case QUERY_NODE_SHOW_APPS_STMT:
    case QUERY_NODE_SHOW_SCORES_STMT:
    case QUERY_NODE_SHOW_VARIABLE_STMT:
    case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
    case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
    case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
198
      return makeNode(type, sizeof(SShowStmt));
199 200 201
    case QUERY_NODE_KILL_CONNECTION_STMT:
    case QUERY_NODE_KILL_QUERY_STMT:
      return makeNode(type, sizeof(SKillStmt));
X
Xiaoyu Wang 已提交
202 203 204 205 206 207 208 209
    case QUERY_NODE_LOGIC_PLAN_SCAN:
      return makeNode(type, sizeof(SScanLogicNode));
    case QUERY_NODE_LOGIC_PLAN_JOIN:
      return makeNode(type, sizeof(SJoinLogicNode));
    case QUERY_NODE_LOGIC_PLAN_AGG:
      return makeNode(type, sizeof(SAggLogicNode));
    case QUERY_NODE_LOGIC_PLAN_PROJECT:
      return makeNode(type, sizeof(SProjectLogicNode));
210 211
    case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
      return makeNode(type, sizeof(SVnodeModifLogicNode));
X
Xiaoyu Wang 已提交
212 213
    case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
      return makeNode(type, sizeof(SExchangeLogicNode));
X
Xiaoyu Wang 已提交
214 215
    case QUERY_NODE_LOGIC_PLAN_WINDOW:
      return makeNode(type, sizeof(SWindowLogicNode));
X
Xiaoyu Wang 已提交
216 217
    case QUERY_NODE_LOGIC_PLAN_SORT:
      return makeNode(type, sizeof(SSortLogicNode));
218 219
    case QUERY_NODE_LOGIC_PLAN_PARTITION:
      return makeNode(type, sizeof(SPartitionLogicNode));
X
Xiaoyu Wang 已提交
220
    case QUERY_NODE_LOGIC_SUBPLAN:
X
Xiaoyu Wang 已提交
221
      return makeNode(type, sizeof(SLogicSubplan));
X
Xiaoyu Wang 已提交
222 223
    case QUERY_NODE_LOGIC_PLAN:
      return makeNode(type, sizeof(SQueryLogicPlan));
X
Xiaoyu Wang 已提交
224 225 226 227
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
      return makeNode(type, sizeof(STagScanPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
      return makeNode(type, sizeof(STableScanPhysiNode));
228 229 230
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
      return makeNode(type, sizeof(STableSeqScanPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
X
Xiaoyu Wang 已提交
231
      return makeNode(type, sizeof(SStreamScanPhysiNode));
X
Xiaoyu Wang 已提交
232 233
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
      return makeNode(type, sizeof(SSystemTableScanPhysiNode));
X
Xiaoyu Wang 已提交
234 235
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
      return makeNode(type, sizeof(SProjectPhysiNode));
X
Xiaoyu Wang 已提交
236 237 238 239
    case QUERY_NODE_PHYSICAL_PLAN_JOIN:
      return makeNode(type, sizeof(SJoinPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_AGG:
      return makeNode(type, sizeof(SAggPhysiNode));
240 241 242
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
      return makeNode(type, sizeof(SExchangePhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_SORT:
X
Xiaoyu Wang 已提交
243
      return makeNode(type, sizeof(SSortPhysiNode));
X
Xiaoyu Wang 已提交
244 245
    case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
      return makeNode(type, sizeof(SIntervalPhysiNode));
246 247
    case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
      return makeNode(type, sizeof(SSessionWinodwPhysiNode));
248 249 250 251
    case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
      return makeNode(type, sizeof(SStateWinodwPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
      return makeNode(type, sizeof(SPartitionPhysiNode));
252 253 254 255
    case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
      return makeNode(type, sizeof(SDataDispatcherNode));
    case QUERY_NODE_PHYSICAL_PLAN_INSERT:
      return makeNode(type, sizeof(SDataInserterNode));
X
Xiaoyu Wang 已提交
256 257 258 259
    case QUERY_NODE_PHYSICAL_SUBPLAN:
      return makeNode(type, sizeof(SSubplan));
    case QUERY_NODE_PHYSICAL_PLAN:
      return makeNode(type, sizeof(SQueryPlan));
260 261 262
    default:
      break;
  }
263
  nodesError("nodesMakeNode unknown node = %s", nodesNodeName(type));
264
  return NULL;
265 266
}

X
Xiaoyu Wang 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
static void destroyVgDataBlockArray(SArray* pArray) {
  size_t size = taosArrayGetSize(pArray);
  for (size_t i = 0; i < size; ++i) {
    SVgDataBlocks* pVg = taosArrayGetP(pArray, i);
    taosMemoryFreeClear(pVg->pData);
    taosMemoryFreeClear(pVg);
  }
  taosArrayDestroy(pArray);
}

static void destroyLogicNode(SLogicNode* pNode) {
  nodesDestroyList(pNode->pChildren);
  nodesDestroyNode(pNode->pConditions);
  nodesDestroyList(pNode->pTargets);
}

static void destroyPhysiNode(SPhysiNode* pNode) {
  nodesDestroyList(pNode->pChildren);
  nodesDestroyNode(pNode->pConditions);
  nodesDestroyNode(pNode->pOutputDataBlockDesc);
}

static void destroyWinodwPhysiNode(SWinodwPhysiNode* pNode) {
  destroyPhysiNode((SPhysiNode*)pNode);
  nodesDestroyList(pNode->pExprs);
  nodesDestroyList(pNode->pFuncs);
293
  nodesDestroyNode(pNode->pTspk);
X
Xiaoyu Wang 已提交
294 295 296 297 298 299 300
}

static void destroyScanPhysiNode(SScanPhysiNode* pNode) {
  destroyPhysiNode((SPhysiNode*)pNode);
  nodesDestroyList(pNode->pScanCols);
}

X
Xiaoyu Wang 已提交
301
static void destroyDataSinkNode(SDataSinkNode* pNode) { nodesDestroyNode(pNode->pInputDataBlockDesc); }
X
Xiaoyu Wang 已提交
302 303 304 305 306 307 308

void nodesDestroyNode(SNodeptr pNode) {
  if (NULL == pNode) {
    return;
  }

  switch (nodeType(pNode)) {
X
Xiaoyu Wang 已提交
309
    case QUERY_NODE_COLUMN:  // pProjectRef is weak reference, no need to release
X
Xiaoyu Wang 已提交
310
      break;
D
dapan1121 已提交
311
    case QUERY_NODE_VALUE: {
X
Xiaoyu Wang 已提交
312
      SValueNode* pValue = (SValueNode*)pNode;
wafwerar's avatar
wafwerar 已提交
313
      taosMemoryFreeClear(pValue->literal);
D
dapan1121 已提交
314
      if (IS_VAR_DATA_TYPE(pValue->node.resType.type)) {
wafwerar's avatar
wafwerar 已提交
315
        taosMemoryFreeClear(pValue->datum.p);
D
dapan1121 已提交
316
      }
X
Xiaoyu Wang 已提交
317 318 319 320 321 322
      break;
    }
    case QUERY_NODE_OPERATOR: {
      SOperatorNode* pOp = (SOperatorNode*)pNode;
      nodesDestroyNode(pOp->pLeft);
      nodesDestroyNode(pOp->pRight);
D
dapan1121 已提交
323 324 325
      break;
    }
    case QUERY_NODE_LOGIC_CONDITION:
X
Xiaoyu Wang 已提交
326
      nodesDestroyList(((SLogicConditionNode*)pNode)->pParameterList);
D
dapan1121 已提交
327 328
      break;
    case QUERY_NODE_FUNCTION:
X
Xiaoyu Wang 已提交
329
      nodesDestroyList(((SFunctionNode*)pNode)->pParameterList);
X
Xiaoyu Wang 已提交
330 331
      break;
    case QUERY_NODE_REAL_TABLE: {
X
Xiaoyu Wang 已提交
332
      SRealTableNode* pReal = (SRealTableNode*)pNode;
wafwerar's avatar
wafwerar 已提交
333 334
      taosMemoryFreeClear(pReal->pMeta);
      taosMemoryFreeClear(pReal->pVgroupList);
X
Xiaoyu Wang 已提交
335 336 337
      break;
    }
    case QUERY_NODE_TEMP_TABLE:
X
Xiaoyu Wang 已提交
338
      nodesDestroyNode(((STempTableNode*)pNode)->pSubquery);
D
dapan1121 已提交
339
      break;
X
Xiaoyu Wang 已提交
340 341 342 343 344
    case QUERY_NODE_JOIN_TABLE: {
      SJoinTableNode* pJoin = (SJoinTableNode*)pNode;
      nodesDestroyNode(pJoin->pLeft);
      nodesDestroyNode(pJoin->pRight);
      nodesDestroyNode(pJoin->pOnCond);
D
dapan1121 已提交
345
      break;
X
Xiaoyu Wang 已提交
346
    }
D
dapan1121 已提交
347
    case QUERY_NODE_GROUPING_SET:
X
Xiaoyu Wang 已提交
348 349 350 351 352
      nodesDestroyList(((SGroupingSetNode*)pNode)->pParameterList);
      break;
    case QUERY_NODE_ORDER_BY_EXPR:
      nodesDestroyNode(((SOrderByExprNode*)pNode)->pExpr);
      break;
X
Xiaoyu Wang 已提交
353
    case QUERY_NODE_LIMIT:  // no pointer field
D
dapan1121 已提交
354
      break;
X
Xiaoyu Wang 已提交
355
    case QUERY_NODE_STATE_WINDOW:
356
      nodesDestroyNode(((SStateWindowNode*)pNode)->pExpr);
X
Xiaoyu Wang 已提交
357 358 359 360 361
      break;
    case QUERY_NODE_SESSION_WINDOW: {
      SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
      nodesDestroyNode(pSession->pCol);
      nodesDestroyNode(pSession->pGap);
D
dapan1121 已提交
362
      break;
X
Xiaoyu Wang 已提交
363 364 365 366 367 368 369 370 371 372
    }
    case QUERY_NODE_INTERVAL_WINDOW: {
      SIntervalWindowNode* pJoin = (SIntervalWindowNode*)pNode;
      nodesDestroyNode(pJoin->pCol);
      nodesDestroyNode(pJoin->pInterval);
      nodesDestroyNode(pJoin->pOffset);
      nodesDestroyNode(pJoin->pSliding);
      nodesDestroyNode(pJoin->pFill);
      break;
    }
D
dapan1121 已提交
373
    case QUERY_NODE_NODE_LIST:
X
Xiaoyu Wang 已提交
374 375 376 377 378 379 380
      nodesDestroyList(((SNodeListNode*)pNode)->pNodeList);
      break;
    case QUERY_NODE_FILL:
      nodesDestroyNode(((SFillNode*)pNode)->pValues);
      break;
    case QUERY_NODE_RAW_EXPR:
      nodesDestroyNode(((SRawExprNode*)pNode)->pNode);
X
Xiaoyu Wang 已提交
381
      break;
X
Xiaoyu Wang 已提交
382 383 384 385 386 387
    case QUERY_NODE_TARGET:
      nodesDestroyNode(((STargetNode*)pNode)->pExpr);
      break;
    case QUERY_NODE_DATABLOCK_DESC:
      nodesDestroyList(((SDataBlockDescNode*)pNode)->pSlots);
      break;
X
Xiaoyu Wang 已提交
388 389 390
    case QUERY_NODE_SLOT_DESC:          // no pointer field
    case QUERY_NODE_COLUMN_DEF:         // no pointer field
    case QUERY_NODE_DOWNSTREAM_SOURCE:  // no pointer field
X
Xiaoyu Wang 已提交
391
      break;
X
Xiaoyu Wang 已提交
392 393 394 395 396
    case QUERY_NODE_DATABASE_OPTIONS: {
      SDatabaseOptions* pOptions = (SDatabaseOptions*)pNode;
      nodesDestroyNode(pOptions->pDaysPerFile);
      nodesDestroyList(pOptions->pKeep);
      nodesDestroyList(pOptions->pRetentions);
X
Xiaoyu Wang 已提交
397
      break;
X
Xiaoyu Wang 已提交
398
    }
X
Xiaoyu Wang 已提交
399
    case QUERY_NODE_TABLE_OPTIONS: {
X
Xiaoyu Wang 已提交
400 401 402
      STableOptions* pOptions = (STableOptions*)pNode;
      nodesDestroyList(pOptions->pSma);
      nodesDestroyList(pOptions->pRollupFuncs);
X
Xiaoyu Wang 已提交
403
      break;
X
Xiaoyu Wang 已提交
404
    }
405
    case QUERY_NODE_INDEX_OPTIONS: {
X
Xiaoyu Wang 已提交
406 407 408 409 410
      SIndexOptions* pOptions = (SIndexOptions*)pNode;
      nodesDestroyList(pOptions->pFuncs);
      nodesDestroyNode(pOptions->pInterval);
      nodesDestroyNode(pOptions->pOffset);
      nodesDestroyNode(pOptions->pSliding);
411 412
      break;
    }
X
Xiaoyu Wang 已提交
413 414 415 416 417 418 419 420
    case QUERY_NODE_SET_OPERATOR: {
      SSetOperator* pStmt = (SSetOperator*)pNode;
      nodesDestroyNode(pStmt->pLeft);
      nodesDestroyNode(pStmt->pRight);
      nodesDestroyList(pStmt->pOrderByList);
      nodesDestroyNode(pStmt->pLimit);
      break;
    }
X
Xiaoyu Wang 已提交
421
    case QUERY_NODE_SELECT_STMT: {
X
Xiaoyu Wang 已提交
422
      SSelectStmt* pStmt = (SSelectStmt*)pNode;
X
Xiaoyu Wang 已提交
423 424 425 426 427 428 429 430 431 432 433 434
      nodesDestroyList(pStmt->pProjectionList);
      nodesDestroyNode(pStmt->pFromTable);
      nodesDestroyNode(pStmt->pWhere);
      nodesDestroyList(pStmt->pPartitionByList);
      nodesDestroyNode(pStmt->pWindow);
      nodesDestroyList(pStmt->pGroupByList);
      nodesDestroyNode(pStmt->pHaving);
      nodesDestroyList(pStmt->pOrderByList);
      nodesDestroyNode(pStmt->pLimit);
      nodesDestroyNode(pStmt->pSlimit);
      break;
    }
X
Xiaoyu Wang 已提交
435 436 437 438 439 440
    case QUERY_NODE_VNODE_MODIF_STMT:
      destroyVgDataBlockArray(((SVnodeModifOpStmt*)pNode)->pDataBlocks);
      break;
    case QUERY_NODE_CREATE_DATABASE_STMT:
      nodesDestroyNode(((SCreateDatabaseStmt*)pNode)->pOptions);
      break;
X
Xiaoyu Wang 已提交
441
    case QUERY_NODE_DROP_DATABASE_STMT:  // no pointer field
X
Xiaoyu Wang 已提交
442 443 444
      break;
    case QUERY_NODE_ALTER_DATABASE_STMT:
      nodesDestroyNode(((SAlterDatabaseStmt*)pNode)->pOptions);
X
Xiaoyu Wang 已提交
445
      break;
X
Xiaoyu Wang 已提交
446
    case QUERY_NODE_CREATE_TABLE_STMT: {
X
Xiaoyu Wang 已提交
447
      SCreateTableStmt* pStmt = (SCreateTableStmt*)pNode;
X
Xiaoyu Wang 已提交
448 449
      nodesDestroyList(pStmt->pCols);
      nodesDestroyList(pStmt->pTags);
X
Xiaoyu Wang 已提交
450
      nodesDestroyNode(pStmt->pOptions);
X
Xiaoyu Wang 已提交
451 452 453
      break;
    }
    case QUERY_NODE_CREATE_SUBTABLE_CLAUSE: {
X
Xiaoyu Wang 已提交
454
      SCreateSubTableClause* pStmt = (SCreateSubTableClause*)pNode;
X
Xiaoyu Wang 已提交
455 456 457 458 459
      nodesDestroyList(pStmt->pSpecificTags);
      nodesDestroyList(pStmt->pValsOfTags);
      break;
    }
    case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
X
Xiaoyu Wang 已提交
460 461
      nodesDestroyList(((SCreateMultiTableStmt*)pNode)->pSubTables);
      break;
X
Xiaoyu Wang 已提交
462
    case QUERY_NODE_DROP_TABLE_CLAUSE:  // no pointer field
X
Xiaoyu Wang 已提交
463 464 465 466
      break;
    case QUERY_NODE_DROP_TABLE_STMT:
      nodesDestroyNode(((SDropTableStmt*)pNode)->pTables);
      break;
X
Xiaoyu Wang 已提交
467
    case QUERY_NODE_DROP_SUPER_TABLE_STMT:  // no pointer field
X
Xiaoyu Wang 已提交
468 469 470 471 472 473 474
      break;
    case QUERY_NODE_ALTER_TABLE_STMT: {
      SAlterTableStmt* pStmt = (SAlterTableStmt*)pNode;
      nodesDestroyNode(pStmt->pOptions);
      nodesDestroyNode(pStmt->pVal);
      break;
    }
X
Xiaoyu Wang 已提交
475 476 477 478 479 480 481
    case QUERY_NODE_CREATE_USER_STMT:   // no pointer field
    case QUERY_NODE_ALTER_USER_STMT:    // no pointer field
    case QUERY_NODE_DROP_USER_STMT:     // no pointer field
    case QUERY_NODE_USE_DATABASE_STMT:  // no pointer field
    case QUERY_NODE_CREATE_DNODE_STMT:  // no pointer field
    case QUERY_NODE_DROP_DNODE_STMT:    // no pointer field
    case QUERY_NODE_ALTER_DNODE_STMT:   // no pointer field
482
      break;
483
    case QUERY_NODE_CREATE_INDEX_STMT: {
X
Xiaoyu Wang 已提交
484
      SCreateIndexStmt* pStmt = (SCreateIndexStmt*)pNode;
485 486 487 488
      nodesDestroyNode(pStmt->pOptions);
      nodesDestroyList(pStmt->pCols);
      break;
    }
X
Xiaoyu Wang 已提交
489 490 491
    case QUERY_NODE_DROP_INDEX_STMT:    // no pointer field
    case QUERY_NODE_CREATE_QNODE_STMT:  // no pointer field
    case QUERY_NODE_DROP_QNODE_STMT:    // no pointer field
X
Xiaoyu Wang 已提交
492 493 494 495
      break;
    case QUERY_NODE_CREATE_TOPIC_STMT:
      nodesDestroyNode(((SCreateTopicStmt*)pNode)->pQuery);
      break;
X
Xiaoyu Wang 已提交
496 497
    case QUERY_NODE_DROP_TOPIC_STMT:   // no pointer field
    case QUERY_NODE_ALTER_LOCAL_STMT:  // no pointer field
X
Xiaoyu Wang 已提交
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
      break;
    case QUERY_NODE_SHOW_DATABASES_STMT:
    case QUERY_NODE_SHOW_TABLES_STMT:
    case QUERY_NODE_SHOW_STABLES_STMT:
    case QUERY_NODE_SHOW_USERS_STMT:
    case QUERY_NODE_SHOW_DNODES_STMT:
    case QUERY_NODE_SHOW_VGROUPS_STMT:
    case QUERY_NODE_SHOW_MNODES_STMT:
    case QUERY_NODE_SHOW_MODULES_STMT:
    case QUERY_NODE_SHOW_QNODES_STMT:
    case QUERY_NODE_SHOW_FUNCTIONS_STMT:
    case QUERY_NODE_SHOW_INDEXES_STMT:
    case QUERY_NODE_SHOW_STREAMS_STMT: {
      SShowStmt* pStmt = (SShowStmt*)pNode;
      nodesDestroyNode(pStmt->pDbName);
      nodesDestroyNode(pStmt->pTbNamePattern);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_SCAN: {
      SScanLogicNode* pLogicNode = (SScanLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyList(pLogicNode->pScanCols);
      taosMemoryFreeClear(pLogicNode->pMeta);
      taosMemoryFreeClear(pLogicNode->pVgroupList);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_JOIN: {
      SJoinLogicNode* pLogicNode = (SJoinLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyNode(pLogicNode->pOnConditions);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_AGG: {
      SAggLogicNode* pLogicNode = (SAggLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyList(pLogicNode->pAggFuncs);
      nodesDestroyList(pLogicNode->pGroupKeys);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_PROJECT: {
      SProjectLogicNode* pLogicNode = (SProjectLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyList(pLogicNode->pProjections);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF: {
      SVnodeModifLogicNode* pLogicNode = (SVnodeModifLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      destroyVgDataBlockArray(pLogicNode->pDataBlocks);
X
bugfix  
Xiaoyu Wang 已提交
547
      // pVgDataBlocks is weak reference
X
Xiaoyu Wang 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
      destroyLogicNode((SLogicNode*)pNode);
      break;
    case QUERY_NODE_LOGIC_PLAN_WINDOW: {
      SWindowLogicNode* pLogicNode = (SWindowLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyList(pLogicNode->pFuncs);
      nodesDestroyNode(pLogicNode->pFill);
      nodesDestroyNode(pLogicNode->pTspk);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_SORT: {
      SSortLogicNode* pLogicNode = (SSortLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyList(pLogicNode->pSortKeys);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN_PARTITION: {
      SPartitionLogicNode* pLogicNode = (SPartitionLogicNode*)pNode;
      destroyLogicNode((SLogicNode*)pLogicNode);
      nodesDestroyList(pLogicNode->pPartitionKeys);
      break;
    }
    case QUERY_NODE_LOGIC_SUBPLAN: {
      SLogicSubplan* pSubplan = (SLogicSubplan*)pNode;
      nodesDestroyList(pSubplan->pChildren);
      nodesDestroyNode(pSubplan->pNode);
X
bugfix  
Xiaoyu Wang 已提交
577
      nodesClearList(pSubplan->pParents);
X
Xiaoyu Wang 已提交
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 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 648 649 650 651 652 653 654 655
      taosMemoryFreeClear(pSubplan->pVgroupList);
      break;
    }
    case QUERY_NODE_LOGIC_PLAN:
      nodesDestroyList(((SQueryLogicPlan*)pNode)->pTopSubplans);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
      destroyScanPhysiNode((SScanPhysiNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
      destroyScanPhysiNode((SScanPhysiNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
      destroyScanPhysiNode((SScanPhysiNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
      destroyScanPhysiNode((SScanPhysiNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
      destroyScanPhysiNode((SScanPhysiNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
      SProjectPhysiNode* pPhyNode = (SProjectPhysiNode*)pNode;
      destroyPhysiNode((SPhysiNode*)pPhyNode);
      nodesDestroyList(pPhyNode->pProjections);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_JOIN: {
      SJoinPhysiNode* pPhyNode = (SJoinPhysiNode*)pNode;
      destroyPhysiNode((SPhysiNode*)pPhyNode);
      nodesDestroyNode(pPhyNode->pOnConditions);
      nodesDestroyList(pPhyNode->pTargets);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_AGG: {
      SAggPhysiNode* pPhyNode = (SAggPhysiNode*)pNode;
      destroyPhysiNode((SPhysiNode*)pPhyNode);
      nodesDestroyList(pPhyNode->pExprs);
      nodesDestroyList(pPhyNode->pAggFuncs);
      nodesDestroyList(pPhyNode->pGroupKeys);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
      SExchangePhysiNode* pPhyNode = (SExchangePhysiNode*)pNode;
      destroyPhysiNode((SPhysiNode*)pPhyNode);
      nodesDestroyList(pPhyNode->pSrcEndPoints);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SORT: {
      SSortPhysiNode* pPhyNode = (SSortPhysiNode*)pNode;
      destroyPhysiNode((SPhysiNode*)pPhyNode);
      nodesDestroyNode(pPhyNode->pExprs);
      nodesDestroyNode(pPhyNode->pSortKeys);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: {
      SIntervalPhysiNode* pPhyNode = (SIntervalPhysiNode*)pNode;
      destroyWinodwPhysiNode((SWinodwPhysiNode*)pPhyNode);
      nodesDestroyNode(pPhyNode->pFill);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
      destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
      destroyDataSinkNode((SDataSinkNode*)pNode);
      break;
    case QUERY_NODE_PHYSICAL_PLAN_INSERT: {
      SDataInserterNode* pSink = (SDataInserterNode*)pNode;
      destroyDataSinkNode((SDataSinkNode*)pSink);
      taosMemoryFreeClear(pSink->pData);
      break;
    }
    case QUERY_NODE_PHYSICAL_SUBPLAN: {
      SSubplan* pSubplan = (SSubplan*)pNode;
      nodesDestroyList(pSubplan->pChildren);
      nodesDestroyNode(pSubplan->pNode);
      nodesDestroyNode(pSubplan->pDataSink);
X
bugfix  
Xiaoyu Wang 已提交
656 657 658 659 660 661 662
      nodesClearList(pSubplan->pParents);
      break;
    }
    case QUERY_NODE_PHYSICAL_PLAN: {
      SQueryPlan* pPlan = (SQueryPlan*)pNode;
      if (NULL != pPlan->pSubplans) {
        // only need to destroy the top-level subplans, because they will recurse to all the subplans below
X
Xiaoyu Wang 已提交
663
        bool   first = true;
X
bugfix  
Xiaoyu Wang 已提交
664 665 666 667 668 669 670 671 672 673 674 675
        SNode* pElement = NULL;
        FOREACH(pElement, pPlan->pSubplans) {
          if (first) {
            first = false;
            nodesDestroyNode(pElement);
          } else {
            nodesClearList(((SNodeListNode*)pElement)->pNodeList);
            taosMemoryFreeClear(pElement);
          }
        }
        nodesClearList(pPlan->pSubplans);
      }
X
Xiaoyu Wang 已提交
676 677
      break;
    }
678 679 680
    default:
      break;
  }
X
Xiaoyu Wang 已提交
681 682
  taosMemoryFreeClear(pNode);
  return;
683 684
}

685
SNodeList* nodesMakeList() {
wafwerar's avatar
wafwerar 已提交
686
  SNodeList* p = taosMemoryCalloc(1, sizeof(SNodeList));
687 688 689 690 691 692
  if (NULL == p) {
    return NULL;
  }
  return p;
}

X
Xiaoyu Wang 已提交
693
int32_t nodesListAppend(SNodeList* pList, SNodeptr pNode) {
694
  if (NULL == pList || NULL == pNode) {
X
Xiaoyu Wang 已提交
695
    return TSDB_CODE_FAILED;
696
  }
wafwerar's avatar
wafwerar 已提交
697
  SListCell* p = taosMemoryCalloc(1, sizeof(SListCell));
698
  if (NULL == p) {
X
Xiaoyu Wang 已提交
699 700
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return TSDB_CODE_OUT_OF_MEMORY;
701 702
  }
  p->pNode = pNode;
703 704 705 706 707 708
  if (NULL == pList->pHead) {
    pList->pHead = p;
  }
  if (NULL != pList->pTail) {
    pList->pTail->pNext = p;
  }
709
  p->pPrev = pList->pTail;
710
  pList->pTail = p;
711
  ++(pList->length);
X
Xiaoyu Wang 已提交
712
  return TSDB_CODE_SUCCESS;
713 714
}

715 716
int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode) {
  if (NULL == pNode) {
X
Xiaoyu Wang 已提交
717
    terrno = TSDB_CODE_OUT_OF_MEMORY;
718 719 720 721 722 723 724 725 726
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  int32_t code = nodesListAppend(pList, pNode);
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyNode(pNode);
  }
  return code;
}

X
Xiaoyu Wang 已提交
727 728 729 730 731 732 733 734 735 736 737
int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode) {
  if (NULL == *pList) {
    *pList = nodesMakeList();
    if (NULL == *pList) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  return nodesListAppend(*pList, pNode);
}

S
Shengliang Guan 已提交
738 739 740 741 742 743 744 745 746 747 748
int32_t nodesListMakeStrictAppend(SNodeList** pList, SNodeptr pNode) {
  if (NULL == *pList) {
    *pList = nodesMakeList();
    if (NULL == *pList) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }
  return nodesListStrictAppend(*pList, pNode);
}

X
Xiaoyu Wang 已提交
749
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc) {
X
Xiaoyu Wang 已提交
750
  if (NULL == pTarget || NULL == pSrc) {
X
Xiaoyu Wang 已提交
751
    return TSDB_CODE_FAILED;
X
Xiaoyu Wang 已提交
752 753 754 755 756 757 758 759 760 761
  }

  if (NULL == pTarget->pHead) {
    pTarget->pHead = pSrc->pHead;
  } else {
    pTarget->pTail->pNext = pSrc->pHead;
    if (NULL != pSrc->pHead) {
      pSrc->pHead->pPrev = pTarget->pTail;
    }
  }
X
Xiaoyu Wang 已提交
762 763
  pTarget->pTail = pSrc->pTail;
  pTarget->length += pSrc->length;
wafwerar's avatar
wafwerar 已提交
764
  taosMemoryFreeClear(pSrc);
X
Xiaoyu Wang 已提交
765

X
Xiaoyu Wang 已提交
766 767 768
  return TSDB_CODE_SUCCESS;
}

769 770 771 772 773 774 775 776 777 778 779
int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc) {
  if (NULL == pSrc) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  int32_t code = nodesListAppendList(pTarget, pSrc);
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyList(pSrc);
  }
  return code;
}

X
Xiaoyu Wang 已提交
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
int32_t nodesListPushFront(SNodeList* pList, SNodeptr pNode) {
  if (NULL == pList || NULL == pNode) {
    return TSDB_CODE_FAILED;
  }
  SListCell* p = taosMemoryCalloc(1, sizeof(SListCell));
  if (NULL == p) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  p->pNode = pNode;
  if (NULL != pList->pHead) {
    pList->pHead->pPrev = p;
    p->pNext = pList->pHead;
  }
  pList->pHead = p;
  ++(pList->length);
  return TSDB_CODE_SUCCESS;
}

799 800 801 802 803
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) {
  if (NULL == pCell->pPrev) {
    pList->pHead = pCell->pNext;
  } else {
    pCell->pPrev->pNext = pCell->pNext;
X
Xiaoyu Wang 已提交
804 805 806 807
  }
  if (NULL == pCell->pNext) {
    pList->pTail = pCell->pPrev;
  } else {
808 809 810
    pCell->pNext->pPrev = pCell->pPrev;
  }
  SListCell* pNext = pCell->pNext;
X
Xiaoyu Wang 已提交
811
  nodesDestroyNode(pCell->pNode);
wafwerar's avatar
wafwerar 已提交
812
  taosMemoryFreeClear(pCell);
813 814 815 816
  --(pList->length);
  return pNext;
}

X
Xiaoyu Wang 已提交
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc) {
  if (NULL == pTarget || NULL == pPos || NULL == pSrc) {
    return;
  }

  if (NULL == pPos->pPrev) {
    pTarget->pHead = pSrc->pHead;
  } else {
    pPos->pPrev->pNext = pSrc->pHead;
  }
  pSrc->pHead->pPrev = pPos->pPrev;
  pSrc->pTail->pNext = pPos;
  pPos->pPrev = pSrc->pTail;

  pTarget->length += pSrc->length;
  taosMemoryFreeClear(pSrc);
}

X
Xiaoyu Wang 已提交
835
SNodeptr nodesListGetNode(SNodeList* pList, int32_t index) {
836 837 838 839 840 841 842 843 844
  SNode* node;
  FOREACH(node, pList) {
    if (0 == index--) {
      return node;
    }
  }
  return NULL;
}

845
void nodesDestroyList(SNodeList* pList) {
846 847 848
  if (NULL == pList) {
    return;
  }
X
Xiaoyu Wang 已提交
849

D
dapan1121 已提交
850 851 852
  SListCell* pNext = pList->pHead;
  while (NULL != pNext) {
    pNext = nodesListErase(pList, pNext);
853
  }
wafwerar's avatar
wafwerar 已提交
854
  taosMemoryFreeClear(pList);
855 856
}

X
Xiaoyu Wang 已提交
857 858 859 860 861 862 863 864 865
void nodesClearList(SNodeList* pList) {
  if (NULL == pList) {
    return;
  }

  SListCell* pNext = pList->pHead;
  while (NULL != pNext) {
    SListCell* tmp = pNext;
    pNext = pNext->pNext;
wafwerar's avatar
wafwerar 已提交
866
    taosMemoryFreeClear(tmp);
X
Xiaoyu Wang 已提交
867
  }
wafwerar's avatar
wafwerar 已提交
868
  taosMemoryFreeClear(pList);
X
Xiaoyu Wang 已提交
869 870
}

X
Xiaoyu Wang 已提交
871
void* nodesGetValueFromNode(SValueNode* pNode) {
D
dapan1121 已提交
872 873
  switch (pNode->node.resType.type) {
    case TSDB_DATA_TYPE_BOOL:
X
Xiaoyu Wang 已提交
874
      return (void*)&pNode->datum.b;
D
dapan1121 已提交
875 876 877 878 879
    case TSDB_DATA_TYPE_TINYINT:
    case TSDB_DATA_TYPE_SMALLINT:
    case TSDB_DATA_TYPE_INT:
    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_TIMESTAMP:
X
Xiaoyu Wang 已提交
880
      return (void*)&pNode->datum.i;
D
dapan1121 已提交
881 882 883 884
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT:
X
Xiaoyu Wang 已提交
885
      return (void*)&pNode->datum.u;
D
dapan1121 已提交
886
    case TSDB_DATA_TYPE_FLOAT:
887
    case TSDB_DATA_TYPE_DOUBLE:
X
Xiaoyu Wang 已提交
888
      return (void*)&pNode->datum.d;
D
dapan1121 已提交
889 890
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_VARCHAR:
891
    case TSDB_DATA_TYPE_VARBINARY:
X
Xiaoyu Wang 已提交
892
      return (void*)pNode->datum.p;
D
dapan1121 已提交
893 894 895 896 897 898 899
    default:
      break;
  }

  return NULL;
}

X
Xiaoyu Wang 已提交
900
char* nodesGetStrValueFromNode(SValueNode* pNode) {
D
dapan1121 已提交
901
  switch (pNode->node.resType.type) {
D
dapan1121 已提交
902
    case TSDB_DATA_TYPE_BOOL: {
X
Xiaoyu Wang 已提交
903
      void* buf = taosMemoryMalloc(MAX_NUM_STR_SIZE);
D
dapan1121 已提交
904 905 906
      if (NULL == buf) {
        return NULL;
      }
907

D
dapan1121 已提交
908 909
      sprintf(buf, "%s", pNode->datum.b ? "true" : "false");
      return buf;
D
dapan1121 已提交
910
    }
D
dapan1121 已提交
911 912 913 914 915
    case TSDB_DATA_TYPE_TINYINT:
    case TSDB_DATA_TYPE_SMALLINT:
    case TSDB_DATA_TYPE_INT:
    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_TIMESTAMP: {
X
Xiaoyu Wang 已提交
916
      void* buf = taosMemoryMalloc(MAX_NUM_STR_SIZE);
D
dapan1121 已提交
917 918 919
      if (NULL == buf) {
        return NULL;
      }
920

D
dapan1121 已提交
921 922 923 924 925 926 927
      sprintf(buf, "%" PRId64, pNode->datum.i);
      return buf;
    }
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT: {
X
Xiaoyu Wang 已提交
928
      void* buf = taosMemoryMalloc(MAX_NUM_STR_SIZE);
D
dapan1121 已提交
929 930 931
      if (NULL == buf) {
        return NULL;
      }
932

D
dapan1121 已提交
933 934 935 936 937
      sprintf(buf, "%" PRIu64, pNode->datum.u);
      return buf;
    }
    case TSDB_DATA_TYPE_FLOAT:
    case TSDB_DATA_TYPE_DOUBLE: {
X
Xiaoyu Wang 已提交
938
      void* buf = taosMemoryMalloc(MAX_NUM_STR_SIZE);
D
dapan1121 已提交
939 940 941
      if (NULL == buf) {
        return NULL;
      }
942

D
dapan1121 已提交
943 944 945 946 947 948
      sprintf(buf, "%e", pNode->datum.d);
      return buf;
    }
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY: {
D
dapan1121 已提交
949
      int32_t bufSize = varDataLen(pNode->datum.p) + 2 + 1;
X
Xiaoyu Wang 已提交
950
      void*   buf = taosMemoryMalloc(bufSize);
D
dapan1121 已提交
951 952 953
      if (NULL == buf) {
        return NULL;
      }
954

D
dapan1121 已提交
955
      snprintf(buf, bufSize, "'%s'", varDataVal(pNode->datum.p));
D
dapan1121 已提交
956 957 958 959 960 961 962 963 964
      return buf;
    }
    default:
      break;
  }

  return NULL;
}

965 966
bool nodesIsExprNode(const SNode* pNode) {
  ENodeType type = nodeType(pNode);
X
Xiaoyu Wang 已提交
967 968
  return (QUERY_NODE_COLUMN == type || QUERY_NODE_VALUE == type || QUERY_NODE_OPERATOR == type ||
          QUERY_NODE_FUNCTION == type);
969 970
}

X
Xiaoyu Wang 已提交
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
bool nodesIsUnaryOp(const SOperatorNode* pOp) {
  switch (pOp->opType) {
    case OP_TYPE_MINUS:
    case OP_TYPE_IS_NULL:
    case OP_TYPE_IS_NOT_NULL:
    case OP_TYPE_IS_TRUE:
    case OP_TYPE_IS_FALSE:
    case OP_TYPE_IS_UNKNOWN:
    case OP_TYPE_IS_NOT_TRUE:
    case OP_TYPE_IS_NOT_FALSE:
    case OP_TYPE_IS_NOT_UNKNOWN:
      return true;
    default:
      break;
  }
  return false;
}

989 990 991 992 993 994 995 996 997 998 999 1000 1001
bool nodesIsArithmeticOp(const SOperatorNode* pOp) {
  switch (pOp->opType) {
    case OP_TYPE_ADD:
    case OP_TYPE_SUB:
    case OP_TYPE_MULTI:
    case OP_TYPE_DIV:
    case OP_TYPE_MOD:
      return true;
    default:
      break;
  }
  return false;
}
1002

1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
bool nodesIsComparisonOp(const SOperatorNode* pOp) {
  switch (pOp->opType) {
    case OP_TYPE_GREATER_THAN:
    case OP_TYPE_GREATER_EQUAL:
    case OP_TYPE_LOWER_THAN:
    case OP_TYPE_LOWER_EQUAL:
    case OP_TYPE_EQUAL:
    case OP_TYPE_NOT_EQUAL:
    case OP_TYPE_IN:
    case OP_TYPE_NOT_IN:
    case OP_TYPE_LIKE:
    case OP_TYPE_NOT_LIKE:
    case OP_TYPE_MATCH:
    case OP_TYPE_NMATCH:
1017
    case OP_TYPE_JSON_CONTAINS:
X
Xiaoyu Wang 已提交
1018 1019 1020 1021 1022 1023 1024 1025
    case OP_TYPE_IS_NULL:
    case OP_TYPE_IS_NOT_NULL:
    case OP_TYPE_IS_TRUE:
    case OP_TYPE_IS_FALSE:
    case OP_TYPE_IS_UNKNOWN:
    case OP_TYPE_IS_NOT_TRUE:
    case OP_TYPE_IS_NOT_FALSE:
    case OP_TYPE_IS_NOT_UNKNOWN:
1026 1027 1028 1029 1030
      return true;
    default:
      break;
  }
  return false;
1031 1032
}

1033 1034 1035 1036 1037 1038 1039 1040 1041
bool nodesIsJsonOp(const SOperatorNode* pOp) {
  switch (pOp->opType) {
    case OP_TYPE_JSON_GET_VALUE:
      return true;
    default:
      break;
  }
  return false;
}
1042

X
Xiaoyu Wang 已提交
1043
bool nodesIsTimeorderQuery(const SNode* pQuery) { return false; }
1044

X
Xiaoyu Wang 已提交
1045
bool nodesIsTimelineQuery(const SNode* pQuery) { return false; }
X
Xiaoyu Wang 已提交
1046 1047

typedef struct SCollectColumnsCxt {
1048 1049 1050 1051 1052
  int32_t         errCode;
  const char*     pTableAlias;
  ECollectColType collectType;
  SNodeList*      pCols;
  SHashObj*       pColHash;
X
Xiaoyu Wang 已提交
1053 1054
} SCollectColumnsCxt;

1055
static EDealRes doCollect(SCollectColumnsCxt* pCxt, SColumnNode* pCol, SNode* pNode) {
X
Xiaoyu Wang 已提交
1056
  char    name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN];
1057 1058 1059 1060 1061 1062 1063
  int32_t len = 0;
  if ('\0' == pCol->tableAlias[0]) {
    len = sprintf(name, "%s", pCol->colName);
  }
  len = sprintf(name, "%s.%s", pCol->tableAlias, pCol->colName);
  if (NULL == taosHashGet(pCxt->pColHash, name, len)) {
    pCxt->errCode = taosHashPut(pCxt->pColHash, name, len, NULL, 0);
X
Xiaoyu Wang 已提交
1064
    if (TSDB_CODE_SUCCESS == pCxt->errCode) {
1065
      pCxt->errCode = nodesListStrictAppend(pCxt->pCols, nodesCloneNode(pNode));
X
Xiaoyu Wang 已提交
1066 1067 1068 1069 1070 1071
    }
    return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
  }
  return DEAL_RES_CONTINUE;
}

1072 1073 1074 1075 1076 1077
static bool isCollectType(ECollectColType collectType, EColumnType colType) {
  return COLLECT_COL_TYPE_ALL == collectType
             ? true
             : (COLLECT_COL_TYPE_TAG == collectType ? COLUMN_TYPE_TAG == colType : COLUMN_TYPE_TAG != colType);
}

X
Xiaoyu Wang 已提交
1078 1079
static EDealRes collectColumns(SNode* pNode, void* pContext) {
  SCollectColumnsCxt* pCxt = (SCollectColumnsCxt*)pContext;
X
Xiaoyu Wang 已提交
1080
  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
X
Xiaoyu Wang 已提交
1081
    SColumnNode* pCol = (SColumnNode*)pNode;
1082 1083
    if (isCollectType(pCxt->collectType, pCol->colType) &&
        (NULL == pCxt->pTableAlias || 0 == strcmp(pCxt->pTableAlias, pCol->tableAlias))) {
1084
      return doCollect(pCxt, pCol, pNode);
X
Xiaoyu Wang 已提交
1085 1086 1087 1088 1089
    }
  }
  return DEAL_RES_CONTINUE;
}

1090 1091
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
                            SNodeList** pCols) {
X
Xiaoyu Wang 已提交
1092 1093 1094 1095 1096
  if (NULL == pSelect || NULL == pCols) {
    return TSDB_CODE_SUCCESS;
  }

  SCollectColumnsCxt cxt = {
X
Xiaoyu Wang 已提交
1097 1098
      .errCode = TSDB_CODE_SUCCESS,
      .pTableAlias = pTableAlias,
1099
      .collectType = type,
X
Xiaoyu Wang 已提交
1100 1101
      .pCols = nodesMakeList(),
      .pColHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK)};
1102
  if (NULL == cxt.pCols || NULL == cxt.pColHash) {
X
Xiaoyu Wang 已提交
1103 1104 1105 1106
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt);
1107
  taosHashCleanup(cxt.pColHash);
X
Xiaoyu Wang 已提交
1108
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
1109
    nodesDestroyList(cxt.pCols);
X
Xiaoyu Wang 已提交
1110 1111
    return cxt.errCode;
  }
X
Xiaoyu Wang 已提交
1112
  if (0 == LIST_LENGTH(cxt.pCols)) {
1113
    nodesDestroyList(cxt.pCols);
X
Xiaoyu Wang 已提交
1114 1115
    cxt.pCols = NULL;
  }
X
Xiaoyu Wang 已提交
1116 1117 1118 1119 1120
  *pCols = cxt.pCols;
  return TSDB_CODE_SUCCESS;
}

typedef struct SCollectFuncsCxt {
X
Xiaoyu Wang 已提交
1121
  int32_t         errCode;
X
Xiaoyu Wang 已提交
1122
  FFuncClassifier classifier;
X
Xiaoyu Wang 已提交
1123
  SNodeList*      pFuncs;
X
Xiaoyu Wang 已提交
1124 1125 1126 1127 1128
} SCollectFuncsCxt;

static EDealRes collectFuncs(SNode* pNode, void* pContext) {
  SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext;
  if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId)) {
1129
    pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
X
Xiaoyu Wang 已提交
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
    return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
  }
  return DEAL_RES_CONTINUE;
}

int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs) {
  if (NULL == pSelect || NULL == pFuncs) {
    return TSDB_CODE_SUCCESS;
  }

1140 1141
  SCollectFuncsCxt cxt = {
      .errCode = TSDB_CODE_SUCCESS, .classifier = classifier, .pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs)};
X
Xiaoyu Wang 已提交
1142 1143 1144
  if (NULL == cxt.pFuncs) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
1145
  *pFuncs = NULL;
X
Xiaoyu Wang 已提交
1146 1147 1148 1149 1150
  nodesWalkSelectStmt(pSelect, SQL_CLAUSE_GROUP_BY, collectFuncs, &cxt);
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyList(cxt.pFuncs);
    return cxt.errCode;
  }
X
Xiaoyu Wang 已提交
1151 1152 1153 1154 1155
  if (LIST_LENGTH(cxt.pFuncs) > 0) {
    *pFuncs = cxt.pFuncs;
  } else {
    nodesDestroyList(cxt.pFuncs);
  }
X
Xiaoyu Wang 已提交
1156

X
Xiaoyu Wang 已提交
1157 1158
  return TSDB_CODE_SUCCESS;
}
D
dapan1121 已提交
1159

X
Xiaoyu Wang 已提交
1160
char* getFillModeString(EFillMode mode) {
D
dapan1121 已提交
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
  switch (mode) {
    case FILL_MODE_NONE:
      return "none";
    case FILL_MODE_VALUE:
      return "value";
    case FILL_MODE_PREV:
      return "prev";
    case FILL_MODE_NULL:
      return "null";
    case FILL_MODE_LINEAR:
      return "linear";
    case FILL_MODE_NEXT:
      return "next";
    default:
      return "unknown";
  }
}

X
Xiaoyu Wang 已提交
1179
char* nodesGetNameFromColumnNode(SNode* pNode) {
D
dapan1121 已提交
1180 1181 1182
  if (NULL == pNode || QUERY_NODE_COLUMN != pNode->type) {
    return "NULL";
  }
X
Xiaoyu Wang 已提交
1183 1184

  return ((SColumnNode*)pNode)->colName;
D
dapan1121 已提交
1185 1186
}

D
dapan1121 已提交
1187 1188 1189 1190 1191
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots) {
  if (NULL == pSlots || pSlots->length <= 0) {
    return 0;
  }

X
Xiaoyu Wang 已提交
1192
  SNode*  pNode = NULL;
D
dapan1121 已提交
1193 1194 1195 1196 1197 1198
  int32_t num = 0;
  FOREACH(pNode, pSlots) {
    if (QUERY_NODE_SLOT_DESC != pNode->type) {
      continue;
    }

X
Xiaoyu Wang 已提交
1199
    SSlotDescNode* descNode = (SSlotDescNode*)pNode;
D
dapan1121 已提交
1200 1201 1202 1203 1204 1205 1206 1207
    if (descNode->output) {
      ++num;
    }
  }

  return num;
}

D
dapan1121 已提交
1208 1209 1210 1211 1212
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal) {
  pVal->nType = pNode->node.resType.type;
  pVal->nLen = pNode->node.resType.bytes;
  switch (pNode->node.resType.type) {
    case TSDB_DATA_TYPE_NULL:
X
Xiaoyu Wang 已提交
1213
      break;
D
dapan1121 已提交
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
    case TSDB_DATA_TYPE_BOOL:
      pVal->i = pNode->datum.b;
      break;
    case TSDB_DATA_TYPE_TINYINT:
    case TSDB_DATA_TYPE_SMALLINT:
    case TSDB_DATA_TYPE_INT:
    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_TIMESTAMP:
      pVal->i = pNode->datum.i;
      break;
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT:
      pVal->u = pNode->datum.u;
      break;
    case TSDB_DATA_TYPE_FLOAT:
    case TSDB_DATA_TYPE_DOUBLE:
      pVal->d = pNode->datum.d;
      break;
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY:
1237
      pVal->pz = pNode->datum.p;
D
dapan1121 已提交
1238 1239 1240 1241 1242 1243 1244 1245 1246
      break;
    case TSDB_DATA_TYPE_JSON:
    case TSDB_DATA_TYPE_DECIMAL:
    case TSDB_DATA_TYPE_BLOB:
      // todo
    default:
      break;
  }
}