physicalPlanJson.c 39.5 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

23 24 25 26 27 28 29 30 31
static char* getString(const cJSON* json, const char* name) {
  char* p = cJSON_GetStringValue(cJSON_GetObjectItem(json, name));
  return strdup(p);
}

static void copyString(const cJSON* json, const char* name, char* dst) {
  strcpy(dst, cJSON_GetStringValue(cJSON_GetObjectItem(json, name)));
}

H
Haojun Liao 已提交
32 33 34 35 36 37 38 39
static uint64_t getBigintFromString(const cJSON* json, const char* name) {
  char* val = getString(json, name);
  uint64_t intVal = strtoul(val, NULL, 10);
  tfree(val);

  return intVal;
}

40
static int64_t getNumber(const cJSON* json, const char* name) {
H
Haojun Liao 已提交
41 42
  double d = cJSON_GetNumberValue(cJSON_GetObjectItem(json, name));
  return (int64_t) d;
43 44
}

X
Xiaoyu Wang 已提交
45
static bool addObject(cJSON* json, const char* name, FToJson func, const void* obj) {
X
Xiaoyu Wang 已提交
46 47 48 49
  if (NULL == obj) {
    return true;
  }

X
Xiaoyu Wang 已提交
50 51 52
  cJSON* jObj = cJSON_CreateObject();
  if (NULL == jObj || !func(obj, jObj)) {
    cJSON_Delete(jObj);
X
Xiaoyu Wang 已提交
53 54 55 56 57
    return false;
  }
  return cJSON_AddItemToObject(json, name, jObj);
}

X
Xiaoyu Wang 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
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 已提交
82 83
    return false;
  }
X
Xiaoyu Wang 已提交
84
  return func(jObj, *obj);
X
Xiaoyu Wang 已提交
85 86
}

87 88 89
static const char* jkPnodeType = "Type";
static int32_t getPnodeTypeSize(cJSON* json) {
  switch (getNumber(json, jkPnodeType)) {
L
Liu Jicong 已提交
90
    case OP_StreamScan:
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
    case OP_DataBlocksOptScan:
    case OP_TableSeqScan:
      return sizeof(STableScanPhyNode);
    case OP_TagScan:
      return sizeof(STagScanPhyNode);
    case OP_SystemTableScan:
      return sizeof(SSystemTableScanPhyNode);
    case OP_Aggregate:
      return sizeof(SAggPhyNode);
    case OP_Exchange:
      return sizeof(SExchangePhyNode);
    default:
      break;
  };
  return -1;
}

static bool fromPnode(const cJSON* json, const char* name, FFromJson func, void** obj) {
  cJSON* jObj = cJSON_GetObjectItem(json, name);
  if (NULL == jObj) {
    return true;
  }
  *obj = calloc(1, getPnodeTypeSize(jObj));
  if (NULL == *obj) {
    return false;
  }
  return func(jObj, *obj);
}

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
static bool fromPnodeArray(const cJSON* json, const char* name, FFromJson func, SArray** array) {
  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) {
    cJSON* jItem = cJSON_GetArrayItem(jArray, i);
    void* item = calloc(1, getPnodeTypeSize(jItem));
    if (NULL == item || !func(jItem, item)) {
      return false;
    }
    taosArrayPush(*array, &item);
  }
  return true;
}

X
Xiaoyu Wang 已提交
140
static bool addTarray(cJSON* json, const char* name, FToJson func, const SArray* array, bool isPoint) {
X
Xiaoyu Wang 已提交
141 142 143 144 145 146 147
  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) {
X
Xiaoyu Wang 已提交
148
      if (!addItem(jArray, func, isPoint ? taosArrayGetP(array, i) : taosArrayGet(array, i))) {
X
Xiaoyu Wang 已提交
149 150 151 152 153 154 155
        return false;
      }
    }
  }
  return true;
}

X
Xiaoyu Wang 已提交
156 157 158 159 160 161 162 163 164
static bool addInlineArray(cJSON* json, const char* name, FToJson func, const SArray* array) {
  return addTarray(json, name, func, array, false);
}

static bool addArray(cJSON* json, const char* name, FToJson func, const SArray* array) {
  return addTarray(json, name, func, array, true);
}

static bool fromTarray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize, bool isPoint) {
X
Xiaoyu Wang 已提交
165 166 167
  const cJSON* jArray = cJSON_GetObjectItem(json, name);
  int32_t size = (NULL == jArray ? 0 : cJSON_GetArraySize(jArray));
  if (size > 0) {
X
Xiaoyu Wang 已提交
168
    *array = taosArrayInit(size, isPoint ? POINTER_BYTES : itemSize);
X
Xiaoyu Wang 已提交
169 170 171 172 173 174 175 176 177
    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;
    }
X
Xiaoyu Wang 已提交
178
    taosArrayPush(*array, isPoint ? &item : item);
X
Xiaoyu Wang 已提交
179 180 181 182
  }
  return true;
}

X
Xiaoyu Wang 已提交
183 184 185 186 187 188 189 190
static bool fromInlineArray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize) {
  return fromTarray(json, name, func, array, itemSize, false);
}

static bool fromArray(const cJSON* json, const char* name, FFromJson func, SArray** array, int32_t itemSize) {
  return fromTarray(json, name, func, array, itemSize, true);
}

X
Xiaoyu Wang 已提交
191
static bool addRawArray(cJSON* json, const char* name, FToJson func, const void* array, int32_t itemSize, int32_t size) {
X
Xiaoyu Wang 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204 205
  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 已提交
206 207 208 209 210 211 212 213
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) {
H
Haojun Liao 已提交
214
    if (!func(cJSON_GetArrayItem(jArray, i), (char*)array + itemSize * i)) {
X
Xiaoyu Wang 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227
      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 已提交
228
  }
X
Xiaoyu Wang 已提交
229 230 231
  return fromItem(jArray, func, *array, itemSize, *size);
}

232
static bool fromRawArray(const cJSON* json, const char* name, FFromJson func, void* array, int32_t itemSize, int32_t* size) {
X
Xiaoyu Wang 已提交
233
  const cJSON* jArray = getArray(json, name, size);
234
  return fromItem(jArray, func, array, itemSize, *size);
X
Xiaoyu Wang 已提交
235
}
X
Xiaoyu Wang 已提交
236

X
Xiaoyu Wang 已提交
237 238 239 240 241 242 243
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 已提交
244
  if (res) {
X
Xiaoyu Wang 已提交
245
    res = cJSON_AddNumberToObject(jSchema, jkSchemaColId, schema->colId);
X
Xiaoyu Wang 已提交
246 247
  }
  if (res) {
X
Xiaoyu Wang 已提交
248
    res = cJSON_AddNumberToObject(jSchema, jkSchemaBytes, schema->bytes);
X
Xiaoyu Wang 已提交
249
  }
X
Xiaoyu Wang 已提交
250 251
  return res;
}
X
Xiaoyu Wang 已提交
252

