scalar.c 52.8 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
  colDataSetVal(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
  SScalarParam *pLeft = taosMemoryCalloc(1, sizeof(SScalarParam));
  if (NULL == pLeft) {
    sclError("calloc %d failed", (int32_t)sizeof(SScalarParam));
S
Shengliang Guan 已提交
86
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan1121 已提交
87 88 89 90 91
  }

  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
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);
S
Shengliang Guan 已提交
107
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan1121 已提交
108 109
  }

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");
S
Shengliang Guan 已提交
165
      SCL_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan1121 已提交
166
    }
D
dapan1121 已提交
167

168
    colInfoDataCleanup(out.columnData, out.numOfRows);
D
dapan1121 已提交
169
    cell = cell->pNext;
D
dapan1121 已提交
170 171 172
  }

  *data = pObj;
D
dapan1121 已提交
173 174 175

  colDataDestroy(out.columnData);
  taosMemoryFreeClear(out.columnData);
D
dapan1121 已提交
176 177 178
  return TSDB_CODE_SUCCESS;

_return:
D
dapan1121 已提交
179 180 181

  colDataDestroy(out.columnData);
  taosMemoryFreeClear(out.columnData);
D
dapan1121 已提交
182 183 184 185
  taosHashCleanup(pObj);
  SCL_RET(code);
}

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

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

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

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

  if (param->pHashFilter != NULL) {
    taosHashCleanup(param->pHashFilter);
D
dapan1121 已提交
212
    param->pHashFilter = NULL;
213
  }
D
dapan1121 已提交
214 215
}

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

wafwerar's avatar
wafwerar 已提交
221
  *res = taosMemoryMalloc(pNode->node.resType.bytes);
D
dapan1121 已提交
222 223
  if (NULL == (*res)) {
    sclError("malloc %d failed", pNode->node.resType.bytes);
S
Shengliang Guan 已提交
224
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan1121 已提交
225 226 227 228 229 230
  }

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

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

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

  taosMemoryFree(param);
}

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

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

G
Ganlin Zhao 已提交
330 331 332 333
      if (param->columnData != NULL) {
        sclError("columnData should be NULL");
        SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
      }
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
        colDataSetNULL(param->columnData, 0);
341
      } else {
342
        colDataSetVal(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
      int32_t type = vectorGetConvertType(ctx->type.selfType, ctx->type.peerType);
      if (type == 0) {
355
        type = nodeList->node.resType.type;
D
dapan1121 已提交
356
      }
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
        sclError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
S
Shengliang Guan 已提交
365
        return TSDB_CODE_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);
S
Shengliang Guan 已提交
373
        SCL_ERR_RET(TSDB_CODE_APP_ERROR);
D
dapan1121 已提交
374
      }
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);
H
Haojun Liao 已提交
381
        if (pb->info.id.blockId == ref->dataBlockId) {
382 383 384 385 386 387
          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
      SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, &node, POINTER_BYTES);
      if (NULL == res) {
        sclError("no result for node, type:%d, node:%p", nodeType(node), node);
S
Shengliang Guan 已提交
420
        SCL_ERR_RET(TSDB_CODE_APP_ERROR);
D
dapan1121 已提交
421 422
      }
      *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)));
S
Shengliang Guan 已提交
462
    SCL_ERR_RET(TSDB_CODE_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
    case QUERY_NODE_VALUE: {
      SValueNode *valueNode = (SValueNode *)pNode;
      return valueNode->node.resType.type;
    }
    case QUERY_NODE_NODE_LIST: {
      SNodeListNode *nodeList = (SNodeListNode *)pNode;
513
      return nodeList->node.resType.type;
D
dapan1121 已提交
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_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)));
S
Shengliang Guan 已提交
551
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan1121 已提交
552 553
  }

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
      char *pData = isNull ? NULL : colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0));
608
      colDataSetVal(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
    char *pData = isNull ? NULL : colDataGetData(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0));
622
    colDataSetVal(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
  colDataSetVal(output->columnData, rowIdx, NULL, true);
D
dapan1121 已提交
633

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
      char *pData = isNull ? NULL : colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0));
