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
  // 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);
5000
    return PROJECT_RETRIEVE_DONE;
5001
  }
5002

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (pBlock == NULL) {
      break;
    }

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

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

dengyihao's avatar
dengyihao 已提交
5130
#if 0  // test for encode/decode result info
5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141
    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);
      }
5142
    }
5143
#endif
5144 5145
  }

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

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

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

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

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

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

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

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

5181
    return pBlock->info.rows == 0 ? NULL : pBlock;
5182 5183 5184
  }
}

dengyihao's avatar
dengyihao 已提交
5185
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5186
  STableIntervalOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5187
  int32_t                     order = TSDB_ORDER_ASC;
5188 5189 5190 5191 5192 5193

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

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5194 5195
    doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5196 5197 5198
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      pOperator->status = OP_EXEC_DONE;
    }
5199
    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5200 5201 5202
  }

  //  STimeWindow win = {0};
5203
  *newgroup = false;
5204 5205 5206 5207 5208 5209
  SOperatorInfo* downstream = pOperator->pDownstream[0];

  SArray* pUpdated = NULL;

  while (1) {
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5210
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
5211 5212 5213 5214 5215 5216
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);

    if (pBlock == NULL) {
      break;
    }

dengyihao's avatar
dengyihao 已提交
5217 5218
    // 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.
5219 5220 5221

    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    // the pDataBlock are always the same one, no need to call this again
5222
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
5223 5224 5225
    pUpdated = hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0);
  }

dengyihao's avatar
dengyihao 已提交
5226 5227
  finalizeUpdatedResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, pUpdated,
                        pInfo->binfo.rowCellInfoOffset);
5228

H
Haojun Liao 已提交
5229
  initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
5230
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5231 5232
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5233 5234 5235 5236 5237 5238 5239

  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 已提交
5240
static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5241 5242 5243 5244
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5245
  STimeSliceOperatorInfo* pSliceInfo = pOperator->info;
5246
  if (pOperator->status == OP_RES_TO_RETURN) {
5247
    //    doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
5248
    if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5249 5250 5251
      doSetOperatorCompleted(pOperator);
    }

5252
    return pSliceInfo->binfo.pRes;
5253 5254
  }

dengyihao's avatar
dengyihao 已提交
5255 5256
  int32_t order = TSDB_ORDER_ASC;
  //  STimeWindow win = pQueryAttr->window;
H
Haojun Liao 已提交
5257
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5258

L
Liu Jicong 已提交
5259
  while (1) {
H
Haojun Liao 已提交
5260
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5261
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5262
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5263 5264 5265 5266
    if (pBlock == NULL) {
      break;
    }

L
Liu Jicong 已提交
5267
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5268
    // the pDataBlock are always the same one, no need to call this again
5269
    setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true);
dengyihao's avatar
dengyihao 已提交
5270
    //    hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
5271 5272 5273 5274
  }

  // restore the value
  pOperator->status = OP_RES_TO_RETURN;
5275
  closeAllResultRows(&pSliceInfo->binfo.resultRowInfo);
5276
  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
dengyihao's avatar
dengyihao 已提交
5277
  //  finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfOutput);
5278

5279
//  initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
5280
  //  doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
5281

5282
  if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5283 5284 5285
    pOperator->status = OP_EXEC_DONE;
  }

5286
  return pSliceInfo->binfo.pRes->info.rows == 0 ? NULL : pSliceInfo->binfo.pRes;
5287 5288
}

L
Liu Jicong 已提交
5289
static SSDataBlock* doSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5290 5291 5292 5293
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5294
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
5295

5296
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5297 5298
  if (pOperator->status == OP_RES_TO_RETURN) {
    int64_t st = taosGetTimestampUs();
5299
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5300 5301
      doSetOperatorCompleted(pOperator);
    }
5302 5303

    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5304 5305
  }

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

L
Liu Jicong 已提交
5308
  while (1) {
H
Haojun Liao 已提交
5309
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5310
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5311
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5312 5313 5314 5315 5316 5317

    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
L
Liu Jicong 已提交
5318
    //    setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5319
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC, true);
5320
    STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;
5321

5322
    setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window);
dengyihao's avatar
dengyihao 已提交
5323
    //    hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pBlock->info.groupId);
5324 5325
  }

5326 5327 5328
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5329

5330
//  initGroupedResultInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
5331 5332
  OPTR_SET_OPENED(pOperator);

5333
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5334 5335
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5336 5337 5338

  if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5339 5340
  }

5341
  return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5342 5343
}

5344
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) {
dengyihao's avatar
dengyihao 已提交
5345
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
5346 5347
  SOptrBasicInfo* pBInfo = &pInfo->binfo;

5348
  SColumnInfoData* pStateColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->colIndex);
dengyihao's avatar
dengyihao 已提交
5349
  int64_t          gid = pBlock->info.groupId;
5350

5351 5352 5353 5354 5355 5356 5357 5358
  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;
5359

5360 5361
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;
dengyihao's avatar
dengyihao 已提交
5362

5363 5364
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
    if (colDataIsNull(pStateColInfoData, pBlock->info.rows, j, pBlock->pBlockAgg)) {
5365 5366
      continue;
    }
5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379

    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;
5380
      }
5381
    } else {  // a new state window started
5382
      SResultRow* pResult = NULL;
5383 5384 5385 5386 5387 5388

      // 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 已提交
5389 5390
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
5391
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5392
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5393 5394
      }

5395
      updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
dengyihao's avatar
dengyihao 已提交
5396 5397
      doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                       pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5398 5399 5400 5401

      // here we start a new session window
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
5402 5403 5404 5405
    }
  }

  SResultRow* pResult = NULL;
5406
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
5407 5408 5409
  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);
5410
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5411
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5412 5413
  }

5414
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
dengyihao's avatar
dengyihao 已提交
5415 5416
  doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                   pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5417 5418
}

L
Liu Jicong 已提交
5419
static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5420 5421 5422 5423
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5424
  SStateWindowOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5425 5426
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
  SOptrBasicInfo*           pBInfo = &pInfo->binfo;
5427 5428

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5429 5430
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5431 5432 5433 5434
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
    }
5435 5436 5437 5438

    return pBInfo->pRes;
  }

dengyihao's avatar
dengyihao 已提交
5439 5440
  int32_t     order = TSDB_ORDER_ASC;
  STimeWindow win = pTaskInfo->window;
H
Haojun Liao 已提交
5441

H
Haojun Liao 已提交
5442
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5443
  while (1) {
H
Haojun Liao 已提交
5444
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5445
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5446
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5447 5448 5449 5450

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
5451

5452
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5453
    doStateWindowAggImpl(pOperator, pInfo, pBlock);
5454 5455 5456 5457
  }

  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pBInfo->resultRowInfo);
dengyihao's avatar
dengyihao 已提交
5458 5459
  finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
                                pBInfo->rowCellInfoOffset);
5460

5461
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5462
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5463 5464
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5465 5466 5467
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
5468

L
Liu Jicong 已提交
5469
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5470 5471
}

L
Liu Jicong 已提交
5472
static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5473 5474 5475 5476
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5477
  SSessionAggOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5478
  SOptrBasicInfo*          pBInfo = &pInfo->binfo;
