scalar.c 51.4 KB
Newer Older
H
Hongze Cheng 已提交
1
#include "scalar.h"
D
dapan1121 已提交
2 3
#include "function.h"
#include "functionMgt.h"
H
Haojun Liao 已提交
4 5
#include "nodes.h"
#include "querynodes.h"
D
dapan1121 已提交
6
#include "sclInt.h"
H
Haojun Liao 已提交
7 8
#include "sclvector.h"
#include "tcommon.h"
H
Hongze Cheng 已提交
9
#include "tcompare.h"
H
Haojun Liao 已提交
10
#include "tdatablock.h"
D
fix bug  
dapan1121 已提交
11
#include "ttime.h"
H
Hongze Cheng 已提交
12
#include "tudf.h"
D
dapan1121 已提交
13

D
dapan1121 已提交
14
int32_t scalarGetOperatorParamNum(EOperatorType type) {
H
Hongze Cheng 已提交
15 16 17
  if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type || OP_TYPE_IS_TRUE == type ||
      OP_TYPE_IS_NOT_TRUE == type || OP_TYPE_IS_FALSE == type || OP_TYPE_IS_NOT_FALSE == type ||
      OP_TYPE_IS_UNKNOWN == type || OP_TYPE_IS_NOT_UNKNOWN == type || OP_TYPE_MINUS == type) {
D
dapan1121 已提交
18 19 20 21 22 23
    return 1;
  }

  return 2;
}

H
Hongze Cheng 已提交
24 25
int32_t sclConvertToTsValueNode(int8_t precision, SValueNode *valueNode) {
  char   *timeStr = valueNode->datum.p;
X
Xiaoyu Wang 已提交
26 27
  int64_t value = 0;
  int32_t code = convertStringToTimestamp(valueNode->node.resType.type, valueNode->datum.p, precision, &value);
D
dapan1121 已提交
28 29
  if (code != TSDB_CODE_SUCCESS) {
    return code;
D
dapan 已提交
30 31
  }
  taosMemoryFree(timeStr);
X
Xiaoyu Wang 已提交
32
  valueNode->datum.i = value;
D
dapan1121 已提交
33
  valueNode->typeData = valueNode->datum.i;
G
Ganlin Zhao 已提交
34

D
dapan 已提交
35 36
  valueNode->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
  valueNode->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
D
dapan1121 已提交
37 38

  return TSDB_CODE_SUCCESS;
D
dapan 已提交
39 40
}

H
Hongze Cheng 已提交
41 42
int32_t sclCreateColumnInfoData(SDataType *pType, int32_t numOfRows, SScalarParam *pParam) {
  SColumnInfoData *pColumnData = taosMemoryCalloc(1, sizeof(SColumnInfoData));
43 44
  if (pColumnData == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
45
    return terrno;
46 47
  }

H
Hongze Cheng 已提交
48 49 50
  pColumnData->info.type = pType->type;
  pColumnData->info.bytes = pType->bytes;
  pColumnData->info.scale = pType->scale;
51 52
  pColumnData->info.precision = pType->precision;

H
Haojun Liao 已提交
53
  int32_t code = colInfoDataEnsureCapacity(pColumnData, numOfRows, true);
54 55
  if (code != TSDB_CODE_SUCCESS) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
56
    taosMemoryFree(pColumnData);
H
Haojun Liao 已提交
57
    return terrno;
58
  }
H
Haojun Liao 已提交
59 60

  pParam->columnData = pColumnData;
D
dapan1121 已提交
61
  pParam->colAlloced = true;
H
Haojun Liao 已提交
62
  return TSDB_CODE_SUCCESS;
63 64
}

X
Xiaoyu Wang 已提交
65
int32_t sclConvertValueToSclParam(SValueNode *pValueNode, SScalarParam *out, int32_t *overflow) {
66
  SScalarParam in = {.numOfRows = 1};
H
Hongze Cheng 已提交
67
  int32_t      code = sclCreateColumnInfoData(&pValueNode->node.resType, 1, &in);
H
Haojun Liao 已提交
68 69 70 71
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

72
  colDataAppend(in.columnData, 0, nodesGetValueFromNode(pValueNode), false);
73

H
Haojun Liao 已提交
74
  colInfoDataEnsureCapacity(out->columnData, 1, true);
D
dapan1121 已提交
75
  code = vectorConvertSingleColImpl(&in, out, overflow, -1, -1);
76 77 78
  sclFreeParam(&in);

  return code;
79 80
}

D
dapan1121 已提交
81
int32_t sclExtendResRows(SScalarParam *pDst, SScalarParam *pSrc, SArray *pBlockList) {
X
Xiaoyu Wang 已提交
82
  SSDataBlock  *pb = taosArrayGetP(pBlockList, 0);
D
dapan1121 已提交
83 84 85 86 87 88 89 90 91
  SScalarParam *pLeft = taosMemoryCalloc(1, sizeof(SScalarParam));
  if (NULL == pLeft) {
    sclError("calloc %d failed", (int32_t)sizeof(SScalarParam));
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

  pLeft->numOfRows = pb->info.rows;

  if (pDst->numOfRows < pb->info.rows) {
H
Haojun Liao 已提交
92
    colInfoDataEnsureCapacity(pDst->columnData, pb->info.rows, true);
D
dapan1121 已提交
93
  }
X
Xiaoyu Wang 已提交
94

D
dapan1121 已提交
95 96 97 98 99 100 101 102
  _bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(OP_TYPE_ASSIGN);
  OperatorFn(pLeft, pSrc, pDst, TSDB_ORDER_ASC);

  taosMemoryFree(pLeft);

  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
103 104 105 106 107 108 109
int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
  SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
  if (NULL == pObj) {
    sclError("taosHashInit failed, size:%d", 256);
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

G
Ganlin Zhao 已提交
110
  taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type));
D
dapan1121 已提交
111

H
Hongze Cheng 已提交
112
  int32_t        code = 0;
D
dapan1121 已提交
113
  SNodeListNode *nodeList = (SNodeListNode *)pNode;
H
Hongze Cheng 已提交
114 115
  SListCell     *cell = nodeList->pNodeList->pHead;
  SScalarParam   out = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
116

D
dapan1121 已提交
117
  int32_t len = 0;
H
Hongze Cheng 已提交
118
  void   *buf = NULL;
G
Ganlin Zhao 已提交
119

D
dapan1121 已提交
120 121
  for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) {
    SValueNode *valueNode = (SValueNode *)cell->pNode;
G
Ganlin Zhao 已提交
122

D
dapan1121 已提交
123
    if (valueNode->node.resType.type != type) {
124
      out.columnData->info.type = type;
D
dapan1121 已提交
125 126 127 128 129 130 131 132 133
      if (IS_VAR_DATA_TYPE(type)) {
        if (IS_VAR_DATA_TYPE(valueNode->node.resType.type)) {
          out.columnData->info.bytes = valueNode->node.resType.bytes * TSDB_NCHAR_SIZE;
        } else {
          out.columnData->info.bytes = 64 * TSDB_NCHAR_SIZE;
        }
      } else {
        out.columnData->info.bytes = tDataTypes[type].bytes;
      }
134

D
dapan1121 已提交
135
      int32_t overflow = 0;
D
dapan1121 已提交
136
      code = sclConvertValueToSclParam(valueNode, &out, &overflow);
137
      if (code != TSDB_CODE_SUCCESS) {
H
Hongze Cheng 已提交
138
        //        sclError("convert data from %d to %d failed", in.type, out.type);
D
dapan1121 已提交
139 140 141
        SCL_ERR_JRET(code);
      }

D
dapan1121 已提交
142 143 144 145 146
      if (overflow) {
        cell = cell->pNext;
        continue;
      }

D
dapan1121 已提交
147
      if (IS_VAR_DATA_TYPE(type)) {
148
        buf = colDataGetVarData(out.columnData, 0);
D
dapan1121 已提交
149
        len = varDataTLen(buf);
D
dapan1121 已提交
150 151
      } else {
        len = tDataTypes[type].bytes;
152
        buf = out.columnData->pData;
D
dapan1121 已提交
153 154 155
      }
    } else {
      buf = nodesGetValueFromNode(valueNode);
D
dapan1121 已提交
156
      if (IS_VAR_DATA_TYPE(type)) {
157
        len = varDataTLen(buf);
D
dapan1121 已提交
158 159
      } else {
        len = valueNode->node.resType.bytes;
160
      }
D
dapan1121 已提交
161
    }
G
Ganlin Zhao 已提交
162

163
    if (taosHashPut(pObj, buf, (size_t)len, NULL, 0)) {
D
dapan1121 已提交
164
      sclError("taosHashPut to set failed");
D
dapan1121 已提交
165 166
      SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
    }
D
dapan1121 已提交
167

D
dapan1121 已提交
168 169 170 171
    colDataDestroy(out.columnData);
    taosMemoryFreeClear(out.columnData);
    out.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData));

D
dapan1121 已提交
172
    cell = cell->pNext;
D
dapan1121 已提交
173 174 175
  }

  *data = pObj;
D
dapan1121 已提交
176 177 178

  colDataDestroy(out.columnData);
  taosMemoryFreeClear(out.columnData);
D
dapan1121 已提交
179 180 181
  return TSDB_CODE_SUCCESS;

_return:
D
dapan1121 已提交
182 183 184

  colDataDestroy(out.columnData);
  taosMemoryFreeClear(out.columnData);
D
dapan1121 已提交
185 186 187 188
  taosHashCleanup(pObj);
  SCL_RET(code);
}

D
dapan1121 已提交
189 190
void sclFreeRes(SHashObj *res) {
  SScalarParam *p = NULL;
H
Hongze Cheng 已提交
191
  void         *pIter = taosHashIterate(res, NULL);
D
dapan1121 已提交
192 193 194 195
  while (pIter) {
    p = (SScalarParam *)pIter;

    if (p) {
D
dapan 已提交
196
      sclFreeParam(p);
D
dapan1121 已提交
197 198 199 200 201 202
    }
    pIter = taosHashIterate(res, pIter);
  }
  taosHashCleanup(res);
}

D
dapan1121 已提交
203
void sclFreeParam(SScalarParam *param) {
D
dapan1121 已提交
204
  if (NULL == param || !param->colAlloced) {
D
dapan1121 已提交
205 206
    return;
  }
H
Hongze Cheng 已提交
207

D
dapan1121 已提交
208
  if (param->columnData != NULL) {
209
    colDataDestroy(param->columnData);
210
    taosMemoryFreeClear(param->columnData);
211 212 213 214
  }

  if (param->pHashFilter != NULL) {
    taosHashCleanup(param->pHashFilter);
D
dapan1121 已提交
215
    param->pHashFilter = NULL;
216
  }
D
dapan1121 已提交
217 218
}