671
      colDataSetVal(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
    char *pData = isNull ? NULL : colDataGetData(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0));
690
    colDataSetVal(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
    goto _return;
  }

700
  colDataSetVal(output->columnData, rowIdx, NULL, true);
D
dapan1121 已提交
701

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) {
818
      colDataSetVal(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) {
923
        colDataSetVal(output->columnData, i, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)),
X
Xiaoyu Wang 已提交
924
                      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) {
941
        colDataSetVal(output->columnData, i, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)),
X
Xiaoyu Wang 已提交
942
                      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");
S
Shengliang Guan 已提交
990
      ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
991 992
      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");
S
Shengliang Guan 已提交
1002
      ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1003 1004
      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

1035 1036 1037 1038

int32_t sclConvertOpValueNodeTs(SOperatorNode *node, SScalarCtx *ctx) {
  int32_t code = 0;
  
D
dapan1121 已提交
1039
  if (node->pLeft && SCL_IS_VAR_VALUE_NODE(node->pLeft)) {
1040 1041 1042
    if (node->pRight && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pRight)->resType.type)) {
      SCL_ERR_JRET(sclConvertToTsValueNode(((SExprNode *)node->pRight)->resType.precision, (SValueNode*)node->pLeft));
    }
D
dapan1121 已提交
1043
  } else if (node->pRight && SCL_IS_NOTNULL_CONST_NODE(node->pRight)) {
1044 1045 1046
    if (node->pLeft && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pLeft)->resType.type)) {
      if (SCL_IS_VAR_VALUE_NODE(node->pRight)) {
        SCL_ERR_JRET(sclConvertToTsValueNode(((SExprNode *)node->pLeft)->resType.precision, (SValueNode*)node->pRight));
D
dapan1121 已提交
1047
      } else if (QUERY_NODE_NODE_LIST == node->pRight->type) {
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
        SNode* pNode;
        FOREACH(pNode, ((SNodeListNode*)node->pRight)->pNodeList) {
          if (SCL_IS_VAR_VALUE_NODE(pNode)) {
            SCL_ERR_JRET(sclConvertToTsValueNode(((SExprNode *)node->pLeft)->resType.precision, (SValueNode*)pNode));
          }
        }
      }
    }
  }

  return TSDB_CODE_SUCCESS;

_return:

  ctx->code = code;
  return DEAL_RES_ERROR;
}



int32_t sclConvertCaseWhenValueNodeTs(SCaseWhenNode *node, SScalarCtx *ctx) {
  int32_t code = 0;

  if (NULL == node->pCase) {
    return TSDB_CODE_SUCCESS;
  }
  
  if (SCL_IS_VAR_VALUE_NODE(node->pCase)) {
    SNode* pNode;
    FOREACH(pNode, node->pWhenThenList) {
      SExprNode *pExpr = (SExprNode *)((SWhenThenNode *)pNode)->pWhen;
      if (TSDB_DATA_TYPE_TIMESTAMP == pExpr->resType.type) {
        SCL_ERR_JRET(sclConvertToTsValueNode(pExpr->resType.precision, (SValueNode*)node->pCase));
        break;
      }
    }
  } else if (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pCase)->resType.type) {
    SNode* pNode;
    FOREACH(pNode, node->pWhenThenList) {
      if (SCL_IS_VAR_VALUE_NODE(((SWhenThenNode *)pNode)->pWhen)) {
        SCL_ERR_JRET(sclConvertToTsValueNode(((SExprNode *)node->pCase)->resType.precision, (SValueNode*)((SWhenThenNode *)pNode)->pWhen));
      }
    }
  }

  return TSDB_CODE_SUCCESS;

_return:

  ctx->code = code;
  return DEAL_RES_ERROR;
}

