executorimpl.c 264.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
15

H
Haojun Liao 已提交
16 17
#include "filter.h"
#include "function.h"
18 19
#include "functionMgt.h"
#include "os.h"
H
Haojun Liao 已提交
20
#include "querynodes.h"
21
#include "tfill.h"
dengyihao's avatar
dengyihao 已提交
22
#include "tname.h"
23

H
Haojun Liao 已提交
24
#include "tdatablock.h"
25
#include "tglobal.h"
H
Haojun Liao 已提交
26
#include "tmsg.h"
H
Haojun Liao 已提交
27
#include "tsort.h"
28
#include "ttime.h"
H
Haojun Liao 已提交
29

30
#include "executorimpl.h"
31
#include "query.h"
32 33
#include "tcompare.h"
#include "tcompression.h"
H
Haojun Liao 已提交
34
#include "thash.h"
35
#include "ttypes.h"
dengyihao's avatar
dengyihao 已提交
36
#include "vnode.h"
37

H
Haojun Liao 已提交
38
#define IS_MAIN_SCAN(runtime)          ((runtime)->scanFlag == MAIN_SCAN)
39 40
#define IS_REVERSE_SCAN(runtime)       ((runtime)->scanFlag == REVERSE_SCAN)
#define IS_REPEAT_SCAN(runtime)        ((runtime)->scanFlag == REPEAT_SCAN)
L
Liu Jicong 已提交
41
#define SET_MAIN_SCAN_FLAG(runtime)    ((runtime)->scanFlag = MAIN_SCAN)
42 43 44 45
#define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN)

#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))

L
Liu Jicong 已提交
46 47
#define SDATA_BLOCK_INITIALIZER \
  (SDataBlockInfo) { {0}, 0 }
48 49 50 51

#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)

enum {
L
Liu Jicong 已提交
52 53
  TS_JOIN_TS_EQUAL = 0,
  TS_JOIN_TS_NOT_EQUALS = 1,
54 55 56 57 58
  TS_JOIN_TAG_NOT_EQUALS = 2,
};

typedef enum SResultTsInterpType {
  RESULT_ROW_START_INTERP = 1,
L
Liu Jicong 已提交
59
  RESULT_ROW_END_INTERP = 2,
60 61 62 63
} SResultTsInterpType;

#if 0
static UNUSED_FUNC void *u_malloc (size_t __size) {
wafwerar's avatar
wafwerar 已提交
64
  uint32_t v = taosRand();
65 66 67 68

  if (v % 1000 <= 0) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
69
    return taosMemoryMalloc(__size);
70 71 72 73
  }
}

static UNUSED_FUNC void* u_calloc(size_t num, size_t __size) {
wafwerar's avatar
wafwerar 已提交
74
  uint32_t v = taosRand();
75 76 77
  if (v % 1000 <= 0) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
78
    return taosMemoryCalloc(num, __size);
79 80 81 82
  }
}

static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
wafwerar's avatar
wafwerar 已提交
83
  uint32_t v = taosRand();
84 85 86
  if (v % 5 <= 1) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
87
    return taosMemoryRealloc(p, __size);
88 89 90 91 92 93 94 95 96 97 98 99
  }
}

#define calloc  u_calloc
#define malloc  u_malloc
#define realloc u_realloc
#endif

#define CLEAR_QUERY_STATUS(q, st)   ((q)->status &= (~(st)))
#define GET_NUM_OF_TABLEGROUP(q)    taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)

L
Liu Jicong 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
#define TSKEY_MAX_ADD(a, b)                      \
  do {                                           \
    if (a < 0) {                                 \
      a = a + b;                                 \
      break;                                     \
    }                                            \
    if (sizeof(a) == sizeof(int32_t)) {          \
      if ((b) > 0 && ((b) >= INT32_MAX - (a))) { \
        a = INT32_MAX;                           \
      } else {                                   \
        a = a + b;                               \
      }                                          \
    } else {                                     \
      if ((b) > 0 && ((b) >= INT64_MAX - (a))) { \
        a = INT64_MAX;                           \
      } else {                                   \
        a = a + b;                               \
      }                                          \
    }                                            \
  } while (0)

#define TSKEY_MIN_SUB(a, b)                      \
  do {                                           \
    if (a >= 0) {                                \
      a = a + b;                                 \
      break;                                     \
    }                                            \
    if (sizeof(a) == sizeof(int32_t)) {          \
      if ((b) < 0 && ((b) <= INT32_MIN - (a))) { \
        a = INT32_MIN;                           \
      } else {                                   \
        a = a + b;                               \
      }                                          \
    } else {                                     \
      if ((b) < 0 && ((b) <= INT64_MIN - (a))) { \
        a = INT64_MIN;                           \
      } else {                                   \
        a = a + b;                               \
      }                                          \
    }                                            \
  } while (0)

int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; }

static int32_t getExprFunctionId(SExprInfo* pExprInfo) {
145
  assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
146
  return 0;
147 148
}

H
Haojun Liao 已提交
149 150 151 152 153
static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t order, STimeWindow* tw) {
  int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
  if (pInterval->intervalUnit != 'n' && pInterval->intervalUnit != 'y') {
    tw->skey += pInterval->sliding * factor;
    tw->ekey = tw->skey + pInterval->interval - 1;
154 155 156
    return;
  }

H
Haojun Liao 已提交
157
  int64_t key = tw->skey, interval = pInterval->interval;
L
Liu Jicong 已提交
158
  // convert key to second
H
Haojun Liao 已提交
159
  key = convertTimePrecision(key, precision, TSDB_TIME_PRECISION_MILLI) / 1000;
160

H
Haojun Liao 已提交
161
  if (pInterval->intervalUnit == 'y') {
162 163 164 165
    interval *= 12;
  }

  struct tm tm;
L
Liu Jicong 已提交
166
  time_t    t = (time_t)key;
wafwerar's avatar
wafwerar 已提交
167
  taosLocalTime(&t, &tm);
168 169 170 171

  int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
  tm.tm_year = mon / 12;
  tm.tm_mon = mon % 12;
172
  tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, precision);
173 174 175 176

  mon = (int)(mon + interval);
  tm.tm_year = mon / 12;
  tm.tm_mon = mon % 12;
177
  tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, precision);
178 179 180 181 182

  tw->ekey -= 1;
}

static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes);
L
Liu Jicong 已提交
183
static bool functionNeedToExecute(SqlFunctionCtx* pCtx);
184

185
static void setBlockStatisInfo(SqlFunctionCtx* pCtx, SExprInfo* pExpr, SSDataBlock* pSDataBlock);
186

L
Liu Jicong 已提交
187
static void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo);
188 189 190

static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols);

L
Liu Jicong 已提交
191 192 193
static int32_t setTimestampListJoinInfo(STaskRuntimeEnv* pRuntimeEnv, SVariant* pTag, STableQueryInfo* pTableQueryInfo);
static void    releaseQueryBuf(size_t numOfTables);
static int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
194
// static SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win);
195 196
static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo);

H
Haojun Liao 已提交
197
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr);
198 199 200 201 202 203 204 205 206

static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput);
static void destroySFillOperatorInfo(void* param, int32_t numOfOutput);
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput);
static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput);
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput);
static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput);
static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput);
static void destroyAggOperatorInfo(void* param, int32_t numOfOutput);
X
Xiaoyu Wang 已提交
207

H
Haojun Liao 已提交
208
static void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput);
H
Haojun Liao 已提交
209 210
static void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput);

211
static void destroyOperatorInfo(SOperatorInfo* pOperator);
212
static void destroySysTableScannerOperatorInfo(void* param, int32_t numOfOutput);
213

214
void doSetOperatorCompleted(SOperatorInfo* pOperator) {
215
  pOperator->status = OP_EXEC_DONE;
H
Haojun Liao 已提交
216
  if (pOperator->pTaskInfo != NULL) {
217
    setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
218 219
  }
}
220

221 222 223
#define OPTR_IS_OPENED(_optr)  (((_optr)->status & OP_OPENED) == OP_OPENED)
#define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)

H
Haojun Liao 已提交
224
int32_t operatorDummyOpenFn(SOperatorInfo* pOperator) {
225
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
226
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
227 228
}

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t streamFn,
                                    __optr_fn_t cleanup, __optr_close_fn_t closeFn, __optr_encode_fn_t encode,
                                    __optr_decode_fn_t decode, __optr_get_explain_fn_t explain) {
  SOperatorFpSet fpSet = {
      ._openFn = openFn,
      .getNextFn = nextFn,
      .getStreamResFn = streamFn,
      .cleanupFn = cleanup,
      .closeFn = closeFn,
      .encodeResultRow = encode,
      .decodeResultRow = decode,
      .getExplainFn = explain,
  };

  return fpSet;
}

H
Haojun Liao 已提交
246
void operatorDummyCloseFn(void* param, int32_t numOfCols) {}
H
Haojun Liao 已提交
247

dengyihao's avatar
dengyihao 已提交
248 249 250
static int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
                                  SGroupResInfo* pGroupResInfo, int32_t orderType, int32_t* rowCellOffset,
                                  SqlFunctionCtx* pCtx);
H
Haojun Liao 已提交
251

252
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
H
Haojun Liao 已提交
253
static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo);
dengyihao's avatar
dengyihao 已提交
254 255
static void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId,
                                     SExecTaskInfo* pTaskInfo);
256

H
Haojun Liao 已提交
257
SArray* getOrderCheckColumns(STaskAttr* pQuery);
258 259

typedef struct SRowCompSupporter {
L
Liu Jicong 已提交
260 261 262
  STaskRuntimeEnv* pRuntimeEnv;
  int16_t          dataOffset;
  __compar_fn_t    comFunc;
263 264
} SRowCompSupporter;

L
Liu Jicong 已提交
265 266 267
static int compareRowData(const void* a, const void* b, const void* userData) {
  const SResultRow* pRow1 = (const SResultRow*)a;
  const SResultRow* pRow2 = (const SResultRow*)b;
268

L
Liu Jicong 已提交
269 270
  SRowCompSupporter* supporter = (SRowCompSupporter*)userData;
  STaskRuntimeEnv*   pRuntimeEnv = supporter->pRuntimeEnv;
271

L
Liu Jicong 已提交
272 273
  SFilePage* page1 = getBufPage(pRuntimeEnv->pResultBuf, pRow1->pageId);
  SFilePage* page2 = getBufPage(pRuntimeEnv->pResultBuf, pRow2->pageId);
274 275

  int16_t offset = supporter->dataOffset;
L
Liu Jicong 已提交
276 277
  char*   in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
  char*   in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
278 279 280 281

  return (in1 != NULL && in2 != NULL) ? supporter->comFunc(in1, in2) : 0;
}

L
Liu Jicong 已提交
282
// setup the output buffer for each operator
283
SSDataBlock* createResDataBlock(SDataBlockDescNode* pNode) {
H
Haojun Liao 已提交
284
  int32_t numOfCols = LIST_LENGTH(pNode->pSlots);
H
Haojun Liao 已提交
285

wafwerar's avatar
wafwerar 已提交
286
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
H
Haojun Liao 已提交
287 288
  pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));

H
Haojun Liao 已提交
289
  pBlock->info.blockId = pNode->dataBlockId;
dengyihao's avatar
dengyihao 已提交
290
  pBlock->info.rowSize = pNode->totalRowSize;  // todo ??
H
Haojun Liao 已提交
291

L
Liu Jicong 已提交
292
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
293
    SColumnInfoData idata = {{0}};
L
Liu Jicong 已提交
294
    SSlotDescNode*  pDescNode = nodesListGetNode(pNode->pSlots, i);
H
Haojun Liao 已提交
295 296
    if (!pDescNode->output) {
      continue;
H
Haojun Liao 已提交
297
    }
H
Haojun Liao 已提交
298

dengyihao's avatar
dengyihao 已提交
299
    idata.info.type = pDescNode->dataType.type;
L
Liu Jicong 已提交
300 301
    idata.info.bytes = pDescNode->dataType.bytes;
    idata.info.scale = pDescNode->dataType.scale;
H
Haojun Liao 已提交
302
    idata.info.slotId = pDescNode->slotId;
H
Haojun Liao 已提交
303 304
    idata.info.precision = pDescNode->dataType.precision;

H
Hongze Cheng 已提交
305 306 307 308
    if (IS_VAR_DATA_TYPE(idata.info.type)) {
      pBlock->info.hasVarCol = true;
    }

H
Haojun Liao 已提交
309
    taosArrayPush(pBlock->pDataBlock, &idata);
H
Haojun Liao 已提交
310
  }
H
Haojun Liao 已提交
311

312
  pBlock->info.numOfCols = taosArrayGetSize(pBlock->pDataBlock);
H
Haojun Liao 已提交
313
  return pBlock;
H
Haojun Liao 已提交
314 315
}

L
Liu Jicong 已提交
316
static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
dengyihao's avatar
dengyihao 已提交
317 318
  if (TSDB_COL_IS_TAG(pColumn->flag) || TSDB_COL_IS_UD_COL(pColumn->flag) ||
      pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
319 320 321 322 323 324 325 326 327 328
    return false;
  }

  if (pStatis != NULL && pStatis->numOfNull == 0) {
    return false;
  }

  return true;
}

H
Haojun Liao 已提交
329
static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) {
330 331
  int64_t newCapacity = 0;

332 333 334 335 336 337 338 339 340 341 342
  // more than the capacity, reallocate the resources
  if (pResultRowInfo->size < pResultRowInfo->capacity) {
    return;
  }

  if (pResultRowInfo->capacity > 10000) {
    newCapacity = (int64_t)(pResultRowInfo->capacity * 1.25);
  } else {
    newCapacity = (int64_t)(pResultRowInfo->capacity * 1.5);
  }

343
  if (newCapacity <= pResultRowInfo->capacity) {
H
Haojun Liao 已提交
344 345 346
    newCapacity += 4;
  }

347 348 349 350 351 352
  char* p = taosMemoryRealloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition));
  if (p == NULL) {
    longjmp(env, TSDB_CODE_OUT_OF_MEMORY);
  }

  pResultRowInfo->pPosition = (SResultRowPosition*)p;
353 354

  int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity;
wmmhello's avatar
wmmhello 已提交
355
  memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition) * inc);
356 357 358
  pResultRowInfo->capacity = (int32_t)newCapacity;
}

L
Liu Jicong 已提交
359 360
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
                                int16_t bytes, bool masterscan, uint64_t uid) {
361 362 363
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);

L
Liu Jicong 已提交
364 365
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
366 367 368 369 370 371 372 373 374 375 376

  // in case of repeat scan/reverse scan, no new time window added.
  if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQueryAttr)) {
    if (!masterscan) {  // the *p1 may be NULL in case of sliding+offset exists.
      return p1 != NULL;
    }

    if (p1 != NULL) {
      if (pResultRowInfo->size == 0) {
        existed = false;
      } else if (pResultRowInfo->size == 1) {
dengyihao's avatar
dengyihao 已提交
377
        //        existed = (pResultRowInfo->pResult[0] == (*p1));
378 379
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid, pResultRowInfo);
L
Liu Jicong 已提交
380 381
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
382 383 384 385 386 387 388 389 390 391 392 393 394 395
        if (index != NULL) {
          existed = true;
        } else {
          existed = false;
        }
      }
    }

    return existed;
  }

  return p1 != NULL;
}

396
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
L
Liu Jicong 已提交
397
  SFilePage* pData = NULL;
398 399 400 401 402 403 404 405 406 407 408 409 410

  // in the first scan, new space needed for results
  int32_t pageId = -1;
  SIDList list = getDataBufPagesIdList(pResultBuf, tableGroupId);

  if (taosArrayGetSize(list) == 0) {
    pData = getNewBufPage(pResultBuf, tableGroupId, &pageId);
    pData->num = sizeof(SFilePage);
  } else {
    SPageInfo* pi = getLastPageInfo(list);
    pData = getBufPage(pResultBuf, getPageId(pi));
    pageId = getPageId(pi);

wmmhello's avatar
wmmhello 已提交
411
    if (pData->num + interBufSize > getBufPageSize(pResultBuf)) {
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
      // release current page first, and prepare the next one
      releaseBufPageInfo(pResultBuf, pi);

      pData = getNewBufPage(pResultBuf, tableGroupId, &pageId);
      if (pData != NULL) {
        pData->num = sizeof(SFilePage);
      }
    }
  }

  if (pData == NULL) {
    return NULL;
  }

  // set the number of rows in current disk page
  SResultRow* pResultRow = (SResultRow*)((char*)pData + pData->num);
  pResultRow->pageId = pageId;
  pResultRow->offset = (int32_t)pData->num;

wmmhello's avatar
wmmhello 已提交
431
  pData->num += interBufSize;
432 433 434 435

  return pResultRow;
}

436 437 438 439 440 441 442
/**
 * the struct of key in hash table
 * +----------+---------------+
 * | group id |   key data    |
 * | 8 bytes  | actual length |
 * +----------+---------------+
 */
443
static SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, int64_t uid,
444
                                             char* pData, int16_t bytes, bool masterscan, uint64_t groupId,
L
Liu Jicong 已提交
445
                                             SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup) {
446
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
H
Haojun Liao 已提交
447

dengyihao's avatar
dengyihao 已提交
448 449
  SResultRowPosition* p1 =
      (SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
H
Haojun Liao 已提交
450

451 452
  SResultRow* pResult = NULL;

H
Haojun Liao 已提交
453 454
  // in case of repeat scan/reverse scan, no new time window added.
  if (isIntervalQuery) {
455 456
    if (masterscan && p1 != NULL) {  // the *p1 may be NULL in case of sliding+offset exists.
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
457 458
    }
  } else {
dengyihao's avatar
dengyihao 已提交
459 460
    // In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
    // pResultRowInfo object.
H
Haojun Liao 已提交
461
    if (p1 != NULL) {
462
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
463 464 465
    }
  }

H
Haojun Liao 已提交
466
    // 1. close current opened time window
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
  if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
                                            pResult->offset != pResultRowInfo->cur.offset))) {
    // todo extract function
    SResultRowPosition pos = pResultRowInfo->cur;
    SFilePage*         pPage = getBufPage(pResultBuf, pos.pageId);
    SResultRow*        pRow = (SResultRow*)((char*)pPage + pos.offset);
    closeResultRow(pRow);
    releaseBufPage(pResultBuf, pPage);
  }

  // allocate a new buffer page
  prepareResultListBuffer(pResultRowInfo, pTaskInfo->env);
  if (pResult == NULL) {
    pResult = getNewResultRow_rv(pResultBuf, groupId, pSup->resultRowSize);
    initResultRow(pResult);
H
Haojun Liao 已提交
482

483 484 485
    // add a new result set for a new group
    SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
    taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos, sizeof(SResultRowPosition));
H
Haojun Liao 已提交
486 487
  }

488 489 490 491 492
  // 2. set the new time window to be the new active time window
  pResultRowInfo->pPosition[pResultRowInfo->size++] =
      (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
  pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};

H
Haojun Liao 已提交
493 494 495 496 497
  // too many time window in query
  if (pResultRowInfo->size > MAX_INTERVAL_TIME_WINDOW) {
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
  }

H
Haojun Liao 已提交
498
  return pResult;
H
Haojun Liao 已提交
499 500
}

dengyihao's avatar
dengyihao 已提交
501 502
static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, TSKEY ts, STimeWindow* w,
                                      bool ascQuery) {
H
Haojun Liao 已提交
503
  if (ascQuery) {
504
    getAlignQueryTimeWindow(pInterval, precision, ts, w);
505 506
  } else {
    // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
507
    getAlignQueryTimeWindow(pInterval, precision, ts, w);
508 509

    int64_t key = w->skey;
L
Liu Jicong 已提交
510
    while (key < ts) {  // moving towards end
511
      key = taosTimeAdd(key, pInterval->sliding, pInterval->slidingUnit, precision);
512 513 514 515 516 517 518 519 520 521
      if (key >= ts) {
        break;
      }

      w->skey = key;
    }
  }
}

// get the correct time window according to the handled timestamp
dengyihao's avatar
dengyihao 已提交
522 523
static STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int64_t ts,
                                       SInterval* pInterval, int32_t precision, STimeWindow* win) {
524 525
  STimeWindow w = {0};

526
  if (pResultRowInfo->cur.pageId == -1) {  // the first window, from the previous stored value
527
    getInitialStartTimeWindow(pInterval, precision, ts, &w, true);
528
    w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
529
  } else {
530
    w = getResultRowByPos(pBuf, &pResultRowInfo->cur)->win;
531 532 533
  }

  if (w.skey > ts || w.ekey < ts) {
H
Haojun Liao 已提交
534 535 536
    if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
      w.skey = taosTimeTruncate(ts, pInterval, precision);
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
537 538 539 540
    } else {
      int64_t st = w.skey;

      if (st > ts) {
H
Haojun Liao 已提交
541
        st -= ((st - ts + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
542 543
      }

H
Haojun Liao 已提交
544
      int64_t et = st + pInterval->interval - 1;
545
      if (et < ts) {
H
Haojun Liao 已提交
546
        st += ((ts - et + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
547 548 549
      }

      w.skey = st;
550
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
551 552 553 554 555 556
    }
  }
  return w;
}

// get the correct time window according to the handled timestamp
L
Liu Jicong 已提交
557
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo* pResultRowInfo, int64_t ts, STaskAttr* pQueryAttr) {
558
  STimeWindow w = {0};
H
Haojun Liao 已提交
559
#if 0
L
Liu Jicong 已提交
560 561
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
                                       //    getInitialStartTimeWindow(pQueryAttr, ts, &w);
562 563

    if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') {
L
Liu Jicong 已提交
564 565 566
      w.ekey =
          taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) -
          1;
567 568 569 570
    } else {
      w.ekey = w.skey + pQueryAttr->interval.interval - 1;
    }
  } else {
H
Haojun Liao 已提交
571
    w = pRow->win;
572 573 574 575 576 577 578 579 580
  }

  /*
   * query border check, skey should not be bounded by the query time range, since the value skey will
   * be used as the time window index value. So we only change ekey of time window accordingly.
   */
  if (w.ekey > pQueryAttr->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) {
    w.ekey = pQueryAttr->window.ekey;
  }
H
Haojun Liao 已提交
581
#endif
582 583 584 585 586

  return w;
}

// a new buffer page for each table. Needs to opt this design
L
Liu Jicong 已提交
587
static int32_t addNewWindowResultBuf(SResultRow* pWindowRes, SDiskbasedBuf* pResultBuf, int32_t tid, uint32_t size) {
588 589 590 591
  if (pWindowRes->pageId != -1) {
    return 0;
  }

L
Liu Jicong 已提交
592
  SFilePage* pData = NULL;
593 594 595 596 597 598

  // in the first scan, new space needed for results
  int32_t pageId = -1;
  SIDList list = getDataBufPagesIdList(pResultBuf, tid);

  if (taosArrayGetSize(list) == 0) {
H
Haojun Liao 已提交
599
    pData = getNewBufPage(pResultBuf, tid, &pageId);
600
    pData->num = sizeof(SFilePage);
601 602
  } else {
    SPageInfo* pi = getLastPageInfo(list);
603
    pData = getBufPage(pResultBuf, getPageId(pi));
604
    pageId = getPageId(pi);
605

606
    if (pData->num + size > getBufPageSize(pResultBuf)) {
607
      // release current page first, and prepare the next one
608
      releaseBufPageInfo(pResultBuf, pi);
609

H
Haojun Liao 已提交
610
      pData = getNewBufPage(pResultBuf, tid, &pageId);
611
      if (pData != NULL) {
612
        pData->num = sizeof(SFilePage);
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
      }
    }
  }

  if (pData == NULL) {
    return -1;
  }

  // set the number of rows in current disk page
  if (pWindowRes->pageId == -1) {  // not allocated yet, allocate new buffer
    pWindowRes->pageId = pageId;
    pWindowRes->offset = (int32_t)pData->num;

    pData->num += size;
    assert(pWindowRes->pageId >= 0);
  }

  return 0;
}

L
Liu Jicong 已提交
633 634 635
static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, STimeWindow* win,
                                    bool masterscan, SResultRow** pResult, int64_t groupId, SqlFunctionCtx* pCtx,
                                    int32_t numOfOutput, int32_t* rowCellInfoOffset) {
636
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
637
  return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char*)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
638 639
}

dengyihao's avatar
dengyihao 已提交
640 641
static void setResultRowOutputBufInitCtx_rv(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput,
                                            int32_t* rowCellInfoOffset);
H
Haojun Liao 已提交
642

L
Liu Jicong 已提交
643 644 645 646
static int32_t setResultOutputBufByKey_rv(SResultRowInfo* pResultRowInfo, int64_t id, STimeWindow* win, bool masterscan,
                                          SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx,
                                          int32_t numOfOutput, int32_t* rowCellInfoOffset, SAggSupporter* pAggSup,
                                          SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
647
  assert(win->skey <= win->ekey);
648
  SResultRow* pResultRow = doSetResultOutBufByKey(pAggSup->pResultBuf, pResultRowInfo, id, (char*)&win->skey,
L
Liu Jicong 已提交
649
                                                     TSDB_KEYSIZE, masterscan, tableGroupId, pTaskInfo, true, pAggSup);
H
Haojun Liao 已提交
650 651 652 653 654 655 656 657 658

  if (pResultRow == NULL) {
    *pResult = NULL;
    return TSDB_CODE_SUCCESS;
  }

  // set time window for current result
  pResultRow->win = (*win);
  *pResult = pResultRow;
H
Haojun Liao 已提交
659
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
H
Haojun Liao 已提交
660 661 662
  return TSDB_CODE_SUCCESS;
}

663 664 665 666 667
static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
  assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
  if (type == RESULT_ROW_START_INTERP) {
    pResult->startInterp = true;
  } else {
L
Liu Jicong 已提交
668
    pResult->endInterp = true;
669 670 671 672 673 674 675 676
  }
}

static bool resultRowInterpolated(SResultRow* pResult, SResultTsInterpType type) {
  assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
  if (type == RESULT_ROW_START_INTERP) {
    return pResult->startInterp == true;
  } else {
L
Liu Jicong 已提交
677
    return pResult->endInterp == true;
678 679 680
  }
}

L
Liu Jicong 已提交
681 682
static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey,
                                                   int16_t pos, int16_t order, int64_t* pData) {
683 684 685
  int32_t forwardStep = 0;

  if (order == TSDB_ORDER_ASC) {
L
Liu Jicong 已提交
686
    int32_t end = searchFn((char*)&pData[pos], numOfRows - pos, ekey, order);
687 688 689 690 691 692 693 694
    if (end >= 0) {
      forwardStep = end;

      if (pData[end + pos] == ekey) {
        forwardStep += 1;
      }
    }
  } else {
L
Liu Jicong 已提交
695
    int32_t end = searchFn((char*)pData, pos + 1, ekey, order);
696 697 698 699 700 701 702 703 704 705 706 707 708
    if (end >= 0) {
      forwardStep = pos - end;

      if (pData[end] == ekey) {
        forwardStep += 1;
      }
    }
  }

  assert(forwardStep >= 0);
  return forwardStep;
}

dengyihao's avatar
dengyihao 已提交
709 710
static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey, bool ascQuery,
                                   bool timeWindowInterpo) {
711
  int64_t skey = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
712
#if 0
713 714
  int32_t i = 0;
  for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
715
    SResultRow* pResult = pResultRowInfo->pResult[i];
716 717 718 719 720 721
    if (pResult->closed) {
      break;
    }

    // new closed result rows
    if (timeWindowInterpo) {
L
Liu Jicong 已提交
722 723 724
      if (pResult->endInterp &&
          ((pResult->win.skey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery))) {
        if (i > 0) {  // the first time window, the startInterp is false.
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
          assert(pResult->startInterp);
        }

        closeResultRow(pResultRowInfo, i);
      } else {
        skey = pResult->win.skey;
      }
    } else {
      if ((pResult->win.ekey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery)) {
        closeResultRow(pResultRowInfo, i);
      } else {
        skey = pResult->win.skey;
      }
    }
  }

  // all result rows are closed, set the last one to be the skey
  if (skey == TSKEY_INITIAL_VAL) {
    if (pResultRowInfo->size == 0) {
L
Liu Jicong 已提交
744
      //      assert(pResultRowInfo->current == NULL);
745 746 747 748 749 750 751
      assert(pResultRowInfo->curPos == -1);
      pResultRowInfo->curPos = -1;
    } else {
      pResultRowInfo->curPos = pResultRowInfo->size - 1;
    }
  } else {
    for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
752
      SResultRow* pResult = pResultRowInfo->pResult[i];
753 754 755 756 757 758 759 760 761 762 763
      if (pResult->closed) {
        break;
      }
    }

    if (i == pResultRowInfo->size - 1) {
      pResultRowInfo->curPos = i;
    } else {
      pResultRowInfo->curPos = i + 1;  // current not closed result object
    }
  }
H
Haojun Liao 已提交
764
#endif
765
}
766
//
dengyihao's avatar
dengyihao 已提交
767
// static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
768 769 770 771 772 773 774 775 776
//                                           bool ascQuery, bool interp) {
//  if ((lastKey > pWin->ekey && ascQuery) || (lastKey < pWin->ekey && (!ascQuery))) {
//    closeAllResultRows(pResultRowInfo);
//    pResultRowInfo->curPos = pResultRowInfo->size - 1;
//  } else {
//    int32_t step = ascQuery ? 1 : -1;
//    doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, interp);
//  }
//}
777

L
Liu Jicong 已提交
778 779 780
static int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos,
                                        TSKEY ekey, __block_search_fn_t searchFn, STableQueryInfo* item,
                                        int32_t order) {
781 782
  assert(startPos >= 0 && startPos < pDataBlockInfo->rows);

L
Liu Jicong 已提交
783 784
  int32_t num = -1;
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
785

H
Haojun Liao 已提交
786
  if (order == TSDB_ORDER_ASC) {
787 788
    if (ekey < pDataBlockInfo->window.ekey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
789
      if (item != NULL) {
790 791 792 793
        item->lastKey = pPrimaryColumn[startPos + (num - 1)] + step;
      }
    } else {
      num = pDataBlockInfo->rows - startPos;
H
Haojun Liao 已提交
794
      if (item != NULL) {
795 796 797 798 799 800
        item->lastKey = pDataBlockInfo->window.ekey + step;
      }
    }
  } else {  // desc
    if (ekey > pDataBlockInfo->window.skey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
801
      if (item != NULL) {
802 803 804 805
        item->lastKey = pPrimaryColumn[startPos - (num - 1)] + step;
      }
    } else {
      num = startPos + 1;
H
Haojun Liao 已提交
806
      if (item != NULL) {
807 808 809 810 811 812 813 814 815
        item->lastKey = pDataBlockInfo->window.skey + step;
      }
    }
  }

  assert(num >= 0);
  return num;
}

816 817 818 819 820
//  query_range_start, query_range_end, window_duration, window_start, window_end
static void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow) {
  pColData->info.type = TSDB_DATA_TYPE_TIMESTAMP;
  pColData->info.bytes = sizeof(int64_t);

821
  colInfoDataEnsureCapacity(pColData, 0, 5);
822 823 824 825 826 827 828 829 830
  colDataAppendInt64(pColData, 0, &pQueryWindow->skey);
  colDataAppendInt64(pColData, 1, &pQueryWindow->ekey);

  int64_t interval = 0;
  colDataAppendInt64(pColData, 2, &interval);  // this value may be variable in case of 'n' and 'y'.
  colDataAppendInt64(pColData, 3, &pQueryWindow->skey);
  colDataAppendInt64(pColData, 4, &pQueryWindow->ekey);
}

831
static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, bool includeEndpoint) {
832
  int64_t* ts = (int64_t*)pColData->pData;
dengyihao's avatar
dengyihao 已提交
833
  int32_t  delta = includeEndpoint ? 1 : 0;
834

835
  int64_t duration = pWin->ekey - pWin->skey + delta;
dengyihao's avatar
dengyihao 已提交
836 837 838
  ts[2] = duration;            // set the duration
  ts[3] = pWin->skey;          // window start key
  ts[4] = pWin->ekey + delta;  // window end key
839 840
}

dengyihao's avatar
dengyihao 已提交
841 842
void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset,
                      int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
843 844 845
  for (int32_t k = 0; k < numOfOutput; ++k) {
    pCtx[k].startTs = pWin->skey;

H
Haojun Liao 已提交
846
    // keep it temporarily
dengyihao's avatar
dengyihao 已提交
847 848
    bool    hasAgg = pCtx[k].input.colDataAggIsSet;
    int32_t numOfRows = pCtx[k].input.numOfRows;
H
Haojun Liao 已提交
849
    int32_t startOffset = pCtx[k].input.startRowIndex;
850

H
Haojun Liao 已提交
851
    int32_t pos = (order == TSDB_ORDER_ASC) ? offset : offset - (forwardStep - 1);
852 853
    pCtx[k].input.startRowIndex = pos;
    pCtx[k].input.numOfRows = forwardStep;
854 855

    if (tsCol != NULL) {
H
Haojun Liao 已提交
856
      pCtx[k].ptsList = tsCol;
857 858 859 860 861 862 863 864
    }

    // not a whole block involved in query processing, statistics data can not be used
    // NOTE: the original value of isSet have been changed here
    if (pCtx[k].isAggSet && forwardStep < numOfTotal) {
      pCtx[k].isAggSet = false;
    }

865 866
    if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
      SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
dengyihao's avatar
dengyihao 已提交
867
      char*                p = GET_ROWCELL_INTERBUF(pEntryInfo);
868

869
      SColumnInfoData idata = {0};
dengyihao's avatar
dengyihao 已提交
870
      idata.info.type = TSDB_DATA_TYPE_BIGINT;
871
      idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
dengyihao's avatar
dengyihao 已提交
872
      idata.pData = p;
873 874 875 876

      SScalarParam out = {.columnData = &idata};
      SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
      pCtx[k].sfp.process(&tw, 1, &out);
877 878 879 880
      pEntryInfo->numOfRes = 1;
      continue;
    }

H
Haojun Liao 已提交
881
    if (functionNeedToExecute(&pCtx[k])) {
882
      pCtx[k].fpSet.process(&pCtx[k]);
883 884 885
    }

    // restore it
886 887 888
    pCtx[k].input.colDataAggIsSet = hasAgg;
    pCtx[k].input.startRowIndex = startOffset;
    pCtx[k].input.numOfRows = numOfRows;
889 890 891
  }
}