X
Xiaoyu Wang 已提交
253 254 255 256 257 258
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 已提交
259 260
}

X
Xiaoyu Wang 已提交
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
static const char* jkDataBlockSchemaSlotSchema = "SlotSchema";
static const char* jkDataBlockSchemaResultRowSize = "resultRowSize";
static const char* jkDataBlockSchemaPrecision = "Precision";

static bool dataBlockSchemaToJson(const void* obj, cJSON* json) {
  const SDataBlockSchema* schema = (const SDataBlockSchema*)obj;
  bool res = addRawArray(json, jkDataBlockSchemaSlotSchema, schemaToJson, schema->pSchema, sizeof(SSlotSchema), schema->numOfCols);
  if (res) {
    res = cJSON_AddNumberToObject(json, jkDataBlockSchemaResultRowSize, schema->resultRowSize);
  }
  if (res) {
    res = cJSON_AddNumberToObject(json, jkDataBlockSchemaPrecision, schema->precision);
  }
  return res;
}

static bool dataBlockSchemaFromJson(const cJSON* json, void* obj) {
  SDataBlockSchema* schema = (SDataBlockSchema*)obj;
  schema->resultRowSize = getNumber(json, jkDataBlockSchemaResultRowSize);
  schema->precision = getNumber(json, jkDataBlockSchemaPrecision);
H
Haojun Liao 已提交
281

282
  return fromRawArrayWithAlloc(json, jkDataBlockSchemaSlotSchema, schemaFromJson, (void**)&(schema->pSchema), sizeof(SSlotSchema), &schema->numOfCols);
X
Xiaoyu Wang 已提交
283 284
}

X
Xiaoyu Wang 已提交
285 286 287 288 289
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 已提交
290

X
Xiaoyu Wang 已提交
291 292 293
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 已提交
294
  if (res) {
X
Xiaoyu Wang 已提交
295
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoUpperRelOptr, filter->upperRelOptr);
X
Xiaoyu Wang 已提交
296 297
  }
  if (res) {
X
Xiaoyu Wang 已提交
298
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoFilterstr, filter->filterstr);
X
Xiaoyu Wang 已提交
299 300
  }
  if (res) {
X
Xiaoyu Wang 已提交
301
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoLowerBnd, filter->lowerBndd);
X
Xiaoyu Wang 已提交
302 303
  }
  if (res) {
X
Xiaoyu Wang 已提交
304
    res = cJSON_AddNumberToObject(jFilter, jkColumnFilterInfoUpperBnd, filter->upperBndd);
X
Xiaoyu Wang 已提交
305
  }
X
Xiaoyu Wang 已提交
306 307
  return res;
}
X
Xiaoyu Wang 已提交
308

X
Xiaoyu Wang 已提交
309 310 311 312 313 314 315 316
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 已提交
317 318
}

X
Xiaoyu Wang 已提交
319 320 321 322
static const char* jkColumnInfoColId = "ColId";
static const char* jkColumnInfoType = "Type";
static const char* jkColumnInfoBytes = "Bytes";
static const char* jkColumnInfoFilterList = "FilterList";
X
Xiaoyu Wang 已提交
323

X
Xiaoyu Wang 已提交
324 325 326
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 已提交
327
  if (res) {
X
Xiaoyu Wang 已提交
328
    res = cJSON_AddNumberToObject(jCol, jkColumnInfoType, col->type);
X
Xiaoyu Wang 已提交
329 330
  }
  if (res) {
X
Xiaoyu Wang 已提交
331
    res = cJSON_AddNumberToObject(jCol, jkColumnInfoBytes, col->bytes);
X
Xiaoyu Wang 已提交
332
  }
H
Haojun Liao 已提交
333 334 335

  if (res) { // TODO: temporarily disable it
//    res = addRawArray(jCol, jkColumnInfoFilterList, columnFilterInfoToJson, col->flist.filterInfo, sizeof(SColumnFilterInfo), col->flist.numOfFilters);
X
Xiaoyu Wang 已提交
336
  }
H
Haojun Liao 已提交
337

X
Xiaoyu Wang 已提交
338 339
  return res;
}
X
Xiaoyu Wang 已提交
340

X
Xiaoyu Wang 已提交
341 342 343
static bool columnInfoFromJson(const cJSON* json, void* obj) {
  SColumnInfo* col = (SColumnInfo*)obj;
  col->colId = getNumber(json, jkColumnInfoColId);
H
Haojun Liao 已提交
344
  col->type  = getNumber(json, jkColumnInfoType);
X
Xiaoyu Wang 已提交
345 346 347 348 349
  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 已提交
350 351
}

X
Xiaoyu Wang 已提交
352 353 354
static const char* jkColumnTableId = "TableId";
static const char* jkColumnFlag = "Flag";
static const char* jkColumnInfo = "Info";
X
Xiaoyu Wang 已提交
355

X
Xiaoyu Wang 已提交
356 357 358
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 已提交
359
  if (res) {
X
Xiaoyu Wang 已提交
360
    res = cJSON_AddNumberToObject(jCol, jkColumnFlag, col->flag);
X
Xiaoyu Wang 已提交
361 362
  }
  if (res) {
X
Xiaoyu Wang 已提交
363
    res = addObject(jCol, jkColumnInfo, columnInfoToJson, &col->info);
X
Xiaoyu Wang 已提交
364
  }
X
Xiaoyu Wang 已提交
365 366
  return res;
}
X
Xiaoyu Wang 已提交
367

X
Xiaoyu Wang 已提交
368 369 370 371 372
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 已提交
373 374
}

X
Xiaoyu Wang 已提交
375 376
static bool exprNodeToJson(const void* obj, cJSON* jExprInfo);
static bool exprNodeFromJson(const cJSON* json, void* obj);
X
Xiaoyu Wang 已提交
377

X
Xiaoyu Wang 已提交
378 379 380
static const char* jkExprNodeOper = "Oper";
static const char* jkExprNodeLeft = "Left";
static const char* jkExprNodeRight = "Right";
X
Xiaoyu Wang 已提交
381

X
Xiaoyu Wang 已提交
382 383 384
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 已提交
385
  if (res) {
X
Xiaoyu Wang 已提交
386
    res = addObject(jOper, jkExprNodeLeft, exprNodeToJson, exprInfo->_node.pLeft);
X
Xiaoyu Wang 已提交
387 388
  }
  if (res) {
X
Xiaoyu Wang 已提交
389
    res = addObject(jOper, jkExprNodeRight, exprNodeToJson, exprInfo->_node.pRight);
X
Xiaoyu Wang 已提交
390
  }
X
Xiaoyu Wang 已提交
391 392
  return res;
}
X
Xiaoyu Wang 已提交
393

X
Xiaoyu Wang 已提交
394 395 396 397 398 399
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 已提交
400
  }
X
Xiaoyu Wang 已提交
401
  return res;
X
Xiaoyu Wang 已提交
402 403
}

X
Xiaoyu Wang 已提交
404 405
static const char* jkFunctionName = "Name";
static const char* jkFunctionChild = "Child";
X
Xiaoyu Wang 已提交
406

