nodesUtilFuncs.c 19.9 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 87 88
    case QUERY_NODE_SET_OPERATOR:
      return makeNode(type, sizeof(SSetOperator));
    case QUERY_NODE_SELECT_STMT:
      return makeNode(type, sizeof(SSelectStmt));
89 90 91 92
    case QUERY_NODE_VNODE_MODIF_STMT:
      return makeNode(type, sizeof(SVnodeModifOpStmt));
    case QUERY_NODE_CREATE_DATABASE_STMT:
      return makeNode(type, sizeof(SCreateDatabaseStmt));
93
    case QUERY_NODE_DROP_DATABASE_STMT:
X
Xiaoyu Wang 已提交
94
      return makeNode(type, sizeof(SDropDatabaseStmt));    
95 96
    case QUERY_NODE_ALTER_DATABASE_STMT:
      return makeNode(type, sizeof(SAlterDatabaseStmt));
97 98
    case QUERY_NODE_CREATE_TABLE_STMT:
      return makeNode(type, sizeof(SCreateTableStmt));
99 100
    case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
      return makeNode(type, sizeof(SCreateSubTableClause));
101 102
    case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
      return makeNode(type, sizeof(SCreateMultiTableStmt));
103 104 105 106
    case QUERY_NODE_DROP_TABLE_CLAUSE:
      return makeNode(type, sizeof(SDropTableClause));
    case QUERY_NODE_DROP_TABLE_STMT:
      return makeNode(type, sizeof(SDropTableStmt));
107 108
    case QUERY_NODE_DROP_SUPER_TABLE_STMT:
      return makeNode(type, sizeof(SDropSuperTableStmt));
109 110 111 112 113 114
    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));
115 116
    case QUERY_NODE_USE_DATABASE_STMT:
      return makeNode(type, sizeof(SUseDatabaseStmt));
117 118 119 120
    case QUERY_NODE_CREATE_DNODE_STMT:
      return makeNode(type, sizeof(SCreateDnodeStmt));
    case QUERY_NODE_DROP_DNODE_STMT:
      return makeNode(type, sizeof(SDropDnodeStmt));
121 122
    case QUERY_NODE_ALTER_DNODE_STMT:
      return makeNode(type, sizeof(SAlterDnodeStmt));
X
Xiaoyu Wang 已提交
123 124
    case QUERY_NODE_CREATE_INDEX_STMT:
      return makeNode(type, sizeof(SCreateIndexStmt));
125 126
    case QUERY_NODE_DROP_INDEX_STMT:
      return makeNode(type, sizeof(SDropIndexStmt));
X
Xiaoyu Wang 已提交
127 128
    case QUERY_NODE_CREATE_QNODE_STMT:
      return makeNode(type, sizeof(SCreateQnodeStmt));
129 130 131 132 133 134
    case QUERY_NODE_DROP_QNODE_STMT:
      return makeNode(type, sizeof(SDropQnodeStmt));
    case QUERY_NODE_CREATE_TOPIC_STMT:
      return makeNode(type, sizeof(SCreateTopicStmt));
    case QUERY_NODE_DROP_TOPIC_STMT:
      return makeNode(type, sizeof(SDropTopicStmt));
X
Xiaoyu Wang 已提交
135 136 137 138
    case QUERY_NODE_SHOW_DATABASES_STMT:
    case QUERY_NODE_SHOW_TABLES_STMT:
    case QUERY_NODE_SHOW_STABLES_STMT:
    case QUERY_NODE_SHOW_USERS_STMT:
139 140
    case QUERY_NODE_SHOW_DNODES_STMT:
    case QUERY_NODE_SHOW_VGROUPS_STMT:
X
Xiaoyu Wang 已提交
141
    case QUERY_NODE_SHOW_MNODES_STMT:
X
Xiaoyu Wang 已提交
142 143 144 145 146
    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:
147
      return makeNode(type, sizeof(SShowStmt));
X
Xiaoyu Wang 已提交
148 149 150 151 152 153 154 155
    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));
156 157
    case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
      return makeNode(type, sizeof(SVnodeModifLogicNode));
X
Xiaoyu Wang 已提交
158 159
    case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
      return makeNode(type, sizeof(SExchangeLogicNode));
X
Xiaoyu Wang 已提交
160 161
    case QUERY_NODE_LOGIC_PLAN_WINDOW:
      return makeNode(type, sizeof(SWindowLogicNode));
X
Xiaoyu Wang 已提交
162 163
    case QUERY_NODE_LOGIC_PLAN_SORT:
      return makeNode(type, sizeof(SSortLogicNode));