5479 5480

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5481 5482
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5483 5484 5485
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
5486 5487 5488 5489 5490
    }

    return pBInfo->pRes;
  }

L
Liu Jicong 已提交
5491
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
5492
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5493

L
Liu Jicong 已提交
5494
  while (1) {
H
Haojun Liao 已提交
5495
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5496
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5497
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5498 5499 5500 5501 5502
    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
5503
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5504
    doSessionWindowAggImpl(pOperator, pInfo, pBlock);
5505 5506 5507 5508 5509
  }

  // restore the value
  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pBInfo->resultRowInfo);
dengyihao's avatar
dengyihao 已提交
5510 5511
  finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
                                pBInfo->rowCellInfoOffset);
5512

5513
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5514
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5515 5516
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5517 5518
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5519 5520
  }

L
Liu Jicong 已提交
5521
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5522 5523
}

L
Liu Jicong 已提交
5524 5525
static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                               SExecTaskInfo* pTaskInfo) {
5526
  pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows;
H
Haojun Liao 已提交
5527

L
Liu Jicong 已提交
5528 5529
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
5530 5531
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

5532
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
5533 5534
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

H
Haojun Liao 已提交
5535
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity, pInfo->p);
5536 5537 5538 5539
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
5540 5541
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
5542 5543
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
H
Haojun Liao 已提交
5544 5545
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity, pInfo->p);
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
5546 5547 5548 5549 5550 5551
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
5552
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5553 5554 5555
  }
}

L
Liu Jicong 已提交
5556 5557 5558
static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
5559

H
Haojun Liao 已提交
5560
  SResultInfo* pResultInfo = &pOperator->resultInfo;
5561 5562 5563
  SSDataBlock* pResBlock = pInfo->pRes;

  blockDataCleanup(pResBlock);
5564 5565 5566 5567
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5568
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5569 5570
  if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
    return pResBlock;
H
Haojun Liao 已提交
5571
  }
5572

H
Haojun Liao 已提交
5573
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
5574
  while (1) {
H
Haojun Liao 已提交
5575
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5576
    SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream, newgroup);
H
Haojun Liao 已提交
5577
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588

    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
5589
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5590 5591 5592 5593 5594 5595 5596
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

5597
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5598 5599 5600 5601 5602 5603 5604
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

5605
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity, pInfo->p);
5606 5607

    // current group has no more result to return
5608
    if (pResBlock->info.rows > 0) {
5609 5610
      // 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
5611 5612
      if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
        return pResBlock;
5613 5614
      }

5615
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5616 5617
      if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
        return pResBlock;
5618 5619 5620
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
5621
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5622 5623
      if (pResBlock->info.rows > pResultInfo->threshold) {
        return pResBlock;
5624 5625 5626 5627 5628 5629 5630 5631
      }
    } else {
      return NULL;
    }
  }
}

// todo set the attribute of query scan count
H
Haojun Liao 已提交
5632
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
L
Liu Jicong 已提交
5633
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647
    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;
  }

5648 5649
  if (pOperator->fpSet.closeFn != NULL) {
    pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfOutput);
5650 5651
  }

H
Haojun Liao 已提交
5652
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
5653
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
5654
      destroyOperatorInfo(pOperator->pDownstream[i]);
5655 5656
    }

wafwerar's avatar
wafwerar 已提交
5657
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
5658
    pOperator->numOfDownstream = 0;
5659 5660
  }

wafwerar's avatar
wafwerar 已提交
5661 5662
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
5663 5664
}

dengyihao's avatar
dengyihao 已提交
5665 5666
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                         const char* pKey) {
5667 5668
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

dengyihao's avatar
dengyihao 已提交
5669 5670
  pAggSup->resultRowSize = getResultRowSize(pCtx, numOfOutput);
  pAggSup->keyBuf = taosMemoryCalloc(1, keyBufSize + POINTER_BYTES + sizeof(int64_t));
5671
  pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK);
5672 5673
//  pAggSup->pResultRowListSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
//  pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell));
5674

5675
  if (pAggSup->keyBuf == NULL /*|| pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL*/ ||
5676
      pAggSup->pResultRowHashTable == NULL) {
5677 5678 5679
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
5680 5681 5682 5683 5684
  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, 4096, 4096 * 256, pKey, "/tmp/");
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

5685 5686 5687
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
5688
static void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
5689
  taosMemoryFreeClear(pAggSup->keyBuf);
5690
  taosHashCleanup(pAggSup->pResultRowHashTable);
5691 5692
//  taosHashCleanup(pAggSup->pResultRowListSet);
//  taosArrayDestroy(pAggSup->pResultRowArrayList);
H
Haojun Liao 已提交
5693
  destroyDiskbasedBuf(pAggSup->pResultBuf);
5694 5695
}

H
Haojun Liao 已提交
5696
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
5697
                    SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey) {
5698
  pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5699 5700
  pBasicInfo->pRes = pResultBlock;

5701
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, keyBufSize, pkey);
5702 5703 5704 5705 5706

  for(int32_t i = 0; i < numOfCols; ++i) {
    pBasicInfo->pCtx[i].pBuf = pAggSup->pResultBuf;
  }

5707
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
5708 5709
}

5710 5711 5712 5713 5714 5715 5716 5717 5718
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 已提交
5719
static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5720
  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
H
Haojun Liao 已提交
5721 5722
  if (pTableQueryInfo == NULL) {
    return NULL;
H
Haojun Liao 已提交
5723
  }
H
Haojun Liao 已提交
5724 5725

  int32_t index = 0;
L
Liu Jicong 已提交
5726
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
H
Haojun Liao 已提交
5727
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
L
Liu Jicong 已提交
5728
    for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
H
Haojun Liao 已提交
5729 5730
      STableKeyInfo* pk = taosArrayGet(pa, j);

H
Haojun Liao 已提交
5731
      STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
dengyihao's avatar
dengyihao 已提交
5732
      //      pTQueryInfo->uid = pk->uid;
L
Liu Jicong 已提交
5733
      pTQueryInfo->lastKey = pk->lastKey;
dengyihao's avatar
dengyihao 已提交
5734
      //      pTQueryInfo->groupIndex = i;
H
Haojun Liao 已提交
5735 5736
    }
  }
H
Haojun Liao 已提交
5737 5738

  STimeWindow win = {0, INT64_MAX};
H
Haojun Liao 已提交
5739 5740
  createTableQueryInfo(pTableQueryInfo, false, win);
  return pTableQueryInfo;
H
Haojun Liao 已提交
5741 5742
}

L
Liu Jicong 已提交
5743
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5744
                                           SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
5745
                                           int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5746
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
5747
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5748 5749 5750
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5751

H
Haojun Liao 已提交
5752
  int32_t numOfRows = 1;
dengyihao's avatar
dengyihao 已提交
5753
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5754 5755

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
5756 5757
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResultBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
5758 5759
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) {
H
Haojun Liao 已提交
5760 5761
    goto _error;
  }
H
Haojun Liao 已提交
5762

H
Haojun Liao 已提交
5763 5764 5765 5766 5767 5768 5769
  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);

5770 5771
  pInfo->pScalarExprInfo = pScalarExprInfo;
  pInfo->numOfScalarExpr = numOfScalarExpr;