X
Xiaoyu Wang 已提交
407 408 409
static bool functionToJson(const void* obj, cJSON* jFunc) {
  const tExprNode* exprInfo = (const tExprNode*)obj;
  bool res = cJSON_AddStringToObject(jFunc, jkFunctionName, exprInfo->_function.functionName);
410
  if (res && NULL != exprInfo->_function.pChild) {
H
Haojun Liao 已提交
411
      res = addRawArray(jFunc, jkFunctionChild, exprNodeToJson, exprInfo->_function.pChild, sizeof(tExprNode*), exprInfo->_function.num);
X
Xiaoyu Wang 已提交
412
  }
X
Xiaoyu Wang 已提交
413 414
  return res;
}
X
Xiaoyu Wang 已提交
415

X
Xiaoyu Wang 已提交
416 417 418
static bool functionFromJson(const cJSON* json, void* obj) {
  tExprNode* exprInfo = (tExprNode*)obj;
  copyString(json, jkFunctionName, exprInfo->_function.functionName);
419 420 421 422
  exprInfo->_function.pChild = calloc(1, sizeof(tExprNode*));
  if (NULL == exprInfo->_function.pChild) {
    return false;
  }
X
Xiaoyu Wang 已提交
423
  return fromRawArrayWithAlloc(json, jkFunctionChild, exprNodeFromJson, (void**)exprInfo->_function.pChild, sizeof(tExprNode*), &exprInfo->_function.num);
X
Xiaoyu Wang 已提交
424 425
}

X
Xiaoyu Wang 已提交
426 427 428 429
static const char* jkVariantType = "Type";
static const char* jkVariantLen = "Len";
static const char* jkVariantvalues = "values";
static const char* jkVariantValue = "Value";
X
Xiaoyu Wang 已提交
430

X
Xiaoyu Wang 已提交
431 432 433
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 已提交
434
  if (res) {
X
Xiaoyu Wang 已提交
435
    res = cJSON_AddNumberToObject(jVar, jkVariantLen, var->nLen);
X
Xiaoyu Wang 已提交
436 437 438
  }
  if (res) {
    if (0/* in */) {
X
Xiaoyu Wang 已提交
439
      res = addArray(jVar, jkVariantvalues, variantToJson, var->arr);
X
Xiaoyu Wang 已提交
440
    } else if (IS_NUMERIC_TYPE(var->nType)) {
X
Xiaoyu Wang 已提交
441
      res = cJSON_AddNumberToObject(jVar, jkVariantValue, var->d);
X
Xiaoyu Wang 已提交
442
    } else {
X
Xiaoyu Wang 已提交
443
      res = cJSON_AddStringToObject(jVar, jkVariantValue, var->pz);
X
Xiaoyu Wang 已提交
444 445
    }
  }
X
Xiaoyu Wang 已提交
446 447
  return res;
}
X
Xiaoyu Wang 已提交
448

X
Xiaoyu Wang 已提交
449 450 451 452 453 454 455 456 457 458
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 已提交
459
  }
X
Xiaoyu Wang 已提交
460
  return true;
X
Xiaoyu Wang 已提交
461 462
}

X
Xiaoyu Wang 已提交
463 464 465 466 467
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 已提交
468

X
Xiaoyu Wang 已提交
469
static bool exprNodeToJson(const void* obj, cJSON* jExprInfo) {
H
Haojun Liao 已提交
470
  const tExprNode* exprInfo = *(const tExprNode**)obj;
X
Xiaoyu Wang 已提交
471
  bool res = cJSON_AddNumberToObject(jExprInfo, jkExprNodeType, exprInfo->nodeType);
X
Xiaoyu Wang 已提交
472 473 474 475
  if (res) {
    switch (exprInfo->nodeType) {
      case TEXPR_BINARYEXPR_NODE:
      case TEXPR_UNARYEXPR_NODE:
X
Xiaoyu Wang 已提交
476
        res = addObject(jExprInfo, jkExprNodeOperator, operatorToJson, exprInfo);
X
Xiaoyu Wang 已提交
477 478
        break;
      case TEXPR_FUNCTION_NODE:
X
Xiaoyu Wang 已提交
479
        res = addObject(jExprInfo, jkExprNodeFunction, functionToJson, exprInfo);
X
Xiaoyu Wang 已提交
480 481
        break;
      case TEXPR_COL_NODE:
X
Xiaoyu Wang 已提交
482
        res = addObject(jExprInfo, jkExprNodeColumn, schemaToJson, exprInfo->pSchema);
X
Xiaoyu Wang 已提交
483 484
        break;
      case TEXPR_VALUE_NODE:
X
Xiaoyu Wang 已提交
485
        res = addObject(jExprInfo, jkExprNodeValue, variantToJson, exprInfo->pVal);
X
Xiaoyu Wang 已提交
486 487 488 489 490 491
        break;
      default:
        res = false;
        break;
    }
  }
X
Xiaoyu Wang 已提交
492 493
  return res;
}
X
Xiaoyu Wang 已提交
494

X
Xiaoyu Wang 已提交
495 496 497 498 499 500 501 502 503 504
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:
X
Xiaoyu Wang 已提交
505
      return fromObjectWithAlloc(json, jkExprNodeColumn, schemaFromJson, (void**)&exprInfo->pSchema, sizeof(SSchema), false);
X
Xiaoyu Wang 已提交
506 507 508 509 510 511
    case TEXPR_VALUE_NODE:
      return fromObject(json, jkExprNodeValue, variantFromJson, exprInfo->pVal, false);
    default:
      break;
  }
  return false;
X
Xiaoyu Wang 已提交
512 513
}

X
Xiaoyu Wang 已提交
514 515 516 517 518 519
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 已提交
520
  const SSqlExpr* expr = (const SSqlExpr*)obj;
X
Xiaoyu Wang 已提交
521
  bool res = addObject(jExpr, jkSqlExprSchema, schemaToJson, &expr->resSchema);
X
Xiaoyu Wang 已提交
522
  if (res) {
X
Xiaoyu Wang 已提交
523
    res = addRawArray(jExpr, jkSqlExprColumns, columnToJson, expr->pColumns, sizeof(SColumn), expr->numOfCols);
X
Xiaoyu Wang 已提交
524 525
  }
  if (res) {
X
Xiaoyu Wang 已提交
526
    res = cJSON_AddNumberToObject(jExpr, jkSqlExprInterBytes, expr->interBytes);
X
Xiaoyu Wang 已提交
527 528
  }
  if (res) {
X
Xiaoyu Wang 已提交
529
    res = addRawArray(jExpr, jkSqlExprParams, variantToJson, expr->param, sizeof(SVariant), expr->numOfParams);
X
Xiaoyu Wang 已提交
530
  }
X
Xiaoyu Wang 已提交
531 532
  return res;
}
X
Xiaoyu Wang 已提交
533

