nodesCloneFuncs.c 12.0 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/>.
 */

X
Xiaoyu Wang 已提交
16
#include "nodesUtil.h"
17
#include "plannodes.h"
X
Xiaoyu Wang 已提交
18 19
#include "querynodes.h"
#include "taos.h"
X
Xiaoyu Wang 已提交
20
#include "taoserror.h"
21

X
Xiaoyu Wang 已提交
22 23 24 25
#define COPY_SCALAR_FIELD(fldname) \
	do { \
    (pDst)->fldname = (pSrc)->fldname; \
	} while (0)
26

X
Xiaoyu Wang 已提交
27 28 29 30 31 32 33
#define COPY_CHAR_ARRAY_FIELD(fldname) \
	do { \
    strcpy((pDst)->fldname, (pSrc)->fldname); \
	} while (0)

#define COPY_CHAR_POINT_FIELD(fldname) \
	do { \
X
Xiaoyu Wang 已提交
34 35 36
    if (NULL == (pSrc)->fldname) { \
      break; \
    } \
X
Xiaoyu Wang 已提交
37 38 39
    (pDst)->fldname = strdup((pSrc)->fldname); \
	} while (0)

40
#define CLONE_NODE_FIELD(fldname) \
X
Xiaoyu Wang 已提交
41
	do { \
42 43 44
    if (NULL == (pSrc)->fldname) { \
      break; \
    } \
X
Xiaoyu Wang 已提交
45 46 47 48 49 50 51
    (pDst)->fldname = nodesCloneNode((pSrc)->fldname); \
    if (NULL == (pDst)->fldname) { \
      nodesDestroyNode((SNode*)(pDst)); \
      return NULL; \
    } \
	} while (0)

52
#define CLONE_NODE_LIST_FIELD(fldname) \
X
Xiaoyu Wang 已提交
53
	do { \
54 55 56
    if (NULL == (pSrc)->fldname) { \
      break; \
    } \
X
Xiaoyu Wang 已提交
57 58 59 60 61 62 63
    (pDst)->fldname = nodesCloneList((pSrc)->fldname); \
    if (NULL == (pDst)->fldname) { \
      nodesDestroyNode((SNode*)(pDst)); \
      return NULL; \
    } \
	} while (0)

64 65
#define CLONE_OBJECT_FIELD(fldname, cloneFunc) \
	do { \
X
Xiaoyu Wang 已提交
66 67 68
    if (NULL == (pSrc)->fldname) { \
      break; \
    } \
69 70 71 72 73 74 75 76 77 78 79 80 81 82
    (pDst)->fldname = cloneFunc((pSrc)->fldname); \
    if (NULL == (pDst)->fldname) { \
      nodesDestroyNode((SNode*)(pDst)); \
      return NULL; \
    } \
	} while (0)

#define COPY_BASE_OBJECT_FIELD(fldname, copyFunc) \
	do { \
    if (NULL == copyFunc(&((pSrc)->fldname), &((pDst)->fldname))) { \
      return NULL; \
    } \
	} while (0)

X
Xiaoyu Wang 已提交
83 84 85 86 87 88 89 90 91 92
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);
93
  // CLONE_NODE_LIST_FIELD(pAssociationList);
X
Xiaoyu Wang 已提交
94 95 96
}

static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
X
Xiaoyu Wang 已提交
97
  exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
X
Xiaoyu Wang 已提交
98 99 100 101 102 103
  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);
104
  // CLONE_NODE_FIELD(pProjectRef);
X
Xiaoyu Wang 已提交
105 106
  COPY_SCALAR_FIELD(dataBlockId);
  COPY_SCALAR_FIELD(slotId);
X
Xiaoyu Wang 已提交
107 108 109 110
  return (SNode*)pDst;
}

static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
X
Xiaoyu Wang 已提交
111
  exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
X
Xiaoyu Wang 已提交
112 113
  COPY_CHAR_POINT_FIELD(literal);
  COPY_SCALAR_FIELD(isDuration);