5772 5773 5774
  if (pInfo->pScalarExprInfo != NULL) {
    pInfo->pScalarCtx = createSqlFunctionCtx(pScalarExprInfo, numOfCols, &pInfo->rowCellInfoOffset);
  }
5775

dengyihao's avatar
dengyihao 已提交
5776
  pOperator->name = "TableAggregate";
X
Xiaoyu Wang 已提交
5777
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
5778
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5779 5780 5781 5782 5783
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
5784

5785 5786
  pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
H
Haojun Liao 已提交
5787 5788 5789 5790 5791

  code = appendDownstream(pOperator, &downstream, 1);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
5792 5793

  return pOperator;
L
Liu Jicong 已提交
5794
_error:
H
Haojun Liao 已提交
5795
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5796 5797
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5798 5799
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5800 5801
}

H
Haojun Liao 已提交
5802
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
5803 5804
  assert(pInfo != NULL);

5805
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
5806
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
5807 5808

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
5809
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
5810 5811
}

H
Haojun Liao 已提交
5812
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5813
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
5814 5815
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
5816 5817

void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5818
  SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param;
5819
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
5820
  taosMemoryFreeClear(pInfo->stateKey.pData);
5821
}
H
Haojun Liao 已提交
5822 5823

void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5824
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
5825 5826
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
5827

H
Haojun Liao 已提交
5828
void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5829
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)param;
H
Haojun Liao 已提交
5830 5831 5832 5833 5834
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
  cleanupAggSup(&pInfo->aggSup);
}

void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5835
  SSessionAggOperatorInfo* pInfo = (SSessionAggOperatorInfo*)param;
5836 5837 5838
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5839
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5840
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
5841
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
5842
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
5843
  taosMemoryFreeClear(pInfo->p);
5844 5845
}

H
Haojun Liao 已提交
5846
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5847
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
5848 5849 5850
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5851
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5852
  SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
H
Haojun Liao 已提交
5853 5854
  pInfo->pDataBlock = blockDataDestroy(pInfo->pDataBlock);

H
Haojun Liao 已提交
5855
  taosArrayDestroy(pInfo->pSortInfo);
5856
  taosArrayDestroy(pInfo->inputSlotMap);
5857 5858
}

H
Haojun Liao 已提交
5859
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5860
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
5861 5862 5863 5864 5865 5866 5867 5868 5869
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

H
Haojun Liao 已提交
5870 5871
static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols) {
  SArray* pList = taosArrayInit(4, sizeof(int32_t));
dengyihao's avatar
dengyihao 已提交
5872
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
5873 5874 5875 5876 5877 5878 5879 5880
    if (fmIsPseudoColumnFunc(pCtx[i].functionId)) {
      taosArrayPush(pList, &i);
    }
  }

  return pList;
}

L
Liu Jicong 已提交
5881
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
dengyihao's avatar
dengyihao 已提交
5882 5883
                                         SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit,
                                         SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5884
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
5885
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5886 5887 5888
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
5889

dengyihao's avatar
dengyihao 已提交
5890 5891 5892
  pInfo->limit = *pLimit;
  pInfo->slimit = *pSlimit;
  pInfo->curOffset = pLimit->offset;
H
Haojun Liao 已提交
5893 5894
  pInfo->curSOffset = pSlimit->offset;

H
Haojun Liao 已提交
5895
  pInfo->binfo.pRes = pResBlock;
H
Haojun Liao 已提交
5896 5897 5898

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5899
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5900 5901 5902

  initResultSizeInfo(pOperator, numOfRows);
  initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
5903
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
H
Haojun Liao 已提交
5904
  pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pInfo->binfo.pCtx, numOfCols);
5905

dengyihao's avatar
dengyihao 已提交
5906
  pOperator->name = "ProjectOperator";
H
Haojun Liao 已提交
5907
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
5908
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
5909 5910 5911 5912
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = num;
5913 5914 5915

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL, destroyProjectOperatorInfo,
                                         NULL, NULL, NULL);
L
Liu Jicong 已提交
5916 5917

  pOperator->pTaskInfo = pTaskInfo;
5918
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5919
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
5920 5921
    goto _error;
  }
5922 5923

  return pOperator;
H
Haojun Liao 已提交
5924

L
Liu Jicong 已提交
5925
_error:
H
Haojun Liao 已提交
5926 5927
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5928 5929
}

L
Liu Jicong 已提交
5930
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5931
                                          SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
dengyihao's avatar
dengyihao 已提交
5932 5933
                                          STimeWindowAggSupp* pTwAggSupp, const STableGroupInfo* pTableGroupInfo,
                                          SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5934
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
L
Liu Jicong 已提交
5935
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5936 5937 5938
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5939

5940 5941
  pInfo->order          = TSDB_ORDER_ASC;
  pInfo->interval       = *pInterval;
H
Haojun Liao 已提交
5942 5943
//  pInfo->execModel      = OPTR_EXEC_MODEL_STREAM;
  pInfo->execModel      = pTaskInfo->execModel;
5944 5945
  pInfo->win            = pTaskInfo->window;
  pInfo->twAggSup       = *pTwAggSupp;
5946
  pInfo->primaryTsIndex = primaryTsSlotId;
5947

5948
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5949
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5950 5951

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
5952 5953
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
5954
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);
5955

L
Liu Jicong 已提交
5956 5957
  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
H
Haojun Liao 已提交
5958 5959
    goto _error;
  }
H
Haojun Liao 已提交
5960 5961

  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
5962

dengyihao's avatar
dengyihao 已提交
5963
  pOperator->name = "TimeIntervalAggOperator";
H
Haojun Liao 已提交
5964
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
5965
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5966 5967 5968 5969 5970
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
5971 5972 5973

  pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doBuildIntervalResult, doStreamIntervalAgg, NULL, destroyIntervalOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
5974

H
Haojun Liao 已提交
5975
  code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5976 5977 5978 5979
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

5980
  return pOperator;
H
Haojun Liao 已提交
5981

L
Liu Jicong 已提交
5982
_error:
H
Haojun Liao 已提交
5983
  destroyIntervalOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5984 5985
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5986 5987
  pTaskInfo->code = code;
  return NULL;
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 6048
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 已提交
6049 6050
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                           SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo) {
6051
  STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
dengyihao's avatar
dengyihao 已提交
6052
  SOperatorInfo*          pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6053 6054 6055
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }
6056

H
Haojun Liao 已提交
6057
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6058

dengyihao's avatar
dengyihao 已提交
6059
  pOperator->name = "TimeSliceOperator";
L
Liu Jicong 已提交
6060
  //  pOperator->operatorType = OP_AllTimeWindow;
6061
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6062 6063 6064 6065 6066
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
6067 6068 6069

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doAllIntervalAgg, NULL, NULL, destroyBasicOperatorInfo,
                                         NULL, NULL, NULL);
6070

L
Liu Jicong 已提交
6071
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6072
  return pOperator;
6073

dengyihao's avatar
dengyihao 已提交
6074
_error:
6075 6076 6077 6078
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
6079 6080
}

dengyihao's avatar
dengyihao 已提交
6081 6082 6083
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
                                             SSDataBlock* pResBlock, STimeWindowAggSupp* pTwAggSup,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6084
  SStateWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStateWindowOperatorInfo));