X
Xiaoyu Wang 已提交
534 535 536 537 538 539 540 541 542 543 544 545 546
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 已提交
547
  }
X
Xiaoyu Wang 已提交
548
  return res;
X
Xiaoyu Wang 已提交
549 550
}

X
Xiaoyu Wang 已提交
551 552
static const char* jkExprInfoBase = "Base";
static const char* jkExprInfoExpr = "Expr";
X
Xiaoyu Wang 已提交
553

X
Xiaoyu Wang 已提交
554 555 556
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 已提交
557
  if (res) {
H
Haojun Liao 已提交
558
    res = addObject(jExprInfo, jkExprInfoExpr, exprNodeToJson, &exprInfo->pExpr);
X
Xiaoyu Wang 已提交
559
  }
X
Xiaoyu Wang 已提交
560 561
  return res;
}
X
Xiaoyu Wang 已提交
562

X
Xiaoyu Wang 已提交
563 564 565 566 567
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 已提交
568
  }
X
Xiaoyu Wang 已提交
569
  return res;
X
Xiaoyu Wang 已提交
570 571
}

X
Xiaoyu Wang 已提交
572 573 574 575 576
static const char* jkTimeWindowStartKey = "StartKey";
static const char* jkTimeWindowEndKey = "EndKey";

static bool timeWindowToJson(const void* obj, cJSON* json) {
  const STimeWindow* win = (const STimeWindow*)obj;
H
Haojun Liao 已提交
577

H
Haojun Liao 已提交
578 579
  char tmp[40] = {0};
  snprintf(tmp, tListLen(tmp),"%"PRId64, win->skey);
H
Haojun Liao 已提交
580 581

  bool res = cJSON_AddStringToObject(json, jkTimeWindowStartKey, tmp);
X
Xiaoyu Wang 已提交
582
  if (res) {
H
Haojun Liao 已提交
583
    memset(tmp, 0, tListLen(tmp));
H
Haojun Liao 已提交
584
    snprintf(tmp, tListLen(tmp),"%"PRId64, win->ekey);
H
Haojun Liao 已提交
585
    res = cJSON_AddStringToObject(json, jkTimeWindowEndKey, tmp);
X
Xiaoyu Wang 已提交
586 587 588 589 590 591
  }
  return res;
}

static bool timeWindowFromJson(const cJSON* json, void* obj) {
  STimeWindow* win = (STimeWindow*)obj;
H
Haojun Liao 已提交
592 593
  win->skey = getBigintFromString(json, jkTimeWindowStartKey);
  win->ekey = getBigintFromString(json, jkTimeWindowEndKey);
X
Xiaoyu Wang 已提交
594 595 596 597 598
  return true;
}

static const char* jkScanNodeTableId = "TableId";
static const char* jkScanNodeTableType = "TableType";
H
Haojun Liao 已提交
599 600
static const char* jkScanNodeTableOrder = "Order";
static const char* jkScanNodeTableCount = "Count";
601
static const char* jkScanNodeTableRevCount = "Reverse";
X
Xiaoyu Wang 已提交
602 603

static bool scanNodeToJson(const void* obj, cJSON* json) {
604
  const SScanPhyNode* pNode = (const SScanPhyNode*)obj;
605 606 607 608

  char uid[40] = {0};
  snprintf(uid, tListLen(uid), "%"PRIu64, pNode->uid);
  bool res = cJSON_AddStringToObject(json, jkScanNodeTableId, uid);
H
Haojun Liao 已提交
609

X
Xiaoyu Wang 已提交
610
  if (res) {
611
    res = cJSON_AddNumberToObject(json, jkScanNodeTableType, pNode->tableType);
X
Xiaoyu Wang 已提交
612
  }
613

H
Haojun Liao 已提交
614
  if (res) {
615
    res = cJSON_AddNumberToObject(json, jkScanNodeTableOrder, pNode->order);
H
Haojun Liao 已提交
616
  }
617

H
Haojun Liao 已提交
618
  if (res) {
619 620 621 622 623
    res = cJSON_AddNumberToObject(json, jkScanNodeTableCount, pNode->count);
  }

  if (res) {
    res = cJSON_AddNumberToObject(json, jkScanNodeTableRevCount, pNode->reverse);
H
Haojun Liao 已提交
624
  }
625

X
Xiaoyu Wang 已提交
626 627 628 629
  return res;
}

static bool scanNodeFromJson(const cJSON* json, void* obj) {
630
  SScanPhyNode* pNode = (SScanPhyNode*)obj;
631

H
Haojun Liao 已提交
632
  pNode->uid       = getBigintFromString(json, jkScanNodeTableId);
633 634 635 636
  pNode->tableType = getNumber(json, jkScanNodeTableType);
  pNode->count     = getNumber(json, jkScanNodeTableCount);
  pNode->order     = getNumber(json, jkScanNodeTableOrder);
  pNode->reverse   = getNumber(json, jkScanNodeTableRevCount);
X
Xiaoyu Wang 已提交
637 638 639
  return true;
}

640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
static const char* jkColIndexColId = "ColId";
static const char* jkColIndexColIndex = "ColIndex";
static const char* jkColIndexFlag = "Flag";
static const char* jkColIndexName = "Name";

static bool colIndexToJson(const void* obj, cJSON* json) {
  const SColIndex* col = (const SColIndex*)obj;
  bool res = cJSON_AddNumberToObject(json, jkColIndexColId, col->colId);
  if (res) {
    res = cJSON_AddNumberToObject(json, jkColIndexColIndex, col->colIndex);
  }
  if (res) {
    res = cJSON_AddNumberToObject(json, jkColIndexFlag, col->flag);
  }
  if (res) {
    res = cJSON_AddStringToObject(json, jkColIndexName, col->name);
  }
  return res;
}

static bool colIndexFromJson(const cJSON* json, void* obj) {
  SColIndex* col = (SColIndex*)obj;
  col->colId = getNumber(json, jkColIndexColId);
  col->colIndex = getNumber(json, jkColIndexColIndex);
  col->flag = getNumber(json, jkColIndexFlag);
  copyString(json, jkColIndexName, col->name);
  return true;
}

static const char* jkAggNodeAggAlgo = "AggAlgo";
static const char* jkAggNodeAggSplit = "AggSplit";
static const char* jkAggNodeExprs = "Exprs";
static const char* jkAggNodeGroupByList = "GroupByList";

static bool aggNodeToJson(const void* obj, cJSON* json) {
  const SAggPhyNode* agg = (const SAggPhyNode*)obj;
  bool res = cJSON_AddNumberToObject(json, jkAggNodeAggAlgo, agg->aggAlgo);
  if (res) {
    res = cJSON_AddNumberToObject(json, jkAggNodeAggSplit, agg->aggSplit);
  }
  if (res) {
    res = addArray(json, jkAggNodeExprs, exprInfoToJson, agg->pExprs);
  }
  if (res) {
    res = addArray(json, jkAggNodeGroupByList, colIndexToJson, agg->pGroupByList);
  }
  return res;
}