H
Hongze Cheng 已提交
1101
EDealRes sclRewriteNonConstOperator(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1102
  SOperatorNode *node = (SOperatorNode *)*pNode;
H
Hongze Cheng 已提交
1103
  int32_t        code = 0;
D
dapan1121 已提交
1104 1105 1106

  if (node->pLeft && (QUERY_NODE_VALUE == nodeType(node->pLeft))) {
    SValueNode *valueNode = (SValueNode *)node->pLeft;
H
Hongze Cheng 已提交
1107 1108
    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 已提交
1109
      return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1110
    }
D
dapan 已提交
1111

1112 1113
    if (SCL_IS_COMPARISON_OPERATOR(node->opType) && SCL_DOWNGRADE_DATETYPE(valueNode->node.resType.type)) {
      sclDowngradeValueType(valueNode);
H
Hongze Cheng 已提交
1114
    }
D
dapan1121 已提交
1115 1116 1117 1118
  }

  if (node->pRight && (QUERY_NODE_VALUE == nodeType(node->pRight))) {
    SValueNode *valueNode = (SValueNode *)node->pRight;
H
Hongze Cheng 已提交
1119 1120
    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 已提交
1121
      return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1122
    }
D
dapan 已提交
1123

1124 1125
    if (SCL_IS_COMPARISON_OPERATOR(node->opType) && SCL_DOWNGRADE_DATETYPE(valueNode->node.resType.type)) {
      sclDowngradeValueType(valueNode);
H
Hongze Cheng 已提交
1126
    }
D
dapan1121 已提交
1127 1128 1129 1130
  }

  if (node->pRight && (QUERY_NODE_NODE_LIST == nodeType(node->pRight))) {
    SNodeListNode *listNode = (SNodeListNode *)node->pRight;
H
Hongze Cheng 已提交
1131
    SNode         *tnode = NULL;
D
dapan1121 已提交
1132 1133 1134 1135 1136
    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 已提交
1137
        } else {  // OP_TYPE_NOT_IN
D
dapan1121 已提交
1138
          return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1139 1140 1141 1142 1143 1144 1145
        }
      }

      WHERE_NEXT;
    }

    if (listNode->pNodeList->length <= 0) {
D
dapan1121 已提交
1146
      return sclRewriteNullInOptr(pNode, ctx, node->opType);
D
dapan1121 已提交
1147 1148 1149 1150 1151 1152
    }
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1153
EDealRes sclRewriteFunction(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1154
  SFunctionNode *node = (SFunctionNode *)*pNode;
H
Hongze Cheng 已提交
1155
  SNode         *tnode = NULL;
X
Xiaoyu Wang 已提交
1156
  if ((!fmIsScalarFunc(node->funcId) && (!ctx->dual)) || fmIsUserDefinedFunc(node->funcId)) {
G
Ganlin Zhao 已提交
1157 1158
    return DEAL_RES_CONTINUE;
  }
1159

D
dapan1121 已提交
1160 1161 1162 1163 1164 1165
  FOREACH(tnode, node->pParameterList) {
    if (!SCL_IS_CONST_NODE(tnode)) {
      return DEAL_RES_CONTINUE;
    }
  }

D
dapan1121 已提交
1166
  SScalarParam output = {0};
1167

1168
  ctx->code = sclExecFunction(node, ctx, &output);
D
dapan 已提交
1169
  if (ctx->code) {
D
dapan1121 已提交
1170 1171 1172
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1173
  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
D
dapan1121 已提交
1174 1175
  if (NULL == res) {
    sclError("make value node failed");
D
dapan1121 已提交
1176
    sclFreeParam(&output);
S
Shengliang Guan 已提交
1177
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1178 1179 1180
    return DEAL_RES_ERROR;
  }

1181 1182
  res->translate = true;

1183 1184 1185 1186
  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;
1187
  if (colDataIsNull_s(output.columnData, 0)) {
1188
    res->isNull = true;
D
dapan1121 已提交
1189
  } else {
1190
    int32_t type = output.columnData->info.type;
H
Hongze Cheng 已提交
1191
    if (type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
1192 1193 1194 1195
      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 已提交
1196
      // res->datum.p = taosMemoryCalloc(res->node.resType.bytes + VARSTR_HEADER_SIZE + 1, 1);
1197
      res->datum.p = taosMemoryCalloc(varDataTLen(output.columnData->pData) + 1, 1);
1198
      res->node.resType.bytes = varDataTLen(output.columnData->pData);
1199
      memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData));
1200
    } else {
D
dapan1121 已提交
1201
      nodesSetValueNodeValue(res, output.columnData->pData);
1202
    }
D
dapan1121 已提交
1203
  }
