physicalPlanJson.c 19.9 KB
Newer Older
X
Xiaoyu Wang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * 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 "plannerInt.h"
#include "parser.h"
#include "cJSON.h"

X
Xiaoyu Wang 已提交
20 21
typedef bool (*FToJson)(const void* obj, cJSON* json); 
typedef bool (*FFromJson)(const cJSON* json, void* obj); 
X
Xiaoyu Wang 已提交
22

X
Xiaoyu Wang 已提交
23
static bool addObject(cJSON* json, const char* name, FToJson func, const void* obj) {
X
Xiaoyu Wang 已提交
24 25 26 27
  if (NULL == obj) {
    return true;
  }

X
Xiaoyu Wang 已提交
28 29 30
  cJSON* jObj = cJSON_CreateObject();
  if (NULL == jObj || !func(obj, jObj)) {
    cJSON_Delete(jObj);
X
Xiaoyu Wang 已提交
31 32 33 34 35
    return false;
  }
  return cJSON_AddItemToObject(json, name, jObj);
}

X
Xiaoyu Wang 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
static bool addItem(cJSON* json, FToJson func, const void* obj) {
  cJSON* jObj = cJSON_CreateObject();
  if (NULL == jObj || !func(obj, jObj)) {
    cJSON_Delete(jObj);
    return false;
  }
  return cJSON_AddItemToArray(json, jObj);
}

static bool fromObject(const cJSON* json, const char* name, FFromJson func, void* obj, bool required) {
  cJSON* jObj = cJSON_GetObjectItem(json, name);
  if (NULL == jObj) {
    return !required;
  }
  return func(jObj, obj);
}

static bool fromObjectWithAlloc(const cJSON* json, const char* name, FFromJson func, void** obj, int32_t size, bool required) {
  cJSON* jObj = cJSON_GetObjectItem(json, name);
  if (NULL == jObj) {
    return !required;
  }
  *obj = calloc(1, size);
  if (NULL == *obj) {
X
Xiaoyu Wang 已提交
60 61
    return false;
  }
X
Xiaoyu Wang 已提交
62
  return func(jObj, *obj);
X
Xiaoyu Wang 已提交
63 64
}

X
Xiaoyu Wang 已提交
65
static bool addArray(cJSON* json, const char* name, FToJson func, const SArray* array) {
X
Xiaoyu Wang 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  size_t size = (NULL == array) ? 0 : taosArrayGetSize(array);
  if (size > 0) {
    cJSON* jArray = cJSON_AddArrayToObject(json, name);
    if (NULL == jArray) {
      return false;
    }
    for (size_t i = 0; i < size; ++i) {
      if (!addItem(jArray, func, taosArrayGetP(array, i))) {
        return false;
      }
    }
  }
  return true;
}

X
Xiaoyu Wang 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
static bool fromArray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize) {
  const cJSON* jArray = cJSON_GetObjectItem(json, name);
  int32_t size = (NULL == jArray ? 0 : cJSON_GetArraySize(jArray));
  if (size > 0) {
    *array = taosArrayInit(size, POINTER_BYTES);
    if (NULL == *array) {
      return false;
    }
  }
  for (int32_t i = 0; i < size; ++i) {
    void* item = calloc(1, itemSize);
    if (NULL == item || !func(cJSON_GetArrayItem(jArray, i), item)) {
      return false;
    }
    taosArrayPush(*array, &item);
  }
  return true;
}

static bool addRawArray(cJSON* json, const char* name, FToJson func, const void* array, int32_t itemSize, int32_t size) {
X
Xiaoyu Wang 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114
  if (size > 0) {
    cJSON* jArray = cJSON_AddArrayToObject(json, name);
    if (NULL == jArray) {
      return false;
    }
    for (size_t i = 0; i < size; ++i) {
      if (!addItem(jArray, func, (const char*)array + itemSize * i)) {
        return false;
      }
    }
  }
  return true;
}

X
Xiaoyu Wang 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
static const cJSON* getArray(const cJSON* json, const char* name, int32_t* size) {
  const cJSON* jArray = cJSON_GetObjectItem(json, name);
  *size = (NULL == jArray ? 0 : cJSON_GetArraySize(jArray));
  return jArray;
}