D
dapan1121 已提交
219 220 221 222
int32_t sclCopyValueNodeValue(SValueNode *pNode, void **res) {
  if (TSDB_DATA_TYPE_NULL == pNode->node.resType.type) {
    return TSDB_CODE_SUCCESS;
  }
G
Ganlin Zhao 已提交
223

wafwerar's avatar
wafwerar 已提交
224
  *res = taosMemoryMalloc(pNode->node.resType.bytes);
D
dapan1121 已提交
225 226 227 228 229 230 231 232 233
  if (NULL == (*res)) {
    sclError("malloc %d failed", pNode->node.resType.bytes);
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

  memcpy(*res, nodesGetValueFromNode(pNode), pNode->node.resType.bytes);
  return TSDB_CODE_SUCCESS;
}

D
dapan1121 已提交
234 235 236 237 238 239
void sclFreeParamList(SScalarParam *param, int32_t paramNum) {
  if (NULL == param) {
    return;
  }

  for (int32_t i = 0; i < paramNum; ++i) {
H
Hongze Cheng 已提交
240
    SScalarParam *p = param + i;
D
dapan1121 已提交
241 242 243 244 245 246
    sclFreeParam(p);
  }

  taosMemoryFree(param);
}

247 248 249 250 251 252
void sclDowngradeValueType(SValueNode *valueNode) {
  switch (valueNode->node.resType.type) {
    case TSDB_DATA_TYPE_BIGINT: {
      int8_t i8 = valueNode->datum.i;
      if (i8 == valueNode->datum.i) {
        valueNode->node.resType.type = TSDB_DATA_TYPE_TINYINT;
H
Hongze Cheng 已提交
253
        *(int8_t *)&valueNode->typeData = i8;
254 255 256 257 258
        break;
      }
      int16_t i16 = valueNode->datum.i;
      if (i16 == valueNode->datum.i) {
        valueNode->node.resType.type = TSDB_DATA_TYPE_SMALLINT;
H
Hongze Cheng 已提交
259
        *(int16_t *)&valueNode->typeData = i16;
260 261 262 263 264
        break;
      }
      int32_t i32 = valueNode->datum.i;
      if (i32 == valueNode->datum.i) {
        valueNode->node.resType.type = TSDB_DATA_TYPE_INT;
H
Hongze Cheng 已提交
265
        *(int32_t *)&valueNode->typeData = i32;
266 267 268 269
        break;
      }
      break;
    }
H
Hongze Cheng 已提交
270
    case TSDB_DATA_TYPE_UBIGINT: {
271 272 273 274 275
      uint8_t u8 = valueNode->datum.i;
      if (u8 == valueNode->datum.i) {
        int8_t i8 = valueNode->datum.i;
        if (i8 == valueNode->datum.i) {
          valueNode->node.resType.type = TSDB_DATA_TYPE_TINYINT;
H
Hongze Cheng 已提交
276
          *(int8_t *)&valueNode->typeData = i8;
277 278
        } else {
          valueNode->node.resType.type = TSDB_DATA_TYPE_UTINYINT;
H
Hongze Cheng 已提交
279
          *(uint8_t *)&valueNode->typeData = u8;
280 281 282 283 284 285 286 287
        }
        break;
      }
      uint16_t u16 = valueNode->datum.i;
      if (u16 == valueNode->datum.i) {
        int16_t i16 = valueNode->datum.i;
        if (i16 == valueNode->datum.i) {
          valueNode->node.resType.type = TSDB_DATA_TYPE_SMALLINT;
H
Hongze Cheng 已提交
288
          *(int16_t *)&valueNode->typeData = i16;
289 290
        } else {
          valueNode->node.resType.type = TSDB_DATA_TYPE_USMALLINT;
H
Hongze Cheng 已提交
291
          *(uint16_t *)&valueNode->typeData = u16;
292 293 294 295 296 297 298 299
        }
        break;
      }
      uint32_t u32 = valueNode->datum.i;
      if (u32 == valueNode->datum.i) {
        int32_t i32 = valueNode->datum.i;
        if (i32 == valueNode->datum.i) {
          valueNode->node.resType.type = TSDB_DATA_TYPE_INT;
H
Hongze Cheng 已提交
300
          *(int32_t *)&valueNode->typeData = i32;
301 302
        } else {
          valueNode->node.resType.type = TSDB_DATA_TYPE_UINT;
H
Hongze Cheng 已提交
303
          *(uint32_t *)&valueNode->typeData = u32;
304 305 306 307 308 309 310 311 312
        }
        break;
      }
      break;
    }
    case TSDB_DATA_TYPE_DOUBLE: {
      float f = valueNode->datum.d;
      if (FLT_EQUAL(f, valueNode->datum.d)) {
        valueNode->node.resType.type = TSDB_DATA_TYPE_FLOAT;
H
Hongze Cheng 已提交
313
        *(float *)&valueNode->typeData = f;
314 315 316 317 318 319 320 321 322
        break;
      }
      break;
    }
    default:
      break;
  }
}

H
Hongze Cheng 已提交
323
int32_t sclInitParam(SNode *node, SScalarParam *param, SScalarCtx *ctx, int32_t *rowNum) {
D
dapan1121 已提交
324
  switch (nodeType(node)) {
D
dapan1121 已提交
325
    case QUERY_NODE_LEFT_VALUE: {
H
Hongze Cheng 已提交
326
      SSDataBlock *pb = taosArrayGetP(ctx->pBlockList, 0);
D
dapan1121 已提交
327 328 329
      param->numOfRows = pb->info.rows;
      break;
    }
D
dapan1121 已提交
330 331
    case QUERY_NODE_VALUE: {
      SValueNode *valueNode = (SValueNode *)node;
332

H
Haojun Liao 已提交
333
      ASSERT(param->columnData == NULL);
334
      param->numOfRows = 1;
G
Ganlin Zhao 已提交
335 336 337 338
      int32_t code = sclCreateColumnInfoData(&valueNode->node.resType, 1, param);
      if (code != TSDB_CODE_SUCCESS) {
        SCL_RET(TSDB_CODE_OUT_OF_MEMORY);
      }
wmmhello's avatar
wmmhello 已提交
339
      if (TSDB_DATA_TYPE_NULL == valueNode->node.resType.type || valueNode->isNull) {
340
        colDataAppendNULL(param->columnData, 0);
341 342
      } else {
        colDataAppend(param->columnData, 0, nodesGetValueFromNode(valueNode), false);
D
dapan1121 已提交
343
      }
D
dapan1121 已提交
344 345
      break;
    }
D
dapan1121 已提交
346 347
    case QUERY_NODE_NODE_LIST: {
      SNodeListNode *nodeList = (SNodeListNode *)node;
348 349
      if (LIST_LENGTH(nodeList->pNodeList) <= 0) {
        sclError("invalid length in nodeList, length:%d", LIST_LENGTH(nodeList->pNodeList));
D
dapan1121 已提交
350 351 352
        SCL_RET(TSDB_CODE_QRY_INVALID_INPUT);
      }

D
dapan1121 已提交
353 354 355 356
      int32_t type = vectorGetConvertType(ctx->type.selfType, ctx->type.peerType);
      if (type == 0) {
        type = nodeList->dataType.type;
      }
G
Ganlin Zhao 已提交
357

D
dapan1121 已提交
358 359
      SCL_ERR_RET(scalarGenerateSetFromList((void **)&param->pHashFilter, node, type));
      param->hashValueType = type;
D
dapan1121 已提交
360
      param->colAlloced = true;
D
dapan 已提交
361
      if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
362
        taosHashCleanup(param->pHashFilter);
D
dapan1121 已提交
363
        param->pHashFilter = NULL;
D
dapan 已提交
364 365
        sclError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
        return TSDB_CODE_QRY_OUT_OF_MEMORY;
G
Ganlin Zhao 已提交
366
      }
D
dapan1121 已提交
367
      param->colAlloced = false;
D
dapan1121 已提交
368 369
      break;
    }
X
Xiaoyu Wang 已提交
370
    case QUERY_NODE_COLUMN: {
D
dapan 已提交
371 372
      if (NULL == ctx->pBlockList) {
        sclError("invalid node type for constant calculating, type:%d, src:%p", nodeType(node), ctx->pBlockList);
D
dapan1121 已提交
373 374
        SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
      }
G
Ganlin Zhao 已提交
375

X
Xiaoyu Wang 已提交
376
      SColumnNode *ref = (SColumnNode *)node;
377 378

      int32_t index = -1;
H
Hongze Cheng 已提交
379 380
      for (int32_t i = 0; i < taosArrayGetSize(ctx->pBlockList); ++i) {
        SSDataBlock *pb = taosArrayGetP(ctx->pBlockList, i);
381 382 383 384 385 386 387
        if (pb->info.blockId == ref->dataBlockId) {
          index = i;
          break;
        }
      }

      if (index == -1) {
H
Hongze Cheng 已提交
388 389
        sclError("column tupleId is too big, tupleId:%d, dataBlockNum:%d", ref->dataBlockId,
                 (int32_t)taosArrayGetSize(ctx->pBlockList));
D
dapan 已提交
390 391 392
        SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
      }

393
      SSDataBlock *block = *(SSDataBlock **)taosArrayGet(ctx->pBlockList, index);
G
Ganlin Zhao 已提交
394 395 396 397 398
      if (NULL == block) {
        SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
      }

      if (ref->slotId >= taosArrayGetSize(block->pDataBlock)) {
H
Hongze Cheng 已提交
399 400
        sclError("column slotId is too big, slodId:%d, dataBlockSize:%d", ref->slotId,
                 (int32_t)taosArrayGetSize(block->pDataBlock));
D
dapan1121 已提交
401 402 403
        SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
      }

D
dapan 已提交
404
      SColumnInfoData *columnData = (SColumnInfoData *)taosArrayGet(block->pDataBlock, ref->slotId);
405
#if TAG_FILTER_DEBUG
H
Hongze Cheng 已提交
406 407
      qDebug("tagfilter column info, slotId:%d, colId:%d, type:%d", ref->slotId, columnData->info.colId,
             columnData->info.type);
408
#endif
409 410
      param->numOfRows = block->info.rows;
      param->columnData = columnData;
D
dapan1121 已提交
411 412
      break;
    }
413 414
    case QUERY_NODE_FUNCTION:
    case QUERY_NODE_OPERATOR:
D
dapan1121 已提交
415 416
    case QUERY_NODE_LOGIC_CONDITION:
    case QUERY_NODE_CASE_WHEN: {
D
dapan1121 已提交
417 418 419 420 421 422
      SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, &node, POINTER_BYTES);
      if (NULL == res) {
        sclError("no result for node, type:%d, node:%p", nodeType(node), node);
        SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
      }
      *param = *res;
D
dapan1121 已提交
423
      param->colAlloced = false;
D
dapan1121 已提交
424 425
      break;
    }
426 427
    default:
      break;
D
dapan1121 已提交
428 429
  }