1204

D
dapan1121 已提交
1205
  nodesDestroyNode(*pNode);
H
Hongze Cheng 已提交
1206
  *pNode = (SNode *)res;
D
dapan1121 已提交
1207

D
dapan1121 已提交
1208
  sclFreeParam(&output);
D
dapan1121 已提交
1209 1210 1211
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1212
EDealRes sclRewriteLogic(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1213 1214
  SLogicConditionNode *node = (SLogicConditionNode *)*pNode;

H
Haojun Liao 已提交
1215
  SScalarParam output = {0};
D
dapan 已提交
1216 1217
  ctx->code = sclExecLogic(node, ctx, &output);
  if (ctx->code) {
D
dapan1121 已提交
1218 1219 1220
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1221 1222 1223 1224
  if (0 == output.numOfRows) {
    return DEAL_RES_CONTINUE;
  }

D
dapan1121 已提交
1225
  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
D
dapan1121 已提交
1226 1227
  if (NULL == res) {
    sclError("make value node failed");
1228
    sclFreeParam(&output);
S
Shengliang Guan 已提交
1229
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1230 1231 1232 1233
    return DEAL_RES_ERROR;
  }

  res->node.resType = node->node.resType;
1234
  res->translate = true;
D
dapan1121 已提交
1235

1236 1237 1238 1239
  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 已提交
1240
  } else {
D
dapan1121 已提交
1241
    nodesSetValueNodeValue(res, output.columnData->pData);
D
dapan1121 已提交
1242
  }
D
dapan1121 已提交
1243 1244

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

D
dapan1121 已提交
1247
  sclFreeParam(&output);
D
dapan1121 已提交
1248 1249 1250
  return DEAL_RES_CONTINUE;
}

1251

H
Hongze Cheng 已提交
1252
EDealRes sclRewriteOperator(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1253
  SOperatorNode *node = (SOperatorNode *)*pNode;
D
dapan1121 已提交
1254

1255 1256
  SCL_ERR_RET(sclConvertOpValueNodeTs(node, ctx));

D
dapan1121 已提交
1257
  if ((!SCL_IS_CONST_NODE(node->pLeft)) || (!SCL_IS_CONST_NODE(node->pRight))) {
D
dapan 已提交
1258
    return sclRewriteNonConstOperator(pNode, ctx);
D
dapan1121 已提交
1259 1260
  }

H
Haojun Liao 已提交
1261
  SScalarParam output = {0};
D
dapan 已提交
1262 1263
  ctx->code = sclExecOperator(node, ctx, &output);
  if (ctx->code) {
dengyihao's avatar
dengyihao 已提交
1264
    sclFreeParam(&output);
D
dapan1121 已提交
1265 1266 1267
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1268
  SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
D
dapan1121 已提交
1269
  if (NULL == res) {
1270 1271
    sclError("make value node failed");
    sclFreeParam(&output);
S
Shengliang Guan 已提交
1272
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1273 1274 1275
    return DEAL_RES_ERROR;
  }

1276
  res->translate = true;
D
dapan1121 已提交
1277

1278
  res->node.resType = node->node.resType;
1279
  if (colDataIsNull_s(output.columnData, 0)) {
1280 1281
    res->isNull = true;
    res->node.resType = node->node.resType;
1282
  } else {
1283 1284 1285 1286 1287
    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 已提交
1288
      nodesSetValueNodeValue(res, output.columnData->pData);
1289
    }
D
dapan1121 已提交
1290
  }
D
dapan1121 已提交
1291 1292

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

H
Haojun Liao 已提交
1295
  sclFreeParam(&output);
D
dapan1121 已提交
1296 1297 1298
  return DEAL_RES_CONTINUE;
}