static bool fromItem(const cJSON* jArray, FFromJson func, void* array, int32_t itemSize, int32_t size) {
  for (int32_t i = 0; i < size; ++i) {
    if (!func(cJSON_GetArrayItem(jArray, i), (char*)array + itemSize)) {
      return false;
    }
  }
  return true;
}

static bool fromRawArrayWithAlloc(const cJSON* json, const char* name, FFromJson func, void** array, int32_t itemSize, int32_t* size) {
  const cJSON* jArray = getArray(json, name, size);
  if (*size > 0) {
    *array = calloc(1, itemSize * (*size));
    if (NULL == *array) {
      return false;
    }
X
Xiaoyu Wang 已提交
137
  }
X
Xiaoyu Wang 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
  return fromItem(jArray, func, *array, itemSize, *size);
}

static bool fromRawArray(const cJSON* json, const char* name, FFromJson func, void* array, int32_t itemSize, int32_t* size) {
  const cJSON* jArray = getArray(json, name, size);
  return fromItem(jArray, func, array, itemSize, *size);
}

static char* getString(const cJSON* json, const char* name) {
  char* p = cJSON_GetStringValue(cJSON_GetObjectItem(json, name));
  char* res = calloc(1, strlen(p) + 1);
  strcpy(res, p);
  return res;
}

static void copyString(const cJSON* json, const char* name, char* dst) {
  strcpy(dst, cJSON_GetStringValue(cJSON_GetObjectItem(json, name)));
}
X
Xiaoyu Wang 已提交
156

X
Xiaoyu Wang 已提交
157 158 159
static int64_t getNumber(const cJSON* json, const char* name) {
  return cJSON_GetNumberValue(cJSON_GetObjectItem(json, name));
}
X
Xiaoyu Wang 已提交
160

X
Xiaoyu Wang 已提交
161 162 163 164 165 166 167
static const char* jkSchemaType = "Type";
static const char* jkSchemaColId = "ColId";
static const char* jkSchemaBytes = "Bytes";
// The 'name' field do not need to be serialized.
static bool schemaToJson(const void* obj, cJSON* jSchema) {
  const SSlotSchema* schema = (const SSlotSchema*)obj;
  bool res = cJSON_AddNumberToObject(jSchema, jkSchemaType, schema->type);
X
Xiaoyu Wang 已提交
168
  if (res) {
X
Xiaoyu Wang 已提交
169
    res = cJSON_AddNumberToObject(jSchema, jkSchemaColId, schema->colId);
X
Xiaoyu Wang 已提交
170 171
  }
  if (res) {
X
Xiaoyu Wang 已提交
172
    res = cJSON_AddNumberToObject(jSchema, jkSchemaBytes, schema->bytes);
X
Xiaoyu Wang 已提交
173
  }
X
Xiaoyu Wang 已提交
174 175
  return res;
}
X
Xiaoyu Wang 已提交
176

X
Xiaoyu Wang 已提交
177 178 179 180 181 182
static bool schemaFromJson(const cJSON* json, void* obj) {
  SSlotSchema* schema = (SSlotSchema*)obj;
  schema->type = getNumber(json, jkSchemaType);
  schema->colId = getNumber(json, jkSchemaColId);
  schema->bytes = getNumber(json, jkSchemaBytes);
  return true;
X
Xiaoyu Wang 已提交
183 184
}

X
Xiaoyu Wang 已提交
185 186 187 188 189
static const char* jkColumnFilterInfoLowerRelOptr = "LowerRelOptr";
static const char* jkColumnFilterInfoUpperRelOptr = "UpperRelOptr";
static const char* jkColumnFilterInfoFilterstr = "Filterstr";
static const char* jkColumnFilterInfoLowerBnd = "LowerBnd";
static const char* jkColumnFilterInfoUpperBnd = "UpperBnd";
X
Xiaoyu Wang 已提交
190

X
Xiaoyu Wang 已提交
191 192 193
static bool columnFilterInfoToJson(const void* obj, cJSON* jFilter) {
  const SColumnFilterInfo* filter = (const SColumnFilterInfo*)obj;
  bool res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoLowerRelOptr, filter->lowerRelOptr);