X
Xiaoyu Wang 已提交
164
    case QUERY_NODE_LOGIC_SUBPLAN:
X
Xiaoyu Wang 已提交
165
      return makeNode(type, sizeof(SLogicSubplan));
X
Xiaoyu Wang 已提交
166 167
    case QUERY_NODE_LOGIC_PLAN:
      return makeNode(type, sizeof(SQueryLogicPlan));
X
Xiaoyu Wang 已提交
168 169 170 171
    case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
      return makeNode(type, sizeof(STagScanPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
      return makeNode(type, sizeof(STableScanPhysiNode));
172 173 174
    case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
      return makeNode(type, sizeof(STableSeqScanPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
X
Xiaoyu Wang 已提交
175
      return makeNode(type, sizeof(SStreamScanPhysiNode));
X
Xiaoyu Wang 已提交
176 177
    case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
      return makeNode(type, sizeof(SSystemTableScanPhysiNode));
X
Xiaoyu Wang 已提交
178 179
    case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
      return makeNode(type, sizeof(SProjectPhysiNode));
X
Xiaoyu Wang 已提交
180 181 182 183
    case QUERY_NODE_PHYSICAL_PLAN_JOIN:
      return makeNode(type, sizeof(SJoinPhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_AGG:
      return makeNode(type, sizeof(SAggPhysiNode));
184 185 186
    case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
      return makeNode(type, sizeof(SExchangePhysiNode));
    case QUERY_NODE_PHYSICAL_PLAN_SORT:
X
Xiaoyu Wang 已提交
187
      return makeNode(type, sizeof(SSortPhysiNode));
X
Xiaoyu Wang 已提交
188 189
    case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
      return makeNode(type, sizeof(SIntervalPhysiNode));
190 191
    case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
      return makeNode(type, sizeof(SSessionWinodwPhysiNode));
192 193 194 195
    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 已提交
196 197 198 199
    case QUERY_NODE_PHYSICAL_SUBPLAN:
      return makeNode(type, sizeof(SSubplan));
    case QUERY_NODE_PHYSICAL_PLAN:
      return makeNode(type, sizeof(SQueryPlan));
200 201 202
    default:
      break;
  }
203
  nodesError("nodesMakeNode unknown node = %s", nodesNodeName(type));
204
  return NULL;
205 206
}

D
dapan1121 已提交
207 208 209 210 211
static EDealRes destroyNode(SNode** pNode, void* pContext) {
  switch (nodeType(*pNode)) {
    case QUERY_NODE_VALUE: {
      SValueNode* pValue = (SValueNode*)*pNode;
      
wafwerar's avatar
wafwerar 已提交
212
      taosMemoryFreeClear(pValue->literal);
D
dapan1121 已提交
213
      if (IS_VAR_DATA_TYPE(pValue->node.resType.type)) {
wafwerar's avatar
wafwerar 已提交
214
        taosMemoryFreeClear(pValue->datum.p);
D
dapan1121 已提交
215 216 217 218 219
      }
      
      break;
    }
    case QUERY_NODE_LOGIC_CONDITION:
X
Xiaoyu Wang 已提交
220
      nodesClearList(((SLogicConditionNode*)(*pNode))->pParameterList);
D
dapan1121 已提交
221 222
      break;
    case QUERY_NODE_FUNCTION:
X
Xiaoyu Wang 已提交
223 224 225 226
      nodesClearList(((SFunctionNode*)(*pNode))->pParameterList);
      break;
    case QUERY_NODE_REAL_TABLE: {
      SRealTableNode* pReal = (SRealTableNode*)*pNode;
wafwerar's avatar
wafwerar 已提交
227 228
      taosMemoryFreeClear(pReal->pMeta);
      taosMemoryFreeClear(pReal->pVgroupList);
X
Xiaoyu Wang 已提交
229 230 231 232
      break;
    }
    case QUERY_NODE_TEMP_TABLE:
      nodesDestroyNode(((STempTableNode*)(*pNode))->pSubquery);
D
dapan1121 已提交
233 234
      break;
    case QUERY_NODE_GROUPING_SET:
X
Xiaoyu Wang 已提交
235
      nodesClearList(((SGroupingSetNode*)(*pNode))->pParameterList);
D
dapan1121 已提交
236 237
      break;
    case QUERY_NODE_NODE_LIST:
X
Xiaoyu Wang 已提交
238 239
      nodesClearList(((SNodeListNode*)(*pNode))->pNodeList);
      break;
240 241 242 243 244 245 246 247
    case QUERY_NODE_INDEX_OPTIONS: {
      SIndexOptions* pStmt = (SIndexOptions*)*pNode;
      nodesDestroyList(pStmt->pFuncs);
      nodesDestroyNode(pStmt->pInterval);
      nodesDestroyNode(pStmt->pOffset);
      nodesDestroyNode(pStmt->pSliding);
      break;
    }
X
Xiaoyu Wang 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260 261
    case QUERY_NODE_SELECT_STMT: {
      SSelectStmt* pStmt = (SSelectStmt*)*pNode;
      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 已提交
262 263 264 265 266
    case QUERY_NODE_VNODE_MODIF_STMT: {
      SVnodeModifOpStmt* pStmt = (SVnodeModifOpStmt*)*pNode;
      size_t size = taosArrayGetSize(pStmt->pDataBlocks);
      for (size_t i = 0; i < size; ++i) {
        SVgDataBlocks* pVg = taosArrayGetP(pStmt->pDataBlocks, i);
wafwerar's avatar
wafwerar 已提交
267 268
        taosMemoryFreeClear(pVg->pData);
        taosMemoryFreeClear(pVg);
X
Xiaoyu Wang 已提交
269 270 271 272
      }
      taosArrayDestroy(pStmt->pDataBlocks);
      break;
    }
X
Xiaoyu Wang 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286
    case QUERY_NODE_CREATE_TABLE_STMT: {
      SCreateTableStmt* pStmt = (SCreateTableStmt*)*pNode;
      nodesDestroyList(pStmt->pCols);
      nodesDestroyList(pStmt->pTags);
      break;
    }
    case QUERY_NODE_CREATE_SUBTABLE_CLAUSE: {
      SCreateSubTableClause* pStmt = (SCreateSubTableClause*)*pNode;
      nodesDestroyList(pStmt->pSpecificTags);
      nodesDestroyList(pStmt->pValsOfTags);
      break;
    }
    case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
      nodesDestroyList(((SCreateMultiTableStmt*)(*pNode))->pSubTables);
287
      break;
288 289 290 291 292 293
    case QUERY_NODE_CREATE_INDEX_STMT: {
      SCreateIndexStmt* pStmt = (SCreateIndexStmt*)*pNode;
      nodesDestroyNode(pStmt->pOptions);
      nodesDestroyList(pStmt->pCols);
      break;
    }
294 295 296
    default:
      break;
  }
wafwerar's avatar
wafwerar 已提交
297
  taosMemoryFreeClear(*pNode);
298
  return DEAL_RES_CONTINUE;
299
}
300

X
Xiaoyu Wang 已提交
301
void nodesDestroyNode(SNodeptr pNode) {
D
dapan1121 已提交
302 303 304
  if (NULL == pNode) {
    return;
  }
X
Xiaoyu Wang 已提交
305
  nodesRewriteNodePostOrder((SNode**)&pNode, destroyNode, NULL);
306 307
}

308
SNodeList* nodesMakeList() {
wafwerar's avatar
wafwerar 已提交
309
  SNodeList* p = taosMemoryCalloc(1, sizeof(SNodeList));
310 311 312 313 314 315
  if (NULL == p) {
    return NULL;
  }
  return p;
}

X
Xiaoyu Wang 已提交
316
int32_t nodesListAppend(SNodeList* pList, SNodeptr pNode) {
317
  if (NULL == pList || NULL == pNode) {
X
Xiaoyu Wang 已提交
318
    return TSDB_CODE_SUCCESS;
319
  }
wafwerar's avatar
wafwerar 已提交
320
  SListCell* p = taosMemoryCalloc(1, sizeof(SListCell));
321
  if (NULL == p) {
X
Xiaoyu Wang 已提交
322 323
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return TSDB_CODE_OUT_OF_MEMORY;
324 325
  }
  p->pNode = pNode;
326 327 328 329 330 331
  if (NULL == pList->pHead) {
    pList->pHead = p;
  }
  if (NULL != pList->pTail) {
    pList->pTail->pNext = p;
  }
332
  pList->pTail = p;
333
  ++(pList->length);
X
Xiaoyu Wang 已提交
334
  return TSDB_CODE_SUCCESS;
335 336
}

337 338
int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode) {
  if (NULL == pNode) {
X
Xiaoyu Wang 已提交
339
    terrno = TSDB_CODE_OUT_OF_MEMORY;
340 341 342 343 344 345 346 347 348
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  int32_t code = nodesListAppend(pList, pNode);
  if (TSDB_CODE_SUCCESS != code) {
    nodesDestroyNode(pNode);
  }
  return code;
}

X
Xiaoyu Wang 已提交
349 350 351 352 353 354 355 356 357 358 359
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);
}

X
Xiaoyu Wang 已提交
360
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc) {
X
Xiaoyu Wang 已提交
361 362 363 364 365 366 367 368 369 370 371 372
  if (NULL == pTarget || NULL == pSrc) {
    return TSDB_CODE_SUCCESS;
  }

  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 已提交
373 374
  pTarget->pTail = pSrc->pTail;
  pTarget->length += pSrc->length;
wafwerar's avatar
wafwerar 已提交
375
  taosMemoryFreeClear(pSrc);
X
Xiaoyu Wang 已提交
376

X
Xiaoyu Wang 已提交
377 378 379
  return TSDB_CODE_SUCCESS;
}

380 381 382 383 384 385 386 387 388 389 390
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;
}

391 392 393 394 395 396 397 398
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) {
  if (NULL == pCell->pPrev) {
    pList->pHead = pCell->pNext;
  } else {
    pCell->pPrev->pNext = pCell->pNext;
    pCell->pNext->pPrev = pCell->pPrev;
  }
  SListCell* pNext = pCell->pNext;
X
Xiaoyu Wang 已提交
399
  nodesDestroyNode(pCell->pNode);
wafwerar's avatar
wafwerar 已提交
400
  taosMemoryFreeClear(pCell);
401 402 403 404
  --(pList->length);
  return pNext;
}

