physicalPlanJson.c 39.6 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 120
    case OP_TableScan:
    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);
}

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
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 已提交
141
static bool addTarray(cJSON* json, const char* name, FToJson func, const SArray* array, bool isPoint) {
X
Xiaoyu Wang 已提交
142 143 144 145 146 147 148
  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 已提交
149
      if (!addItem(jArray, func, isPoint ? taosArrayGetP(array, i) : taosArrayGet(array, i))) {
X
Xiaoyu Wang 已提交
150 151 152 153 154 155 156
        return false;
      }
    }
  }
  return true;
}

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

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

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

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

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

X
Xiaoyu Wang 已提交
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
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 已提交
282

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

X
Xiaoyu Wang 已提交
573 574 575 576 577
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 已提交
578

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

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

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

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

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

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

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

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

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

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

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

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

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

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 700
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 已提交
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 738
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) {
S
Shengliang Guan 已提交
739
  const SEpAddr* ep = (const SEpAddr*)obj;
X
Xiaoyu Wang 已提交
740 741 742 743 744 745 746 747
  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) {
S
Shengliang Guan 已提交
748
  SEpAddr* ep = (SEpAddr*)obj;
X
Xiaoyu Wang 已提交
749 750 751 752 753
  copyString(json, jkEpAddrFqdn, ep->fqdn);
  ep->port = getNumber(json, jkEpAddrPort);
  return true;
}

H
Haojun Liao 已提交
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
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) {
    res = cJSON_AddNumberToObject(json, jkNodeAddrInUse, pAddr->inUse);
  }

  if (res) {
    res = addRawArray(json, jkNodeAddrEpAddrs, epAddrToJson, pAddr->epAddr, sizeof(SEpAddr), pAddr->numOfEps);
  }
  return res;
}

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

  pAddr->nodeId = getNumber(json, jkNodeAddrId);
  pAddr->inUse = getNumber(json, jkNodeAddrInUse);

  int32_t numOfEps = 0;
  bool res = fromRawArray(json, jkNodeAddrEpAddrs, epAddrFromJson, pAddr->epAddr, sizeof(SEpAddr), &numOfEps);
  pAddr->numOfEps = numOfEps;
  return res;
}
X
Xiaoyu Wang 已提交
786 787

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

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

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

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

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

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

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 已提交
819
    res = addRawArray(json, jkExchangeNodeSrcEndPoints, nodeAddrToJson, exchange->pSrcEndPoints->pData, sizeof(SDownstreamSource), taosArrayGetSize(exchange->pSrcEndPoints));
X
Xiaoyu Wang 已提交
820 821 822 823 824 825 826
  }
  return res;
}

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