X
Xiaoyu Wang 已提交
114 115 116 117
  COPY_SCALAR_FIELD(translate);
  if (!pSrc->translate) {
    return (SNode*)pDst;
  }
X
Xiaoyu Wang 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  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_NCHAR:
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY:
X
Xiaoyu Wang 已提交
144 145 146 147 148 149
      pDst->datum.p = malloc(pSrc->node.resType.bytes + VARSTR_HEADER_SIZE);
      if (NULL == pDst->datum.p) {
        nodesDestroyNode(pDst);
        return NULL;
      }
      memcpy(pDst->datum.p, pSrc->datum.p, pSrc->node.resType.bytes + VARSTR_HEADER_SIZE);
X
Xiaoyu Wang 已提交
150 151 152 153 154 155 156 157 158 159 160 161
      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) {
X
Xiaoyu Wang 已提交
162
  exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
X
Xiaoyu Wang 已提交
163
  COPY_SCALAR_FIELD(opType);
164 165
  CLONE_NODE_FIELD(pLeft);
  CLONE_NODE_FIELD(pRight);
X
Xiaoyu Wang 已提交
166 167 168 169
  return (SNode*)pDst;
}

static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) {
X
Xiaoyu Wang 已提交
170
  exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
X
Xiaoyu Wang 已提交
171
  COPY_SCALAR_FIELD(condType);
172
  CLONE_NODE_LIST_FIELD(pParameterList);
X
Xiaoyu Wang 已提交
173 174 175 176
  return (SNode*)pDst;
}

static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
X
Xiaoyu Wang 已提交
177
  exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
X
Xiaoyu Wang 已提交
178 179 180
  COPY_CHAR_ARRAY_FIELD(functionName);
  COPY_SCALAR_FIELD(funcId);
  COPY_SCALAR_FIELD(funcType);
181
  CLONE_NODE_LIST_FIELD(pParameterList);
X
Xiaoyu Wang 已提交
182 183 184
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
185
static SNode* targetNodeCopy(const STargetNode* pSrc, STargetNode* pDst) {
X
Xiaoyu Wang 已提交
186
  COPY_SCALAR_FIELD(dataBlockId);
X
Xiaoyu Wang 已提交
187
  COPY_SCALAR_FIELD(slotId);
188
  CLONE_NODE_FIELD(pExpr);
X
Xiaoyu Wang 已提交
189 190 191
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
192 193
static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode* pDst) {
  COPY_SCALAR_FIELD(groupingSetType);
194 195 196 197
  CLONE_NODE_LIST_FIELD(pParameterList);
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
198 199 200 201 202 203
static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) {
  COPY_SCALAR_FIELD(mode);
  CLONE_NODE_FIELD(pValues);
  return (SNode*)pDst;
}

204 205 206 207 208 209 210 211
static SNode* logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
  CLONE_NODE_LIST_FIELD(pTargets);
  CLONE_NODE_FIELD(pConditions);
  CLONE_NODE_LIST_FIELD(pChildren);
  return (SNode*)pDst;
}

static STableMeta* tableMetaClone(const STableMeta* pSrc) {
X
Xiaoyu Wang 已提交
212
  int32_t len = TABLE_META_SIZE(pSrc);
213 214 215 216 217 218 219 220 221
  STableMeta* pDst = malloc(len);
  if (NULL == pDst) {
    return NULL;
  }
  memcpy(pDst, pSrc, len);
  return pDst;
}

static SVgroupsInfo* vgroupsInfoClone(const SVgroupsInfo* pSrc) {
X
Xiaoyu Wang 已提交
222
  int32_t len = VGROUPS_INFO_SIZE(pSrc);
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
  SVgroupsInfo* pDst = malloc(len);
  if (NULL == pDst) {
    return NULL;
  }
  memcpy(pDst, pSrc, len);
  return pDst;
}