X
Xiaoyu Wang 已提交
194
  if (res) {
X
Xiaoyu Wang 已提交
195
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoUpperRelOptr, filter->upperRelOptr);
X
Xiaoyu Wang 已提交
196 197
  }
  if (res) {
X
Xiaoyu Wang 已提交
198
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoFilterstr, filter->filterstr);
X
Xiaoyu Wang 已提交
199 200
  }
  if (res) {
X
Xiaoyu Wang 已提交
201
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoLowerBnd, filter->lowerBndd);
X
Xiaoyu Wang 已提交
202 203
  }
  if (res) {
X
Xiaoyu Wang 已提交
204
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoUpperBnd, filter->upperBndd);
X
Xiaoyu Wang 已提交
205
  }
X
Xiaoyu Wang 已提交
206 207
  return res;
}
X
Xiaoyu Wang 已提交
208

X
Xiaoyu Wang 已提交
209 210 211 212 213 214 215 216
static bool columnFilterInfoFromJson(const cJSON* json, void* obj) {
  SColumnFilterInfo* filter = (SColumnFilterInfo*)obj;
  filter->lowerRelOptr = getNumber(json, jkColumnFilterInfoLowerRelOptr);
  filter->upperRelOptr = getNumber(json, jkColumnFilterInfoUpperRelOptr);
  filter->filterstr = getNumber(json, jkColumnFilterInfoFilterstr);
  filter->lowerBndd = getNumber(json, jkColumnFilterInfoLowerBnd);
  filter->upperBndd = getNumber(json, jkColumnFilterInfoUpperBnd);
  return true;
X
Xiaoyu Wang 已提交
217 218
}

X
Xiaoyu Wang 已提交
219 220 221 222
static const char* jkColumnInfoColId = "ColId";
static const char* jkColumnInfoType = "Type";
static const char* jkColumnInfoBytes = "Bytes";
static const char* jkColumnInfoFilterList = "FilterList";
X
Xiaoyu Wang 已提交
223

X
Xiaoyu Wang 已提交
224 225 226
static bool columnInfoToJson(const void* obj, cJSON* jCol) {
  const SColumnInfo* col = (const SColumnInfo*)obj;
  bool res = cJSON_AddNumberToObject(jCol, jkColumnInfoColId, col->colId);
X
Xiaoyu Wang 已提交
227
  if (res) {
X
Xiaoyu Wang 已提交
228
    res = cJSON_AddNumberToObject(jCol, jkColumnInfoType, col->type);
X
Xiaoyu Wang 已提交
229 230
  }
  if (res) {
X
Xiaoyu Wang 已提交
231
    res = cJSON_AddNumberToObject(jCol, jkColumnInfoBytes, col->bytes);
X
Xiaoyu Wang 已提交
232 233
  }
  if (res) {
X
Xiaoyu Wang 已提交
234
    res = addRawArray(jCol, jkColumnInfoFilterList, columnFilterInfoToJson, col->flist.filterInfo, sizeof(SColumnFilterInfo), col->flist.numOfFilters);
X
Xiaoyu Wang 已提交
235
  }
X
Xiaoyu Wang 已提交
236 237
  return res;
}
X
Xiaoyu Wang 已提交
238

X
Xiaoyu Wang 已提交
239 240 241 242 243 244 245 246 247
static bool columnInfoFromJson(const cJSON* json, void* obj) {
  SColumnInfo* col = (SColumnInfo*)obj;
  col->colId = getNumber(json, jkColumnInfoColId);
  col->type = getNumber(json, jkColumnInfoType);
  col->bytes = getNumber(json, jkColumnInfoBytes);
  int32_t size = 0;
  bool res = fromRawArrayWithAlloc(json, jkColumnInfoFilterList, columnFilterInfoFromJson, (void**)&col->flist.filterInfo, sizeof(SColumnFilterInfo), &size);
  col->flist.numOfFilters = size;
  return res;
X
Xiaoyu Wang 已提交
248 249
}

X
Xiaoyu Wang 已提交
250 251 252
static const char* jkColumnTableId = "TableId";
static const char* jkColumnFlag = "Flag";
static const char* jkColumnInfo = "Info";
X
Xiaoyu Wang 已提交
253