430 431 432
  if (param->numOfRows > *rowNum) {
    if ((1 != param->numOfRows) && (1 < *rowNum)) {
      sclError("different row nums, rowNum:%d, newRowNum:%d", *rowNum, param->numOfRows);
D
dapan1121 已提交
433 434
      SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
    }
G
Ganlin Zhao 已提交
435

436
    *rowNum = param->numOfRows;
D
dapan1121 已提交
437 438
  }

439
  param->param = ctx->param;
D
dapan1121 已提交
440 441 442
  return TSDB_CODE_SUCCESS;
}

H
Hongze Cheng 已提交
443 444
int32_t sclInitParamList(SScalarParam **pParams, SNodeList *pParamList, SScalarCtx *ctx, int32_t *paramNum,
                         int32_t *rowNum) {
D
dapan1121 已提交
445
  int32_t code = 0;
D
dapan1121 已提交
446 447
  if (NULL == pParamList) {
    if (ctx->pBlockList) {
D
dapan1121 已提交
448
      SSDataBlock *pBlock = taosArrayGetP(ctx->pBlockList, 0);
D
dapan1121 已提交
449 450 451 452 453
      *rowNum = pBlock->info.rows;
    } else {
      *rowNum = 1;
    }

D
dapan 已提交
454
    *paramNum = 1;
D
dapan1121 已提交
455
  } else {
D
dapan 已提交
456
    *paramNum = pParamList->length;
D
dapan1121 已提交
457 458
  }

D
dapan 已提交
459
  SScalarParam *paramList = taosMemoryCalloc(*paramNum, sizeof(SScalarParam));
D
dapan1121 已提交
460
  if (NULL == paramList) {
D
dapan 已提交
461
    sclError("calloc %d failed", (int32_t)((*paramNum) * sizeof(SScalarParam)));
D
dapan1121 已提交
462
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
D
dapan1121 已提交
463 464
  }

D
dapan1121 已提交
465
  if (pParamList) {
H
Hongze Cheng 已提交
466
    SNode  *tnode = NULL;
D
dapan1121 已提交
467 468
    int32_t i = 0;
    if (SCL_IS_CONST_CALC(ctx)) {
H
Hongze Cheng 已提交
469
      WHERE_EACH(tnode, pParamList) {
D
dapan1121 已提交
470
        if (!SCL_IS_CONST_NODE(tnode)) {
D
dapan 已提交
471
          WHERE_NEXT;
D
dapan1121 已提交
472 473 474 475
        } else {
          SCL_ERR_JRET(sclInitParam(tnode, &paramList[i], ctx, rowNum));
          ERASE_NODE(pParamList);
        }
G
Ganlin Zhao 已提交
476

D
dapan1121 已提交
477 478 479
        ++i;
      }
    } else {
G
Ganlin Zhao 已提交
480
      FOREACH(tnode, pParamList) {
D
dapan1121 已提交
481 482 483
        SCL_ERR_JRET(sclInitParam(tnode, &paramList[i], ctx, rowNum));
        ++i;
      }
D
dapan1121 已提交
484
    }
D
dapan1121 已提交
485 486 487
  } else {
    paramList[0].numOfRows = *rowNum;
  }
D
dapan1121 已提交
488

D
dapan1121 已提交
489
  if (0 == *rowNum) {
G
Ganlin Zhao 已提交
490
    taosMemoryFreeClear(paramList);
D
dapan1121 已提交
491
  }
D
dapan1121 已提交
492

D
dapan1121 已提交
493
  *pParams = paramList;
D
dapan1121 已提交
494
  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
495

D
dapan1121 已提交
496
_return:
wafwerar's avatar
wafwerar 已提交
497
  taosMemoryFreeClear(paramList);
D
dapan1121 已提交
498 499 500
  SCL_RET(code);
}

D
dapan1121 已提交
501 502 503 504
int32_t sclGetNodeType(SNode *pNode, SScalarCtx *ctx) {
  if (NULL == pNode) {
    return -1;
  }
G
Ganlin Zhao 已提交
505

wafwerar's avatar
wafwerar 已提交
506
  switch ((int)nodeType(pNode)) {
D
dapan1121 已提交
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
    case QUERY_NODE_VALUE: {
      SValueNode *valueNode = (SValueNode *)pNode;
      return valueNode->node.resType.type;
    }
    case QUERY_NODE_NODE_LIST: {
      SNodeListNode *nodeList = (SNodeListNode *)pNode;
      return nodeList->dataType.type;
    }
    case QUERY_NODE_COLUMN: {
      SColumnNode *colNode = (SColumnNode *)pNode;
      return colNode->node.resType.type;
    }
    case QUERY_NODE_FUNCTION:
    case QUERY_NODE_OPERATOR:
    case QUERY_NODE_LOGIC_CONDITION: {
      SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, &pNode, POINTER_BYTES);
      if (NULL == res) {
        sclError("no result for node, type:%d, node:%p", nodeType(pNode), pNode);
        return -1;
      }
      return res->columnData->info.type;
    }
  }

  return -1;
}

void sclSetOperatorValueType(SOperatorNode *node, SScalarCtx *ctx) {
  ctx->type.opResType = node->node.resType.type;
  ctx->type.selfType = sclGetNodeType(node->pLeft, ctx);
  ctx->type.peerType = sclGetNodeType(node->pRight, ctx);
}

D
dapan1121 已提交
540 541
int32_t sclInitOperatorParams(SScalarParam **pParams, SOperatorNode *node, SScalarCtx *ctx, int32_t *rowNum) {
  int32_t code = 0;
D
dapan1121 已提交
542
  int32_t paramNum = scalarGetOperatorParamNum(node->opType);
D
dapan1121 已提交
543 544 545 546
  if (NULL == node->pLeft || (paramNum == 2 && NULL == node->pRight)) {
    sclError("invalid operation node, left:%p, right:%p", node->pLeft, node->pRight);
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }
G
Ganlin Zhao 已提交
547

wafwerar's avatar
wafwerar 已提交
548
  SScalarParam *paramList = taosMemoryCalloc(paramNum, sizeof(SScalarParam));
D
dapan1121 已提交
549 550
  if (NULL == paramList) {
    sclError("calloc %d failed", (int32_t)(paramNum * sizeof(SScalarParam)));
D
dapan1121 已提交
551 552 553
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }

D
dapan1121 已提交
554 555
  sclSetOperatorValueType(node, ctx);

D
dapan1121 已提交
556
  SCL_ERR_JRET(sclInitParam(node->pLeft, &paramList[0], ctx, rowNum));
D
dapan1121 已提交
557
  if (paramNum > 1) {
D
dapan1121 已提交
558
    TSWAP(ctx->type.selfType, ctx->type.peerType);
D
dapan1121 已提交
559
    SCL_ERR_JRET(sclInitParam(node->pRight, &paramList[1], ctx, rowNum));
D
dapan1121 已提交
560 561
  }

D
dapan1121 已提交
562
  *pParams = paramList;
D
dapan1121 已提交
563
  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
564 565

_return:
wafwerar's avatar
wafwerar 已提交
566
  taosMemoryFreeClear(paramList);
D
dapan1121 已提交
567
  SCL_RET(code);
D
dapan1121 已提交
568 569
}

X
Xiaoyu Wang 已提交
570
int32_t sclGetNodeRes(SNode *node, SScalarCtx *ctx, SScalarParam **res) {
D
dapan1121 已提交
571 572 573 574 575 576 577 578 579
  if (NULL == node) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t rowNum = 0;
  *res = taosMemoryCalloc(1, sizeof(**res));
  if (NULL == *res) {
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
  }
X
Xiaoyu Wang 已提交
580

D
dapan1121 已提交
581 582 583 584 585
  SCL_ERR_RET(sclInitParam(node, *res, ctx, &rowNum));

  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
586 587 588 589 590 591 592 593 594 595 596 597
int32_t sclWalkCaseWhenList(SScalarCtx *ctx, SNodeList *pList, struct SListCell *pCell, SScalarParam *pCase,
                            SScalarParam *pElse, SScalarParam *pComp, SScalarParam *output, int32_t rowIdx,
                            int32_t totalRows, bool *complete) {
  SNode         *node = NULL;
  SWhenThenNode *pWhenThen = NULL;
  SScalarParam  *pWhen = NULL;
  SScalarParam  *pThen = NULL;
  int32_t        code = 0;

  for (SListCell *cell = pCell; (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false));
       cell = cell->pNext) {
    pWhenThen = (SWhenThenNode *)node;
D
dapan1121 已提交
598 599 600

    SCL_ERR_RET(sclGetNodeRes(pWhenThen->pWhen, ctx, &pWhen));
    SCL_ERR_RET(sclGetNodeRes(pWhenThen->pThen, ctx, &pThen));
X
Xiaoyu Wang 已提交
601

D
dapan1121 已提交
602
    vectorCompareImpl(pCase, pWhen, pComp, rowIdx, 1, TSDB_ORDER_ASC, OP_TYPE_EQUAL);
X
Xiaoyu Wang 已提交
603 604

    bool *equal = (bool *)colDataGetData(pComp->columnData, rowIdx);
D
dapan1121 已提交
605
    if (*equal) {
dengyihao's avatar
dengyihao 已提交
606
      bool  isNull = colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0));
D
dapan1121 已提交
607 608
      char *pData = isNull ? NULL : colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0));
      colDataAppend(output->columnData, rowIdx, pData, isNull);
D
dapan1121 已提交
609 610 611 612 613

      if (0 == rowIdx && 1 == pCase->numOfRows && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && totalRows > 1) {
        SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
        *complete = true;
      }
X
Xiaoyu Wang 已提交
614

D
dapan1121 已提交
615
      goto _return;
D
dapan1121 已提交
616 617 618 619
    }
  }

  if (pElse) {
dengyihao's avatar
dengyihao 已提交
620
    bool  isNull = colDataIsNull_s(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0));
D
dapan1121 已提交
621 622
    char *pData = isNull ? NULL : colDataGetData(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0));
    colDataAppend(output->columnData, rowIdx, pData, isNull);
D
dapan1121 已提交
623 624 625 626 627

    if (0 == rowIdx && 1 == pCase->numOfRows && 1 == pElse->numOfRows && totalRows > 1) {
      SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
      *complete = true;
    }
X
Xiaoyu Wang 已提交
628

D
dapan1121 已提交
629
    goto _return;
D
dapan1121 已提交
630 631 632 633
  }

  colDataAppend(output->columnData, rowIdx, NULL, true);