dengyihao's avatar
dengyihao 已提交
6085
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6086 6087 6088
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6089

L
Liu Jicong 已提交
6090
  pInfo->colIndex = -1;
6091
  size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6092 6093 6094

  initResultSizeInfo(pOperator, 4096);
  initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExpr, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
6095
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6096

6097 6098 6099
  pInfo->twAggSup = *pTwAggSup;
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);

dengyihao's avatar
dengyihao 已提交
6100
  pOperator->name = "StateWindowOperator";
6101
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW;
6102
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6103 6104 6105 6106 6107 6108
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;

  pOperator->pTaskInfo = pTaskInfo;
  pOperator->info = pInfo;
6109 6110 6111

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStateWindowAgg, NULL, NULL, destroyStateWindowOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
6112

H
Haojun Liao 已提交
6113
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6114
  return pOperator;
6115

dengyihao's avatar
dengyihao 已提交
6116
_error:
6117 6118
  pTaskInfo->code = TSDB_CODE_SUCCESS;
  return NULL;
6119 6120
}

L
Liu Jicong 已提交
6121
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
dengyihao's avatar
dengyihao 已提交
6122 6123
                                            SSDataBlock* pResBlock, int64_t gap, STimeWindowAggSupp* pTwAggSupp,
                                            SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6124
  SSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSessionAggOperatorInfo));
L
Liu Jicong 已提交
6125
  SOperatorInfo*           pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6126 6127 6128
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6129

H
Haojun Liao 已提交
6130
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
6131
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6132 6133

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
6134 6135
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
6136 6137 6138
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6139

6140
  pInfo->twAggSup = *pTwAggSupp;
H
Haojun Liao 已提交
6141
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6142
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
6143

dengyihao's avatar
dengyihao 已提交
6144 6145 6146 6147 6148
  pInfo->gap = gap;
  pInfo->binfo.pRes = pResBlock;
  pInfo->winSup.prevTs = INT64_MIN;
  pInfo->reptScan = false;
  pOperator->name = "SessionWindowAggOperator";
H
Haojun Liao 已提交
6149
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW;
6150
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6151 6152 6153 6154
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
6155 6156 6157

  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSessionWindowAgg, NULL, NULL, destroySWindowOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
dengyihao's avatar
dengyihao 已提交
6158
  pOperator->pTaskInfo = pTaskInfo;
6159

H
Haojun Liao 已提交
6160
  code = appendDownstream(pOperator, &downstream, 1);
6161
  return pOperator;
H
Haojun Liao 已提交
6162

L
Liu Jicong 已提交
6163
_error:
H
Haojun Liao 已提交
6164 6165 6166 6167
  if (pInfo != NULL) {
    destroySWindowOperatorInfo(pInfo, numOfCols);
  }

wafwerar's avatar
wafwerar 已提交
6168 6169
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6170 6171
  pTaskInfo->code = code;
  return NULL;
6172 6173
}

H
Haojun Liao 已提交
6174
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, int64_t* fillVal,
L
Liu Jicong 已提交
6175
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
6176
  SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, NULL);
H
Haojun Liao 已提交
6177 6178 6179

  // TODO set correct time precision
  STimeWindow w = TSWINDOW_INITIALIZER;
6180
  getAlignQueryTimeWindow(pInterval, TSDB_TIME_PRECISION_MILLI, win.skey, &w);
H
Haojun Liao 已提交
6181 6182

  int32_t order = TSDB_ORDER_ASC;
6183
  pInfo->pFillInfo = taosCreateFillInfo(order, w.skey, 0, capacity, numOfCols, pInterval, fillType, pColInfo, id);
H
Haojun Liao 已提交
6184

wafwerar's avatar
wafwerar 已提交
6185
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
6186 6187 6188 6189 6190 6191 6192 6193

  if (pInfo->pFillInfo == NULL || pInfo->p == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  } else {
    return TSDB_CODE_SUCCESS;
  }
}

L
Liu Jicong 已提交
6194 6195 6196
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 已提交
6197
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
6198
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6199

L
Liu Jicong 已提交
6200
  pInfo->pRes = pResBlock;
6201
  pInfo->multigroupResult = multigroupResult;
L
Liu Jicong 已提交
6202
  pInfo->intervalInfo = *pInterval;
6203

6204 6205
  int32_t type = TSDB_FILL_NONE;
  switch (fillType) {
dengyihao's avatar
dengyihao 已提交
6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223
    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;
6224 6225 6226 6227
    default:
      type = TSDB_FILL_NONE;
  }

H
Haojun Liao 已提交
6228
  SResultInfo* pResultInfo = &pOperator->resultInfo;
6229 6230 6231 6232
  initResultSizeInfo(pOperator, 4096);

  int32_t code = initFillInfo(pInfo, pExpr, numOfCols, (int64_t*)fillVal, pTaskInfo->window, pResultInfo->capacity,
                              pTaskInfo->id.str, pInterval, type);
6233 6234 6235
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6236

dengyihao's avatar
dengyihao 已提交
6237
  pOperator->name = "FillOperator";
6238
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
6239
  pOperator->status = OP_NOT_OPENED;
L
Liu Jicong 已提交
6240
  //  pOperator->operatorType = OP_Fill;
dengyihao's avatar
dengyihao 已提交
6241 6242 6243
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
H
Haojun Liao 已提交
6244

6245 6246 6247
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo,
                                         NULL, NULL, NULL);
  pOperator->pTaskInfo = pTaskInfo;
6248
  code = appendDownstream(pOperator, &downstream, 1);
6249
  return pOperator;
H
Haojun Liao 已提交
6250

L
Liu Jicong 已提交
6251
_error:
wafwerar's avatar
wafwerar 已提交
6252 6253
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
6254
  return NULL;
6255 6256
}

H
Haojun Liao 已提交
6257

L
Liu Jicong 已提交
6258
static int32_t getColumnIndexInSource(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6259 6260
  int32_t j = 0;

H
Haojun Liao 已提交
6261 6262
  if (TSDB_COL_IS_TAG(pExpr->pParam[0].pCol->type)) {
    if (pExpr->pParam[0].pCol->colId == TSDB_TBNAME_COLUMN_INDEX) {
6263 6264 6265
      return TSDB_TBNAME_COLUMN_INDEX;
    }

L
Liu Jicong 已提交
6266
    while (j < pTableInfo->numOfTags) {
H
Haojun Liao 已提交
6267
      if (pExpr->pParam[0].pCol->colId == pTagCols[j].colId) {
6268 6269 6270 6271 6272 6273
        return j;
      }

      j += 1;
    }

6274
  } /*else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {  // user specified column data
6275 6276 6277 6278 6279 6280 6281 6282 6283
    return TSDB_UD_COLUMN_INDEX;
  } else {
    while (j < pTableInfo->numOfCols) {
      if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) {
        return j;
      }

      j += 1;
    }
6284
  }*/
6285 6286 6287 6288

  return INT32_MIN;  // return a less than TSDB_TBNAME_COLUMN_INDEX value
}

L
Liu Jicong 已提交
6289
bool validateExprColumnInfo(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6290 6291 6292 6293
  int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols);
  return j != INT32_MIN;
}

L
Liu Jicong 已提交
6294 6295
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
6296
  SResSchema s = {0};