X
Xiaoyu Wang 已提交
254 255 256
static bool columnToJson(const void* obj, cJSON* jCol) {
  const SColumn* col = (const SColumn*)obj;
  bool res = cJSON_AddNumberToObject(jCol, jkColumnTableId, col->uid);
X
Xiaoyu Wang 已提交
257
  if (res) {
X
Xiaoyu Wang 已提交
258
    res = cJSON_AddNumberToObject(jCol, jkColumnFlag, col->flag);
X
Xiaoyu Wang 已提交
259 260
  }
  if (res) {
X
Xiaoyu Wang 已提交
261
    res = addObject(jCol, jkColumnInfo, columnInfoToJson, &col->info);
X
Xiaoyu Wang 已提交
262
  }
X
Xiaoyu Wang 已提交
263 264
  return res;
}
X
Xiaoyu Wang 已提交
265

X
Xiaoyu Wang 已提交
266 267 268 269 270
static bool columnFromJson(const cJSON* json, void* obj) {
  SColumn* col = (SColumn*)obj;
  col->uid = getNumber(json, jkColumnTableId);
  col->flag = getNumber(json, jkColumnFlag);
  return fromObject(json, jkColumnInfo, columnInfoFromJson, &col->info, true);
X
Xiaoyu Wang 已提交
271 272
}

X
Xiaoyu Wang 已提交
273 274
static bool exprNodeToJson(const void* obj, cJSON* jExprInfo);
static bool exprNodeFromJson(const cJSON* json, void* obj);
X
Xiaoyu Wang 已提交
275

X
Xiaoyu Wang 已提交
276 277 278
static const char* jkExprNodeOper = "Oper";
static const char* jkExprNodeLeft = "Left";
static const char* jkExprNodeRight = "Right";
X
Xiaoyu Wang 已提交
279

X
Xiaoyu Wang 已提交
280 281 282
static bool operatorToJson(const void* obj, cJSON* jOper) {
  const tExprNode* exprInfo = (const tExprNode*)obj;
  bool res = cJSON_AddNumberToObject(jOper, jkExprNodeOper, exprInfo->_node.optr);
X
Xiaoyu Wang 已提交
283
  if (res) {
X
Xiaoyu Wang 已提交
284
    res = addObject(jOper, jkExprNodeLeft, exprNodeToJson, exprInfo->_node.pLeft);
X
Xiaoyu Wang 已提交
285 286
  }
  if (res) {
X
Xiaoyu Wang 已提交
287
    res = addObject(jOper, jkExprNodeRight, exprNodeToJson, exprInfo->_node.pRight);
X
Xiaoyu Wang 已提交
288
  }
X
Xiaoyu Wang 已提交
289 290
  return res;
}
X
Xiaoyu Wang 已提交
291

X
Xiaoyu Wang 已提交
292 293 294 295 296 297
static bool operatorFromJson(const cJSON* json, void* obj) {
  tExprNode* exprInfo = (tExprNode*)obj;
  exprInfo->_node.optr = getNumber(json, jkExprNodeOper);
  bool res = fromObject(json, jkExprNodeLeft, exprNodeFromJson, exprInfo->_node.pLeft, false);
  if (res) {
    res = fromObject(json, jkExprNodeRight, exprNodeFromJson, exprInfo->_node.pRight, false);
X
Xiaoyu Wang 已提交
298
  }
X
Xiaoyu Wang 已提交
299
  return res;
X
Xiaoyu Wang 已提交
300 301
}

X
Xiaoyu Wang 已提交
302 303
static const char* jkFunctionName = "Name";
static const char* jkFunctionChild = "Child";
X
Xiaoyu Wang 已提交
304

X
Xiaoyu Wang 已提交
305 306 307
static bool functionToJson(const void* obj, cJSON* jFunc) {
  const tExprNode* exprInfo = (const tExprNode*)obj;
  bool res = cJSON_AddStringToObject(jFunc, jkFunctionName, exprInfo->_function.functionName);
X
Xiaoyu Wang 已提交
308
  if (res) {
X
Xiaoyu Wang 已提交
309
    res = addRawArray(jFunc, jkFunctionChild, exprNodeToJson, exprInfo->_function.pChild, sizeof(tExprNode*), exprInfo->_function.num);
X
Xiaoyu Wang 已提交
310
  }
X
Xiaoyu Wang 已提交
311 312
  return res;
}
X
Xiaoyu Wang 已提交
313

X
Xiaoyu Wang 已提交
314 315 316 317
static bool functionFromJson(const cJSON* json, void* obj) {
  tExprNode* exprInfo = (tExprNode*)obj;
  copyString(json, jkFunctionName, exprInfo->_function.functionName);
  return fromRawArrayWithAlloc(json, jkFunctionChild, exprNodeFromJson, (void**)exprInfo->_function.pChild, sizeof(tExprNode*), &exprInfo->_function.num);
X
Xiaoyu Wang 已提交
318 319
}