static bool specificPhyNodeToJson(const void* obj, cJSON* json) {
  const SPhyNode* phyNode = (const SPhyNode*)obj;
  switch (phyNode->info.type) {
H
Haojun Liao 已提交
833
    case OP_StreamScan:
X
Xiaoyu Wang 已提交
834 835 836 837 838 839 840 841
    case OP_TableScan:
    case OP_DataBlocksOptScan:
    case OP_TableSeqScan:
      return tableScanNodeToJson(obj, json);
    case OP_TagScan:
    case OP_SystemTableScan:
      return scanNodeToJson(obj, json);
    case OP_Aggregate:
842
      return aggNodeToJson(obj, json);
X
Xiaoyu Wang 已提交
843 844
    case OP_Project:
      return true;
845
    // case OP_Groupby:
X
Xiaoyu Wang 已提交
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
    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) {
    case OP_TableScan:
L
Liu Jicong 已提交
873
    case OP_StreamScan:
X
Xiaoyu Wang 已提交
874 875 876 877 878 879 880
    case OP_DataBlocksOptScan:
    case OP_TableSeqScan:
      return tableScanNodeFromJson(json, obj);
    case OP_TagScan:
    case OP_SystemTableScan:
      return scanNodeFromJson(json, obj);
    case OP_Aggregate:
881
      return aggNodeFromJson(json, obj);
X
Xiaoyu Wang 已提交
882 883
    case OP_Project:
      return true;
884
    // case OP_Groupby:
X
Xiaoyu Wang 已提交
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
    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 已提交
908 909 910
static const char* jkPnodeName = "Name";
static const char* jkPnodeTargets = "Targets";
static const char* jkPnodeConditions = "Conditions";
911
static const char* jkPnodeSchema = "TargetSchema";
X
Xiaoyu Wang 已提交
912 913 914
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 已提交
915
  const SPhyNode* phyNode = (const SPhyNode*)obj;
916 917 918 919
  bool res = cJSON_AddNumberToObject(jNode, jkPnodeType, phyNode->info.type);
  if (res) {
    res = cJSON_AddStringToObject(jNode, jkPnodeName, phyNode->info.name);
  }
X
Xiaoyu Wang 已提交
920
  if (res) {
X
Xiaoyu Wang 已提交
921
    res = addArray(jNode, jkPnodeTargets, exprInfoToJson, phyNode->pTargets);
X
Xiaoyu Wang 已提交
922 923
  }
  if (res) {
X
Xiaoyu Wang 已提交
924
    res = addArray(jNode, jkPnodeConditions, exprInfoToJson, phyNode->pConditions);
X
Xiaoyu Wang 已提交
925 926
  }
  if (res) {
X
Xiaoyu Wang 已提交
927
    res = addObject(jNode, jkPnodeSchema, dataBlockSchemaToJson, &phyNode->targetSchema);
X
Xiaoyu Wang 已提交
928 929
  }
  if (res) {
X
Xiaoyu Wang 已提交
930
    res = addArray(jNode, jkPnodeChildren, phyNodeToJson, phyNode->pChildren);
X
Xiaoyu Wang 已提交
931
  }
X
Xiaoyu Wang 已提交
932 933 934
  if (res) {
    res = addObject(jNode, phyNode->info.name, specificPhyNodeToJson, phyNode);
  }
X
Xiaoyu Wang 已提交
935 936
  return res;
}
X
Xiaoyu Wang 已提交
937

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

941 942
  node->info.type = getNumber(json, jkPnodeType);
  node->info.name = opTypeToOpName(node->info.type);
H
Haojun Liao 已提交
943

X
Xiaoyu Wang 已提交
944 945 946 947 948
  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 已提交
949
    res = fromObject(json, jkPnodeSchema, dataBlockSchemaFromJson, &node->targetSchema, true);
X
Xiaoyu Wang 已提交
950 951
  }
  if (res) {
952
    res = fromPnodeArray(json, jkPnodeChildren, phyNodeFromJson, &node->pChildren);
X
Xiaoyu Wang 已提交
953
  }
X
Xiaoyu Wang 已提交
954 955 956
  if (res) {
    res = fromObject(json, node->info.name, specificPhyNodeFromJson, node, true);
  }
X
Xiaoyu Wang 已提交
957
  return res;
X
Xiaoyu Wang 已提交
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 1004 1005 1006
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 已提交
1007
static const char* jkDataSinkSchema = "Schema";
1008 1009 1010 1011 1012 1013 1014

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 已提交
1015 1016 1017
  if (res) {
    res = addObject(json, jkDataSinkSchema, dataBlockSchemaToJson, &dsink->schema);
  }
1018 1019 1020 1021 1022 1023 1024
  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 已提交
1025 1026 1027 1028 1029
  bool res = fromObject(json, jkDataSinkSchema, dataBlockSchemaFromJson, &dsink->schema, true);
  if (res) {
    res = fromObject(json, dsink->info.name, specificDataSinkFromJson, dsink, true);
  }
  return res;
1030 1031
}

X
Xiaoyu Wang 已提交
1032 1033 1034
static const char* jkIdQueryId = "QueryId";
static const char* jkIdTemplateId = "TemplateId";
static const char* jkIdSubplanId = "SubplanId";
X
Xiaoyu Wang 已提交
1035

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

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

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

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

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