D
dapan1121 已提交
634
  if (0 == rowIdx && 1 == pCase->numOfRows && totalRows > 1) {
D
dapan1121 已提交
635 636 637 638 639
    SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
    *complete = true;
  }

_return:
X
Xiaoyu Wang 已提交
640

D
dapan1121 已提交
641 642
  sclFreeParam(pWhen);
  sclFreeParam(pThen);
D
dapan1121 已提交
643 644
  taosMemoryFree(pWhen);
  taosMemoryFree(pThen);
D
dapan1121 已提交
645 646

  SCL_RET(code);
D
dapan1121 已提交
647 648
}

X
Xiaoyu Wang 已提交
649 650 651 652 653 654 655
int32_t sclWalkWhenList(SScalarCtx *ctx, SNodeList *pList, struct SListCell *pCell, SScalarParam *pElse,
                        SScalarParam *output, int32_t rowIdx, int32_t totalRows, bool *complete, bool preSingle) {
  SNode         *node = NULL;
  SWhenThenNode *pWhenThen = NULL;
  SScalarParam  *pWhen = NULL;
  SScalarParam  *pThen = NULL;
  int32_t        code = 0;
D
dapan1121 已提交
656

X
Xiaoyu Wang 已提交
657 658 659
  for (SListCell *cell = pCell; (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false));
       cell = cell->pNext) {
    pWhenThen = (SWhenThenNode *)node;
D
dapan1121 已提交
660 661
    pWhen = NULL;
    pThen = NULL;
X
Xiaoyu Wang 已提交
662

D
dapan1121 已提交
663 664 665
    SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pWhen, ctx, &pWhen));
    SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pThen, ctx, &pThen));

X
Xiaoyu Wang 已提交
666 667
    bool *whenValue = (bool *)colDataGetData(pWhen->columnData, (pWhen->numOfRows > 1 ? rowIdx : 0));

D
dapan1121 已提交
668
    if (*whenValue) {
dengyihao's avatar
dengyihao 已提交
669
      bool  isNull = colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0));
D
dapan1121 已提交
670 671
      char *pData = isNull ? NULL : colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0));
      colDataAppend(output->columnData, rowIdx, pData, isNull);
D
dapan1121 已提交
672

D
dapan1121 已提交
673
      if (preSingle && 0 == rowIdx && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && totalRows > 1) {
D
dapan1121 已提交
674
        SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
D
dapan1121 已提交
675
        *complete = true;
D
dapan1121 已提交
676
      }
X
Xiaoyu Wang 已提交
677

D
dapan1121 已提交
678 679 680 681 682
      goto _return;
    }

    sclFreeParam(pWhen);
    sclFreeParam(pThen);
D
dapan1121 已提交
683 684
    taosMemoryFreeClear(pWhen);
    taosMemoryFreeClear(pThen);
D
dapan1121 已提交
685 686 687
  }

  if (pElse) {
dengyihao's avatar
dengyihao 已提交
688
    bool  isNull = colDataIsNull_s(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0));
D
dapan1121 已提交
689 690
    char *pData = isNull ? NULL : colDataGetData(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0));
    colDataAppend(output->columnData, rowIdx, pData, isNull);
D
dapan1121 已提交
691

D
dapan1121 已提交
692
    if (preSingle && 0 == rowIdx && 1 == pElse->numOfRows && totalRows > 1) {
D
dapan1121 已提交
693
      SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
D
dapan1121 已提交
694
      *complete = true;
D
dapan1121 已提交
695
    }
X
Xiaoyu Wang 已提交
696

D
dapan1121 已提交
697 698 699 700 701
    goto _return;
  }

  colDataAppend(output->columnData, rowIdx, NULL, true);

D
dapan1121 已提交
702
  if (preSingle && 0 == rowIdx && totalRows > 1) {
D
dapan1121 已提交
703
    SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
D
dapan1121 已提交
704
    *complete = true;
D
dapan1121 已提交
705 706
  }

D
dapan1121 已提交
707 708 709 710
_return:

  sclFreeParam(pWhen);
  sclFreeParam(pThen);
D
dapan1121 已提交
711 712
  taosMemoryFree(pWhen);
  taosMemoryFree(pThen);
D
dapan1121 已提交
713

D
dapan1121 已提交
714
  SCL_RET(code);
D
dapan1121 已提交
715 716
}

717
int32_t sclExecFunction(SFunctionNode *node, SScalarCtx *ctx, SScalarParam *output) {
D
dapan1121 已提交
718
  SScalarParam *params = NULL;
H
Hongze Cheng 已提交
719 720 721
  int32_t       rowNum = 0;
  int32_t       paramNum = 0;
  int32_t       code = 0;
D
dapan 已提交
722
  SCL_ERR_RET(sclInitParamList(&params, node->pParameterList, ctx, &paramNum, &rowNum));
D
dapan1121 已提交
723

D
dapan1121 已提交
724
  if (fmIsUserDefinedFunc(node->funcId)) {
725
    code = callUdfScalarFunc(node->functionName, params, paramNum, output);
726 727 728 729
    if (code != 0) {
      sclError("fmExecFunction error. callUdfScalarFunc. function name: %s, udf code:%d", node->functionName, code);
      goto _return;
    }
D
dapan1121 已提交
730 731 732 733 734 735 736
  } else {
    SScalarFuncExecFuncs ffpSet = {0};
    code = fmGetScalarFuncExecFuncs(node->funcId, &ffpSet);
    if (code) {
      sclError("fmGetFuncExecFuncs failed, funcId:%d, code:%s", node->funcId, tstrerror(code));
      SCL_ERR_JRET(code);
    }
G
Ganlin Zhao 已提交
737

H
Haojun Liao 已提交
738 739 740
    code = sclCreateColumnInfoData(&node->node.resType, rowNum, output);
    if (code != TSDB_CODE_SUCCESS) {
      SCL_ERR_JRET(code);
D
dapan1121 已提交
741 742 743 744 745 746 747
    }

    code = (*ffpSet.process)(params, paramNum, output);
    if (code) {
      sclError("scalar function exec failed, funcId:%d, code:%s", node->funcId, tstrerror(code));
      SCL_ERR_JRET(code);
    }
D
dapan1121 已提交
748 749 750 751
  }

_return:

D
dapan1121 已提交
752
  sclFreeParamList(params, paramNum);
D
dapan1121 已提交
753 754 755 756 757
  SCL_RET(code);
}

int32_t sclExecLogic(SLogicConditionNode *node, SScalarCtx *ctx, SScalarParam *output) {
  if (NULL == node->pParameterList || node->pParameterList->length <= 0) {
H
Hongze Cheng 已提交
758 759
    sclError("invalid logic parameter list, list:%p, paramNum:%d", node->pParameterList,
             node->pParameterList ? node->pParameterList->length : 0);
D
dapan1121 已提交
760 761 762 763 764 765
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

  if (TSDB_DATA_TYPE_BOOL != node->node.resType.type) {
    sclError("invalid logic resType, type:%d", node->node.resType.type);
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
D
dapan1121 已提交
766 767
  }

D
dapan1121 已提交
768 769 770 771 772 773
  if (LOGIC_COND_TYPE_NOT == node->condType && node->pParameterList->length > 1) {
    sclError("invalid NOT operation parameter number, paramNum:%d", node->pParameterList->length);
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

  SScalarParam *params = NULL;
H
Hongze Cheng 已提交
774 775 776
  int32_t       rowNum = 0;
  int32_t       paramNum = 0;
  int32_t       code = 0;
D
dapan 已提交
777
  SCL_ERR_RET(sclInitParamList(&params, node->pParameterList, ctx, &paramNum, &rowNum));
D
dapan1121 已提交
778 779 780 781
  if (NULL == params) {
    output->numOfRows = 0;
    return TSDB_CODE_SUCCESS;
  }
D
dapan1121 已提交
782

783 784 785 786
  int32_t type = node->node.resType.type;
  output->numOfRows = rowNum;

  SDataType t = {.type = type, .bytes = tDataTypes[type].bytes};
H
Haojun Liao 已提交
787 788 789
  code = sclCreateColumnInfoData(&t, rowNum, output);
  if (code != TSDB_CODE_SUCCESS) {
    SCL_ERR_JRET(code);
D
dapan1121 已提交
790
  }
D
dapan1121 已提交
791

792 793
  int32_t numOfQualified = 0;

D
dapan1121 已提交
794
  bool value = false;
D
dapan 已提交
795
  bool complete = true;
D
dapan1121 已提交
796
  for (int32_t i = 0; i < rowNum; ++i) {
D
dapan 已提交
797 798
    complete = true;
    for (int32_t m = 0; m < paramNum; ++m) {
D
dapan1121 已提交
799
      if (NULL == params[m].columnData) {
D
dapan 已提交
800
        complete = false;
D
dapan1121 已提交
801 802
        continue;
      }
H
Hongze Cheng 已提交
803
      char *p = colDataGetData(params[m].columnData, i);
804 805
      GET_TYPED_DATA(value, bool, params[m].columnData->info.type, p);

D
dapan1121 已提交
806
      if (LOGIC_COND_TYPE_AND == node->condType && (false == value)) {
D
dapan1121 已提交
807
        complete = true;
D
dapan1121 已提交
808 809
        break;
      } else if (LOGIC_COND_TYPE_OR == node->condType && value) {
D
dapan1121 已提交
810
        complete = true;
D
dapan1121 已提交
811 812 813 814 815 816
        break;
      } else if (LOGIC_COND_TYPE_NOT == node->condType) {
        value = !value;
      }
    }

D
dapan 已提交
817
    if (complete) {
H
Hongze Cheng 已提交
818
      colDataAppend(output->columnData, i, (char *)&value, false);
819 820 821
      if (value) {
        numOfQualified++;
      }
D
dapan 已提交
822
    }
D
dapan1121 已提交
823 824
  }

D
dapan1121 已提交
825 826 827 828 829
  if (SCL_IS_CONST_CALC(ctx) && (false == complete)) {
    sclFreeParam(output);
    output->numOfRows = 0;
  }

830
  output->numOfQualified = numOfQualified;
D
dapan1121 已提交
831

832
_return:
D
dapan1121 已提交
833
  sclFreeParamList(params, paramNum);
D
dapan1121 已提交
834
  SCL_RET(code);
D
dapan1121 已提交
835 836 837 838
}

int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *output) {
  SScalarParam *params = NULL;
H
Hongze Cheng 已提交
839 840
  int32_t       rowNum = 0;
  int32_t       code = 0;
841

wmmhello's avatar
wmmhello 已提交
842
  // json not support in in operator
H
Haojun Liao 已提交
843
  if (nodeType(node->pLeft) == QUERY_NODE_VALUE) {
wmmhello's avatar
wmmhello 已提交
844
    SValueNode *valueNode = (SValueNode *)node->pLeft;
H
Hongze Cheng 已提交
845 846
    if (valueNode->node.resType.type == TSDB_DATA_TYPE_JSON &&
        (node->opType == OP_TYPE_IN || node->opType == OP_TYPE_NOT_IN)) {
wmmhello's avatar
wmmhello 已提交
847 848 849 850
      SCL_RET(TSDB_CODE_QRY_JSON_IN_ERROR);
    }
  }

D
dapan1121 已提交
851
  SCL_ERR_RET(sclInitOperatorParams(&params, node, ctx, &rowNum));
852
  if (output->columnData == NULL) {
H
Haojun Liao 已提交
853 854 855 856
    code = sclCreateColumnInfoData(&node->node.resType, rowNum, output);
    if (code != TSDB_CODE_SUCCESS) {
      SCL_ERR_JRET(code);
    }
D
dapan1121 已提交
857 858 859 860
  }

  _bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(node->opType);

H
Hongze Cheng 已提交
861 862 863
  int32_t       paramNum = scalarGetOperatorParamNum(node->opType);
  SScalarParam *pLeft = &params[0];
  SScalarParam *pRight = paramNum > 1 ? &params[1] : NULL;
864

wmmhello's avatar
wmmhello 已提交
865
  terrno = TSDB_CODE_SUCCESS;
D
dapan 已提交
866
  OperatorFn(pLeft, pRight, output, TSDB_ORDER_ASC);
wmmhello's avatar
wmmhello 已提交
867
  code = terrno;
D
dapan1121 已提交
868 869

_return:
D
dapan1121 已提交
870

D
dapan1121 已提交
871
  sclFreeParamList(params, paramNum);
D
dapan1121 已提交
872
  SCL_RET(code);
D
dapan1121 已提交
873 874
}

D
dapan1121 已提交
875
int32_t sclExecCaseWhen(SCaseWhenNode *node, SScalarCtx *ctx, SScalarParam *output) {
X
Xiaoyu Wang 已提交
876
  int32_t       code = 0;
D
dapan1121 已提交
877 878
  SScalarParam *pCase = NULL;
  SScalarParam *pElse = NULL;
D
dapan1121 已提交
879 880
  SScalarParam *pWhen = NULL;
  SScalarParam *pThen = NULL;
D
dapan1121 已提交
881
  SScalarParam  comp = {0};
X
Xiaoyu Wang 已提交
882 883
  int32_t       rowNum = 1;
  bool          complete = false;
D
dapan1121 已提交
884 885 886 887 888 889 890

  if (NULL == node->pWhenThenList || node->pWhenThenList->length <= 0) {
    sclError("invalid whenThen list");
    SCL_ERR_RET(TSDB_CODE_INVALID_PARA);
  }

  if (ctx->pBlockList) {
X
Xiaoyu Wang 已提交
891
    SSDataBlock *pb = taosArrayGetP(ctx->pBlockList, 0);
D
dapan1121 已提交
892
    rowNum = pb->info.rows;
D
dapan1121 已提交
893
    output->numOfRows = pb->info.rows;
D
dapan1121 已提交
894
  }
D
dapan1121 已提交
895 896

  SCL_ERR_JRET(sclCreateColumnInfoData(&node->node.resType, rowNum, output));
X
Xiaoyu Wang 已提交
897

D
dapan1121 已提交
898 899 900 901 902 903
  SCL_ERR_JRET(sclGetNodeRes(node->pCase, ctx, &pCase));
  SCL_ERR_JRET(sclGetNodeRes(node->pElse, ctx, &pElse));

  SDataType compType = {0};
  compType.type = TSDB_DATA_TYPE_BOOL;
  compType.bytes = tDataTypes[compType.type].bytes;
X
Xiaoyu Wang 已提交
904

D
dapan1121 已提交
905
  SCL_ERR_JRET(sclCreateColumnInfoData(&compType, rowNum, &comp));
D
dapan1121 已提交
906

X
Xiaoyu Wang 已提交
907 908
  SNode         *tnode = NULL;
  SWhenThenNode *pWhenThen = (SWhenThenNode *)node->pWhenThenList->pHead->pNode;
D
dapan1121 已提交
909 910 911

  SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pWhen, ctx, &pWhen));
  SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pThen, ctx, &pThen));
