/* * Copyright (c) 2019 TAOS Data, Inc. * * 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 . */ #include "nodes.h" #include "nodesShowStmts.h" #include "taoserror.h" static SNode* makeNode(ENodeType type, size_t size) { SNode* p = calloc(1, size); if (NULL == p) { return NULL; } setNodeType(p, type); return p; } SNode* nodesMakeNode(ENodeType type) { 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_IS_NULL_CONDITION: return makeNode(type, sizeof(SIsNullCondNode)); 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)); 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)); case QUERY_NODE_SET_OPERATOR: return makeNode(type, sizeof(SSetOperator)); case QUERY_NODE_SELECT_STMT: return makeNode(type, sizeof(SSelectStmt)); case QUERY_NODE_SHOW_STMT: return makeNode(type, sizeof(SShowStmt)); default: break; } return NULL; } static EDealRes destroyNode(SNode* pNode, void* pContext) { switch (nodeType(pNode)) { case QUERY_NODE_VALUE: tfree(((SValueNode*)pNode)->literal); break; default: break; } tfree(pNode); return DEAL_RES_CONTINUE; } void nodesDestroyNode(SNode* pNode) { nodesWalkNodePostOrder(pNode, destroyNode, NULL); } SNodeList* nodesMakeList() { SNodeList* p = calloc(1, sizeof(SNodeList)); if (NULL == p) { return NULL; } return p; } SNodeList* nodesListAppend(SNodeList* pList, SNode* pNode) { if (NULL == pList || NULL == pNode) { return NULL; } SListCell* p = calloc(1, sizeof(SListCell)); if (NULL == p) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return pList; } p->pNode = pNode; if (NULL == pList->pHead) { pList->pHead = p; } if (NULL != pList->pTail) { pList->pTail->pNext = p; } pList->pTail = p; ++(pList->length); return pList; } 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; tfree(pCell); --(pList->length); return pNext; } SNode* nodesListGetNode(SNodeList* pList, int32_t index) { SNode* node; FOREACH(node, pList) { if (0 == index--) { return node; } } return NULL; } void nodesDestroyList(SNodeList* pList) { SNode* node; FOREACH(node, pList) { nodesDestroyNode(node); } tfree(pList); } void *nodesGetValueFromNode(SValueNode *pNode) { switch (pNode->node.resType.type) { case TSDB_DATA_TYPE_BOOL: return (void *)&pNode->datum.b; 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: return (void *)&pNode->datum.i; case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_UBIGINT: return (void *)&pNode->datum.u; case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_DOUBLE: return (void *)&pNode->datum.d; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARBINARY: return (void *)pNode->datum.p; default: break; } return NULL; } 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); } 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; } 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: return true; default: break; } return false; } 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; } bool nodesIsTimeorderQuery(const SNode* pQuery) { return false; } bool nodesIsTimelineQuery(const SNode* pQuery) { return false; }