X
Xiaoyu Wang 已提交
320 321 322 323
static const char* jkVariantType = "Type";
static const char* jkVariantLen = "Len";
static const char* jkVariantvalues = "values";
static const char* jkVariantValue = "Value";
X
Xiaoyu Wang 已提交
324

X
Xiaoyu Wang 已提交
325 326 327
static bool variantToJson(const void* obj, cJSON* jVar) {
  const SVariant* var = (const SVariant*)obj;
  bool res = cJSON_AddNumberToObject(jVar, jkVariantType, var->nType);
X
Xiaoyu Wang 已提交
328
  if (res) {
X
Xiaoyu Wang 已提交
329
    res = cJSON_AddNumberToObject(jVar, jkVariantLen, var->nLen);
X
Xiaoyu Wang 已提交
330 331 332
  }
  if (res) {
    if (0/* in */) {
X
Xiaoyu Wang 已提交
333
      res = addArray(jVar, jkVariantvalues, variantToJson, var->arr);
X
Xiaoyu Wang 已提交
334
    } else if (IS_NUMERIC_TYPE(var->nType)) {
X
Xiaoyu Wang 已提交
335
      res = cJSON_AddNumberToObject(jVar, jkVariantValue, var->d);
X
Xiaoyu Wang 已提交
336
    } else {
X
Xiaoyu Wang 已提交
337
      res = cJSON_AddStringToObject(jVar, jkVariantValue, var->pz);
X
Xiaoyu Wang 已提交
338 339
    }
  }
X
Xiaoyu Wang 已提交
340 341
  return res;
}
X
Xiaoyu Wang 已提交
342

X
Xiaoyu Wang 已提交
343 344 345 346 347 348 349 350 351 352
static bool variantFromJson(const cJSON* json, void* obj) {
  SVariant* var = (SVariant*)obj;
  var->nType = getNumber(json, jkVariantType);
  var->nLen = getNumber(json, jkVariantLen);
  if (0/* in */) {
    return fromArray(json, jkVariantvalues, variantFromJson, &var->arr, sizeof(SVariant));
  } else if (IS_NUMERIC_TYPE(var->nType)) {
    var->d = getNumber(json, jkVariantValue);
  } else {
    var->pz = getString(json, jkVariantValue);
X
Xiaoyu Wang 已提交
353
  }
X
Xiaoyu Wang 已提交
354
  return true;
X
Xiaoyu Wang 已提交
355 356
}

X
Xiaoyu Wang 已提交
357 358 359 360 361
static const char* jkExprNodeType = "Type";
static const char* jkExprNodeOperator = "Operator";
static const char* jkExprNodeFunction = "Function";
static const char* jkExprNodeColumn = "Column";
static const char* jkExprNodeValue = "Value";
X
Xiaoyu Wang 已提交
362

X
Xiaoyu Wang 已提交
363 364 365
static bool exprNodeToJson(const void* obj, cJSON* jExprInfo) {
  const tExprNode* exprInfo = (const tExprNode*)obj;
  bool res = cJSON_AddNumberToObject(jExprInfo, jkExprNodeType, exprInfo->nodeType);
X
Xiaoyu Wang 已提交
366 367 368 369
  if (res) {
    switch (exprInfo->nodeType) {
      case TEXPR_BINARYEXPR_NODE:
      case TEXPR_UNARYEXPR_NODE:
X
Xiaoyu Wang 已提交
370
        res = addObject(jExprInfo, jkExprNodeOperator, operatorToJson, exprInfo);
X
Xiaoyu Wang 已提交
371 372
        break;
      case TEXPR_FUNCTION_NODE:
X
Xiaoyu Wang 已提交
373
        res = addObject(jExprInfo, jkExprNodeFunction, functionToJson, exprInfo);
X
Xiaoyu Wang 已提交
374 375
        break;
      case TEXPR_COL_NODE:
X
Xiaoyu Wang 已提交
376
        res = addObject(jExprInfo, jkExprNodeColumn, schemaToJson, exprInfo->pSchema);
X
Xiaoyu Wang 已提交
377 378
        break;
      case TEXPR_VALUE_NODE:
X
Xiaoyu Wang 已提交
379
        res = addObject(jExprInfo, jkExprNodeValue, variantToJson, exprInfo->pVal);
X
Xiaoyu Wang 已提交
380 381 382 383 384 385
        break;
      default:
        res = false;
        break;
    }
  }
X
Xiaoyu Wang 已提交
386 387
  return res;
}
X
Xiaoyu Wang 已提交
388