D
dapan1121 已提交
912 913 914 915
  if (NULL == pWhen || NULL == pThen) {
    sclError("invalid when/then in whenThen list");
    SCL_ERR_JRET(TSDB_CODE_INVALID_PARA);
  }
D
dapan1121 已提交
916 917

  if (pCase) {
D
dapan1121 已提交
918
    vectorCompare(pCase, pWhen, &comp, TSDB_ORDER_ASC, OP_TYPE_EQUAL);
X
Xiaoyu Wang 已提交
919

D
dapan1121 已提交
920
    for (int32_t i = 0; i < rowNum; ++i) {
X
Xiaoyu Wang 已提交
921
      bool *equal = (bool *)colDataGetData(comp.columnData, (comp.numOfRows > 1 ? i : 0));
D
dapan1121 已提交
922
      if (*equal) {
X
Xiaoyu Wang 已提交
923 924
        colDataAppend(output->columnData, i, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)),
                      colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)));
D
dapan1121 已提交
925
        if (0 == i && 1 == pCase->numOfRows && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && rowNum > 1) {
D
dapan1121 已提交
926 927 928
          SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
          break;
        }
D
dapan1121 已提交
929
      } else {
X
Xiaoyu Wang 已提交
930 931
        SCL_ERR_JRET(sclWalkCaseWhenList(ctx, node->pWhenThenList, node->pWhenThenList->pHead->pNext, pCase, pElse,
                                         &comp, output, i, rowNum, &complete));
D
dapan1121 已提交
932 933 934
        if (complete) {
          break;
        }
D
dapan1121 已提交
935
      }
D
dapan1121 已提交
936
    }
D
dapan1121 已提交
937 938
  } else {
    for (int32_t i = 0; i < rowNum; ++i) {
X
Xiaoyu Wang 已提交
939
      bool *whenValue = (bool *)colDataGetData(pWhen->columnData, (pWhen->numOfRows > 1 ? i : 0));
D
dapan1121 已提交
940
      if (*whenValue) {
X
Xiaoyu Wang 已提交
941 942
        colDataAppend(output->columnData, i, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)),
                      colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)));
D
dapan1121 已提交
943 944 945 946
        if (0 == i && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && rowNum > 1) {
          SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
          break;
        }
D
dapan1121 已提交
947
      } else {
X
Xiaoyu Wang 已提交
948 949
        SCL_ERR_JRET(sclWalkWhenList(ctx, node->pWhenThenList, node->pWhenThenList->pHead->pNext, pElse, output, i,
                                     rowNum, &complete, (pWhen->numOfRows == 1 && pThen->numOfRows == 1)));
D
dapan1121 已提交
950 951 952
        if (complete) {
          break;
        }
D
dapan1121 已提交
953
      }
D
dapan1121 已提交
954 955 956
    }
  }

D
dapan1121 已提交
957 958
  sclFreeParam(pCase);
  sclFreeParam(pElse);
D
dapan1121 已提交
959
  sclFreeParam(&comp);
D
dapan1121 已提交
960 961
  sclFreeParam(pWhen);
  sclFreeParam(pThen);
D
dapan1121 已提交
962 963 964 965
  taosMemoryFree(pCase);
  taosMemoryFree(pElse);
  taosMemoryFree(pWhen);
  taosMemoryFree(pThen);
D
dapan1121 已提交
966

D
dapan1121 已提交
967
  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
968 969 970

_return:

D
dapan1121 已提交
971 972
  sclFreeParam(pCase);
  sclFreeParam(pElse);
D
dapan1121 已提交
973
  sclFreeParam(&comp);
D
dapan1121 已提交
974 975 976
  sclFreeParam(pWhen);
  sclFreeParam(pThen);
  sclFreeParam(output);
D
dapan1121 已提交
977 978 979 980
  taosMemoryFree(pCase);
  taosMemoryFree(pElse);
  taosMemoryFree(pWhen);
  taosMemoryFree(pThen);
D
dapan1121 已提交
981

D
dapan1121 已提交
982 983 984
  SCL_RET(code);
}