static bool aggNodeFromJson(const cJSON* json, void* obj) {
  SAggPhyNode* agg = (SAggPhyNode*)obj;
  agg->aggAlgo = getNumber(json, jkAggNodeAggAlgo);
  agg->aggSplit = getNumber(json, jkAggNodeAggSplit);
  bool res = fromArray(json, jkAggNodeExprs, exprInfoFromJson, &agg->pExprs, sizeof(SExprInfo));
  if (res) {
    res = fromArray(json, jkAggNodeGroupByList, colIndexFromJson, &agg->pGroupByList, sizeof(SExprInfo));
  }
  return res;
}

X
Xiaoyu Wang 已提交
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
static const char* jkTableScanNodeFlag = "Flag";
static const char* jkTableScanNodeWindow = "Window";
static const char* jkTableScanNodeTagsConditions = "TagsConditions";

static bool tableScanNodeToJson(const void* obj, cJSON* json) {
  const STableScanPhyNode* scan = (const STableScanPhyNode*)obj;
  bool res = scanNodeToJson(obj, json);
  if (res) {
    res = cJSON_AddNumberToObject(json, jkTableScanNodeFlag, scan->scanFlag);
  }
  if (res) {
    res = addObject(json, jkTableScanNodeWindow, timeWindowToJson, &scan->window);
  }
  if (res) {
    res = addArray(json, jkTableScanNodeTagsConditions, exprInfoToJson, scan->pTagsConditions);
  }
  return res;
}

static bool tableScanNodeFromJson(const cJSON* json, void* obj) {
  STableScanPhyNode* scan = (STableScanPhyNode*)obj;
  bool res = scanNodeFromJson(json, obj);
  if (res) {
    scan->scanFlag = getNumber(json, jkTableScanNodeFlag);
  }
  if (res) {
    res = fromObject(json, jkTableScanNodeWindow, timeWindowFromJson, &scan->window, true);
  }
  if (res) {
    res = fromArray(json, jkTableScanNodeTagsConditions, exprInfoFromJson, &scan->pTagsConditions, sizeof(SExprInfo));
  }
  return res;
}

static const char* jkEpAddrFqdn = "Fqdn";
static const char* jkEpAddrPort = "Port";

static bool epAddrToJson(const void* obj, cJSON* json) {
H
Haojun Liao 已提交
738
  const SEp* ep = (const SEp*)obj;
X
Xiaoyu Wang 已提交
739 740 741 742 743 744 745 746
  bool res = cJSON_AddStringToObject(json, jkEpAddrFqdn, ep->fqdn);
  if (res) {
    res = cJSON_AddNumberToObject(json, jkEpAddrPort, ep->port);
  }
  return res;
}

static bool epAddrFromJson(const cJSON* json, void* obj) {
H
Haojun Liao 已提交
747
  SEp* ep = (SEp*)obj;
X
Xiaoyu Wang 已提交
748 749 750 751 752
  copyString(json, jkEpAddrFqdn, ep->fqdn);
  ep->port = getNumber(json, jkEpAddrPort);
  return true;
}

H
Haojun Liao 已提交
753 754 755 756 757 758 759 760 761 762 763 764
static const char* jkNodeAddrId      = "NodeId";
static const char* jkNodeAddrInUse   = "InUse";
static const char* jkNodeAddrEpAddrs = "Ep";
static const char* jkNodeAddr        = "NodeAddr";
static const char* jkNodeTaskId      = "TaskId";
static const char* jkNodeTaskSchedId = "SchedId";

static bool queryNodeAddrToJson(const void* obj, cJSON* json) {
  const SQueryNodeAddr* pAddr = (const SQueryNodeAddr*) obj;
  bool res = cJSON_AddNumberToObject(json, jkNodeAddrId, pAddr->nodeId);

  if (res) {
H
Haojun Liao 已提交
765
    res = cJSON_AddNumberToObject(json, jkNodeAddrInUse, pAddr->epset.inUse);
H
Haojun Liao 已提交
766 767 768
  }

  if (res) {
H
Haojun Liao 已提交
769
    res = addRawArray(json, jkNodeAddrEpAddrs, epAddrToJson, pAddr->epset.eps, sizeof(SEp), pAddr->epset.numOfEps);
H
Haojun Liao 已提交
770 771 772 773 774 775 776 777
  }
  return res;
}

static bool queryNodeAddrFromJson(const cJSON* json, void* obj) {
  SQueryNodeAddr* pAddr = (SQueryNodeAddr*) obj;

  pAddr->nodeId = getNumber(json, jkNodeAddrId);
H
Haojun Liao 已提交
778
  pAddr->epset.inUse = getNumber(json, jkNodeAddrInUse);
H
Haojun Liao 已提交
779 780

  int32_t numOfEps = 0;
H
Haojun Liao 已提交
781 782
  bool res = fromRawArray(json, jkNodeAddrEpAddrs, epAddrFromJson, pAddr->epset.eps, sizeof(SEp), &numOfEps);
  pAddr->epset.numOfEps = numOfEps;
H
Haojun Liao 已提交
783 784
  return res;
}
X
Xiaoyu Wang 已提交
785 786

static bool nodeAddrToJson(const void* obj, cJSON* json) {
H
Haojun Liao 已提交
787 788 789
  const SDownstreamSource* pSource = (const SDownstreamSource*) obj;
  bool res = cJSON_AddNumberToObject(json, jkNodeTaskId, pSource->taskId);

X
Xiaoyu Wang 已提交
790
  if (res) {
H
Haojun Liao 已提交
791 792 793
    char t[30] = {0};
    snprintf(t, tListLen(t), "%"PRIu64, pSource->schedId);
    res = cJSON_AddStringToObject(json, jkNodeTaskSchedId, t);
X
Xiaoyu Wang 已提交
794
  }
H
Haojun Liao 已提交
795

X
Xiaoyu Wang 已提交
796
  if (res) {
H
Haojun Liao 已提交
797
    res = addObject(json, jkNodeAddr, queryNodeAddrToJson, &pSource->addr);
X
Xiaoyu Wang 已提交
798 799 800 801 802
  }
  return res;
}

static bool nodeAddrFromJson(const cJSON* json, void* obj) {
H
Haojun Liao 已提交
803 804 805
  SDownstreamSource* pSource = (SDownstreamSource*)obj;
  pSource->taskId = getNumber(json, jkNodeTaskId);

H
Haojun Liao 已提交
806
  pSource->schedId = getBigintFromString(json, jkNodeTaskSchedId);
H
Haojun Liao 已提交
807
  bool res = fromObject(json, jkNodeAddr, queryNodeAddrFromJson, &pSource->addr, true);
X
Xiaoyu Wang 已提交
808 809 810
  return res;
}

X
Xiaoyu Wang 已提交
811
static const char* jkExchangeNodeSrcTemplateId = "SrcTemplateId";
H
Haojun Liao 已提交
812
static const char* jkExchangeNodeSrcEndPoints = "SrcAddrs";
X
Xiaoyu Wang 已提交
813 814 815 816 817