X
Xiaoyu Wang 已提交
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
static bool exprNodeFromJson(const cJSON* json, void* obj) {
  tExprNode* exprInfo = (tExprNode*)obj;
  exprInfo->nodeType = getNumber(json, jkExprNodeType);
  switch (exprInfo->nodeType) {
    case TEXPR_BINARYEXPR_NODE:
    case TEXPR_UNARYEXPR_NODE:
      return fromObject(json, jkExprNodeOperator, operatorFromJson, exprInfo, false);
    case TEXPR_FUNCTION_NODE:
      return fromObject(json, jkExprNodeFunction, functionFromJson, exprInfo, false);
    case TEXPR_COL_NODE:
      return fromObject(json, jkExprNodeColumn, schemaFromJson, exprInfo->pSchema, false);
    case TEXPR_VALUE_NODE:
      return fromObject(json, jkExprNodeValue, variantFromJson, exprInfo->pVal, false);
    default:
      break;
  }
  return false;
X
Xiaoyu Wang 已提交
406 407
}

X
Xiaoyu Wang 已提交
408 409 410 411 412 413
static const char* jkSqlExprSchema = "Schema";
static const char* jkSqlExprColumns = "Columns";
static const char* jkSqlExprInterBytes = "InterBytes";
static const char* jkSqlExprParams = "Params";
// token does not need to be serialized.
static bool sqlExprToJson(const void* obj, cJSON* jExpr) {
X
Xiaoyu Wang 已提交
414
  const SSqlExpr* expr = (const SSqlExpr*)obj;
X
Xiaoyu Wang 已提交
415
  bool res = addObject(jExpr, jkSqlExprSchema, schemaToJson, &expr->resSchema);
X
Xiaoyu Wang 已提交
416
  if (res) {
X
Xiaoyu Wang 已提交
417
    res = addRawArray(jExpr, jkSqlExprColumns, columnToJson, expr->pColumns, sizeof(SColumn), expr->numOfCols);
X
Xiaoyu Wang 已提交
418 419
  }
  if (res) {
X
Xiaoyu Wang 已提交
420
    res = cJSON_AddNumberToObject(jExpr, jkSqlExprInterBytes, expr->interBytes);
X
Xiaoyu Wang 已提交
421 422
  }
  if (res) {
X
Xiaoyu Wang 已提交
423
    res = addRawArray(jExpr, jkSqlExprParams, variantToJson, expr->param, sizeof(SVariant), expr->numOfParams);
X
Xiaoyu Wang 已提交
424
  }
X
Xiaoyu Wang 已提交
425 426
  return res;
}
X
Xiaoyu Wang 已提交
427

X
Xiaoyu Wang 已提交
428 429 430 431 432 433 434 435 436 437 438 439 440
static bool sqlExprFromJson(const cJSON* json, void* obj) {
  SSqlExpr* expr = (SSqlExpr*)obj;
  bool res = fromObject(json, jkSqlExprSchema, schemaFromJson, &expr->resSchema, false);
  if (res) {
    res = fromRawArrayWithAlloc(json, jkSqlExprColumns, columnFromJson, (void**)&expr->pColumns, sizeof(SColumn), &expr->numOfCols);
  }
  if (res) {
    expr->interBytes = getNumber(json, jkSqlExprInterBytes);
  }
  if (res) {
    int32_t size = 0;
    res = fromRawArray(json, jkSqlExprParams, variantFromJson, expr->param, sizeof(SVariant), &size);
    expr->numOfParams = size;
X
Xiaoyu Wang 已提交
441
  }
X
Xiaoyu Wang 已提交
442
  return res;
X
Xiaoyu Wang 已提交
443 444
}

X
Xiaoyu Wang 已提交
445 446
static const char* jkExprInfoBase = "Base";
static const char* jkExprInfoExpr = "Expr";
X
Xiaoyu Wang 已提交
447