H
Hongze Cheng 已提交
985
EDealRes sclRewriteNullInOptr(SNode **pNode, SScalarCtx *ctx, EOperatorType opType) {
D
dapan1121 已提交
986 987 988
  if (opType <= OP_TYPE_CALC_MAX) {
    SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
    if (NULL == res) {
G
Ganlin Zhao 已提交
989
      sclError("make value node failed");
D
dapan1121 已提交
990 991 992
      ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
      return DEAL_RES_ERROR;
    }
G
Ganlin Zhao 已提交
993

D
dapan1121 已提交
994
    res->node.resType.type = TSDB_DATA_TYPE_NULL;
G
Ganlin Zhao 已提交
995

D
dapan1121 已提交
996
    nodesDestroyNode(*pNode);
H
Hongze Cheng 已提交
997
    *pNode = (SNode *)res;
D
dapan1121 已提交
998 999 1000
  } else {
    SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
    if (NULL == res) {
G
Ganlin Zhao 已提交
1001
      sclError("make value node failed");
D
dapan1121 已提交
1002 1003 1004
      ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
      return DEAL_RES_ERROR;
    }
G
Ganlin Zhao 已提交
1005

D
dapan1121 已提交
1006
    res->node.resType.type = TSDB_DATA_TYPE_BOOL;
D
dapan1121 已提交
1007
    res->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
D
dapan1121 已提交
1008
    res->datum.b = false;
G
Ganlin Zhao 已提交
1009

D
dapan1121 已提交
1010
    nodesDestroyNode(*pNode);
H
Hongze Cheng 已提交
1011
    *pNode = (SNode *)res;
D
dapan1121 已提交
1012 1013 1014 1015 1016
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1017
EDealRes sclAggFuncWalker(SNode *pNode, void *pContext) {
D
dapan1121 已提交
1018
  if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
H
Hongze Cheng 已提交
1019 1020 1021
    SFunctionNode *pFunc = (SFunctionNode *)pNode;
    *(bool *)pContext = fmIsAggFunc(pFunc->funcId);
    if (*(bool *)pContext) {
D
dapan1121 已提交
1022 1023 1024 1025 1026 1027 1028
      return DEAL_RES_END;
    }
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1029
bool sclContainsAggFuncNode(SNode *pNode) {
D
dapan1121 已提交
1030 1031 1032 1033
  bool aggFunc = false;
  nodesWalkExpr(pNode, sclAggFuncWalker, (void *)&aggFunc);
  return aggFunc;
}
D
dapan1121 已提交
1034

H
Hongze Cheng 已提交
1035
EDealRes sclRewriteNonConstOperator(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1036
  SOperatorNode *node = (SOperatorNode *)*pNode;
H
Hongze Cheng 已提交
1037
  int32_t        code = 0;
D
dapan1121 已提交
1038 1039 1040

  if (node->pLeft && (QUERY_NODE_VALUE == nodeType(node->pLeft))) {
    SValueNode *valueNode = (SValueNode *)node->pLeft;
H
Hongze Cheng 已提交
1041 1042
    if (SCL_IS_NULL_VALUE_NODE(valueNode) && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL) &&
        (!sclContainsAggFuncNode(node->pRight))) {
D
dapan1121 已提交
1043
      return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1044
    }
D
dapan 已提交
1045

H
Hongze Cheng 已提交
1046 1047 1048
    if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pRight && nodesIsExprNode(node->pRight) &&
        ((SExprNode *)node->pRight)->resType.type == TSDB_DATA_TYPE_TIMESTAMP) {
      code = sclConvertToTsValueNode(((SExprNode *)node->pRight)->resType.precision, valueNode);
D
dapan1121 已提交
1049 1050 1051 1052
      if (code) {
        ctx->code = code;
        return DEAL_RES_ERROR;
      }
D
dapan 已提交
1053
    }
1054 1055 1056

    if (SCL_IS_COMPARISON_OPERATOR(node->opType) && SCL_DOWNGRADE_DATETYPE(valueNode->node.resType.type)) {
      sclDowngradeValueType(valueNode);
H
Hongze Cheng 已提交
1057
    }
D
dapan1121 已提交
1058 1059 1060 1061
  }

  if (node->pRight && (QUERY_NODE_VALUE == nodeType(node->pRight))) {
    SValueNode *valueNode = (SValueNode *)node->pRight;
H
Hongze Cheng 已提交
1062 1063
    if (SCL_IS_NULL_VALUE_NODE(valueNode) && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL) &&
        (!sclContainsAggFuncNode(node->pLeft))) {
D
dapan1121 已提交
1064
      return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1065
    }
D
dapan 已提交
1066

H
Hongze Cheng 已提交
1067 1068 1069
    if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pLeft && nodesIsExprNode(node->pLeft) &&
        ((SExprNode *)node->pLeft)->resType.type == TSDB_DATA_TYPE_TIMESTAMP) {
      code = sclConvertToTsValueNode(((SExprNode *)node->pLeft)->resType.precision, valueNode);
D
dapan1121 已提交
1070 1071 1072 1073
      if (code) {
        ctx->code = code;
        return DEAL_RES_ERROR;
      }
D
dapan 已提交
1074
    }
1075 1076 1077

    if (SCL_IS_COMPARISON_OPERATOR(node->opType) && SCL_DOWNGRADE_DATETYPE(valueNode->node.resType.type)) {
      sclDowngradeValueType(valueNode);
H
Hongze Cheng 已提交
1078
    }
D
dapan1121 已提交
1079 1080 1081 1082
  }

  if (node->pRight && (QUERY_NODE_NODE_LIST == nodeType(node->pRight))) {
    SNodeListNode *listNode = (SNodeListNode *)node->pRight;
H
Hongze Cheng 已提交
1083
    SNode         *tnode = NULL;
D
dapan1121 已提交
1084 1085 1086 1087 1088
    WHERE_EACH(tnode, listNode->pNodeList) {
      if (SCL_IS_NULL_VALUE_NODE(tnode)) {
        if (node->opType == OP_TYPE_IN) {
          ERASE_NODE(listNode->pNodeList);
          continue;
H
Hongze Cheng 已提交
1089
        } else {  // OP_TYPE_NOT_IN
D
dapan1121 已提交
1090
          return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1091 1092 1093 1094 1095 1096 1097
        }
      }

      WHERE_NEXT;
    }

    if (listNode->pNodeList->length <= 0) {
D
dapan1121 已提交
1098
      return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1099 1100 1101 1102 1103 1104
    }
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1105
EDealRes sclRewriteFunction(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1106
  SFunctionNode *node = (SFunctionNode *)*pNode;
H
Hongze Cheng 已提交
1107
  SNode         *tnode = NULL;
X
Xiaoyu Wang 已提交
1108
  if ((!fmIsScalarFunc(node->funcId) && (!ctx->dual)) || fmIsUserDefinedFunc(node->funcId)) {
G
Ganlin Zhao 已提交
1109 1110
    return DEAL_RES_CONTINUE;
  }
1111

D
dapan1121 已提交
1112 1113 1114 1115 1116 1117
  FOREACH(tnode, node->pParameterList) {
    if (!SCL_IS_CONST_NODE(tnode)) {
      return DEAL_RES_CONTINUE;
    }
  }

D
dapan1121 已提交
1118
  SScalarParam output = {0};
1119

1120
  ctx->code = sclExecFunction(node, ctx, &output);
D
dapan 已提交
1121
  if (ctx->code) {
D
dapan1121 已提交
1122 1123 1124
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1125
  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
D
dapan1121 已提交
1126 1127
  if (NULL == res) {
    sclError("make value node failed");
D
dapan1121 已提交
1128
    sclFreeParam(&output);
D
dapan 已提交
1129
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
D
dapan1121 已提交
1130 1131 1132
    return DEAL_RES_ERROR;
  }

1133 1134
  res->translate = true;

1135 1136 1137 1138
  res->node.resType.type = output.columnData->info.type;
  res->node.resType.bytes = output.columnData->info.bytes;
  res->node.resType.scale = output.columnData->info.scale;
  res->node.resType.precision = output.columnData->info.precision;
1139
  if (colDataIsNull_s(output.columnData, 0)) {
1140
    res->isNull = true;
D
dapan1121 已提交
1141
  } else {
1142
    int32_t type = output.columnData->info.type;
H
Hongze Cheng 已提交
1143
    if (type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
1144 1145 1146 1147
      int32_t len = getJsonValueLen(output.columnData->pData);
      res->datum.p = taosMemoryCalloc(len, 1);
      memcpy(res->datum.p, output.columnData->pData, len);
    } else if (IS_VAR_DATA_TYPE(type)) {
H
Hongze Cheng 已提交
1148
      // res->datum.p = taosMemoryCalloc(res->node.resType.bytes + VARSTR_HEADER_SIZE + 1, 1);
1149
      res->datum.p = taosMemoryCalloc(varDataTLen(output.columnData->pData) + 1, 1);
1150
      res->node.resType.bytes = varDataTLen(output.columnData->pData);
1151
      memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData));
1152
    } else {
D
dapan1121 已提交
1153
      nodesSetValueNodeValue(res, output.columnData->pData);
1154
    }
D
dapan1121 已提交
1155
  }
1156

D
dapan1121 已提交
1157
  nodesDestroyNode(*pNode);
H
Hongze Cheng 已提交
1158
  *pNode = (SNode *)res;
D
dapan1121 已提交
1159

D
dapan1121 已提交
1160
  sclFreeParam(&output);
D
dapan1121 已提交
1161 1162 1163
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1164
EDealRes sclRewriteLogic(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1165 1166
  SLogicConditionNode *node = (SLogicConditionNode *)*pNode;

H
Haojun Liao 已提交
1167
  SScalarParam output = {0};
D
dapan 已提交
1168 1169
  ctx->code = sclExecLogic(node, ctx, &output);
  if (ctx->code) {
D
dapan1121 已提交
1170 1171 1172
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1173 1174 1175 1176
  if (0 == output.numOfRows) {
    return DEAL_RES_CONTINUE;
  }

D
dapan1121 已提交
1177
  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
D
dapan1121 已提交
1178 1179
  if (NULL == res) {
    sclError("make value node failed");
1180
    sclFreeParam(&output);
D
dapan 已提交
1181
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
D
dapan1121 已提交
1182 1183 1184 1185
    return DEAL_RES_ERROR;
  }

  res->node.resType = node->node.resType;
1186
  res->translate = true;
D
dapan1121 已提交
1187

1188 1189 1190 1191
  int32_t type = output.columnData->info.type;
  if (IS_VAR_DATA_TYPE(type)) {
    res->datum.p = output.columnData->pData;
    output.columnData->pData = NULL;
D
dapan1121 已提交
1192
  } else {
D
dapan1121 已提交
1193
    nodesSetValueNodeValue(res, output.columnData->pData);
D
dapan1121 已提交
1194
  }
D
dapan1121 已提交
1195 1196

  nodesDestroyNode(*pNode);
H
Hongze Cheng 已提交
1197
  *pNode = (SNode *)res;
D
dapan1121 已提交
1198

D
dapan1121 已提交
1199
  sclFreeParam(&output);
D
dapan1121 已提交
1200 1201 1202
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1203
EDealRes sclRewriteOperator(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1204
  SOperatorNode *node = (SOperatorNode *)*pNode;
D
dapan1121 已提交
1205

D
dapan1121 已提交
1206
  if ((!SCL_IS_CONST_NODE(node->pLeft)) || (!SCL_IS_CONST_NODE(node->pRight))) {
D
dapan 已提交
1207
    return sclRewriteNonConstOperator(pNode, ctx);
D
dapan1121 已提交
1208 1209
  }

H
Haojun Liao 已提交
1210
  SScalarParam output = {0};
D
dapan 已提交
1211 1212
  ctx->code = sclExecOperator(node, ctx, &output);
  if (ctx->code) {
dengyihao's avatar
dengyihao 已提交
1213
    sclFreeParam(&output);
D
dapan1121 已提交
1214 1215 1216
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1217
  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
D
dapan1121 已提交
1218
  if (NULL == res) {
1219 1220
    sclError("make value node failed");
    sclFreeParam(&output);
D
dapan 已提交
1221
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
D
dapan1121 已提交
1222 1223 1224
    return DEAL_RES_ERROR;
  }

1225
  res->translate = true;
D
dapan1121 已提交
1226

1227
  res->node.resType = node->node.resType;
1228
  if (colDataIsNull_s(output.columnData, 0)) {
1229 1230
    res->isNull = true;
    res->node.resType = node->node.resType;
1231
  } else {
1232 1233 1234 1235 1236
    int32_t type = output.columnData->info.type;
    if (IS_VAR_DATA_TYPE(type)) {  // todo refactor
      res->datum.p = output.columnData->pData;
      output.columnData->pData = NULL;
    } else {
G
Ganlin Zhao 已提交
1237
      nodesSetValueNodeValue(res, output.columnData->pData);
1238
    }
D
dapan1121 已提交
1239
  }
D
dapan1121 已提交
1240 1241

  nodesDestroyNode(*pNode);
H
Hongze Cheng 已提交
1242
  *pNode = (SNode *)res;
D
dapan1121 已提交
1243

H
Haojun Liao 已提交
1244
  sclFreeParam(&output);
D
dapan1121 已提交
1245 1246 1247
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
1248
EDealRes sclRewriteCaseWhen(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1249 1250 1251 1252 1253 1254
  SCaseWhenNode *node = (SCaseWhenNode *)*pNode;

  if ((!SCL_IS_CONST_NODE(node->pCase)) || (!SCL_IS_CONST_NODE(node->pElse))) {
    return DEAL_RES_CONTINUE;
  }

X
Xiaoyu Wang 已提交
1255
  SNode *tnode = NULL;
D
dapan1121 已提交
1256
  FOREACH(tnode, node->pWhenThenList) {
X
Xiaoyu Wang 已提交
1257
    SWhenThenNode *pWhenThen = (SWhenThenNode *)tnode;
D
dapan1121 已提交
1258
    if (!SCL_IS_CONST_NODE(pWhenThen->pWhen) || !SCL_IS_CONST_NODE(pWhenThen->pThen)) {
D
dapan1121 已提交
1259 1260
      return DEAL_RES_CONTINUE;
    }
X
Xiaoyu Wang 已提交
1261
  }
D
dapan1121 已提交
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293

  SScalarParam output = {0};
  ctx->code = sclExecCaseWhen(node, ctx, &output);
  if (ctx->code) {
    return DEAL_RES_ERROR;
  }

  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
  if (NULL == res) {
    sclError("make value node failed");
    sclFreeParam(&output);
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return DEAL_RES_ERROR;
  }

  res->translate = true;

  res->node.resType = node->node.resType;
  if (colDataIsNull_s(output.columnData, 0)) {
    res->isNull = true;
    res->node.resType = node->node.resType;
  } else {
    int32_t type = output.columnData->info.type;
    if (IS_VAR_DATA_TYPE(type)) {  // todo refactor
      res->datum.p = output.columnData->pData;
      output.columnData->pData = NULL;
    } else {
      nodesSetValueNodeValue(res, output.columnData->pData);
    }
  }

  nodesDestroyNode(*pNode);
X
Xiaoyu Wang 已提交
1294
  *pNode = (SNode *)res;
D
dapan1121 已提交
1295 1296 1297 1298 1299

  sclFreeParam(&output);
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1300
EDealRes sclConstantsRewriter(SNode **pNode, void *pContext) {
D
dapan 已提交
1301 1302
  SScalarCtx *ctx = (SScalarCtx *)pContext;

D
dapan1121 已提交
1303 1304 1305 1306
  if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
    return sclRewriteOperator(pNode, ctx);
  }

D
dapan1121 已提交
1307
  if (QUERY_NODE_FUNCTION == nodeType(*pNode)) {
D
dapan 已提交
1308
    return sclRewriteFunction(pNode, ctx);
D
dapan1121 已提交
1309 1310 1311
  }

  if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) {
D
dapan 已提交
1312
    return sclRewriteLogic(pNode, ctx);
D
dapan1121 已提交
1313 1314
  }

D
dapan1121 已提交
1315
  if (QUERY_NODE_CASE_WHEN == nodeType(*pNode)) {
D
dapan1121 已提交
1316
    return sclRewriteCaseWhen(pNode, ctx);
1317
  }
1318 1319

  return DEAL_RES_CONTINUE;
D
dapan1121 已提交
1320 1321
}

H
Hongze Cheng 已提交
1322
EDealRes sclWalkFunction(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1323
  SFunctionNode *node = (SFunctionNode *)pNode;
H
Hongze Cheng 已提交
1324
  SScalarParam   output = {0};
1325

1326
  ctx->code = sclExecFunction(node, ctx, &output);
D
dapan1121 已提交
1327 1328
  if (ctx->code) {
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1329 1330
  }

D
dapan1121 已提交
1331
  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
D
dapan1121 已提交
1332 1333
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1334 1335
  }

D
dapan1121 已提交
1336 1337 1338
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1339
EDealRes sclWalkLogic(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1340
  SLogicConditionNode *node = (SLogicConditionNode *)pNode;
H
Hongze Cheng 已提交
1341
  SScalarParam         output = {0};
1342

D
dapan1121 已提交
1343 1344 1345
  ctx->code = sclExecLogic(node, ctx, &output);
  if (ctx->code) {
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1346 1347
  }

D
dapan1121 已提交
1348
  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
D
dapan1121 已提交
1349
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
D
dapan1121 已提交
1350
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1351 1352 1353 1354 1355
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1356
EDealRes sclWalkOperator(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1357
  SOperatorNode *node = (SOperatorNode *)pNode;
H
Hongze Cheng 已提交
1358
  SScalarParam   output = {0};
G
Ganlin Zhao 已提交
1359

D
dapan1121 已提交
1360 1361
  ctx->code = sclExecOperator(node, ctx, &output);
  if (ctx->code) {
dengyihao's avatar
dengyihao 已提交
1362
    sclFreeParam(&output);
D
dapan1121 已提交
1363 1364
    return DEAL_RES_ERROR;
  }
D
dapan1121 已提交
1365

D
dapan1121 已提交
1366
  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
D
dapan1121 已提交
1367
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
D
dapan1121 已提交
1368 1369 1370
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1371 1372 1373
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1374
EDealRes sclWalkTarget(SNode *pNode, SScalarCtx *ctx) {
1375 1376 1377
  STargetNode *target = (STargetNode *)pNode;

  if (target->dataBlockId >= taosArrayGetSize(ctx->pBlockList)) {
H
Hongze Cheng 已提交
1378 1379
    sclError("target tupleId is too big, tupleId:%d, dataBlockNum:%d", target->dataBlockId,
             (int32_t)taosArrayGetSize(ctx->pBlockList));
1380 1381 1382 1383 1384
    ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
    return DEAL_RES_ERROR;
  }

  int32_t index = -1;
H
Hongze Cheng 已提交
1385 1386
  for (int32_t i = 0; i < taosArrayGetSize(ctx->pBlockList); ++i) {
    SSDataBlock *pb = taosArrayGetP(ctx->pBlockList, i);
1387 1388 1389 1390 1391 1392 1393
    if (pb->info.blockId == target->dataBlockId) {
      index = i;
      break;
    }
  }

  if (index == -1) {
H
Hongze Cheng 已提交
1394 1395
    sclError("column tupleId is too big, tupleId:%d, dataBlockNum:%d", target->dataBlockId,
             (int32_t)taosArrayGetSize(ctx->pBlockList));
1396 1397 1398 1399 1400 1401 1402
    ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
    return DEAL_RES_ERROR;
  }

  SSDataBlock *block = *(SSDataBlock **)taosArrayGet(ctx->pBlockList, index);

  if (target->slotId >= taosArrayGetSize(block->pDataBlock)) {
H
Hongze Cheng 已提交
1403 1404
    sclError("target slot not exist, dataBlockId:%d, slotId:%d, dataBlockNum:%d", target->dataBlockId, target->slotId,
             (int32_t)taosArrayGetSize(block->pDataBlock));
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
    ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
    return DEAL_RES_ERROR;
  }

  // if block->pDataBlock is not enough, there are problems if target->slotId bigger than the size of block->pDataBlock,
  SColumnInfoData *col = taosArrayGet(block->pDataBlock, target->slotId);

  SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, (void *)&target->pExpr, POINTER_BYTES);
  if (NULL == res) {
    sclError("no valid res in hash, node:%p, type:%d", target->pExpr, nodeType(target->pExpr));
    ctx->code = TSDB_CODE_QRY_APP_ERROR;
    return DEAL_RES_ERROR;
  }

1419
  colDataAssign(col, res->columnData, res->numOfRows, NULL);
1420 1421 1422 1423 1424 1425
  block->info.rows = res->numOfRows;

  sclFreeParam(res);
  taosHashRemove(ctx->pRes, (void *)&target->pExpr, POINTER_BYTES);
  return DEAL_RES_CONTINUE;
}
D
dapan 已提交
1426

X
Xiaoyu Wang 已提交
1427
EDealRes sclWalkCaseWhen(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1428
  SCaseWhenNode *node = (SCaseWhenNode *)pNode;
X
Xiaoyu Wang 已提交
1429
  SScalarParam   output = {0};
D
dapan1121 已提交
1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443

  ctx->code = sclExecCaseWhen(node, ctx, &output);
  if (ctx->code) {
    return DEAL_RES_ERROR;
  }

  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
    ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return DEAL_RES_ERROR;
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1444
EDealRes sclCalcWalker(SNode *pNode, void *pContext) {
X
Xiaoyu Wang 已提交
1445 1446 1447
  if (QUERY_NODE_VALUE == nodeType(pNode) || QUERY_NODE_NODE_LIST == nodeType(pNode) ||
      QUERY_NODE_COLUMN == nodeType(pNode) || QUERY_NODE_LEFT_VALUE == nodeType(pNode) ||
      QUERY_NODE_WHEN_THEN == nodeType(pNode)) {
D
dapan1121 已提交
1448
    return DEAL_RES_CONTINUE;
D
dapan1121 已提交
1449
  }
D
dapan 已提交
1450 1451

  SScalarCtx *ctx = (SScalarCtx *)pContext;
D
dapan1121 已提交
1452 1453 1454 1455
  if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
    return sclWalkOperator(pNode, ctx);
  }

D
dapan1121 已提交
1456
  if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
D
dapan 已提交
1457
    return sclWalkFunction(pNode, ctx);
D
dapan1121 已提交
1458
  }
D
dapan1121 已提交
1459

D
dapan1121 已提交
1460
  if (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode)) {
D
dapan 已提交
1461
    return sclWalkLogic(pNode, ctx);
D
dapan1121 已提交
1462
  }
D
dapan1121 已提交
1463

1464 1465 1466
  if (QUERY_NODE_TARGET == nodeType(pNode)) {
    return sclWalkTarget(pNode, ctx);
  }
D
dapan1121 已提交
1467

D
dapan1121 已提交
1468 1469 1470 1471
  if (QUERY_NODE_CASE_WHEN == nodeType(pNode)) {
    return sclWalkCaseWhen(pNode, ctx);
  }

D
dapan 已提交
1472
  sclError("invalid node type for scalar calculating, type:%d", nodeType(pNode));
D
dapan1121 已提交
1473 1474
  ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
  return DEAL_RES_ERROR;
D
dapan1121 已提交
1475 1476
}

D
dapan1121 已提交
1477
int32_t sclCalcConstants(SNode *pNode, bool dual, SNode **pRes) {
D
dapan1121 已提交
1478 1479 1480 1481
  if (NULL == pNode) {
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

H
Hongze Cheng 已提交
1482
  int32_t    code = 0;
D
dapan 已提交
1483
  SScalarCtx ctx = {0};
D
dapan1121 已提交
1484
  ctx.dual = dual;
1485
  ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
D
dapan 已提交
1486
  if (NULL == ctx.pRes) {
1487
    sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM);
D
dapan 已提交
1488 1489
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }
G
Ganlin Zhao 已提交
1490

X
Xiaoyu Wang 已提交
1491
  nodesRewriteExprPostOrder(&pNode, sclConstantsRewriter, (void *)&ctx);
D
dapan 已提交
1492
  SCL_ERR_JRET(ctx.code);
D
dapan1121 已提交
1493 1494
  *pRes = pNode;

D
dapan 已提交
1495
_return:
1496

D
dapan 已提交
1497 1498
  sclFreeRes(ctx.pRes);
  return code;
D
dapan1121 已提交
1499
}
D
dapan1121 已提交
1500

H
Hongze Cheng 已提交
1501 1502
static int32_t sclGetMinusOperatorResType(SOperatorNode *pOp) {
  if (!IS_MATHABLE_TYPE(((SExprNode *)(pOp->pLeft))->resType.type)) {
1503 1504 1505 1506 1507 1508 1509
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }
  pOp->node.resType.type = TSDB_DATA_TYPE_DOUBLE;
  pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
  return TSDB_CODE_SUCCESS;
}

H
Hongze Cheng 已提交
1510
static int32_t sclGetMathOperatorResType(SOperatorNode *pOp) {
G
Ganlin Zhao 已提交
1511 1512 1513 1514
  if (pOp == NULL || pOp->pLeft == NULL || pOp->pRight == NULL) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

H
Hongze Cheng 已提交
1515 1516
  SDataType ldt = ((SExprNode *)(pOp->pLeft))->resType;
  SDataType rdt = ((SExprNode *)(pOp->pRight))->resType;
G
Ganlin Zhao 已提交
1517

1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
  if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_TIMESTAMP == rdt.type) ||
      (TSDB_DATA_TYPE_TIMESTAMP == ldt.type && (IS_VAR_DATA_TYPE(rdt.type) || IS_FLOAT_TYPE(rdt.type))) ||
      (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && (IS_VAR_DATA_TYPE(ldt.type) || IS_FLOAT_TYPE(ldt.type)))) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

  if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && IS_INTEGER_TYPE(rdt.type)) ||
      (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && IS_INTEGER_TYPE(ldt.type)) ||
      (TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_BOOL == rdt.type) ||
      (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && TSDB_DATA_TYPE_BOOL == ldt.type)) {
    pOp->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
    pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
  } else {
    pOp->node.resType.type = TSDB_DATA_TYPE_DOUBLE;
    pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
  }
  return TSDB_CODE_SUCCESS;
}