X
Xiaoyu Wang 已提交
1299
EDealRes sclRewriteCaseWhen(SNode **pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1300 1301
  SCaseWhenNode *node = (SCaseWhenNode *)*pNode;

1302 1303
  SCL_ERR_RET(sclConvertCaseWhenValueNodeTs(node, ctx));

D
dapan1121 已提交
1304 1305 1306 1307
  if ((!SCL_IS_CONST_NODE(node->pCase)) || (!SCL_IS_CONST_NODE(node->pElse))) {
    return DEAL_RES_CONTINUE;
  }

X
Xiaoyu Wang 已提交
1308
  SNode *tnode = NULL;
D
dapan1121 已提交
1309
  FOREACH(tnode, node->pWhenThenList) {
X
Xiaoyu Wang 已提交
1310
    SWhenThenNode *pWhenThen = (SWhenThenNode *)tnode;
D
dapan1121 已提交
1311
    if (!SCL_IS_CONST_NODE(pWhenThen->pWhen) || !SCL_IS_CONST_NODE(pWhenThen->pThen)) {
D
dapan1121 已提交
1312 1313
      return DEAL_RES_CONTINUE;
    }
X
Xiaoyu Wang 已提交
1314
  }
D
dapan1121 已提交
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325

  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);
S
Shengliang Guan 已提交
1326
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
    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 已提交
1347
  *pNode = (SNode *)res;
D
dapan1121 已提交
1348 1349 1350 1351 1352

  sclFreeParam(&output);
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1353
EDealRes sclConstantsRewriter(SNode **pNode, void *pContext) {
D
dapan 已提交
1354 1355
  SScalarCtx *ctx = (SScalarCtx *)pContext;

D
dapan1121 已提交
1356 1357 1358 1359
  if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
    return sclRewriteOperator(pNode, ctx);
  }

D
dapan1121 已提交
1360
  if (QUERY_NODE_FUNCTION == nodeType(*pNode)) {
D
dapan 已提交
1361
    return sclRewriteFunction(pNode, ctx);
D
dapan1121 已提交
1362 1363 1364
  }

  if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) {
D
dapan 已提交
1365
    return sclRewriteLogic(pNode, ctx);
D
dapan1121 已提交
1366 1367
  }

D
dapan1121 已提交
1368
  if (QUERY_NODE_CASE_WHEN == nodeType(*pNode)) {
D
dapan1121 已提交
1369
    return sclRewriteCaseWhen(pNode, ctx);
1370
  }
1371 1372

  return DEAL_RES_CONTINUE;
D
dapan1121 已提交
1373 1374
}

H
Hongze Cheng 已提交
1375
EDealRes sclWalkFunction(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1376
  SFunctionNode *node = (SFunctionNode *)pNode;
H
Hongze Cheng 已提交
1377
  SScalarParam   output = {0};
1378

1379
  ctx->code = sclExecFunction(node, ctx, &output);
D
dapan1121 已提交
1380 1381
  if (ctx->code) {
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1382 1383
  }

D
dapan1121 已提交
1384
  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
S
Shengliang Guan 已提交
1385
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1386
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1387 1388
  }