dengyihao's avatar
dengyihao 已提交
6297 6298 6299 6300
  s.scale = scale;
  s.type = type;
  s.bytes = bytes;
  s.slotId = slotId;
H
Haojun Liao 已提交
6301
  s.precision = precision;
H
Haojun Liao 已提交
6302 6303 6304 6305
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
6306

H
Haojun Liao 已提交
6307 6308 6309 6310 6311 6312 6313
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 已提交
6314 6315 6316 6317 6318
  pCol->slotId = slotId;
  pCol->bytes = pType->bytes;
  pCol->type = pType->type;
  pCol->scale = pType->scale;
  pCol->precision = pType->precision;
H
Haojun Liao 已提交
6319 6320 6321 6322 6323
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
6324
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
6325
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6326 6327 6328 6329
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
6330

H
Haojun Liao 已提交
6331
  *numOfExprs = numOfFuncs + numOfGroupKeys;
wafwerar's avatar
wafwerar 已提交
6332
  SExprInfo* pExprs = taosMemoryCalloc(*numOfExprs, sizeof(SExprInfo));
H
Haojun Liao 已提交
6333

L
Liu Jicong 已提交
6334
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
6335 6336 6337 6338 6339 6340
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
6341

6342
    SExprInfo* pExp = &pExprs[i];
H
Haojun Liao 已提交
6343

wafwerar's avatar
wafwerar 已提交
6344
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
6345
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
6346
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
6347

6348
    int32_t type = nodeType(pTargetNode->pExpr);
H
Haojun Liao 已提交
6349
    // it is a project query, or group by column
6350
    if (type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
6351
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
6352
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
6353

G
Ganlin Zhao 已提交
6354 6355 6356
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
6357
      SDataType* pType = &pColNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6358 6359
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pColNode->colName);
H
Haojun Liao 已提交
6360 6361
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pType);
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
6362
    } else if (type == QUERY_NODE_VALUE) {
6363 6364 6365 6366 6367 6368 6369
      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 已提交
6370 6371
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pValNode->node.aliasName);
6372 6373
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
      valueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
6374
    } else if (type == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
6375
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
6376 6377 6378
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

      SDataType* pType = &pFuncNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6379 6380
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pFuncNode->node.aliasName);
H
Haojun Liao 已提交
6381

H
Haojun Liao 已提交
6382
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
6383
      pExp->pExpr->_function.pFunctNode = pFuncNode;
dengyihao's avatar
dengyihao 已提交
6384 6385
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
H
Haojun Liao 已提交
6386 6387

      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
6388 6389 6390 6391

      pExp->base.pParam = taosMemoryCalloc(numOfParam, sizeof(SFunctParam));
      pExp->base.numOfParams = numOfParam;

H
Haojun Liao 已提交
6392
      for (int32_t j = 0; j < numOfParam; ++j) {
6393
        SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
6394
        if (p1->type == QUERY_NODE_COLUMN) {
dengyihao's avatar
dengyihao 已提交
6395
          SColumnNode* pcn = (SColumnNode*)p1;
G
Ganlin Zhao 已提交
6396 6397

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
H
Haojun Liao 已提交
6398
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, &pcn->node.resType);
G
Ganlin Zhao 已提交
6399 6400 6401
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
6402
          valueNodeToVariant(pvn, &pExp->base.pParam[j].param);
G
Ganlin Zhao 已提交
6403
        }
H
Haojun Liao 已提交
6404
      }
6405
    } else if (type == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
6406
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
6407
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
6408

G
Ganlin Zhao 已提交
6409 6410 6411
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

6412
      SDataType* pType = &pNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6413 6414
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pNode->node.aliasName);
6415 6416 6417
      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6418 6419 6420
    }
  }

H
Haojun Liao 已提交
6421
  return pExprs;
H
Haojun Liao 已提交
6422 6423
}

6424
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model) {
wafwerar's avatar
wafwerar 已提交
6425
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
6426
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
6427

6428
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
6429
  pTaskInfo->id.queryId = queryId;
dengyihao's avatar
dengyihao 已提交
6430
  pTaskInfo->execModel = model;
H
Haojun Liao 已提交
6431

wafwerar's avatar
wafwerar 已提交
6432
  char* p = taosMemoryCalloc(1, 128);
L
Liu Jicong 已提交
6433
  snprintf(p, 128, "TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, queryId);
6434
  pTaskInfo->id.str = strdup(p);
H
Haojun Liao 已提交
6435

6436 6437
  return pTaskInfo;
}
H
Haojun Liao 已提交
6438

L
Liu Jicong 已提交
6439 6440
static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                                      STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId);
H
Haojun Liao 已提交
6441

L
Liu Jicong 已提交
6442 6443
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                                  uint64_t queryId, uint64_t taskId);
6444
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
H
Haojun Liao 已提交
6445
static SArray* extractColumnInfo(SNodeList* pNodeList);
H
Haojun Liao 已提交
6446
static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols);
6447

6448
static SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget);
6449
static SArray* createIndexMap(SNodeList* pNodeList);
6450
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463
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 已提交
6464

H
Haojun Liao 已提交
6465
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
6466
                                  uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
6467 6468
  int32_t type = nodeType(pPhyNode);

X
Xiaoyu Wang 已提交
6469
  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
H
Haojun Liao 已提交
6470
    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
dengyihao's avatar
dengyihao 已提交
6471 6472
      SScanPhysiNode*      pScanPhyNode = (SScanPhysiNode*)pPhyNode;
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6473

6474
      int32_t numOfCols = 0;
H
Haojun Liao 已提交
6475
      tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
6476
      if (pDataReader == NULL && terrno != 0) {
6477 6478
        return NULL;
      }
6479

dengyihao's avatar
dengyihao 已提交
6480 6481
      SArray* pColList =
          extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
6482
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6483

6484 6485 6486 6487 6488
      SQueryTableDataCond cond = {0};
      int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }
6489

6490 6491
      SInterval interval = extractIntervalInfo(pTableScanNode);
      return createTableScanOperatorInfo(pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList,
H
Haojun Liao 已提交
6492
                                         pResBlock, pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo);
H
Haojun Liao 已提交
6493
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
H
Haojun Liao 已提交
6494
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
6495
      SSDataBlock*        pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
6496
      return createExchangeOperatorInfo(pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
H
Haojun Liao 已提交
6497
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
H
Haojun Liao 已提交
6498
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
6499

6500
      int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, queryId, taskId);
H
Haojun Liao 已提交
6501
      SArray* tableIdList = extractTableIdList(pTableGroupInfo);
H
Haojun Liao 已提交
6502

6503
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6504 6505

      int32_t numOfCols = 0;
6506 6507
      SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
      SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo);
6508
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
6509
      return pOperator;
H
Haojun Liao 已提交
6510
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
L
Liu Jicong 已提交
6511
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
6512
      SScanPhysiNode* pScanNode = &pSysScanPhyNode->scan;
H
Haojun Liao 已提交
6513

6514
      SSDataBlock* pResBlock = createResDataBlock(pScanNode->node.pOutputDataBlockDesc);
6515

6516 6517
      int32_t numOfOutputCols = 0;
      SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pScanNode->node.pOutputDataBlockDesc, &numOfOutputCols);