H
Hongze Cheng 已提交
1537
static int32_t sclGetCompOperatorResType(SOperatorNode *pOp) {
G
Ganlin Zhao 已提交
1538
  if (pOp == NULL || pOp->pLeft == NULL) {
G
Ganlin Zhao 已提交
1539 1540 1541
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

H
Hongze Cheng 已提交
1542
  SDataType ldt = ((SExprNode *)(pOp->pLeft))->resType;
G
Ganlin Zhao 已提交
1543

1544
  if (OP_TYPE_IN == pOp->opType || OP_TYPE_NOT_IN == pOp->opType) {
G
Ganlin Zhao 已提交
1545 1546 1547
    if (pOp->pRight == NULL) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
    }
H
Hongze Cheng 已提交
1548
    ((SExprNode *)(pOp->pRight))->resType = ldt;
1549
  } else if (nodesIsRegularOp(pOp)) {
G
Ganlin Zhao 已提交
1550 1551 1552
    if (pOp->pRight == NULL) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
    }
H
Hongze Cheng 已提交
1553
    SDataType rdt = ((SExprNode *)(pOp->pRight))->resType;
1554 1555 1556
    if (!IS_VAR_DATA_TYPE(ldt.type) || QUERY_NODE_VALUE != nodeType(pOp->pRight) ||
        (!IS_STR_DATA_TYPE(rdt.type) && (rdt.type != TSDB_DATA_TYPE_NULL))) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
1557 1558 1559 1560 1561 1562 1563
    }
  }
  pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
  pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
  return TSDB_CODE_SUCCESS;
}