D
dapan1121 已提交
1389 1390 1391
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1392
EDealRes sclWalkLogic(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1393
  SLogicConditionNode *node = (SLogicConditionNode *)pNode;
H
Hongze Cheng 已提交
1394
  SScalarParam         output = {0};
1395

D
dapan1121 已提交
1396 1397 1398
  ctx->code = sclExecLogic(node, ctx, &output);
  if (ctx->code) {
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1399 1400
  }

D
dapan1121 已提交
1401
  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
S
Shengliang Guan 已提交
1402
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1403
    return DEAL_RES_ERROR;
D
dapan1121 已提交
1404 1405 1406 1407 1408
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1409
EDealRes sclWalkOperator(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1410
  SOperatorNode *node = (SOperatorNode *)pNode;
H
Hongze Cheng 已提交
1411
  SScalarParam   output = {0};
G
Ganlin Zhao 已提交
1412

D
dapan1121 已提交
1413 1414
  ctx->code = sclExecOperator(node, ctx, &output);
  if (ctx->code) {
dengyihao's avatar
dengyihao 已提交
1415
    sclFreeParam(&output);
D
dapan1121 已提交
1416 1417
    return DEAL_RES_ERROR;
  }
D
dapan1121 已提交
1418

D
dapan1121 已提交
1419
  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
S
Shengliang Guan 已提交
1420
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1421 1422 1423
    return DEAL_RES_ERROR;
  }

D
dapan1121 已提交
1424 1425 1426
  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1427
EDealRes sclWalkTarget(SNode *pNode, SScalarCtx *ctx) {
1428 1429 1430
  STargetNode *target = (STargetNode *)pNode;

  if (target->dataBlockId >= taosArrayGetSize(ctx->pBlockList)) {
H
Hongze Cheng 已提交
1431 1432
    sclError("target tupleId is too big, tupleId:%d, dataBlockNum:%d", target->dataBlockId,
             (int32_t)taosArrayGetSize(ctx->pBlockList));
1433 1434 1435 1436 1437
    ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
    return DEAL_RES_ERROR;
  }

  int32_t index = -1;
H
Hongze Cheng 已提交
1438 1439
  for (int32_t i = 0; i < taosArrayGetSize(ctx->pBlockList); ++i) {
    SSDataBlock *pb = taosArrayGetP(ctx->pBlockList, i);
H
Haojun Liao 已提交
1440
    if (pb->info.id.blockId == target->dataBlockId) {
1441 1442 1443 1444 1445 1446
      index = i;
      break;
    }
  }

  if (index == -1) {
H
Hongze Cheng 已提交
1447 1448
    sclError("column tupleId is too big, tupleId:%d, dataBlockNum:%d", target->dataBlockId,
             (int32_t)taosArrayGetSize(ctx->pBlockList));
1449 1450 1451 1452 1453 1454 1455
    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 已提交
1456 1457
    sclError("target slot not exist, dataBlockId:%d, slotId:%d, dataBlockNum:%d", target->dataBlockId, target->slotId,
             (int32_t)taosArrayGetSize(block->pDataBlock));
1458 1459 1460 1461 1462 1463 1464 1465 1466 1467
    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));
S
Shengliang Guan 已提交
1468
    ctx->code = TSDB_CODE_APP_ERROR;
1469 1470 1471
    return DEAL_RES_ERROR;
  }

1472
  colDataAssign(col, res->columnData, res->numOfRows, NULL);
1473 1474 1475 1476 1477 1478
  block->info.rows = res->numOfRows;

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

X
Xiaoyu Wang 已提交
1480
EDealRes sclWalkCaseWhen(SNode *pNode, SScalarCtx *ctx) {
D
dapan1121 已提交
1481
  SCaseWhenNode *node = (SCaseWhenNode *)pNode;
X
Xiaoyu Wang 已提交
1482
  SScalarParam   output = {0};
D
dapan1121 已提交
1483 1484 1485 1486 1487 1488 1489

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

  if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
S
Shengliang Guan 已提交
1490
    ctx->code = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
1491 1492 1493 1494 1495 1496
    return DEAL_RES_ERROR;
  }

  return DEAL_RES_CONTINUE;
}

H
Hongze Cheng 已提交
1497
EDealRes sclCalcWalker(SNode *pNode, void *pContext) {
X
Xiaoyu Wang 已提交
1498 1499 1500
  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 已提交
1501
    return DEAL_RES_CONTINUE;
D
dapan1121 已提交
1502
  }
D
dapan 已提交
1503 1504

  SScalarCtx *ctx = (SScalarCtx *)pContext;
D
dapan1121 已提交
1505 1506 1507 1508
  if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
    return sclWalkOperator(pNode, ctx);
  }

D
dapan1121 已提交
1509
  if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