L
Liu Jicong 已提交
6518
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
6519
          pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
L
Liu Jicong 已提交
6520
          colList, pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
6521 6522 6523
      return pOperator;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6524 6525 6526
    }
  }

6527 6528
  int32_t num = 0;
  size_t  size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
6529

6530
  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
dengyihao's avatar
dengyihao 已提交
6531
  for (int32_t i = 0; i < size; ++i) {
6532 6533
    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
6534 6535 6536
    if (ops[i] == NULL) {
      return NULL;
    }
6537
  }
H
Haojun Liao 已提交
6538

6539
  SOperatorInfo* pOptr = NULL;
H
Haojun Liao 已提交
6540
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
dengyihao's avatar
dengyihao 已提交
6541 6542
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*)pPhyNode;
    SExprInfo*         pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);
H
Haojun Liao 已提交
6543

6544
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
dengyihao's avatar
dengyihao 已提交
6545 6546
    SLimit       limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
    SLimit       slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
6547
    pOptr = createProjectOperatorInfo(ops[0], pExprInfo, num, pResBlock, &limit, &slimit, pTaskInfo);
H
Haojun Liao 已提交
6548 6549 6550
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == type) {
    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
    SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
6551
    SSDataBlock*   pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
6552

dengyihao's avatar
dengyihao 已提交
6553
    int32_t    numOfScalarExpr = 0;
6554 6555 6556 6557 6558
    SExprInfo* pScalarExprInfo = NULL;
    if (pAggNode->pExprs != NULL) {
      pScalarExprInfo = createExprInfo(pAggNode->pExprs, NULL, &numOfScalarExpr);
    }

H
Haojun Liao 已提交
6559 6560
    if (pAggNode->pGroupKeys != NULL) {
      SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
dengyihao's avatar
dengyihao 已提交
6561 6562
      pOptr = createGroupOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pAggNode->node.pConditions,
                                      pScalarExprInfo, numOfScalarExpr, pTaskInfo, NULL);
H
Haojun Liao 已提交
6563
    } else {
dengyihao's avatar
dengyihao 已提交
6564 6565
      pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr,
                                          pTaskInfo, pTableGroupInfo);
H
Haojun Liao 已提交
6566
    }
H
Haojun Liao 已提交
6567 6568
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type) {
    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6569

H
Haojun Liao 已提交
6570
    SExprInfo*   pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
6571
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
6572

dengyihao's avatar
dengyihao 已提交
6573 6574 6575 6576 6577 6578
    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 已提交
6579

dengyihao's avatar
dengyihao 已提交
6580 6581
    STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
                             .calTrigger = pIntervalPhyNode->window.triggerType};
6582

dengyihao's avatar
dengyihao 已提交
6583 6584 6585
    int32_t primaryTsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
    pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as,
                                       pTableGroupInfo, pTaskInfo);
6586 6587

    if (pIntervalPhyNode->pFill != NULL) {
dengyihao's avatar
dengyihao 已提交
6588 6589
      pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode, NULL,
                                     false, pTaskInfo);
6590 6591
    }

H
Haojun Liao 已提交
6592
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
H
Haojun Liao 已提交
6593
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6594

6595
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6596
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys, pSortPhyNode->pTargets);
6597
    SArray*      slotMap = createIndexMap(pSortPhyNode->pTargets);
6598
    pOptr = createSortOperatorInfo(ops[0], pResBlock, info, slotMap, pTaskInfo);
H
Haojun Liao 已提交
6599
  } else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
H
Haojun Liao 已提交
6600 6601
    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

dengyihao's avatar
dengyihao 已提交
6602 6603
    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};
6604

H
Haojun Liao 已提交
6605
    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
6606
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6607
    pOptr = createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, &as, pTaskInfo);
H
Haojun Liao 已提交
6608
  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
dengyihao's avatar
dengyihao 已提交
6609 6610 6611
    SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
    SArray*              pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
    SSDataBlock*         pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6612 6613

    SExprInfo* pExprInfo = createExprInfo(pPartNode->pTargets, NULL, &num);
6614
    pOptr = createPartitionOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pTaskInfo, NULL);
6615
  } else if (QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW == type) {
dengyihao's avatar
dengyihao 已提交
6616
    SStateWinodwPhysiNode* pStateNode = (SStateWinodwPhysiNode*)pPhyNode;
6617

6618 6619
    STimeWindowAggSupp as = {.waterMark = pStateNode->window.watermark, .calTrigger = pStateNode->window.triggerType};

dengyihao's avatar
dengyihao 已提交
6620
    SExprInfo*   pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &num);
6621
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6622
    pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, pTaskInfo);
6623
  } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
dengyihao's avatar
dengyihao 已提交
6624 6625
    SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6626 6627

    SExprInfo* pExprInfo = createExprInfo(pJoinNode->pTargets, NULL, &num);
6628
    pOptr = createJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
H
Haojun Liao 已提交
6629 6630
  } else {
    ASSERT(0);
H
Haojun Liao 已提交
6631
  }
6632 6633 6634

  taosMemoryFree(ops);
  return pOptr;
6635
}
H
Haojun Liao 已提交
6636 6637


6638 6639 6640 6641 6642 6643 6644
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 已提交
6645
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
6646 6647 6648 6649 6650 6651 6652 6653 6654 6655
    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 已提交
6656
  }
6657
#endif
H
Haojun Liao 已提交
6658

6659 6660
  pCond->type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
  //  pCond->type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
6661

H
Haojun Liao 已提交
6662
  int32_t j = 0;
6663
  for (int32_t i = 0; i < pCond->numOfCols; ++i) {
H
Haojun Liao 已提交
6664 6665
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6666 6667 6668
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
6669

6670 6671 6672
    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 已提交
6673
    j += 1;
H
Haojun Liao 已提交
6674 6675
  }

6676 6677
  pCond->numOfCols = j;
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
6678
}
H
Haojun Liao 已提交
6679

H
Haojun Liao 已提交
6680
SArray* extractColumnInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
6681
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6682 6683 6684 6685 6686 6687
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6688 6689
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
H
Haojun Liao 已提交
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 6715
    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 已提交
6716 6717 6718 6719 6720
  }

  return pList;
}

6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734
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 已提交
6735 6736 6737
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
6738 6739 6740 6741 6742 6743 6744 6745 6746
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;

    taosArrayPush(pList, &c);
  }

  return pList;
}