static SNode* logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
  COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
  CLONE_NODE_LIST_FIELD(pScanCols);
  CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
  CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
  COPY_SCALAR_FIELD(scanType);
  COPY_SCALAR_FIELD(scanFlag);
  COPY_SCALAR_FIELD(scanRange);
X
Xiaoyu Wang 已提交
239
  COPY_SCALAR_FIELD(tableName);
240 241 242 243 244 245 246 247 248 249 250 251 252
  return (SNode*)pDst;
}

static SNode* logicAggCopy(const SAggLogicNode* pSrc, SAggLogicNode* pDst) {
  COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
  CLONE_NODE_LIST_FIELD(pGroupKeys);
  CLONE_NODE_LIST_FIELD(pAggFuncs);
  return (SNode*)pDst;
}

static SNode* logicProjectCopy(const SProjectLogicNode* pSrc, SProjectLogicNode* pDst) {
  COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
  CLONE_NODE_LIST_FIELD(pProjections);
X
Xiaoyu Wang 已提交
253 254 255
  return (SNode*)pDst;
}

256
static SNode* logicVnodeModifCopy(const SVnodeModifLogicNode* pSrc, SVnodeModifLogicNode* pDst) {
X
Xiaoyu Wang 已提交
257
  COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
258
  COPY_SCALAR_FIELD(msgType);
X
Xiaoyu Wang 已提交
259 260 261
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
262 263 264 265 266 267
static SNode* logicExchangeCopy(const SExchangeLogicNode* pSrc, SExchangeLogicNode* pDst) {
  COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
  COPY_SCALAR_FIELD(srcGroupId);
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
268 269 270 271 272 273 274
static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pDst) {
  COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
  COPY_SCALAR_FIELD(winType);
  CLONE_NODE_LIST_FIELD(pFuncs);
  COPY_SCALAR_FIELD(interval);
  COPY_SCALAR_FIELD(offset);
  COPY_SCALAR_FIELD(sliding);
275 276
  COPY_SCALAR_FIELD(intervalUnit);
  COPY_SCALAR_FIELD(slidingUnit);
X
Xiaoyu Wang 已提交
277
  CLONE_NODE_FIELD(pFill);
278
  COPY_SCALAR_FIELD(sessionGap);
X
Xiaoyu Wang 已提交
279 280 281
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
282
static SNode* logicSubplanCopy(const SLogicSubplan* pSrc, SLogicSubplan* pDst) {
283
  CLONE_NODE_FIELD(pNode);
284 285 286 287
  COPY_SCALAR_FIELD(subplanType);
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
288 289
static SNode* dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) {
  COPY_SCALAR_FIELD(dataBlockId);
290
  CLONE_NODE_LIST_FIELD(pSlots);
X
Xiaoyu Wang 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304
  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;
}

X
Xiaoyu Wang 已提交
305 306 307 308 309 310 311
static SNode* downstreamSourceCopy(const SDownstreamSourceNode* pSrc, SDownstreamSourceNode* pDst) {
  COPY_SCALAR_FIELD(addr);
  COPY_SCALAR_FIELD(taskId);
  COPY_SCALAR_FIELD(schedId);
  return (SNode*)pDst;
}

X
Xiaoyu Wang 已提交
312
SNodeptr nodesCloneNode(const SNodeptr pNode) {
X
Xiaoyu Wang 已提交
313 314 315 316 317
  if (NULL == pNode) {
    return NULL;
  }
  SNode* pDst = nodesMakeNode(nodeType(pNode));
  if (NULL == pDst) {
X
Xiaoyu Wang 已提交
318
    terrno = TSDB_CODE_OUT_OF_MEMORY;
X
Xiaoyu Wang 已提交
319 320 321 322 323 324 325 326 327 328 329 330 331
    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);
X
Xiaoyu Wang 已提交
332 333
    case QUERY_NODE_TARGET:
      return targetNodeCopy((const STargetNode*)pNode, (STargetNode*)pDst);
X
Xiaoyu Wang 已提交
334 335 336
    case QUERY_NODE_REAL_TABLE:
    case QUERY_NODE_TEMP_TABLE:
    case QUERY_NODE_JOIN_TABLE:
X
Xiaoyu Wang 已提交
337
      break;
X
Xiaoyu Wang 已提交
338
    case QUERY_NODE_GROUPING_SET:
X
Xiaoyu Wang 已提交
339
      return groupingSetNodeCopy((const SGroupingSetNode*)pNode, (SGroupingSetNode*)pDst);
X
Xiaoyu Wang 已提交
340 341
    case QUERY_NODE_ORDER_BY_EXPR:
    case QUERY_NODE_LIMIT:
342
      break;
X
Xiaoyu Wang 已提交
343 344
    case QUERY_NODE_FILL:
      return fillNodeCopy((const SFillNode*)pNode, (SFillNode*)pDst);
X
Xiaoyu Wang 已提交
345 346 347 348
    case QUERY_NODE_DATABLOCK_DESC:
      return dataBlockDescCopy((const SDataBlockDescNode*)pNode, (SDataBlockDescNode*)pDst);
    case QUERY_NODE_SLOT_DESC:
      return slotDescCopy((const SSlotDescNode*)pNode, (SSlotDescNode*)pDst);
X
Xiaoyu Wang 已提交
349 350
    case QUERY_NODE_DOWNSTREAM_SOURCE:
      return downstreamSourceCopy((const SDownstreamSourceNode*)pNode, (SDownstreamSourceNode*)pDst);
351 352 353 354 355 356 357 358
    case QUERY_NODE_LOGIC_PLAN_SCAN:
      return logicScanCopy((const SScanLogicNode*)pNode, (SScanLogicNode*)pDst);
    case QUERY_NODE_LOGIC_PLAN_AGG:
      return logicAggCopy((const SAggLogicNode*)pNode, (SAggLogicNode*)pDst);
    case QUERY_NODE_LOGIC_PLAN_PROJECT:
      return logicProjectCopy((const SProjectLogicNode*)pNode, (SProjectLogicNode*)pDst);
    case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
      return logicVnodeModifCopy((const SVnodeModifLogicNode*)pNode, (SVnodeModifLogicNode*)pDst);
X
Xiaoyu Wang 已提交
359 360
    case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
      return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst);
X
Xiaoyu Wang 已提交
361 362
    case QUERY_NODE_LOGIC_PLAN_WINDOW:
      return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst);
363
    case QUERY_NODE_LOGIC_SUBPLAN:
X
Xiaoyu Wang 已提交
364
      return logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst);
X
Xiaoyu Wang 已提交
365 366 367
    default:
      break;
  }
368 369 370
  nodesDestroyNode(pDst);
  nodesError("nodesCloneNode unknown node = %s", nodesNodeName(nodeType(pNode)));
  return NULL;
X
Xiaoyu Wang 已提交
371 372 373
}

SNodeList* nodesCloneList(const SNodeList* pList) {
X
Xiaoyu Wang 已提交
374 375 376 377
  if (NULL == pList) {
    return NULL;
  }

X
Xiaoyu Wang 已提交
378 379
  SNodeList* pDst = nodesMakeList();
  if (NULL == pDst) {
X
Xiaoyu Wang 已提交
380
    terrno = TSDB_CODE_OUT_OF_MEMORY;
X
Xiaoyu Wang 已提交
381 382 383 384 385 386 387 388 389 390 391 392
    return NULL;
  }
  SNode* pNode;
  FOREACH(pNode, pList) {
    SNode* pNewNode = nodesCloneNode(pNode);
    if (NULL == pNewNode) {
      nodesDestroyList(pDst);
      return NULL;
    }
    nodesListAppend(pDst, pNewNode);
  }
  return pDst;
393
}