X
Xiaoyu Wang 已提交
448 449 450
static bool exprInfoToJson(const void* obj, cJSON* jExprInfo) {
  const SExprInfo* exprInfo = (const SExprInfo*)obj;
  bool res = addObject(jExprInfo, jkExprInfoBase, sqlExprToJson, &exprInfo->base);
X
Xiaoyu Wang 已提交
451
  if (res) {
X
Xiaoyu Wang 已提交
452
    res = addObject(jExprInfo, jkExprInfoExpr, exprNodeToJson, exprInfo->pExpr);
X
Xiaoyu Wang 已提交
453
  }
X
Xiaoyu Wang 已提交
454 455
  return res;
}
X
Xiaoyu Wang 已提交
456

X
Xiaoyu Wang 已提交
457 458 459 460 461
static bool exprInfoFromJson(const cJSON* json, void* obj) {
  SExprInfo* exprInfo = (SExprInfo*)obj;
  bool res = fromObject(json, jkExprInfoBase, sqlExprFromJson, &exprInfo->base, true);
  if (res) {
    res = fromObjectWithAlloc(json, jkExprInfoExpr, exprNodeFromJson, (void**)&exprInfo->pExpr, sizeof(tExprNode), true);
X
Xiaoyu Wang 已提交
462
  }
X
Xiaoyu Wang 已提交
463
  return res;
X
Xiaoyu Wang 已提交
464 465
}

X
Xiaoyu Wang 已提交
466 467 468 469 470 471 472
static const char* jkPnodeName = "Name";
static const char* jkPnodeTargets = "Targets";
static const char* jkPnodeConditions = "Conditions";
static const char* jkPnodeSchema = "Schema";
static const char* jkPnodeChildren = "Children";
// The 'pParent' field do not need to be serialized.
static bool phyNodeToJson(const void* obj, cJSON* jNode) {
X
Xiaoyu Wang 已提交
473
  const SPhyNode* phyNode = (const SPhyNode*)obj;
X
Xiaoyu Wang 已提交
474
  bool res = cJSON_AddStringToObject(jNode, jkPnodeName, phyNode->info.name);
X
Xiaoyu Wang 已提交
475
  if (res) {
X
Xiaoyu Wang 已提交
476
    res = addArray(jNode, jkPnodeTargets, exprInfoToJson, phyNode->pTargets);
X
Xiaoyu Wang 已提交
477 478
  }
  if (res) {
X
Xiaoyu Wang 已提交
479
    res = addArray(jNode, jkPnodeConditions, exprInfoToJson, phyNode->pConditions);
X
Xiaoyu Wang 已提交
480 481
  }
  if (res) {
X
Xiaoyu Wang 已提交
482
    res = addRawArray(jNode, jkPnodeSchema, schemaToJson, phyNode->targetSchema.pSchema, sizeof(SSlotSchema), phyNode->targetSchema.numOfCols);
X
Xiaoyu Wang 已提交
483 484
  }
  if (res) {
X
Xiaoyu Wang 已提交
485
    res = addArray(jNode, jkPnodeChildren, phyNodeToJson, phyNode->pChildren);
X
Xiaoyu Wang 已提交
486
  }
X
Xiaoyu Wang 已提交
487 488
  return res;
}
X
Xiaoyu Wang 已提交
489

X
Xiaoyu Wang 已提交
490 491 492 493 494 495 496 497 498 499 500 501 502
static bool phyNodeFromJson(const cJSON* json, void* obj) {
  SPhyNode* node = (SPhyNode*)obj;
  node->info.name = getString(json, jkPnodeName);
  node->info.type = opNameToOpType(node->info.name);
  bool res = fromArray(json, jkPnodeTargets, exprInfoFromJson, &node->pTargets, sizeof(SExprInfo));
  if (res) {
    res = fromArray(json, jkPnodeConditions, exprInfoFromJson, &node->pConditions, sizeof(SExprInfo));
  }
  if (res) {
    res = fromRawArray(json, jkPnodeSchema, schemaFromJson, node->targetSchema.pSchema, sizeof(SSlotSchema), &node->targetSchema.numOfCols);
  }
  if (res) {
    res = fromArray(json, jkPnodeChildren, phyNodeFromJson, &node->pChildren, sizeof(SSlotSchema));
X
Xiaoyu Wang 已提交
503
  }
X
Xiaoyu Wang 已提交
504
  return res;
X
Xiaoyu Wang 已提交
505 506
}