6747
SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget) {
L
Liu Jicong 已提交
6748
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6749 6750 6751 6752 6753 6754
  SArray* pList = taosArrayInit(numOfCols, sizeof(SBlockOrderInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

L
Liu Jicong 已提交
6755
  for (int32_t i = 0; i < numOfCols; ++i) {
6756
    SOrderByExprNode* pSortKey = (SOrderByExprNode*)nodesListGetNode(pNodeList, i);
L
Liu Jicong 已提交
6757 6758
    SBlockOrderInfo   bi = {0};
    bi.order = (pSortKey->order == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
H
Haojun Liao 已提交
6759 6760 6761 6762
    bi.nullFirst = (pSortKey->nullOrder == NULL_ORDER_FIRST);

    SColumnNode* pColNode = (SColumnNode*)pSortKey->pExpr;

6763 6764 6765 6766 6767
    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 已提交
6768
      if (pColNode->slotId == pColNodeT->slotId) {  // to find slotId in PhysiSort OutputDataBlockDesc
6769 6770 6771 6772 6773 6774
        bi.slotId = pTarget->slotId;
        found = true;
        break;
      }
    }

dengyihao's avatar
dengyihao 已提交
6775
    if (!found) {
6776 6777
      qError("sort slot id does not found");
    }
H
Haojun Liao 已提交
6778 6779 6780 6781 6782 6783
    taosArrayPush(pList, &bi);
  }

  return pList;
}

6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801
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 已提交
6802
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols) {
L
Liu Jicong 已提交
6803
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6804 6805 6806 6807 6808 6809
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6810 6811 6812
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6813 6814

    SColMatchInfo c = {0};
6815
    c.output = true;
L
Liu Jicong 已提交
6816
    c.colId = pColNode->colId;
H
Haojun Liao 已提交
6817 6818 6819 6820
    c.targetSlotId = pNode->slotId;
    taosArrayPush(pList, &c);
  }

H
Haojun Liao 已提交
6821 6822
  *numOfOutputCols = 0;
  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
6823 6824
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
6825

6826
    // todo: add reserve flag check
6827 6828
    // it is a column reserved for the arithmetic expression calculation
    if (pNode->slotId >= numOfCols) {
6829 6830 6831 6832
      (*numOfOutputCols) += 1;
      continue;
    }

H
Haojun Liao 已提交
6833
    SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
H
Haojun Liao 已提交
6834 6835 6836 6837 6838
    if (pNode->output) {
      (*numOfOutputCols) += 1;
    } else {
      info->output = false;
    }
H
Haojun Liao 已提交
6839 6840
  }

H
Haojun Liao 已提交
6841 6842 6843
  return pList;
}

dengyihao's avatar
dengyihao 已提交
6844 6845
int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                           uint64_t queryId, uint64_t taskId) {
6846
  int32_t code = 0;
H
Haojun Liao 已提交
6847
  if (tableType == TSDB_SUPER_TABLE) {
H
Haojun Liao 已提交
6848
    code = tsdbQuerySTableByTagCond(metaHandle, tableUid, 0, NULL, 0, 0, NULL, pGroupInfo, NULL, 0, queryId, taskId);
H
Haojun Liao 已提交
6849
  } else {  // Create one table group.
H
Haojun Liao 已提交
6850
    code = tsdbGetOneTableGroup(metaHandle, tableUid, 0, pGroupInfo);
6851 6852 6853 6854
  }

  return code;
}
H
Haojun Liao 已提交
6855

6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873
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 已提交
6874 6875
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                               STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId) {
6876
  uint64_t uid = pTableScanNode->scan.uid;
L
Liu Jicong 已提交
6877 6878
  int32_t  code =
      doCreateTableGroup(pHandle->meta, pTableScanNode->scan.tableType, uid, pTableGroupInfo, queryId, taskId);
6879 6880
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
H
Haojun Liao 已提交
6881
  }
H
Haojun Liao 已提交
6882

H
Haojun Liao 已提交
6883
  if (pTableGroupInfo->numOfTables == 0) {
H
Haojun Liao 已提交
6884
    code = 0;
L
Liu Jicong 已提交
6885
    qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
H
Haojun Liao 已提交
6886 6887
    goto _error;
  }
H
Haojun Liao 已提交
6888

6889 6890 6891 6892 6893 6894 6895
  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 已提交
6896

L
Liu Jicong 已提交
6897
_error:
H
Haojun Liao 已提交
6898 6899 6900 6901
  terrno = code;
  return NULL;
}

dengyihao's avatar
dengyihao 已提交
6902 6903
int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
                               EOPTR_EXEC_MODEL model) {
H
Haojun Liao 已提交
6904 6905
  uint64_t queryId = pPlan->id.queryId;

H
Haojun Liao 已提交
6906
  int32_t code = TSDB_CODE_SUCCESS;
6907
  *pTaskInfo = createExecTaskInfo(queryId, taskId, model);
H
Haojun Liao 已提交
6908 6909 6910 6911
  if (*pTaskInfo == NULL) {
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    goto _complete;
  }
H
Haojun Liao 已提交
6912

6913
  (*pTaskInfo)->pRoot = createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoGroupInfo);
D
dapan1121 已提交
6914
  if (NULL == (*pTaskInfo)->pRoot) {
L
Liu Jicong 已提交
6915
    code = terrno;
D
dapan1121 已提交
6916 6917
    goto _complete;
  }
H
Haojun Liao 已提交
6918

6919
  if ((*pTaskInfo)->pRoot == NULL) {
H
Haojun Liao 已提交
6920
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
H
Haojun Liao 已提交
6921
    goto _complete;
6922 6923
  }

H
Haojun Liao 已提交
6924 6925
  return code;

H
Haojun Liao 已提交
6926
_complete:
wafwerar's avatar
wafwerar 已提交
6927
  taosMemoryFreeClear(*pTaskInfo);
H
Haojun Liao 已提交
6928 6929 6930

  terrno = code;
  return code;
H
Haojun Liao 已提交
6931 6932
}

L
Liu Jicong 已提交
6933 6934
static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SColumnInfo* pTagCols, SExprInfo* pExprs,
                                             int32_t numOfOutput, int32_t tagLen, bool superTable) {
6935 6936 6937 6938 6939 6940 6941 6942 6943
  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 已提交
6944 6945 6946 6947
        //        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);
6948 6949 6950 6951 6952 6953 6954
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
6955
void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo) {
6956 6957 6958 6959 6960 6961 6962 6963
  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 已提交
6964 6965 6966 6967 6968 6969 6970 6971 6972 6973
  //  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;
  //  }
6974 6975

  pResultInfo->threshold = (int32_t)(pResultInfo->capacity * THRESHOLD_RATIO);
H
Haojun Liao 已提交
6976
  pResultInfo->totalRows = 0;
6977 6978
}

L
Liu Jicong 已提交
6979
// TODO refactor
6980
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
L
Liu Jicong 已提交
6981 6982 6983
  if (pFilter == NULL || numOfFilters == 0) {
    return;
  }
6984

L
Liu Jicong 已提交
6985 6986 6987
  for (int32_t i = 0; i < numOfFilters; i++) {
    if (pFilter[i].filterstr && pFilter[i].pz) {
      taosMemoryFree((void*)(pFilter[i].pz));
6988
    }
L
Liu Jicong 已提交
6989
  }
6990

L
Liu Jicong 已提交
6991
  taosMemoryFree(pFilter);