H
Haojun Liao 已提交
892 893 894
static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo,
                                      TSKEY* primaryKeys, int32_t prevPosition, STableIntervalOperatorInfo* pInfo) {
  int32_t order = pInfo->order;
L
Liu Jicong 已提交
895
  bool    ascQuery = (order == TSDB_ORDER_ASC);
H
Haojun Liao 已提交
896

897
  int32_t precision = pInterval->precision;
H
Haojun Liao 已提交
898
  getNextTimeWindow(pInterval, precision, order, pNext);
899 900

  // next time window is not in current block
H
Haojun Liao 已提交
901 902
  if ((pNext->skey > pDataBlockInfo->window.ekey && order == TSDB_ORDER_ASC) ||
      (pNext->ekey < pDataBlockInfo->window.skey && order == TSDB_ORDER_DESC)) {
903 904 905
    return -1;
  }

L
Liu Jicong 已提交
906
  TSKEY   startKey = ascQuery ? pNext->skey : pNext->ekey;
907 908 909
  int32_t startPos = 0;

  // tumbling time window query, a special case of sliding time window query
H
Haojun Liao 已提交
910 911
  if (pInterval->sliding == pInterval->interval && prevPosition != -1) {
    int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
912 913
    startPos = prevPosition + factor;
  } else {
H
Haojun Liao 已提交
914
    if (startKey <= pDataBlockInfo->window.skey && ascQuery) {
915
      startPos = 0;
H
Haojun Liao 已提交
916
    } else if (startKey >= pDataBlockInfo->window.ekey && !ascQuery) {
917 918
      startPos = pDataBlockInfo->rows - 1;
    } else {
L
Liu Jicong 已提交
919
      startPos = binarySearchForKey((char*)primaryKeys, pDataBlockInfo->rows, startKey, order);
920 921 922 923
    }
  }

  /* interp query with fill should not skip time window */
L
Liu Jicong 已提交
924 925 926
  //  if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
  //    return startPos;
  //  }
927 928 929 930 931 932

  /*
   * This time window does not cover any data, try next time window,
   * this case may happen when the time window is too small
   */
  if (primaryKeys == NULL) {
H
Haojun Liao 已提交
933
    if (ascQuery) {
934 935 936 937 938
      assert(pDataBlockInfo->window.skey <= pNext->ekey);
    } else {
      assert(pDataBlockInfo->window.ekey >= pNext->skey);
    }
  } else {
H
Haojun Liao 已提交
939
    if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
940
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
941 942 943
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
944
      } else {
L
Liu Jicong 已提交
945
        pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
H
Haojun Liao 已提交
946
        pNext->skey = pNext->ekey - pInterval->interval + 1;
947
      }
H
Haojun Liao 已提交
948
    } else if ((!ascQuery) && primaryKeys[startPos] < pNext->skey) {
949
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
950 951 952
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
953
      } else {
H
Haojun Liao 已提交
954 955
        pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
        pNext->ekey = pNext->skey + pInterval->interval - 1;
956 957 958 959 960 961 962
      }
    }
  }

  return startPos;
}

L
Liu Jicong 已提交
963
static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* pWindow) {
dengyihao's avatar
dengyihao 已提交
964
  TSKEY   ekey = -1;
965 966
  int32_t order = TSDB_ORDER_ASC;
  if (order == TSDB_ORDER_ASC) {
967 968 969 970 971 972 973 974 975 976 977 978 979 980
    ekey = pWindow->ekey;
    if (ekey > pQueryAttr->window.ekey) {
      ekey = pQueryAttr->window.ekey;
    }
  } else {
    ekey = pWindow->skey;
    if (ekey < pQueryAttr->window.ekey) {
      ekey = pQueryAttr->window.ekey;
    }
  }

  return ekey;
}

H
Haojun Liao 已提交
981
static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t type) {
982 983 984 985 986 987 988 989 990 991 992
  if (type == RESULT_ROW_START_INTERP) {
    for (int32_t k = 0; k < numOfOutput; ++k) {
      pCtx[k].start.key = INT64_MIN;
    }
  } else {
    for (int32_t k = 0; k < numOfOutput; ++k) {
      pCtx[k].end.key = INT64_MIN;
    }
  }
}

H
Haojun Liao 已提交
993
static void saveDataBlockLastRow(char** pRow, SArray* pDataBlock, int32_t rowIndex, int32_t numOfCols) {
994 995 996 997
  if (pDataBlock == NULL) {
    return;
  }

H
Haojun Liao 已提交
998
  for (int32_t k = 0; k < numOfCols; ++k) {
L
Liu Jicong 已提交
999
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, k);
H
Haojun Liao 已提交
1000
    memcpy(pRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes);
1001 1002 1003
  }
}

H
Haojun Liao 已提交
1004
static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols, int32_t rows, bool ascQuery) {
1005 1006
  TSKEY ts = TSKEY_INITIAL_VAL;
  if (tsCols == NULL) {
L
Liu Jicong 已提交
1007
    ts = ascQuery ? win->skey : win->ekey;
1008
  } else {
L
Liu Jicong 已提交
1009
    int32_t offset = ascQuery ? 0 : rows - 1;
1010 1011 1012 1013 1014 1015
    ts = tsCols[offset];
  }

  return ts;
}

dengyihao's avatar
dengyihao 已提交
1016 1017
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                                   bool createDummyCol);
1018

dengyihao's avatar
dengyihao 已提交
1019 1020
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
                                    int32_t order) {
1021 1022
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
    pCtx[i].order = order;
L
Liu Jicong 已提交
1023
    pCtx[i].size = pBlock->info.rows;
1024
    setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
1025 1026 1027
  }
}

dengyihao's avatar
dengyihao 已提交
1028 1029
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                       bool createDummyCol) {
1030
  if (pBlock->pBlockAgg != NULL) {
H
Haojun Liao 已提交
1031
    doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
1032
  } else {
1033
    doSetInputDataBlock(pOperator, pCtx, pBlock, order, createDummyCol);
H
Haojun Liao 已提交
1034
  }
1035 1036
}

1037
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam,
dengyihao's avatar
dengyihao 已提交
1038
                                             int32_t paramIndex, int32_t numOfRows) {
1039 1040 1041 1042 1043 1044 1045 1046
  SColumnInfoData* pColInfo = NULL;
  if (pInput->pData[paramIndex] == NULL) {
    pColInfo = taosMemoryCalloc(1, sizeof(SColumnInfoData));
    if (pColInfo == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }

    // Set the correct column info (data type and bytes)
1047 1048
    pColInfo->info.type = pFuncParam->param.nType;
    pColInfo->info.bytes = pFuncParam->param.nLen;
1049 1050

    pInput->pData[paramIndex] = pColInfo;
1051 1052
  } else {
    pColInfo = pInput->pData[paramIndex];
1053 1054
  }

1055
  colInfoDataEnsureCapacity(pColInfo, 0, numOfRows);
1056

1057
  int8_t type = pFuncParam->param.nType;
1058 1059
  if (type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_UBIGINT) {
    int64_t v = pFuncParam->param.i;
dengyihao's avatar
dengyihao 已提交
1060
    for (int32_t i = 0; i < numOfRows; ++i) {
1061 1062 1063 1064
      colDataAppendInt64(pColInfo, i, &v);
    }
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
dengyihao's avatar
dengyihao 已提交
1065
    for (int32_t i = 0; i < numOfRows; ++i) {
1066 1067
      colDataAppendDouble(pColInfo, i, &v);
    }
1068 1069 1070 1071 1072 1073
  } else if (type == TSDB_DATA_TYPE_VARCHAR) {
    char *tmp = taosMemoryMalloc(pFuncParam->param.nLen + VARSTR_HEADER_SIZE);
    STR_WITH_SIZE_TO_VARSTR(tmp, pFuncParam->param.pz, pFuncParam->param.nLen);
    for(int32_t i = 0; i < numOfRows; ++i) {
      colDataAppend(pColInfo, i, tmp, false);
    }
1074 1075 1076 1077 1078
  }

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
1079 1080
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                                   bool createDummyCol) {
1081 1082
  int32_t code = TSDB_CODE_SUCCESS;

1083
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
1084 1085 1086
    pCtx[i].order      = order;
    pCtx[i].size       = pBlock->info.rows;
    pCtx[i].pSrcBlock  = pBlock;
H
Haojun Liao 已提交
1087 1088
    pCtx[i].currentStage = MAIN_SCAN;

1089
    SInputColumnInfoData* pInput = &pCtx[i].input;
1090
    pInput->uid = pBlock->info.uid;
C
Cary Xu 已提交
1091
    pInput->colDataAggIsSet = false;
1092

1093 1094
    SExprInfo* pOneExpr = &pOperator->pExpr[i];
    for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
dengyihao's avatar
dengyihao 已提交
1095
      SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
G
Ganlin Zhao 已提交
1096 1097
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
dengyihao's avatar
dengyihao 已提交
1098
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
1099 1100 1101
        pInput->totalRows = pBlock->info.rows;
        pInput->numOfRows = pBlock->info.rows;
        pInput->startRowIndex = 0;
1102

dengyihao's avatar
dengyihao 已提交
1103
        pInput->pPTS = taosArrayGet(pBlock->pDataBlock, 0);  // todo set the correct timestamp column
1104 1105
        ASSERT(pInput->pData[j] != NULL);
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
1106 1107 1108
        // todo avoid case: top(k, 12), 12 is the value parameter.
        // sum(11), 11 is also the value parameter.
        if (createDummyCol && pOneExpr->base.numOfParams == 1) {
1109 1110 1111 1112
          pInput->totalRows = pBlock->info.rows;
          pInput->numOfRows = pBlock->info.rows;
          pInput->startRowIndex = 0;

1113
          code = doCreateConstantValColumnInfo(pInput, pFuncParam, j, pBlock->info.rows);
1114 1115 1116
          if (code != TSDB_CODE_SUCCESS) {
            return code;
          }
1117
        }
G
Ganlin Zhao 已提交
1118 1119
      }
    }
H
Haojun Liao 已提交
1120

H
Haojun Liao 已提交
1121
    //    setBlockStatisInfo(&pCtx[i], pBlock, pOperator->pExpr[i].base.pColumns);
H
Haojun Liao 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
    //      uint32_t flag = pOperator->pExpr[i].base.pParam[0].pCol->flag;
    //      if (TSDB_COL_IS_NORMAL_COL(flag) /*|| (pCtx[i].functionId == FUNCTION_BLKINFO) ||
    //          (TSDB_COL_IS_TAG(flag) && pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)*/) {

    //        SColumn* pCol = pOperator->pExpr[i].base.pParam[0].pCol;
    //        if (pCtx[i].columnIndex == -1) {
    //          for(int32_t j = 0; j < pBlock->info.numOfCols; ++j) {
    //            SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, j);
    //            if (pColData->info.colId == pCol->colId) {
    //              pCtx[i].columnIndex = j;
    //              break;
    //            }
    //          }
    //        }

    //        uint32_t status = aAggs[pCtx[i].functionId].status;
    //        if ((status & (FUNCSTATE_SELECTIVITY | FUNCSTATE_NEED_TS)) != 0) {
    //          SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0);
    // In case of the top/bottom query again the nest query result, which has no timestamp column
    // don't set the ptsList attribute.
    //          if (tsInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
    //            pCtx[i].ptsList = (int64_t*) tsInfo->pData;
    //          } else {
    //            pCtx[i].ptsList = NULL;
    //          }
    //        }
    //      } else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) {
    //        SColIndex*       pColIndex = &pOperator->pExpr[i].base.colInfo;
    //        SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, pColIndex->colIndex);
    //
    //        pCtx[i].pInput = p->pData;
    //        assert(p->info.colId == pColIndex->info.colId && pCtx[i].inputType == p->info.type);
    //        for(int32_t j = 0; j < pBlock->info.rows; ++j) {
    //          char* dst = p->pData + j * p->info.bytes;
    //          taosVariantDump(&pOperator->pExpr[i].base.param[1], dst, p->info.type, true);
    //        }
    //      }
  }
1160 1161

  return code;
H
Haojun Liao 已提交
1162 1163 1164
}

static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
1165
  for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
H
Haojun Liao 已提交
1166
    if (functionNeedToExecute(&pCtx[k])) {
L
Liu Jicong 已提交
1167
      pCtx[k].startTs = startTs;  // this can be set during create the struct
H
Haojun Liao 已提交
1168
      pCtx[k].fpSet.process(&pCtx[k]);
1169 1170 1171 1172
    }
  }
}

H
Haojun Liao 已提交
1173
static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, SArray* pPseudoList) {
dengyihao's avatar
dengyihao 已提交
1174
  size_t num = (pPseudoList != NULL) ? taosArrayGetSize(pPseudoList) : 0;
H
Haojun Liao 已提交
1175 1176 1177 1178 1179
  for (int32_t i = 0; i < num; ++i) {
    pCtx[i].pOutput = taosArrayGet(pResult->pDataBlock, i);
  }
}

dengyihao's avatar
dengyihao 已提交
1180 1181
void projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
                           int32_t numOfOutput, SArray* pPseudoList) {
H
Haojun Liao 已提交
1182
  setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
H
Haojun Liao 已提交
1183
  pResult->info.groupId = pSrcBlock->info.groupId;
H
Haojun Liao 已提交
1184

dengyihao's avatar
dengyihao 已提交
1185 1186
  // if the source equals to the destination, it is to create a new column as the result of scalar function or some
  // operators.
1187 1188
  bool createNewColModel = (pResult == pSrcBlock);

1189 1190
  int32_t numOfRows = 0;

1191
  for (int32_t k = 0; k < numOfOutput; ++k) {
dengyihao's avatar
dengyihao 已提交
1192
    int32_t         outputSlotId = pExpr[k].base.resSchema.slotId;
1193 1194
    SqlFunctionCtx* pfCtx = &pCtx[k];

L
Liu Jicong 已提交
1195
    if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) {  // it is a project query
1196
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
1197
      if (pResult->info.rows > 0 && !createNewColModel) {
1198 1199 1200 1201
        colDataMergeCol(pColInfoData, pResult->info.rows, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      } else {
        colDataAssign(pColInfoData, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      }
1202

1203
      numOfRows = pfCtx->input.numOfRows;
1204
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_VALUE) {
1205
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
1206

dengyihao's avatar
dengyihao 已提交
1207
      int32_t offset = createNewColModel ? 0 : pResult->info.rows;
1208
      for (int32_t i = 0; i < pSrcBlock->info.rows; ++i) {
dengyihao's avatar
dengyihao 已提交
1209 1210 1211
        colDataAppend(pColInfoData, i + offset,
                      taosVariantGet(&pExpr[k].base.pParam[0].param, pExpr[k].base.pParam[0].param.nType),
                      TSDB_DATA_TYPE_NULL == pExpr[k].base.pParam[0].param.nType);
1212
      }
1213 1214

      numOfRows = pSrcBlock->info.rows;
H
Haojun Liao 已提交
1215
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_OPERATOR) {
1216 1217 1218
      SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
      taosArrayPush(pBlockList, &pSrcBlock);

1219
      SColumnInfoData* pResColData = taosArrayGet(pResult->pDataBlock, outputSlotId);
dengyihao's avatar
dengyihao 已提交
1220
      SColumnInfoData  idata = {.info = pResColData->info};
1221

1222
      SScalarParam dest = {.columnData = &idata};
1223 1224
      scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);

dengyihao's avatar
dengyihao 已提交
1225
      int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
1226
      colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
1227 1228

      numOfRows = dest.numOfRows;
1229 1230
      taosArrayDestroy(pBlockList);
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) {
1231
      ASSERT(!fmIsAggFunc(pfCtx->functionId));
1232

1233
      if (fmIsPseudoColumnFunc(pfCtx->functionId)) {
H
Haojun Liao 已提交
1234
        // do nothing
1235
      } else if (fmIsNonstandardSQLFunc(pfCtx->functionId)) {
H
Haojun Liao 已提交
1236
        // todo set the correct timestamp column
1237
        pfCtx->input.pPTS = taosArrayGet(pSrcBlock->pDataBlock, 1);
1238

dengyihao's avatar
dengyihao 已提交
1239
        SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[k]);
1240
        pfCtx->fpSet.init(&pCtx[k], pResInfo);
1241

1242
        pfCtx->pOutput = taosArrayGet(pResult->pDataBlock, outputSlotId);
dengyihao's avatar
dengyihao 已提交
1243
        pfCtx->offset = createNewColModel ? 0 : pResult->info.rows;  // set the start offset
H
Haojun Liao 已提交
1244

1245
        // set the timestamp(_rowts) output buffer
1246 1247
        if (taosArrayGetSize(pPseudoList) > 0) {
          int32_t* outputColIndex = taosArrayGet(pPseudoList, 0);
1248
          pfCtx->pTsOutput = (SColumnInfoData*)pCtx[*outputColIndex].pOutput;
1249
        }
H
Haojun Liao 已提交
1250

1251
        numOfRows = pfCtx->fpSet.process(pfCtx);
H
Haojun Liao 已提交
1252 1253 1254
      } else {
        SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
        taosArrayPush(pBlockList, &pSrcBlock);
G
Ganlin Zhao 已提交
1255

1256
        SColumnInfoData* pResColData = taosArrayGet(pResult->pDataBlock, outputSlotId);
dengyihao's avatar
dengyihao 已提交
1257
        SColumnInfoData  idata = {.info = pResColData->info};
H
Haojun Liao 已提交
1258

1259
        SScalarParam dest = {.columnData = &idata};
H
Haojun Liao 已提交
1260
        scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
1261

dengyihao's avatar
dengyihao 已提交
1262
        int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
1263
        colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
1264 1265

        numOfRows = dest.numOfRows;
H
Haojun Liao 已提交
1266 1267
        taosArrayDestroy(pBlockList);
      }
1268
    } else {
1269
      ASSERT(0);
1270 1271
    }
  }
1272

1273 1274 1275
  if (!createNewColModel) {
    pResult->info.rows += numOfRows;
  }
1276 1277 1278 1279
}

void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SArray* pDataBlock, TSKEY prevTs,
                               int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type) {
dengyihao's avatar
dengyihao 已提交
1280
  SExprInfo* pExpr = pOperator->pExpr;
1281

H
Haojun Liao 已提交
1282
  SqlFunctionCtx* pCtx = pInfo->pCtx;
1283 1284 1285 1286 1287 1288 1289 1290

  for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
    int32_t functionId = pCtx[k].functionId;
    if (functionId != FUNCTION_TWA && functionId != FUNCTION_INTERP) {
      pCtx[k].start.key = INT64_MIN;
      continue;
    }

L
Liu Jicong 已提交
1291
    SColIndex*       pColIndex = NULL /*&pExpr[k].base.colInfo*/;
1292
    int16_t          index = pColIndex->colIndex;
L
Liu Jicong 已提交
1293
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, index);
1294

L
Liu Jicong 已提交
1295
    //    assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
1296 1297 1298
    double v1 = 0, v2 = 0, v = 0;

    if (prevRowIndex == -1) {
dengyihao's avatar
dengyihao 已提交
1299
      //      GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pRuntimeEnv->prevRow[index]);
1300
    } else {
L
Liu Jicong 已提交
1301
      GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pColInfo->pData + prevRowIndex * pColInfo->info.bytes);
1302 1303
    }

L
Liu Jicong 已提交
1304
    GET_TYPED_DATA(v2, double, pColInfo->info.type, (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes);
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315

    if (functionId == FUNCTION_INTERP) {
      if (type == RESULT_ROW_START_INTERP) {
        pCtx[k].start.key = prevTs;
        pCtx[k].start.val = v1;

        pCtx[k].end.key = curTs;
        pCtx[k].end.val = v2;

        if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) {
          if (prevRowIndex == -1) {
dengyihao's avatar
dengyihao 已提交
1316
            //            pCtx[k].start.ptr = (char*)pRuntimeEnv->prevRow[index];
1317
          } else {
L
Liu Jicong 已提交
1318
            pCtx[k].start.ptr = (char*)pColInfo->pData + prevRowIndex * pColInfo->info.bytes;
1319 1320
          }

L
Liu Jicong 已提交
1321
          pCtx[k].end.ptr = (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes;
1322 1323 1324
        }
      }
    } else if (functionId == FUNCTION_TWA) {
L
Liu Jicong 已提交
1325 1326 1327
      SPoint point1 = (SPoint){.key = prevTs, .val = &v1};
      SPoint point2 = (SPoint){.key = curTs, .val = &v2};
      SPoint point = (SPoint){.key = windowKey, .val = &v};
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341

      taosGetLinearInterpolationVal(&point, TSDB_DATA_TYPE_DOUBLE, &point1, &point2, TSDB_DATA_TYPE_DOUBLE);

      if (type == RESULT_ROW_START_INTERP) {
        pCtx[k].start.key = point.key;
        pCtx[k].start.val = v;
      } else {
        pCtx[k].end.key = point.key;
        pCtx[k].end.val = v;
      }
    }
  }
}

H
Haojun Liao 已提交
1342
static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t pos,
dengyihao's avatar
dengyihao 已提交
1343 1344
                                              int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols,
                                              STimeWindow* win) {
H
Haojun Liao 已提交
1345
  bool  ascQuery = true;
L
Liu Jicong 已提交
1346
  TSKEY curTs = tsCols[pos];
dengyihao's avatar
dengyihao 已提交
1347
  TSKEY lastTs = 0;  //*(TSKEY*)pRuntimeEnv->prevRow[0];
1348 1349 1350

  // lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
  // start exactly from this point, no need to do interpolation
L
Liu Jicong 已提交
1351
  TSKEY key = ascQuery ? win->skey : win->ekey;
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
  if (key == curTs) {
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
    return true;
  }

  if (lastTs == INT64_MIN && ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery))) {
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
    return true;
  }

dengyihao's avatar
dengyihao 已提交
1362
  int32_t step = 1;  // GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
L
Liu Jicong 已提交
1363
  TSKEY   prevTs = ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery)) ? lastTs : tsCols[pos - step];
1364

dengyihao's avatar
dengyihao 已提交
1365 1366
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, key,
                            RESULT_ROW_START_INTERP);
1367 1368 1369
  return true;
}