static bool exchangeNodeToJson(const void* obj, cJSON* json) {
  const SExchangePhyNode* exchange = (const SExchangePhyNode*)obj;
  bool res = cJSON_AddNumberToObject(json, jkExchangeNodeSrcTemplateId, exchange->srcTemplateId);
  if (res) {
H
Haojun Liao 已提交
818
    res = addRawArray(json, jkExchangeNodeSrcEndPoints, nodeAddrToJson, exchange->pSrcEndPoints->pData, sizeof(SDownstreamSource), taosArrayGetSize(exchange->pSrcEndPoints));
X
Xiaoyu Wang 已提交
819 820 821 822 823 824 825
  }
  return res;
}

static bool exchangeNodeFromJson(const cJSON* json, void* obj) {
  SExchangePhyNode* exchange = (SExchangePhyNode*)obj;
  exchange->srcTemplateId = getNumber(json, jkExchangeNodeSrcTemplateId);
H
Haojun Liao 已提交
826
  return fromInlineArray(json, jkExchangeNodeSrcEndPoints, nodeAddrFromJson, &exchange->pSrcEndPoints, sizeof(SDownstreamSource));
X
Xiaoyu Wang 已提交
827 828 829 830 831
}

static bool specificPhyNodeToJson(const void* obj, cJSON* json) {
  const SPhyNode* phyNode = (const SPhyNode*)obj;
  switch (phyNode->info.type) {
H
Haojun Liao 已提交
832
    case OP_StreamScan:
X
Xiaoyu Wang 已提交
833 834 835 836 837 838 839
    case OP_DataBlocksOptScan:
    case OP_TableSeqScan:
      return tableScanNodeToJson(obj, json);
    case OP_TagScan:
    case OP_SystemTableScan:
      return scanNodeToJson(obj, json);
    case OP_Aggregate:
840
      return aggNodeToJson(obj, json);
X
Xiaoyu Wang 已提交
841 842
    case OP_Project:
      return true;
843
    // case OP_Groupby:
X
Xiaoyu Wang 已提交
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
    case OP_Limit:
    case OP_SLimit:
    case OP_TimeWindow:
    case OP_SessionWindow:
    case OP_StateWindow:
    case OP_Fill:
    case OP_MultiTableAggregate:
    case OP_MultiTableTimeInterval:
    case OP_Filter:
    case OP_Distinct:
    case OP_Join:
    case OP_AllTimeWindow:
    case OP_AllMultiTableTimeInterval:
    case OP_Order:
      break; // todo
    case OP_Exchange:
      return exchangeNodeToJson(obj, json);
    default:
      break;
  }
  return false;
}

static bool specificPhyNodeFromJson(const cJSON* json, void* obj) {
  SPhyNode* phyNode = (SPhyNode*)obj;
  switch (phyNode->info.type) {
L
Liu Jicong 已提交
870
    case OP_StreamScan:
X
Xiaoyu Wang 已提交
871 872 873 874 875 876 877
    case OP_DataBlocksOptScan:
    case OP_TableSeqScan:
      return tableScanNodeFromJson(json, obj);
    case OP_TagScan:
    case OP_SystemTableScan:
      return scanNodeFromJson(json, obj);
    case OP_Aggregate:
878
      return aggNodeFromJson(json, obj);
X
Xiaoyu Wang 已提交
879 880
    case OP_Project:
      return true;
881
    // case OP_Groupby:
X
Xiaoyu Wang 已提交
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
    case OP_Limit:
    case OP_SLimit:
    case OP_TimeWindow:
    case OP_SessionWindow:
    case OP_StateWindow:
    case OP_Fill:
    case OP_MultiTableAggregate:
    case OP_MultiTableTimeInterval:
    case OP_Filter:
    case OP_Distinct:
    case OP_Join:
    case OP_AllTimeWindow:
    case OP_AllMultiTableTimeInterval:
    case OP_Order:
      break; // todo
    case OP_Exchange:
      return exchangeNodeFromJson(json, obj);
    default:
      break;
  }
  return false;
}

X
Xiaoyu Wang 已提交
905 906 907
static const char* jkPnodeName = "Name";
static const char* jkPnodeTargets = "Targets";
static const char* jkPnodeConditions = "Conditions";
908
static const char* jkPnodeSchema = "TargetSchema";
X
Xiaoyu Wang 已提交
909 910 911
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 已提交
912
  const SPhyNode* phyNode = (const SPhyNode*)obj;
913 914 915 916
  bool res = cJSON_AddNumberToObject(jNode, jkPnodeType, phyNode->info.type);
  if (res) {
    res = cJSON_AddStringToObject(jNode, jkPnodeName, phyNode->info.name);
  }
X
Xiaoyu Wang 已提交
917
  if (res) {
X
Xiaoyu Wang 已提交
918
    res = addArray(jNode, jkPnodeTargets, exprInfoToJson, phyNode->pTargets);
X
Xiaoyu Wang 已提交
919 920
  }
  if (res) {
X
Xiaoyu Wang 已提交
921
    res = addArray(jNode, jkPnodeConditions, exprInfoToJson, phyNode->pConditions);
X
Xiaoyu Wang 已提交
922 923
  }
  if (res) {
X
Xiaoyu Wang 已提交
924
    res = addObject(jNode, jkPnodeSchema, dataBlockSchemaToJson, &phyNode->targetSchema);
X
Xiaoyu Wang 已提交
925 926
  }
  if (res) {
X
Xiaoyu Wang 已提交
927
    res = addArray(jNode, jkPnodeChildren, phyNodeToJson, phyNode->pChildren);
X
Xiaoyu Wang 已提交
928
  }
X
Xiaoyu Wang 已提交
929 930 931
  if (res) {
    res = addObject(jNode, phyNode->info.name, specificPhyNodeToJson, phyNode);
  }
X
Xiaoyu Wang 已提交
932 933
  return res;
}
X
Xiaoyu Wang 已提交
934

X
Xiaoyu Wang 已提交
935
static bool phyNodeFromJson(const cJSON* json, void* obj) {
H
Haojun Liao 已提交
936 937
  SPhyNode* node = (SPhyNode*) obj;

938 939
  node->info.type = getNumber(json, jkPnodeType);
  node->info.name = opTypeToOpName(node->info.type);
H
Haojun Liao 已提交
940

X
Xiaoyu Wang 已提交
941 942 943 944 945
  bool res = fromArray(json, jkPnodeTargets, exprInfoFromJson, &node->pTargets, sizeof(SExprInfo));
  if (res) {
    res = fromArray(json, jkPnodeConditions, exprInfoFromJson, &node->pConditions, sizeof(SExprInfo));
  }
  if (res) {
X
Xiaoyu Wang 已提交
946
    res = fromObject(json, jkPnodeSchema, dataBlockSchemaFromJson, &node->targetSchema, true);
X
Xiaoyu Wang 已提交
947 948
  }
  if (res) {
949
    res = fromPnodeArray(json, jkPnodeChildren, phyNodeFromJson, &node->pChildren);
X
Xiaoyu Wang 已提交
950
  }
X
Xiaoyu Wang 已提交
951 952 953
  if (res) {
    res = fromObject(json, node->info.name, specificPhyNodeFromJson, node, true);
  }
X
Xiaoyu Wang 已提交
954
  return res;
X
Xiaoyu Wang 已提交
955 956
}