H
Hongze Cheng 已提交
1564
static int32_t sclGetJsonOperatorResType(SOperatorNode *pOp) {
G
Ganlin Zhao 已提交
1565 1566 1567 1568
  if (pOp == NULL || pOp->pLeft == NULL || pOp->pRight == NULL) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

H
Hongze Cheng 已提交
1569 1570
  SDataType ldt = ((SExprNode *)(pOp->pLeft))->resType;
  SDataType rdt = ((SExprNode *)(pOp->pRight))->resType;
G
Ganlin Zhao 已提交
1571

1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
  if (TSDB_DATA_TYPE_JSON != ldt.type || !IS_STR_DATA_TYPE(rdt.type)) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }
  if (pOp->opType == OP_TYPE_JSON_GET_VALUE) {
    pOp->node.resType.type = TSDB_DATA_TYPE_JSON;
  } else if (pOp->opType == OP_TYPE_JSON_CONTAINS) {
    pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
  }
  pOp->node.resType.bytes = tDataTypes[pOp->node.resType.type].bytes;
  return TSDB_CODE_SUCCESS;
}

H
Hongze Cheng 已提交
1584
static int32_t sclGetBitwiseOperatorResType(SOperatorNode *pOp) {
1585 1586 1587 1588 1589
  pOp->node.resType.type = TSDB_DATA_TYPE_BIGINT;
  pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
  return TSDB_CODE_SUCCESS;
}

H
Hongze Cheng 已提交
1590
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { return sclCalcConstants(pNode, false, pRes); }
D
dapan1121 已提交
1591

H
Hongze Cheng 已提交
1592
int32_t scalarCalculateConstantsFromDual(SNode *pNode, SNode **pRes) { return sclCalcConstants(pNode, true, pRes); }
D
dapan1121 已提交
1593 1594 1595 1596 1597 1598

int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) {
  if (NULL == pNode || NULL == pBlockList) {
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

H
Hongze Cheng 已提交
1599
  int32_t    code = 0;
D
dapan1121 已提交
1600 1601 1602 1603 1604 1605 1606 1607
  SScalarCtx ctx = {.code = 0, .pBlockList = pBlockList, .param = pDst ? pDst->param : NULL};

  // TODO: OPT performance
  ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
  if (NULL == ctx.pRes) {
    sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM);
    SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
  }
1608

D
dapan1121 已提交
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621
  nodesWalkExprPostOrder(pNode, sclCalcWalker, (void *)&ctx);
  SCL_ERR_JRET(ctx.code);

  if (pDst) {
    SScalarParam *res = (SScalarParam *)taosHashGet(ctx.pRes, (void *)&pNode, POINTER_BYTES);
    if (NULL == res) {
      sclError("no valid res in hash, node:%p, type:%d", pNode, nodeType(pNode));
      SCL_ERR_JRET(TSDB_CODE_QRY_APP_ERROR);
    }

    if (1 == res->numOfRows) {
      SCL_ERR_JRET(sclExtendResRows(pDst, res, pBlockList));
    } else {
H
Haojun Liao 已提交
1622
      colInfoDataEnsureCapacity(pDst->columnData, res->numOfRows, true);
D
dapan1121 已提交
1623 1624
      colDataAssign(pDst->columnData, res->columnData, res->numOfRows, NULL);
      pDst->numOfRows = res->numOfRows;
1625
      pDst->numOfQualified = res->numOfQualified;
D
dapan1121 已提交
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
    }

    sclFreeParam(res);
    taosHashRemove(ctx.pRes, (void *)&pNode, POINTER_BYTES);
  }

_return:
  sclFreeRes(ctx.pRes);
  return code;
}

H
Hongze Cheng 已提交
1637 1638 1639
int32_t scalarGetOperatorResultType(SOperatorNode *pOp) {
  if (TSDB_DATA_TYPE_BLOB == ((SExprNode *)(pOp->pLeft))->resType.type ||
      (NULL != pOp->pRight && TSDB_DATA_TYPE_BLOB == ((SExprNode *)(pOp->pRight))->resType.type)) {
1640 1641 1642 1643 1644
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

  switch (pOp->opType) {
    case OP_TYPE_ADD:
D
dapan1121 已提交
1645 1646 1647 1648
    case OP_TYPE_SUB:
    case OP_TYPE_MULTI:
    case OP_TYPE_DIV:
    case OP_TYPE_REM:
D
dapan1121 已提交
1649
      return sclGetMathOperatorResType(pOp);
D
dapan1121 已提交
1650
    case OP_TYPE_MINUS:
D
dapan1121 已提交
1651
      return sclGetMinusOperatorResType(pOp);
1652
    case OP_TYPE_ASSIGN:
H
Hongze Cheng 已提交
1653
      pOp->node.resType = ((SExprNode *)(pOp->pLeft))->resType;
1654 1655 1656
      break;
    case OP_TYPE_BIT_AND:
    case OP_TYPE_BIT_OR:
D
dapan1121 已提交
1657
      return sclGetBitwiseOperatorResType(pOp);
D
dapan1121 已提交
1658 1659 1660 1661 1662 1663
    case OP_TYPE_GREATER_THAN:
    case OP_TYPE_GREATER_EQUAL:
    case OP_TYPE_LOWER_THAN:
    case OP_TYPE_LOWER_EQUAL:
    case OP_TYPE_EQUAL:
    case OP_TYPE_NOT_EQUAL:
1664 1665 1666 1667 1668 1669 1670 1671
    case OP_TYPE_IS_NULL:
    case OP_TYPE_IS_NOT_NULL:
    case OP_TYPE_IS_TRUE:
    case OP_TYPE_IS_FALSE:
    case OP_TYPE_IS_UNKNOWN:
    case OP_TYPE_IS_NOT_TRUE:
    case OP_TYPE_IS_NOT_FALSE:
    case OP_TYPE_IS_NOT_UNKNOWN:
D
dapan1121 已提交
1672 1673 1674 1675
    case OP_TYPE_LIKE:
    case OP_TYPE_NOT_LIKE:
    case OP_TYPE_MATCH:
    case OP_TYPE_NMATCH:
1676 1677
    case OP_TYPE_IN:
    case OP_TYPE_NOT_IN:
D
dapan1121 已提交
1678
      return sclGetCompOperatorResType(pOp);
D
dapan1121 已提交
1679
    case OP_TYPE_JSON_GET_VALUE:
1680
    case OP_TYPE_JSON_CONTAINS:
D
dapan1121 已提交
1681
      return sclGetJsonOperatorResType(pOp);
D
dapan1121 已提交
1682
    default:
1683
      break;
D
dapan1121 已提交
1684 1685
  }

1686 1687
  return TSDB_CODE_SUCCESS;
}