L
Liu Jicong 已提交
1370 1371 1372
static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t endRowIndex,
                                            SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
                                            STimeWindow* win) {
H
Haojun Liao 已提交
1373 1374
  int32_t order = TSDB_ORDER_ASC;
  int32_t numOfOutput = pOperatorInfo->numOfOutput;
1375

L
Liu Jicong 已提交
1376
  TSKEY actualEndKey = tsCols[endRowIndex];
H
Haojun Liao 已提交
1377
  TSKEY key = order ? win->ekey : win->skey;
1378 1379

  // not ended in current data block, do not invoke interpolation
dengyihao's avatar
dengyihao 已提交
1380 1381
  if ((key > blockEkey /*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/) ||
      (key < blockEkey /*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/)) {
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
    setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP);
    return false;
  }

  // there is actual end point of current time window, no interpolation need
  if (key == actualEndKey) {
    setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP);
    return true;
  }

H
Haojun Liao 已提交
1392
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
1393 1394 1395 1396 1397
  int32_t nextRowIndex = endRowIndex + step;
  assert(nextRowIndex >= 0);

  TSKEY nextKey = tsCols[nextRowIndex];
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, actualEndKey, endRowIndex, nextKey,
L
Liu Jicong 已提交
1398
                            nextRowIndex, key, RESULT_ROW_END_INTERP);
1399 1400 1401
  return true;
}

H
Haojun Liao 已提交
1402
static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SqlFunctionCtx* pCtx,
L
Liu Jicong 已提交
1403 1404
                                        SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep,
                                        int32_t order, bool timeWindowInterpo) {
H
Haojun Liao 已提交
1405
  if (!timeWindowInterpo) {
1406 1407 1408 1409
    return;
  }

  assert(pBlock != NULL);
H
Haojun Liao 已提交
1410
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
1411

L
Liu Jicong 已提交
1412 1413
  if (pBlock->pDataBlock == NULL) {
    //    tscError("pBlock->pDataBlock == NULL");
1414 1415
    return;
  }
H
Haojun Liao 已提交
1416

L
Liu Jicong 已提交
1417
  SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
1418

L
Liu Jicong 已提交
1419 1420 1421
  TSKEY* tsCols = (TSKEY*)(pColInfo->pData);
  bool   done = resultRowInterpolated(pResult, RESULT_ROW_START_INTERP);
  if (!done) {  // it is not interpolated, now start to generated the interpolated value
1422
    int32_t startRowIndex = startPos;
L
Liu Jicong 已提交
1423
    bool    interp = setTimeWindowInterpolationStartTs(pOperatorInfo, pCtx, startRowIndex, pBlock->info.rows,
dengyihao's avatar
dengyihao 已提交
1424
                                                    pBlock->pDataBlock, tsCols, win);
1425 1426 1427 1428
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1429
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1430 1431 1432
  }

  // point interpolation does not require the end key time window interpolation.
L
Liu Jicong 已提交
1433 1434 1435
  //  if (pointInterpQuery) {
  //    return;
  //  }
1436 1437 1438 1439 1440 1441

  // interpolation query does not generate the time window end interpolation
  done = resultRowInterpolated(pResult, RESULT_ROW_END_INTERP);
  if (!done) {
    int32_t endRowIndex = startPos + (forwardStep - 1) * step;

L
Liu Jicong 已提交
1442 1443 1444
    TSKEY endKey = (order == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey;
    bool  interp =
        setTimeWindowInterpolationEndTs(pOperatorInfo, pCtx, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
1445 1446 1447 1448
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1449
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_END_INTERP);
1450 1451 1452
  }
}

dengyihao's avatar
dengyihao 已提交
1453 1454
static SArray* hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock,
                               int32_t tableGroupId) {
L
Liu Jicong 已提交
1455
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)pOperatorInfo->info;
1456

H
Haojun Liao 已提交
1457
  SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
L
Liu Jicong 已提交
1458
  int32_t        numOfOutput = pOperatorInfo->numOfOutput;
1459

1460 1461
  SArray* pUpdated = NULL;
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1462
    pUpdated = taosArrayInit(4, POINTER_BYTES);
1463 1464
  }

H
Haojun Liao 已提交
1465
  int32_t step = 1;
1466
  bool    ascScan = true;
1467

dengyihao's avatar
dengyihao 已提交
1468
  //  int32_t prevIndex = pResultRowInfo->curPos;
1469 1470 1471

  TSKEY* tsCols = NULL;
  if (pSDataBlock->pDataBlock != NULL) {
1472
    SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
L
Liu Jicong 已提交
1473
    tsCols = (int64_t*)pColDataInfo->pData;
1474 1475
  }

dengyihao's avatar
dengyihao 已提交
1476
  int32_t startPos = ascScan ? 0 : (pSDataBlock->info.rows - 1);
1477
  TSKEY   ts = getStartTsKey(&pSDataBlock->info.window, tsCols, pSDataBlock->info.rows, ascScan);
1478

dengyihao's avatar
dengyihao 已提交
1479 1480
  STimeWindow win = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval,
                                        pInfo->interval.precision, &pInfo->win);
L
Liu Jicong 已提交
1481
  bool        masterScan = true;
1482 1483

  SResultRow* pResult = NULL;
L
Liu Jicong 已提交
1484
  int32_t     ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult,
dengyihao's avatar
dengyihao 已提交
1485 1486
                                           tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset,
                                           &pInfo->aggSup, pTaskInfo);
1487
  if (ret != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1488
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1489 1490
  }

1491
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1492 1493 1494 1495 1496
    SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
    pos->groupId = tableGroupId;
    pos->pos     = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset};
    *(int64_t*) pos->key = pResult->win.skey;

1497 1498 1499
    taosArrayPush(pUpdated, &pos);
  }

1500
  int32_t forwardStep = 0;
H
Haojun Liao 已提交
1501
  TSKEY   ekey = win.ekey;
1502
  forwardStep =
H
Haojun Liao 已提交
1503
      getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1504 1505

  // prev time window not interpolation yet.
dengyihao's avatar
dengyihao 已提交
1506
  //  int32_t curIndex = pResultRowInfo->curPos;
H
Haojun Liao 已提交
1507 1508

#if 0
H
Haojun Liao 已提交
1509
  if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
1510 1511 1512
    for (int32_t j = prevIndex; j < curIndex; ++j) {  // previous time window may be all closed already.
      SResultRow* pRes = getResultRow(pResultRowInfo, j);
      if (pRes->closed) {
1513
        assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
1514 1515 1516
        continue;
      }

L
Liu Jicong 已提交
1517 1518 1519 1520 1521 1522 1523
      STimeWindow w = pRes->win;
      ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &w, masterScan, &pResult, tableGroupId,
                                       pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                       pTaskInfo);
      if (ret != TSDB_CODE_SUCCESS) {
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
      }
1524

L
Liu Jicong 已提交
1525 1526 1527
      assert(!resultRowInterpolated(pResult, RESULT_ROW_END_INTERP));
      doTimeWindowInterpolation(pOperatorInfo, &pInfo->binfo, pSDataBlock->pDataBlock, *(TSKEY*)pInfo->pRow[0], -1,
                                tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP);
1528

L
Liu Jicong 已提交
1529 1530
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
      setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1531

1532
      doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
L
Liu Jicong 已提交
1533
    }
1534 1535

    // restore current time window
L
Liu Jicong 已提交
1536 1537 1538
    ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
                                     pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                     pTaskInfo);
1539
    if (ret != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1540
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1541 1542
    }
  }
H
Haojun Liao 已提交
1543
#endif
1544 1545

  // window start key interpolation
dengyihao's avatar
dengyihao 已提交
1546 1547
  doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &win, startPos, forwardStep,
                              pInfo->order, false);
1548

1549
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &win, true);
dengyihao's avatar
dengyihao 已提交
1550 1551
  doApplyFunctions(pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
                   pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1552 1553 1554 1555

  STimeWindow nextWin = win;
  while (1) {
    int32_t prevEndPos = (forwardStep - 1) * step + startPos;
H
Haojun Liao 已提交
1556
    startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, pInfo);
1557 1558 1559 1560 1561
    if (startPos < 0) {
      break;
    }

    // null data, failed to allocate more memory buffer
L
Liu Jicong 已提交
1562 1563 1564
    int32_t code = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &nextWin, masterScan, &pResult,
                                              tableGroupId, pInfo->binfo.pCtx, numOfOutput,
                                              pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1565
    if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1566
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1567 1568
    }

1569
    if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1570 1571 1572 1573 1574
      SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
      pos->groupId = tableGroupId;
      pos->pos     = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset};
      *(int64_t*) pos->key = pResult->win.skey;

1575 1576 1577
      taosArrayPush(pUpdated, &pos);
    }

L
Liu Jicong 已提交
1578 1579 1580
    ekey = nextWin.ekey;  // reviseWindowEkey(pQueryAttr, &nextWin);
    forwardStep =
        getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1581 1582

    // window start(end) key interpolation
C
Cary Xu 已提交
1583 1584
    doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardStep,
                                pInfo->order, false);
1585

1586
    updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
dengyihao's avatar
dengyihao 已提交
1587 1588
    doApplyFunctions(pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
                     pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1589 1590
  }

H
Haojun Liao 已提交
1591
  if (pInfo->timeWindowInterpo) {
1592
    int32_t rowIndex = ascScan ? (pSDataBlock->info.rows - 1) : 0;
H
Haojun Liao 已提交
1593
    saveDataBlockLastRow(pInfo->pRow, pSDataBlock->pDataBlock, rowIndex, pSDataBlock->info.numOfCols);
1594 1595
  }

1596
  return pUpdated;
L
Liu Jicong 已提交
1597
  //  updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
1598 1599
}

1600
static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts) {
dengyihao's avatar
dengyihao 已提交
1601 1602
  pRowSup->win.ekey = ts;
  pRowSup->prevTs = ts;
1603
  pRowSup->numOfRows += 1;
1604 1605
}

1606 1607
static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsList, int32_t rowIndex) {
  pRowSup->startRowIndex = rowIndex;
dengyihao's avatar
dengyihao 已提交
1608 1609
  pRowSup->numOfRows = 0;
  pRowSup->win.skey = tsList[rowIndex];
1610 1611
}

1612
// todo handle multiple tables cases.
L
Liu Jicong 已提交
1613
static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperatorInfo* pInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
1614
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
1615

1616
  // todo find the correct time stamp column slot
1617
  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
1618

1619 1620 1621
  bool    masterScan = true;
  int32_t numOfOutput = pOperator->numOfOutput;
  int64_t gid = pBlock->info.groupId;
1622

H
Haojun Liao 已提交
1623
  int64_t gap = pInfo->gap;
1624

1625
  if (!pInfo->reptScan) {
1626
    pInfo->reptScan = true;
1627
    pInfo->winSup.prevTs = INT64_MIN;
1628 1629
  }

1630 1631 1632
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;

1633
  // In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
1634
  TSKEY* tsList = (TSKEY*)pColInfoData->pData;
1635
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
1636 1637 1638 1639
    if (pInfo->winSup.prevTs == INT64_MIN) {
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
    } else if (tsList[j] - pRowSup->prevTs <= gap && (tsList[j] - pRowSup->prevTs) >= 0) {
1640
      // The gap is less than the threshold, so it belongs to current session window that has been opened already.
1641 1642 1643
      doKeepTuple(pRowSup, tsList[j]);
      if (j == 0 && pRowSup->startRowIndex != 0) {
        pRowSup->startRowIndex = 0;
1644 1645 1646
      }
    } else {  // start a new session window
      SResultRow* pResult = NULL;
1647 1648

      // keep the time window for the closed time window.
1649
      STimeWindow window = pRowSup->win;
1650

1651
      pRowSup->win.ekey = pRowSup->win.skey;
L
Liu Jicong 已提交
1652
      int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &window, masterScan,
dengyihao's avatar
dengyihao 已提交
1653 1654
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1655
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1656
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1657 1658
      }

1659
      // pInfo->numOfRows data belong to the current session window
1660
      updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
dengyihao's avatar
dengyihao 已提交
1661 1662
      doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                       pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1663

1664
      // here we start a new session window
1665 1666
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
1667 1668 1669 1670
    }
  }

  SResultRow* pResult = NULL;
1671
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
1672 1673 1674
  int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &pRowSup->win, masterScan,
                                           &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                           pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1675
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1676
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1677 1678
  }

1679
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
dengyihao's avatar
dengyihao 已提交
1680 1681
  doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                   pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1682 1683 1684 1685
}

static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
  if (IS_VAR_DATA_TYPE(type)) {
1686
    // todo disable this
dengyihao's avatar
dengyihao 已提交
1687 1688 1689 1690 1691 1692
    //    if (pResultRow->key == NULL) {
    //      pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
    //      varDataCopy(pResultRow->key, pData);
    //    } else {
    //      ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
    //    }
1693 1694 1695 1696 1697 1698 1699 1700 1701
  } else {
    int64_t v = -1;
    GET_TYPED_DATA(v, int64_t, type, pData);

    pResultRow->win.skey = v;
    pResultRow->win.ekey = v;
  }
}

1702
int32_t setGroupResultOutputBuf(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type, int16_t bytes,
dengyihao's avatar
dengyihao 已提交
1703 1704
                                int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo,
                                SAggSupporter* pAggSup) {
L
Liu Jicong 已提交
1705 1706
  SResultRowInfo* pResultRowInfo = &binfo->resultRowInfo;
  SqlFunctionCtx* pCtx = binfo->pCtx;
1707

1708
  SResultRow* pResultRow = doSetResultOutBufByKey(pBuf, pResultRowInfo, groupId, (char*)pData, bytes, true, groupId,
H
Haojun Liao 已提交
1709
                                                     pTaskInfo, false, pAggSup);
L
Liu Jicong 已提交
1710
  assert(pResultRow != NULL);
1711 1712

  setResultRowKey(pResultRow, pData, type);
H
Haojun Liao 已提交
1713
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfCols, binfo->rowCellInfoOffset);
1714 1715 1716
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
1717 1718
static bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
  struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
1719 1720 1721

  // in case of timestamp column, always generated results.
  int32_t functionId = pCtx->functionId;
H
Haojun Liao 已提交
1722 1723 1724 1725
  if (functionId == -1) {
    return false;
  }

1726
  if (isRowEntryCompleted(pResInfo)) {
1727 1728 1729 1730
    return false;
  }

  if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
L
Liu Jicong 已提交
1731
    //    return QUERY_IS_ASC_QUERY(pQueryAttr);
1732 1733 1734 1735
  }

  // denote the order type
  if ((functionId == FUNCTION_LAST_DST || functionId == FUNCTION_LAST)) {
L
Liu Jicong 已提交
1736
    //    return pCtx->param[0].i == pQueryAttr->order.order;
1737 1738 1739
  }

  // in the reverse table scan, only the following functions need to be executed
L
Liu Jicong 已提交
1740 1741 1742 1743
  //  if (IS_REVERSE_SCAN(pRuntimeEnv) ||
  //      (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
  //    return false;
  //  }
1744 1745 1746 1747

  return true;
}

dengyihao's avatar
dengyihao 已提交
1748 1749
static int32_t doCreateConstantValColumnAggInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t type,
                                                int32_t paramIndex, int32_t numOfRows) {
1750 1751 1752 1753 1754 1755 1756
  if (pInput->pData[paramIndex] == NULL) {
    pInput->pData[paramIndex] = taosMemoryCalloc(1, sizeof(SColumnInfoData));
    if (pInput->pData[paramIndex] == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }

    // Set the correct column info (data type and bytes)
dengyihao's avatar
dengyihao 已提交
1757 1758
    pInput->pData[paramIndex]->info.type = type;
    pInput->pData[paramIndex]->info.bytes = tDataTypes[type].bytes;
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
  }

  SColumnDataAgg* da = NULL;
  if (pInput->pColumnDataAgg[paramIndex] == NULL) {
    da = taosMemoryCalloc(1, sizeof(SColumnDataAgg));
    pInput->pColumnDataAgg[paramIndex] = da;
    if (da == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  } else {
    da = pInput->pColumnDataAgg[paramIndex];
  }

  ASSERT(!IS_VAR_DATA_TYPE(type));

  if (type == TSDB_DATA_TYPE_BIGINT) {
    int64_t v = pFuncParam->param.i;
dengyihao's avatar
dengyihao 已提交
1776
    *da = (SColumnDataAgg){.numOfNull = 0, .min = v, .max = v, .maxIndex = 0, .minIndex = 0, .sum = v * numOfRows};
1777 1778
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
dengyihao's avatar
dengyihao 已提交
1779
    *da = (SColumnDataAgg){.numOfNull = 0, .maxIndex = 0, .minIndex = 0};
1780

dengyihao's avatar
dengyihao 已提交
1781 1782 1783
    *(double*)&da->min = v;
    *(double*)&da->max = v;
    *(double*)&da->sum = v * numOfRows;
1784 1785 1786
  } else if (type == TSDB_DATA_TYPE_BOOL) {  // todo validate this data type
    bool v = pFuncParam->param.i;

dengyihao's avatar
dengyihao 已提交
1787 1788 1789 1790
    *da = (SColumnDataAgg){.numOfNull = 0, .maxIndex = 0, .minIndex = 0};
    *(bool*)&da->min = 0;
    *(bool*)&da->max = v;
    *(bool*)&da->sum = v * numOfRows;
1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809
  } else if (type == TSDB_DATA_TYPE_TIMESTAMP) {
    // do nothing
  } else {
    ASSERT(0);
  }

  return TSDB_CODE_SUCCESS;
}

void setBlockStatisInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pBlock) {
  int32_t numOfRows = pBlock->info.rows;

  SInputColumnInfoData* pInput = &pCtx->input;
  pInput->numOfRows = numOfRows;
  pInput->totalRows = numOfRows;

  if (pBlock->pBlockAgg != NULL) {
    pInput->colDataAggIsSet = true;

1810 1811
    for (int32_t j = 0; j < pExprInfo->base.numOfParams; ++j) {
      SFunctParam* pFuncParam = &pExprInfo->base.pParam[j];
1812

1813 1814 1815
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
        pInput->pColumnDataAgg[j] = &pBlock->pBlockAgg[slotId];
1816 1817 1818 1819

        // Here we set the column info data since the data type for each column data is required, but
        // the data in the corresponding SColumnInfoData will not be used.
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
1820 1821
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
        doCreateConstantValColumnAggInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
1822 1823
      }
    }
1824
  } else {
1825
    pInput->colDataAggIsSet = false;
1826 1827 1828
  }

  // set the statistics data for primary time stamp column
1829 1830 1831 1832 1833
  //  if (pCtx->functionId == FUNCTION_SPREAD && pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
  //    pCtx->isAggSet = true;
  //    pCtx->agg.min = pBlock->info.window.skey;
  //    pCtx->agg.max = pBlock->info.window.ekey;
  //  }
1834 1835 1836
}

// set the output buffer for the selectivity + tag query
L
Liu Jicong 已提交
1837
static int32_t setCtxTagColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1838 1839 1840
  int32_t num = 0;
  int16_t tagLen = 0;

H
Haojun Liao 已提交
1841
  SqlFunctionCtx*  p = NULL;
wafwerar's avatar
wafwerar 已提交
1842
  SqlFunctionCtx** pTagCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
1843 1844 1845 1846 1847 1848 1849 1850
  if (pTagCtx == NULL) {
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;

    if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
H
Haojun Liao 已提交
1851
      tagLen += pCtx[i].resDataInfo.bytes;
1852
      pTagCtx[num++] = &pCtx[i];
L
Liu Jicong 已提交
1853
    } else if (1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/) {
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
      p = &pCtx[i];
    } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
      // tag function may be the group by tag column
      // ts may be the required primary timestamp column
      continue;
    } else {
      // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
    }
  }
  if (p != NULL) {
1864 1865
    p->subsidiaries.pCtx = pTagCtx;
    p->subsidiaries.num = num;
1866
  } else {
wafwerar's avatar
wafwerar 已提交
1867
    taosMemoryFreeClear(pTagCtx);
1868 1869 1870 1871 1872
  }

  return TSDB_CODE_SUCCESS;
}

1873
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) {
L
Liu Jicong 已提交
1874
  SqlFunctionCtx* pFuncCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
H
Haojun Liao 已提交
1875 1876 1877 1878
  if (pFuncCtx == NULL) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
1879
  *rowCellInfoOffset = taosMemoryCalloc(numOfOutput, sizeof(int32_t));
H
Haojun Liao 已提交
1880
  if (*rowCellInfoOffset == 0) {
wafwerar's avatar
wafwerar 已提交
1881
    taosMemoryFreeClear(pFuncCtx);
H
Haojun Liao 已提交
1882 1883 1884 1885
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
1886
    SExprInfo* pExpr = &pExprInfo[i];
H
Haojun Liao 已提交
1887

L
Liu Jicong 已提交
1888
    SExprBasicInfo* pFunct = &pExpr->base;
H
Haojun Liao 已提交
1889
    SqlFunctionCtx* pCtx = &pFuncCtx[i];
H
Haojun Liao 已提交
1890

1891
    pCtx->functionId = -1;
1892 1893 1894
    pCtx->curBufPage = -1;
    pCtx->pExpr      = pExpr;

H
Haojun Liao 已提交
1895
    if (pExpr->pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1896
      SFuncExecEnv env = {0};
H
Haojun Liao 已提交
1897 1898
      pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;

H
Haojun Liao 已提交
1899
      if (fmIsAggFunc(pCtx->functionId) || fmIsNonstandardSQLFunc(pCtx->functionId)) {
1900 1901 1902 1903
        fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
        pCtx->fpSet.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
      } else {
        fmGetScalarFuncExecFuncs(pCtx->functionId, &pCtx->sfp);
1904 1905 1906
        if (pCtx->sfp.getEnv != NULL) {
          pCtx->sfp.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
        }
1907
      }
H
Haojun Liao 已提交
1908
      pCtx->resDataInfo.interBufSize = env.calcMemSize;
1909 1910 1911 1912
    } else if (pExpr->pExpr->nodeType == QUERY_NODE_COLUMN || pExpr->pExpr->nodeType == QUERY_NODE_OPERATOR ||
               pExpr->pExpr->nodeType == QUERY_NODE_VALUE) {
      // for simple column, the intermediate buffer needs to hold one element.
      pCtx->resDataInfo.interBufSize = pFunct->resSchema.bytes;
H
Haojun Liao 已提交
1913
    }
H
Haojun Liao 已提交
1914

H
Haojun Liao 已提交
1915
    pCtx->input.numOfInputCols = pFunct->numOfParams;
wafwerar's avatar
wafwerar 已提交
1916 1917
    pCtx->input.pData = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
    pCtx->input.pColumnDataAgg = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
H
Haojun Liao 已提交
1918

1919
    pCtx->pTsOutput = NULL;
L
Liu Jicong 已提交
1920
    pCtx->resDataInfo.bytes = pFunct->resSchema.bytes;
1921
    pCtx->resDataInfo.type = pFunct->resSchema.type;
1922
    pCtx->order     = TSDB_ORDER_ASC;
1923
    pCtx->start.key = INT64_MIN;
1924
    pCtx->end.key   = INT64_MIN;
1925
    pCtx->numOfParams = pExpr->base.numOfParams;
H
Haojun Liao 已提交
1926

1927
    pCtx->param = pFunct->pParam;
dengyihao's avatar
dengyihao 已提交
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961
    //    for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
    //      // set the order information for top/bottom query
    //      int32_t functionId = pCtx->functionId;
    //      if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF) {
    //        int32_t f = getExprFunctionId(&pExpr[0]);
    //        assert(f == FUNCTION_TS || f == FUNCTION_TS_DUMMY);
    //
    //        //      pCtx->param[2].i = pQueryAttr->order.order;
    //        //      pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
    //        //      pCtx->param[3].i = functionId;
    //        //      pCtx->param[3].nType = TSDB_DATA_TYPE_BIGINT;
    //
    //        //      pCtx->param[1].i = pQueryAttr->order.col.info.colId;
    //      } else if (functionId == FUNCTION_INTERP) {
    //        //      pCtx->param[2].i = (int8_t)pQueryAttr->fillType;
    //        //      if (pQueryAttr->fillVal != NULL) {
    //        //        if (isNull((const char *)&pQueryAttr->fillVal[i], pCtx->inputType)) {
    //        //          pCtx->param[1].nType = TSDB_DATA_TYPE_NULL;
    //        //        } else {  // todo refactor, taosVariantCreateFromBinary should handle the NULL value
    //        //          if (pCtx->inputType != TSDB_DATA_TYPE_BINARY && pCtx->inputType != TSDB_DATA_TYPE_NCHAR) {
    //        //            taosVariantCreateFromBinary(&pCtx->param[1], (char *)&pQueryAttr->fillVal[i],
    //        pCtx->inputBytes, pCtx->inputType);
    //        //          }
    //        //        }
    //        //      }
    //      } else if (functionId == FUNCTION_TWA) {
    //        //      pCtx->param[1].i = pQueryAttr->window.skey;
    //        //      pCtx->param[1].nType = TSDB_DATA_TYPE_BIGINT;
    //        //      pCtx->param[2].i = pQueryAttr->window.ekey;
    //        //      pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
    //      } else if (functionId == FUNCTION_ARITHM) {
    //        //      pCtx->param[1].pz = (char*) getScalarFuncSupport(pRuntimeEnv->scalarSup, i);
    //      }
    //    }
H
Haojun Liao 已提交
1962 1963
  }

L
Liu Jicong 已提交
1964 1965 1966
  for (int32_t i = 1; i < numOfOutput; ++i) {
    (*rowCellInfoOffset)[i] =
        (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowEntryInfo) + pFuncCtx[i - 1].resDataInfo.interBufSize);
H
Haojun Liao 已提交
1967
  }
H
Haojun Liao 已提交
1968 1969 1970 1971 1972

  setCtxTagColumnInfo(pFuncCtx, numOfOutput);
  return pFuncCtx;
}

1973
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1974 1975 1976 1977 1978 1979
  if (pCtx == NULL) {
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    for (int32_t j = 0; j < pCtx[i].numOfParams; ++j) {
1980
      taosVariantDestroy(&pCtx[i].param[j].param);
1981 1982 1983
    }

    taosVariantDestroy(&pCtx[i].tag);
1984
    taosMemoryFreeClear(pCtx[i].subsidiaries.pCtx);
1985 1986
  }

wafwerar's avatar
wafwerar 已提交
1987
  taosMemoryFreeClear(pCtx);
1988 1989 1990
  return NULL;
}

L
Liu Jicong 已提交
1991
bool isTaskKilled(SExecTaskInfo* pTaskInfo) {
1992 1993
  // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
  // abort current query execution.
L
Liu Jicong 已提交
1994 1995
  if (pTaskInfo->owner != 0 &&
      ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec())
1996 1997
      /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) {
    assert(pTaskInfo->cost.start != 0);
L
Liu Jicong 已提交
1998 1999 2000
    //    qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64
    //           ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec());
    //    return true;
2001 2002 2003 2004 2005
  }

  return false;
}

L
Liu Jicong 已提交
2006
void setTaskKilled(SExecTaskInfo* pTaskInfo) { pTaskInfo->code = TSDB_CODE_TSC_QUERY_CANCELLED; }
2007

L
Liu Jicong 已提交
2008
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
2009 2010 2011 2012 2013 2014 2015 2016 2017
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
    if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) {
      continue;
    }

    return false;
  }

2018 2019
  int32_t order = TSDB_ORDER_ASC;
  if (order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) {
2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038
    return false;
  }

  if (pQueryAttr->groupbyColumn) {
    return false;
  }

  if (pQueryAttr->interval.interval > 0) {
    return false;
  }

  if (pQueryAttr->numOfFilterCols > 0 || pQueryAttr->havingNum > 0) {
    return false;
  }

  return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////
L
Liu Jicong 已提交
2039
// todo refactor : return window
2040
void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, STimeWindow* win) {
H
Haojun Liao 已提交
2041
  win->skey = taosTimeTruncate(key, pInterval, precision);
2042 2043

  /*
H
Haojun Liao 已提交
2044
   * if the realSkey > INT64_MAX - pInterval->interval, the query duration between
2045 2046
   * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
   */
2047 2048
  win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
  if (win->ekey < win->skey) {
2049 2050 2051 2052
    win->ekey = INT64_MAX;
  }
}

L
Liu Jicong 已提交
2053
static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
2054 2055 2056
  bool hasFirstLastFunc = false;
  bool hasOtherFunc = false;

2057
  if (status == BLK_DATA_DATA_LOAD || status == BLK_DATA_FILTEROUT) {
2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
    return status;
  }

  for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQuery->pExpr1[i]);

    if (functionId == FUNCTION_TS || functionId == FUNCTION_TS_DUMMY || functionId == FUNCTION_TAG ||
        functionId == FUNCTION_TAG_DUMMY) {
      continue;
    }

    if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_LAST_DST) {
      hasFirstLastFunc = true;
    } else {
      hasOtherFunc = true;
    }
  }

2076
  if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
L
Liu Jicong 已提交
2077
    if (!hasOtherFunc) {
2078
      return BLK_DATA_FILTEROUT;
2079
    } else {
2080
      return BLK_DATA_DATA_LOAD;
2081 2082 2083 2084 2085 2086
    }
  }

  return status;
}

L
Liu Jicong 已提交
2087 2088
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
//   STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
H
Haojun Liao 已提交
2089
//
L
Liu Jicong 已提交
2090 2091 2092 2093
//   // in case of point-interpolation query, use asc order scan
//   char msg[] = "QInfo:0x%"PRIx64" scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%"
//   PRId64
//                "-%" PRId64 ", new qrange:%" PRId64 "-%" PRId64;
H
Haojun Liao 已提交
2094
//
L
Liu Jicong 已提交
2095 2096 2097 2098 2099
//   // todo handle the case the the order irrelevant query type mixed up with order critical query type
//   // descending order query for last_row query
//   if (isFirstLastRowQuery(pQueryAttr)) {
//     //qDebug("QInfo:0x%"PRIx64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId,
//     pQueryAttr->order.order, TSDB_ORDER_ASC);
H
Haojun Liao 已提交
2100
//
L
Liu Jicong 已提交
2101 2102 2103 2104
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2105
//
L
Liu Jicong 已提交
2106 2107 2108
//     pQueryAttr->needReverseScan = false;
//     return;
//   }
H
Haojun Liao 已提交
2109
//
L
Liu Jicong 已提交
2110 2111 2112 2113 2114
//   if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) {
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2115
//
L
Liu Jicong 已提交
2116 2117 2118 2119
//     pQueryAttr->needReverseScan = false;
//     doUpdateLastKey(pQueryAttr);
//     return;
//   }
H
Haojun Liao 已提交
2120
//
L
Liu Jicong 已提交
2121 2122 2123 2124 2125 2126
//   if (pQueryAttr->pointInterpQuery && pQueryAttr->interval.interval == 0) {
//     if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//       //qDebug(msg, pQInfo->qId, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
//       pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); TSWAP(pQueryAttr->window.skey,
//       pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2127
//
L
Liu Jicong 已提交
2128 2129 2130
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     return;
//   }
H
Haojun Liao 已提交
2131
//
L
Liu Jicong 已提交
2132 2133 2134 2135
//   if (pQueryAttr->interval.interval == 0) {
//     if (onlyFirstQuery(pQueryAttr)) {
//       if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//         //qDebug(msg, pQInfo->qId, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
H
Haojun Liao 已提交
2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//        doUpdateLastKey(pQueryAttr);
//      }
//
//      pQueryAttr->order.order = TSDB_ORDER_ASC;
//      pQueryAttr->needReverseScan = false;
//    } else if (onlyLastQuery(pQueryAttr) && notContainSessionOrStateWindow(pQueryAttr)) {
//      if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//        //qDebug(msg, pQInfo->qId, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//        doUpdateLastKey(pQueryAttr);
//      }
//
//      pQueryAttr->order.order = TSDB_ORDER_DESC;
//      pQueryAttr->needReverseScan = false;
//    }
//
//  } else {  // interval query
//    if (stableQuery) {
//      if (onlyFirstQuery(pQueryAttr)) {
//        if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//          //qDebug(msg, pQInfo->qId, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC,
L
Liu Jicong 已提交
2162 2163
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_ASC;
//        pQueryAttr->needReverseScan = false;
//      } else if (onlyLastQuery(pQueryAttr)) {
//        if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//          //qDebug(msg, pQInfo->qId, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC,
L
Liu Jicong 已提交
2174 2175
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_DESC;
//        pQueryAttr->needReverseScan = false;
//      }
//    }
//  }
//}
2187

H
Haojun Liao 已提交
2188 2189
static void getIntermediateBufInfo(STaskRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) {
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
L
Liu Jicong 已提交
2190
  int32_t    MIN_ROWS_PER_PAGE = 4;
2191

L
Liu Jicong 已提交
2192 2193
  *rowsize = (int32_t)(pQueryAttr->resultRowSize *
                       getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
2194 2195 2196 2197
  int32_t overhead = sizeof(SFilePage);

  // one page contains at least two rows
  *ps = DEFAULT_INTERN_BUF_PAGE_SIZE;
L
Liu Jicong 已提交
2198
  while (((*rowsize) * MIN_ROWS_PER_PAGE) > (*ps) - overhead) {
2199 2200 2201 2202 2203 2204
    *ps = ((*ps) << 1u);
  }
}

#define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR)

L
Liu Jicong 已提交
2205 2206 2207
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
//   STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2208
//
L
Liu Jicong 已提交
2209 2210 2211
//   if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
//     return true;
//   }
2212
//
L
Liu Jicong 已提交
2213 2214
//   return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
2215

H
Haojun Liao 已提交
2216
static bool overlapWithTimeWindow(STaskAttr* pQueryAttr, SDataBlockInfo* pBlockInfo) {
2217 2218
  STimeWindow w = {0};

dengyihao's avatar
dengyihao 已提交
2219 2220
  TSKEY sk = TMIN(pQueryAttr->window.skey, pQueryAttr->window.ekey);
  TSKEY ek = TMAX(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2221

2222
  if (true) {
L
Liu Jicong 已提交
2223
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
2224 2225 2226 2227 2228 2229
    assert(w.ekey >= pBlockInfo->window.skey);

    if (w.ekey < pBlockInfo->window.ekey) {
      return true;
    }

L
Liu Jicong 已提交
2230 2231
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2232 2233 2234 2235 2236 2237 2238 2239 2240 2241
      if (w.skey > pBlockInfo->window.ekey) {
        break;
      }

      assert(w.ekey > pBlockInfo->window.ekey);
      if (w.skey <= pBlockInfo->window.ekey && w.skey > pBlockInfo->window.skey) {
        return true;
      }
    }
  } else {
L
Liu Jicong 已提交
2242
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
2243 2244 2245 2246 2247 2248
    assert(w.skey <= pBlockInfo->window.ekey);

    if (w.skey > pBlockInfo->window.skey) {
      return true;
    }

L
Liu Jicong 已提交
2249 2250
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
      if (w.ekey < pBlockInfo->window.skey) {
        break;
      }

      assert(w.skey < pBlockInfo->window.skey);
      if (w.ekey < pBlockInfo->window.ekey && w.ekey >= pBlockInfo->window.skey) {
        return true;
      }
    }
  }

  return false;
}

void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p) {
  int32_t len = 0;
  int32_t start = 0;
  for (int32_t j = 0; j < numOfRows; ++j) {
    if (p[j] == 1) {
      len++;
    } else {
      if (len > 0) {
        int32_t cstart = j - len;
        for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
          SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i);

          int16_t bytes = pColumnInfoData->info.bytes;
          memmove(((char*)pColumnInfoData->pData) + start * bytes, pColumnInfoData->pData + cstart * bytes,
                  len * bytes);
        }

        start += len;
        len = 0;
      }
    }
  }

  if (len > 0) {
    int32_t cstart = numOfRows - len;
    for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i);

      int16_t bytes = pColumnInfoData->info.bytes;
      memmove(pColumnInfoData->pData + start * bytes, pColumnInfoData->pData + cstart * bytes, len * bytes);
    }

    start += len;
    len = 0;
  }

  pBlock->info.rows = start;
  pBlock->pBlockAgg = NULL;  // clean the block statistics info

  if (start > 0) {
    SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, 0);
    if (pColumnInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP &&
        pColumnInfoData->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
      pBlock->info.window.skey = *(int64_t*)pColumnInfoData->pData;
      pBlock->info.window.ekey = *(int64_t*)(pColumnInfoData->pData + TSDB_KEYSIZE * (start - 1));
    }
  }
}

static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t numOfTags, int16_t colId);
L
Liu Jicong 已提交
2315
static void         doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes);
2316 2317

static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
2318
  SqlFunctionCtx* pCtx = pTableScanInfo->pCtx;
2319
  uint32_t        status = BLK_DATA_NOT_LOAD;
2320 2321 2322 2323

  int32_t numOfOutput = pTableScanInfo->numOfOutput;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;
H
Haojun Liao 已提交
2324
    int32_t colId = pTableScanInfo->pExpr[i].base.pParam[0].pCol->colId;
2325 2326 2327

    // group by + first/last should not apply the first/last block filter
    if (functionId < 0) {
2328
      status |= BLK_DATA_DATA_LOAD;
2329 2330
      return status;
    } else {
L
Liu Jicong 已提交
2331
      //      status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
2332
      //      if ((status & BLK_DATA_DATA_LOAD) == BLK_DATA_DATA_LOAD) {
L
Liu Jicong 已提交
2333 2334
      //        return status;
      //      }
2335 2336 2337 2338 2339 2340
    }
  }

  return status;
}

L
Liu Jicong 已提交
2341 2342
int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                              uint32_t* status) {
2343
  *status = BLK_DATA_NOT_LOAD;
2344

H
Haojun Liao 已提交
2345
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
2346
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
2347

L
Liu Jicong 已提交
2348 2349
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2350

H
Haojun Liao 已提交
2351
  STaskCostInfo* pCost = &pTaskInfo->cost;
2352 2353 2354

  pCost->totalBlocks += 1;
  pCost->totalRows += pBlock->info.rows;
H
Haojun Liao 已提交
2355
#if 0
2356 2357 2358
  // Calculate all time windows that are overlapping or contain current data block.
  // If current data block is contained by all possible time window, do not load current data block.
  if (/*pQueryAttr->pFilters || */pQueryAttr->groupbyColumn || pQueryAttr->sw.gap > 0 ||
H
Haojun Liao 已提交
2359
      (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) {
2360
    (*status) = BLK_DATA_DATA_LOAD;
2361 2362 2363
  }

  // check if this data block is required to load
2364
  if ((*status) != BLK_DATA_DATA_LOAD) {
2365 2366 2367 2368 2369 2370 2371
    bool needFilter = true;

    // the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet,
    // the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer
    if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
      SResultRow* pResult = NULL;

H
Haojun Liao 已提交
2372
      bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395
      TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey;

      STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr);
      if (pQueryAttr->pointInterpQuery) {
        needFilter = chkWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId,
                                    pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
                                    pTableScanInfo->rowCellInfoOffset);
      } else {
        if (setResultOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pBlock->info.uid, &win, masterScan, &pResult, groupId,
                                    pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
                                    pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) {
          longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
        }
      }
    } else if (pQueryAttr->stableQuery && (!pQueryAttr->tsCompQuery) && (!pQueryAttr->diffQuery)) { // stable aggregate, not interval aggregate or normal column aggregate
      doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx,
                               pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput,
                               pRuntimeEnv->current->groupIndex);
    }

    if (needFilter) {
      (*status) = doFilterByBlockTimeWindow(pTableScanInfo, pBlock);
    } else {
2396
      (*status) = BLK_DATA_DATA_LOAD;
2397 2398 2399 2400
    }
  }

  SDataBlockInfo* pBlockInfo = &pBlock->info;
H
Haojun Liao 已提交
2401
//  *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *status);
2402

2403
  if ((*status) == BLK_DATA_NOT_LOAD || (*status) == BLK_DATA_FILTEROUT) {
2404 2405
    //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//           pBlockInfo->window.ekey, pBlockInfo->rows);
2406
    pCost->skipBlocks += 1;
2407
  } else if ((*status) == BLK_DATA_SMA_LOAD) {
2408 2409
    // this function never returns error?
    pCost->loadBlockStatis += 1;
2410
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2411 2412

    if (pBlock->pBlockAgg == NULL) {  // data block statistics does not exist, load data block
2413
//      pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2414 2415 2416
      pCost->totalCheckedRows += pBlock->info.rows;
    }
  } else {
2417
    assert((*status) == BLK_DATA_DATA_LOAD);
2418 2419 2420

    // load the data block statistics to perform further filter
    pCost->loadBlockStatis += 1;
2421
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2422 2423 2424 2425 2426 2427

    if (pQueryAttr->topBotQuery && pBlock->pBlockAgg != NULL) {
      { // set previous window
        if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
          SResultRow* pResult = NULL;

H
Haojun Liao 已提交
2428
          bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445
          TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey;

          STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr);
          if (setResultOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pBlock->info.uid, &win, masterScan, &pResult, groupId,
                                      pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
                                      pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) {
            longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
          }
        }
      }
      bool load = false;
      for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
        int32_t functionId = pTableScanInfo->pCtx[i].functionId;
        if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) {
//          load = topbot_datablock_filter(&pTableScanInfo->pCtx[i], (char*)&(pBlock->pBlockAgg[i].min),
//                                         (char*)&(pBlock->pBlockAgg[i].max));
          if (!load) { // current block has been discard due to filter applied
2446
            pCost->skipBlocks += 1;
2447 2448
            //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
//                   pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
2449
            (*status) = BLK_DATA_FILTEROUT;
2450 2451 2452 2453 2454 2455 2456 2457
            return TSDB_CODE_SUCCESS;
          }
        }
      }
    }

    // current block has been discard due to filter applied
//    if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
2458
//      pCost->skipBlocks += 1;
2459 2460
//      qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//             pBlockInfo->window.ekey, pBlockInfo->rows);
2461
//      (*status) = BLK_DATA_FILTEROUT;
2462 2463 2464 2465 2466
//      return TSDB_CODE_SUCCESS;
//    }

    pCost->totalCheckedRows += pBlockInfo->rows;
    pCost->loadBlocks += 1;
2467
//    pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479
//    if (pBlock->pDataBlock == NULL) {
//      return terrno;
//    }

//    if (pQueryAttr->pFilters != NULL) {
//      filterSetColFieldData(pQueryAttr->pFilters, pBlock->info.numOfCols, pBlock->pDataBlock);
//    }
    
//    if (pQueryAttr->pFilters != NULL || pRuntimeEnv->pTsBuf != NULL) {
//      filterColRowsInDataBlock(pRuntimeEnv, pBlock, ascQuery);
//    }
  }
H
Haojun Liao 已提交
2480
#endif
2481 2482 2483
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
2484
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
2485 2486 2487 2488 2489 2490 2491 2492 2493
  int32_t midPos = -1;
  int32_t numOfRows;

  if (num <= 0) {
    return -1;
  }

  assert(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);

L
Liu Jicong 已提交
2494
  TSKEY*  keyList = (TSKEY*)pValue;
2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547
  int32_t firstPos = 0;
  int32_t lastPos = num - 1;

  if (order == TSDB_ORDER_DESC) {
    // find the first position which is smaller than the key
    while (1) {
      if (key >= keyList[lastPos]) return lastPos;
      if (key == keyList[firstPos]) return firstPos;
      if (key < keyList[firstPos]) return firstPos - 1;

      numOfRows = lastPos - firstPos + 1;
      midPos = (numOfRows >> 1) + firstPos;

      if (key < keyList[midPos]) {
        lastPos = midPos - 1;
      } else if (key > keyList[midPos]) {
        firstPos = midPos + 1;
      } else {
        break;
      }
    }

  } else {
    // find the first position which is bigger than the key
    while (1) {
      if (key <= keyList[firstPos]) return firstPos;
      if (key == keyList[lastPos]) return lastPos;

      if (key > keyList[lastPos]) {
        lastPos = lastPos + 1;
        if (lastPos >= num)
          return -1;
        else
          return lastPos;
      }

      numOfRows = lastPos - firstPos + 1;
      midPos = (numOfRows >> 1u) + firstPos;

      if (key < keyList[midPos]) {
        lastPos = midPos - 1;
      } else if (key > keyList[midPos]) {
        firstPos = midPos + 1;
      } else {
        break;
      }
    }
  }

  return midPos;
}

/*
H
Haojun Liao 已提交
2548
 * set tag value in SqlFunctionCtx
2549 2550
 * e.g.,tag information into input buffer
 */
L
Liu Jicong 已提交
2551
static void doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes) {
2552 2553 2554
  taosVariantDestroy(tag);

  char* val = NULL;
L
Liu Jicong 已提交
2555 2556 2557 2558 2559 2560
  //  if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
  //    val = tsdbGetTableName(pTable);
  //    assert(val != NULL);
  //  } else {
  //    val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
  //  }
2561 2562 2563 2564 2565 2566 2567 2568

  if (val == NULL || isNull(val, type)) {
    tag->nType = TSDB_DATA_TYPE_NULL;
    return;
  }

  if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
    int32_t maxLen = bytes - VARSTR_HEADER_SIZE;
L
Liu Jicong 已提交
2569
    int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
2570
    taosVariantCreateFromBinary(tag, varDataVal(val), len, type);
L
Liu Jicong 已提交
2571
    // taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
2572 2573 2574 2575 2576 2577 2578 2579
  } else {
    taosVariantCreateFromBinary(tag, val, bytes, type);
  }
}

static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t numOfTags, int16_t colId) {
  assert(pTagColList != NULL && numOfTags > 0);

L
Liu Jicong 已提交
2580
  for (int32_t i = 0; i < numOfTags; ++i) {
2581 2582 2583 2584 2585 2586 2587 2588
    if (pTagColList[i].colId == colId) {
      return &pTagColList[i];
    }
  }

  return NULL;
}

L
Liu Jicong 已提交
2589 2590
void setTagValue(SOperatorInfo* pOperatorInfo, void* pTable, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
  SExprInfo* pExpr = pOperatorInfo->pExpr;
2591
  SExprInfo* pExprInfo = &pExpr[0];
L
Liu Jicong 已提交
2592
  int32_t    functionId = getExprFunctionId(pExprInfo);
2593
#if 0
2594 2595 2596
  if (pQueryAttr->numOfOutput == 1 && functionId == FUNCTION_TS_COMP && pQueryAttr->stableQuery) {
    assert(pExprInfo->base.numOfParams == 1);

L
Liu Jicong 已提交
2597
    //    int16_t      tagColId = (int16_t)pExprInfo->base.param[0].i;
H
Haojun Liao 已提交
2598
    int16_t      tagColId = -1;
2599 2600 2601
    SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);

    doSetTagValueInParam(pTable, tagColId, &pCtx[0].tag, pColInfo->type, pColInfo->bytes);
H
Haojun Liao 已提交
2602

2603 2604 2605 2606 2607 2608 2609 2610 2611
  } else {
    // set tag value, by which the results are aggregated.
    int32_t offset = 0;
    memset(pRuntimeEnv->tagVal, 0, pQueryAttr->tagLen);

    for (int32_t idx = 0; idx < numOfOutput; ++idx) {
      SExprInfo* pLocalExprInfo = &pExpr[idx];

      // ts_comp column required the tag value for join filter
H
Haojun Liao 已提交
2612
      if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.pParam[0].pCol->flag)) {
2613 2614 2615 2616
        continue;
      }

      // todo use tag column index to optimize performance
L
Liu Jicong 已提交
2617 2618
      doSetTagValueInParam(pTable, pLocalExprInfo->base.pParam[0].pCol->colId, &pCtx[idx].tag,
                           pLocalExprInfo->base.resSchema.type, pLocalExprInfo->base.resSchema.bytes);
2619