D
dapan 已提交
1510
    return sclWalkFunction(pNode, ctx);
D
dapan1121 已提交
1511
  }
D
dapan1121 已提交
1512

D
dapan1121 已提交
1513
  if (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode)) {
D
dapan 已提交
1514
    return sclWalkLogic(pNode, ctx);
D
dapan1121 已提交
1515
  }
D
dapan1121 已提交
1516

1517 1518 1519
  if (QUERY_NODE_TARGET == nodeType(pNode)) {
    return sclWalkTarget(pNode, ctx);
  }
D
dapan1121 已提交
1520

D
dapan1121 已提交
1521 1522 1523 1524
  if (QUERY_NODE_CASE_WHEN == nodeType(pNode)) {
    return sclWalkCaseWhen(pNode, ctx);
  }

D
dapan 已提交
1525
  sclError("invalid node type for scalar calculating, type:%d", nodeType(pNode));
D
dapan1121 已提交
1526 1527
  ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
  return DEAL_RES_ERROR;
D
dapan1121 已提交
1528 1529
}

D
dapan1121 已提交
1530
int32_t sclCalcConstants(SNode *pNode, bool dual, SNode **pRes) {
D
dapan1121 已提交
1531 1532 1533 1534
  if (NULL == pNode) {
    SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
  }

H
Hongze Cheng 已提交
1535
  int32_t    code = 0;
D
dapan 已提交
1536
  SScalarCtx ctx = {0};
D
dapan1121 已提交
1537
  ctx.dual = dual;
1538
  ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
D
dapan 已提交
1539
  if (NULL == ctx.pRes) {
1540
    sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM);
S
Shengliang Guan 已提交
1541
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan 已提交
1542
  }
G
Ganlin Zhao 已提交
1543

X
Xiaoyu Wang 已提交
1544
  nodesRewriteExprPostOrder(&pNode, sclConstantsRewriter, (void *)&ctx);
D
dapan 已提交
1545
  SCL_ERR_JRET(ctx.code);
D
dapan1121 已提交
1546 1547
  *pRes = pNode;

D
dapan 已提交
1548
_return:
1549

D
dapan 已提交
1550 1551
  sclFreeRes(ctx.pRes);
  return code;
D
dapan1121 已提交
1552
}
D
dapan1121 已提交
1553

