249 lines
7.4 KiB
C
249 lines
7.4 KiB
C
/*
|
|
* 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 "plannodes.h"
|
|
#include "querynodes.h"
|
|
#include "taos.h"
|
|
#include "taoserror.h"
|
|
|
|
#define COPY_SCALAR_FIELD(fldname) \
|
|
do { \
|
|
(pDst)->fldname = (pSrc)->fldname; \
|
|
} while (0)
|
|
|
|
#define COPY_CHAR_ARRAY_FIELD(fldname) \
|
|
do { \
|
|
strcpy((pDst)->fldname, (pSrc)->fldname); \
|
|
} while (0)
|
|
|
|
#define COPY_CHAR_POINT_FIELD(fldname) \
|
|
do { \
|
|
(pDst)->fldname = strdup((pSrc)->fldname); \
|
|
} while (0)
|
|
|
|
#define COPY_NODE_FIELD(fldname) \
|
|
do { \
|
|
(pDst)->fldname = nodesCloneNode((pSrc)->fldname); \
|
|
if (NULL == (pDst)->fldname) { \
|
|
nodesDestroyNode((SNode*)(pDst)); \
|
|
return NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define COPY_NODE_LIST_FIELD(fldname) \
|
|
do { \
|
|
(pDst)->fldname = nodesCloneList((pSrc)->fldname); \
|
|
if (NULL == (pDst)->fldname) { \
|
|
nodesDestroyNode((SNode*)(pDst)); \
|
|
return NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
static void dataTypeCopy(const SDataType* pSrc, SDataType* pDst) {
|
|
COPY_SCALAR_FIELD(type);
|
|
COPY_SCALAR_FIELD(precision);
|
|
COPY_SCALAR_FIELD(scale);
|
|
COPY_SCALAR_FIELD(bytes);
|
|
}
|
|
|
|
static void exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
|
|
dataTypeCopy(&pSrc->resType, &pDst->resType);
|
|
COPY_CHAR_ARRAY_FIELD(aliasName);
|
|
// COPY_NODE_LIST_FIELD(pAssociationList);
|
|
}
|
|
|
|
static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
|
COPY_SCALAR_FIELD(colId);
|
|
COPY_SCALAR_FIELD(colType);
|
|
COPY_CHAR_ARRAY_FIELD(dbName);
|
|
COPY_CHAR_ARRAY_FIELD(tableName);
|
|
COPY_CHAR_ARRAY_FIELD(tableAlias);
|
|
COPY_CHAR_ARRAY_FIELD(colName);
|
|
// COPY_NODE_FIELD(pProjectRef);
|
|
COPY_SCALAR_FIELD(dataBlockId);
|
|
COPY_SCALAR_FIELD(slotId);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
|
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
|
COPY_CHAR_POINT_FIELD(literal);
|
|
COPY_SCALAR_FIELD(isDuration);
|
|
switch (pSrc->node.resType.type) {
|
|
case TSDB_DATA_TYPE_NULL:
|
|
break;
|
|
case TSDB_DATA_TYPE_BOOL:
|
|
COPY_SCALAR_FIELD(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:
|
|
COPY_SCALAR_FIELD(datum.i);
|
|
break;
|
|
case TSDB_DATA_TYPE_UTINYINT:
|
|
case TSDB_DATA_TYPE_USMALLINT:
|
|
case TSDB_DATA_TYPE_UINT:
|
|
case TSDB_DATA_TYPE_UBIGINT:
|
|
COPY_SCALAR_FIELD(datum.u);
|
|
break;
|
|
case TSDB_DATA_TYPE_FLOAT:
|
|
case TSDB_DATA_TYPE_DOUBLE:
|
|
COPY_SCALAR_FIELD(datum.d);
|
|
break;
|
|
case TSDB_DATA_TYPE_BINARY:
|
|
case TSDB_DATA_TYPE_NCHAR:
|
|
case TSDB_DATA_TYPE_VARCHAR:
|
|
case TSDB_DATA_TYPE_VARBINARY:
|
|
COPY_CHAR_POINT_FIELD(datum.p);
|
|
break;
|
|
case TSDB_DATA_TYPE_JSON:
|
|
case TSDB_DATA_TYPE_DECIMAL:
|
|
case TSDB_DATA_TYPE_BLOB:
|
|
// todo
|
|
default:
|
|
break;
|
|
}
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) {
|
|
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
|
COPY_SCALAR_FIELD(opType);
|
|
COPY_NODE_FIELD(pLeft);
|
|
COPY_NODE_FIELD(pRight);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) {
|
|
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
|
COPY_SCALAR_FIELD(condType);
|
|
COPY_NODE_LIST_FIELD(pParameterList);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
|
|
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
|
COPY_CHAR_ARRAY_FIELD(functionName);
|
|
COPY_SCALAR_FIELD(funcId);
|
|
COPY_SCALAR_FIELD(funcType);
|
|
COPY_NODE_LIST_FIELD(pParameterList);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* targetNodeCopy(const STargetNode* pSrc, STargetNode* pDst) {
|
|
COPY_SCALAR_FIELD(dataBlockId);
|
|
COPY_SCALAR_FIELD(slotId);
|
|
COPY_NODE_FIELD(pExpr);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode* pDst) {
|
|
COPY_SCALAR_FIELD(groupingSetType);
|
|
COPY_NODE_LIST_FIELD(pParameterList);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* logicSubplanCopy(const SSubLogicPlan* pSrc, SSubLogicPlan* pDst) {
|
|
COPY_NODE_FIELD(pNode);
|
|
COPY_SCALAR_FIELD(subplanType);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) {
|
|
COPY_SCALAR_FIELD(dataBlockId);
|
|
COPY_NODE_LIST_FIELD(pSlots);
|
|
COPY_SCALAR_FIELD(resultRowSize);
|
|
COPY_SCALAR_FIELD(precision);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
static SNode* slotDescCopy(const SSlotDescNode* pSrc, SSlotDescNode* pDst) {
|
|
COPY_SCALAR_FIELD(slotId);
|
|
dataTypeCopy(&pSrc->dataType, &pDst->dataType);
|
|
COPY_SCALAR_FIELD(reserve);
|
|
COPY_SCALAR_FIELD(output);
|
|
COPY_SCALAR_FIELD(tag);
|
|
return (SNode*)pDst;
|
|
}
|
|
|
|
SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|
if (NULL == pNode) {
|
|
return NULL;
|
|
}
|
|
SNode* pDst = nodesMakeNode(nodeType(pNode));
|
|
if (NULL == pDst) {
|
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
return NULL;
|
|
}
|
|
switch (nodeType(pNode)) {
|
|
case QUERY_NODE_COLUMN:
|
|
return columnNodeCopy((const SColumnNode*)pNode, (SColumnNode*)pDst);
|
|
case QUERY_NODE_VALUE:
|
|
return valueNodeCopy((const SValueNode*)pNode, (SValueNode*)pDst);
|
|
case QUERY_NODE_OPERATOR:
|
|
return operatorNodeCopy((const SOperatorNode*)pNode, (SOperatorNode*)pDst);
|
|
case QUERY_NODE_LOGIC_CONDITION:
|
|
return logicConditionNodeCopy((const SLogicConditionNode*)pNode, (SLogicConditionNode*)pDst);
|
|
case QUERY_NODE_FUNCTION:
|
|
return functionNodeCopy((const SFunctionNode*)pNode, (SFunctionNode*)pDst);
|
|
case QUERY_NODE_TARGET:
|
|
return targetNodeCopy((const STargetNode*)pNode, (STargetNode*)pDst);
|
|
case QUERY_NODE_REAL_TABLE:
|
|
case QUERY_NODE_TEMP_TABLE:
|
|
case QUERY_NODE_JOIN_TABLE:
|
|
break;
|
|
case QUERY_NODE_GROUPING_SET:
|
|
return groupingSetNodeCopy((const SGroupingSetNode*)pNode, (SGroupingSetNode*)pDst);
|
|
case QUERY_NODE_ORDER_BY_EXPR:
|
|
case QUERY_NODE_LIMIT:
|
|
break;
|
|
case QUERY_NODE_DATABLOCK_DESC:
|
|
return dataBlockDescCopy((const SDataBlockDescNode*)pNode, (SDataBlockDescNode*)pDst);
|
|
case QUERY_NODE_SLOT_DESC:
|
|
return slotDescCopy((const SSlotDescNode*)pNode, (SSlotDescNode*)pDst);
|
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
|
return logicSubplanCopy((const SSubLogicPlan*)pNode, (SSubLogicPlan*)pDst);
|
|
default:
|
|
break;
|
|
}
|
|
printf("nodesCloneNode unknown node = %s\n", nodesNodeName(nodeType(pNode)));
|
|
return pDst;
|
|
}
|
|
|
|
SNodeList* nodesCloneList(const SNodeList* pList) {
|
|
if (NULL == pList) {
|
|
return NULL;
|
|
}
|
|
|
|
SNodeList* pDst = nodesMakeList();
|
|
if (NULL == pDst) {
|
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
return NULL;
|
|
}
|
|
SNode* pNode;
|
|
FOREACH(pNode, pList) {
|
|
SNode* pNewNode = nodesCloneNode(pNode);
|
|
if (NULL == pNewNode) {
|
|
nodesDestroyList(pDst);
|
|
return NULL;
|
|
}
|
|
nodesListAppend(pDst, pNewNode);
|
|
}
|
|
return pDst;
|
|
}
|