L
Liu Jicong 已提交
2620 2621 2622
      if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resSchema.type) ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_BOOL ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_TIMESTAMP) {
2623 2624 2625 2626
        memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i, pLocalExprInfo->base.resSchema.bytes);
      } else {
        if (pCtx[idx].tag.pz != NULL) {
          memcpy(pRuntimeEnv->tagVal + offset, pCtx[idx].tag.pz, pCtx[idx].tag.nLen);
L
Liu Jicong 已提交
2627
        }
2628 2629 2630 2631 2632 2633 2634 2635 2636 2637
      }

      offset += pLocalExprInfo->base.resSchema.bytes;
    }
  }

  // set the tsBuf start position before check each data block
  if (pRuntimeEnv->pTsBuf != NULL) {
    setCtxTagForJoin(pRuntimeEnv, &pCtx[0], pExprInfo, pTable);
  }
2638
#endif
2639 2640
}

H
Haojun Liao 已提交
2641
void copyToSDataBlock(SSDataBlock* pBlock, int32_t* offset, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pResBuf) {
2642 2643 2644 2645 2646 2647 2648
  pBlock->info.rows = 0;

  int32_t code = TSDB_CODE_SUCCESS;
  while (pGroupResInfo->currentGroup < pGroupResInfo->totalGroup) {
    // all results in current group have been returned to client, try next group
    if ((pGroupResInfo->pRows == NULL) || taosArrayGetSize(pGroupResInfo->pRows) == 0) {
      assert(pGroupResInfo->index == 0);
L
Liu Jicong 已提交
2649 2650 2651
      //      if ((code = mergeIntoGroupResult(&pGroupResInfo, pRuntimeEnv, offset)) != TSDB_CODE_SUCCESS) {
      return;
      //      }
2652 2653
    }

L
Liu Jicong 已提交
2654
    //    doCopyToSDataBlock(pResBuf, pGroupResInfo, TSDB_ORDER_ASC, pBlock, );
2655 2656 2657 2658 2659 2660 2661 2662 2663 2664

    // current data are all dumped to result buffer, clear it
    if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
      cleanupGroupResInfo(pGroupResInfo);
      if (!incNextGroup(pGroupResInfo)) {
        break;
      }
    }

    // enough results in data buffer, return
L
Liu Jicong 已提交
2665 2666 2667
    //    if (pBlock->info.rows >= threshold) {
    //      break;
    //    }
2668 2669 2670
  }
}

L
Liu Jicong 已提交
2671
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
2672 2673 2674 2675
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2676 2677
  //  TSWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY);
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
2678

L
Liu Jicong 已提交
2679 2680
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
2681 2682

  // set the index to be the end slot of result rows array
dengyihao's avatar
dengyihao 已提交
2683 2684 2685 2686 2687 2688
  //  SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->size > 0) {
  //    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  //  } else {
  //    pResultRowInfo->curPos = -1;
  //  }
2689 2690
}

H
Haojun Liao 已提交
2691
void initResultRow(SResultRow* pResultRow) {
2692 2693 2694 2695 2696 2697
  pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
}

/*
 * The start of each column SResultRowEntryInfo is denote by RowCellInfoOffset.
 * Note that in case of top/bottom query, the whole multiple rows of result is treated as only one row of results.
H
Haojun Liao 已提交
2698 2699 2700
 * +------------+-----------------result column 1------------+------------------result column 2-----------+
 * | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2|
 * +------------+--------------------------------------------+--------------------------------------------+
2701 2702
 *           offset[0]                                  offset[1]                                   offset[2]
 */
2703
// TODO refactor: some function move away
H
Haojun Liao 已提交
2704
void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
2705 2706 2707
  SqlFunctionCtx* pCtx = pInfo->pCtx;
  SSDataBlock*    pDataBlock = pInfo->pRes;
  int32_t*        rowCellInfoOffset = pInfo->rowCellInfoOffset;
H
Haojun Liao 已提交
2708

H
Haojun Liao 已提交
2709
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
2710
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
2711

L
Liu Jicong 已提交
2712 2713
  int64_t     tid = 0;
  int64_t     groupId = 0;
2714
  SResultRow* pRow = doSetResultOutBufByKey(pSup->pResultBuf, pResultRowInfo, tid, (char*)&tid, sizeof(tid), true,
L
Liu Jicong 已提交
2715
                                               groupId, pTaskInfo, false, pSup);
H
Haojun Liao 已提交
2716 2717 2718 2719 2720

  for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
    struct SResultRowEntryInfo* pEntry = getResultCell(pRow, i, rowCellInfoOffset);
    cleanupResultRowEntry(pEntry);

L
Liu Jicong 已提交
2721
    pCtx[i].resultInfo = pEntry;
H
Haojun Liao 已提交
2722 2723 2724
    pCtx[i].currentStage = stage;

    // set the timestamp output buffer for top/bottom/diff query
L
Liu Jicong 已提交
2725 2726
    //    int32_t fid = pCtx[i].functionId;
    //    if (fid == FUNCTION_TOP || fid == FUNCTION_BOTTOM || fid == FUNCTION_DIFF || fid == FUNCTION_DERIVATIVE) {
H
Haojun Liao 已提交
2727
    //      if (i > 0) pCtx[i].pTsOutput = pCtx[i-1].pOutput;
L
Liu Jicong 已提交
2728
    //    }
H
Haojun Liao 已提交
2729 2730 2731 2732 2733
  }

  initCtxOutputBuffer(pCtx, pDataBlock->info.numOfCols);
}

L
Liu Jicong 已提交
2734
void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t* bufCapacity, int32_t numOfInputRows) {
2735 2736
  SSDataBlock* pDataBlock = pBInfo->pRes;

L
Liu Jicong 已提交
2737
  int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5;  // extra output buffer
2738
  if ((*bufCapacity) < newSize) {
L
Liu Jicong 已提交
2739 2740
    for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
2741

wafwerar's avatar
wafwerar 已提交
2742
      char* p = taosMemoryRealloc(pColInfo->pData, newSize * pColInfo->info.bytes);
2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755
      if (p != NULL) {
        pColInfo->pData = p;

        // it starts from the tail of the previously generated results.
        pBInfo->pCtx[i].pOutput = pColInfo->pData;
        (*bufCapacity) = newSize;
      } else {
        // longjmp
      }
    }
  }

  for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
L
Liu Jicong 已提交
2756
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
2757 2758 2759 2760 2761
    pBInfo->pCtx[i].pOutput = pColInfo->pData + pColInfo->info.bytes * pDataBlock->info.rows;

    // set the correct pointer after the memory buffer reallocated.
    int32_t functionId = pBInfo->pCtx[i].functionId;

L
Liu Jicong 已提交
2762 2763
    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
        functionId == FUNCTION_DERIVATIVE) {
dengyihao's avatar
dengyihao 已提交
2764
      //      if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
2765 2766 2767 2768
    }
  }
}

H
Haojun Liao 已提交
2769
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
2770 2771
  bool    needCopyTs = false;
  int32_t tsNum = 0;
L
Liu Jicong 已提交
2772
  char*   src = NULL;
2773 2774 2775 2776
  for (int32_t i = 0; i < numOfOutput; i++) {
    int32_t functionId = pCtx[i].functionId;
    if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) {
      needCopyTs = true;
L
Liu Jicong 已提交
2777 2778
      if (i > 0 && pCtx[i - 1].functionId == FUNCTION_TS_DUMMY) {
        SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1);  // find ts data
2779 2780
        src = pColRes->pData;
      }
L
Liu Jicong 已提交
2781
    } else if (functionId == FUNCTION_TS_DUMMY) {
2782 2783 2784 2785 2786 2787 2788 2789 2790 2791
      tsNum++;
    }
  }

  if (!needCopyTs) return;
  if (tsNum < 2) return;
  if (src == NULL) return;

  for (int32_t i = 0; i < numOfOutput; i++) {
    int32_t functionId = pCtx[i].functionId;
L
Liu Jicong 已提交
2792
    if (functionId == FUNCTION_TS_DUMMY) {
2793 2794 2795 2796 2797 2798
      SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i);
      memcpy(pColRes->pData, src, pColRes->info.bytes * pRes->info.rows);
    }
  }
}

H
Haojun Liao 已提交
2799
void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size) {
2800 2801
  for (int32_t j = 0; j < size; ++j) {
    struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
dengyihao's avatar
dengyihao 已提交
2802 2803
    if (isRowEntryInitialized(pResInfo) || fmIsPseudoColumnFunc(pCtx[j].functionId) || pCtx[j].functionId == -1 ||
        fmIsScalarFunc(pCtx[j].functionId)) {
2804 2805 2806
      continue;
    }

H
Haojun Liao 已提交
2807
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
2808 2809 2810
  }
}

L
Liu Jicong 已提交
2811
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
2812
  if (status == TASK_NOT_COMPLETED) {
H
Haojun Liao 已提交
2813
    pTaskInfo->status = status;
2814 2815
  } else {
    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
2816
    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
2817
    pTaskInfo->status |= status;
2818 2819 2820
  }
}

2821
// todo merged with the build group result.
L
Liu Jicong 已提交
2822 2823
void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf,
                                   SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) {
2824 2825 2826
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
    SResultRowPosition* pPos = &pResultRowInfo->pPosition[i];

L
Liu Jicong 已提交
2827
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pageId);
2828
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset);
H
Haojun Liao 已提交
2829 2830

    // TODO ignore the close status anyway.
dengyihao's avatar
dengyihao 已提交
2831 2832 2833
    //    if (!isResultRowClosed(pRow)) {
    //      continue;
    //    }
2834

2835
    for (int32_t j = 0; j < numOfOutput; ++j) {
2836 2837
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);

H
Haojun Liao 已提交
2838
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
H
Haojun Liao 已提交
2839
      if (!isRowEntryInitialized(pResInfo)) {
2840 2841 2842
        continue;
      }

H
Haojun Liao 已提交
2843
      if (pCtx[j].fpSet.process) {  // TODO set the dummy function, to avoid the check for null ptr.
dengyihao's avatar
dengyihao 已提交
2844
                                    //        pCtx[j].fpSet.finalize(&pCtx[j]);
H
Haojun Liao 已提交
2845
      }
2846 2847 2848 2849

      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
2850
    }
2851 2852 2853

    releaseBufPage(pBuf, bufPage);
  }
2854 2855
}

2856
// todo merged with the build group result.
2857 2858 2859 2860 2861
void finalizeUpdatedResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf, SArray* pUpdateList,
                           int32_t* rowCellInfoOffset) {
  size_t num = taosArrayGetSize(pUpdateList);

  for (int32_t i = 0; i < num; ++i) {
2862
    SResKeyPos * pPos = taosArrayGetP(pUpdateList, i);
2863

2864 2865 2866
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pos.pageId);
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->pos.offset);
//
2867 2868
    for (int32_t j = 0; j < numOfOutput; ++j) {
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);
2869
//
2870
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
2871 2872 2873 2874 2875 2876 2877 2878 2879
//      if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
//        continue;
//      }
//
//      if (pCtx[j].fpSet.process) {  // TODO set the dummy function.
////        pCtx[j].fpSet.finalize(&pCtx[j]);
//        pResInfo->initialized = true;
//      }
//
2880 2881 2882 2883 2884 2885 2886 2887 2888
      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
    }

    releaseBufPage(pBuf, bufPage);
  }
}

L
Liu Jicong 已提交
2889 2890
STableQueryInfo* createTableQueryInfo(void* buf, bool groupbyColumn, STimeWindow win) {
  STableQueryInfo* pTableQueryInfo = buf;
2891 2892 2893
  pTableQueryInfo->lastKey = win.skey;

  // set more initial size of interval/groupby query
L
Liu Jicong 已提交
2894 2895
  //  if (/*QUERY_IS_INTERVAL_QUERY(pQueryAttr) || */groupbyColumn) {
  int32_t initialSize = 128;
dengyihao's avatar
dengyihao 已提交
2896 2897 2898 2899
  //  int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize);
  //  if (code != TSDB_CODE_SUCCESS) {
  //    return NULL;
  //  }
L
Liu Jicong 已提交
2900 2901
  //  } else { // in other aggregate query, do not initialize the windowResInfo
  //  }
2902 2903 2904 2905

  return pTableQueryInfo;
}

L
Liu Jicong 已提交
2906
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
2907 2908 2909 2910
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2911
  //  taosVariantDestroy(&pTableQueryInfo->tag);
dengyihao's avatar
dengyihao 已提交
2912
  //  cleanupResultRowInfo(&pTableQueryInfo->resInfo);
2913 2914
}

dengyihao's avatar
dengyihao 已提交
2915 2916
void setResultRowOutputBufInitCtx_rv(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput,
                                     int32_t* rowCellInfoOffset) {
2917 2918 2919 2920 2921 2922 2923
  for (int32_t i = 0; i < numOfOutput; ++i) {
    pCtx[i].resultInfo = getResultCell(pResult, i, rowCellInfoOffset);

    struct SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo;
    if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
      continue;
    }
2924 2925 2926 2927 2928

    if (fmIsWindowPseudoColumnFunc(pCtx[i].functionId)) {
      continue;
    }

2929 2930 2931 2932 2933 2934
    if (!pResInfo->initialized) {
      if (pCtx[i].functionId != -1) {
        pCtx[i].fpSet.init(&pCtx[i], pResInfo);
      } else {
        pResInfo->initialized = true;
      }
2935 2936 2937 2938
    }
  }
}

2939 2940 2941 2942 2943 2944
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
  if (pFilterNode == NULL) {
    return;
  }

  SFilterInfo* filter = NULL;
H
Haojun Liao 已提交
2945

H
Haojun Liao 已提交
2946
  // todo move to the initialization function
H
Haojun Liao 已提交
2947
  int32_t code = filterInitFromNode((SNode*)pFilterNode, &filter, 0);
2948 2949 2950 2951 2952 2953

  SFilterColumnParam param1 = {.numOfCols = pBlock->info.numOfCols, .pDataBlock = pBlock->pDataBlock};
  code = filterSetDataFromSlotId(filter, &param1);

  int8_t* rowRes = NULL;
  bool    keep = filterExecute(filter, pBlock, &rowRes, NULL, param1.numOfCols);
D
dapan1121 已提交
2954
  filterFreeInfo(filter);
2955

2956
  SSDataBlock* px = createOneDataBlock(pBlock, false);
2957 2958
  blockDataEnsureCapacity(px, pBlock->info.rows);

H
Haojun Liao 已提交
2959
  // todo extract method
2960 2961 2962 2963
  int32_t numOfRow = 0;
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
    SColumnInfoData* pDst = taosArrayGet(px->pDataBlock, i);
    SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, i);
D
dapan1121 已提交
2964 2965 2966 2967 2968 2969 2970 2971 2972
    if (keep) {
      colDataAssign(pDst, pSrc, pBlock->info.rows);
      numOfRow = pBlock->info.rows;
    } else if (NULL != rowRes) {
      numOfRow = 0;
      for (int32_t j = 0; j < pBlock->info.rows; ++j) {
        if (rowRes[j] == 0) {
          continue;
        }
2973

D
dapan1121 已提交
2974 2975 2976 2977 2978 2979
        if (colDataIsNull_s(pSrc, j)) {
          colDataAppendNULL(pDst, numOfRow);
        } else {
          colDataAppend(pDst, numOfRow, colDataGetData(pSrc, j), false);
        }
        numOfRow += 1;
H
Haojun Liao 已提交
2980
      }
D
dapan1121 已提交
2981 2982
    } else {
      numOfRow = 0;
2983 2984 2985 2986 2987 2988
    }

    *pSrc = *pDst;
  }

  pBlock->info.rows = numOfRow;
2989
  blockDataUpdateTsWindow(pBlock);
2990 2991
}

dengyihao's avatar
dengyihao 已提交
2992 2993
void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId,
                              SExecTaskInfo* pTaskInfo) {
2994 2995 2996
  // for simple group by query without interval, all the tables belong to one group result.
  int64_t uid = 0;

2997 2998
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
2999
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
3000

3001
  SResultRow* pResultRow =
3002
      doSetResultOutBufByKey(pAggInfo->aggSup.pResultBuf, pResultRowInfo, uid, (char*)&groupId, sizeof(groupId),
H
Haojun Liao 已提交
3003
                                true, groupId, pTaskInfo, false, &pAggInfo->aggSup);
L
Liu Jicong 已提交
3004
  assert(pResultRow != NULL);
3005 3006 3007 3008 3009 3010

  /*
   * not assign result buffer yet, add new result buffer
   * all group belong to one result set, and each group result has different group id so set the id to be one
   */
  if (pResultRow->pageId == -1) {
dengyihao's avatar
dengyihao 已提交
3011 3012
    int32_t ret =
        addNewWindowResultBuf(pResultRow, pAggInfo->aggSup.pResultBuf, groupId, pAggInfo->binfo.pRes->info.rowSize);
3013 3014 3015 3016 3017
    if (ret != TSDB_CODE_SUCCESS) {
      return;
    }
  }

H
Haojun Liao 已提交
3018
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
3019 3020
}

H
Haojun Liao 已提交
3021 3022
void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* pTaskInfo, SAggOperatorInfo* pAggInfo) {
  if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
3023 3024 3025
    return;
  }

H
Haojun Liao 已提交
3026
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, groupId, pTaskInfo);
3027 3028

  // record the current active group id
H
Haojun Liao 已提交
3029
  pAggInfo->groupId = groupId;
3030 3031 3032 3033 3034
}

/*
 * There are two cases to handle:
 *
L
Liu Jicong 已提交
3035 3036
 * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including
 * pQueryAttr->lastKey, pQueryAttr->window.skey, and pQueryAttr->eKey.
3037 3038 3039 3040
 * 2. Query range is set and query is in progress. There may be another result with the same query ranges to be
 *    merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there
 *    is a previous result generated or not.
 */
3041
void setIntervalQueryRange(STableQueryInfo* pTableQueryInfo, TSKEY key, STimeWindow* pQRange) {
dengyihao's avatar
dengyihao 已提交
3042 3043 3044 3045
  //  SResultRowInfo*  pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->curPos != -1) {
  //    return;
  //  }
3046

dengyihao's avatar
dengyihao 已提交
3047 3048
  //  pTableQueryInfo->win.skey = key;
  //  STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
3049 3050 3051 3052 3053 3054 3055

  /**
   * In handling the both ascending and descending order super table query, we need to find the first qualified
   * timestamp of this table, and then set the first qualified start timestamp.
   * In ascending query, the key is the first qualified timestamp. However, in the descending order query, additional
   * operations involve.
   */
dengyihao's avatar
dengyihao 已提交
3056 3057 3058 3059
  //  STimeWindow w = TSWINDOW_INITIALIZER;
  //
  //  TSKEY sk = TMIN(win.skey, win.ekey);
  //  TSKEY ek = TMAX(win.skey, win.ekey);
L
Liu Jicong 已提交
3060
  //  getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w);
3061

L
Liu Jicong 已提交
3062 3063 3064 3065 3066 3067 3068
  //  if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
  //    if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
  //      assert(win.ekey == pQueryAttr->window.ekey);
  //    }
  //
  //    pResultRowInfo->prevSKey = w.skey;
  //  }
3069

L
Liu Jicong 已提交
3070
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080
}

/**
 * For interval query of both super table and table, copy the data in ascending order, since the output results are
 * ordered in SWindowResutl already. While handling the group by query for both table and super table,
 * all group result are completed already.
 *
 * @param pQInfo
 * @param result
 */
3081
int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo,
3082
                           int32_t orderType, int32_t* rowCellOffset, SqlFunctionCtx* pCtx) {
3083
  int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
L
Liu Jicong 已提交
3084
  int32_t numOfResult = pBlock->info.rows;  // there are already exists result rows
3085 3086 3087 3088

  int32_t start = 0;
  int32_t step = -1;

L
Liu Jicong 已提交
3089
  // qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100
  assert(orderType == TSDB_ORDER_ASC || orderType == TSDB_ORDER_DESC);

  if (orderType == TSDB_ORDER_ASC) {
    start = pGroupResInfo->index;
    step = 1;
  } else {  // desc order copy all data
    start = numOfRows - pGroupResInfo->index - 1;
    step = -1;
  }

  for (int32_t i = start; (i < numOfRows) && (i >= 0); i += step) {
3101 3102
    SResKeyPos *pPos = taosArrayGetP(pGroupResInfo->pRows, i);
    SFilePage*          page = getBufPage(pBuf, pPos->pos.pageId);
3103

3104
    SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
3105 3106 3107 3108 3109
    if (pRow->numOfRows == 0) {
      pGroupResInfo->index += 1;
      continue;
    }

3110
    // TODO copy multiple rows?
3111
    int32_t numOfRowsToCopy = pRow->numOfRows;
3112
    if (numOfResult + numOfRowsToCopy >= pBlock->info.capacity) {
3113 3114 3115 3116 3117 3118
      break;
    }

    pGroupResInfo->index += 1;

    for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) {
3119 3120
      int32_t slotId = pExprInfo[j].base.resSchema.slotId;

3121 3122
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
      if (pCtx[j].fpSet.process) {
3123
        pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
3124 3125
      } else {
        SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
3126

3127 3128 3129
        char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
        colDataAppend(pColInfoData, pBlock->info.rows, in, pCtx[j].resultInfo->isNullRes);
      }
3130 3131
    }

3132 3133
    releaseBufPage(pBuf, page);

3134 3135
    pBlock->info.rows += pRow->numOfRows;
    if (pBlock->info.rows >= pBlock->info.capacity) {  // output buffer is full
3136 3137 3138 3139
      break;
    }
  }

L
Liu Jicong 已提交
3140
  // qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
3141
  blockDataUpdateTsWindow(pBlock);
3142 3143 3144
  return 0;
}

dengyihao's avatar
dengyihao 已提交
3145 3146
void doBuildResultDatablock(SSDataBlock* pBlock, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo,
                            SDiskbasedBuf* pBuf, int32_t* rowCellOffset, SqlFunctionCtx* pCtx) {
3147 3148
  assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup);

3149
  blockDataCleanup(pBlock);
3150 3151 3152 3153
  if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
    return;
  }

3154
  int32_t orderType = TSDB_ORDER_ASC;
3155
  doCopyToSDataBlock(pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
3156

H
Haojun Liao 已提交
3157 3158
  // add condition (pBlock->info.rows >= 1) just to runtime happy
  blockDataUpdateTsWindow(pBlock);
3159 3160
}

L
Liu Jicong 已提交
3161 3162
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
                                        int32_t* rowCellInfoOffset) {
3163
  // update the number of result for each, only update the number of rows for the corresponding window result.
L
Liu Jicong 已提交
3164 3165 3166
  //  if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
  //    return;
  //  }
H
Haojun Liao 已提交
3167
#if 0
3168
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
L
Liu Jicong 已提交
3169
    SResultRow* pResult = pResultRowInfo->pResult[i];
3170 3171 3172 3173 3174 3175 3176

    for (int32_t j = 0; j < numOfOutput; ++j) {
      int32_t functionId = pCtx[j].functionId;
      if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
        continue;
      }

3177 3178
      SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
      pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
3179 3180
    }
  }
H
Haojun Liao 已提交
3181
#endif
3182 3183
}

L
Liu Jicong 已提交
3184
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
3185 3186
  int32_t colSize = pColRes->info.bytes * numOfRows;
  return (*(tDataTypes[pColRes->info.type].compFunc))(pColRes->pData, colSize, numOfRows, data,
L
Liu Jicong 已提交
3187
                                                      colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
3188 3189
}

L
Liu Jicong 已提交
3190 3191 3192 3193 3194
int32_t doFillTimeIntervalGapsInResults(struct SFillInfo* pFillInfo, SSDataBlock* pOutput, int32_t capacity, void** p) {
  //  for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
  //    SColumnInfoData* pColInfoData = taosArrayGet(pOutput->pDataBlock, i);
  //    p[i] = pColInfoData->pData + (pColInfoData->info.bytes * pOutput->info.rows);
  //  }
3195 3196 3197 3198 3199 3200 3201

  int32_t numOfRows = (int32_t)taosFillResultDataBlock(pFillInfo, p, capacity - pOutput->info.rows);
  pOutput->info.rows += numOfRows;

  return pOutput->info.rows;
}

3202
void publishOperatorProfEvent(SOperatorInfo* pOperator, EQueryProfEventType eventType) {
3203 3204
  SQueryProfEvent event = {0};

L
Liu Jicong 已提交
3205 3206
  event.eventType = eventType;
  event.eventTime = taosGetTimestampUs();
3207
  event.operatorType = pOperator->operatorType;
dengyihao's avatar
dengyihao 已提交
3208 3209 3210
  //    if (pQInfo->summary.queryProfEvents) {
  //      taosArrayPush(pQInfo->summary.queryProfEvents, &event);
  //    }
3211 3212
}

L
Liu Jicong 已提交
3213
void publishQueryAbortEvent(SExecTaskInfo* pTaskInfo, int32_t code) {
3214 3215 3216 3217 3218
  SQueryProfEvent event;
  event.eventType = QUERY_PROF_QUERY_ABORT;
  event.eventTime = taosGetTimestampUs();
  event.abortCode = code;

3219 3220
  if (pTaskInfo->cost.queryProfEvents) {
    taosArrayPush(pTaskInfo->cost.queryProfEvents, &event);
3221 3222 3223
  }
}

L
Liu Jicong 已提交
3224
typedef struct {
3225 3226 3227 3228 3229 3230 3231
  uint8_t operatorType;
  int64_t beginTime;
  int64_t endTime;
  int64_t selfTime;
  int64_t descendantsTime;
} SOperatorStackItem;

L
Liu Jicong 已提交
3232 3233
static void doOperatorExecProfOnce(SOperatorStackItem* item, SQueryProfEvent* event, SArray* opStack,
                                   SHashObj* profResults) {
3234 3235 3236 3237 3238 3239 3240 3241
  item->endTime = event->eventTime;
  item->selfTime = (item->endTime - item->beginTime) - (item->descendantsTime);

  for (int32_t j = 0; j < taosArrayGetSize(opStack); ++j) {
    SOperatorStackItem* ancestor = taosArrayGet(opStack, j);
    ancestor->descendantsTime += item->selfTime;
  }

L
Liu Jicong 已提交
3242
  uint8_t              operatorType = item->operatorType;
3243 3244 3245 3246 3247 3248 3249 3250 3251
  SOperatorProfResult* result = taosHashGet(profResults, &operatorType, sizeof(operatorType));
  if (result != NULL) {
    result->sumRunTimes++;
    result->sumSelfTime += item->selfTime;
  } else {
    SOperatorProfResult opResult;
    opResult.operatorType = operatorType;
    opResult.sumSelfTime = item->selfTime;
    opResult.sumRunTimes = 1;
L
Liu Jicong 已提交
3252
    taosHashPut(profResults, &(operatorType), sizeof(operatorType), &opResult, sizeof(opResult));
3253 3254 3255
  }
}

3256
void calculateOperatorProfResults(void) {
dengyihao's avatar
dengyihao 已提交
3257 3258 3259 3260 3261 3262 3263 3264 3265
  //  if (pQInfo->summary.queryProfEvents == NULL) {
  //    // qDebug("QInfo:0x%"PRIx64" query prof events array is null", pQInfo->qId);
  //    return;
  //  }
  //
  //  if (pQInfo->summary.operatorProfResults == NULL) {
  //    // qDebug("QInfo:0x%"PRIx64" operator prof results hash is null", pQInfo->qId);
  //    return;
  //  }
3266 3267 3268 3269 3270

  SArray* opStack = taosArrayInit(32, sizeof(SOperatorStackItem));
  if (opStack == NULL) {
    return;
  }
3271
#if 0
L
Liu Jicong 已提交
3272
  size_t    size = taosArrayGetSize(pQInfo->summary.queryProfEvents);
3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
  SHashObj* profResults = pQInfo->summary.operatorProfResults;

  for (int i = 0; i < size; ++i) {
    SQueryProfEvent* event = taosArrayGet(pQInfo->summary.queryProfEvents, i);
    if (event->eventType == QUERY_PROF_BEFORE_OPERATOR_EXEC) {
      SOperatorStackItem opItem;
      opItem.operatorType = event->operatorType;
      opItem.beginTime = event->eventTime;
      opItem.descendantsTime = 0;
      taosArrayPush(opStack, &opItem);
    } else if (event->eventType == QUERY_PROF_AFTER_OPERATOR_EXEC) {
      SOperatorStackItem* item = taosArrayPop(opStack);
      assert(item->operatorType == event->operatorType);
      doOperatorExecProfOnce(item, event, opStack, profResults);
    } else if (event->eventType == QUERY_PROF_QUERY_ABORT) {
      SOperatorStackItem* item;
      while ((item = taosArrayPop(opStack)) != NULL) {
        doOperatorExecProfOnce(item, event, opStack, profResults);
      }
    }
  }
3294
#endif
3295 3296 3297
  taosArrayDestroy(opStack);
}

L
Liu Jicong 已提交
3298 3299
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
3300

L
Liu Jicong 已提交
3301 3302 3303
  //  uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
  //  hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
  //  pSummary->hashSize = hashSize;
3304 3305 3306 3307

  // add the merge time
  pSummary->elapsedTime += pSummary->firstStageMergeTime;

L
Liu Jicong 已提交
3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327
  //  SResultRowPool* p = pTaskInfo->pool;
  //  if (p != NULL) {
  //    pSummary->winInfoSize = getResultRowPoolMemSize(p);
  //    pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
  //  } else {
  //    pSummary->winInfoSize = 0;
  //    pSummary->numOfTimeWindows = 0;
  //  }
  //
  //  calculateOperatorProfResults(pQInfo);

  qDebug("%s :cost summary: elapsed time:%" PRId64 " us, first merge:%" PRId64
         " us, total blocks:%d, "
         "load block statis:%d, load data block:%d, total rows:%" PRId64 ", check rows:%" PRId64,
         GET_TASKID(pTaskInfo), pSummary->elapsedTime, pSummary->firstStageMergeTime, pSummary->totalBlocks,
         pSummary->loadBlockStatis, pSummary->loadBlocks, pSummary->totalRows, pSummary->totalCheckedRows);
  //
  // qDebug("QInfo:0x%"PRIx64" :cost summary: winResPool size:%.2f Kb, numOfWin:%"PRId64", tableInfoSize:%.2f Kb,
  // hashTable:%.2f Kb", pQInfo->qId, pSummary->winInfoSize/1024.0,
  //      pSummary->numOfTimeWindows, pSummary->tableInfoSize/1024.0, pSummary->hashSize/1024.0);
3328 3329 3330 3331

  if (pSummary->operatorProfResults) {
    SOperatorProfResult* opRes = taosHashIterate(pSummary->operatorProfResults, NULL);
    while (opRes != NULL) {
L
Liu Jicong 已提交
3332 3333
      // qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
      //             pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
3334 3335 3336 3337 3338
      opRes = taosHashIterate(pSummary->operatorProfResults, opRes);
    }
  }
}

L
Liu Jicong 已提交
3339 3340 3341
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
3342
//
L
Liu Jicong 已提交
3343
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3344
//
L
Liu Jicong 已提交
3345 3346 3347 3348
//   if (pQueryAttr->limit.offset == pBlockInfo->rows) {  // current block will ignore completed
//     pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQueryAttr) ? pBlockInfo->window.ekey + step :
//     pBlockInfo->window.skey + step; pQueryAttr->limit.offset = 0; return;
//   }
3349
//
L
Liu Jicong 已提交
3350 3351 3352 3353 3354
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
//   } else {
//     pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
//   }
3355
//
L
Liu Jicong 已提交
3356
//   assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
3357
//
L
Liu Jicong 已提交
3358 3359
//   SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//   SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3360
//
L
Liu Jicong 已提交
3361 3362
//   // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
//   TSKEY *keys = (TSKEY *) pColInfoData->pData;
3363
//
L
Liu Jicong 已提交
3364 3365 3366
//   // update the offset value
//   pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
//   pQueryAttr->limit.offset = 0;
3367
//
L
Liu Jicong 已提交
3368
//   int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
3369
//
L
Liu Jicong 已提交
3370 3371 3372 3373
//   //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d,
//   lastKey:%"PRId64, GET_TASKID(pRuntimeEnv),
//          pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey);
// }
3374