957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
static const char* jkInserterNumOfTables = "NumOfTables";
static const char* jkInserterDataSize = "DataSize";

static bool inserterToJson(const void* obj, cJSON* json) {
  const SDataInserter* inserter = (const SDataInserter*)obj;
  bool res = cJSON_AddNumberToObject(json, jkInserterNumOfTables, inserter->numOfTables);
  if (res) {
    res = cJSON_AddNumberToObject(json, jkInserterDataSize, inserter->size);
  }
  // todo pData
  return res;
}

static bool inserterFromJson(const cJSON* json, void* obj) {
  SDataInserter* inserter = (SDataInserter*)obj;
  inserter->numOfTables = getNumber(json, jkInserterNumOfTables);
  inserter->size = getNumber(json, jkInserterDataSize);
  // todo pData
}

static bool specificDataSinkToJson(const void* obj, cJSON* json) {
  const SDataSink* dsink = (const SDataSink*)obj;
  switch (dsink->info.type) {
    case DSINK_Dispatch:
      return true;
    case DSINK_Insert:
      return inserterToJson(obj, json);
    default:
      break;
  }
  return false;
}

static bool specificDataSinkFromJson(const cJSON* json, void* obj) {
  SDataSink* dsink = (SDataSink*)obj;
  switch (dsink->info.type) {
    case DSINK_Dispatch:
      return true;
    case DSINK_Insert:
      return inserterFromJson(json, obj);
    default:
      break;
  }
  return false;
}

static const char* jkDataSinkName = "Name";
X
Xiaoyu Wang 已提交
1004
static const char* jkDataSinkSchema = "Schema";
1005 1006 1007 1008 1009 1010 1011

static bool dataSinkToJson(const void* obj, cJSON* json) {
  const SDataSink* dsink = (const SDataSink*)obj;
  bool res = cJSON_AddStringToObject(json, jkDataSinkName, dsink->info.name);
  if (res) {
    res = addObject(json, dsink->info.name, specificDataSinkToJson, dsink);
  }
X
Xiaoyu Wang 已提交
1012 1013 1014
  if (res) {
    res = addObject(json, jkDataSinkSchema, dataBlockSchemaToJson, &dsink->schema);
  }
1015 1016 1017 1018 1019 1020 1021
  return res;
}

static bool dataSinkFromJson(const cJSON* json, void* obj) {
  SDataSink* dsink = (SDataSink*)obj;
  dsink->info.name = getString(json, jkDataSinkName);
  dsink->info.type = dsinkNameToDsinkType(dsink->info.name);
X
Xiaoyu Wang 已提交
1022 1023 1024 1025 1026
  bool res = fromObject(json, jkDataSinkSchema, dataBlockSchemaFromJson, &dsink->schema, true);
  if (res) {
    res = fromObject(json, dsink->info.name, specificDataSinkFromJson, dsink, true);
  }
  return res;
1027 1028
}

X
Xiaoyu Wang 已提交
1029 1030 1031
static const char* jkIdQueryId = "QueryId";
static const char* jkIdTemplateId = "TemplateId";
static const char* jkIdSubplanId = "SubplanId";
X
Xiaoyu Wang 已提交
1032

X
Xiaoyu Wang 已提交
1033 1034
static bool subplanIdToJson(const void* obj, cJSON* jId) {
  const SSubplanId* id = (const SSubplanId*)obj;
H
Haojun Liao 已提交
1035 1036 1037 1038 1039

  char ids[40] = {0};
  snprintf(ids, tListLen(ids), "%"PRIu64, id->queryId);

  bool res = cJSON_AddStringToObject(jId, jkIdQueryId, ids);
X
Xiaoyu Wang 已提交
1040
  if (res) {
X
Xiaoyu Wang 已提交
1041
    res = cJSON_AddNumberToObject(jId, jkIdTemplateId, id->templateId);
X
Xiaoyu Wang 已提交
1042 1043
  }
  if (res) {
X
Xiaoyu Wang 已提交
1044
    res = cJSON_AddNumberToObject(jId, jkIdSubplanId, id->subplanId);
X
Xiaoyu Wang 已提交
1045
  }
X
Xiaoyu Wang 已提交
1046 1047
  return res;
}
X
Xiaoyu Wang 已提交
1048

X
Xiaoyu Wang 已提交
1049 1050
static bool subplanIdFromJson(const cJSON* json, void* obj) {
  SSubplanId* id = (SSubplanId*)obj;
H
Haojun Liao 已提交
1051

H
Haojun Liao 已提交
1052
  id->queryId    = getBigintFromString(json, jkIdQueryId);
X
Xiaoyu Wang 已提交
1053
  id->templateId = getNumber(json, jkIdTemplateId);
H
Haojun Liao 已提交
1054
  id->subplanId  = getNumber(json, jkIdSubplanId);
X
Xiaoyu Wang 已提交
1055
  return true;
X
Xiaoyu Wang 已提交
1056 1057
}

X
Xiaoyu Wang 已提交
1058 1059
static const char* jkSubplanId = "Id";
static const char* jkSubplanNode = "Node";
1060
static const char* jkSubplanDataSink = "DataSink";
X
Xiaoyu Wang 已提交
1061

X
Xiaoyu Wang 已提交
1062 1063 1064 1065 1066 1067
static cJSON* subplanToJson(const SSubplan* subplan) {
  cJSON* jSubplan = cJSON_CreateObject();
  if (NULL == jSubplan) {
    return NULL;
  }

H
Haojun Liao 已提交
1068
  // The 'type', 'level', 'execEpSet', 'pChildren' and 'pParents' fields do not need to be serialized.
X
Xiaoyu Wang 已提交
1069
  bool res = addObject(jSubplan, jkSubplanId, subplanIdToJson, &subplan->id);
X
Xiaoyu Wang 已提交
1070
  if (res) {
X
Xiaoyu Wang 已提交
1071
    res = addObject(jSubplan, jkSubplanNode, phyNodeToJson, subplan->pNode);
X
Xiaoyu Wang 已提交
1072
  }
1073 1074 1075
  if (res) {
    res = addObject(jSubplan, jkSubplanDataSink, dataSinkToJson, subplan->pDataSink);
  }
X
Xiaoyu Wang 已提交
1076 1077 1078 1079
  if (!res) {
    cJSON_Delete(jSubplan);
    return NULL;
  }
H
Haojun Liao 已提交
1080

X
Xiaoyu Wang 已提交
1081 1082 1083
  return jSubplan;
}