X
Xiaoyu Wang 已提交
1061 1062
static const char* jkSubplanId = "Id";
static const char* jkSubplanNode = "Node";
1063
static const char* jkSubplanDataSink = "DataSink";
X
Xiaoyu Wang 已提交
1064

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

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

X
Xiaoyu Wang 已提交
1084 1085 1086
  return jSubplan;
}

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

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

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

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

1110 1111 1112 1113 1114
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 已提交
1115
    insert->pData = NULL;
1116 1117 1118
    return TSDB_CODE_SUCCESS;
  }

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

X
Xiaoyu Wang 已提交
1125
  *str = cJSON_Print(json);
1126 1127 1128 1129
  cJSON_Delete(json);

  printf("====Physical plan:====\n");
  printf("%s\n", *str);
X
Xiaoyu Wang 已提交
1130
  *len = strlen(*str) + 1;
X
Xiaoyu Wang 已提交
1131 1132 1133 1134
  return TSDB_CODE_SUCCESS;
}

int32_t stringToSubplan(const char* str, SSubplan** subplan) {
X
Xiaoyu Wang 已提交
1135 1136 1137 1138 1139 1140
  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 已提交
1141
}
L
Liu Jicong 已提交
1142 1143 1144

cJSON* qDagToJson(const SQueryDag* pDag) {
  cJSON* pRoot = cJSON_CreateObject();
L
Liu Jicong 已提交
1145 1146 1147
  if(pRoot == NULL) {
    return NULL;
  }
1148 1149 1150 1151

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

L
Liu Jicong 已提交
1152
  cJSON *pLevels = cJSON_CreateArray();
L
Liu Jicong 已提交
1153 1154 1155 1156
  if(pLevels == NULL) {
    cJSON_Delete(pRoot);
    return NULL;
  }
1157 1158 1159

  cJSON_AddItemToObject(pRoot, "Subplans", pLevels);

L
Liu Jicong 已提交
1160 1161 1162 1163 1164
  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 已提交
1165 1166 1167 1168
    if(plansOneLevel == NULL) {
      cJSON_Delete(pRoot);
      return NULL;
    }
1169

L
Liu Jicong 已提交
1170 1171 1172
    cJSON_AddItemToArray(pLevels, plansOneLevel);
    for(size_t j = 0; j < num; j++) {
      cJSON* pSubplan = subplanToJson((const SSubplan*)taosArrayGetP(pSubplans, j));
L
Liu Jicong 已提交
1173 1174 1175 1176
      if(pSubplan == NULL) {
        cJSON_Delete(pRoot);
        return NULL;
      }
1177

L
Liu Jicong 已提交
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
      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 已提交
1194 1195
  pDag->numOfSubplans = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "Number"));
  pDag->queryId = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "QueryId"));
L
Liu Jicong 已提交
1196
  pDag->pSubplans = taosArrayInit(0, sizeof(SArray));
L
Liu Jicong 已提交
1197 1198 1199 1200
  if (pDag->pSubplans == NULL) {
    free(pDag);
    return NULL;
  }
L
Liu Jicong 已提交
1201
  cJSON* pLevels = cJSON_GetObjectItem(pRoot, "Subplans");
L
Liu Jicong 已提交
1202 1203
  int level = cJSON_GetArraySize(pLevels);
  for(int i = 0; i < level; i++) {
L
Liu Jicong 已提交
1204 1205 1206 1207 1208 1209 1210 1211 1212
    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 已提交
1213 1214 1215 1216 1217
    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 已提交
1218 1219 1220
      taosArrayPush(plansOneLevel, &pSubplan);
    }
    taosArrayPush(pDag->pSubplans, plansOneLevel);
L
Liu Jicong 已提交
1221
  }
L
Liu Jicong 已提交
1222
  return pDag;
L
Liu Jicong 已提交
1223 1224 1225 1226 1227 1228
}

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