L
Liu Jicong 已提交
3375 3376
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
3377
//
L
Liu Jicong 已提交
3378 3379 3380
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
//     return;
//   }
3381
//
L
Liu Jicong 已提交
3382 3383
//   pQueryAttr->pos = 0;
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3384
//
L
Liu Jicong 已提交
3385 3386
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//   TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
3387
//
L
Liu Jicong 已提交
3388 3389 3390 3391 3392
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pTsdbReadHandle)) {
//     if (isTaskKilled(pRuntimeEnv->qinfo)) {
//       longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
//     }
3393
//
L
Liu Jicong 已提交
3394
//     tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
3395
//
L
Liu Jicong 已提交
3396 3397 3398 3399
//     if (pQueryAttr->limit.offset > blockInfo.rows) {
//       pQueryAttr->limit.offset -= blockInfo.rows;
//       pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? blockInfo.window.ekey : blockInfo.window.skey;
//       pTableQueryInfo->lastKey += step;
3400
//
L
Liu Jicong 已提交
3401 3402 3403 3404 3405 3406 3407
//       //qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_TASKID(pRuntimeEnv), blockInfo.rows,
//              pQuery->limit.offset);
//     } else {  // find the appropriated start position in current block
//       updateOffsetVal(pRuntimeEnv, &blockInfo);
//       break;
//     }
//   }
3408
//
L
Liu Jicong 已提交
3409 3410 3411 3412 3413 3414 3415 3416 3417
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
// }

// static TSKEY doSkipIntervalProcess(STaskRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo,
// STableQueryInfo* pTableQueryInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
3418
//
L
Liu Jicong 已提交
3419 3420 3421
//   assert(pQueryAttr->limit.offset == 0);
//   STimeWindow tw = *win;
//   getNextTimeWindow(pQueryAttr, &tw);
3422
//
L
Liu Jicong 已提交
3423 3424
//   if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
//       (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
3425
//
L
Liu Jicong 已提交
3426 3427 3428 3429
//     // load the data block and check data remaining in current data block
//     // TODO optimize performance
//     SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//     SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3430
//
L
Liu Jicong 已提交
3431 3432 3433 3434
//     tw = *win;
//     int32_t startPos =
//         getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
//     assert(startPos >= 0);
3435
//
L
Liu Jicong 已提交
3436 3437
//     // set the abort info
//     pQueryAttr->pos = startPos;
3438
//
L
Liu Jicong 已提交
3439 3440 3441 3442
//     // reset the query start timestamp
//     pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
//     pQueryAttr->window.skey = pTableQueryInfo->win.skey;
//     TSKEY key = pTableQueryInfo->win.skey;
3443
//
L
Liu Jicong 已提交
3444 3445
//     pWindowResInfo->prevSKey = tw.skey;
//     int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
3446
//
L
Liu Jicong 已提交
3447 3448
//     int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//     pRuntimeEnv->resultRowInfo.curIndex = index;  // restore the window index
3449
//
L
Liu Jicong 已提交
3450 3451 3452 3453
//     //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d,
//     lastKey:%" PRId64,
//            GET_TASKID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes,
//            pQueryAttr->current->lastKey);
3454
//
L
Liu Jicong 已提交
3455 3456 3457 3458 3459
//     return key;
//   } else {  // do nothing
//     pQueryAttr->window.skey      = tw.skey;
//     pWindowResInfo->prevSKey = tw.skey;
//     pTableQueryInfo->lastKey = tw.skey;
3460
//
L
Liu Jicong 已提交
3461 3462
//     return tw.skey;
//   }
3463
//
L
Liu Jicong 已提交
3464 3465 3466 3467 3468 3469 3470 3471 3472 3473
//   return true;
// }

// static bool skipTimeInterval(STaskRuntimeEnv *pRuntimeEnv, TSKEY* start) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     assert(*start <= pRuntimeEnv->current->lastKey);
//   } else {
//     assert(*start >= pRuntimeEnv->current->lastKey);
//   }
3474
//
L
Liu Jicong 已提交
3475 3476 3477 3478 3479
//   // if queried with value filter, do NOT forward query start position
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL ||
//   pRuntimeEnv->pFillInfo != NULL) {
//     return true;
//   }
3480
//
L
Liu Jicong 已提交
3481 3482 3483 3484 3485 3486 3487
//   /*
//    * 1. for interval without interpolation query we forward pQueryAttr->interval.interval at a time for
//    *    pQueryAttr->limit.offset times. Since hole exists, pQueryAttr->interval.interval*pQueryAttr->limit.offset
//    value is
//    *    not valid. otherwise, we only forward pQueryAttr->limit.offset number of points
//    */
//   assert(pRuntimeEnv->resultRowInfo.prevSKey == TSKEY_INITIAL_VAL);
3488
//
L
Liu Jicong 已提交
3489 3490
//   STimeWindow w = TSWINDOW_INITIALIZER;
//   bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
3491
//
L
Liu Jicong 已提交
3492 3493
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//   STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
3494
//
L
Liu Jicong 已提交
3495 3496 3497
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
//     tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
3498
//
L
Liu Jicong 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507
//     if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//       if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) {
//         getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.skey, blockInfo.window.skey, pQueryAttr->window.ekey,
//         &w); pWindowResInfo->prevSKey = w.skey;
//       }
//     } else {
//       getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.ekey, pQueryAttr->window.ekey, blockInfo.window.ekey, &w);
//       pWindowResInfo->prevSKey = w.skey;
//     }
3508
//
L
Liu Jicong 已提交
3509 3510
//     // the first time window
//     STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
3511
//
L
Liu Jicong 已提交
3512 3513
//     while (pQueryAttr->limit.offset > 0) {
//       STimeWindow tw = win;
3514
//
L
Liu Jicong 已提交
3515 3516 3517
//       if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
//         pQueryAttr->limit.offset -= 1;
//         pWindowResInfo->prevSKey = win.skey;
3518
//
L
Liu Jicong 已提交
3519 3520 3521 3522 3523 3524
//         // current time window is aligned with blockInfo.window.ekey
//         // restart it from next data block by set prevSKey to be TSKEY_INITIAL_VAL;
//         if ((win.ekey == blockInfo.window.ekey && ascQuery) || (win.ekey == blockInfo.window.skey && !ascQuery)) {
//           pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
//         }
//       }
3525
//
L
Liu Jicong 已提交
3526 3527 3528 3529
//       if (pQueryAttr->limit.offset == 0) {
//         *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//         return true;
//       }
3530
//
L
Liu Jicong 已提交
3531 3532
//       // current window does not ended in current data block, try next data block
//       getNextTimeWindow(pQueryAttr, &tw);
3533
//
L
Liu Jicong 已提交
3534 3535 3536 3537 3538 3539 3540 3541 3542
//       /*
//        * If the next time window still starts from current data block,
//        * load the primary timestamp column first, and then find the start position for the next queried time window.
//        * Note that only the primary timestamp column is required.
//        * TODO: Optimize for this cases. All data blocks are not needed to be loaded, only if the first actually
//        required
//        * time window resides in current data block.
//        */
//       if ((tw.skey <= blockInfo.window.ekey && ascQuery) || (tw.ekey >= blockInfo.window.skey && !ascQuery)) {
3543
//
L
Liu Jicong 已提交
3544 3545
//         SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//         SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3546
//
L
Liu Jicong 已提交
3547 3548 3549
//         if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
//           pQueryAttr->limit.offset -= 1;
//         }
3550
//
L
Liu Jicong 已提交
3551 3552 3553 3554 3555 3556 3557 3558
//         if (pQueryAttr->limit.offset == 0) {
//           *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//           return true;
//         } else {
//           tw = win;
//           int32_t startPos =
//               getNextQualifiedWindow(pQueryAttr, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1);
//           assert(startPos >= 0);
3559
//
L
Liu Jicong 已提交
3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570
//           // set the abort info
//           pQueryAttr->pos = startPos;
//           pTableQueryInfo->lastKey = ((TSKEY *)pColInfoData->pData)[startPos];
//           pWindowResInfo->prevSKey = tw.skey;
//           win = tw;
//         }
//       } else {
//         break;  // offset is not 0, and next time window begins or ends in the next block.
//       }
//     }
//   }
3571
//
L
Liu Jicong 已提交
3572 3573 3574 3575
//   // check for error
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
3576
//
L
Liu Jicong 已提交
3577 3578
//   return true;
// }
3579

3580
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
H
Haojun Liao 已提交
3581
  if (p->pDownstream == NULL) {
H
Haojun Liao 已提交
3582
    assert(p->numOfDownstream == 0);
3583 3584
  }

wafwerar's avatar
wafwerar 已提交
3585
  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
3586 3587 3588 3589 3590 3591 3592
  if (p->pDownstream == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
3593 3594 3595 3596
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);

3597
static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) {
H
Haojun Liao 已提交
3598 3599
#if 0
    if (order == TSDB_ORDER_ASC) {
3600 3601
    assert(
        (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
3602 3603
        (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey));
3604 3605 3606
  } else {
    assert(
        (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
3607 3608
        (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey));
3609
  }
H
Haojun Liao 已提交
3610
#endif
3611 3612
}

3613 3614
// SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
//   SQueryTableDataCond cond = {
L
Liu Jicong 已提交
3615 3616 3617 3618 3619 3620
//       .colList   = pQueryAttr->tableCols,
//       .order     = pQueryAttr->order.order,
//       .numOfCols = pQueryAttr->numOfCols,
//       .type      = BLOCK_LOAD_OFFSET_SEQ_ORDER,
//       .loadExternalRows = false,
//   };
3621
//
L
Liu Jicong 已提交
3622 3623 3624
//   TIME_WINDOW_COPY(cond.twindow, *win);
//   return cond;
// }
3625 3626 3627

static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo) {
  STableIdInfo tidInfo;
L
Liu Jicong 已提交
3628 3629 3630 3631 3632
  //  STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
  //
  //  tidInfo.uid = id->uid;
  //  tidInfo.tid = id->tid;
  //  tidInfo.key = pTableQueryInfo->lastKey;
3633 3634 3635 3636

  return tidInfo;
}

L
Liu Jicong 已提交
3637 3638 3639 3640
// static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBlock, SHashObj* pTableIdInfo, int32_t
// order) {
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
//   pTableQueryInfo->lastKey = ((order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey) + step;
3641
//
L
Liu Jicong 已提交
3642 3643 3644
//   if (pTableQueryInfo->pTable == NULL) {
//     return;
//   }
3645
//
L
Liu Jicong 已提交
3646 3647 3648 3649 3650 3651 3652 3653 3654
//   STableIdInfo tidInfo = createTableIdInfo(pTableQueryInfo);
//   STableIdInfo *idinfo = taosHashGet(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid));
//   if (idinfo != NULL) {
//     assert(idinfo->tid == tidInfo.tid && idinfo->uid == tidInfo.uid);
//     idinfo->key = tidInfo.key;
//   } else {
//     taosHashPut(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid), &tidInfo, sizeof(STableIdInfo));
//   }
// }
3655

3656
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
L
Liu Jicong 已提交
3657
  SSourceDataInfo* pSourceDataInfo = (SSourceDataInfo*)param;
H
Haojun Liao 已提交
3658 3659
  if (code == TSDB_CODE_SUCCESS) {
    pSourceDataInfo->pRsp = pMsg->pData;
3660

H
Haojun Liao 已提交
3661 3662
    SRetrieveTableRsp* pRsp = pSourceDataInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
dengyihao's avatar
dengyihao 已提交
3663 3664
    pRsp->compLen = htonl(pRsp->compLen);
    pRsp->useconds = htobe64(pRsp->useconds);
H
Haojun Liao 已提交
3665 3666 3667
  } else {
    pSourceDataInfo->code = code;
  }
H
Haojun Liao 已提交
3668

H
Haojun Liao 已提交
3669
  pSourceDataInfo->status = EX_SOURCE_DATA_READY;
3670
  tsem_post(&pSourceDataInfo->pEx->ready);
wmmhello's avatar
wmmhello 已提交
3671
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
3672 3673 3674 3675
}

static void destroySendMsgInfo(SMsgSendInfo* pMsgBody) {
  assert(pMsgBody != NULL);
wafwerar's avatar
wafwerar 已提交
3676 3677
  taosMemoryFreeClear(pMsgBody->msgInfo.pData);
  taosMemoryFreeClear(pMsgBody);
H
Haojun Liao 已提交
3678 3679
}

S
Shengliang Guan 已提交
3680
void qProcessFetchRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
L
Liu Jicong 已提交
3681
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->ahandle;
H
Haojun Liao 已提交
3682 3683 3684 3685 3686
  assert(pMsg->ahandle != NULL);

  SDataBuf buf = {.len = pMsg->contLen, .pData = NULL};

  if (pMsg->contLen > 0) {
wafwerar's avatar
wafwerar 已提交
3687
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
H
Haojun Liao 已提交
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698
    if (buf.pData == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      pMsg->code = TSDB_CODE_OUT_OF_MEMORY;
    } else {
      memcpy(buf.pData, pMsg->pCont, pMsg->contLen);
    }
  }

  pSendInfo->fp(pSendInfo->param, &buf, pMsg->code);
  rpcFreeCont(pMsg->pCont);
  destroySendMsgInfo(pSendInfo);
3699 3700
}

L
Liu Jicong 已提交
3701
static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTaskInfo, int32_t sourceIndex) {
3702
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3703

wafwerar's avatar
wafwerar 已提交
3704
  SResFetchReq* pMsg = taosMemoryCalloc(1, sizeof(SResFetchReq));
3705 3706 3707 3708
  if (NULL == pMsg) {
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
  }
3709

L
Liu Jicong 已提交
3710 3711
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
3712

L
Liu Jicong 已提交
3713 3714
  qDebug("%s build fetch msg and send to vgId:%d, ep:%s, taskId:0x%" PRIx64 ", %d/%" PRIzu, GET_TASKID(pTaskInfo),
         pSource->addr.nodeId, pSource->addr.epSet.eps[0].fqdn, pSource->taskId, sourceIndex, totalSources);
3715 3716 3717 3718 3719 3720 3721

  pMsg->header.vgId = htonl(pSource->addr.nodeId);
  pMsg->sId = htobe64(pSource->schedId);
  pMsg->taskId = htobe64(pSource->taskId);
  pMsg->queryId = htobe64(pTaskInfo->id.queryId);

  // send the fetch remote task result reques
wafwerar's avatar
wafwerar 已提交
3722
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
3723
  if (NULL == pMsgSendInfo) {
wafwerar's avatar
wafwerar 已提交
3724
    taosMemoryFreeClear(pMsg);
3725 3726 3727
    qError("%s prepare message %d failed", GET_TASKID(pTaskInfo), (int32_t)sizeof(SMsgSendInfo));
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
H
Haojun Liao 已提交
3728 3729
  }

3730 3731 3732 3733 3734
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
3735

3736
  int64_t transporterId = 0;
L
Liu Jicong 已提交
3737
  int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
3738 3739 3740
  return TSDB_CODE_SUCCESS;
}

3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766
// NOTE: sources columns are more than the destination SSDatablock columns.
static void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
  size_t numOfSrcCols = taosArrayGetSize(pCols);
  ASSERT(numOfSrcCols >= pBlock->info.numOfCols);

  int32_t i = 0, j = 0;
  while(i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
    SColumnInfoData* p = taosArrayGet(pCols, i);
    SColMatchInfo*   pmInfo = taosArrayGet(pColMatchInfo, j);
    if (!pmInfo->output) {
      j++;
      continue;
    }

    if (p->info.colId == pmInfo->colId) {
      taosArraySet(pBlock->pDataBlock, pmInfo->targetSlotId, p);
      i++;
      j++;
    } else if (p->info.colId < pmInfo->colId) {
      i++;
    } else {
      ASSERT(0);
    }
  }
}

3767
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
dengyihao's avatar
dengyihao 已提交
3768 3769
                                  int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
                                  SArray* pColList) {
H
Haojun Liao 已提交
3770
  blockDataEnsureCapacity(pRes, numOfRows);
3771

H
Haojun Liao 已提交
3772
  if (pColList == NULL) {  // data from other sources
3773 3774 3775 3776 3777 3778
    int32_t dataLen = *(int32_t*) pData;
    pData += sizeof(int32_t);

    pRes->info.groupId = *(uint64_t*) pData;
    pData += sizeof(uint64_t);

H
Haojun Liao 已提交
3779 3780
    int32_t* colLen = (int32_t*)pData;

3781
    char* pStart = pData + sizeof(int32_t) * numOfOutput;
3782
    for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
3783
      colLen[i] = htonl(colLen[i]);
3784
      ASSERT(colLen[i] >= 0);
H
Haojun Liao 已提交
3785

3786
      SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
H
Haojun Liao 已提交
3787 3788 3789
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
        pColInfoData->varmeta.length = colLen[i];
        pColInfoData->varmeta.allocLen = colLen[i];
3790

L
Liu Jicong 已提交
3791 3792
        memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
        pStart += sizeof(int32_t) * numOfRows;
H
Haojun Liao 已提交
3793

3794 3795 3796
        if (colLen[i] > 0) {
          pColInfoData->pData = taosMemoryMalloc(colLen[i]);
        }
H
Haojun Liao 已提交
3797 3798 3799
      } else {
        memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
        pStart += BitmapLen(numOfRows);
3800
      }
H
Haojun Liao 已提交
3801

3802 3803 3804 3805
      if (colLen[i] > 0) {
        memcpy(pColInfoData->pData, pStart, colLen[i]);
      }

3806 3807 3808
      //TODO setting this flag to true temporarily so aggregate function on stable will
      //examine NULL value for non-primary key column
      pColInfoData->hasNull = true;
H
Haojun Liao 已提交
3809
      pStart += colLen[i];
3810
    }
H
Haojun Liao 已提交
3811
  } else {  // extract data according to pColList
3812
    ASSERT(numOfOutput == taosArrayGetSize(pColList));
3813 3814 3815 3816 3817
    char* pStart = pData;

    int32_t numOfCols = htonl(*(int32_t*)pStart);
    pStart += sizeof(int32_t);

3818
    // todo refactor:extract method
3819
    SSysTableSchema* pSchema = (SSysTableSchema*)pStart;
dengyihao's avatar
dengyihao 已提交
3820
    for (int32_t i = 0; i < numOfCols; ++i) {
3821 3822 3823 3824 3825 3826 3827 3828
      SSysTableSchema* p = (SSysTableSchema*)pStart;

      p->colId = htons(p->colId);
      p->bytes = htonl(p->bytes);
      pStart += sizeof(SSysTableSchema);
    }

    SSDataBlock block = {.pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData)), .info.numOfCols = numOfCols};
dengyihao's avatar
dengyihao 已提交
3829
    for (int32_t i = 0; i < numOfCols; ++i) {
3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842
      SColumnInfoData idata = {0};
      idata.info.type = pSchema[i].type;
      idata.info.bytes = pSchema[i].bytes;
      idata.info.colId = pSchema[i].colId;

      taosArrayPush(block.pDataBlock, &idata);
      if (IS_VAR_DATA_TYPE(idata.info.type)) {
        block.info.hasVarCol = true;
      }
    }

    blockDataEnsureCapacity(&block, numOfRows);

3843 3844 3845 3846 3847
    int32_t dataLen = *(int32_t*) pStart;
    uint64_t groupId = *(uint64_t*) (pStart + sizeof(int32_t));
    pStart += sizeof(int32_t) + sizeof(uint64_t);

    int32_t* colLen = (int32_t*) (pStart);
3848 3849 3850 3851
    pStart += sizeof(int32_t) * numOfCols;

    for (int32_t i = 0; i < numOfCols; ++i) {
      colLen[i] = htonl(colLen[i]);
3852
      ASSERT(colLen[i] >= 0);
3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870

      SColumnInfoData* pColInfoData = taosArrayGet(block.pDataBlock, i);
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
        pColInfoData->varmeta.length = colLen[i];
        pColInfoData->varmeta.allocLen = colLen[i];

        memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
        pStart += sizeof(int32_t) * numOfRows;

        pColInfoData->pData = taosMemoryMalloc(colLen[i]);
      } else {
        memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
        pStart += BitmapLen(numOfRows);
      }

      memcpy(pColInfoData->pData, pStart, colLen[i]);
      pStart += colLen[i];
    }
H
Haojun Liao 已提交
3871 3872

    // data from mnode
3873
    relocateColumnData(pRes,  pColList, block.pDataBlock);
3874
  }
3875

H
Haojun Liao 已提交
3876
  pRes->info.rows = numOfRows;
3877
  blockDataUpdateTsWindow(pRes);
3878

3879
  int64_t el = taosGetTimestampUs() - startTs;
3880

H
Haojun Liao 已提交
3881 3882
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
3883

H
Haojun Liao 已提交
3884 3885 3886
  if (total != NULL) {
    *total += numOfRows;
  }
3887

H
Haojun Liao 已提交
3888
  pLoadInfo->totalElapsed += el;
3889 3890
  return TSDB_CODE_SUCCESS;
}
3891

L
Liu Jicong 已提交
3892 3893
static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
3894
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3895

L
Liu Jicong 已提交
3896
  int64_t              el = taosGetTimestampUs() - startTs;
H
Haojun Liao 已提交
3897 3898
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
  pLoadInfo->totalElapsed += el;
H
Haojun Liao 已提交
3899

3900
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
L
Liu Jicong 已提交
3901 3902 3903
  qDebug("%s all %" PRIzu " sources are exhausted, total rows: %" PRIu64 " bytes:%" PRIu64 ", elapsed:%.2f ms",
         GET_TASKID(pTaskInfo), totalSources, pLoadInfo->totalRows, pLoadInfo->totalSize,
         pLoadInfo->totalElapsed / 1000.0);
3904 3905 3906 3907 3908

  doSetOperatorCompleted(pOperator);
  return NULL;
}

L
Liu Jicong 已提交
3909 3910
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
                                                   SExecTaskInfo* pTaskInfo) {
3911 3912 3913 3914 3915 3916 3917 3918 3919
  int32_t code = 0;
  int64_t startTs = taosGetTimestampUs();
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);

  while (1) {
    int32_t completed = 0;
    for (int32_t i = 0; i < totalSources; ++i) {
      SSourceDataInfo* pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, i);

3920
      if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
3921
        completed += 1;
H
Haojun Liao 已提交
3922 3923
        continue;
      }
3924

3925
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
3926 3927 3928
        continue;
      }

L
Liu Jicong 已提交
3929
      SRetrieveTableRsp*     pRsp = pDataInfo->pRsp;
X
Xiaoyu Wang 已提交
3930
      SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, i);
3931

L
Liu Jicong 已提交
3932
      SSDataBlock*         pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
3933
      SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
3934
      if (pRsp->numOfRows == 0) {
L
Liu Jicong 已提交
3935 3936
        qDebug("%s vgId:%d, taskID:0x%" PRIx64 " index:%d completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
               " try next",
3937
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, i + 1, pDataInfo->totalRows,
H
Haojun Liao 已提交
3938
               pExchangeInfo->loadInfo.totalRows);
3939
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3940 3941 3942
        completed += 1;
        continue;
      }
H
Haojun Liao 已提交
3943

H
Haojun Liao 已提交
3944
      SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
3945 3946 3947
      code =
          setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                    pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
3948
      if (code != 0) {
3949 3950 3951
        goto _error;
      }

3952 3953 3954
      if (pRsp->completed == 1) {
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, rowsOfSource:%" PRIu64
               ", totalRows:%" PRIu64 ", totalBytes:%" PRIu64 " try next %d/%" PRIzu,
L
Liu Jicong 已提交
3955 3956
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
               pLoadInfo->totalRows, pLoadInfo->totalSize, i + 1, totalSources);
3957
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3958
      } else {
dengyihao's avatar
dengyihao 已提交
3959 3960
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64
               ", totalBytes:%" PRIu64,
H
Haojun Liao 已提交
3961 3962
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
               pLoadInfo->totalSize);
3963 3964
      }

3965 3966
      if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED) {
        pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985
        code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
        if (code != TSDB_CODE_SUCCESS) {
          goto _error;
        }
      }

      return pExchangeInfo->pResult;
    }

    if (completed == totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
    }
  }

_error:
  pTaskInfo->code = code;
  return NULL;
}

L
Liu Jicong 已提交
3986 3987 3988
static SSDataBlock* concurrentlyLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3989

H
Haojun Liao 已提交
3990 3991 3992
  if (pOperator->status == OP_RES_TO_RETURN) {
    return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
  }
3993

L
Liu Jicong 已提交
3994
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3995 3996 3997
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
3998
  for (int32_t i = 0; i < totalSources; ++i) {
3999 4000
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4001
      return NULL;
4002 4003 4004 4005
    }
  }

  int64_t endTs = taosGetTimestampUs();
L
Liu Jicong 已提交
4006 4007
  qDebug("%s send all fetch request to %" PRIzu " sources completed, elapsed:%" PRId64, GET_TASKID(pTaskInfo),
         totalSources, endTs - startTs);
4008 4009

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
4010 4011
  pOperator->status = OP_RES_TO_RETURN;
  return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
4012 4013
}

L
Liu Jicong 已提交
4014 4015 4016
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4017

L
Liu Jicong 已提交
4018
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4019 4020 4021
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
4022
  for (int32_t i = 0; i < totalSources; ++i) {
4023 4024
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4025 4026
      pTaskInfo->code = code;
      return code;
4027 4028 4029 4030
    }
  }

  int64_t endTs = taosGetTimestampUs();
L
Liu Jicong 已提交
4031 4032
  qDebug("%s send all fetch request to %" PRIzu " sources completed, elapsed:%" PRId64, GET_TASKID(pTaskInfo),
         totalSources, endTs - startTs);
4033 4034

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
4035
  pOperator->cost.openCost = taosGetTimestampUs() - startTs;
4036

H
Haojun Liao 已提交
4037
  return TSDB_CODE_SUCCESS;
4038 4039
}

L
Liu Jicong 已提交
4040 4041 4042
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4043

L
Liu Jicong 已提交
4044
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4045
  int64_t startTs = taosGetTimestampUs();
4046

L
Liu Jicong 已提交
4047
  while (1) {
4048 4049
    if (pExchangeInfo->current >= totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
4050
    }
4051

4052 4053 4054
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

dengyihao's avatar
dengyihao 已提交
4055
    SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, pExchangeInfo->current);
X
Xiaoyu Wang 已提交
4056
    SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, pExchangeInfo->current);
4057

H
Haojun Liao 已提交
4058
    if (pDataInfo->code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
dengyihao 已提交
4059 4060
      qError("%s vgId:%d, taskID:0x%" PRIx64 " error happens, code:%s", GET_TASKID(pTaskInfo), pSource->addr.nodeId,
             pSource->taskId, tstrerror(pDataInfo->code));
H
Haojun Liao 已提交
4061 4062 4063 4064
      pOperator->pTaskInfo->code = pDataInfo->code;
      return NULL;
    }

L
Liu Jicong 已提交
4065
    SRetrieveTableRsp*   pRsp = pDataInfo->pRsp;
H
Haojun Liao 已提交
4066
    SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
4067
    if (pRsp->numOfRows == 0) {
dengyihao's avatar
dengyihao 已提交
4068 4069
      qDebug("%s vgId:%d, taskID:0x%" PRIx64 " %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
             " try next",
4070
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
H
Haojun Liao 已提交
4071
             pDataInfo->totalRows, pLoadInfo->totalRows);
H
Haojun Liao 已提交
4072

4073
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4074 4075 4076
      pExchangeInfo->current += 1;
      continue;
    }
H
Haojun Liao 已提交
4077

L
Liu Jicong 已提交
4078
    SSDataBlock*       pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
4079
    SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
4080 4081 4082
    int32_t            code =
        setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                  pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
4083 4084

    if (pRsp->completed == 1) {
H
Haojun Liao 已提交
4085
      qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, rowsOfSource:%" PRIu64
L
Liu Jicong 已提交
4086 4087 4088
             ", totalRows:%" PRIu64 ", totalBytes:%" PRIu64 " try next %d/%" PRIzu,
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
             pLoadInfo->totalRows, pLoadInfo->totalSize, pExchangeInfo->current + 1, totalSources);
4089

4090
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4091 4092
      pExchangeInfo->current += 1;
    } else {
L
Liu Jicong 已提交
4093 4094 4095 4096
      qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64
             ", totalBytes:%" PRIu64,
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
             pLoadInfo->totalSize);
4097 4098 4099 4100
    }

    return pExchangeInfo->pResult;
  }
4101 4102
}

L
Liu Jicong 已提交
4103
static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
4104
  if (OPTR_IS_OPENED(pOperator)) {
H
Haojun Liao 已提交
4105 4106 4107
    return TSDB_CODE_SUCCESS;
  }

L
Liu Jicong 已提交
4108
  SExchangeInfo* pExchangeInfo = pOperator->info;
H
Haojun Liao 已提交
4109 4110 4111 4112 4113 4114 4115 4116 4117
  if (pExchangeInfo->seqLoadData) {
    // do nothing for sequentially load data
  } else {
    int32_t code = prepareConcurrentlyLoad(pOperator);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

4118
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
4119 4120 4121
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4122 4123 4124
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4125

4126
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
4127
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4128 4129
    return NULL;
  }
4130

L
Liu Jicong 已提交
4131
  size_t               totalSources = taosArrayGetSize(pExchangeInfo->pSources);
H
Haojun Liao 已提交
4132
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
H
Haojun Liao 已提交
4133

4134
  if (pOperator->status == OP_EXEC_DONE) {
L
Liu Jicong 已提交
4135 4136 4137
    qDebug("%s all %" PRIzu " source(s) are exhausted, total rows:%" PRIu64 " bytes:%" PRIu64 ", elapsed:%.2f ms",
           GET_TASKID(pTaskInfo), totalSources, pLoadInfo->totalRows, pLoadInfo->totalSize,
           pLoadInfo->totalElapsed / 1000.0);
4138 4139 4140 4141
    return NULL;
  }

  *newgroup = false;
H
Haojun Liao 已提交
4142

4143 4144 4145
  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
4146
    return concurrentlyLoadRemoteData(pOperator);
4147
  }
H
Haojun Liao 已提交
4148

4149
#if 0
H
Haojun Liao 已提交
4150
  _error:
wafwerar's avatar
wafwerar 已提交
4151 4152
  taosMemoryFreeClear(pMsg);
  taosMemoryFreeClear(pMsgSendInfo);
H
Haojun Liao 已提交
4153 4154 4155

  terrno = pTaskInfo->code;
  return NULL;
4156
#endif
H
Haojun Liao 已提交
4157
}
4158

H
Haojun Liao 已提交
4159
static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
4160
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
H
Haojun Liao 已提交
4161 4162
  if (pInfo->pSourceDataInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
4163 4164
  }

L
Liu Jicong 已提交
4165
  for (int32_t i = 0; i < numOfSources; ++i) {
4166
    SSourceDataInfo dataInfo = {0};
H
Haojun Liao 已提交
4167
    dataInfo.status = EX_SOURCE_DATA_NOT_READY;
L
Liu Jicong 已提交
4168 4169
    dataInfo.pEx = pInfo;
    dataInfo.index = i;
4170

H
Haojun Liao 已提交
4171 4172 4173 4174 4175 4176 4177 4178 4179 4180
    void* ret = taosArrayPush(pInfo->pSourceDataInfo, &dataInfo);
    if (ret == NULL) {
      taosArrayDestroy(pInfo->pSourceDataInfo);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
4181
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
4182
  SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
wafwerar's avatar
wafwerar 已提交
4183
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4184 4185

  if (pInfo == NULL || pOperator == NULL) {
wafwerar's avatar
wafwerar 已提交
4186 4187
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4188 4189
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
H
Haojun Liao 已提交
4190 4191
  }

H
Haojun Liao 已提交
4192
  size_t numOfSources = LIST_LENGTH(pSources);
H
Haojun Liao 已提交
4193
  pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
H
Haojun Liao 已提交
4194 4195 4196
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
  if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
    goto _error;
H
Haojun Liao 已提交
4197 4198
  }

L
Liu Jicong 已提交
4199 4200
  for (int32_t i = 0; i < numOfSources; ++i) {
    SNodeListNode* pNode = nodesListGetNode((SNodeList*)pSources, i);
H
Haojun Liao 已提交
4201 4202
    taosArrayPush(pInfo->pSources, pNode);
  }
4203

H
Haojun Liao 已提交
4204 4205 4206
  int32_t code = initDataSource(numOfSources, pInfo);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4207
  }
H
Haojun Liao 已提交
4208

dengyihao's avatar
dengyihao 已提交
4209
  pInfo->pResult = pBlock;
4210 4211 4212
  pInfo->seqLoadData = true;

  tsem_init(&pInfo->ready, 0, 0);
4213

dengyihao's avatar
dengyihao 已提交
4214
  pOperator->name = "ExchangeOperator";
X
Xiaoyu Wang 已提交
4215
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
4216
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
4217 4218 4219 4220
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = pBlock->info.numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
4221 4222 4223

  pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL, destroyExchangeOperatorInfo,
                                         NULL, NULL, NULL);
4224

S
Shengliang Guan 已提交
4225
#if 1
L
Liu Jicong 已提交
4226
  {  // todo refactor
H
Haojun Liao 已提交
4227 4228 4229
    SRpcInit rpcInit;
    memset(&rpcInit, 0, sizeof(rpcInit));
    rpcInit.localPort = 0;
H
Haojun Liao 已提交
4230
    rpcInit.label = "EX";
H
Haojun Liao 已提交
4231
    rpcInit.numOfThreads = 1;
S
Shengliang Guan 已提交
4232
    rpcInit.cfp = qProcessFetchRsp;
S
Shengliang Guan 已提交
4233
    rpcInit.sessions = tsMaxConnections;
H
Haojun Liao 已提交
4234
    rpcInit.connType = TAOS_CONN_CLIENT;
L
Liu Jicong 已提交
4235
    rpcInit.user = (char*)"root";
S
Shengliang Guan 已提交
4236
    rpcInit.idleTime = tsShellActivityTimer * 1000;
H
Haojun Liao 已提交
4237
    rpcInit.ckey = "key";
S
Shengliang Guan 已提交
4238
    rpcInit.spi = 1;
L
Liu Jicong 已提交
4239
    rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
H
Haojun Liao 已提交
4240 4241 4242

    pInfo->pTransporter = rpcOpen(&rpcInit);
    if (pInfo->pTransporter == NULL) {
L
Liu Jicong 已提交
4243
      return NULL;  // todo
H
Haojun Liao 已提交
4244 4245
    }
  }
S
Shengliang 已提交
4246
#endif
4247

4248
  return pOperator;
H
Haojun Liao 已提交
4249

L
Liu Jicong 已提交
4250
_error:
H
Haojun Liao 已提交
4251
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4252
    destroyExchangeOperatorInfo(pInfo, numOfSources);
H
Haojun Liao 已提交
4253 4254
  }

wafwerar's avatar
wafwerar 已提交
4255 4256
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4257
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
4258
  return NULL;
4259 4260
}

dengyihao's avatar
dengyihao 已提交
4261 4262
static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                                const char* pKey);
H
Haojun Liao 已提交
4263
static void    cleanupAggSup(SAggSupporter* pAggSup);
4264

4265
static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4266
  SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*)param;
H
Haojun Liao 已提交
4267
  taosArrayDestroy(pInfo->pSortInfo);
4268 4269 4270
  taosArrayDestroy(pInfo->groupInfo);

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
4271
    tsortDestroySortHandle(pInfo->pSortHandle);
4272 4273
  }

H
Haojun Liao 已提交
4274
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
4275
  cleanupAggSup(&pInfo->aggSup);
4276
}
H
Haojun Liao 已提交
4277

X
Xiaoyu Wang 已提交
4278 4279
static void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
  assert(dst != NULL && src != NULL);
4280

X
Xiaoyu Wang 已提交
4281
  *dst = *src;
4282

X
Xiaoyu Wang 已提交
4283
  dst->pExpr = exprdup(src->pExpr);
wafwerar's avatar
wafwerar 已提交
4284
  dst->base.pParam = taosMemoryCalloc(src->base.numOfParams, sizeof(SColumn));
H
Haojun Liao 已提交
4285
  memcpy(dst->base.pParam, src->base.pParam, sizeof(SColumn) * src->base.numOfParams);
4286

L
Liu Jicong 已提交
4287 4288 4289 4290
  //  memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
  //  for (int32_t j = 0; j < src->base.numOfParams; ++j) {
  //    taosVariantAssign(&dst->base.param[j], &src->base.param[j]);
  //  }
X
Xiaoyu Wang 已提交
4291
}
4292

H
Haojun Liao 已提交
4293
// TODO merge aggregate super table
L
Liu Jicong 已提交
4294
static void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle) {
4295 4296
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
4297

H
Haojun Liao 已提交
4298
    bool isNull = tsortIsNullVal(pTupleHandle, i);
H
Haojun Liao 已提交
4299 4300 4301
    if (isNull) {
      colDataAppend(pColInfo, pBlock->info.rows, NULL, true);
    } else {
H
Haojun Liao 已提交
4302
      char* pData = tsortGetValue(pTupleHandle, i);
H
Haojun Liao 已提交
4303 4304
      colDataAppend(pColInfo, pBlock->info.rows, pData, false);
    }
4305 4306
  }

4307 4308
  pBlock->info.rows += 1;
}
4309

H
Haojun Liao 已提交
4310
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity) {
4311
  blockDataCleanup(pDataBlock);
D
dapan1121 已提交
4312
  blockDataEnsureCapacity(pDataBlock, capacity);
4313

wmmhello's avatar
wmmhello 已提交
4314 4315
  blockDataEnsureCapacity(pDataBlock, capacity);

L
Liu Jicong 已提交
4316
  while (1) {
H
Haojun Liao 已提交
4317
    STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4318 4319 4320
    if (pTupleHandle == NULL) {
      break;
    }
4321

4322 4323 4324
    appendOneRowToDataBlock(pDataBlock, pTupleHandle);
    if (pDataBlock->info.rows >= capacity) {
      return pDataBlock;
H
Haojun Liao 已提交
4325 4326
    }
  }
4327

L
Liu Jicong 已提交
4328
  return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
4329
}
4330