6992 6993 6994 6995
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
  if (pTableqinfoGroupInfo->pGroupList != NULL) {
L
Liu Jicong 已提交
6996
    int32_t numOfGroups = (int32_t)taosArrayGetSize(pTableqinfoGroupInfo->pGroupList);
6997
    for (int32_t i = 0; i < numOfGroups; ++i) {
L
Liu Jicong 已提交
6998
      SArray* p = taosArrayGetP(pTableqinfoGroupInfo->pGroupList, i);
6999 7000

      size_t num = taosArrayGetSize(p);
L
Liu Jicong 已提交
7001
      for (int32_t j = 0; j < num; ++j) {
7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017
        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 已提交
7018
void doDestroyTask(SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
7019 7020
  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));

H
Haojun Liao 已提交
7021
  doDestroyTableQueryInfo(&pTaskInfo->tableqinfoGroupInfo);
L
Liu Jicong 已提交
7022 7023
  //  taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
  //  taosHashCleanup(pTaskInfo->summary.operatorProfResults);
7024

wafwerar's avatar
wafwerar 已提交
7025 7026 7027
  taosMemoryFreeClear(pTaskInfo->sql);
  taosMemoryFreeClear(pTaskInfo->id.str);
  taosMemoryFreeClear(pTaskInfo);
7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039
}

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 已提交
7040
      int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052
      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 已提交
7053 7054
  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
  return (int64_t)(s1 * 1.5 * numOfTables);
7055 7056 7057 7058 7059 7060 7061
}

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 已提交
7062
    while (1) {
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 7088
      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 已提交
7089

dengyihao's avatar
dengyihao 已提交
7090 7091
int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo** pRes, int32_t* capacity,
                                   int32_t* resNum) {
D
dapan1121 已提交
7092 7093
  if (*resNum >= *capacity) {
    *capacity += 10;
dengyihao's avatar
dengyihao 已提交
7094

D
dapan1121 已提交
7095 7096
    *pRes = taosMemoryRealloc(*pRes, (*capacity) * sizeof(SExplainExecInfo));
    if (NULL == *pRes) {
D
dapan1121 已提交
7097
      qError("malloc %d failed", (*capacity) * (int32_t)sizeof(SExplainExecInfo));
D
dapan1121 已提交
7098 7099 7100 7101
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

D
dapan1121 已提交
7102 7103 7104 7105
  (*pRes)[*resNum].numOfRows = operatorInfo->resultInfo.totalRows;
  (*pRes)[*resNum].startupCost = operatorInfo->cost.openCost;
  (*pRes)[*resNum].totalCost = operatorInfo->cost.totalCost;

7106 7107
  if (operatorInfo->fpSet.getExplainFn) {
    int32_t code = (*operatorInfo->fpSet.getExplainFn)(operatorInfo, &(*pRes)->verboseInfo);
D
dapan1121 已提交
7108 7109 7110 7111 7112
    if (code) {
      qError("operator getExplainFn failed, error:%s", tstrerror(code));
      return code;
    }
  }
dengyihao's avatar
dengyihao 已提交
7113

D
dapan1121 已提交
7114
  ++(*resNum);
dengyihao's avatar
dengyihao 已提交
7115

D
dapan1121 已提交
7116
  int32_t code = 0;
D
dapan1121 已提交
7117 7118
  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pRes, capacity, resNum);
D
dapan1121 已提交
7119 7120 7121 7122 7123 7124 7125
    if (code) {
      taosMemoryFreeClear(*pRes);
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
7126 7127
}

7128 7129
static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup) {
  SJoinOperatorInfo* pJoinInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
7130
  //  SOptrBasicInfo* pInfo = &pJoinInfo->binfo;
7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143

  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);
7144
      pJoinInfo->pLeft = ds1->fpSet.getNextFn(ds1, newgroup);
7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156
      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);
7157
      pJoinInfo->pRight = ds2->fpSet.getNextFn(ds2, newgroup);
7158 7159 7160 7161 7162 7163 7164 7165 7166 7167
      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 已提交
7168
    char*            pLeftVal = colDataGetData(pLeftCol, pJoinInfo->leftPos);
7169 7170

    SColumnInfoData* pRightCol = taosArrayGet(pJoinInfo->pRight->pDataBlock, pJoinInfo->rightCol.slotId);
dengyihao's avatar
dengyihao 已提交
7171
    char*            pRightVal = colDataGetData(pRightCol, pJoinInfo->rightPos);
7172 7173

    // only the timestamp match support for ordinary table
dengyihao's avatar
dengyihao 已提交
7174 7175 7176 7177
    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);
7178

dengyihao's avatar
dengyihao 已提交
7179
        SExprInfo* pExprInfo = &pOperator->pExpr[i];
7180

dengyihao's avatar
dengyihao 已提交
7181 7182
        int32_t blockId = pExprInfo->base.pParam[0].pCol->dataBlockId;
        int32_t slotId = pExprInfo->base.pParam[0].pCol->slotId;
7183

dengyihao's avatar
dengyihao 已提交
7184 7185 7186 7187 7188 7189
        SColumnInfoData* pSrc = NULL;
        if (pJoinInfo->pLeft->info.blockId == blockId) {
          pSrc = taosArrayGet(pJoinInfo->pLeft->pDataBlock, slotId);
        } else {
          pSrc = taosArrayGet(pJoinInfo->pRight->pDataBlock, slotId);
        }
7190

dengyihao's avatar
dengyihao 已提交
7191 7192 7193 7194 7195
        if (colDataIsNull_s(pSrc, pJoinInfo->leftPos)) {
          colDataAppendNULL(pDst, nrows);
        } else {
          char* p = colDataGetData(pSrc, pJoinInfo->leftPos);
          colDataAppend(pDst, nrows, p, false);
7196
        }
dengyihao's avatar
dengyihao 已提交
7197
      }
7198

dengyihao's avatar
dengyihao 已提交
7199 7200
      pJoinInfo->leftPos += 1;
      pJoinInfo->rightPos += 1;
7201

dengyihao's avatar
dengyihao 已提交
7202 7203 7204
      nrows += 1;
    } else if (*(int64_t*)pLeftVal < *(int64_t*)pRightVal) {
      pJoinInfo->leftPos += 1;
D
dapan1121 已提交
7205

dengyihao's avatar
dengyihao 已提交
7206 7207
      if (pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
        continue;
7208
      }
dengyihao's avatar
dengyihao 已提交
7209 7210 7211 7212
    } else if (*(int64_t*)pLeftVal > *(int64_t*)pRightVal) {
      pJoinInfo->rightPos += 1;
      if (pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
        continue;
7213
      }
dengyihao's avatar
dengyihao 已提交
7214
    }
7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225

    // 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 已提交
7226 7227 7228
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                      int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
                                      SExecTaskInfo* pTaskInfo) {
7229
  SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
dengyihao's avatar
dengyihao 已提交
7230
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
7231 7232 7233 7234 7235 7236 7237
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }

  pOperator->resultInfo.capacity = 4096;
  pOperator->resultInfo.threshold = 4096 * 0.75;

dengyihao's avatar
dengyihao 已提交
7238 7239 7240
  //  initResultRowInf
  //  o(&pInfo->binfo.resultRowInfo, 8);
  pInfo->pRes = pResBlock;
7241

dengyihao's avatar
dengyihao 已提交
7242
  pOperator->name = "JoinOperator";
7243
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_JOIN;
7244
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
7245 7246 7247 7248 7249
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
7250

7251 7252
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doMergeJoin, NULL, NULL, destroyBasicOperatorInfo,
                                         NULL, NULL, NULL);
7253 7254 7255
  int32_t code = appendDownstream(pOperator, pDownstream, numOfDownstream);
  return pOperator;

dengyihao's avatar
dengyihao 已提交
7256
_error:
7257 7258 7259 7260
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
dengyihao's avatar
dengyihao 已提交
7261
}