X
Xiaoyu Wang 已提交
405
SNodeptr nodesListGetNode(SNodeList* pList, int32_t index) {
406 407 408 409 410 411 412 413 414
  SNode* node;
  FOREACH(node, pList) {
    if (0 == index--) {
      return node;
    }
  }
  return NULL;
}

415
void nodesDestroyList(SNodeList* pList) {
416 417 418
  if (NULL == pList) {
    return;
  }
X
Xiaoyu Wang 已提交
419

D
dapan1121 已提交
420 421 422
  SListCell* pNext = pList->pHead;
  while (NULL != pNext) {
    pNext = nodesListErase(pList, pNext);
423
  }
wafwerar's avatar
wafwerar 已提交
424
  taosMemoryFreeClear(pList);
425 426
}

X
Xiaoyu Wang 已提交
427 428 429 430 431 432 433 434 435
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 已提交
436
    taosMemoryFreeClear(tmp);
X
Xiaoyu Wang 已提交
437
  }
wafwerar's avatar
wafwerar 已提交
438
  taosMemoryFreeClear(pList);
X
Xiaoyu Wang 已提交
439 440
}

X
Xiaoyu Wang 已提交
441
void* nodesGetValueFromNode(SValueNode *pNode) {
D
dapan1121 已提交
442 443
  switch (pNode->node.resType.type) {
    case TSDB_DATA_TYPE_BOOL:
X
Xiaoyu Wang 已提交
444
      return (void*)&pNode->datum.b;
D
dapan1121 已提交
445 446 447 448 449
    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 已提交
450
      return (void*)&pNode->datum.i;
D
dapan1121 已提交
451 452 453 454
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT:
X
Xiaoyu Wang 已提交
455
      return (void*)&pNode->datum.u;
D
dapan1121 已提交
456 457
    case TSDB_DATA_TYPE_FLOAT:
    case TSDB_DATA_TYPE_DOUBLE: 
X
Xiaoyu Wang 已提交
458
      return (void*)&pNode->datum.d;
D
dapan1121 已提交
459 460 461
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY: 
X
Xiaoyu Wang 已提交
462
      return (void*)pNode->datum.p;
D
dapan1121 已提交
463 464 465 466 467 468 469
    default:
      break;
  }

  return NULL;
}