4331
SSDataBlock* loadNextDataBlock(void* param) {
L
Liu Jicong 已提交
4332 4333
  SOperatorInfo* pOperator = (SOperatorInfo*)param;
  bool           newgroup = false;
4334
  return pOperator->fpSet.getNextFn(pOperator, &newgroup);
4335 4336
}

L
Liu Jicong 已提交
4337
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
4338 4339 4340 4341
  size_t size = taosArrayGetSize(groupInfo);
  if (size == 0) {
    return true;
  }
4342

4343 4344
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
4345

4346
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, *index);
L
Liu Jicong 已提交
4347
    bool             isNull = colDataIsNull(pColInfo, rowIndex, pBlock->info.rows, NULL);
4348

4349 4350 4351
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
4352

4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365
    char* pCell = colDataGetData(pColInfo, rowIndex);
    if (IS_VAR_DATA_TYPE(pColInfo->info.type)) {
      if (varDataLen(pCell) != varDataLen(buf[i])) {
        return false;
      } else {
        if (memcmp(varDataVal(pCell), varDataVal(buf[i]), varDataLen(pCell)) != 0) {
          return false;
        }
      }
    } else {
      if (memcmp(pCell, buf[i], pColInfo->info.bytes) != 0) {
        return false;
      }
4366 4367 4368
    }
  }

4369
  return 0;
4370 4371
}

L
Liu Jicong 已提交
4372 4373 4374
static void doMergeResultImpl(SSortedMergeOperatorInfo* pInfo, SqlFunctionCtx* pCtx, int32_t numOfExpr,
                              int32_t rowIndex) {
  for (int32_t j = 0; j < numOfExpr; ++j) {  // TODO set row index
4375
    pCtx[j].startRow = rowIndex;
4376 4377
  }

4378 4379
  for (int32_t j = 0; j < numOfExpr; ++j) {
    int32_t functionId = pCtx[j].functionId;
L
Liu Jicong 已提交
4380 4381 4382 4383 4384 4385 4386 4387 4388
    //    pCtx[j].fpSet->addInput(&pCtx[j]);

    //    if (functionId < 0) {
    //      SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
    //      doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
    //    } else {
    //      assert(!TSDB_FUNC_IS_SCALAR(functionId));
    //      aAggs[functionId].mergeFunc(&pCtx[j]);
    //    }
4389
  }
4390
}
4391

L
Liu Jicong 已提交
4392 4393
static void doFinalizeResultImpl(SqlFunctionCtx* pCtx, int32_t numOfExpr) {
  for (int32_t j = 0; j < numOfExpr; ++j) {
4394 4395 4396 4397
    int32_t functionId = pCtx[j].functionId;
    //    if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
    //      continue;
    //    }
4398

4399 4400 4401 4402
    //    if (functionId < 0) {
    //      SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
    //      doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
    //    } else {
dengyihao's avatar
dengyihao 已提交
4403
    //    pCtx[j].fpSet.finalize(&pCtx[j]);
4404 4405
  }
}
4406

4407
static bool saveCurrentTuple(char** rowColData, SArray* pColumnList, SSDataBlock* pBlock, int32_t rowIndex) {
L
Liu Jicong 已提交
4408
  int32_t size = (int32_t)taosArrayGetSize(pColumnList);
4409

L
Liu Jicong 已提交
4410 4411
  for (int32_t i = 0; i < size; ++i) {
    int32_t*         index = taosArrayGet(pColumnList, i);
4412
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, *index);
H
Haojun Liao 已提交
4413

4414 4415 4416
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
4417

4418 4419
  return true;
}
4420

4421 4422
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
4423

4424
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
L
Liu Jicong 已提交
4425
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
4426 4427
    pCtx[i].size = 1;
  }
4428

L
Liu Jicong 已提交
4429
  for (int32_t i = 0; i < pBlock->info.rows; ++i) {
4430 4431 4432 4433 4434 4435 4436 4437 4438
    if (!pInfo->hasGroupVal) {
      ASSERT(i == 0);
      doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
      pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
    } else {
      if (needToMerge(pBlock, pInfo->groupInfo, pInfo->groupVal, i)) {
        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
      } else {
        doFinalizeResultImpl(pCtx, numOfExpr);
H
Haojun Liao 已提交
4439
        int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4440
        //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4441

4442
        // TODO check for available buffer;
H
Haojun Liao 已提交
4443

4444 4445 4446 4447 4448
        // next group info data
        pInfo->binfo.pRes->info.rows += numOfRows;
        for (int32_t j = 0; j < numOfExpr; ++j) {
          if (pCtx[j].functionId < 0) {
            continue;
4449
          }
4450

H
Haojun Liao 已提交
4451
          pCtx[j].fpSet.process(&pCtx[j]);
4452
        }
4453 4454 4455

        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
        pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
H
Haojun Liao 已提交
4456
      }
4457 4458 4459 4460
    }
  }
}

4461 4462
static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
4463
  SSortHandle*              pHandle = pInfo->pSortHandle;
4464

4465
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes, false);
4466
  blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
4467

L
Liu Jicong 已提交
4468
  while (1) {
4469
    blockDataCleanup(pDataBlock);
4470
    while (1) {
H
Haojun Liao 已提交
4471
      STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4472 4473
      if (pTupleHandle == NULL) {
        break;
4474
      }
4475

4476 4477
      // build datablock for merge for one group
      appendOneRowToDataBlock(pDataBlock, pTupleHandle);
4478
      if (pDataBlock->info.rows >= pOperator->resultInfo.capacity) {
4479 4480
        break;
      }
4481
    }
4482

4483 4484 4485
    if (pDataBlock->info.rows == 0) {
      break;
    }
4486

4487
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, true);
L
Liu Jicong 已提交
4488 4489
    //  updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
    //  pOperator->pRuntimeEnv, true);
4490 4491 4492
    doMergeImpl(pOperator, pOperator->numOfOutput, pDataBlock);
    // flush to tuple store, and after all data have been handled, return to upstream node or sink node
  }
4493

4494
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
4495
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4496
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4497

4498
  // TODO check for available buffer;
4499

4500 4501
  // next group info data
  pInfo->binfo.pRes->info.rows += numOfRows;
L
Liu Jicong 已提交
4502
  return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
4503
}
4504

L
Liu Jicong 已提交
4505
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator, bool* newgroup) {
4506 4507
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
4508 4509
  }

L
Liu Jicong 已提交
4510
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
4511
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
4512
  if (pOperator->status == OP_RES_TO_RETURN) {
4513
    return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity);
4514 4515
  }

4516
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
dengyihao's avatar
dengyihao 已提交
4517 4518
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, NULL, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize,
                                             numOfBufPage, pInfo->binfo.pRes, "GET_TASKID(pTaskInfo)");
H
Haojun Liao 已提交
4519

H
Haojun Liao 已提交
4520
  tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock);
4521

L
Liu Jicong 已提交
4522
  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
wmmhello's avatar
wmmhello 已提交
4523
    SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
H
Haojun Liao 已提交
4524
    ps->param = pOperator->pDownstream[i];
H
Haojun Liao 已提交
4525
    tsortAddSource(pInfo->pSortHandle, ps);
4526 4527
  }

H
Haojun Liao 已提交
4528
  int32_t code = tsortOpen(pInfo->pSortHandle);
4529
  if (code != TSDB_CODE_SUCCESS) {
4530
    longjmp(pTaskInfo->env, terrno);
4531 4532
  }

H
Haojun Liao 已提交
4533
  pOperator->status = OP_RES_TO_RETURN;
4534
  return doMerge(pOperator);
4535
}
4536

L
Liu Jicong 已提交
4537 4538
static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo,
                            SSortedMergeOperatorInfo* pInfo) {
4539 4540
  if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) {
    return 0;
H
Haojun Liao 已提交
4541 4542
  }

4543 4544 4545 4546 4547 4548 4549 4550
  int32_t len = 0;
  SArray* plist = taosArrayInit(3, sizeof(SColumn));
  pInfo->groupInfo = taosArrayInit(3, sizeof(int32_t));

  if (plist == NULL || pInfo->groupInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

L
Liu Jicong 已提交
4551 4552
  size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo);
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4553
    SColumn* pCol = taosArrayGet(pGroupInfo, i);
L
Liu Jicong 已提交
4554
    for (int32_t j = 0; j < numOfCols; ++j) {
H
Haojun Liao 已提交
4555
      SExprInfo* pe = &pExprInfo[j];
4556
      if (pe->base.resSchema.slotId == pCol->colId) {
4557 4558
        taosArrayPush(plist, pCol);
        taosArrayPush(pInfo->groupInfo, &j);
H
Haojun Liao 已提交
4559
        len += pCol->bytes;
4560 4561
        break;
      }
H
Haojun Liao 已提交
4562 4563 4564
    }
  }

4565
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
4566

wafwerar's avatar
wafwerar 已提交
4567
  pInfo->groupVal = taosMemoryCalloc(1, (POINTER_BYTES * numOfGroupCol + len));
4568 4569 4570 4571
  if (pInfo->groupVal == NULL) {
    taosArrayDestroy(plist);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
4572

4573
  int32_t offset = 0;
L
Liu Jicong 已提交
4574 4575
  char*   start = (char*)(pInfo->groupVal + (POINTER_BYTES * numOfGroupCol));
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4576 4577
    pInfo->groupVal[i] = start + offset;
    SColumn* pCol = taosArrayGet(plist, i);
H
Haojun Liao 已提交
4578
    offset += pCol->bytes;
4579
  }
H
Haojun Liao 已提交
4580

4581
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
4582

4583 4584
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
4585

L
Liu Jicong 已提交
4586 4587 4588
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                             int32_t num, SArray* pSortInfo, SArray* pGroupInfo,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4589
  SSortedMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortedMergeOperatorInfo));
L
Liu Jicong 已提交
4590
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
4591
  if (pInfo == NULL || pOperator == NULL) {
4592
    goto _error;
4593
  }
H
Haojun Liao 已提交
4594

4595
  pInfo->binfo.pCtx = createSqlFunctionCtx(pExprInfo, num, &pInfo->binfo.rowCellInfoOffset);
4596
  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
H
Haojun Liao 已提交
4597

4598 4599 4600
  if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
4601

dengyihao's avatar
dengyihao 已提交
4602
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
4603
  int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, keyBufSize, pTaskInfo->id.str);
4604 4605 4606
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4607

H
Haojun Liao 已提交
4608
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
H
Haojun Liao 已提交
4609
  code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo);
4610 4611 4612
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4613

L
Liu Jicong 已提交
4614 4615 4616 4617 4618
  //  pInfo->resultRowFactor = (int32_t)(getRowNumForMultioutput(pRuntimeEnv->pQueryAttr,
  //      pRuntimeEnv->pQueryAttr->topBotQuery, false));
  pInfo->sortBufSize = 1024 * 16;  // 1MB
  pInfo->bufPageSize = 1024;
  pInfo->pSortInfo = pSortInfo;
H
Haojun Liao 已提交
4619

4620
  pOperator->resultInfo.capacity = blockDataGetCapacityInRow(pInfo->binfo.pRes, pInfo->bufPageSize);
H
Haojun Liao 已提交
4621

L
Liu Jicong 已提交
4622
  pOperator->name = "SortedMerge";
X
Xiaoyu Wang 已提交
4623
  // pOperator->operatorType = OP_SortedMerge;
4624
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
4625 4626 4627 4628
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = num;
  pOperator->pExpr = pExprInfo;
H
Haojun Liao 已提交
4629

L
Liu Jicong 已提交
4630
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
4631

4632 4633
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSortedMerge, NULL, NULL, destroySortedMergeOperatorInfo,
                                         NULL, NULL, NULL);
4634 4635 4636
  code = appendDownstream(pOperator, downstream, numOfDownstream);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4637
  }
H
Haojun Liao 已提交
4638

4639
  return pOperator;
H
Haojun Liao 已提交
4640

L
Liu Jicong 已提交
4641
_error:
4642
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4643
    destroySortedMergeOperatorInfo(pInfo, num);
H
Haojun Liao 已提交
4644 4645
  }

wafwerar's avatar
wafwerar 已提交
4646 4647
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
4648 4649
  terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
  return NULL;
H
Haojun Liao 已提交
4650 4651
}

L
Liu Jicong 已提交
4652
static SSDataBlock* doSort(SOperatorInfo* pOperator, bool* newgroup) {
4653 4654 4655 4656
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

L
Liu Jicong 已提交
4657
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
4658 4659
  SSortOperatorInfo* pInfo = pOperator->info;

H
Haojun Liao 已提交
4660
  if (pOperator->status == OP_RES_TO_RETURN) {
H
Haojun Liao 已提交
4661
    return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
H
Haojun Liao 已提交
4662 4663
  }

4664
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
dengyihao's avatar
dengyihao 已提交
4665 4666
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, pInfo->inputSlotMap, SORT_SINGLESOURCE_SORT,
                                             pInfo->bufPageSize, numOfBufPage, pInfo->pDataBlock, pTaskInfo->id.str);
4667

H
Haojun Liao 已提交
4668
  tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock);
H
Haojun Liao 已提交
4669

wmmhello's avatar
wmmhello 已提交
4670
  SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
H
Haojun Liao 已提交
4671
  ps->param = pOperator->pDownstream[0];
H
Haojun Liao 已提交
4672
  tsortAddSource(pInfo->pSortHandle, ps);
4673

H
Haojun Liao 已提交
4674
  int32_t code = tsortOpen(pInfo->pSortHandle);
4675
  taosMemoryFreeClear(ps);
4676
  if (code != TSDB_CODE_SUCCESS) {
4677
    longjmp(pTaskInfo->env, terrno);
4678
  }
4679

H
Haojun Liao 已提交
4680
  pOperator->status = OP_RES_TO_RETURN;
H
Haojun Liao 已提交
4681
  return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
4682 4683
}

dengyihao's avatar
dengyihao 已提交
4684 4685
SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo,
                                      SArray* pIndexMap, SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
4686
  SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo));
L
Liu Jicong 已提交
4687
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
dengyihao's avatar
dengyihao 已提交
4688
  int32_t            rowSize = pResBlock->info.rowSize;
4689 4690

  if (pInfo == NULL || pOperator == NULL || rowSize > 100 * 1024 * 1024) {
wafwerar's avatar
wafwerar 已提交
4691 4692
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4693 4694 4695
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
  }
4696

dengyihao's avatar
dengyihao 已提交
4697
  pInfo->bufPageSize = rowSize < 1024 ? 1024 * 2 : rowSize * 2;  // there are headers, so pageSize = rowSize + header
4698

wmmhello's avatar
wmmhello 已提交
4699
  pInfo->sortBufSize = pInfo->bufPageSize * 16;  // TODO dynamic set the available sort buffer
L
Liu Jicong 已提交
4700 4701 4702
  pInfo->numOfRowsInRes = 1024;
  pInfo->pDataBlock = pResBlock;
  pInfo->pSortInfo = pSortInfo;
4703
  pInfo->inputSlotMap = pIndexMap;
H
Haojun Liao 已提交
4704

dengyihao's avatar
dengyihao 已提交
4705
  pOperator->name = "SortOperator";
L
Liu Jicong 已提交
4706 4707
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
4708 4709
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
4710

dengyihao's avatar
dengyihao 已提交
4711
  pOperator->pTaskInfo = pTaskInfo;
4712 4713
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSort, NULL, NULL, destroyOrderOperatorInfo,
                                         NULL, NULL, NULL);
4714

4715
  int32_t code = appendDownstream(pOperator, &downstream, 1);
4716
  return pOperator;
H
Haojun Liao 已提交
4717

dengyihao's avatar
dengyihao 已提交
4718
_error:
H
Haojun Liao 已提交
4719 4720 4721 4722
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  return NULL;
4723 4724
}

4725 4726
int32_t getTableScanOrder(SOperatorInfo* pOperator) {
  if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
H
Haojun Liao 已提交
4727
    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
4728
      return TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4729 4730
    } else {
      return getTableScanOrder(pOperator->pDownstream[0]);
4731 4732 4733 4734 4735 4736
    }
  }

  STableScanInfo* pTableScanInfo = pOperator->info;
  return pTableScanInfo->cond.order;
}
4737 4738

// this is a blocking operator
L
Liu Jicong 已提交
4739
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
4740 4741
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
4742 4743
  }

H
Haojun Liao 已提交
4744
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
4745
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
4746

dengyihao's avatar
dengyihao 已提交
4747
  SOptrBasicInfo* pInfo = &pAggInfo->binfo;
4748

H
Haojun Liao 已提交
4749
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4750
  SOperatorInfo* downstream = pOperator->pDownstream[0];
4751

H
Haojun Liao 已提交
4752 4753
  bool newgroup = true;
  while (1) {
H
Haojun Liao 已提交
4754
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
4755
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
4756
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
4757 4758 4759 4760

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
4761 4762 4763
    //    if (pAggInfo->current != NULL) {
    //      setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
4764

4765 4766
    // there is an scalar expression that needs to be calculated before apply the group aggregation.
    if (pAggInfo->pScalarExprInfo != NULL) {
dengyihao's avatar
dengyihao 已提交
4767 4768
      projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, pAggInfo->numOfScalarExpr,
                            NULL);
4769 4770
    }

4771
    // the pDataBlock are always the same one, no need to call this again
H
Haojun Liao 已提交
4772
    setExecutionContext(pOperator->numOfOutput, pBlock->info.groupId, pTaskInfo, pAggInfo);
4773
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, true);
H
Haojun Liao 已提交
4774
    doAggregateImpl(pOperator, 0, pInfo->pCtx);
4775

dengyihao's avatar
dengyihao 已提交
4776
#if 0  // test for encode/decode result info
4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787
    if(pOperator->encodeResultRow){
      char *result = NULL;
      int32_t length = 0;
      SAggSupporter   *pSup = &pAggInfo->aggSup;
      pOperator->encodeResultRow(pOperator, pSup, pInfo, &result, &length);
      taosHashClear(pSup->pResultRowHashTable);
      pInfo->resultRowInfo.size = 0;
      pOperator->decodeResultRow(pOperator, pSup, pInfo, result, length);
      if(result){
        taosMemoryFree(result);
      }
4788
    }
4789
#endif
4790 4791
  }

H
Haojun Liao 已提交
4792 4793 4794
  closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pAggInfo->binfo.pCtx, pOperator->numOfOutput, pAggInfo->aggSup.pResultBuf,
                                &pAggInfo->binfo.resultRowInfo, pAggInfo->binfo.rowCellInfoOffset);
H
Haojun Liao 已提交
4795

4796
  initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, false);
H
Haojun Liao 已提交
4797 4798 4799 4800
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4801 4802
static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup) {
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
4803 4804 4805 4806 4807 4808
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;

  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

L
Liu Jicong 已提交
4809
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4810
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
H
Haojun Liao 已提交
4811 4812 4813 4814
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
    return NULL;
  }

H
Haojun Liao 已提交
4815
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
4816 4817
  doBuildResultDatablock(pInfo->pRes, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf,
                         pInfo->rowCellInfoOffset, pInfo->pCtx);
H
Haojun Liao 已提交
4818 4819 4820
  if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
4821

H
Haojun Liao 已提交
4822
  doSetOperatorCompleted(pOperator);
L
Liu Jicong 已提交
4823
  return (blockDataGetNumOfRows(pInfo->pRes) != 0) ? pInfo->pRes : NULL;
4824 4825
}

dengyihao's avatar
dengyihao 已提交
4826 4827
void aggEncodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char** result,
                        int32_t* length) {
wmmhello's avatar
wmmhello 已提交
4828
  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
4829
  size_t  keyLen = sizeof(uint64_t) * 2;  // estimate the key length
wmmhello's avatar
wmmhello 已提交
4830
  int32_t totalSize = sizeof(int32_t) + size * (sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize);
wafwerar's avatar
wafwerar 已提交
4831
  *result = taosMemoryCalloc(1, totalSize);
L
Liu Jicong 已提交
4832
  if (*result == NULL) {
4833
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
wmmhello's avatar
wmmhello 已提交
4834 4835 4836
  }
  *(int32_t*)(*result) = size;
  int32_t offset = sizeof(int32_t);
4837 4838

  // prepare memory
4839
  SResultRowPosition* pos = &pInfo->resultRowInfo.cur;
dengyihao's avatar
dengyihao 已提交
4840 4841
  void*               pPage = getBufPage(pSup->pResultBuf, pos->pageId);
  SResultRow*         pRow = (SResultRow*)((char*)pPage + pos->offset);
4842 4843 4844
  setBufPageDirty(pPage, true);
  releaseBufPage(pSup->pResultBuf, pPage);

dengyihao's avatar
dengyihao 已提交
4845
  void* pIter = taosHashIterate(pSup->pResultRowHashTable, NULL);
wmmhello's avatar
wmmhello 已提交
4846
  while (pIter) {
dengyihao's avatar
dengyihao 已提交
4847
    void*               key = taosHashGetKey(pIter, &keyLen);
4848
    SResultRowPosition* p1 = (SResultRowPosition*)pIter;
4849

dengyihao's avatar
dengyihao 已提交
4850
    pPage = (SFilePage*)getBufPage(pSup->pResultBuf, p1->pageId);
4851
    pRow = (SResultRow*)((char*)pPage + p1->offset);
4852 4853
    setBufPageDirty(pPage, true);
    releaseBufPage(pSup->pResultBuf, pPage);
wmmhello's avatar
wmmhello 已提交
4854 4855 4856

    // recalculate the result size
    int32_t realTotalSize = offset + sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize;
L
Liu Jicong 已提交
4857 4858 4859
    if (realTotalSize > totalSize) {
      char* tmp = taosMemoryRealloc(*result, realTotalSize);
      if (tmp == NULL) {
wmmhello's avatar
wmmhello 已提交
4860
        terrno = TSDB_CODE_OUT_OF_MEMORY;
wafwerar's avatar
wafwerar 已提交
4861
        taosMemoryFree(*result);
wmmhello's avatar
wmmhello 已提交
4862
        *result = NULL;
4863
        longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
L
Liu Jicong 已提交
4864
      } else {
wmmhello's avatar
wmmhello 已提交
4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876
        *result = tmp;
      }
    }
    // save key
    *(int32_t*)(*result + offset) = keyLen;
    offset += sizeof(int32_t);
    memcpy(*result + offset, key, keyLen);
    offset += keyLen;

    // save value
    *(int32_t*)(*result + offset) = pSup->resultRowSize;
    offset += sizeof(int32_t);
4877
    memcpy(*result + offset, pRow, pSup->resultRowSize);
wmmhello's avatar
wmmhello 已提交
4878 4879 4880 4881 4882
    offset += pSup->resultRowSize;

    pIter = taosHashIterate(pSup->pResultRowHashTable, pIter);
  }

L
Liu Jicong 已提交
4883
  if (length) {
wmmhello's avatar
wmmhello 已提交
4884 4885 4886 4887 4888
    *length = offset;
  }
  return;
}

dengyihao's avatar
dengyihao 已提交
4889 4890
bool aggDecodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char* result,
                        int32_t length) {
L
Liu Jicong 已提交
4891
  if (!result || length <= 0) {
wmmhello's avatar
wmmhello 已提交
4892 4893 4894 4895 4896 4897 4898
    return false;
  }

  //  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
  int32_t count = *(int32_t*)(result);

  int32_t offset = sizeof(int32_t);
L
Liu Jicong 已提交
4899
  while (count-- > 0 && length > offset) {
wmmhello's avatar
wmmhello 已提交
4900 4901 4902
    int32_t keyLen = *(int32_t*)(result + offset);
    offset += sizeof(int32_t);

L
Liu Jicong 已提交
4903 4904 4905
    uint64_t    tableGroupId = *(uint64_t*)(result + offset);
    SResultRow* resultRow = getNewResultRow_rv(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
    if (!resultRow) {
4906
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4907
    }
4908

wmmhello's avatar
wmmhello 已提交
4909
    // add a new result set for a new group
4910 4911
    SResultRowPosition pos = {.pageId = resultRow->pageId, .offset = resultRow->offset};
    taosHashPut(pSup->pResultRowHashTable, result + offset, keyLen, &pos, sizeof(SResultRowPosition));
wmmhello's avatar
wmmhello 已提交
4912 4913 4914

    offset += keyLen;
    int32_t valueLen = *(int32_t*)(result + offset);
L
Liu Jicong 已提交
4915
    if (valueLen != pSup->resultRowSize) {
4916
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4917 4918 4919 4920 4921 4922 4923 4924 4925 4926
    }
    offset += sizeof(int32_t);
    int32_t pageId = resultRow->pageId;
    int32_t pOffset = resultRow->offset;
    memcpy(resultRow, result + offset, valueLen);
    resultRow->pageId = pageId;
    resultRow->offset = pOffset;
    offset += valueLen;

    initResultRow(resultRow);
4927
    prepareResultListBuffer(&pInfo->resultRowInfo, pOperator->pTaskInfo->env);
dengyihao's avatar
dengyihao 已提交
4928
    //    pInfo->resultRowInfo.cur = pInfo->resultRowInfo.size;
4929 4930
//    pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
//        (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
dengyihao's avatar
dengyihao 已提交
4931
    pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
wmmhello's avatar
wmmhello 已提交
4932 4933
  }

L
Liu Jicong 已提交
4934
  if (offset != length) {
4935
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4936 4937 4938 4939
  }
  return true;
}

4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996
enum {
  PROJECT_RETRIEVE_CONTINUE = 0x1,
  PROJECT_RETRIEVE_DONE     = 0x2,
};

static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
  SSDataBlock* pRes = pInfo->pRes;

  if (pProjectInfo->curSOffset > 0) {
    if (pProjectInfo->groupId == 0) {  // it is the first group
      pProjectInfo->groupId = pBlock->info.groupId;
      blockDataCleanup(pInfo->pRes);
      return PROJECT_RETRIEVE_CONTINUE;
    } else if (pProjectInfo->groupId != pBlock->info.groupId) {
      pProjectInfo->curSOffset -= 1;

      // ignore data block in current group
      if (pProjectInfo->curSOffset > 0) {
        blockDataCleanup(pInfo->pRes);
        return PROJECT_RETRIEVE_CONTINUE;
      }
    }

    // set current group id of the project operator
    pProjectInfo->groupId = pBlock->info.groupId;
  }

  if (pProjectInfo->groupId != 0 && pProjectInfo->groupId != pBlock->info.groupId) {
    pProjectInfo->curGroupOutput += 1;
    if ((pProjectInfo->slimit.limit > 0) && (pProjectInfo->slimit.limit <= pProjectInfo->curGroupOutput)) {
      pOperator->status = OP_EXEC_DONE;
      blockDataCleanup(pRes);

      return PROJECT_RETRIEVE_DONE;
    }

    // reset the value for a new group data
    pProjectInfo->curOffset = 0;
    pProjectInfo->curOutput = 0;
  }

  // here we reach the start position, according to the limit/offset requirements.

  // set current group id
  pProjectInfo->groupId = pBlock->info.groupId;

  if (pProjectInfo->curOffset >= pRes->info.rows) {
    pProjectInfo->curOffset -= pRes->info.rows;
    blockDataCleanup(pRes);
    return PROJECT_RETRIEVE_CONTINUE;
  } else if (pProjectInfo->curOffset < pRes->info.rows && pProjectInfo->curOffset > 0) {
    blockDataTrimFirstNRows(pRes, pProjectInfo->curOffset);
    pProjectInfo->curOffset = 0;
  }

4997 4998 4999 5000
  // check for the limitation in each group
  if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) {
    pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput);
  }
5001

5002
  if (pRes->info.rows >= pOperator->resultInfo.threshold) {
5003 5004 5005 5006 5007 5008
    return PROJECT_RETRIEVE_DONE;
  } else { // not full enough, continue to accumulate the output data in the buffer.
    return PROJECT_RETRIEVE_CONTINUE;
  }
}

L
Liu Jicong 已提交
5009
static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup) {
5010
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
L
Liu Jicong 已提交
5011
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
5012 5013

  SSDataBlock* pRes = pInfo->pRes;
5014
  blockDataCleanup(pRes);
5015 5016 5017 5018

  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
5019

H
Haojun Liao 已提交
5020
#if 0
5021 5022 5023 5024 5025 5026
  if (pProjectInfo->existDataBlock) {  // TODO refactor
    SSDataBlock* pBlock = pProjectInfo->existDataBlock;
    pProjectInfo->existDataBlock = NULL;
    *newgroup = true;

    // todo dynamic set tags
L
Liu Jicong 已提交
5027 5028 5029
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5030 5031

    // the pDataBlock are always the same one, no need to call this again
H
Haojun Liao 已提交
5032
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC);
5033

H
Haojun Liao 已提交
5034
    blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
5035
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
L
Liu Jicong 已提交
5036
    if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
5037 5038 5039 5040 5041
      copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
      resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
      return pRes;
    }
  }
H
Haojun Liao 已提交
5042
#endif
5043

H
Haojun Liao 已提交
5044 5045
  SOperatorInfo* downstream = pOperator->pDownstream[0];

L
Liu Jicong 已提交
5046
  while (1) {
5047 5048
    bool prevVal = *newgroup;

H
Haojun Liao 已提交
5049
    // The downstream exec may change the value of the newgroup, so use a local variable instead.
H
Haojun Liao 已提交
5050
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5051
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5052
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5053 5054 5055

    if (pBlock == NULL) {
      *newgroup = prevVal;
5056
      setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5057 5058 5059 5060 5061 5062 5063 5064
      break;
    }

    // Return result of the previous group in the firstly.
    if (*newgroup) {
      if (pRes->info.rows > 0) {
        pProjectInfo->existDataBlock = pBlock;
        break;
L
Liu Jicong 已提交
5065
      } else {  // init output buffer for a new group data
5066 5067 5068 5069 5070
        initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfOutput);
      }
    }

    // todo dynamic set tags
H
Haojun Liao 已提交
5071 5072 5073 5074
    //    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5075 5076

    // the pDataBlock are always the same one, no need to call this again
5077 5078 5079
    int32_t order = getTableScanOrder(pOperator->pDownstream[0]);

    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, false);
5080 5081
    blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);

dengyihao's avatar
dengyihao 已提交
5082 5083
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput,
                          pProjectInfo->pPseudoColInfo);
H
Haojun Liao 已提交
5084

5085 5086
    int32_t status = handleLimitOffset(pOperator, pBlock);
    if (status == PROJECT_RETRIEVE_CONTINUE) {
H
Haojun Liao 已提交
5087
      continue;
5088
    } else if (status == PROJECT_RETRIEVE_DONE)  {
5089 5090 5091
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
5092

H
Haojun Liao 已提交
5093
  pProjectInfo->curOutput += pInfo->pRes->info.rows;
H
Haojun Liao 已提交
5094

L
Liu Jicong 已提交
5095 5096
  //  copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
  return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
5097 5098
}

L
Liu Jicong 已提交
5099
static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
5100 5101
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
5102 5103
  }

dengyihao's avatar
dengyihao 已提交
5104
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
5105
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5106

5107
  int32_t order = TSDB_ORDER_ASC;
5108
  //  STimeWindow win = {0};
dengyihao's avatar
dengyihao 已提交
5109
  bool           newgroup = false;
H
Haojun Liao 已提交
5110
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5111

5112
  while (1) {
H
Haojun Liao 已提交
5113
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5114
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
5115
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5116 5117 5118 5119 5120

    if (pBlock == NULL) {
      break;
    }

5121
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
5122
    // the pDataBlock are always the same one, no need to call this again
5123
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
5124 5125 5126
    STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;

    setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window);
5127
    hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, pBlock->info.groupId);
5128

dengyihao's avatar
dengyihao 已提交
5129
#if 0  // test for encode/decode result info
5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140
    if(pOperator->encodeResultRow){
      char *result = NULL;
      int32_t length = 0;
      SAggSupporter   *pSup = &pInfo->aggSup;
      pOperator->encodeResultRow(pOperator, pSup, &pInfo->binfo, &result, &length);
      taosHashClear(pSup->pResultRowHashTable);
      pInfo->binfo.resultRowInfo.size = 0;
      pOperator->decodeResultRow(pOperator, pSup, &pInfo->binfo, result, length);
      if(result){
        taosMemoryFree(result);
      }
5141
    }
5142
#endif
5143 5144
  }

H
Haojun Liao 已提交
5145
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
L
Liu Jicong 已提交
5146 5147
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5148

5149
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5150 5151 5152 5153
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
5154
static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator, bool* newgroup) {
5155
  STableIntervalOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5156
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
5157 5158 5159 5160 5161

  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5162 5163
  SSDataBlock* pBlock = pInfo->binfo.pRes;

5164
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
5165
    return pOperator->fpSet.getStreamResFn(pOperator, newgroup);
5166
  } else {
5167
    pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
5168 5169 5170
    if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
      return NULL;
    }
5171

5172
    blockDataEnsureCapacity(pBlock, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5173 5174
    doBuildResultDatablock(pBlock, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5175

5176
    if (pBlock->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5177 5178
      doSetOperatorCompleted(pOperator);
    }
5179

5180
    return pBlock->info.rows == 0 ? NULL : pBlock;
5181 5182 5183
  }
}

dengyihao's avatar
dengyihao 已提交
5184
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5185
  STableIntervalOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5186
  int32_t                     order = TSDB_ORDER_ASC;
5187 5188 5189 5190 5191 5192

  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5193 5194
    doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5195 5196 5197
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      pOperator->status = OP_EXEC_DONE;
    }
5198
    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5199 5200 5201
  }

  //  STimeWindow win = {0};
5202
  *newgroup = false;
5203 5204 5205 5206 5207 5208
  SOperatorInfo* downstream = pOperator->pDownstream[0];

  SArray* pUpdated = NULL;

  while (1) {
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5209
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
5210 5211 5212 5213 5214 5215
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);

    if (pBlock == NULL) {
      break;
    }

dengyihao's avatar
dengyihao 已提交
5216 5217
    // The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
    // caller. Note that all the time window are not close till now.
5218 5219 5220

    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    // the pDataBlock are always the same one, no need to call this again
5221
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
5222 5223 5224
    pUpdated = hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0);
  }

dengyihao's avatar
dengyihao 已提交
5225 5226
  finalizeUpdatedResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, pUpdated,
                        pInfo->binfo.rowCellInfoOffset);
5227

H
Haojun Liao 已提交
5228
  initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
5229
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5230 5231
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5232 5233 5234 5235 5236 5237 5238

  ASSERT(pInfo->binfo.pRes->info.rows > 0);
  pOperator->status = OP_RES_TO_RETURN;

  return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
}