H
Hongze Cheng 已提交
1554 1555
static int32_t sclGetMinusOperatorResType(SOperatorNode *pOp) {
  if (!IS_MATHABLE_TYPE(((SExprNode *)(pOp->pLeft))->resType.type)) {
1556 1557 1558 1559 1560 1561 1562
    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 已提交
1563
static int32_t sclGetMathOperatorResType(SOperatorNode *pOp) {
G
Ganlin Zhao 已提交
1564 1565 1566 1567
  if (pOp == NULL || pOp->pLeft == NULL || pOp->pRight == NULL) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

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

1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
  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 已提交
1590
static int32_t sclGetCompOperatorResType(SOperatorNode *pOp) {
G
Ganlin Zhao 已提交
1591
  if (pOp == NULL || pOp->pLeft == NULL) {
G
Ganlin Zhao 已提交
1592 1593 1594
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

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

1597
  if (OP_TYPE_IN == pOp->opType || OP_TYPE_NOT_IN == pOp->opType) {
G
Ganlin Zhao 已提交
1598 1599 1600
    if (pOp->pRight == NULL) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
    }
H
Hongze Cheng 已提交
1601
    ((SExprNode *)(pOp->pRight))->resType = ldt;
1602
  } else if (nodesIsRegularOp(pOp)) {
G
Ganlin Zhao 已提交
1603 1604 1605
    if (pOp->pRight == NULL) {
      return TSDB_CODE_TSC_INVALID_OPERATION;
    }
H
Hongze Cheng 已提交
1606
    SDataType rdt = ((SExprNode *)(pOp->pRight))->resType;
1607 1608 1609
    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;
1610 1611 1612 1613 1614 1615 1616
    }
  }
  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 已提交
1617
static int32_t sclGetJsonOperatorResType(SOperatorNode *pOp) {
G
Ganlin Zhao 已提交
1618 1619 1620 1621
  if (pOp == NULL || pOp->pLeft == NULL || pOp->pRight == NULL) {
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

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

1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
  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 已提交
1637
static int32_t sclGetBitwiseOperatorResType(SOperatorNode *pOp) {
1638 1639 1640 1641 1642
  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 已提交
1643
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { return sclCalcConstants(pNode, false, pRes); }
D
dapan1121 已提交
1644

H
Hongze Cheng 已提交
1645
int32_t scalarCalculateConstantsFromDual(SNode *pNode, SNode **pRes) { return sclCalcConstants(pNode, true, pRes); }
D
dapan1121 已提交
1646 1647 1648 1649 1650 1651

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 已提交
1652
  int32_t    code = 0;
D
dapan1121 已提交
1653 1654 1655 1656 1657 1658
  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);
S
Shengliang Guan 已提交
1659
    SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
D
dapan1121 已提交
1660
  }
1661

D
dapan1121 已提交
1662 1663 1664 1665 1666 1667 1668
  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));
S
Shengliang Guan 已提交
1669
      SCL_ERR_JRET(TSDB_CODE_APP_ERROR);
D
dapan1121 已提交
1670 1671 1672 1673 1674
    }

    if (1 == res->numOfRows) {
      SCL_ERR_JRET(sclExtendResRows(pDst, res, pBlockList));
    } else {
H
Haojun Liao 已提交
1675
      colInfoDataEnsureCapacity(pDst->columnData, res->numOfRows, true);
D
dapan1121 已提交
1676 1677
      colDataAssign(pDst->columnData, res->columnData, res->numOfRows, NULL);
      pDst->numOfRows = res->numOfRows;
1678
      pDst->numOfQualified = res->numOfQualified;
D
dapan1121 已提交
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689
    }

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

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

H
Hongze Cheng 已提交
1690 1691 1692
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)) {
1693 1694 1695 1696 1697
    return TSDB_CODE_TSC_INVALID_OPERATION;
  }

  switch (pOp->opType) {
    case OP_TYPE_ADD:
D
dapan1121 已提交
1698 1699 1700 1701
    case OP_TYPE_SUB:
    case OP_TYPE_MULTI:
    case OP_TYPE_DIV:
    case OP_TYPE_REM:
D
dapan1121 已提交
1702
      return sclGetMathOperatorResType(pOp);
D
dapan1121 已提交
1703
    case OP_TYPE_MINUS:
D
dapan1121 已提交
1704
      return sclGetMinusOperatorResType(pOp);
1705
    case OP_TYPE_ASSIGN:
H
Hongze Cheng 已提交
1706
      pOp->node.resType = ((SExprNode *)(pOp->pLeft))->resType;
1707 1708 1709
      break;
    case OP_TYPE_BIT_AND:
    case OP_TYPE_BIT_OR:
D
dapan1121 已提交
1710
      return sclGetBitwiseOperatorResType(pOp);
D
dapan1121 已提交
1711 1712 1713 1714 1715 1716
    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:
1717 1718 1719 1720 1721 1722 1723 1724
    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 已提交
1725 1726 1727 1728
    case OP_TYPE_LIKE:
    case OP_TYPE_NOT_LIKE:
    case OP_TYPE_MATCH:
    case OP_TYPE_NMATCH:
1729 1730
    case OP_TYPE_IN:
    case OP_TYPE_NOT_IN:
D
dapan1121 已提交
1731
      return sclGetCompOperatorResType(pOp);
D
dapan1121 已提交
1732
    case OP_TYPE_JSON_GET_VALUE:
1733
    case OP_TYPE_JSON_CONTAINS:
D
dapan1121 已提交
1734
      return sclGetJsonOperatorResType(pOp);
D
dapan1121 已提交
1735
    default:
1736
      break;
D
dapan1121 已提交
1737 1738
  }

1739 1740
  return TSDB_CODE_SUCCESS;
}