X
Xiaoyu Wang 已提交
1084 1085 1086 1087 1088
static SSubplan* subplanFromJson(const cJSON* json) {
  SSubplan* subplan = calloc(1, sizeof(SSubplan));
  if (NULL == subplan) {
    return NULL;
  }
H
Haojun Liao 已提交
1089

X
Xiaoyu Wang 已提交
1090
  bool res = fromObject(json, jkSubplanId, subplanIdFromJson, &subplan->id, true);
H
Haojun Liao 已提交
1091

X
Xiaoyu Wang 已提交
1092
  if (res) {
1093
    res = fromPnode(json, jkSubplanNode, phyNodeFromJson, (void**)&subplan->pNode);
X
Xiaoyu Wang 已提交
1094
  }
H
Haojun Liao 已提交
1095

1096 1097 1098
  if (res) {
    res = fromObjectWithAlloc(json, jkSubplanDataSink, dataSinkFromJson, (void**)&subplan->pDataSink, sizeof(SDataSink), false);
  }
X
Xiaoyu Wang 已提交
1099 1100 1101 1102 1103 1104 1105 1106
  
  if (!res) {
    qDestroySubplan(subplan);
    return NULL;
  }
  return subplan;
}

1107 1108 1109 1110 1111
int32_t subPlanToString(const SSubplan* subplan, char** str, int32_t* len) {
  if (QUERY_TYPE_MODIFY == subplan->type) {
    SDataInserter* insert = (SDataInserter*)(subplan->pDataSink);
    *len = insert->size;
    *str = insert->pData;
H
Haojun Liao 已提交
1112
    insert->pData = NULL;
1113 1114 1115
    return TSDB_CODE_SUCCESS;
  }

X
Xiaoyu Wang 已提交
1116 1117 1118 1119 1120
  cJSON* json = subplanToJson(subplan);
  if (NULL == json) {
    terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
    return TSDB_CODE_FAILED;
  }
H
Haojun Liao 已提交
1121

X
Xiaoyu Wang 已提交
1122
  *str = cJSON_Print(json);
1123 1124
  cJSON_Delete(json);

X
Xiaoyu Wang 已提交
1125
  *len = strlen(*str) + 1;
X
Xiaoyu Wang 已提交
1126 1127 1128 1129
  return TSDB_CODE_SUCCESS;
}

int32_t stringToSubplan(const char* str, SSubplan** subplan) {
X
Xiaoyu Wang 已提交
1130 1131 1132 1133 1134 1135
  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 已提交
1136
}
L
Liu Jicong 已提交
1137 1138 1139

cJSON* qDagToJson(const SQueryDag* pDag) {
  cJSON* pRoot = cJSON_CreateObject();
L
Liu Jicong 已提交
1140 1141 1142
  if(pRoot == NULL) {
    return NULL;
  }
1143 1144 1145 1146

  cJSON_AddNumberToObject(pRoot, "Number", pDag->numOfSubplans);
  cJSON_AddNumberToObject(pRoot, "QueryId", pDag->queryId);

L
Liu Jicong 已提交
1147
  cJSON *pLevels = cJSON_CreateArray();
L
Liu Jicong 已提交
1148 1149 1150 1151
  if(pLevels == NULL) {
    cJSON_Delete(pRoot);
    return NULL;
  }
1152 1153 1154

  cJSON_AddItemToObject(pRoot, "Subplans", pLevels);

L
Liu Jicong 已提交
1155 1156 1157 1158 1159
  size_t level = taosArrayGetSize(pDag->pSubplans);
  for(size_t i = 0; i < level; i++) {
    const SArray* pSubplans = (const SArray*)taosArrayGetP(pDag->pSubplans, i);
    size_t num = taosArrayGetSize(pSubplans);
    cJSON* plansOneLevel = cJSON_CreateArray();
L
Liu Jicong 已提交
1160 1161 1162 1163
    if(plansOneLevel == NULL) {
      cJSON_Delete(pRoot);
      return NULL;
    }
1164

L
Liu Jicong 已提交
1165 1166 1167
    cJSON_AddItemToArray(pLevels, plansOneLevel);
    for(size_t j = 0; j < num; j++) {
      cJSON* pSubplan = subplanToJson((const SSubplan*)taosArrayGetP(pSubplans, j));
L
Liu Jicong 已提交
1168 1169 1170 1171
      if(pSubplan == NULL) {
        cJSON_Delete(pRoot);
        return NULL;
      }
1172

L
Liu Jicong 已提交
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
      cJSON_AddItemToArray(plansOneLevel, pSubplan);
    }
  }
  return pRoot;
}

char* qDagToString(const SQueryDag* pDag) {
  cJSON* pRoot = qDagToJson(pDag);
  return cJSON_Print(pRoot);
}

SQueryDag* qJsonToDag(const cJSON* pRoot) {
  SQueryDag* pDag = malloc(sizeof(SQueryDag));
  if(pDag == NULL) {
    return NULL;
  }
L
Liu Jicong 已提交
1189 1190
  pDag->numOfSubplans = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "Number"));
  pDag->queryId = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "QueryId"));
L
Liu Jicong 已提交
1191
  pDag->pSubplans = taosArrayInit(0, sizeof(SArray));
L
Liu Jicong 已提交
1192 1193 1194 1195
  if (pDag->pSubplans == NULL) {
    free(pDag);
    return NULL;
  }
L
Liu Jicong 已提交
1196
  cJSON* pLevels = cJSON_GetObjectItem(pRoot, "Subplans");
L
Liu Jicong 已提交
1197 1198
  int level = cJSON_GetArraySize(pLevels);
  for(int i = 0; i < level; i++) {
L
Liu Jicong 已提交
1199 1200 1201 1202 1203 1204 1205 1206 1207
    SArray* plansOneLevel = taosArrayInit(0, sizeof(void*));
    if(plansOneLevel == NULL) {
      for(int j = 0; j < i; j++) {
        taosArrayDestroy(taosArrayGetP(pDag->pSubplans, j));
      }
      taosArrayDestroy(pDag->pSubplans);
      free(pDag);
      return NULL;
    }
L
Liu Jicong 已提交
1208 1209 1210 1211 1212
    cJSON* pItem = cJSON_GetArrayItem(pLevels, i);
    int sz = cJSON_GetArraySize(pItem);
    for(int j = 0; j < sz; j++) {
      cJSON* pSubplanJson = cJSON_GetArrayItem(pItem, j);
      SSubplan* pSubplan = subplanFromJson(pSubplanJson);
L
Liu Jicong 已提交
1213 1214 1215
      taosArrayPush(plansOneLevel, &pSubplan);
    }
    taosArrayPush(pDag->pSubplans, plansOneLevel);
L
Liu Jicong 已提交
1216
  }
L
Liu Jicong 已提交
1217
  return pDag;
L
Liu Jicong 已提交
1218 1219 1220 1221 1222 1223
}

SQueryDag* qStringToDag(const char* pStr) {
  cJSON* pRoot = cJSON_Parse(pStr);
  return qJsonToDag(pRoot);
}