dengyihao's avatar
dengyihao 已提交
5239
static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5240 5241 5242 5243
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5244
  STimeSliceOperatorInfo* pSliceInfo = pOperator->info;
5245
  if (pOperator->status == OP_RES_TO_RETURN) {
5246
    //    doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
5247
    if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5248 5249 5250
      doSetOperatorCompleted(pOperator);
    }

5251
    return pSliceInfo->binfo.pRes;
5252 5253
  }

dengyihao's avatar
dengyihao 已提交
5254 5255
  int32_t order = TSDB_ORDER_ASC;
  //  STimeWindow win = pQueryAttr->window;
H
Haojun Liao 已提交
5256
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5257

L
Liu Jicong 已提交
5258
  while (1) {
H
Haojun Liao 已提交
5259
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5260
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5261
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5262 5263 5264 5265
    if (pBlock == NULL) {
      break;
    }

L
Liu Jicong 已提交
5266
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5267
    // the pDataBlock are always the same one, no need to call this again
5268
    setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true);
dengyihao's avatar
dengyihao 已提交
5269
    //    hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
5270 5271 5272 5273
  }

  // restore the value
  pOperator->status = OP_RES_TO_RETURN;
5274
  closeAllResultRows(&pSliceInfo->binfo.resultRowInfo);
5275
  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
dengyihao's avatar
dengyihao 已提交
5276
  //  finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfOutput);
5277

5278
//  initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
5279
  //  doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
5280

5281
  if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5282 5283 5284
    pOperator->status = OP_EXEC_DONE;
  }

5285
  return pSliceInfo->binfo.pRes->info.rows == 0 ? NULL : pSliceInfo->binfo.pRes;
5286 5287
}

L
Liu Jicong 已提交
5288
static SSDataBlock* doSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5289 5290 5291 5292
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5293
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
5294

5295
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5296 5297
  if (pOperator->status == OP_RES_TO_RETURN) {
    int64_t st = taosGetTimestampUs();
5298
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5299 5300
      doSetOperatorCompleted(pOperator);
    }
5301 5302

    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5303 5304
  }

H
Haojun Liao 已提交
5305
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5306

L
Liu Jicong 已提交
5307
  while (1) {
H
Haojun Liao 已提交
5308
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5309
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5310
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5311 5312 5313 5314 5315 5316

    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
L
Liu Jicong 已提交
5317
    //    setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5318
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC, true);
5319
    STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;
5320

5321
    setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window);
dengyihao's avatar
dengyihao 已提交
5322
    //    hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pBlock->info.groupId);
5323 5324
  }

5325 5326 5327
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5328

5329
//  initGroupedResultInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
5330 5331
  OPTR_SET_OPENED(pOperator);

5332
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5333 5334
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5335 5336 5337

  if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5338 5339
  }

5340
  return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5341 5342
}

5343
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) {
dengyihao's avatar
dengyihao 已提交
5344
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
5345 5346
  SOptrBasicInfo* pBInfo = &pInfo->binfo;

5347
  SColumnInfoData* pStateColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->colIndex);
dengyihao's avatar
dengyihao 已提交
5348
  int64_t          gid = pBlock->info.groupId;
5349

5350 5351 5352 5353 5354 5355 5356 5357
  bool    masterScan = true;
  int32_t numOfOutput = pOperator->numOfOutput;

  int16_t bytes = pStateColInfoData->info.bytes;
  int16_t type = pStateColInfoData->info.type;

  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
  TSKEY*           tsList = (TSKEY*)pColInfoData->pData;
5358

5359 5360
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;
dengyihao's avatar
dengyihao 已提交
5361

5362 5363
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
    if (colDataIsNull(pStateColInfoData, pBlock->info.rows, j, pBlock->pBlockAgg)) {
5364 5365
      continue;
    }
5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378

    char* val = colDataGetData(pStateColInfoData, j);

    if (!pInfo->hasKey) {
      memcpy(pInfo->stateKey.pData, val, bytes);
      pInfo->hasKey = true;

      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
    } else if (memcmp(pInfo->stateKey.pData, val, bytes) == 0) {
      doKeepTuple(pRowSup, tsList[j]);
      if (j == 0 && pRowSup->startRowIndex != 0) {
        pRowSup->startRowIndex = 0;
5379
      }
5380
    } else {  // a new state window started
5381
      SResultRow* pResult = NULL;
5382 5383 5384 5385 5386 5387

      // keep the time window for the closed time window.
      STimeWindow window = pRowSup->win;

      pRowSup->win.ekey = pRowSup->win.skey;
      int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &window, masterScan,
dengyihao's avatar
dengyihao 已提交
5388 5389
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
5390
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5391
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5392 5393
      }

5394
      updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
dengyihao's avatar
dengyihao 已提交
5395 5396
      doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                       pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5397 5398 5399 5400

      // here we start a new session window
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
5401 5402 5403 5404
    }
  }

  SResultRow* pResult = NULL;
5405
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
5406 5407 5408
  int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &pRowSup->win, masterScan,
                                           &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                           pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
5409
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5410
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5411 5412
  }

5413
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
dengyihao's avatar
dengyihao 已提交
5414 5415
  doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                   pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5416 5417
}

L
Liu Jicong 已提交
5418
static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5419 5420 5421 5422
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5423
  SStateWindowOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5424 5425
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
  SOptrBasicInfo*           pBInfo = &pInfo->binfo;
5426 5427

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5428 5429
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5430 5431 5432 5433
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
    }
5434 5435 5436 5437

    return pBInfo->pRes;
  }

dengyihao's avatar
dengyihao 已提交
5438 5439
  int32_t     order = TSDB_ORDER_ASC;
  STimeWindow win = pTaskInfo->window;
H
Haojun Liao 已提交
5440

H
Haojun Liao 已提交
5441
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5442
  while (1) {
H
Haojun Liao 已提交
5443
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5444
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5445
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5446 5447 5448 5449

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
5450

5451
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5452
    doStateWindowAggImpl(pOperator, pInfo, pBlock);
5453 5454 5455 5456
  }

  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pBInfo->resultRowInfo);
dengyihao's avatar
dengyihao 已提交
5457 5458
  finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
                                pBInfo->rowCellInfoOffset);
5459

5460
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5461
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5462 5463
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5464 5465 5466
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
5467

L
Liu Jicong 已提交
5468
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5469 5470
}

L
Liu Jicong 已提交
5471
static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5472 5473 5474 5475
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5476
  SSessionAggOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5477
  SOptrBasicInfo*          pBInfo = &pInfo->binfo;
5478 5479

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5480 5481
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5482 5483 5484
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
5485 5486 5487 5488 5489
    }

    return pBInfo->pRes;
  }

L
Liu Jicong 已提交
5490
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
5491
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5492

L
Liu Jicong 已提交
5493
  while (1) {
H
Haojun Liao 已提交
5494
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5495
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5496
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5497 5498 5499 5500 5501
    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
5502
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5503
    doSessionWindowAggImpl(pOperator, pInfo, pBlock);
5504 5505 5506 5507 5508
  }

  // restore the value
  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pBInfo->resultRowInfo);
dengyihao's avatar
dengyihao 已提交
5509 5510
  finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
                                pBInfo->rowCellInfoOffset);
5511

5512
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5513
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5514 5515
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5516 5517
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5518 5519
  }

L
Liu Jicong 已提交
5520
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5521 5522
}

L
Liu Jicong 已提交
5523 5524
static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                               SExecTaskInfo* pTaskInfo) {
5525
  pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows;
H
Haojun Liao 已提交
5526

L
Liu Jicong 已提交
5527 5528
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
5529 5530
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

5531
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
5532 5533
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

H
Haojun Liao 已提交
5534
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity, pInfo->p);
5535 5536 5537 5538
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
5539 5540
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
5541 5542
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
H
Haojun Liao 已提交
5543 5544
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity, pInfo->p);
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
5545 5546 5547 5548 5549 5550
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
5551
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5552 5553 5554
  }
}

L
Liu Jicong 已提交
5555 5556 5557
static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
5558

H
Haojun Liao 已提交
5559
  SResultInfo* pResultInfo = &pOperator->resultInfo;
5560 5561 5562
  SSDataBlock* pResBlock = pInfo->pRes;

  blockDataCleanup(pResBlock);
5563 5564 5565 5566
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5567
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5568 5569
  if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
    return pResBlock;
H
Haojun Liao 已提交
5570
  }
5571

H
Haojun Liao 已提交
5572
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
5573
  while (1) {
H
Haojun Liao 已提交
5574
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5575
    SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream, newgroup);
H
Haojun Liao 已提交
5576
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587

    if (*newgroup) {
      assert(pBlock != NULL);
    }

    if (*newgroup && pInfo->totalInputRows > 0) {  // there are already processed current group data block
      pInfo->existNewGroupBlock = pBlock;
      *newgroup = false;

      // Fill the previous group data block, before handle the data block of new group.
      // Close the fill operation for previous group data block
5588
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5589 5590 5591 5592 5593 5594 5595
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

5596
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5597 5598 5599 5600 5601 5602 5603
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

5604
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity, pInfo->p);
5605 5606

    // current group has no more result to return
5607
    if (pResBlock->info.rows > 0) {
5608 5609
      // 1. The result in current group not reach the threshold of output result, continue
      // 2. If multiple group results existing in one SSDataBlock is not allowed, return immediately
5610 5611
      if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
        return pResBlock;
5612 5613
      }

5614
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5615 5616
      if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
        return pResBlock;
5617 5618 5619
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
5620
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5621 5622
      if (pResBlock->info.rows > pResultInfo->threshold) {
        return pResBlock;
5623 5624 5625 5626 5627 5628 5629 5630
      }
    } else {
      return NULL;
    }
  }
}

// todo set the attribute of query scan count
H
Haojun Liao 已提交
5631
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
L
Liu Jicong 已提交
5632
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
    if (functionId == FUNCTION_STDDEV || functionId == FUNCTION_PERCT) {
      return 2;
    }
  }

  return 1;
}

static void destroyOperatorInfo(SOperatorInfo* pOperator) {
  if (pOperator == NULL) {
    return;
  }

5647 5648
  if (pOperator->fpSet.closeFn != NULL) {
    pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfOutput);
5649 5650
  }

H
Haojun Liao 已提交
5651
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
5652
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
5653
      destroyOperatorInfo(pOperator->pDownstream[i]);
5654 5655
    }

wafwerar's avatar
wafwerar 已提交
5656
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
5657
    pOperator->numOfDownstream = 0;
5658 5659
  }

wafwerar's avatar
wafwerar 已提交
5660 5661
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
5662 5663
}

dengyihao's avatar
dengyihao 已提交
5664 5665
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                         const char* pKey) {
5666 5667
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

dengyihao's avatar
dengyihao 已提交
5668 5669
  pAggSup->resultRowSize = getResultRowSize(pCtx, numOfOutput);
  pAggSup->keyBuf = taosMemoryCalloc(1, keyBufSize + POINTER_BYTES + sizeof(int64_t));
5670
  pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK);
5671 5672
//  pAggSup->pResultRowListSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
//  pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell));
5673

5674
  if (pAggSup->keyBuf == NULL /*|| pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL*/ ||
5675
      pAggSup->pResultRowHashTable == NULL) {
5676 5677 5678
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
5679 5680 5681 5682 5683
  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, 4096, 4096 * 256, pKey, "/tmp/");
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

5684 5685 5686
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
5687
static void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
5688
  taosMemoryFreeClear(pAggSup->keyBuf);
5689
  taosHashCleanup(pAggSup->pResultRowHashTable);
5690 5691
//  taosHashCleanup(pAggSup->pResultRowListSet);
//  taosArrayDestroy(pAggSup->pResultRowArrayList);
H
Haojun Liao 已提交
5692
  destroyDiskbasedBuf(pAggSup->pResultBuf);
5693 5694
}

H
Haojun Liao 已提交
5695
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
5696
                    SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey) {
5697
  pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5698 5699
  pBasicInfo->pRes = pResultBlock;

5700
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, keyBufSize, pkey);
5701 5702 5703 5704 5705

  for(int32_t i = 0; i < numOfCols; ++i) {
    pBasicInfo->pCtx[i].pBuf = pAggSup->pResultBuf;
  }

5706
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
5707 5708
}

5709 5710 5711 5712 5713 5714 5715 5716 5717
void initResultSizeInfo(SOperatorInfo* pOperator, int32_t numOfRows) {
  pOperator->resultInfo.capacity = numOfRows;
  pOperator->resultInfo.threshold = numOfRows * 0.75;

  if (pOperator->resultInfo.threshold == 0) {
    pOperator->resultInfo.capacity = numOfRows;
  }
}

H
Haojun Liao 已提交
5718
static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5719
  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
H
Haojun Liao 已提交
5720 5721
  if (pTableQueryInfo == NULL) {
    return NULL;
H
Haojun Liao 已提交
5722
  }
H
Haojun Liao 已提交
5723 5724

  int32_t index = 0;
L
Liu Jicong 已提交
5725
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
H
Haojun Liao 已提交
5726
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
L
Liu Jicong 已提交
5727
    for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
H
Haojun Liao 已提交
5728 5729
      STableKeyInfo* pk = taosArrayGet(pa, j);

H
Haojun Liao 已提交
5730
      STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
dengyihao's avatar
dengyihao 已提交
5731
      //      pTQueryInfo->uid = pk->uid;
L
Liu Jicong 已提交
5732
      pTQueryInfo->lastKey = pk->lastKey;
dengyihao's avatar
dengyihao 已提交
5733
      //      pTQueryInfo->groupIndex = i;
H
Haojun Liao 已提交
5734 5735
    }
  }
H
Haojun Liao 已提交
5736 5737

  STimeWindow win = {0, INT64_MAX};
H
Haojun Liao 已提交
5738 5739
  createTableQueryInfo(pTableQueryInfo, false, win);
  return pTableQueryInfo;
H
Haojun Liao 已提交
5740 5741
}

L
Liu Jicong 已提交
5742
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5743
                                           SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
5744
                                           int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5745
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
5746
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5747 5748 5749
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5750

H
Haojun Liao 已提交
5751
  int32_t numOfRows = 1;
dengyihao's avatar
dengyihao 已提交
5752
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5753 5754

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
5755 5756
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResultBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
5757 5758
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) {
H
Haojun Liao 已提交
5759 5760
    goto _error;
  }
H
Haojun Liao 已提交
5761

H
Haojun Liao 已提交
5762 5763 5764 5765 5766 5767 5768
  pOperator->resultInfo.capacity = 4096;
  pOperator->resultInfo.threshold = 4096 * 0.75;

  int32_t numOfGroup = 10;  // todo replaced with true value
  pInfo->groupId = INT32_MIN;
  initResultRowInfo(&pInfo->binfo.resultRowInfo, numOfGroup);

5769 5770
  pInfo->pScalarExprInfo = pScalarExprInfo;
  pInfo->numOfScalarExpr = numOfScalarExpr;
5771 5772 5773
  if (pInfo->pScalarExprInfo != NULL) {
    pInfo->pScalarCtx = createSqlFunctionCtx(pScalarExprInfo, numOfCols, &pInfo->rowCellInfoOffset);
  }
5774

dengyihao's avatar
dengyihao 已提交
5775
  pOperator->name = "TableAggregate";
X
Xiaoyu Wang 已提交
5776
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
5777
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5778 5779 5780 5781 5782
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
5783

5784 5785
  pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
H
Haojun Liao 已提交
5786 5787 5788 5789 5790

  code = appendDownstream(pOperator, &downstream, 1);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
5791 5792

  return pOperator;
L
Liu Jicong 已提交
5793
_error:
H
Haojun Liao 已提交
5794
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5795 5796
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5797 5798
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5799 5800
}

H
Haojun Liao 已提交
5801
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
5802 5803
  assert(pInfo != NULL);

5804
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
5805
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
5806 5807

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
5808
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
5809 5810
}

H
Haojun Liao 已提交
5811
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5812
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
5813 5814
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
5815 5816

void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5817
  SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param;
5818
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
5819
  taosMemoryFreeClear(pInfo->stateKey.pData);
5820
}
H
Haojun Liao 已提交
5821 5822

void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5823
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
5824 5825
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
5826

H
Haojun Liao 已提交
5827
void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5828
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)param;
H
Haojun Liao 已提交
5829 5830 5831 5832 5833
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
  cleanupAggSup(&pInfo->aggSup);
}

void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5834
  SSessionAggOperatorInfo* pInfo = (SSessionAggOperatorInfo*)param;
5835 5836 5837
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5838
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5839
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
5840
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
5841
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
5842
  taosMemoryFreeClear(pInfo->p);
5843 5844
}

H
Haojun Liao 已提交
5845
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5846
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
5847 5848 5849
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5850
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5851
  SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
H
Haojun Liao 已提交
5852 5853
  pInfo->pDataBlock = blockDataDestroy(pInfo->pDataBlock);

H
Haojun Liao 已提交
5854
  taosArrayDestroy(pInfo->pSortInfo);
5855
  taosArrayDestroy(pInfo->inputSlotMap);
5856 5857
}

H
Haojun Liao 已提交
5858
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5859
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
5860 5861 5862 5863 5864 5865 5866 5867 5868
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

H
Haojun Liao 已提交
5869 5870
static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols) {
  SArray* pList = taosArrayInit(4, sizeof(int32_t));
dengyihao's avatar
dengyihao 已提交
5871
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
5872 5873 5874 5875 5876 5877 5878 5879
    if (fmIsPseudoColumnFunc(pCtx[i].functionId)) {
      taosArrayPush(pList, &i);
    }
  }

  return pList;
}

L
Liu Jicong 已提交
5880
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
dengyihao's avatar
dengyihao 已提交
5881 5882
                                         SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit,
                                         SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5883
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
5884
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5885 5886 5887
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
5888

dengyihao's avatar
dengyihao 已提交
5889 5890 5891
  pInfo->limit = *pLimit;
  pInfo->slimit = *pSlimit;
  pInfo->curOffset = pLimit->offset;
H
Haojun Liao 已提交
5892 5893
  pInfo->curSOffset = pSlimit->offset;

H
Haojun Liao 已提交
5894
  pInfo->binfo.pRes = pResBlock;
H
Haojun Liao 已提交
5895 5896 5897

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5898
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5899 5900 5901

  initResultSizeInfo(pOperator, numOfRows);
  initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
5902
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
H
Haojun Liao 已提交
5903
  pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pInfo->binfo.pCtx, numOfCols);
5904

dengyihao's avatar
dengyihao 已提交
5905
  pOperator->name = "ProjectOperator";
H
Haojun Liao 已提交
5906
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
5907
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
5908 5909 5910 5911
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = num;
5912 5913 5914

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL, destroyProjectOperatorInfo,
                                         NULL, NULL, NULL);
L
Liu Jicong 已提交
5915 5916

  pOperator->pTaskInfo = pTaskInfo;
5917
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5918
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
5919 5920
    goto _error;
  }
5921 5922

  return pOperator;
H
Haojun Liao 已提交
5923

L
Liu Jicong 已提交
5924
_error:
H
Haojun Liao 已提交
5925 5926
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5927 5928
}

L
Liu Jicong 已提交
5929
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5930
                                          SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
dengyihao's avatar
dengyihao 已提交
5931 5932
                                          STimeWindowAggSupp* pTwAggSupp, const STableGroupInfo* pTableGroupInfo,
                                          SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5933
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
L
Liu Jicong 已提交
5934
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5935 5936 5937
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5938

5939 5940
  pInfo->order          = TSDB_ORDER_ASC;
  pInfo->interval       = *pInterval;
H
Haojun Liao 已提交
5941 5942
//  pInfo->execModel      = OPTR_EXEC_MODEL_STREAM;
  pInfo->execModel      = pTaskInfo->execModel;
5943 5944
  pInfo->win            = pTaskInfo->window;
  pInfo->twAggSup       = *pTwAggSupp;
5945
  pInfo->primaryTsIndex = primaryTsSlotId;
5946

5947
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5948
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5949 5950

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
5951 5952
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
5953
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);
5954

L
Liu Jicong 已提交
5955 5956
  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
H
Haojun Liao 已提交
5957 5958
    goto _error;
  }
H
Haojun Liao 已提交
5959 5960

  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
5961

dengyihao's avatar
dengyihao 已提交
5962
  pOperator->name = "TimeIntervalAggOperator";
H
Haojun Liao 已提交
5963
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
5964
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5965 5966 5967 5968 5969
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
5970 5971 5972

  pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doBuildIntervalResult, doStreamIntervalAgg, NULL, destroyIntervalOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
5973

H
Haojun Liao 已提交
5974
  code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5975 5976 5977 5978
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

5979
  return pOperator;
H
Haojun Liao 已提交
5980

L
Liu Jicong 已提交
5981
_error:
H
Haojun Liao 已提交
5982
  destroyIntervalOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5983 5984
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5985 5986
  pTaskInfo->code = code;
  return NULL;
5987 5988
}

5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047
SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                                SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
                                                STimeWindowAggSupp *pTwAggSupp, const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo) {
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }

  pInfo->order          = TSDB_ORDER_ASC;
  pInfo->interval       = *pInterval;
  pInfo->execModel      = OPTR_EXEC_MODEL_STREAM;
  pInfo->win            = pTaskInfo->window;
  pInfo->twAggSup       = *pTwAggSupp;
  pInfo->primaryTsIndex = primaryTsSlotId;

  int32_t numOfRows = 4096;
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;

  initResultSizeInfo(pOperator, numOfRows);
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);

  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
    goto _error;
  }

  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);

  pOperator->name = "StreamTimeIntervalAggOperator";
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
  pOperator->blockingOptr = true;
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;

  pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doStreamIntervalAgg, doStreamIntervalAgg, NULL, destroyIntervalOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);

  code = appendDownstream(pOperator, &downstream, 1);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

  return pOperator;

  _error:
  destroyIntervalOperatorInfo(pInfo, numOfCols);
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
  pTaskInfo->code = code;
  return NULL;

}

dengyihao's avatar
dengyihao 已提交
6048 6049
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                           SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo) {
6050
  STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
dengyihao's avatar
dengyihao 已提交
6051
  SOperatorInfo*          pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6052 6053 6054
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }
6055

H
Haojun Liao 已提交
6056
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6057

dengyihao's avatar
dengyihao 已提交
6058
  pOperator->name = "TimeSliceOperator";
L
Liu Jicong 已提交
6059
  //  pOperator->operatorType = OP_AllTimeWindow;
6060
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6061 6062 6063 6064 6065
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
6066 6067 6068

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doAllIntervalAgg, NULL, NULL, destroyBasicOperatorInfo,
                                         NULL, NULL, NULL);
6069

L
Liu Jicong 已提交
6070
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6071
  return pOperator;
6072

dengyihao's avatar
dengyihao 已提交
6073
_error:
6074 6075 6076 6077
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
6078 6079
}

dengyihao's avatar
dengyihao 已提交
6080 6081 6082
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
                                             SSDataBlock* pResBlock, STimeWindowAggSupp* pTwAggSup,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6083
  SStateWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStateWindowOperatorInfo));
dengyihao's avatar
dengyihao 已提交
6084
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6085 6086 6087
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6088

L
Liu Jicong 已提交
6089
  pInfo->colIndex = -1;
6090
  size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6091 6092 6093

  initResultSizeInfo(pOperator, 4096);
  initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExpr, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
6094
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6095

6096 6097 6098
  pInfo->twAggSup = *pTwAggSup;
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);

dengyihao's avatar
dengyihao 已提交
6099
  pOperator->name = "StateWindowOperator";
6100
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW;
6101
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6102 6103 6104 6105 6106 6107
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;

  pOperator->pTaskInfo = pTaskInfo;
  pOperator->info = pInfo;
6108 6109 6110

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStateWindowAgg, NULL, NULL, destroyStateWindowOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
6111

H
Haojun Liao 已提交
6112
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6113
  return pOperator;
6114

dengyihao's avatar
dengyihao 已提交
6115
_error:
6116 6117
  pTaskInfo->code = TSDB_CODE_SUCCESS;
  return NULL;
6118 6119
}

L
Liu Jicong 已提交
6120
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
dengyihao's avatar
dengyihao 已提交
6121 6122
                                            SSDataBlock* pResBlock, int64_t gap, STimeWindowAggSupp* pTwAggSupp,
                                            SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6123
  SSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSessionAggOperatorInfo));
L
Liu Jicong 已提交
6124
  SOperatorInfo*           pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6125 6126 6127
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6128

H
Haojun Liao 已提交
6129
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
6130
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6131 6132

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
6133 6134
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
6135 6136 6137
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6138

6139
  pInfo->twAggSup = *pTwAggSupp;
H
Haojun Liao 已提交
6140
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6141
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
6142

dengyihao's avatar
dengyihao 已提交
6143 6144 6145 6146 6147
  pInfo->gap = gap;
  pInfo->binfo.pRes = pResBlock;
  pInfo->winSup.prevTs = INT64_MIN;
  pInfo->reptScan = false;
  pOperator->name = "SessionWindowAggOperator";
H
Haojun Liao 已提交
6148
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW;
6149
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6150 6151 6152 6153
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
6154 6155 6156

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSessionWindowAgg, NULL, NULL, destroySWindowOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
dengyihao's avatar
dengyihao 已提交
6157
  pOperator->pTaskInfo = pTaskInfo;
6158

H
Haojun Liao 已提交
6159
  code = appendDownstream(pOperator, &downstream, 1);
6160
  return pOperator;
H
Haojun Liao 已提交
6161

L
Liu Jicong 已提交
6162
_error:
H
Haojun Liao 已提交
6163 6164 6165 6166
  if (pInfo != NULL) {
    destroySWindowOperatorInfo(pInfo, numOfCols);
  }

wafwerar's avatar
wafwerar 已提交
6167 6168
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6169 6170
  pTaskInfo->code = code;
  return NULL;
6171 6172
}

H
Haojun Liao 已提交
6173
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, int64_t* fillVal,
L
Liu Jicong 已提交
6174
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
6175
  SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, NULL);
H
Haojun Liao 已提交
6176 6177 6178

  // TODO set correct time precision
  STimeWindow w = TSWINDOW_INITIALIZER;
6179
  getAlignQueryTimeWindow(pInterval, TSDB_TIME_PRECISION_MILLI, win.skey, &w);
H
Haojun Liao 已提交
6180 6181

  int32_t order = TSDB_ORDER_ASC;
6182
  pInfo->pFillInfo = taosCreateFillInfo(order, w.skey, 0, capacity, numOfCols, pInterval, fillType, pColInfo, id);
H
Haojun Liao 已提交
6183

wafwerar's avatar
wafwerar 已提交
6184
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
6185 6186 6187 6188 6189 6190 6191 6192

  if (pInfo->pFillInfo == NULL || pInfo->p == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  } else {
    return TSDB_CODE_SUCCESS;
  }
}

L
Liu Jicong 已提交
6193 6194 6195
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
                                      SInterval* pInterval, SSDataBlock* pResBlock, int32_t fillType, char* fillVal,
                                      bool multigroupResult, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6196
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
6197
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6198

L
Liu Jicong 已提交
6199
  pInfo->pRes = pResBlock;
6200
  pInfo->multigroupResult = multigroupResult;
L
Liu Jicong 已提交
6201
  pInfo->intervalInfo = *pInterval;
6202

6203 6204
  int32_t type = TSDB_FILL_NONE;
  switch (fillType) {
dengyihao's avatar
dengyihao 已提交
6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222
    case FILL_MODE_PREV:
      type = TSDB_FILL_PREV;
      break;
    case FILL_MODE_NONE:
      type = TSDB_FILL_NONE;
      break;
    case FILL_MODE_NULL:
      type = TSDB_FILL_NULL;
      break;
    case FILL_MODE_NEXT:
      type = TSDB_FILL_NEXT;
      break;
    case FILL_MODE_VALUE:
      type = TSDB_FILL_SET_VALUE;
      break;
    case FILL_MODE_LINEAR:
      type = TSDB_FILL_LINEAR;
      break;
6223 6224 6225 6226
    default:
      type = TSDB_FILL_NONE;
  }

H
Haojun Liao 已提交
6227
  SResultInfo* pResultInfo = &pOperator->resultInfo;
6228 6229 6230 6231
  initResultSizeInfo(pOperator, 4096);

  int32_t code = initFillInfo(pInfo, pExpr, numOfCols, (int64_t*)fillVal, pTaskInfo->window, pResultInfo->capacity,
                              pTaskInfo->id.str, pInterval, type);
6232 6233 6234
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6235

dengyihao's avatar
dengyihao 已提交
6236
  pOperator->name = "FillOperator";
6237
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
6238
  pOperator->status = OP_NOT_OPENED;
L
Liu Jicong 已提交
6239
  //  pOperator->operatorType = OP_Fill;
dengyihao's avatar
dengyihao 已提交
6240 6241 6242
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
H
Haojun Liao 已提交
6243

6244 6245 6246
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo,
                                         NULL, NULL, NULL);
  pOperator->pTaskInfo = pTaskInfo;
6247
  code = appendDownstream(pOperator, &downstream, 1);
6248
  return pOperator;
H
Haojun Liao 已提交
6249

L
Liu Jicong 已提交
6250
_error:
wafwerar's avatar
wafwerar 已提交
6251 6252
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
6253
  return NULL;
6254 6255
}

H
Haojun Liao 已提交
6256

L
Liu Jicong 已提交
6257
static int32_t getColumnIndexInSource(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6258 6259
  int32_t j = 0;

H
Haojun Liao 已提交
6260 6261
  if (TSDB_COL_IS_TAG(pExpr->pParam[0].pCol->type)) {
    if (pExpr->pParam[0].pCol->colId == TSDB_TBNAME_COLUMN_INDEX) {
6262 6263 6264
      return TSDB_TBNAME_COLUMN_INDEX;
    }

L
Liu Jicong 已提交
6265
    while (j < pTableInfo->numOfTags) {
H
Haojun Liao 已提交
6266
      if (pExpr->pParam[0].pCol->colId == pTagCols[j].colId) {
6267 6268 6269 6270 6271 6272
        return j;
      }

      j += 1;
    }

6273
  } /*else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {  // user specified column data
6274 6275 6276 6277 6278 6279 6280 6281 6282
    return TSDB_UD_COLUMN_INDEX;
  } else {
    while (j < pTableInfo->numOfCols) {
      if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) {
        return j;
      }

      j += 1;
    }
6283
  }*/
6284 6285 6286 6287

  return INT32_MIN;  // return a less than TSDB_TBNAME_COLUMN_INDEX value
}

L
Liu Jicong 已提交
6288
bool validateExprColumnInfo(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6289 6290 6291 6292
  int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols);
  return j != INT32_MIN;
}

L
Liu Jicong 已提交
6293 6294
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
6295
  SResSchema s = {0};
dengyihao's avatar
dengyihao 已提交
6296 6297 6298 6299
  s.scale = scale;
  s.type = type;
  s.bytes = bytes;
  s.slotId = slotId;
H
Haojun Liao 已提交
6300
  s.precision = precision;
H
Haojun Liao 已提交
6301 6302 6303 6304
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
6305

H
Haojun Liao 已提交
6306 6307 6308 6309 6310 6311 6312
static SColumn* createColumn(int32_t blockId, int32_t slotId, SDataType* pType) {
  SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn));
  if (pCol == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

dengyihao's avatar
dengyihao 已提交
6313 6314 6315 6316 6317
  pCol->slotId = slotId;
  pCol->bytes = pType->bytes;
  pCol->type = pType->type;
  pCol->scale = pType->scale;
  pCol->precision = pType->precision;
H
Haojun Liao 已提交
6318 6319 6320 6321 6322
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
6323
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
6324
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6325 6326 6327 6328
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
6329

H
Haojun Liao 已提交
6330
  *numOfExprs = numOfFuncs + numOfGroupKeys;
wafwerar's avatar
wafwerar 已提交
6331
  SExprInfo* pExprs = taosMemoryCalloc(*numOfExprs, sizeof(SExprInfo));
H
Haojun Liao 已提交
6332

L
Liu Jicong 已提交
6333
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
6334 6335 6336 6337 6338 6339
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
6340

6341
    SExprInfo* pExp = &pExprs[i];
H
Haojun Liao 已提交
6342

wafwerar's avatar
wafwerar 已提交
6343
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
6344
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
6345
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
6346

6347
    int32_t type = nodeType(pTargetNode->pExpr);
H
Haojun Liao 已提交
6348
    // it is a project query, or group by column
6349
    if (type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
6350
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
6351
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
6352

G
Ganlin Zhao 已提交
6353 6354 6355
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
6356
      SDataType* pType = &pColNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6357 6358
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pColNode->colName);
H
Haojun Liao 已提交
6359 6360
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pType);
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
6361
    } else if (type == QUERY_NODE_VALUE) {
6362 6363 6364 6365 6366 6367 6368
      pExp->pExpr->nodeType = QUERY_NODE_VALUE;
      SValueNode* pValNode = (SValueNode*)pTargetNode->pExpr;

      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

      SDataType* pType = &pValNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6369 6370
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pValNode->node.aliasName);
6371 6372
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
      valueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
6373
    } else if (type == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
6374
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
6375 6376 6377
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

      SDataType* pType = &pFuncNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6378 6379
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pFuncNode->node.aliasName);
H
Haojun Liao 已提交
6380

H
Haojun Liao 已提交
6381
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
6382
      pExp->pExpr->_function.pFunctNode = pFuncNode;
dengyihao's avatar
dengyihao 已提交
6383 6384
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
H
Haojun Liao 已提交
6385 6386

      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
6387 6388 6389 6390

      pExp->base.pParam = taosMemoryCalloc(numOfParam, sizeof(SFunctParam));
      pExp->base.numOfParams = numOfParam;

H
Haojun Liao 已提交
6391
      for (int32_t j = 0; j < numOfParam; ++j) {
6392
        SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
6393
        if (p1->type == QUERY_NODE_COLUMN) {
dengyihao's avatar
dengyihao 已提交
6394
          SColumnNode* pcn = (SColumnNode*)p1;
G
Ganlin Zhao 已提交
6395 6396

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
H
Haojun Liao 已提交
6397
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, &pcn->node.resType);
G
Ganlin Zhao 已提交
6398 6399 6400
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
6401
          valueNodeToVariant(pvn, &pExp->base.pParam[j].param);
G
Ganlin Zhao 已提交
6402
        }
H
Haojun Liao 已提交
6403
      }
6404
    } else if (type == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
6405
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
6406
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
6407

G
Ganlin Zhao 已提交
6408 6409 6410
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

6411
      SDataType* pType = &pNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6412 6413
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pNode->node.aliasName);
6414 6415 6416
      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6417 6418 6419
    }
  }

H
Haojun Liao 已提交
6420
  return pExprs;
H
Haojun Liao 已提交
6421 6422
}