X
Xiaoyu Wang 已提交
507 508 509
static const char* jkIdQueryId = "QueryId";
static const char* jkIdTemplateId = "TemplateId";
static const char* jkIdSubplanId = "SubplanId";
X
Xiaoyu Wang 已提交
510

X
Xiaoyu Wang 已提交
511 512 513
static bool subplanIdToJson(const void* obj, cJSON* jId) {
  const SSubplanId* id = (const SSubplanId*)obj;
  bool res = cJSON_AddNumberToObject(jId, jkIdQueryId, id->queryId);
X
Xiaoyu Wang 已提交
514
  if (res) {
X
Xiaoyu Wang 已提交
515
    res = cJSON_AddNumberToObject(jId, jkIdTemplateId, id->templateId);
X
Xiaoyu Wang 已提交
516 517
  }
  if (res) {
X
Xiaoyu Wang 已提交
518
    res = cJSON_AddNumberToObject(jId, jkIdSubplanId, id->subplanId);
X
Xiaoyu Wang 已提交
519
  }
X
Xiaoyu Wang 已提交
520 521
  return res;
}
X
Xiaoyu Wang 已提交
522

X
Xiaoyu Wang 已提交
523 524 525 526 527 528
static bool subplanIdFromJson(const cJSON* json, void* obj) {
  SSubplanId* id = (SSubplanId*)obj;
  id->queryId = getNumber(json, jkIdQueryId);
  id->templateId = getNumber(json, jkIdTemplateId);
  id->subplanId = getNumber(json, jkIdSubplanId);
  return true;
X
Xiaoyu Wang 已提交
529 530
}

X
Xiaoyu Wang 已提交
531 532 533
static const char* jkSubplanId = "Id";
static const char* jkSubplanNode = "Node";

X
Xiaoyu Wang 已提交
534 535 536 537 538 539 540 541
static cJSON* subplanToJson(const SSubplan* subplan) {
  cJSON* jSubplan = cJSON_CreateObject();
  if (NULL == jSubplan) {
    return NULL;
  }

  // The 'type', 'level', 'execEpSet', 'pChildern' and 'pParents' fields do not need to be serialized.

X
Xiaoyu Wang 已提交
542
  bool res = addObject(jSubplan, jkSubplanId, subplanIdToJson, &subplan->id);
X
Xiaoyu Wang 已提交
543
  if (res) {
X
Xiaoyu Wang 已提交
544
    res = addObject(jSubplan, jkSubplanNode, phyNodeToJson, subplan->pNode);
X
Xiaoyu Wang 已提交
545 546 547 548 549 550 551 552 553
  }

  if (!res) {
    cJSON_Delete(jSubplan);
    return NULL;
  }
  return jSubplan;
}

X
Xiaoyu Wang 已提交
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
static SSubplan* subplanFromJson(const cJSON* json) {
  SSubplan* subplan = calloc(1, sizeof(SSubplan));
  if (NULL == subplan) {
    return NULL;
  }
  bool res = fromObject(json, jkSubplanId, subplanIdFromJson, &subplan->id, true);
  if (res) {
    res = fromObjectWithAlloc(json, jkSubplanNode, phyNodeFromJson, (void**)&subplan->pNode, sizeof(SPhyNode), false);
  }
  
  if (!res) {
    qDestroySubplan(subplan);
    return NULL;
  }
  return subplan;
}

X
Xiaoyu Wang 已提交
571 572 573 574 575 576 577 578 579 580 581
int32_t subPlanToString(const SSubplan* subplan, char** str) {
  cJSON* json = subplanToJson(subplan);
  if (NULL == json) {
    terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
    return TSDB_CODE_FAILED;
  }
  *str = cJSON_Print(json);
  return TSDB_CODE_SUCCESS;
}

int32_t stringToSubplan(const char* str, SSubplan** subplan) {
X
Xiaoyu Wang 已提交
582 583 584 585 586 587
  cJSON* json = cJSON_Parse(str);
  if (NULL == json) {
    return TSDB_CODE_FAILED;
  }
  *subplan = subplanFromJson(json);
  return (NULL == *subplan ? TSDB_CODE_FAILED : TSDB_CODE_SUCCESS);
X
Xiaoyu Wang 已提交
588
}