470 471 472 473 474
bool nodesIsExprNode(const SNode* pNode) {
  ENodeType type = nodeType(pNode);
  return (QUERY_NODE_COLUMN == type || QUERY_NODE_VALUE == type || QUERY_NODE_OPERATOR == type || QUERY_NODE_FUNCTION == type);
}

475 476 477 478 479 480 481 482 483 484 485 486 487
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;
}
488

489 490 491 492 493 494 495 496 497 498 499 500 501 502
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:
X
Xiaoyu Wang 已提交
503 504 505 506 507 508 509 510
    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:
511 512 513 514 515
      return true;
    default:
      break;
  }
  return false;
516 517
}

518 519 520 521 522 523 524 525 526 527
bool nodesIsJsonOp(const SOperatorNode* pOp) {
  switch (pOp->opType) {
    case OP_TYPE_JSON_GET_VALUE:
    case OP_TYPE_JSON_CONTAINS:
      return true;
    default:
      break;
  }
  return false;
}
528

529 530
bool nodesIsTimeorderQuery(const SNode* pQuery) {
  return false;
531
}
532 533

bool nodesIsTimelineQuery(const SNode* pQuery) {
534
  return false;
D
dapan1121 已提交
535
}
X
Xiaoyu Wang 已提交
536 537 538