6423
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model) {
wafwerar's avatar
wafwerar 已提交
6424
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
6425
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
6426

6427
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
6428
  pTaskInfo->id.queryId = queryId;
dengyihao's avatar
dengyihao 已提交
6429
  pTaskInfo->execModel = model;
H
Haojun Liao 已提交
6430

wafwerar's avatar
wafwerar 已提交
6431
  char* p = taosMemoryCalloc(1, 128);
L
Liu Jicong 已提交
6432
  snprintf(p, 128, "TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, queryId);
6433
  pTaskInfo->id.str = strdup(p);
H
Haojun Liao 已提交
6434

6435 6436
  return pTaskInfo;
}
H
Haojun Liao 已提交
6437

L
Liu Jicong 已提交
6438 6439
static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                                      STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId);
H
Haojun Liao 已提交
6440

L
Liu Jicong 已提交
6441 6442
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                                  uint64_t queryId, uint64_t taskId);
6443
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
H
Haojun Liao 已提交
6444
static SArray* extractColumnInfo(SNodeList* pNodeList);
H
Haojun Liao 已提交
6445
static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols);
6446

6447
static SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget);
6448
static SArray* createIndexMap(SNodeList* pNodeList);
6449
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462
static int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode);

static SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode) {
  SInterval interval = {
      .interval     = pTableScanNode->interval,
      .sliding      = pTableScanNode->sliding,
      .intervalUnit = pTableScanNode->intervalUnit,
      .slidingUnit  = pTableScanNode->slidingUnit,
      .offset       = pTableScanNode->offset,
  };

  return interval;
}
H
Haojun Liao 已提交
6463

H
Haojun Liao 已提交
6464
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
6465
                                  uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
6466 6467
  int32_t type = nodeType(pPhyNode);

X
Xiaoyu Wang 已提交
6468
  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
H
Haojun Liao 已提交
6469
    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
dengyihao's avatar
dengyihao 已提交
6470 6471
      SScanPhysiNode*      pScanPhyNode = (SScanPhysiNode*)pPhyNode;
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6472

6473
      int32_t numOfCols = 0;
H
Haojun Liao 已提交
6474
      tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
6475
      if (pDataReader == NULL && terrno != 0) {
6476 6477
        return NULL;
      }
6478

dengyihao's avatar
dengyihao 已提交
6479 6480
      SArray* pColList =
          extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
6481
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6482

6483 6484 6485 6486 6487
      SQueryTableDataCond cond = {0};
      int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }
6488

6489 6490
      SInterval interval = extractIntervalInfo(pTableScanNode);
      return createTableScanOperatorInfo(pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList,
H
Haojun Liao 已提交
6491
                                         pResBlock, pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo);
H
Haojun Liao 已提交
6492
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
H
Haojun Liao 已提交
6493
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
6494
      SSDataBlock*        pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
6495
      return createExchangeOperatorInfo(pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
H
Haojun Liao 已提交
6496
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
H
Haojun Liao 已提交
6497
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
6498

6499
      int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, queryId, taskId);
H
Haojun Liao 已提交
6500
      SArray* tableIdList = extractTableIdList(pTableGroupInfo);
H
Haojun Liao 已提交
6501

6502
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6503 6504

      int32_t numOfCols = 0;
6505 6506
      SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
      SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo);
6507
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
6508
      return pOperator;
H
Haojun Liao 已提交
6509
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
L
Liu Jicong 已提交
6510
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
6511
      SScanPhysiNode* pScanNode = &pSysScanPhyNode->scan;
H
Haojun Liao 已提交
6512

6513
      SSDataBlock* pResBlock = createResDataBlock(pScanNode->node.pOutputDataBlockDesc);
6514

6515 6516
      int32_t numOfOutputCols = 0;
      SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pScanNode->node.pOutputDataBlockDesc, &numOfOutputCols);
L
Liu Jicong 已提交
6517
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
6518
          pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
L
Liu Jicong 已提交
6519
          colList, pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
6520 6521 6522
      return pOperator;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6523 6524 6525
    }
  }

6526 6527
  int32_t num = 0;
  size_t  size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
6528

6529
  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
dengyihao's avatar
dengyihao 已提交
6530
  for (int32_t i = 0; i < size; ++i) {
6531 6532
    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
6533 6534 6535
    if (ops[i] == NULL) {
      return NULL;
    }
6536
  }
H
Haojun Liao 已提交
6537

6538
  SOperatorInfo* pOptr = NULL;
H
Haojun Liao 已提交
6539
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
dengyihao's avatar
dengyihao 已提交
6540 6541
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*)pPhyNode;
    SExprInfo*         pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);
H
Haojun Liao 已提交
6542

6543
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
dengyihao's avatar
dengyihao 已提交
6544 6545
    SLimit       limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
    SLimit       slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
6546
    pOptr = createProjectOperatorInfo(ops[0], pExprInfo, num, pResBlock, &limit, &slimit, pTaskInfo);
H
Haojun Liao 已提交
6547 6548 6549
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == type) {
    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
    SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
6550
    SSDataBlock*   pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
6551

dengyihao's avatar
dengyihao 已提交
6552
    int32_t    numOfScalarExpr = 0;
6553 6554 6555 6556 6557
    SExprInfo* pScalarExprInfo = NULL;
    if (pAggNode->pExprs != NULL) {
      pScalarExprInfo = createExprInfo(pAggNode->pExprs, NULL, &numOfScalarExpr);
    }

H
Haojun Liao 已提交
6558 6559
    if (pAggNode->pGroupKeys != NULL) {
      SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
dengyihao's avatar
dengyihao 已提交
6560 6561
      pOptr = createGroupOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pAggNode->node.pConditions,
                                      pScalarExprInfo, numOfScalarExpr, pTaskInfo, NULL);
H
Haojun Liao 已提交
6562
    } else {
dengyihao's avatar
dengyihao 已提交
6563 6564
      pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr,
                                          pTaskInfo, pTableGroupInfo);
H
Haojun Liao 已提交
6565
    }
H
Haojun Liao 已提交
6566 6567
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type) {
    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6568

H
Haojun Liao 已提交
6569
    SExprInfo*   pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
6570
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
6571

dengyihao's avatar
dengyihao 已提交
6572 6573 6574 6575 6576 6577
    SInterval interval = {.interval = pIntervalPhyNode->interval,
                          .sliding = pIntervalPhyNode->sliding,
                          .intervalUnit = pIntervalPhyNode->intervalUnit,
                          .slidingUnit = pIntervalPhyNode->slidingUnit,
                          .offset = pIntervalPhyNode->offset,
                          .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision};
H
Haojun Liao 已提交
6578

dengyihao's avatar
dengyihao 已提交
6579 6580
    STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
                             .calTrigger = pIntervalPhyNode->window.triggerType};
6581

dengyihao's avatar
dengyihao 已提交
6582 6583 6584
    int32_t primaryTsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
    pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as,
                                       pTableGroupInfo, pTaskInfo);
6585 6586

    if (pIntervalPhyNode->pFill != NULL) {
dengyihao's avatar
dengyihao 已提交
6587 6588
      pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode, NULL,
                                     false, pTaskInfo);
6589 6590
    }

H
Haojun Liao 已提交
6591
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
H
Haojun Liao 已提交
6592
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6593

6594
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6595
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys, pSortPhyNode->pTargets);
6596
    SArray*      slotMap = createIndexMap(pSortPhyNode->pTargets);
6597
    pOptr = createSortOperatorInfo(ops[0], pResBlock, info, slotMap, pTaskInfo);
H
Haojun Liao 已提交
6598
  } else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
H
Haojun Liao 已提交
6599 6600
    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

dengyihao's avatar
dengyihao 已提交
6601 6602
    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};
6603

H
Haojun Liao 已提交
6604
    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
6605
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6606
    pOptr = createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, &as, pTaskInfo);
H
Haojun Liao 已提交
6607
  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
dengyihao's avatar
dengyihao 已提交
6608 6609 6610
    SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
    SArray*              pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
    SSDataBlock*         pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6611 6612

    SExprInfo* pExprInfo = createExprInfo(pPartNode->pTargets, NULL, &num);
6613
    pOptr = createPartitionOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pTaskInfo, NULL);
6614
  } else if (QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW == type) {
dengyihao's avatar
dengyihao 已提交
6615
    SStateWinodwPhysiNode* pStateNode = (SStateWinodwPhysiNode*)pPhyNode;
6616

6617 6618
    STimeWindowAggSupp as = {.waterMark = pStateNode->window.watermark, .calTrigger = pStateNode->window.triggerType};

dengyihao's avatar
dengyihao 已提交
6619
    SExprInfo*   pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &num);
6620
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6621
    pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, pTaskInfo);
6622
  } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
dengyihao's avatar
dengyihao 已提交
6623 6624
    SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6625 6626

    SExprInfo* pExprInfo = createExprInfo(pJoinNode->pTargets, NULL, &num);
6627
    pOptr = createJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
H
Haojun Liao 已提交
6628 6629
  } else {
    ASSERT(0);
H
Haojun Liao 已提交
6630
  }
6631 6632 6633

  taosMemoryFree(ops);
  return pOptr;
6634
}
H
Haojun Liao 已提交
6635 6636


6637 6638 6639 6640 6641 6642 6643
static  int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode) {
  pCond->loadExternalRows = false;

  pCond->order = pTableScanNode->scanSeq[0] > 0 ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
  pCond->numOfCols = LIST_LENGTH(pTableScanNode->scan.pScanCols);
  pCond->colList = taosMemoryCalloc(pCond->numOfCols, sizeof(SColumnInfo));
  if (pCond->colList == NULL) {
H
Haojun Liao 已提交
6644
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
6645 6646 6647 6648 6649 6650 6651 6652 6653 6654
    return terrno;
  }

  pCond->twindow = pTableScanNode->scanRange;

#if 1
  //todo work around a problem, remove it later
  if ((pCond->order == TSDB_ORDER_ASC && pCond->twindow.skey > pCond->twindow.ekey) ||
      (pCond->order == TSDB_ORDER_DESC && pCond->twindow.skey < pCond->twindow.ekey)) {
    TSWAP(pCond->twindow.skey, pCond->twindow.ekey, int64_t);
H
Haojun Liao 已提交
6655
  }
6656
#endif
H
Haojun Liao 已提交
6657

6658 6659
  pCond->type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
  //  pCond->type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
6660

H
Haojun Liao 已提交
6661
  int32_t j = 0;
6662
  for (int32_t i = 0; i < pCond->numOfCols; ++i) {
H
Haojun Liao 已提交
6663 6664
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6665 6666 6667
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
6668

6669 6670 6671
    pCond->colList[j].type = pColNode->node.resType.type;
    pCond->colList[j].bytes = pColNode->node.resType.bytes;
    pCond->colList[j].colId = pColNode->colId;
H
Haojun Liao 已提交
6672
    j += 1;
H
Haojun Liao 已提交
6673 6674
  }

6675 6676
  pCond->numOfCols = j;
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
6677
}
H
Haojun Liao 已提交
6678

H
Haojun Liao 已提交
6679
SArray* extractColumnInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
6680
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6681 6682 6683 6684 6685 6686
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6687 6688
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
H
Haojun Liao 已提交
6689

6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714
    if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN) {
      SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;

      // todo extract method
      SColumn c = {0};
      c.slotId  = pColNode->slotId;
      c.colId   = pColNode->colId;
      c.type    = pColNode->node.resType.type;
      c.bytes   = pColNode->node.resType.bytes;
      c.scale   = pColNode->node.resType.scale;
      c.precision = pColNode->node.resType.precision;

      taosArrayPush(pList, &c);
    } else if (nodeType(pNode->pExpr) == QUERY_NODE_VALUE) {
      SValueNode* pValNode = (SValueNode*) pNode->pExpr;
      SColumn c = {0};
      c.slotId = pNode->slotId;
      c.colId  = pNode->slotId;
      c.type   = pValNode->node.type;
      c.bytes  = pValNode->node.resType.bytes;
      c.scale  = pValNode->node.resType.scale;
      c.precision = pValNode->node.resType.precision;

      taosArrayPush(pList, &c);
    }
H
Haojun Liao 已提交
6715 6716 6717 6718 6719
  }

  return pList;
}

6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733
SArray* extractPartitionColInfo(SNodeList* pNodeList) {
  size_t  numOfCols = LIST_LENGTH(pNodeList);
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

  for (int32_t i = 0; i < numOfCols; ++i) {
    SColumnNode* pColNode = (SColumnNode*)nodesListGetNode(pNodeList, i);

    // todo extract method
    SColumn c = {0};
    c.slotId = pColNode->slotId;
dengyihao's avatar
dengyihao 已提交
6734 6735 6736
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
6737 6738 6739 6740 6741 6742 6743 6744 6745
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;

    taosArrayPush(pList, &c);
  }

  return pList;
}

6746
SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget) {
L
Liu Jicong 已提交
6747
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6748 6749 6750 6751 6752 6753
  SArray* pList = taosArrayInit(numOfCols, sizeof(SBlockOrderInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

L
Liu Jicong 已提交
6754
  for (int32_t i = 0; i < numOfCols; ++i) {
6755
    SOrderByExprNode* pSortKey = (SOrderByExprNode*)nodesListGetNode(pNodeList, i);
L
Liu Jicong 已提交
6756 6757
    SBlockOrderInfo   bi = {0};
    bi.order = (pSortKey->order == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
H
Haojun Liao 已提交
6758 6759 6760 6761
    bi.nullFirst = (pSortKey->nullOrder == NULL_ORDER_FIRST);

    SColumnNode* pColNode = (SColumnNode*)pSortKey->pExpr;

6762 6763 6764 6765 6766
    bool found = false;
    for (int32_t j = 0; j < LIST_LENGTH(pNodeListTarget); ++j) {
      STargetNode* pTarget = (STargetNode*)nodesListGetNode(pNodeListTarget, j);

      SColumnNode* pColNodeT = (SColumnNode*)pTarget->pExpr;
dengyihao's avatar
dengyihao 已提交
6767
      if (pColNode->slotId == pColNodeT->slotId) {  // to find slotId in PhysiSort OutputDataBlockDesc
6768 6769 6770 6771 6772 6773
        bi.slotId = pTarget->slotId;
        found = true;
        break;
      }
    }

dengyihao's avatar
dengyihao 已提交
6774
    if (!found) {
6775 6776
      qError("sort slot id does not found");
    }
H
Haojun Liao 已提交
6777 6778 6779 6780 6781 6782
    taosArrayPush(pList, &bi);
  }

  return pList;
}

6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800
SArray* createIndexMap(SNodeList* pNodeList) {
  size_t  numOfCols = LIST_LENGTH(pNodeList);
  SArray* pList = taosArrayInit(numOfCols, sizeof(int32_t));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pTarget = (STargetNode*)nodesListGetNode(pNodeList, i);

    SColumnNode* pColNode = (SColumnNode*)pTarget->pExpr;
    taosArrayPush(pList, &pColNode->slotId);
  }

  return pList;
}

H
Haojun Liao 已提交
6801
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols) {
L
Liu Jicong 已提交
6802
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6803 6804 6805 6806 6807 6808
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6809 6810 6811
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6812 6813

    SColMatchInfo c = {0};
6814
    c.output = true;
L
Liu Jicong 已提交
6815
    c.colId = pColNode->colId;
H
Haojun Liao 已提交
6816 6817 6818 6819
    c.targetSlotId = pNode->slotId;
    taosArrayPush(pList, &c);
  }

H
Haojun Liao 已提交
6820 6821
  *numOfOutputCols = 0;
  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
6822 6823
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
6824

6825
    // todo: add reserve flag check
6826 6827
    // it is a column reserved for the arithmetic expression calculation
    if (pNode->slotId >= numOfCols) {
6828 6829 6830 6831
      (*numOfOutputCols) += 1;
      continue;
    }

H
Haojun Liao 已提交
6832
    SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
H
Haojun Liao 已提交
6833 6834 6835 6836 6837
    if (pNode->output) {
      (*numOfOutputCols) += 1;
    } else {
      info->output = false;
    }
H
Haojun Liao 已提交
6838 6839
  }

H
Haojun Liao 已提交
6840 6841 6842
  return pList;
}

dengyihao's avatar
dengyihao 已提交
6843 6844
int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                           uint64_t queryId, uint64_t taskId) {
6845
  int32_t code = 0;
H
Haojun Liao 已提交
6846
  if (tableType == TSDB_SUPER_TABLE) {
H
Haojun Liao 已提交
6847
    code = tsdbQuerySTableByTagCond(metaHandle, tableUid, 0, NULL, 0, 0, NULL, pGroupInfo, NULL, 0, queryId, taskId);
H
Haojun Liao 已提交
6848
  } else {  // Create one table group.
H
Haojun Liao 已提交
6849
    code = tsdbGetOneTableGroup(metaHandle, tableUid, 0, pGroupInfo);
6850 6851 6852 6853
  }

  return code;
}
H
Haojun Liao 已提交
6854

6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872
SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo) {
  SArray* tableIdList = taosArrayInit(4, sizeof(uint64_t));

  if (pTableGroupInfo->numOfTables > 0) {
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, 0);
    ASSERT(taosArrayGetSize(pTableGroupInfo->pGroupList) == 1);

    // Transfer the Array of STableKeyInfo into uid list.
    size_t numOfTables = taosArrayGetSize(pa);
    for (int32_t i = 0; i < numOfTables; ++i) {
      STableKeyInfo* pkeyInfo = taosArrayGet(pa, i);
      taosArrayPush(tableIdList, &pkeyInfo->uid);
    }
  }

  return tableIdList;
}

L
Liu Jicong 已提交
6873 6874
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                               STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId) {
6875
  uint64_t uid = pTableScanNode->scan.uid;
L
Liu Jicong 已提交
6876 6877
  int32_t  code =
      doCreateTableGroup(pHandle->meta, pTableScanNode->scan.tableType, uid, pTableGroupInfo, queryId, taskId);
6878 6879
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
H
Haojun Liao 已提交
6880
  }
H
Haojun Liao 已提交
6881

H
Haojun Liao 已提交
6882
  if (pTableGroupInfo->numOfTables == 0) {
H
Haojun Liao 已提交
6883
    code = 0;
L
Liu Jicong 已提交
6884
    qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
H
Haojun Liao 已提交
6885 6886
    goto _error;
  }
H
Haojun Liao 已提交
6887

6888 6889 6890 6891 6892 6893 6894
  SQueryTableDataCond cond = {0};
  code = initQueryTableDataCond(&cond, pTableScanNode);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

  return tsdbQueryTables(pHandle->reader, &cond, pTableGroupInfo, queryId, taskId);
H
Haojun Liao 已提交
6895

L
Liu Jicong 已提交
6896
_error:
H
Haojun Liao 已提交
6897 6898 6899 6900
  terrno = code;
  return NULL;
}

dengyihao's avatar
dengyihao 已提交
6901 6902
int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
                               EOPTR_EXEC_MODEL model) {
H
Haojun Liao 已提交
6903 6904
  uint64_t queryId = pPlan->id.queryId;

H
Haojun Liao 已提交
6905
  int32_t code = TSDB_CODE_SUCCESS;
6906
  *pTaskInfo = createExecTaskInfo(queryId, taskId, model);
H
Haojun Liao 已提交
6907 6908 6909 6910
  if (*pTaskInfo == NULL) {
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    goto _complete;
  }
H
Haojun Liao 已提交
6911

6912
  (*pTaskInfo)->pRoot = createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoGroupInfo);
D
dapan1121 已提交
6913
  if (NULL == (*pTaskInfo)->pRoot) {
L
Liu Jicong 已提交
6914
    code = terrno;
D
dapan1121 已提交
6915 6916
    goto _complete;
  }
H
Haojun Liao 已提交
6917

6918
  if ((*pTaskInfo)->pRoot == NULL) {
H
Haojun Liao 已提交
6919
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
H
Haojun Liao 已提交
6920
    goto _complete;
6921 6922
  }

H
Haojun Liao 已提交
6923 6924
  return code;

H
Haojun Liao 已提交
6925
_complete:
wafwerar's avatar
wafwerar 已提交
6926
  taosMemoryFreeClear(*pTaskInfo);
H
Haojun Liao 已提交
6927 6928 6929

  terrno = code;
  return code;
H
Haojun Liao 已提交
6930 6931
}

L
Liu Jicong 已提交
6932 6933
static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SColumnInfo* pTagCols, SExprInfo* pExprs,
                                             int32_t numOfOutput, int32_t tagLen, bool superTable) {
6934 6935 6936 6937 6938 6939 6940 6941 6942
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int16_t functId = getExprFunctionId(&pExprs[i]);

    if (functId == FUNCTION_TOP || functId == FUNCTION_BOTTOM) {
      int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols);
      if (j < 0 || j >= pTableInfo->numOfCols) {
        return TSDB_CODE_QRY_INVALID_MSG;
      } else {
        SColumnInfo* pCol = &pTableInfo->colList[j];
L
Liu Jicong 已提交
6943 6944 6945 6946
        //        int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i,
        //                                        &pExprs[i].base.resSchema.type, &pExprs[i].base.resSchema.bytes,
        //                                        &pExprs[i].base.interBytes, tagLen, superTable, NULL);
        //        assert(ret == TSDB_CODE_SUCCESS);
6947 6948 6949 6950 6951 6952 6953
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
6954
void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo) {
6955 6956 6957 6958 6959 6960 6961 6962
  const int32_t DEFAULT_RESULT_MSG_SIZE = 1024 * (1024 + 512);

  // the minimum number of rows for projection query
  const int32_t MIN_ROWS_FOR_PRJ_QUERY = 8192;
  const int32_t DEFAULT_MIN_ROWS = 4096;

  const float THRESHOLD_RATIO = 0.85f;

dengyihao's avatar
dengyihao 已提交
6963 6964 6965 6966 6967 6968 6969 6970 6971 6972
  //  if (isProjQuery(pQueryAttr)) {
  //    int32_t numOfRes = DEFAULT_RESULT_MSG_SIZE / pQueryAttr->resultRowSize;
  //    if (numOfRes < MIN_ROWS_FOR_PRJ_QUERY) {
  //      numOfRes = MIN_ROWS_FOR_PRJ_QUERY;
  //    }
  //
  //    pResultInfo->capacity = numOfRes;
  //  } else {  // in case of non-prj query, a smaller output buffer will be used.
  //    pResultInfo->capacity = DEFAULT_MIN_ROWS;
  //  }
6973 6974

  pResultInfo->threshold = (int32_t)(pResultInfo->capacity * THRESHOLD_RATIO);
H
Haojun Liao 已提交
6975
  pResultInfo->totalRows = 0;
6976 6977
}

L
Liu Jicong 已提交
6978
// TODO refactor
6979
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
L
Liu Jicong 已提交
6980 6981 6982
  if (pFilter == NULL || numOfFilters == 0) {
    return;
  }
6983

L
Liu Jicong 已提交
6984 6985 6986
  for (int32_t i = 0; i < numOfFilters; i++) {
    if (pFilter[i].filterstr && pFilter[i].pz) {
      taosMemoryFree((void*)(pFilter[i].pz));
6987
    }
L
Liu Jicong 已提交
6988
  }
6989

L
Liu Jicong 已提交
6990
  taosMemoryFree(pFilter);
6991 6992 6993 6994
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
  if (pTableqinfoGroupInfo->pGroupList != NULL) {
L
Liu Jicong 已提交
6995
    int32_t numOfGroups = (int32_t)taosArrayGetSize(pTableqinfoGroupInfo->pGroupList);
6996
    for (int32_t i = 0; i < numOfGroups; ++i) {
L
Liu Jicong 已提交
6997
      SArray* p = taosArrayGetP(pTableqinfoGroupInfo->pGroupList, i);
6998 6999

      size_t num = taosArrayGetSize(p);
L
Liu Jicong 已提交
7000
      for (int32_t j = 0; j < num; ++j) {
7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016
        STableQueryInfo* item = taosArrayGetP(p, j);
        destroyTableQueryInfoImpl(item);
      }

      taosArrayDestroy(p);
    }
  }

  taosArrayDestroy(pTableqinfoGroupInfo->pGroupList);
  taosHashCleanup(pTableqinfoGroupInfo->map);

  pTableqinfoGroupInfo->pGroupList = NULL;
  pTableqinfoGroupInfo->map = NULL;
  pTableqinfoGroupInfo->numOfTables = 0;
}

L
Liu Jicong 已提交
7017
void doDestroyTask(SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
7018 7019
  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));

H
Haojun Liao 已提交
7020
  doDestroyTableQueryInfo(&pTaskInfo->tableqinfoGroupInfo);
L
Liu Jicong 已提交
7021 7022
  //  taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
  //  taosHashCleanup(pTaskInfo->summary.operatorProfResults);
7023

wafwerar's avatar
wafwerar 已提交
7024 7025 7026
  taosMemoryFreeClear(pTaskInfo->sql);
  taosMemoryFreeClear(pTaskInfo->id.str);
  taosMemoryFreeClear(pTaskInfo);
7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038
}

static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes) {
  if (val == NULL) {
    setNull(output, type, bytes);
    return;
  }

  if (IS_VAR_DATA_TYPE(type)) {
    // Binary data overflows for sort of unknown reasons. Let trim the overflow data
    if (varDataTLen(val) > bytes) {
      int32_t maxLen = bytes - VARSTR_HEADER_SIZE;
L
Liu Jicong 已提交
7039
      int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051
      memcpy(varDataVal(output), varDataVal(val), len);
      varDataSetLen(output, len);
    } else {
      varDataCopy(output, val);
    }
  } else {
    memcpy(output, val, bytes);
  }
}

static int64_t getQuerySupportBufSize(size_t numOfTables) {
  size_t s1 = sizeof(STableQueryInfo);
L
Liu Jicong 已提交
7052 7053
  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
  return (int64_t)(s1 * 1.5 * numOfTables);
7054 7055 7056 7057 7058 7059 7060
}

int32_t checkForQueryBuf(size_t numOfTables) {
  int64_t t = getQuerySupportBufSize(numOfTables);
  if (tsQueryBufferSizeBytes < 0) {
    return TSDB_CODE_SUCCESS;
  } else if (tsQueryBufferSizeBytes > 0) {
L
Liu Jicong 已提交
7061
    while (1) {
7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087
      int64_t s = tsQueryBufferSizeBytes;
      int64_t remain = s - t;
      if (remain >= 0) {
        if (atomic_val_compare_exchange_64(&tsQueryBufferSizeBytes, s, remain) == s) {
          return TSDB_CODE_SUCCESS;
        }
      } else {
        return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER;
      }
    }
  }

  // disable query processing if the value of tsQueryBufferSize is zero.
  return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER;
}

void releaseQueryBuf(size_t numOfTables) {
  if (tsQueryBufferSizeBytes < 0) {
    return;
  }

  int64_t t = getQuerySupportBufSize(numOfTables);

  // restore value is not enough buffer available
  atomic_add_fetch_64(&tsQueryBufferSizeBytes, t);
}
D
dapan1121 已提交
7088

dengyihao's avatar
dengyihao 已提交
7089 7090
int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo** pRes, int32_t* capacity,
                                   int32_t* resNum) {
D
dapan1121 已提交
7091 7092
  if (*resNum >= *capacity) {
    *capacity += 10;
dengyihao's avatar
dengyihao 已提交
7093

D
dapan1121 已提交
7094 7095
    *pRes = taosMemoryRealloc(*pRes, (*capacity) * sizeof(SExplainExecInfo));
    if (NULL == *pRes) {
D
dapan1121 已提交
7096
      qError("malloc %d failed", (*capacity) * (int32_t)sizeof(SExplainExecInfo));
D
dapan1121 已提交
7097 7098 7099 7100
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

D
dapan1121 已提交
7101 7102 7103 7104
  (*pRes)[*resNum].numOfRows = operatorInfo->resultInfo.totalRows;
  (*pRes)[*resNum].startupCost = operatorInfo->cost.openCost;
  (*pRes)[*resNum].totalCost = operatorInfo->cost.totalCost;

7105 7106
  if (operatorInfo->fpSet.getExplainFn) {
    int32_t code = (*operatorInfo->fpSet.getExplainFn)(operatorInfo, &(*pRes)->verboseInfo);
D
dapan1121 已提交
7107 7108 7109 7110 7111
    if (code) {
      qError("operator getExplainFn failed, error:%s", tstrerror(code));
      return code;
    }
  }
dengyihao's avatar
dengyihao 已提交
7112

D
dapan1121 已提交
7113
  ++(*resNum);
dengyihao's avatar
dengyihao 已提交
7114

D
dapan1121 已提交
7115
  int32_t code = 0;
D
dapan1121 已提交
7116 7117
  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pRes, capacity, resNum);
D
dapan1121 已提交
7118 7119 7120 7121 7122 7123 7124
    if (code) {
      taosMemoryFreeClear(*pRes);
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
7125 7126
}

7127 7128
static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup) {
  SJoinOperatorInfo* pJoinInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
7129
  //  SOptrBasicInfo* pInfo = &pJoinInfo->binfo;
7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142

  SSDataBlock* pRes = pJoinInfo->pRes;
  blockDataCleanup(pRes);
  blockDataEnsureCapacity(pRes, 4096);

  int32_t nrows = 0;

  while (1) {
    bool prevVal = *newgroup;

    if (pJoinInfo->pLeft == NULL || pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
      SOperatorInfo* ds1 = pOperator->pDownstream[0];
      publishOperatorProfEvent(ds1, QUERY_PROF_BEFORE_OPERATOR_EXEC);
7143
      pJoinInfo->pLeft = ds1->fpSet.getNextFn(ds1, newgroup);
7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155
      publishOperatorProfEvent(ds1, QUERY_PROF_AFTER_OPERATOR_EXEC);

      pJoinInfo->leftPos = 0;
      if (pJoinInfo->pLeft == NULL) {
        setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
        break;
      }
    }

    if (pJoinInfo->pRight == NULL || pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
      SOperatorInfo* ds2 = pOperator->pDownstream[1];
      publishOperatorProfEvent(ds2, QUERY_PROF_BEFORE_OPERATOR_EXEC);
7156
      pJoinInfo->pRight = ds2->fpSet.getNextFn(ds2, newgroup);
7157 7158 7159 7160 7161 7162 7163 7164 7165 7166
      publishOperatorProfEvent(ds2, QUERY_PROF_AFTER_OPERATOR_EXEC);

      pJoinInfo->rightPos = 0;
      if (pJoinInfo->pRight == NULL) {
        setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
        break;
      }
    }

    SColumnInfoData* pLeftCol = taosArrayGet(pJoinInfo->pLeft->pDataBlock, pJoinInfo->leftCol.slotId);
dengyihao's avatar
dengyihao 已提交
7167
    char*            pLeftVal = colDataGetData(pLeftCol, pJoinInfo->leftPos);
7168 7169

    SColumnInfoData* pRightCol = taosArrayGet(pJoinInfo->pRight->pDataBlock, pJoinInfo->rightCol.slotId);
dengyihao's avatar
dengyihao 已提交
7170
    char*            pRightVal = colDataGetData(pRightCol, pJoinInfo->rightPos);
7171 7172

    // only the timestamp match support for ordinary table
dengyihao's avatar
dengyihao 已提交
7173 7174 7175 7176
    ASSERT(pLeftCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
    if (*(int64_t*)pLeftVal == *(int64_t*)pRightVal) {
      for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
        SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, i);
7177

dengyihao's avatar
dengyihao 已提交
7178
        SExprInfo* pExprInfo = &pOperator->pExpr[i];
7179

dengyihao's avatar
dengyihao 已提交
7180 7181
        int32_t blockId = pExprInfo->base.pParam[0].pCol->dataBlockId;
        int32_t slotId = pExprInfo->base.pParam[0].pCol->slotId;
7182

dengyihao's avatar
dengyihao 已提交
7183 7184 7185 7186 7187 7188
        SColumnInfoData* pSrc = NULL;
        if (pJoinInfo->pLeft->info.blockId == blockId) {
          pSrc = taosArrayGet(pJoinInfo->pLeft->pDataBlock, slotId);
        } else {
          pSrc = taosArrayGet(pJoinInfo->pRight->pDataBlock, slotId);
        }
7189

dengyihao's avatar
dengyihao 已提交
7190 7191 7192 7193 7194
        if (colDataIsNull_s(pSrc, pJoinInfo->leftPos)) {
          colDataAppendNULL(pDst, nrows);
        } else {
          char* p = colDataGetData(pSrc, pJoinInfo->leftPos);
          colDataAppend(pDst, nrows, p, false);
7195
        }
dengyihao's avatar
dengyihao 已提交
7196
      }
7197

dengyihao's avatar
dengyihao 已提交
7198 7199
      pJoinInfo->leftPos += 1;
      pJoinInfo->rightPos += 1;
7200

dengyihao's avatar
dengyihao 已提交
7201 7202 7203
      nrows += 1;
    } else if (*(int64_t*)pLeftVal < *(int64_t*)pRightVal) {
      pJoinInfo->leftPos += 1;
D
dapan1121 已提交
7204

dengyihao's avatar
dengyihao 已提交
7205 7206
      if (pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
        continue;
7207
      }
dengyihao's avatar
dengyihao 已提交
7208 7209 7210 7211
    } else if (*(int64_t*)pLeftVal > *(int64_t*)pRightVal) {
      pJoinInfo->rightPos += 1;
      if (pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
        continue;
7212
      }
dengyihao's avatar
dengyihao 已提交
7213
    }
7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224

    // the pDataBlock are always the same one, no need to call this again
    pRes->info.rows = nrows;
    if (pRes->info.rows >= pOperator->resultInfo.threshold) {
      break;
    }
  }

  return (pRes->info.rows > 0) ? pRes : NULL;
}

dengyihao's avatar
dengyihao 已提交
7225 7226 7227
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                      int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
                                      SExecTaskInfo* pTaskInfo) {
7228
  SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
dengyihao's avatar
dengyihao 已提交
7229
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
7230 7231 7232 7233 7234 7235 7236
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }

  pOperator->resultInfo.capacity = 4096;
  pOperator->resultInfo.threshold = 4096 * 0.75;

dengyihao's avatar
dengyihao 已提交
7237 7238 7239
  //  initResultRowInf
  //  o(&pInfo->binfo.resultRowInfo, 8);
  pInfo->pRes = pResBlock;
7240

dengyihao's avatar
dengyihao 已提交
7241
  pOperator->name = "JoinOperator";
7242
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_JOIN;
7243
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
7244 7245 7246 7247 7248
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
7249

7250 7251
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doMergeJoin, NULL, NULL, destroyBasicOperatorInfo,
                                         NULL, NULL, NULL);
7252 7253 7254
  int32_t code = appendDownstream(pOperator, pDownstream, numOfDownstream);
  return pOperator;

dengyihao's avatar
dengyihao 已提交
7255
_error:
7256 7257 7258 7259
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
dengyihao's avatar
dengyihao 已提交
7260
}