typedef struct SCollectColumnsCxt {
  int32_t errCode;
X
Xiaoyu Wang 已提交
539
  const char* pTableAlias;
X
Xiaoyu Wang 已提交
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
  SNodeList* pCols;
  SHashObj* pColIdHash;
} SCollectColumnsCxt;

static EDealRes doCollect(SCollectColumnsCxt* pCxt, int32_t id, SNode* pNode) {
  if (NULL == taosHashGet(pCxt->pColIdHash, &id, sizeof(id))) {
    pCxt->errCode = taosHashPut(pCxt->pColIdHash, &id, sizeof(id), NULL, 0);
    if (TSDB_CODE_SUCCESS == pCxt->errCode) {
      pCxt->errCode = nodesListAppend(pCxt->pCols, pNode);
    }
    return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
  }
  return DEAL_RES_CONTINUE;
}

static EDealRes collectColumns(SNode* pNode, void* pContext) {
  SCollectColumnsCxt* pCxt = (SCollectColumnsCxt*)pContext;
X
Xiaoyu Wang 已提交
557
  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
X
Xiaoyu Wang 已提交
558 559
    SColumnNode* pCol = (SColumnNode*)pNode;
    int32_t colId = pCol->colId;
X
Xiaoyu Wang 已提交
560
    if (NULL == pCxt->pTableAlias || 0 == strcmp(pCxt->pTableAlias, pCol->tableAlias)) {
X
Xiaoyu Wang 已提交
561 562 563 564 565 566
      return doCollect(pCxt, colId, pNode);
    }
  }
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
567
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, SNodeList** pCols) {
X
Xiaoyu Wang 已提交
568 569 570 571 572 573
  if (NULL == pSelect || NULL == pCols) {
    return TSDB_CODE_SUCCESS;
  }

  SCollectColumnsCxt cxt = {
    .errCode = TSDB_CODE_SUCCESS,
X
Xiaoyu Wang 已提交
574
    .pTableAlias = pTableAlias,
X
Xiaoyu Wang 已提交
575 576 577 578 579 580 581 582 583 584 585 586 587
    .pCols = nodesMakeList(),
    .pColIdHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK)
  };
  if (NULL == cxt.pCols || NULL == cxt.pColIdHash) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt);
  taosHashCleanup(cxt.pColIdHash);
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyList(cxt.pCols);
    return cxt.errCode;
  }
X
Xiaoyu Wang 已提交
588 589 590 591
  if (0 == LIST_LENGTH(cxt.pCols)) {
    nodesDestroyList(cxt.pCols);
    cxt.pCols = NULL;
  }
X
Xiaoyu Wang 已提交
592 593 594 595 596 597 598 599 600 601 602 603 604
  *pCols = cxt.pCols;
  return TSDB_CODE_SUCCESS;
}

typedef struct SCollectFuncsCxt {
  int32_t errCode;
  FFuncClassifier classifier;
  SNodeList* pFuncs;
} SCollectFuncsCxt;

static EDealRes collectFuncs(SNode* pNode, void* pContext) {
  SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext;
  if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId)) {
605
    pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
X
Xiaoyu Wang 已提交
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
    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;
  }

  SCollectFuncsCxt cxt = {
    .errCode = TSDB_CODE_SUCCESS,
    .classifier = classifier,
    .pFuncs = nodesMakeList()
  };
  if (NULL == cxt.pFuncs) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  nodesWalkSelectStmt(pSelect, SQL_CLAUSE_GROUP_BY, collectFuncs, &cxt);
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
    nodesDestroyList(cxt.pFuncs);
    return cxt.errCode;
  }
X
Xiaoyu Wang 已提交
629 630 631 632 633 634 635
  if (LIST_LENGTH(cxt.pFuncs) > 0) {
    *pFuncs = cxt.pFuncs;
  } else {
    nodesDestroyList(cxt.pFuncs);
    *pFuncs = NULL;
  }
  
X
Xiaoyu Wang 已提交
636 637
  return TSDB_CODE_SUCCESS;
}