executorimpl.c 201.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

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

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

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

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

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

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

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

#if 0
static UNUSED_FUNC void *u_malloc (size_t __size) {
wafwerar's avatar
wafwerar 已提交
58
  uint32_t v = taosRand();
59 60 61 62

  if (v % 1000 <= 0) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
63
    return taosMemoryMalloc(__size);
64 65 66 67
  }
}

static UNUSED_FUNC void* u_calloc(size_t num, size_t __size) {
wafwerar's avatar
wafwerar 已提交
68
  uint32_t v = taosRand();
69 70 71
  if (v % 1000 <= 0) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
72
    return taosMemoryCalloc(num, __size);
73 74 75 76
  }
}

static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
wafwerar's avatar
wafwerar 已提交
77
  uint32_t v = taosRand();
78 79 80
  if (v % 5 <= 1) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
81
    return taosMemoryRealloc(p, __size);
82 83 84 85 86 87 88 89 90 91 92 93
  }
}

#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 已提交
94 95 96
int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; }

static int32_t getExprFunctionId(SExprInfo* pExprInfo) {
97
  assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
98
  return 0;
99 100 101
}

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

104
static void setBlockStatisInfo(SqlFunctionCtx* pCtx, SExprInfo* pExpr, SSDataBlock* pSDataBlock);
105

L
Liu Jicong 已提交
106
static void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo);
107 108 109

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

L
Liu Jicong 已提交
110
static void    releaseQueryBuf(size_t numOfTables);
111

H
Haojun Liao 已提交
112
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr);
113 114 115 116 117 118

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 destroyAggOperatorInfo(void* param, int32_t numOfOutput);
X
Xiaoyu Wang 已提交
119

H
Haojun Liao 已提交
120
static void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput);
H
Haojun Liao 已提交
121 122
static void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput);

123
static void destroyOperatorInfo(SOperatorInfo* pOperator);
124
static void destroySysTableScannerOperatorInfo(void* param, int32_t numOfOutput);
125

126
void doSetOperatorCompleted(SOperatorInfo* pOperator) {
127
  pOperator->status = OP_EXEC_DONE;
H
Haojun Liao 已提交
128
  if (pOperator->pTaskInfo != NULL) {
129
    setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
130 131
  }
}
132

H
Haojun Liao 已提交
133
int32_t operatorDummyOpenFn(SOperatorInfo* pOperator) {
134
  OPTR_SET_OPENED(pOperator);
135
  pOperator->cost.openCost = 0;
H
Haojun Liao 已提交
136
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
137 138
}

139
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t streamFn,
L
Liu Jicong 已提交
140 141
                                   __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) {
142 143 144 145 146 147 148 149 150 151 152 153 154 155
  SOperatorFpSet fpSet = {
      ._openFn = openFn,
      .getNextFn = nextFn,
      .getStreamResFn = streamFn,
      .cleanupFn = cleanup,
      .closeFn = closeFn,
      .encodeResultRow = encode,
      .decodeResultRow = decode,
      .getExplainFn = explain,
  };

  return fpSet;
}

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

158
static int32_t doCopyToSDataBlock(SExecTaskInfo *taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
dengyihao's avatar
dengyihao 已提交
159 160
                                  SGroupResInfo* pGroupResInfo, int32_t orderType, int32_t* rowCellOffset,
                                  SqlFunctionCtx* pCtx);
H
Haojun Liao 已提交
161

162
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
H
Haojun Liao 已提交
163
static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo);
dengyihao's avatar
dengyihao 已提交
164 165
static void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId,
                                     SExecTaskInfo* pTaskInfo);
166

H
Haojun Liao 已提交
167
SArray* getOrderCheckColumns(STaskAttr* pQuery);
168 169

typedef struct SRowCompSupporter {
L
Liu Jicong 已提交
170 171 172
  STaskRuntimeEnv* pRuntimeEnv;
  int16_t          dataOffset;
  __compar_fn_t    comFunc;
173 174
} SRowCompSupporter;

L
Liu Jicong 已提交
175 176 177
static int compareRowData(const void* a, const void* b, const void* userData) {
  const SResultRow* pRow1 = (const SResultRow*)a;
  const SResultRow* pRow2 = (const SResultRow*)b;
178

L
Liu Jicong 已提交
179 180
  SRowCompSupporter* supporter = (SRowCompSupporter*)userData;
  STaskRuntimeEnv*   pRuntimeEnv = supporter->pRuntimeEnv;
181

L
Liu Jicong 已提交
182 183
  SFilePage* page1 = getBufPage(pRuntimeEnv->pResultBuf, pRow1->pageId);
  SFilePage* page2 = getBufPage(pRuntimeEnv->pResultBuf, pRow2->pageId);
184 185

  int16_t offset = supporter->dataOffset;
L
Liu Jicong 已提交
186 187
  char*   in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
  char*   in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
188 189 190 191

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

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

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

H
Haojun Liao 已提交
199
  pBlock->info.blockId = pNode->dataBlockId;
dengyihao's avatar
dengyihao 已提交
200
  pBlock->info.rowSize = pNode->totalRowSize;  // todo ??
5
54liuyao 已提交
201
  pBlock->info.type = STREAM_INVALID;
H
Haojun Liao 已提交
202

L
Liu Jicong 已提交
203
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
204
    SColumnInfoData idata = {{0}};
L
Liu Jicong 已提交
205
    SSlotDescNode*  pDescNode = nodesListGetNode(pNode->pSlots, i);
X
Xiaoyu Wang 已提交
206 207 208
    //    if (!pDescNode->output) {  // todo disable it temporarily
    //      continue;
    //    }
H
Haojun Liao 已提交
209

dengyihao's avatar
dengyihao 已提交
210
    idata.info.type = pDescNode->dataType.type;
L
Liu Jicong 已提交
211 212
    idata.info.bytes = pDescNode->dataType.bytes;
    idata.info.scale = pDescNode->dataType.scale;
H
Haojun Liao 已提交
213
    idata.info.slotId = pDescNode->slotId;
H
Haojun Liao 已提交
214 215
    idata.info.precision = pDescNode->dataType.precision;

H
Hongze Cheng 已提交
216 217 218 219
    if (IS_VAR_DATA_TYPE(idata.info.type)) {
      pBlock->info.hasVarCol = true;
    }

H
Haojun Liao 已提交
220
    taosArrayPush(pBlock->pDataBlock, &idata);
H
Haojun Liao 已提交
221
  }
H
Haojun Liao 已提交
222

223
  pBlock->info.numOfCols = taosArrayGetSize(pBlock->pDataBlock);
H
Haojun Liao 已提交
224
  return pBlock;
H
Haojun Liao 已提交
225 226
}

L
Liu Jicong 已提交
227
static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
dengyihao's avatar
dengyihao 已提交
228 229
  if (TSDB_COL_IS_TAG(pColumn->flag) || TSDB_COL_IS_UD_COL(pColumn->flag) ||
      pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
230 231 232 233 234 235 236 237 238 239
    return false;
  }

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

  return true;
}

H
Haojun Liao 已提交
240
static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) {
241 242
  int64_t newCapacity = 0;

243 244 245 246 247 248 249 250 251 252 253
  // 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);
  }

254
  if (newCapacity <= pResultRowInfo->capacity) {
H
Haojun Liao 已提交
255 256 257
    newCapacity += 4;
  }

258 259 260 261 262 263
  char* p = taosMemoryRealloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition));
  if (p == NULL) {
    longjmp(env, TSDB_CODE_OUT_OF_MEMORY);
  }

  pResultRowInfo->pPosition = (SResultRowPosition*)p;
264 265

  int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity;
wmmhello's avatar
wmmhello 已提交
266
  memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition) * inc);
267 268 269
  pResultRowInfo->capacity = (int32_t)newCapacity;
}

L
Liu Jicong 已提交
270 271
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
                                int16_t bytes, bool masterscan, uint64_t uid) {
272 273 274
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);

L
Liu Jicong 已提交
275 276
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
277 278 279 280 281 282 283 284 285 286 287

  // 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 已提交
288
        //        existed = (pResultRowInfo->pResult[0] == (*p1));
289 290
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid, pResultRowInfo);
L
Liu Jicong 已提交
291 292
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
293 294 295 296 297 298 299 300 301 302 303 304 305 306
        if (index != NULL) {
          existed = true;
        } else {
          existed = false;
        }
      }
    }

    return existed;
  }

  return p1 != NULL;
}

307
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
L
Liu Jicong 已提交
308
  SFilePage* pData = NULL;
309 310 311 312 313 314 315 316 317 318 319 320 321

  // 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 已提交
322
    if (pData->num + interBufSize > getBufPageSize(pResultBuf)) {
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
      // 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 已提交
342
  pData->num += interBufSize;
343 344 345 346

  return pResultRow;
}

5
54liuyao 已提交
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
void doClearWindow(SIntervalAggOperatorInfo* pInfo, char* pData, int16_t bytes,
    uint64_t groupId, int32_t numOfOutput) {
  SAggSupporter* pSup = &pInfo->aggSup;
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
  SResultRowPosition* p1 =
      (SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, pSup->keyBuf,
          GET_RES_WINDOW_KEY_LEN(bytes));
  SResultRow* pResult = getResultRowByPos(pSup->pResultBuf, p1);
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    pCtx[i].resultInfo = getResultCell(pResult, i, pInfo->binfo.rowCellInfoOffset);
    struct SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo;
    if (fmIsWindowPseudoColumnFunc(pCtx[i].functionId)) {
      continue;
    }
    pResInfo->initialized = false;
    if (pCtx[i].functionId != -1) {
      pCtx[i].fpSet.init(&pCtx[i], pResInfo);
    }
  }
}

369 370 371 372 373 374 375
/**
 * the struct of key in hash table
 * +----------+---------------+
 * | group id |   key data    |
 * | 8 bytes  | actual length |
 * +----------+---------------+
 */
376 377 378
SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, char* pData,
                                   int16_t bytes, bool masterscan, uint64_t groupId, SExecTaskInfo* pTaskInfo,
                                   bool isIntervalQuery, SAggSupporter* pSup) {
379
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
H
Haojun Liao 已提交
380

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

384 385
  SResultRow* pResult = NULL;

H
Haojun Liao 已提交
386 387
  // in case of repeat scan/reverse scan, no new time window added.
  if (isIntervalQuery) {
388 389
    if (masterscan && p1 != NULL) {  // the *p1 may be NULL in case of sliding+offset exists.
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
390 391
    }
  } else {
dengyihao's avatar
dengyihao 已提交
392 393
    // In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
    // pResultRowInfo object.
H
Haojun Liao 已提交
394
    if (p1 != NULL) {
395
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
396 397 398
    }
  }

L
Liu Jicong 已提交
399
  // 1. close current opened time window
400
  if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
L
Liu Jicong 已提交
401
                                                                 pResult->offset != pResultRowInfo->cur.offset))) {
402 403 404 405 406 407 408 409 410 411 412
    // 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) {
H
Haojun Liao 已提交
413
    ASSERT(pSup->resultRowSize > 0);
414 415
    pResult = getNewResultRow_rv(pResultBuf, groupId, pSup->resultRowSize);
    initResultRow(pResult);
H
Haojun Liao 已提交
416

417 418
    // add a new result set for a new group
    SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
L
Liu Jicong 已提交
419 420
    taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos,
                sizeof(SResultRowPosition));
H
Haojun Liao 已提交
421 422
  }

423 424 425 426 427
  // 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 已提交
428 429 430 431 432
  // 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 已提交
433
  return pResult;
H
Haojun Liao 已提交
434 435
}

436
// get the correct time window according to the handled timestamp
L
Liu Jicong 已提交
437
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo* pResultRowInfo, int64_t ts, STaskAttr* pQueryAttr) {
438
  STimeWindow w = {0};
H
Haojun Liao 已提交
439
#if 0
L
Liu Jicong 已提交
440 441
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
                                       //    getInitialStartTimeWindow(pQueryAttr, ts, &w);
442 443

    if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') {
L
Liu Jicong 已提交
444 445 446
      w.ekey =
          taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) -
          1;
447 448 449 450
    } else {
      w.ekey = w.skey + pQueryAttr->interval.interval - 1;
    }
  } else {
H
Haojun Liao 已提交
451
    w = pRow->win;
452 453 454 455 456 457 458 459 460
  }

  /*
   * 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 已提交
461
#endif
462 463 464 465 466

  return w;
}

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

L
Liu Jicong 已提交
472
  SFilePage* pData = NULL;
473 474 475 476 477 478

  // 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 已提交
479
    pData = getNewBufPage(pResultBuf, tid, &pageId);
480
    pData->num = sizeof(SFilePage);
481 482
  } else {
    SPageInfo* pi = getLastPageInfo(list);
483
    pData = getBufPage(pResultBuf, getPageId(pi));
484
    pageId = getPageId(pi);
485

486
    if (pData->num + size > getBufPageSize(pResultBuf)) {
487
      // release current page first, and prepare the next one
488
      releaseBufPageInfo(pResultBuf, pi);
489

H
Haojun Liao 已提交
490
      pData = getNewBufPage(pResultBuf, tid, &pageId);
491
      if (pData != NULL) {
492
        pData->num = sizeof(SFilePage);
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
      }
    }
  }

  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 已提交
513 514 515
static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, STimeWindow* win,
                                    bool masterscan, SResultRow** pResult, int64_t groupId, SqlFunctionCtx* pCtx,
                                    int32_t numOfOutput, int32_t* rowCellInfoOffset) {
516
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
517
  return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char*)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
518 519
}

dengyihao's avatar
dengyihao 已提交
520 521
static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey, bool ascQuery,
                                   bool timeWindowInterpo) {
522
  int64_t skey = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
523
#if 0
524 525
  int32_t i = 0;
  for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
526
    SResultRow* pResult = pResultRowInfo->pResult[i];
527 528 529 530 531 532
    if (pResult->closed) {
      break;
    }

    // new closed result rows
    if (timeWindowInterpo) {
L
Liu Jicong 已提交
533 534 535
      if (pResult->endInterp &&
          ((pResult->win.skey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery))) {
        if (i > 0) {  // the first time window, the startInterp is false.
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
          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 已提交
555
      //      assert(pResultRowInfo->current == NULL);
556 557 558 559 560 561 562
      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 已提交
563
      SResultRow* pResult = pResultRowInfo->pResult[i];
564 565 566 567 568 569 570 571 572 573 574
      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 已提交
575
#endif
576
}
577
//
dengyihao's avatar
dengyihao 已提交
578
// static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
579 580 581 582 583 584 585 586 587
//                                           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);
//  }
//}
588

589
//  query_range_start, query_range_end, window_duration, window_start, window_end
590
void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow) {
591 592 593
  pColData->info.type = TSDB_DATA_TYPE_TIMESTAMP;
  pColData->info.bytes = sizeof(int64_t);

594
  colInfoDataEnsureCapacity(pColData, 0, 5);
595 596 597 598 599 600 601 602 603
  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);
}

604
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset,
dengyihao's avatar
dengyihao 已提交
605
                      int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
606 607 608
  for (int32_t k = 0; k < numOfOutput; ++k) {
    pCtx[k].startTs = pWin->skey;

H
Haojun Liao 已提交
609
    // keep it temporarily
dengyihao's avatar
dengyihao 已提交
610 611
    bool    hasAgg = pCtx[k].input.colDataAggIsSet;
    int32_t numOfRows = pCtx[k].input.numOfRows;
H
Haojun Liao 已提交
612
    int32_t startOffset = pCtx[k].input.startRowIndex;
613

H
Haojun Liao 已提交
614
    int32_t pos = (order == TSDB_ORDER_ASC) ? offset : offset - (forwardStep - 1);
615 616
    pCtx[k].input.startRowIndex = pos;
    pCtx[k].input.numOfRows = forwardStep;
617 618

    if (tsCol != NULL) {
H
Haojun Liao 已提交
619
      pCtx[k].ptsList = tsCol;
620 621 622 623 624 625 626 627
    }

    // 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;
    }

628 629
    if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
      SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
dengyihao's avatar
dengyihao 已提交
630
      char*                p = GET_ROWCELL_INTERBUF(pEntryInfo);
631

632
      SColumnInfoData idata = {0};
dengyihao's avatar
dengyihao 已提交
633
      idata.info.type = TSDB_DATA_TYPE_BIGINT;
634
      idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
dengyihao's avatar
dengyihao 已提交
635
      idata.pData = p;
636 637 638 639

      SScalarParam out = {.columnData = &idata};
      SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
      pCtx[k].sfp.process(&tw, 1, &out);
640 641 642
      pEntryInfo->numOfRes = 1;
      continue;
    }
643
    int32_t code = TSDB_CODE_SUCCESS;
644
    if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
645 646 647 648 649 650
      code = pCtx[k].fpSet.process(&pCtx[k]);
      if (code != TSDB_CODE_SUCCESS) {
        qError("%s apply functions error, code: %s", GET_TASKID(taskInfo), tstrerror(code));
        taskInfo->code = code;
        longjmp(taskInfo->env, code);
      }
651 652 653
    }

    // restore it
654 655 656
    pCtx[k].input.colDataAggIsSet = hasAgg;
    pCtx[k].input.startRowIndex = startOffset;
    pCtx[k].input.numOfRows = numOfRows;
657 658 659
  }
}

L
Liu Jicong 已提交
660
static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* pWindow) {
dengyihao's avatar
dengyihao 已提交
661
  TSKEY   ekey = -1;
662 663
  int32_t order = TSDB_ORDER_ASC;
  if (order == TSDB_ORDER_ASC) {
664 665 666 667 668 669 670 671 672 673 674 675 676 677
    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;
}

dengyihao's avatar
dengyihao 已提交
678
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
679
                                   int32_t scanFlag, bool createDummyCol);
680

dengyihao's avatar
dengyihao 已提交
681 682
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
                                    int32_t order) {
683
  for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
684
    pCtx[i].order = order;
L
Liu Jicong 已提交
685
    pCtx[i].size = pBlock->info.rows;
686
    setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
687 688 689
  }
}

690
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, int32_t scanFlag,
dengyihao's avatar
dengyihao 已提交
691
                       bool createDummyCol) {
692
  if (pBlock->pBlockAgg != NULL) {
H
Haojun Liao 已提交
693
    doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
694
  } else {
695
    doSetInputDataBlock(pOperator, pCtx, pBlock, order, scanFlag, createDummyCol);
H
Haojun Liao 已提交
696
  }
697 698
}

L
Liu Jicong 已提交
699 700
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t paramIndex,
                                             int32_t numOfRows) {
701 702 703 704 705 706 707 708
  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)
709 710
    pColInfo->info.type = pFuncParam->param.nType;
    pColInfo->info.bytes = pFuncParam->param.nLen;
711 712

    pInput->pData[paramIndex] = pColInfo;
713 714
  } else {
    pColInfo = pInput->pData[paramIndex];
715 716
  }

717
  colInfoDataEnsureCapacity(pColInfo, 0, numOfRows);
718

719
  int8_t type = pFuncParam->param.nType;
720 721
  if (type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_UBIGINT) {
    int64_t v = pFuncParam->param.i;
dengyihao's avatar
dengyihao 已提交
722
    for (int32_t i = 0; i < numOfRows; ++i) {
723 724 725 726
      colDataAppendInt64(pColInfo, i, &v);
    }
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
dengyihao's avatar
dengyihao 已提交
727
    for (int32_t i = 0; i < numOfRows; ++i) {
728 729
      colDataAppendDouble(pColInfo, i, &v);
    }
730
  } else if (type == TSDB_DATA_TYPE_VARCHAR) {
L
Liu Jicong 已提交
731
    char* tmp = taosMemoryMalloc(pFuncParam->param.nLen + VARSTR_HEADER_SIZE);
732
    STR_WITH_SIZE_TO_VARSTR(tmp, pFuncParam->param.pz, pFuncParam->param.nLen);
L
Liu Jicong 已提交
733
    for (int32_t i = 0; i < numOfRows; ++i) {
734 735
      colDataAppend(pColInfo, i, tmp, false);
    }
736 737 738 739 740
  }

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
741
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
742
    int32_t scanFlag, bool createDummyCol) {
743 744
  int32_t code = TSDB_CODE_SUCCESS;

745
  for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
L
Liu Jicong 已提交
746 747 748
    pCtx[i].order = order;
    pCtx[i].size = pBlock->info.rows;
    pCtx[i].pSrcBlock = pBlock;
749
    pCtx[i].currentStage = scanFlag;
H
Haojun Liao 已提交
750

751
    SInputColumnInfoData* pInput = &pCtx[i].input;
752
    pInput->uid = pBlock->info.uid;
C
Cary Xu 已提交
753
    pInput->colDataAggIsSet = false;
754

755 756
    SExprInfo* pOneExpr = &pOperator->pExpr[i];
    for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
dengyihao's avatar
dengyihao 已提交
757
      SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
G
Ganlin Zhao 已提交
758 759
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
dengyihao's avatar
dengyihao 已提交
760
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
761 762 763
        pInput->totalRows = pBlock->info.rows;
        pInput->numOfRows = pBlock->info.rows;
        pInput->startRowIndex = 0;
764

765
        // NOTE: the last parameter is the primary timestamp column
766 767 768
        if (fmIsTimelineFunc(pCtx[i].functionId) && (j == pOneExpr->base.numOfParams - 1)) {
          pInput->pPTS = pInput->pData[j];
        }
769 770
        ASSERT(pInput->pData[j] != NULL);
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
771 772 773
        // 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) {
774 775 776 777
          pInput->totalRows = pBlock->info.rows;
          pInput->numOfRows = pBlock->info.rows;
          pInput->startRowIndex = 0;

778
          code = doCreateConstantValColumnInfo(pInput, pFuncParam, j, pBlock->info.rows);
779 780 781
          if (code != TSDB_CODE_SUCCESS) {
            return code;
          }
782
        }
G
Ganlin Zhao 已提交
783 784
      }
    }
H
Haojun Liao 已提交
785

H
Haojun Liao 已提交
786
    //    setBlockStatisInfo(&pCtx[i], pBlock, pOperator->pExpr[i].base.pColumns);
H
Haojun Liao 已提交
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
    //      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);
    //        }
    //      }
  }
825 826

  return code;
H
Haojun Liao 已提交
827 828 829
}

static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
830
  for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
H
Haojun Liao 已提交
831
    if (functionNeedToExecute(&pCtx[k])) {
832 833 834 835
      pCtx[k].startTs = startTs;
      // this can be set during create the struct
      // todo add a dummy funtion to avoid process check
      if (pCtx[k].fpSet.process != NULL) {
836 837 838 839 840 841 842
        int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
        if (code != TSDB_CODE_SUCCESS) {
          qError("%s call aggregate function error happens, code : %s",
                 GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
          pOperator->pTaskInfo->code = code;
          longjmp(pOperator->pTaskInfo->env, code);
        }
843
      }
844 845 846 847
    }
  }
}

H
Haojun Liao 已提交
848
static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, SArray* pPseudoList) {
dengyihao's avatar
dengyihao 已提交
849
  size_t num = (pPseudoList != NULL) ? taosArrayGetSize(pPseudoList) : 0;
H
Haojun Liao 已提交
850 851 852 853 854
  for (int32_t i = 0; i < num; ++i) {
    pCtx[i].pOutput = taosArrayGet(pResult->pDataBlock, i);
  }
}

855
int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
X
Xiaoyu Wang 已提交
856
                              int32_t numOfOutput, SArray* pPseudoList) {
H
Haojun Liao 已提交
857
  setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
H
Haojun Liao 已提交
858
  pResult->info.groupId = pSrcBlock->info.groupId;
H
Haojun Liao 已提交
859

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

864 865
  int32_t numOfRows = 0;

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

L
Liu Jicong 已提交
870
    if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) {  // it is a project query
871
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
872
      if (pResult->info.rows > 0 && !createNewColModel) {
X
Xiaoyu Wang 已提交
873 874
        colDataMergeCol(pColInfoData, pResult->info.rows, &pResult->info.capacity, pfCtx->input.pData[0],
                        pfCtx->input.numOfRows);
875 876 877
      } else {
        colDataAssign(pColInfoData, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      }
878

879
      numOfRows = pfCtx->input.numOfRows;
880
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_VALUE) {
881
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
882

dengyihao's avatar
dengyihao 已提交
883
      int32_t offset = createNewColModel ? 0 : pResult->info.rows;
884
      for (int32_t i = 0; i < pSrcBlock->info.rows; ++i) {
dengyihao's avatar
dengyihao 已提交
885 886 887
        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);
888
      }
889 890

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

895
      SColumnInfoData* pResColData = taosArrayGet(pResult->pDataBlock, outputSlotId);
896
      SColumnInfoData  idata = {.info = pResColData->info, .hasNull = true};
897

898
      SScalarParam dest = {.columnData = &idata};
899 900
      scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);

dengyihao's avatar
dengyihao 已提交
901
      int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
902
      colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
903 904

      numOfRows = dest.numOfRows;
905 906
      taosArrayDestroy(pBlockList);
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) {
907
      ASSERT(!fmIsAggFunc(pfCtx->functionId));
908

909 910
      // _rowts/_c0, not tbname column
      if (fmIsPseudoColumnFunc(pfCtx->functionId) && (!fmIsScanPseudoColumnFunc(pfCtx->functionId))) {
H
Haojun Liao 已提交
911
        // do nothing
912
      } else if (fmIsNonstandardSQLFunc(pfCtx->functionId)) {
dengyihao's avatar
dengyihao 已提交
913
        SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[k]);
914
        pfCtx->fpSet.init(&pCtx[k], pResInfo);
915

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

919
        // set the timestamp(_rowts) output buffer
920 921
        if (taosArrayGetSize(pPseudoList) > 0) {
          int32_t* outputColIndex = taosArrayGet(pPseudoList, 0);
922
          pfCtx->pTsOutput = (SColumnInfoData*)pCtx[*outputColIndex].pOutput;
923
        }
H
Haojun Liao 已提交
924

925
        numOfRows = pfCtx->fpSet.process(pfCtx);
H
Haojun Liao 已提交
926 927 928
      } else {
        SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
        taosArrayPush(pBlockList, &pSrcBlock);
G
Ganlin Zhao 已提交
929

930
        SColumnInfoData* pResColData = taosArrayGet(pResult->pDataBlock, outputSlotId);
931
        SColumnInfoData  idata = {.info = pResColData->info, .hasNull = true};
H
Haojun Liao 已提交
932

933
        SScalarParam dest = {.columnData = &idata};
X
Xiaoyu Wang 已提交
934
        int32_t      code = scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
935 936 937 938
        if (code != TSDB_CODE_SUCCESS) {
          taosArrayDestroy(pBlockList);
          return code;
        }
939

dengyihao's avatar
dengyihao 已提交
940
        int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
941
        colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
942 943

        numOfRows = dest.numOfRows;
H
Haojun Liao 已提交
944 945
        taosArrayDestroy(pBlockList);
      }
946
    } else {
947
      ASSERT(0);
948 949
    }
  }
950

951 952 953
  if (!createNewColModel) {
    pResult->info.rows += numOfRows;
  }
954 955

  return TSDB_CODE_SUCCESS;
956 957
}

958 959 960
static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
  if (IS_VAR_DATA_TYPE(type)) {
    // todo disable this
961

962 963 964 965 966 967 968 969 970
    //    if (pResultRow->key == NULL) {
    //      pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
    //      varDataCopy(pResultRow->key, pData);
    //    } else {
    //      ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
    //    }
  } else {
    int64_t v = -1;
    GET_TYPED_DATA(v, int64_t, type, pData);
971

972 973
    pResultRow->win.skey = v;
    pResultRow->win.ekey = v;
974 975 976
  }
}

977 978 979 980 981
int32_t setGroupResultOutputBuf(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type, int16_t bytes,
                                int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo,
                                SAggSupporter* pAggSup) {
  SResultRowInfo* pResultRowInfo = &binfo->resultRowInfo;
  SqlFunctionCtx* pCtx = binfo->pCtx;
982

983 984 985
  SResultRow* pResultRow =
      doSetResultOutBufByKey(pBuf, pResultRowInfo, (char*)pData, bytes, true, groupId, pTaskInfo, false, pAggSup);
  assert(pResultRow != NULL);
986

987
  setResultRowKey(pResultRow, pData, type);
988
  setResultRowInitCtx(pResultRow, pCtx, numOfCols, binfo->rowCellInfoOffset);
989
  return TSDB_CODE_SUCCESS;
990 991
}

992 993
static bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
  struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
994

995 996 997 998 999
  // in case of timestamp column, always generated results.
  int32_t functionId = pCtx->functionId;
  if (functionId == -1) {
    return false;
  }
1000

1001
  if (isRowEntryCompleted(pResInfo)) {
1002 1003 1004
    return false;
  }

1005 1006 1007 1008 1009 1010 1011
  if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
    //    return QUERY_IS_ASC_QUERY(pQueryAttr);
  }

  // denote the order type
  if ((functionId == FUNCTION_LAST_DST || functionId == FUNCTION_LAST)) {
    //    return pCtx->param[0].i == pQueryAttr->order.order;
1012 1013
  }

1014 1015 1016 1017 1018
  // in the reverse table scan, only the following functions need to be executed
  //  if (IS_REVERSE_SCAN(pRuntimeEnv) ||
  //      (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
  //    return false;
  //  }
1019 1020 1021 1022

  return true;
}

1023 1024 1025 1026 1027 1028 1029
static int32_t doCreateConstantValColumnAggInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t type,
                                                int32_t paramIndex, int32_t numOfRows) {
  if (pInput->pData[paramIndex] == NULL) {
    pInput->pData[paramIndex] = taosMemoryCalloc(1, sizeof(SColumnInfoData));
    if (pInput->pData[paramIndex] == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }
1030

1031 1032 1033
    // Set the correct column info (data type and bytes)
    pInput->pData[paramIndex]->info.type = type;
    pInput->pData[paramIndex]->info.bytes = tDataTypes[type].bytes;
1034
  }
H
Haojun Liao 已提交
1035

1036 1037 1038 1039 1040 1041
  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;
1042 1043
    }
  } else {
1044
    da = pInput->pColumnDataAgg[paramIndex];
1045 1046
  }

1047
  ASSERT(!IS_VAR_DATA_TYPE(type));
1048

1049 1050 1051 1052 1053 1054
  if (type == TSDB_DATA_TYPE_BIGINT) {
    int64_t v = pFuncParam->param.i;
    *da = (SColumnDataAgg){.numOfNull = 0, .min = v, .max = v, .maxIndex = 0, .minIndex = 0, .sum = v * numOfRows};
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
    *da = (SColumnDataAgg){.numOfNull = 0, .maxIndex = 0, .minIndex = 0};
1055

1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
    *(double*)&da->min = v;
    *(double*)&da->max = v;
    *(double*)&da->sum = v * numOfRows;
  } else if (type == TSDB_DATA_TYPE_BOOL) {  // todo validate this data type
    bool v = pFuncParam->param.i;

    *da = (SColumnDataAgg){.numOfNull = 0, .maxIndex = 0, .minIndex = 0};
    *(bool*)&da->min = 0;
    *(bool*)&da->max = v;
    *(bool*)&da->sum = v * numOfRows;
  } else if (type == TSDB_DATA_TYPE_TIMESTAMP) {
    // do nothing
1068
  } else {
1069
    ASSERT(0);
1070 1071
  }

1072 1073
  return TSDB_CODE_SUCCESS;
}
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084

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;

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

1088 1089
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
1090 1091 1092 1093
        pInput->pColumnDataAgg[j] = pBlock->pBlockAgg[slotId];
        if (pInput->pColumnDataAgg[j] == NULL) {
          pInput->colDataAggIsSet = false;
        }
1094 1095 1096 1097

        // 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);
1098 1099
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
        doCreateConstantValColumnAggInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
1100 1101
      }
    }
1102
  } else {
1103
    pInput->colDataAggIsSet = false;
1104 1105 1106
  }

  // set the statistics data for primary time stamp column
1107 1108 1109 1110 1111
  //  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;
  //  }
1112 1113 1114
}

// set the output buffer for the selectivity + tag query
1115
static int32_t setSelectValueColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1116 1117
  int32_t num = 0;

H
Haojun Liao 已提交
1118
  SqlFunctionCtx*  p = NULL;
1119 1120
  SqlFunctionCtx** pValCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
  if (pValCtx == NULL) {
1121 1122 1123 1124
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
1125 1126
    if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
      pValCtx[num++] = &pCtx[i];
1127
    } else if (fmIsAggFunc(pCtx[i].functionId)) {
1128
      p = &pCtx[i];
1129
    }
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
//    if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
//      tagLen += pCtx[i].resDataInfo.bytes;
//      pTagCtx[num++] = &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
//    }
1140
  }
1141

1142
  if (p != NULL) {
1143
    p->subsidiaries.pCtx = pValCtx;
1144
    p->subsidiaries.num = num;
1145
  } else {
1146
    taosMemoryFreeClear(pValCtx);
1147 1148 1149 1150 1151
  }

  return TSDB_CODE_SUCCESS;
}

1152
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) {
L
Liu Jicong 已提交
1153
  SqlFunctionCtx* pFuncCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
H
Haojun Liao 已提交
1154 1155 1156 1157
  if (pFuncCtx == NULL) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
1158
  *rowCellInfoOffset = taosMemoryCalloc(numOfOutput, sizeof(int32_t));
H
Haojun Liao 已提交
1159
  if (*rowCellInfoOffset == 0) {
wafwerar's avatar
wafwerar 已提交
1160
    taosMemoryFreeClear(pFuncCtx);
H
Haojun Liao 已提交
1161 1162 1163 1164
    return NULL;
  }

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

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

1170
    pCtx->functionId = -1;
1171
    pCtx->curBufPage = -1;
L
Liu Jicong 已提交
1172
    pCtx->pExpr = pExpr;
1173

H
Haojun Liao 已提交
1174
    if (pExpr->pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1175
      SFuncExecEnv env = {0};
H
Haojun Liao 已提交
1176 1177
      pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;

H
Haojun Liao 已提交
1178
      if (fmIsAggFunc(pCtx->functionId) || fmIsNonstandardSQLFunc(pCtx->functionId)) {
1179 1180 1181 1182
        bool isUdaf = fmIsUserDefinedFunc(pCtx->functionId);
        if (!isUdaf) {
          fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
        } else {
1183
          char* udfName = pExpr->pExpr->_function.pFunctNode->functionName;
1184 1185 1186
          strncpy(pCtx->udfName, udfName, strlen(udfName));
          fmGetUdafExecFuncs(pCtx->functionId, &pCtx->fpSet);
        }
1187 1188 1189
        pCtx->fpSet.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
      } else {
        fmGetScalarFuncExecFuncs(pCtx->functionId, &pCtx->sfp);
1190 1191 1192
        if (pCtx->sfp.getEnv != NULL) {
          pCtx->sfp.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
        }
1193
      }
H
Haojun Liao 已提交
1194
      pCtx->resDataInfo.interBufSize = env.calcMemSize;
1195 1196
    } else if (pExpr->pExpr->nodeType == QUERY_NODE_COLUMN || pExpr->pExpr->nodeType == QUERY_NODE_OPERATOR ||
               pExpr->pExpr->nodeType == QUERY_NODE_VALUE) {
H
Haojun Liao 已提交
1197
      // for simple column, the result buffer needs to hold at least one element.
1198
      pCtx->resDataInfo.interBufSize = pFunct->resSchema.bytes;
H
Haojun Liao 已提交
1199
    }
H
Haojun Liao 已提交
1200

H
Haojun Liao 已提交
1201
    pCtx->input.numOfInputCols = pFunct->numOfParams;
wafwerar's avatar
wafwerar 已提交
1202 1203
    pCtx->input.pData = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
    pCtx->input.pColumnDataAgg = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
H
Haojun Liao 已提交
1204

1205
    pCtx->pTsOutput = NULL;
L
Liu Jicong 已提交
1206
    pCtx->resDataInfo.bytes = pFunct->resSchema.bytes;
1207
    pCtx->resDataInfo.type = pFunct->resSchema.type;
L
Liu Jicong 已提交
1208
    pCtx->order = TSDB_ORDER_ASC;
1209
    pCtx->start.key = INT64_MIN;
L
Liu Jicong 已提交
1210
    pCtx->end.key = INT64_MIN;
1211
    pCtx->numOfParams = pExpr->base.numOfParams;
H
Haojun Liao 已提交
1212

1213
    pCtx->param = pFunct->pParam;
dengyihao's avatar
dengyihao 已提交
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
    //    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 已提交
1248 1249
  }

L
Liu Jicong 已提交
1250 1251 1252
  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 已提交
1253
  }
H
Haojun Liao 已提交
1254

1255
  setSelectValueColumnInfo(pFuncCtx, numOfOutput);
H
Haojun Liao 已提交
1256 1257 1258
  return pFuncCtx;
}

1259
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1260 1261 1262 1263 1264 1265
  if (pCtx == NULL) {
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    for (int32_t j = 0; j < pCtx[i].numOfParams; ++j) {
1266
      taosVariantDestroy(&pCtx[i].param[j].param);
1267 1268 1269
    }

    taosVariantDestroy(&pCtx[i].tag);
1270
    taosMemoryFreeClear(pCtx[i].subsidiaries.pCtx);
H
Haojun Liao 已提交
1271 1272
    taosMemoryFree(pCtx[i].input.pData);
    taosMemoryFree(pCtx[i].input.pColumnDataAgg);
1273 1274
  }

wafwerar's avatar
wafwerar 已提交
1275
  taosMemoryFreeClear(pCtx);
1276 1277 1278
  return NULL;
}

L
Liu Jicong 已提交
1279
bool isTaskKilled(SExecTaskInfo* pTaskInfo) {
1280 1281
  // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
  // abort current query execution.
L
Liu Jicong 已提交
1282 1283
  if (pTaskInfo->owner != 0 &&
      ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec())
1284 1285
      /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) {
    assert(pTaskInfo->cost.start != 0);
L
Liu Jicong 已提交
1286 1287 1288
    //    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;
1289 1290 1291 1292 1293
  }

  return false;
}

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

L
Liu Jicong 已提交
1296
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
1297 1298 1299 1300 1301 1302 1303 1304 1305
  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;
  }

1306 1307
  int32_t order = TSDB_ORDER_ASC;
  if (order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) {
1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326
    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 已提交
1327
// todo refactor : return window
1328
void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, STimeWindow* win) {
H
Haojun Liao 已提交
1329
  win->skey = taosTimeTruncate(key, pInterval, precision);
1330 1331

  /*
H
Haojun Liao 已提交
1332
   * if the realSkey > INT64_MAX - pInterval->interval, the query duration between
1333 1334
   * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
   */
1335 1336
  win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
  if (win->ekey < win->skey) {
1337 1338 1339 1340
    win->ekey = INT64_MAX;
  }
}

L
Liu Jicong 已提交
1341
static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
1342 1343 1344
  bool hasFirstLastFunc = false;
  bool hasOtherFunc = false;

1345
  if (status == BLK_DATA_DATA_LOAD || status == BLK_DATA_FILTEROUT) {
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
    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;
    }
  }

1364
  if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
L
Liu Jicong 已提交
1365
    if (!hasOtherFunc) {
1366
      return BLK_DATA_FILTEROUT;
1367
    } else {
1368
      return BLK_DATA_DATA_LOAD;
1369 1370 1371 1372 1373 1374
    }
  }

  return status;
}

L
Liu Jicong 已提交
1375 1376
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
//   STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
H
Haojun Liao 已提交
1377
//
L
Liu Jicong 已提交
1378 1379 1380 1381
//   // 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 已提交
1382
//
L
Liu Jicong 已提交
1383 1384 1385 1386 1387
//   // 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 已提交
1388
//
L
Liu Jicong 已提交
1389 1390
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
wafwerar's avatar
wafwerar 已提交
1391
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
L
Liu Jicong 已提交
1392
//     }
H
Haojun Liao 已提交
1393
//
L
Liu Jicong 已提交
1394 1395 1396
//     pQueryAttr->needReverseScan = false;
//     return;
//   }
H
Haojun Liao 已提交
1397
//
L
Liu Jicong 已提交
1398 1399 1400
//   if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) {
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
wafwerar's avatar
wafwerar 已提交
1401
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
L
Liu Jicong 已提交
1402
//     }
H
Haojun Liao 已提交
1403
//
L
Liu Jicong 已提交
1404 1405 1406 1407
//     pQueryAttr->needReverseScan = false;
//     doUpdateLastKey(pQueryAttr);
//     return;
//   }
H
Haojun Liao 已提交
1408
//
L
Liu Jicong 已提交
1409 1410 1411 1412 1413 1414
//   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 已提交
1415
//
L
Liu Jicong 已提交
1416 1417 1418
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     return;
//   }
H
Haojun Liao 已提交
1419
//
L
Liu Jicong 已提交
1420 1421 1422 1423
//   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 已提交
1424 1425
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
wafwerar's avatar
wafwerar 已提交
1426
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
//        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);
//
wafwerar's avatar
wafwerar 已提交
1437
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449
//        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 已提交
1450 1451
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
1452
//
wafwerar's avatar
wafwerar 已提交
1453
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1454 1455 1456 1457 1458 1459 1460 1461
//          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 已提交
1462 1463
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
1464
//
wafwerar's avatar
wafwerar 已提交
1465
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1466 1467 1468 1469 1470 1471 1472 1473 1474
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_DESC;
//        pQueryAttr->needReverseScan = false;
//      }
//    }
//  }
//}
1475

H
Haojun Liao 已提交
1476 1477
static void getIntermediateBufInfo(STaskRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) {
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
L
Liu Jicong 已提交
1478
  int32_t    MIN_ROWS_PER_PAGE = 4;
1479

L
Liu Jicong 已提交
1480 1481
  *rowsize = (int32_t)(pQueryAttr->resultRowSize *
                       getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
1482 1483 1484 1485
  int32_t overhead = sizeof(SFilePage);

  // one page contains at least two rows
  *ps = DEFAULT_INTERN_BUF_PAGE_SIZE;
L
Liu Jicong 已提交
1486
  while (((*rowsize) * MIN_ROWS_PER_PAGE) > (*ps) - overhead) {
1487 1488 1489 1490
    *ps = ((*ps) << 1u);
  }
}

L
Liu Jicong 已提交
1491 1492 1493
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
//   STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
1494
//
L
Liu Jicong 已提交
1495 1496 1497
//   if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
//     return true;
//   }
1498
//
L
Liu Jicong 已提交
1499 1500
//   return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
1501

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

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

1508
  if (true) {
L
Liu Jicong 已提交
1509
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
1510 1511 1512 1513 1514 1515
    assert(w.ekey >= pBlockInfo->window.skey);

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

L
Liu Jicong 已提交
1516 1517
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527
      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 已提交
1528
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
1529 1530 1531 1532 1533 1534
    assert(w.skey <= pBlockInfo->window.ekey);

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

L
Liu Jicong 已提交
1535 1536
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600
      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 已提交
1601
static void         doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes);
1602 1603

static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
1604
  SqlFunctionCtx* pCtx = pTableScanInfo->pCtx;
1605
  uint32_t        status = BLK_DATA_NOT_LOAD;
1606 1607 1608 1609

  int32_t numOfOutput = pTableScanInfo->numOfOutput;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;
H
Haojun Liao 已提交
1610
    int32_t colId = pTableScanInfo->pExpr[i].base.pParam[0].pCol->colId;
1611 1612 1613

    // group by + first/last should not apply the first/last block filter
    if (functionId < 0) {
1614
      status |= BLK_DATA_DATA_LOAD;
1615 1616
      return status;
    } else {
L
Liu Jicong 已提交
1617
      //      status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
1618
      //      if ((status & BLK_DATA_DATA_LOAD) == BLK_DATA_DATA_LOAD) {
L
Liu Jicong 已提交
1619 1620
      //        return status;
      //      }
1621 1622 1623 1624 1625 1626
    }
  }

  return status;
}

L
Liu Jicong 已提交
1627 1628
int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                              uint32_t* status) {
1629
  *status = BLK_DATA_NOT_LOAD;
1630

H
Haojun Liao 已提交
1631
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
1632
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
1633

L
Liu Jicong 已提交
1634 1635
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
1636

H
Haojun Liao 已提交
1637
  STaskCostInfo* pCost = &pTaskInfo->cost;
1638

1639 1640
//  pCost->totalBlocks += 1;
//  pCost->totalRows += pBlock->info.rows;
H
Haojun Liao 已提交
1641
#if 0
1642 1643 1644
  // 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 已提交
1645
      (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) {
1646
    (*status) = BLK_DATA_DATA_LOAD;
1647 1648 1649
  }

  // check if this data block is required to load
1650
  if ((*status) != BLK_DATA_DATA_LOAD) {
1651 1652 1653 1654 1655 1656 1657
    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 已提交
1658
      bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
      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 {
1682
      (*status) = BLK_DATA_DATA_LOAD;
1683 1684 1685 1686
    }
  }

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

1689
  if ((*status) == BLK_DATA_NOT_LOAD || (*status) == BLK_DATA_FILTEROUT) {
1690 1691
    //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//           pBlockInfo->window.ekey, pBlockInfo->rows);
1692
    pCost->skipBlocks += 1;
1693
  } else if ((*status) == BLK_DATA_SMA_LOAD) {
1694 1695
    // this function never returns error?
    pCost->loadBlockStatis += 1;
1696
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
1697 1698

    if (pBlock->pBlockAgg == NULL) {  // data block statistics does not exist, load data block
1699
//      pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
1700 1701 1702
      pCost->totalCheckedRows += pBlock->info.rows;
    }
  } else {
1703
    assert((*status) == BLK_DATA_DATA_LOAD);
1704 1705 1706

    // load the data block statistics to perform further filter
    pCost->loadBlockStatis += 1;
1707
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
1708 1709 1710 1711 1712 1713

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

H
Haojun Liao 已提交
1714
          bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731
          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
1732
            pCost->skipBlocks += 1;
1733 1734
            //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
//                   pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
1735
            (*status) = BLK_DATA_FILTEROUT;
1736 1737 1738 1739 1740 1741 1742 1743
            return TSDB_CODE_SUCCESS;
          }
        }
      }
    }

    // current block has been discard due to filter applied
//    if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
1744
//      pCost->skipBlocks += 1;
1745 1746
//      qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//             pBlockInfo->window.ekey, pBlockInfo->rows);
1747
//      (*status) = BLK_DATA_FILTEROUT;
1748 1749 1750 1751 1752
//      return TSDB_CODE_SUCCESS;
//    }

    pCost->totalCheckedRows += pBlockInfo->rows;
    pCost->loadBlocks += 1;
1753
//    pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
1754 1755 1756 1757 1758 1759 1760
//    if (pBlock->pDataBlock == NULL) {
//      return terrno;
//    }

//    if (pQueryAttr->pFilters != NULL) {
//      filterSetColFieldData(pQueryAttr->pFilters, pBlock->info.numOfCols, pBlock->pDataBlock);
//    }
1761

1762 1763 1764 1765
//    if (pQueryAttr->pFilters != NULL || pRuntimeEnv->pTsBuf != NULL) {
//      filterColRowsInDataBlock(pRuntimeEnv, pBlock, ascQuery);
//    }
  }
H
Haojun Liao 已提交
1766
#endif
1767 1768 1769 1770
  return TSDB_CODE_SUCCESS;
}

/*
H
Haojun Liao 已提交
1771
 * set tag value in SqlFunctionCtx
1772 1773
 * e.g.,tag information into input buffer
 */
L
Liu Jicong 已提交
1774
static void doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes) {
1775 1776 1777
  taosVariantDestroy(tag);

  char* val = NULL;
L
Liu Jicong 已提交
1778 1779 1780 1781 1782 1783
  //  if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
  //    val = tsdbGetTableName(pTable);
  //    assert(val != NULL);
  //  } else {
  //    val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
  //  }
1784 1785 1786 1787 1788 1789 1790 1791

  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 已提交
1792
    int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
1793
    taosVariantCreateFromBinary(tag, varDataVal(val), len, type);
L
Liu Jicong 已提交
1794
    // taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
1795 1796 1797 1798 1799 1800 1801 1802
  } 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 已提交
1803
  for (int32_t i = 0; i < numOfTags; ++i) {
1804 1805 1806 1807 1808 1809 1810 1811
    if (pTagColList[i].colId == colId) {
      return &pTagColList[i];
    }
  }

  return NULL;
}

L
Liu Jicong 已提交
1812 1813
void setTagValue(SOperatorInfo* pOperatorInfo, void* pTable, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
  SExprInfo* pExpr = pOperatorInfo->pExpr;
1814
  SExprInfo* pExprInfo = &pExpr[0];
L
Liu Jicong 已提交
1815
  int32_t    functionId = getExprFunctionId(pExprInfo);
1816
#if 0
1817 1818 1819
  if (pQueryAttr->numOfOutput == 1 && functionId == FUNCTION_TS_COMP && pQueryAttr->stableQuery) {
    assert(pExprInfo->base.numOfParams == 1);

L
Liu Jicong 已提交
1820
    //    int16_t      tagColId = (int16_t)pExprInfo->base.param[0].i;
H
Haojun Liao 已提交
1821
    int16_t      tagColId = -1;
1822 1823 1824
    SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);

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

1826 1827 1828 1829 1830 1831 1832 1833 1834
  } 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 已提交
1835
      if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.pParam[0].pCol->flag)) {
1836 1837 1838 1839
        continue;
      }

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

L
Liu Jicong 已提交
1843 1844 1845
      if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resSchema.type) ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_BOOL ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_TIMESTAMP) {
1846 1847 1848 1849
        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 已提交
1850
        }
1851 1852 1853 1854 1855 1856 1857 1858 1859 1860
      }

      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);
  }
1861
#endif
1862 1863
}

H
Haojun Liao 已提交
1864
void copyToSDataBlock(SSDataBlock* pBlock, int32_t* offset, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pResBuf) {
1865 1866 1867 1868 1869 1870 1871
  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 已提交
1872 1873 1874
      //      if ((code = mergeIntoGroupResult(&pGroupResInfo, pRuntimeEnv, offset)) != TSDB_CODE_SUCCESS) {
      return;
      //      }
1875 1876
    }

L
Liu Jicong 已提交
1877
    //    doCopyToSDataBlock(pResBuf, pGroupResInfo, TSDB_ORDER_ASC, pBlock, );
1878 1879 1880 1881 1882 1883 1884 1885 1886 1887

    // 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 已提交
1888 1889 1890
    //    if (pBlock->info.rows >= threshold) {
    //      break;
    //    }
1891 1892 1893
  }
}

L
Liu Jicong 已提交
1894
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
1895 1896 1897 1898
  if (pTableQueryInfo == NULL) {
    return;
  }

wafwerar's avatar
wafwerar 已提交
1899
  //  TSWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey);
L
Liu Jicong 已提交
1900
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
1901

L
Liu Jicong 已提交
1902 1903
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
1904 1905

  // set the index to be the end slot of result rows array
dengyihao's avatar
dengyihao 已提交
1906 1907 1908 1909 1910 1911
  //  SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->size > 0) {
  //    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  //  } else {
  //    pResultRowInfo->curPos = -1;
  //  }
1912 1913
}

H
Haojun Liao 已提交
1914
void initResultRow(SResultRow* pResultRow) {
X
Xiaoyu Wang 已提交
1915
  //  pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
1916 1917 1918 1919 1920
}

/*
 * 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 已提交
1921 1922 1923
 * +------------+-----------------result column 1------------+------------------result column 2-----------+
 * | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2|
 * +------------+--------------------------------------------+--------------------------------------------+
1924 1925
 *           offset[0]                                  offset[1]                                   offset[2]
 */
1926
// TODO refactor: some function move away
X
Xiaoyu Wang 已提交
1927 1928
void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, int32_t numOfExprs,
                             SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
1929 1930 1931
  SqlFunctionCtx* pCtx = pInfo->pCtx;
  SSDataBlock*    pDataBlock = pInfo->pRes;
  int32_t*        rowCellInfoOffset = pInfo->rowCellInfoOffset;
H
Haojun Liao 已提交
1932

H
Haojun Liao 已提交
1933
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
1934
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
1935

L
Liu Jicong 已提交
1936 1937
  int64_t     tid = 0;
  int64_t     groupId = 0;
1938 1939
  SResultRow* pRow = doSetResultOutBufByKey(pSup->pResultBuf, pResultRowInfo, (char*)&tid, sizeof(tid), true, groupId,
                                            pTaskInfo, false, pSup);
H
Haojun Liao 已提交
1940

H
Haojun Liao 已提交
1941
  ASSERT(pDataBlock->info.numOfCols == numOfExprs);
H
Haojun Liao 已提交
1942 1943 1944 1945
  for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
    struct SResultRowEntryInfo* pEntry = getResultCell(pRow, i, rowCellInfoOffset);
    cleanupResultRowEntry(pEntry);

L
Liu Jicong 已提交
1946
    pCtx[i].resultInfo = pEntry;
H
Haojun Liao 已提交
1947 1948 1949
    pCtx[i].currentStage = stage;

    // set the timestamp output buffer for top/bottom/diff query
L
Liu Jicong 已提交
1950 1951
    //    int32_t fid = pCtx[i].functionId;
    //    if (fid == FUNCTION_TOP || fid == FUNCTION_BOTTOM || fid == FUNCTION_DIFF || fid == FUNCTION_DERIVATIVE) {
H
Haojun Liao 已提交
1952
    //      if (i > 0) pCtx[i].pTsOutput = pCtx[i-1].pOutput;
L
Liu Jicong 已提交
1953
    //    }
H
Haojun Liao 已提交
1954 1955 1956 1957 1958
  }

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

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

L
Liu Jicong 已提交
1962
  int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5;  // extra output buffer
1963
  if ((*bufCapacity) < newSize) {
L
Liu Jicong 已提交
1964 1965
    for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
1966

wafwerar's avatar
wafwerar 已提交
1967
      char* p = taosMemoryRealloc(pColInfo->pData, newSize * pColInfo->info.bytes);
1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980
      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 已提交
1981
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
1982 1983 1984 1985 1986
    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 已提交
1987 1988
    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
        functionId == FUNCTION_DERIVATIVE) {
dengyihao's avatar
dengyihao 已提交
1989
      //      if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
1990 1991 1992 1993
    }
  }
}

H
Haojun Liao 已提交
1994
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1995 1996
  bool    needCopyTs = false;
  int32_t tsNum = 0;
L
Liu Jicong 已提交
1997
  char*   src = NULL;
1998 1999 2000 2001
  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 已提交
2002 2003
      if (i > 0 && pCtx[i - 1].functionId == FUNCTION_TS_DUMMY) {
        SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1);  // find ts data
2004 2005
        src = pColRes->pData;
      }
L
Liu Jicong 已提交
2006
    } else if (functionId == FUNCTION_TS_DUMMY) {
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
      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 已提交
2017
    if (functionId == FUNCTION_TS_DUMMY) {
2018 2019 2020 2021 2022 2023
      SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i);
      memcpy(pColRes->pData, src, pColRes->info.bytes * pRes->info.rows);
    }
  }
}

H
Haojun Liao 已提交
2024
void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size) {
2025 2026
  for (int32_t j = 0; j < size; ++j) {
    struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
dengyihao's avatar
dengyihao 已提交
2027 2028
    if (isRowEntryInitialized(pResInfo) || fmIsPseudoColumnFunc(pCtx[j].functionId) || pCtx[j].functionId == -1 ||
        fmIsScalarFunc(pCtx[j].functionId)) {
2029 2030 2031
      continue;
    }

H
Haojun Liao 已提交
2032
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
2033 2034 2035
  }
}

L
Liu Jicong 已提交
2036
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
2037
  if (status == TASK_NOT_COMPLETED) {
H
Haojun Liao 已提交
2038
    pTaskInfo->status = status;
2039 2040
  } else {
    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
2041
    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
2042
    pTaskInfo->status |= status;
2043 2044 2045
  }
}

2046
// todo merged with the build group result.
2047 2048
void finalizeMultiTupleQueryResult(int32_t numOfOutput, SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo,
                                   int32_t* rowCellInfoOffset) {
2049 2050 2051
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
    SResultRowPosition* pPos = &pResultRowInfo->pPosition[i];

L
Liu Jicong 已提交
2052
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pageId);
2053
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset);
H
Haojun Liao 已提交
2054 2055

    // TODO ignore the close status anyway.
dengyihao's avatar
dengyihao 已提交
2056 2057 2058
    //    if (!isResultRowClosed(pRow)) {
    //      continue;
    //    }
2059

2060
    for (int32_t j = 0; j < numOfOutput; ++j) {
2061
      struct SResultRowEntryInfo* pResInfo = getResultCell(pRow, j, rowCellInfoOffset);
H
Haojun Liao 已提交
2062
      if (!isRowEntryInitialized(pResInfo)) {
2063 2064 2065 2066 2067 2068
        continue;
      }

      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
2069
    }
2070 2071 2072

    releaseBufPage(pBuf, bufPage);
  }
2073 2074
}

2075
STableQueryInfo* createTableQueryInfo(void* buf, STimeWindow win) {
L
Liu Jicong 已提交
2076
  STableQueryInfo* pTableQueryInfo = buf;
2077 2078 2079 2080
  pTableQueryInfo->lastKey = win.skey;
  return pTableQueryInfo;
}

L
Liu Jicong 已提交
2081
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
2082 2083 2084 2085
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2086
  //  taosVariantDestroy(&pTableQueryInfo->tag);
dengyihao's avatar
dengyihao 已提交
2087
  //  cleanupResultRowInfo(&pTableQueryInfo->resInfo);
2088 2089
}

2090
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) {
2091 2092 2093 2094 2095 2096 2097
  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;
    }
2098 2099 2100 2101 2102

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

2103 2104 2105 2106 2107 2108
    if (!pResInfo->initialized) {
      if (pCtx[i].functionId != -1) {
        pCtx[i].fpSet.init(&pCtx[i], pResInfo);
      } else {
        pResInfo->initialized = true;
      }
2109 2110 2111 2112
    }
  }
}

2113 2114 2115 2116 2117 2118
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
  if (pFilterNode == NULL) {
    return;
  }

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

H
Haojun Liao 已提交
2120
  // todo move to the initialization function
H
Haojun Liao 已提交
2121
  int32_t code = filterInitFromNode((SNode*)pFilterNode, &filter, 0);
2122 2123 2124 2125 2126 2127

  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 已提交
2128
  filterFreeInfo(filter);
2129

2130
  SSDataBlock* px = createOneDataBlock(pBlock, false);
2131 2132
  blockDataEnsureCapacity(px, pBlock->info.rows);

H
Haojun Liao 已提交
2133
  // todo extract method
2134 2135 2136 2137
  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 已提交
2138 2139 2140 2141 2142 2143 2144 2145 2146
    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;
        }
2147

D
dapan1121 已提交
2148 2149 2150 2151 2152 2153
        if (colDataIsNull_s(pSrc, j)) {
          colDataAppendNULL(pDst, numOfRow);
        } else {
          colDataAppend(pDst, numOfRow, colDataGetData(pSrc, j), false);
        }
        numOfRow += 1;
H
Haojun Liao 已提交
2154
      }
D
dapan1121 已提交
2155 2156
    } else {
      numOfRow = 0;
2157 2158 2159 2160 2161 2162
    }

    *pSrc = *pDst;
  }

  pBlock->info.rows = numOfRow;
2163
  blockDataUpdateTsWindow(pBlock);
2164 2165
}

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

2171 2172
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
2173
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
2174

2175
  SResultRow* pResultRow = doSetResultOutBufByKey(pAggInfo->aggSup.pResultBuf, pResultRowInfo, (char*)&groupId,
L
Liu Jicong 已提交
2176
                                                  sizeof(groupId), true, groupId, pTaskInfo, false, &pAggInfo->aggSup);
L
Liu Jicong 已提交
2177
  assert(pResultRow != NULL);
2178 2179 2180 2181 2182 2183

  /*
   * 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 已提交
2184 2185
    int32_t ret =
        addNewWindowResultBuf(pResultRow, pAggInfo->aggSup.pResultBuf, groupId, pAggInfo->binfo.pRes->info.rowSize);
2186 2187 2188 2189 2190
    if (ret != TSDB_CODE_SUCCESS) {
      return;
    }
  }

2191
  setResultRowInitCtx(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
2192 2193
}

H
Haojun Liao 已提交
2194 2195
void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* pTaskInfo, SAggOperatorInfo* pAggInfo) {
  if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
2196 2197 2198
    return;
  }

H
Haojun Liao 已提交
2199
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, groupId, pTaskInfo);
2200 2201

  // record the current active group id
H
Haojun Liao 已提交
2202
  pAggInfo->groupId = groupId;
2203 2204 2205 2206 2207 2208 2209 2210 2211 2212
}

/**
 * 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
 */
2213
int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo,
2214
                           int32_t orderType, int32_t* rowCellOffset, SqlFunctionCtx* pCtx) {
2215
  int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
L
Liu Jicong 已提交
2216
  int32_t numOfResult = pBlock->info.rows;  // there are already exists result rows
2217 2218

  int32_t start = 0;
2219
  int32_t step = 1;
2220

L
Liu Jicong 已提交
2221
  // qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
2222 2223 2224 2225 2226 2227 2228 2229 2230
  assert(orderType == TSDB_ORDER_ASC || orderType == TSDB_ORDER_DESC);

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

  for (int32_t i = start; (i < numOfRows) && (i >= 0); i += step) {
L
Liu Jicong 已提交
2231 2232
    SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
    SFilePage*  page = getBufPage(pBuf, pPos->pos.pageId);
2233

2234
    SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
2235 2236 2237 2238 2239
    if (pRow->numOfRows == 0) {
      pGroupResInfo->index += 1;
      continue;
    }

2240
    // TODO copy multiple rows?
2241
    int32_t numOfRowsToCopy = pRow->numOfRows;
2242
    if (numOfResult + numOfRowsToCopy >= pBlock->info.capacity) {
2243 2244 2245 2246 2247 2248
      break;
    }

    pGroupResInfo->index += 1;

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

2251
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
2252 2253 2254
      if (pCtx[j].fpSet.finalize) {
        int32_t code = TSDB_CODE_SUCCESS;
        code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
2255
        if (TAOS_FAILED(code)) {
2256 2257 2258 2259
          qError("%s build result data block error, code %s", GET_TASKID(taskInfo), tstrerror(code));
          taskInfo->code = code;
          longjmp(taskInfo->env, code);
        }
2260 2261
      } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
        // do nothing, todo refactor
2262
      } else {
2263 2264 2265 2266 2267 2268 2269
        // expand the result into multiple rows. E.g., _wstartts, top(k, 20)
        // the _wstartts needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
          SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
          char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
          for(int32_t k = 0; k < pRow->numOfRows; ++k) {
            colDataAppend(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes);
          }
2270
      }
2271 2272
    }

2273 2274
    releaseBufPage(pBuf, page);

2275 2276
    pBlock->info.rows += pRow->numOfRows;
    if (pBlock->info.rows >= pBlock->info.capacity) {  // output buffer is full
2277 2278 2279 2280
      break;
    }
  }

L
Liu Jicong 已提交
2281
  // qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
2282
  blockDataUpdateTsWindow(pBlock);
2283 2284 2285
  return 0;
}

2286
void doBuildResultDatablock(SExecTaskInfo *taskInfo, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo,
X
Xiaoyu Wang 已提交
2287
                            SDiskbasedBuf* pBuf) {
2288 2289
  assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup);

X
Xiaoyu Wang 已提交
2290 2291 2292
  int32_t*        rowCellOffset = pbInfo->rowCellInfoOffset;
  SSDataBlock*    pBlock = pbInfo->pRes;
  SqlFunctionCtx* pCtx = pbInfo->pCtx;
2293

2294
  blockDataCleanup(pBlock);
2295 2296 2297 2298
  if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
    return;
  }

2299
  int32_t orderType = TSDB_ORDER_ASC;
2300
  doCopyToSDataBlock(taskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
2301

H
Haojun Liao 已提交
2302 2303
  // add condition (pBlock->info.rows >= 1) just to runtime happy
  blockDataUpdateTsWindow(pBlock);
2304 2305
}

L
Liu Jicong 已提交
2306 2307
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
                                        int32_t* rowCellInfoOffset) {
2308
  // update the number of result for each, only update the number of rows for the corresponding window result.
L
Liu Jicong 已提交
2309 2310 2311
  //  if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
  //    return;
  //  }
H
Haojun Liao 已提交
2312
#if 0
2313
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
L
Liu Jicong 已提交
2314
    SResultRow* pResult = pResultRowInfo->pResult[i];
2315 2316 2317 2318 2319 2320 2321

    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;
      }

2322 2323
      SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
      pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
2324 2325
    }
  }
H
Haojun Liao 已提交
2326
#endif
2327 2328
}

L
Liu Jicong 已提交
2329
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
2330 2331
  int32_t colSize = pColRes->info.bytes * numOfRows;
  return (*(tDataTypes[pColRes->info.type].compFunc))(pColRes->pData, colSize, numOfRows, data,
L
Liu Jicong 已提交
2332
                                                      colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
2333 2334
}

2335
int32_t doFillTimeIntervalGapsInResults(struct SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t capacity) {
L
Liu Jicong 已提交
2336 2337 2338 2339
  //  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);
  //  }
2340

2341 2342
  int32_t numOfRows = (int32_t)taosFillResultDataBlock(pFillInfo, pBlock, capacity - pBlock->info.rows);
  pBlock->info.rows += numOfRows;
2343

2344
  return pBlock->info.rows;
2345 2346
}

2347
void publishOperatorProfEvent(SOperatorInfo* pOperator, EQueryProfEventType eventType) {
2348 2349
  SQueryProfEvent event = {0};

L
Liu Jicong 已提交
2350 2351
  event.eventType = eventType;
  event.eventTime = taosGetTimestampUs();
2352
  event.operatorType = pOperator->operatorType;
dengyihao's avatar
dengyihao 已提交
2353 2354 2355
  //    if (pQInfo->summary.queryProfEvents) {
  //      taosArrayPush(pQInfo->summary.queryProfEvents, &event);
  //    }
2356 2357
}

L
Liu Jicong 已提交
2358
void publishQueryAbortEvent(SExecTaskInfo* pTaskInfo, int32_t code) {
2359 2360 2361 2362 2363
  SQueryProfEvent event;
  event.eventType = QUERY_PROF_QUERY_ABORT;
  event.eventTime = taosGetTimestampUs();
  event.abortCode = code;

2364 2365
  if (pTaskInfo->cost.queryProfEvents) {
    taosArrayPush(pTaskInfo->cost.queryProfEvents, &event);
2366 2367 2368
  }
}

L
Liu Jicong 已提交
2369
typedef struct {
2370 2371 2372 2373 2374 2375 2376
  uint8_t operatorType;
  int64_t beginTime;
  int64_t endTime;
  int64_t selfTime;
  int64_t descendantsTime;
} SOperatorStackItem;

L
Liu Jicong 已提交
2377 2378
static void doOperatorExecProfOnce(SOperatorStackItem* item, SQueryProfEvent* event, SArray* opStack,
                                   SHashObj* profResults) {
2379 2380 2381 2382 2383 2384 2385 2386
  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 已提交
2387
  uint8_t              operatorType = item->operatorType;
2388 2389 2390 2391 2392 2393 2394 2395 2396
  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 已提交
2397
    taosHashPut(profResults, &(operatorType), sizeof(operatorType), &opResult, sizeof(opResult));
2398 2399 2400
  }
}

2401
void calculateOperatorProfResults(void) {
dengyihao's avatar
dengyihao 已提交
2402 2403 2404 2405 2406 2407 2408 2409 2410
  //  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;
  //  }
2411 2412 2413 2414 2415

  SArray* opStack = taosArrayInit(32, sizeof(SOperatorStackItem));
  if (opStack == NULL) {
    return;
  }
2416
#if 0
L
Liu Jicong 已提交
2417
  size_t    size = taosArrayGetSize(pQInfo->summary.queryProfEvents);
2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438
  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);
      }
    }
  }
2439
#endif
2440 2441 2442
  taosArrayDestroy(opStack);
}

L
Liu Jicong 已提交
2443 2444
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
2445

L
Liu Jicong 已提交
2446 2447 2448
  //  uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
  //  hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
  //  pSummary->hashSize = hashSize;
2449 2450 2451 2452

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

L
Liu Jicong 已提交
2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463
  //  SResultRowPool* p = pTaskInfo->pool;
  //  if (p != NULL) {
  //    pSummary->winInfoSize = getResultRowPoolMemSize(p);
  //    pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
  //  } else {
  //    pSummary->winInfoSize = 0;
  //    pSummary->numOfTimeWindows = 0;
  //  }
  //
  //  calculateOperatorProfResults(pQInfo);

2464 2465
  SFileBlockLoadRecorder* pRecorder = pSummary->pRecoder;
  if (pSummary->pRecoder != NULL) {
X
Xiaoyu Wang 已提交
2466 2467
    qDebug("%s :cost summary: elapsed time:%" PRId64 " us, first merge:%" PRId64
           " us, total blocks:%d, "
2468 2469 2470 2471
           "load block statis:%d, load data block:%d, total rows:%" PRId64 ", check rows:%" PRId64,
           GET_TASKID(pTaskInfo), pSummary->elapsedTime, pSummary->firstStageMergeTime, pRecorder->totalBlocks,
           pRecorder->loadBlockStatis, pRecorder->loadBlocks, pRecorder->totalRows, pRecorder->totalCheckedRows);
  }
L
Liu Jicong 已提交
2472 2473 2474
  // 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);
2475 2476 2477 2478

  if (pSummary->operatorProfResults) {
    SOperatorProfResult* opRes = taosHashIterate(pSummary->operatorProfResults, NULL);
    while (opRes != NULL) {
L
Liu Jicong 已提交
2479 2480
      // qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
      //             pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
2481 2482 2483 2484 2485
      opRes = taosHashIterate(pSummary->operatorProfResults, opRes);
    }
  }
}

L
Liu Jicong 已提交
2486 2487 2488
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
2489
//
L
Liu Jicong 已提交
2490
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2491
//
L
Liu Jicong 已提交
2492 2493 2494 2495
//   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;
//   }
2496
//
L
Liu Jicong 已提交
2497 2498 2499 2500 2501
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
//   } else {
//     pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
//   }
2502
//
L
Liu Jicong 已提交
2503
//   assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
2504
//
L
Liu Jicong 已提交
2505 2506
//   SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//   SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2507
//
L
Liu Jicong 已提交
2508 2509
//   // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
//   TSKEY *keys = (TSKEY *) pColInfoData->pData;
2510
//
L
Liu Jicong 已提交
2511 2512 2513
//   // update the offset value
//   pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
//   pQueryAttr->limit.offset = 0;
2514
//
L
Liu Jicong 已提交
2515
//   int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
2516
//
L
Liu Jicong 已提交
2517 2518 2519 2520
//   //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);
// }
2521

L
Liu Jicong 已提交
2522 2523
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2524
//
L
Liu Jicong 已提交
2525 2526 2527
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
//     return;
//   }
2528
//
L
Liu Jicong 已提交
2529 2530
//   pQueryAttr->pos = 0;
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2531
//
L
Liu Jicong 已提交
2532 2533
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//   TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
2534
//
L
Liu Jicong 已提交
2535 2536 2537 2538 2539
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pTsdbReadHandle)) {
//     if (isTaskKilled(pRuntimeEnv->qinfo)) {
//       longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
//     }
2540
//
L
Liu Jicong 已提交
2541
//     tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
2542
//
L
Liu Jicong 已提交
2543 2544 2545 2546
//     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;
2547
//
L
Liu Jicong 已提交
2548 2549 2550 2551 2552 2553 2554
//       //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;
//     }
//   }
2555
//
L
Liu Jicong 已提交
2556 2557 2558 2559 2560 2561 2562 2563 2564
//   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;
2565
//
L
Liu Jicong 已提交
2566 2567 2568
//   assert(pQueryAttr->limit.offset == 0);
//   STimeWindow tw = *win;
//   getNextTimeWindow(pQueryAttr, &tw);
2569
//
L
Liu Jicong 已提交
2570 2571
//   if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
//       (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
2572
//
L
Liu Jicong 已提交
2573 2574 2575 2576
//     // 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);
2577
//
L
Liu Jicong 已提交
2578 2579 2580 2581
//     tw = *win;
//     int32_t startPos =
//         getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
//     assert(startPos >= 0);
2582
//
L
Liu Jicong 已提交
2583 2584
//     // set the abort info
//     pQueryAttr->pos = startPos;
2585
//
L
Liu Jicong 已提交
2586 2587 2588 2589
//     // reset the query start timestamp
//     pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
//     pQueryAttr->window.skey = pTableQueryInfo->win.skey;
//     TSKEY key = pTableQueryInfo->win.skey;
2590
//
L
Liu Jicong 已提交
2591 2592
//     pWindowResInfo->prevSKey = tw.skey;
//     int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
2593
//
L
Liu Jicong 已提交
2594 2595
//     int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//     pRuntimeEnv->resultRowInfo.curIndex = index;  // restore the window index
2596
//
L
Liu Jicong 已提交
2597 2598 2599 2600
//     //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);
2601
//
L
Liu Jicong 已提交
2602 2603 2604 2605 2606
//     return key;
//   } else {  // do nothing
//     pQueryAttr->window.skey      = tw.skey;
//     pWindowResInfo->prevSKey = tw.skey;
//     pTableQueryInfo->lastKey = tw.skey;
2607
//
L
Liu Jicong 已提交
2608 2609
//     return tw.skey;
//   }
2610
//
L
Liu Jicong 已提交
2611 2612 2613 2614 2615 2616 2617 2618 2619 2620
//   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);
//   }
2621
//
L
Liu Jicong 已提交
2622 2623 2624 2625 2626
//   // 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;
//   }
2627
//
L
Liu Jicong 已提交
2628 2629 2630 2631 2632 2633 2634
//   /*
//    * 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);
2635
//
L
Liu Jicong 已提交
2636 2637
//   STimeWindow w = TSWINDOW_INITIALIZER;
//   bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2638
//
L
Liu Jicong 已提交
2639 2640
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//   STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
2641
//
L
Liu Jicong 已提交
2642 2643 2644
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
//     tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
2645
//
L
Liu Jicong 已提交
2646 2647 2648 2649 2650 2651 2652 2653 2654
//     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;
//     }
2655
//
L
Liu Jicong 已提交
2656 2657
//     // the first time window
//     STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
2658
//
L
Liu Jicong 已提交
2659 2660
//     while (pQueryAttr->limit.offset > 0) {
//       STimeWindow tw = win;
2661
//
L
Liu Jicong 已提交
2662 2663 2664
//       if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
//         pQueryAttr->limit.offset -= 1;
//         pWindowResInfo->prevSKey = win.skey;
2665
//
L
Liu Jicong 已提交
2666 2667 2668 2669 2670 2671
//         // 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;
//         }
//       }
2672
//
L
Liu Jicong 已提交
2673 2674 2675 2676
//       if (pQueryAttr->limit.offset == 0) {
//         *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//         return true;
//       }
2677
//
L
Liu Jicong 已提交
2678 2679
//       // current window does not ended in current data block, try next data block
//       getNextTimeWindow(pQueryAttr, &tw);
2680
//
L
Liu Jicong 已提交
2681 2682 2683 2684 2685 2686 2687 2688 2689
//       /*
//        * 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)) {
2690
//
L
Liu Jicong 已提交
2691 2692
//         SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//         SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2693
//
L
Liu Jicong 已提交
2694 2695 2696
//         if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
//           pQueryAttr->limit.offset -= 1;
//         }
2697
//
L
Liu Jicong 已提交
2698 2699 2700 2701 2702 2703 2704 2705
//         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);
2706
//
L
Liu Jicong 已提交
2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717
//           // 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.
//       }
//     }
//   }
2718
//
L
Liu Jicong 已提交
2719 2720 2721 2722
//   // check for error
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
2723
//
L
Liu Jicong 已提交
2724 2725
//   return true;
// }
2726

2727
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
H
Haojun Liao 已提交
2728
  if (p->pDownstream == NULL) {
H
Haojun Liao 已提交
2729
    assert(p->numOfDownstream == 0);
2730 2731
  }

wafwerar's avatar
wafwerar 已提交
2732
  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
2733 2734 2735 2736 2737 2738 2739
  if (p->pDownstream == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
2740 2741 2742 2743
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);

2744
static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) {
H
Haojun Liao 已提交
2745 2746
#if 0
    if (order == TSDB_ORDER_ASC) {
2747 2748
    assert(
        (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
2749 2750
        (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey));
2751 2752 2753
  } else {
    assert(
        (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
2754 2755
        (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey));
2756
  }
H
Haojun Liao 已提交
2757
#endif
2758 2759
}

L
Liu Jicong 已提交
2760 2761 2762 2763
// 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;
2764
//
L
Liu Jicong 已提交
2765 2766 2767
//   if (pTableQueryInfo->pTable == NULL) {
//     return;
//   }
2768
//
L
Liu Jicong 已提交
2769 2770 2771 2772 2773 2774 2775 2776 2777
//   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));
//   }
// }
2778

2779
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
L
Liu Jicong 已提交
2780
  SSourceDataInfo* pSourceDataInfo = (SSourceDataInfo*)param;
H
Haojun Liao 已提交
2781 2782
  if (code == TSDB_CODE_SUCCESS) {
    pSourceDataInfo->pRsp = pMsg->pData;
2783

H
Haojun Liao 已提交
2784 2785
    SRetrieveTableRsp* pRsp = pSourceDataInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
dengyihao's avatar
dengyihao 已提交
2786
    pRsp->compLen = htonl(pRsp->compLen);
2787
    pRsp->numOfCols = htonl(pRsp->numOfCols);
dengyihao's avatar
dengyihao 已提交
2788
    pRsp->useconds = htobe64(pRsp->useconds);
H
Haojun Liao 已提交
2789 2790 2791
  } else {
    pSourceDataInfo->code = code;
  }
H
Haojun Liao 已提交
2792

H
Haojun Liao 已提交
2793
  pSourceDataInfo->status = EX_SOURCE_DATA_READY;
2794
  tsem_post(&pSourceDataInfo->pEx->ready);
wmmhello's avatar
wmmhello 已提交
2795
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
2796 2797 2798 2799
}

static void destroySendMsgInfo(SMsgSendInfo* pMsgBody) {
  assert(pMsgBody != NULL);
wafwerar's avatar
wafwerar 已提交
2800 2801
  taosMemoryFreeClear(pMsgBody->msgInfo.pData);
  taosMemoryFreeClear(pMsgBody);
H
Haojun Liao 已提交
2802 2803
}

S
Shengliang Guan 已提交
2804
void qProcessFetchRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
L
Liu Jicong 已提交
2805
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->ahandle;
H
Haojun Liao 已提交
2806 2807 2808 2809 2810
  assert(pMsg->ahandle != NULL);

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

  if (pMsg->contLen > 0) {
wafwerar's avatar
wafwerar 已提交
2811
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
H
Haojun Liao 已提交
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822
    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);
2823 2824
}

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

wafwerar's avatar
wafwerar 已提交
2828
  SResFetchReq* pMsg = taosMemoryCalloc(1, sizeof(SResFetchReq));
2829 2830 2831 2832
  if (NULL == pMsg) {
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
  }
2833

L
Liu Jicong 已提交
2834 2835
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
2836

L
Liu Jicong 已提交
2837 2838
  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);
2839 2840 2841 2842 2843 2844 2845

  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 已提交
2846
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
2847
  if (NULL == pMsgSendInfo) {
wafwerar's avatar
wafwerar 已提交
2848
    taosMemoryFreeClear(pMsg);
2849 2850 2851
    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 已提交
2852 2853
  }

2854 2855 2856 2857 2858
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
2859

2860
  int64_t transporterId = 0;
L
Liu Jicong 已提交
2861
  int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
2862 2863 2864
  return TSDB_CODE_SUCCESS;
}

2865
// NOTE: sources columns are more than the destination SSDatablock columns.
2866
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
2867 2868 2869
  size_t numOfSrcCols = taosArrayGetSize(pCols);

  int32_t i = 0, j = 0;
L
Liu Jicong 已提交
2870
  while (i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889
    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);
    }
  }
}

2890
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
dengyihao's avatar
dengyihao 已提交
2891 2892
                                  int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
                                  SArray* pColList) {
H
Haojun Liao 已提交
2893
  if (pColList == NULL) {  // data from other sources
H
Haojun Liao 已提交
2894 2895
    blockDataEnsureCapacity(pRes, numOfRows);

L
Liu Jicong 已提交
2896
    int32_t dataLen = *(int32_t*)pData;
2897 2898
    pData += sizeof(int32_t);

L
Liu Jicong 已提交
2899
    pRes->info.groupId = *(uint64_t*)pData;
2900 2901
    pData += sizeof(uint64_t);

H
Haojun Liao 已提交
2902 2903
    int32_t* colLen = (int32_t*)pData;

2904
    char* pStart = pData + sizeof(int32_t) * numOfOutput;
2905
    for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
2906
      colLen[i] = htonl(colLen[i]);
2907
      ASSERT(colLen[i] >= 0);
H
Haojun Liao 已提交
2908

2909
      SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
H
Haojun Liao 已提交
2910 2911 2912
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
        pColInfoData->varmeta.length = colLen[i];
        pColInfoData->varmeta.allocLen = colLen[i];
2913

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

2917 2918 2919
        if (colLen[i] > 0) {
          pColInfoData->pData = taosMemoryMalloc(colLen[i]);
        }
H
Haojun Liao 已提交
2920 2921 2922
      } else {
        memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
        pStart += BitmapLen(numOfRows);
2923
      }
H
Haojun Liao 已提交
2924

2925 2926 2927 2928
      if (colLen[i] > 0) {
        memcpy(pColInfoData->pData, pStart, colLen[i]);
      }

L
Liu Jicong 已提交
2929 2930
      // TODO setting this flag to true temporarily so aggregate function on stable will
      // examine NULL value for non-primary key column
2931
      pColInfoData->hasNull = true;
H
Haojun Liao 已提交
2932
      pStart += colLen[i];
2933
    }
H
Haojun Liao 已提交
2934
  } else {  // extract data according to pColList
2935
    ASSERT(numOfOutput == taosArrayGetSize(pColList));
2936 2937 2938 2939 2940
    char* pStart = pData;

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

2941
    // todo refactor:extract method
2942
    SSysTableSchema* pSchema = (SSysTableSchema*)pStart;
dengyihao's avatar
dengyihao 已提交
2943
    for (int32_t i = 0; i < numOfCols; ++i) {
2944 2945 2946 2947 2948 2949 2950
      SSysTableSchema* p = (SSysTableSchema*)pStart;

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

H
Haojun Liao 已提交
2951 2952 2953 2954
    SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
    pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
    pBlock->info.numOfCols = numOfCols;

dengyihao's avatar
dengyihao 已提交
2955
    for (int32_t i = 0; i < numOfCols; ++i) {
2956 2957 2958 2959 2960
      SColumnInfoData idata = {0};
      idata.info.type = pSchema[i].type;
      idata.info.bytes = pSchema[i].bytes;
      idata.info.colId = pSchema[i].colId;

H
Haojun Liao 已提交
2961
      taosArrayPush(pBlock->pDataBlock, &idata);
2962
      if (IS_VAR_DATA_TYPE(idata.info.type)) {
H
Haojun Liao 已提交
2963
        pBlock->info.hasVarCol = true;
2964 2965 2966
      }
    }

H
Haojun Liao 已提交
2967
    blockDataEnsureCapacity(pBlock, numOfRows);
2968

L
Liu Jicong 已提交
2969 2970
    int32_t  dataLen = *(int32_t*)pStart;
    uint64_t groupId = *(uint64_t*)(pStart + sizeof(int32_t));
2971 2972
    pStart += sizeof(int32_t) + sizeof(uint64_t);

L
Liu Jicong 已提交
2973
    int32_t* colLen = (int32_t*)(pStart);
2974 2975 2976 2977
    pStart += sizeof(int32_t) * numOfCols;

    for (int32_t i = 0; i < numOfCols; ++i) {
      colLen[i] = htonl(colLen[i]);
2978
      ASSERT(colLen[i] >= 0);
2979

H
Haojun Liao 已提交
2980
      SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996
      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 已提交
2997 2998

    // data from mnode
H
Haojun Liao 已提交
2999 3000 3001
    relocateColumnData(pRes, pColList, pBlock->pDataBlock);
    taosArrayDestroy(pBlock->pDataBlock);
    taosMemoryFree(pBlock);
X
Xiaoyu Wang 已提交
3002
    //    blockDataDestroy(pBlock);
3003
  }
3004

H
Haojun Liao 已提交
3005
  pRes->info.rows = numOfRows;
3006
  blockDataUpdateTsWindow(pRes);
3007

3008
  int64_t el = taosGetTimestampUs() - startTs;
3009

H
Haojun Liao 已提交
3010 3011
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
3012

H
Haojun Liao 已提交
3013 3014 3015
  if (total != NULL) {
    *total += numOfRows;
  }
3016

H
Haojun Liao 已提交
3017
  pLoadInfo->totalElapsed += el;
3018 3019
  return TSDB_CODE_SUCCESS;
}
3020

L
Liu Jicong 已提交
3021 3022
static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
3023
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3024

L
Liu Jicong 已提交
3025
  int64_t              el = taosGetTimestampUs() - startTs;
H
Haojun Liao 已提交
3026 3027
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
  pLoadInfo->totalElapsed += el;
H
Haojun Liao 已提交
3028

3029
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
L
Liu Jicong 已提交
3030 3031 3032
  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);
3033 3034 3035 3036 3037

  doSetOperatorCompleted(pOperator);
  return NULL;
}

L
Liu Jicong 已提交
3038 3039
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
                                                   SExecTaskInfo* pTaskInfo) {
3040 3041 3042 3043 3044 3045 3046 3047 3048
  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);

3049
      if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
3050
        completed += 1;
H
Haojun Liao 已提交
3051 3052
        continue;
      }
3053

3054
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
3055 3056 3057
        continue;
      }

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

L
Liu Jicong 已提交
3061
      SSDataBlock*         pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
3062
      SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
3063
      if (pRsp->numOfRows == 0) {
L
Liu Jicong 已提交
3064 3065
        qDebug("%s vgId:%d, taskID:0x%" PRIx64 " index:%d completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
               " try next",
3066
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, i + 1, pDataInfo->totalRows,
H
Haojun Liao 已提交
3067
               pExchangeInfo->loadInfo.totalRows);
3068
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3069 3070 3071
        completed += 1;
        continue;
      }
H
Haojun Liao 已提交
3072

H
Haojun Liao 已提交
3073
      SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
X
Xiaoyu Wang 已提交
3074 3075
      code = setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                       pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
3076
      if (code != 0) {
3077 3078 3079
        goto _error;
      }

3080 3081 3082
      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 已提交
3083 3084
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
               pLoadInfo->totalRows, pLoadInfo->totalSize, i + 1, totalSources);
3085
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3086
      } else {
dengyihao's avatar
dengyihao 已提交
3087 3088
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64
               ", totalBytes:%" PRIu64,
H
Haojun Liao 已提交
3089 3090
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
               pLoadInfo->totalSize);
3091 3092
      }

3093 3094
      if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED) {
        pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113
        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 已提交
3114 3115 3116
static SSDataBlock* concurrentlyLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3117

H
Haojun Liao 已提交
3118 3119 3120
  if (pOperator->status == OP_RES_TO_RETURN) {
    return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
  }
3121

L
Liu Jicong 已提交
3122
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3123 3124 3125
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
3126
  for (int32_t i = 0; i < totalSources; ++i) {
3127 3128
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
3129
      return NULL;
3130 3131 3132 3133
    }
  }

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

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
3138 3139
  pOperator->status = OP_RES_TO_RETURN;
  return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
3140 3141
}

L
Liu Jicong 已提交
3142 3143 3144
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3145

L
Liu Jicong 已提交
3146
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3147 3148 3149
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
3150
  for (int32_t i = 0; i < totalSources; ++i) {
3151 3152
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
3153 3154
      pTaskInfo->code = code;
      return code;
3155 3156 3157 3158
    }
  }

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

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

H
Haojun Liao 已提交
3165
  return TSDB_CODE_SUCCESS;
3166 3167
}

L
Liu Jicong 已提交
3168 3169 3170
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3171

L
Liu Jicong 已提交
3172
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3173
  int64_t startTs = taosGetTimestampUs();
3174

L
Liu Jicong 已提交
3175
  while (1) {
3176 3177
    if (pExchangeInfo->current >= totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
3178
    }
3179

3180 3181 3182
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

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

H
Haojun Liao 已提交
3186
    if (pDataInfo->code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
dengyihao 已提交
3187 3188
      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 已提交
3189 3190 3191 3192
      pOperator->pTaskInfo->code = pDataInfo->code;
      return NULL;
    }

L
Liu Jicong 已提交
3193
    SRetrieveTableRsp*   pRsp = pDataInfo->pRsp;
H
Haojun Liao 已提交
3194
    SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
3195
    if (pRsp->numOfRows == 0) {
dengyihao's avatar
dengyihao 已提交
3196 3197
      qDebug("%s vgId:%d, taskID:0x%" PRIx64 " %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
             " try next",
3198
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
H
Haojun Liao 已提交
3199
             pDataInfo->totalRows, pLoadInfo->totalRows);
H
Haojun Liao 已提交
3200

3201
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3202 3203 3204
      pExchangeInfo->current += 1;
      continue;
    }
H
Haojun Liao 已提交
3205

L
Liu Jicong 已提交
3206
    SSDataBlock*       pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
3207
    SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
3208 3209
    int32_t            code =
        setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
3210
                                  pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
3211 3212

    if (pRsp->completed == 1) {
H
Haojun Liao 已提交
3213
      qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, rowsOfSource:%" PRIu64
L
Liu Jicong 已提交
3214 3215 3216
             ", 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);
3217

3218
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3219 3220
      pExchangeInfo->current += 1;
    } else {
L
Liu Jicong 已提交
3221 3222 3223 3224
      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);
3225 3226 3227 3228
    }

    return pExchangeInfo->pResult;
  }
3229 3230
}

L
Liu Jicong 已提交
3231
static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
3232
  if (OPTR_IS_OPENED(pOperator)) {
H
Haojun Liao 已提交
3233 3234 3235
    return TSDB_CODE_SUCCESS;
  }

L
Liu Jicong 已提交
3236
  SExchangeInfo* pExchangeInfo = pOperator->info;
H
Haojun Liao 已提交
3237 3238 3239 3240 3241 3242 3243 3244 3245
  if (pExchangeInfo->seqLoadData) {
    // do nothing for sequentially load data
  } else {
    int32_t code = prepareConcurrentlyLoad(pOperator);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

3246
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
3247 3248 3249
  return TSDB_CODE_SUCCESS;
}

3250
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
3251 3252
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3253

3254
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
3255
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
3256 3257
    return NULL;
  }
3258

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

3262
  if (pOperator->status == OP_EXEC_DONE) {
L
Liu Jicong 已提交
3263 3264 3265
    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);
3266 3267 3268 3269 3270 3271
    return NULL;
  }

  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
3272
    return concurrentlyLoadRemoteData(pOperator);
3273
  }
H
Haojun Liao 已提交
3274

3275
#if 0
H
Haojun Liao 已提交
3276
  _error:
wafwerar's avatar
wafwerar 已提交
3277 3278
  taosMemoryFreeClear(pMsg);
  taosMemoryFreeClear(pMsgSendInfo);
H
Haojun Liao 已提交
3279 3280 3281

  terrno = pTaskInfo->code;
  return NULL;
3282
#endif
H
Haojun Liao 已提交
3283
}
3284

H
Haojun Liao 已提交
3285
static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
3286
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
H
Haojun Liao 已提交
3287 3288
  if (pInfo->pSourceDataInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
3289 3290
  }

L
Liu Jicong 已提交
3291
  for (int32_t i = 0; i < numOfSources; ++i) {
3292
    SSourceDataInfo dataInfo = {0};
H
Haojun Liao 已提交
3293
    dataInfo.status = EX_SOURCE_DATA_NOT_READY;
L
Liu Jicong 已提交
3294 3295
    dataInfo.pEx = pInfo;
    dataInfo.index = i;
3296

H
Haojun Liao 已提交
3297 3298 3299 3300 3301 3302 3303 3304 3305 3306
    void* ret = taosArrayPush(pInfo->pSourceDataInfo, &dataInfo);
    if (ret == NULL) {
      taosArrayDestroy(pInfo->pSourceDataInfo);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
}

3307
SOperatorInfo* createExchangeOperatorInfo(void *pTransporter, const SNodeList* pSources, SSDataBlock* pBlock,
3308
                                          SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
3309
  SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
wafwerar's avatar
wafwerar 已提交
3310
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
3311 3312

  if (pInfo == NULL || pOperator == NULL) {
wafwerar's avatar
wafwerar 已提交
3313 3314
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
3315 3316
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
H
Haojun Liao 已提交
3317 3318
  }

H
Haojun Liao 已提交
3319
  size_t numOfSources = LIST_LENGTH(pSources);
H
Haojun Liao 已提交
3320
  pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
H
Haojun Liao 已提交
3321 3322 3323
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
  if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
    goto _error;
H
Haojun Liao 已提交
3324 3325
  }

L
Liu Jicong 已提交
3326 3327
  for (int32_t i = 0; i < numOfSources; ++i) {
    SNodeListNode* pNode = nodesListGetNode((SNodeList*)pSources, i);
H
Haojun Liao 已提交
3328 3329
    taosArrayPush(pInfo->pSources, pNode);
  }
3330

H
Haojun Liao 已提交
3331 3332 3333
  int32_t code = initDataSource(numOfSources, pInfo);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
3334
  }
H
Haojun Liao 已提交
3335

dengyihao's avatar
dengyihao 已提交
3336
  pInfo->pResult = pBlock;
3337 3338 3339
  pInfo->seqLoadData = true;

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

dengyihao's avatar
dengyihao 已提交
3341
  pOperator->name = "ExchangeOperator";
X
Xiaoyu Wang 已提交
3342
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
3343
  pOperator->blocking = false;
dengyihao's avatar
dengyihao 已提交
3344 3345
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
3346
  pOperator->numOfExprs = pBlock->info.numOfCols;
dengyihao's avatar
dengyihao 已提交
3347
  pOperator->pTaskInfo = pTaskInfo;
3348

L
Liu Jicong 已提交
3349 3350
  pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
                                         destroyExchangeOperatorInfo, NULL, NULL, NULL);
3351
  pInfo->pTransporter = pTransporter;
3352

3353
  return pOperator;
H
Haojun Liao 已提交
3354

L
Liu Jicong 已提交
3355
_error:
H
Haojun Liao 已提交
3356
  if (pInfo != NULL) {
H
Haojun Liao 已提交
3357
    destroyExchangeOperatorInfo(pInfo, numOfSources);
H
Haojun Liao 已提交
3358 3359
  }

wafwerar's avatar
wafwerar 已提交
3360 3361
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
3362
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
3363
  return NULL;
3364 3365
}

dengyihao's avatar
dengyihao 已提交
3366 3367
static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                                const char* pKey);
3368

3369
static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
3370
  SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*)param;
H
Haojun Liao 已提交
3371
  taosArrayDestroy(pInfo->pSortInfo);
3372 3373 3374
  taosArrayDestroy(pInfo->groupInfo);

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
3375
    tsortDestroySortHandle(pInfo->pSortHandle);
3376 3377
  }

H
Haojun Liao 已提交
3378
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
3379
  cleanupAggSup(&pInfo->aggSup);
3380
}
H
Haojun Liao 已提交
3381

L
Liu Jicong 已提交
3382
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
3383 3384 3385 3386
  size_t size = taosArrayGetSize(groupInfo);
  if (size == 0) {
    return true;
  }
3387

3388 3389
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
3390

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

3394 3395 3396
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
3397

3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410
    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;
      }
3411 3412 3413
    }
  }

3414
  return 0;
3415 3416
}

L
Liu Jicong 已提交
3417 3418 3419
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
3420
    pCtx[j].startRow = rowIndex;
3421 3422
  }

3423 3424
  for (int32_t j = 0; j < numOfExpr; ++j) {
    int32_t functionId = pCtx[j].functionId;
L
Liu Jicong 已提交
3425 3426 3427 3428 3429 3430 3431 3432 3433
    //    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]);
    //    }
3434
  }
3435
}
3436

L
Liu Jicong 已提交
3437 3438
static void doFinalizeResultImpl(SqlFunctionCtx* pCtx, int32_t numOfExpr) {
  for (int32_t j = 0; j < numOfExpr; ++j) {
3439 3440 3441 3442
    int32_t functionId = pCtx[j].functionId;
    //    if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
    //      continue;
    //    }
3443

3444 3445 3446 3447
    //    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 已提交
3448
    //    pCtx[j].fpSet.finalize(&pCtx[j]);
3449 3450
  }
}
3451

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

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

3459 3460 3461
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
3462

3463 3464
  return true;
}
3465

3466 3467
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
3468

3469
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
L
Liu Jicong 已提交
3470
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
3471 3472
    pCtx[i].size = 1;
  }
3473

L
Liu Jicong 已提交
3474
  for (int32_t i = 0; i < pBlock->info.rows; ++i) {
3475 3476 3477 3478 3479 3480 3481 3482 3483
    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);
3484 3485
        int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
        //        setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
3486

3487
        // TODO check for available buffer;
H
Haojun Liao 已提交
3488

3489 3490 3491 3492 3493
        // next group info data
        pInfo->binfo.pRes->info.rows += numOfRows;
        for (int32_t j = 0; j < numOfExpr; ++j) {
          if (pCtx[j].functionId < 0) {
            continue;
3494
          }
3495

H
Haojun Liao 已提交
3496
          pCtx[j].fpSet.process(&pCtx[j]);
3497
        }
3498 3499 3500

        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
        pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
H
Haojun Liao 已提交
3501
      }
3502 3503 3504 3505
    }
  }
}

3506 3507
static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
3508
  SSortHandle*              pHandle = pInfo->pSortHandle;
3509

3510
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes, false);
3511
  blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
3512

L
Liu Jicong 已提交
3513
  while (1) {
3514
    blockDataCleanup(pDataBlock);
3515
    while (1) {
H
Haojun Liao 已提交
3516
      STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
3517 3518
      if (pTupleHandle == NULL) {
        break;
3519
      }
3520

3521 3522
      // build datablock for merge for one group
      appendOneRowToDataBlock(pDataBlock, pTupleHandle);
3523
      if (pDataBlock->info.rows >= pOperator->resultInfo.capacity) {
3524 3525
        break;
      }
3526
    }
3527

3528 3529 3530
    if (pDataBlock->info.rows == 0) {
      break;
    }
3531

3532
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
L
Liu Jicong 已提交
3533 3534
    //  updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
    //  pOperator->pRuntimeEnv, true);
3535
    doMergeImpl(pOperator, pOperator->numOfExprs, pDataBlock);
3536 3537
    // flush to tuple store, and after all data have been handled, return to upstream node or sink node
  }
3538

3539 3540 3541
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfExprs);
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
3542

3543
  // TODO check for available buffer;
3544

3545 3546
  // next group info data
  pInfo->binfo.pRes->info.rows += numOfRows;
L
Liu Jicong 已提交
3547
  return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
3548
}
3549

3550
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
3551 3552
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
3553 3554
  }

L
Liu Jicong 已提交
3555
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
3556
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
3557
  if (pOperator->status == OP_RES_TO_RETURN) {
3558
    return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity, NULL);
3559 3560
  }

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

3565
  tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL);
3566

L
Liu Jicong 已提交
3567
  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
wmmhello's avatar
wmmhello 已提交
3568
    SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
H
Haojun Liao 已提交
3569
    ps->param = pOperator->pDownstream[i];
H
Haojun Liao 已提交
3570
    tsortAddSource(pInfo->pSortHandle, ps);
3571 3572
  }

H
Haojun Liao 已提交
3573
  int32_t code = tsortOpen(pInfo->pSortHandle);
3574
  if (code != TSDB_CODE_SUCCESS) {
3575
    longjmp(pTaskInfo->env, terrno);
3576 3577
  }

H
Haojun Liao 已提交
3578
  pOperator->status = OP_RES_TO_RETURN;
3579
  return doMerge(pOperator);
3580
}
3581

L
Liu Jicong 已提交
3582 3583
static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo,
                            SSortedMergeOperatorInfo* pInfo) {
3584 3585
  if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) {
    return 0;
H
Haojun Liao 已提交
3586 3587
  }

3588 3589 3590 3591 3592 3593 3594 3595
  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 已提交
3596 3597
  size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo);
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
3598
    SColumn* pCol = taosArrayGet(pGroupInfo, i);
L
Liu Jicong 已提交
3599
    for (int32_t j = 0; j < numOfCols; ++j) {
H
Haojun Liao 已提交
3600
      SExprInfo* pe = &pExprInfo[j];
3601
      if (pe->base.resSchema.slotId == pCol->colId) {
3602 3603
        taosArrayPush(plist, pCol);
        taosArrayPush(pInfo->groupInfo, &j);
H
Haojun Liao 已提交
3604
        len += pCol->bytes;
3605 3606
        break;
      }
H
Haojun Liao 已提交
3607 3608 3609
    }
  }

3610
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
3611

wafwerar's avatar
wafwerar 已提交
3612
  pInfo->groupVal = taosMemoryCalloc(1, (POINTER_BYTES * numOfGroupCol + len));
3613 3614 3615 3616
  if (pInfo->groupVal == NULL) {
    taosArrayDestroy(plist);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
3617

3618
  int32_t offset = 0;
L
Liu Jicong 已提交
3619 3620
  char*   start = (char*)(pInfo->groupVal + (POINTER_BYTES * numOfGroupCol));
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
3621 3622
    pInfo->groupVal[i] = start + offset;
    SColumn* pCol = taosArrayGet(plist, i);
H
Haojun Liao 已提交
3623
    offset += pCol->bytes;
3624
  }
H
Haojun Liao 已提交
3625

3626
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
3627

3628 3629
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
3630

L
Liu Jicong 已提交
3631 3632 3633
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                             int32_t num, SArray* pSortInfo, SArray* pGroupInfo,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
3634
  SSortedMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortedMergeOperatorInfo));
L
Liu Jicong 已提交
3635
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
3636
  if (pInfo == NULL || pOperator == NULL) {
3637
    goto _error;
3638
  }
H
Haojun Liao 已提交
3639

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

3643 3644 3645
  if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
3646

dengyihao's avatar
dengyihao 已提交
3647
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
3648
  int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, keyBufSize, pTaskInfo->id.str);
3649 3650 3651
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
3652

H
Haojun Liao 已提交
3653
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, num, pTaskInfo);
H
Haojun Liao 已提交
3654
  code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo);
3655 3656 3657
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
3658

L
Liu Jicong 已提交
3659 3660 3661 3662 3663
  //  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 已提交
3664

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

L
Liu Jicong 已提交
3667
  pOperator->name = "SortedMerge";
X
Xiaoyu Wang 已提交
3668
  // pOperator->operatorType = OP_SortedMerge;
3669
  pOperator->blocking = true;
L
Liu Jicong 已提交
3670 3671
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
3672
  pOperator->numOfExprs = num;
L
Liu Jicong 已提交
3673
  pOperator->pExpr = pExprInfo;
H
Haojun Liao 已提交
3674

L
Liu Jicong 已提交
3675
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
3676

3677 3678
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSortedMerge, NULL, NULL, destroySortedMergeOperatorInfo,
                                         NULL, NULL, NULL);
3679 3680 3681
  code = appendDownstream(pOperator, downstream, numOfDownstream);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
3682
  }
H
Haojun Liao 已提交
3683

3684
  return pOperator;
H
Haojun Liao 已提交
3685

L
Liu Jicong 已提交
3686
_error:
3687
  if (pInfo != NULL) {
H
Haojun Liao 已提交
3688
    destroySortedMergeOperatorInfo(pInfo, num);
H
Haojun Liao 已提交
3689 3690
  }

wafwerar's avatar
wafwerar 已提交
3691 3692
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
3693 3694
  terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
  return NULL;
H
Haojun Liao 已提交
3695 3696
}

3697
int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scanFlag) {
3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708
  // todo add more information about exchange operation
  if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
    *order = TSDB_ORDER_ASC;
    *scanFlag = MAIN_SCAN;
    return TSDB_CODE_SUCCESS;
  } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
    STableScanInfo* pTableScanInfo = pOperator->info;
    *order = pTableScanInfo->cond.order;
    *scanFlag = pTableScanInfo->scanFlag;
    return TSDB_CODE_SUCCESS;
  } else {
H
Haojun Liao 已提交
3709
    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
3710
      return TSDB_CODE_INVALID_PARA;
H
Haojun Liao 已提交
3711
    } else {
3712
      return getTableScanInfo(pOperator->pDownstream[0], order, scanFlag);
3713 3714 3715
    }
  }
}
3716 3717

// this is a blocking operator
L
Liu Jicong 已提交
3718
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
3719 3720
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
3721 3722
  }

H
Haojun Liao 已提交
3723
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
3724
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
3725

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

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

3730 3731 3732
  int32_t order = TSDB_ORDER_ASC;
  int32_t scanFlag = MAIN_SCAN;

H
Haojun Liao 已提交
3733
  while (1) {
H
Haojun Liao 已提交
3734
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
3735
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
H
Haojun Liao 已提交
3736
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
3737 3738 3739 3740

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
3741
    //    if (pAggInfo->current != NULL) {
3742
    //      setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfExprs);
H
Haojun Liao 已提交
3743
    //    }
3744

3745 3746 3747 3748
    int32_t code = getTableScanInfo(pOperator, &order, &scanFlag);
    if (code != TSDB_CODE_SUCCESS) {
      longjmp(pTaskInfo->env, code);
    }
3749

3750 3751
    // there is an scalar expression that needs to be calculated before apply the group aggregation.
    if (pAggInfo->pScalarExprInfo != NULL) {
3752
      code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx,
X
Xiaoyu Wang 已提交
3753
                                           pAggInfo->numOfScalarExpr, NULL);
3754 3755 3756 3757
      if (code != TSDB_CODE_SUCCESS) {
        pTaskInfo->code = code;
        longjmp(pTaskInfo->env, pTaskInfo->code);
      }
3758 3759
    }

3760
    // the pDataBlock are always the same one, no need to call this again
3761
    setExecutionContext(pOperator->numOfExprs, pBlock->info.groupId, pTaskInfo, pAggInfo);
3762
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, true);
H
Haojun Liao 已提交
3763
    doAggregateImpl(pOperator, 0, pInfo->pCtx);
3764

dengyihao's avatar
dengyihao 已提交
3765
#if 0  // test for encode/decode result info
3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776
    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);
      }
3777
    }
3778
#endif
3779 3780
  }

H
Haojun Liao 已提交
3781
  closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
3782 3783
  finalizeMultiTupleQueryResult(pOperator->numOfExprs, pAggInfo->aggSup.pResultBuf, &pAggInfo->binfo.resultRowInfo,
                                pAggInfo->binfo.rowCellInfoOffset);
H
Haojun Liao 已提交
3784

3785
  initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, false);
H
Haojun Liao 已提交
3786 3787 3788 3789
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

3790
static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
3791
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
3792 3793 3794 3795 3796 3797
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;

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

L
Liu Jicong 已提交
3798
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3799
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
H
Haojun Liao 已提交
3800 3801 3802 3803
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
    return NULL;
  }

H
Haojun Liao 已提交
3804
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
3805
  doBuildResultDatablock(pTaskInfo, pInfo, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf);
H
Haojun Liao 已提交
3806 3807 3808
  if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
3809

H
Haojun Liao 已提交
3810
  doSetOperatorCompleted(pOperator);
L
Liu Jicong 已提交
3811
  return (blockDataGetNumOfRows(pInfo->pRes) != 0) ? pInfo->pRes : NULL;
3812 3813
}

dengyihao's avatar
dengyihao 已提交
3814 3815
void aggEncodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char** result,
                        int32_t* length) {
wmmhello's avatar
wmmhello 已提交
3816
  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
3817
  size_t  keyLen = sizeof(uint64_t) * 2;  // estimate the key length
wmmhello's avatar
wmmhello 已提交
3818
  int32_t totalSize = sizeof(int32_t) + size * (sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize);
wafwerar's avatar
wafwerar 已提交
3819
  *result = taosMemoryCalloc(1, totalSize);
L
Liu Jicong 已提交
3820
  if (*result == NULL) {
3821
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
wmmhello's avatar
wmmhello 已提交
3822 3823 3824
  }
  *(int32_t*)(*result) = size;
  int32_t offset = sizeof(int32_t);
3825 3826

  // prepare memory
3827
  SResultRowPosition* pos = &pInfo->resultRowInfo.cur;
dengyihao's avatar
dengyihao 已提交
3828 3829
  void*               pPage = getBufPage(pSup->pResultBuf, pos->pageId);
  SResultRow*         pRow = (SResultRow*)((char*)pPage + pos->offset);
3830 3831 3832
  setBufPageDirty(pPage, true);
  releaseBufPage(pSup->pResultBuf, pPage);

dengyihao's avatar
dengyihao 已提交
3833
  void* pIter = taosHashIterate(pSup->pResultRowHashTable, NULL);
wmmhello's avatar
wmmhello 已提交
3834
  while (pIter) {
dengyihao's avatar
dengyihao 已提交
3835
    void*               key = taosHashGetKey(pIter, &keyLen);
3836
    SResultRowPosition* p1 = (SResultRowPosition*)pIter;
3837

dengyihao's avatar
dengyihao 已提交
3838
    pPage = (SFilePage*)getBufPage(pSup->pResultBuf, p1->pageId);
3839
    pRow = (SResultRow*)((char*)pPage + p1->offset);
3840 3841
    setBufPageDirty(pPage, true);
    releaseBufPage(pSup->pResultBuf, pPage);
wmmhello's avatar
wmmhello 已提交
3842 3843 3844

    // recalculate the result size
    int32_t realTotalSize = offset + sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize;
L
Liu Jicong 已提交
3845 3846 3847
    if (realTotalSize > totalSize) {
      char* tmp = taosMemoryRealloc(*result, realTotalSize);
      if (tmp == NULL) {
wmmhello's avatar
wmmhello 已提交
3848
        terrno = TSDB_CODE_OUT_OF_MEMORY;
wafwerar's avatar
wafwerar 已提交
3849
        taosMemoryFree(*result);
wmmhello's avatar
wmmhello 已提交
3850
        *result = NULL;
3851
        longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
L
Liu Jicong 已提交
3852
      } else {
wmmhello's avatar
wmmhello 已提交
3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864
        *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);
3865
    memcpy(*result + offset, pRow, pSup->resultRowSize);
wmmhello's avatar
wmmhello 已提交
3866 3867 3868 3869 3870
    offset += pSup->resultRowSize;

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

L
Liu Jicong 已提交
3871
  if (length) {
wmmhello's avatar
wmmhello 已提交
3872 3873 3874 3875 3876
    *length = offset;
  }
  return;
}

dengyihao's avatar
dengyihao 已提交
3877 3878
bool aggDecodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char* result,
                        int32_t length) {
L
Liu Jicong 已提交
3879
  if (!result || length <= 0) {
wmmhello's avatar
wmmhello 已提交
3880 3881 3882 3883 3884 3885 3886
    return false;
  }

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

  int32_t offset = sizeof(int32_t);
L
Liu Jicong 已提交
3887
  while (count-- > 0 && length > offset) {
wmmhello's avatar
wmmhello 已提交
3888 3889 3890
    int32_t keyLen = *(int32_t*)(result + offset);
    offset += sizeof(int32_t);

L
Liu Jicong 已提交
3891 3892 3893
    uint64_t    tableGroupId = *(uint64_t*)(result + offset);
    SResultRow* resultRow = getNewResultRow_rv(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
    if (!resultRow) {
3894
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
3895
    }
3896

wmmhello's avatar
wmmhello 已提交
3897
    // add a new result set for a new group
3898 3899
    SResultRowPosition pos = {.pageId = resultRow->pageId, .offset = resultRow->offset};
    taosHashPut(pSup->pResultRowHashTable, result + offset, keyLen, &pos, sizeof(SResultRowPosition));
wmmhello's avatar
wmmhello 已提交
3900 3901 3902

    offset += keyLen;
    int32_t valueLen = *(int32_t*)(result + offset);
L
Liu Jicong 已提交
3903
    if (valueLen != pSup->resultRowSize) {
3904
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
3905 3906 3907 3908 3909 3910 3911 3912 3913 3914
    }
    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);
3915
    prepareResultListBuffer(&pInfo->resultRowInfo, pOperator->pTaskInfo->env);
dengyihao's avatar
dengyihao 已提交
3916
    //    pInfo->resultRowInfo.cur = pInfo->resultRowInfo.size;
L
Liu Jicong 已提交
3917 3918
    //    pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
    //        (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
dengyihao's avatar
dengyihao 已提交
3919
    pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
wmmhello's avatar
wmmhello 已提交
3920 3921
  }

L
Liu Jicong 已提交
3922
  if (offset != length) {
3923
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
3924 3925 3926 3927
  }
  return true;
}

3928 3929
enum {
  PROJECT_RETRIEVE_CONTINUE = 0x1,
L
Liu Jicong 已提交
3930
  PROJECT_RETRIEVE_DONE = 0x2,
3931 3932 3933 3934 3935
};

static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
L
Liu Jicong 已提交
3936
  SSDataBlock*          pRes = pInfo->pRes;
3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984

  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;
  }

3985 3986 3987
  // 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);
3988 3989 3990 3991 3992

    if (pProjectInfo->slimit.limit == -1 || pProjectInfo->slimit.limit <= pProjectInfo->curGroupOutput) {
      pOperator->status = OP_EXEC_DONE;
    }

3993
    return PROJECT_RETRIEVE_DONE;
3994
  }
3995

3996
  // todo optimize performance
3997 3998
  // If there are slimit/soffset value exists, multi-round result can not be packed into one group, since the
  // they may not belong to the same group the limit/offset value is not valid in this case.
L
Liu Jicong 已提交
3999 4000
  if (pRes->info.rows >= pOperator->resultInfo.threshold || pProjectInfo->slimit.offset != -1 ||
      pProjectInfo->slimit.limit != -1) {
4001
    return PROJECT_RETRIEVE_DONE;
L
Liu Jicong 已提交
4002
  } else {  // not full enough, continue to accumulate the output data in the buffer.
4003 4004 4005 4006
    return PROJECT_RETRIEVE_CONTINUE;
  }
}

4007
static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
4008
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
L
Liu Jicong 已提交
4009
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
4010 4011

  SSDataBlock* pRes = pInfo->pRes;
4012
  blockDataCleanup(pRes);
4013

4014
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4015 4016 4017
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
4018

H
Haojun Liao 已提交
4019
#if 0
4020 4021 4022 4023 4024 4025
  if (pProjectInfo->existDataBlock) {  // TODO refactor
    SSDataBlock* pBlock = pProjectInfo->existDataBlock;
    pProjectInfo->existDataBlock = NULL;
    *newgroup = true;

    // todo dynamic set tags
L
Liu Jicong 已提交
4026
    //    if (pTableQueryInfo != NULL) {
4027
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfExprs);
L
Liu Jicong 已提交
4028
    //    }
4029 4030

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

H
Haojun Liao 已提交
4033
    blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
4034
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs);
L
Liu Jicong 已提交
4035
    if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
4036 4037
      copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfExprs);
      resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfExprs);
4038 4039 4040
      return pRes;
    }
  }
H
Haojun Liao 已提交
4041
#endif
4042

4043 4044 4045
  int32_t order = 0;
  int32_t scanFlag = 0;

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

L
Liu Jicong 已提交
4048
  while (1) {
H
Haojun Liao 已提交
4049
    // The downstream exec may change the value of the newgroup, so use a local variable instead.
H
Haojun Liao 已提交
4050
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
4051
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
H
Haojun Liao 已提交
4052
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
4053 4054

    if (pBlock == NULL) {
4055
      setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
4056 4057 4058 4059
      break;
    }

    // Return result of the previous group in the firstly.
4060
    if (false) {
4061 4062 4063
      if (pRes->info.rows > 0) {
        pProjectInfo->existDataBlock = pBlock;
        break;
L
Liu Jicong 已提交
4064
      } else {  // init output buffer for a new group data
4065
        initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfExprs);
4066 4067 4068
      }
    }

4069 4070
    // todo set tags

H
Haojun Liao 已提交
4071 4072
    //    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
    //    if (pTableQueryInfo != NULL) {
4073
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfExprs);
H
Haojun Liao 已提交
4074
    //    }
4075 4076

    // the pDataBlock are always the same one, no need to call this again
4077
    int32_t code = getTableScanInfo(pOperator->pDownstream[0], &order, &scanFlag);
4078

4079
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, false);
4080 4081
    blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);

4082 4083 4084
    code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs, pProjectInfo->pPseudoColInfo);
    if (code != TSDB_CODE_SUCCESS) {
      longjmp(pTaskInfo->env, code);
4085 4086
    }

4087 4088
    int32_t status = handleLimitOffset(pOperator, pBlock);
    if (status == PROJECT_RETRIEVE_CONTINUE) {
H
Haojun Liao 已提交
4089
      continue;
L
Liu Jicong 已提交
4090
    } else if (status == PROJECT_RETRIEVE_DONE) {
4091 4092 4093
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
4094

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

4097
  //  copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfExprs);
L
Liu Jicong 已提交
4098
  return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
4099 4100
}

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

L
Liu Jicong 已提交
4105 4106
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
4107 4108
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

4109
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
4110 4111
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

4112
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity);
4113 4114 4115 4116
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
4117 4118
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
4119 4120
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
4121
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity);
H
Haojun Liao 已提交
4122
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
4123 4124 4125 4126 4127 4128
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
4129
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
4130 4131 4132
  }
}

4133
static SSDataBlock* doFill(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
4134 4135
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
4136

H
Haojun Liao 已提交
4137
  SResultInfo* pResultInfo = &pOperator->resultInfo;
4138 4139 4140
  SSDataBlock* pResBlock = pInfo->pRes;

  blockDataCleanup(pResBlock);
4141 4142 4143 4144
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

4145
  // todo handle different group data interpolation
X
Xiaoyu Wang 已提交
4146 4147
  bool  n = false;
  bool* newgroup = &n;
4148
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
4149 4150
  if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
    return pResBlock;
H
Haojun Liao 已提交
4151
  }
4152

H
Haojun Liao 已提交
4153
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
4154
  while (1) {
H
Haojun Liao 已提交
4155
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
4156
    SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream);
H
Haojun Liao 已提交
4157
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168

    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
4169
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
4170 4171 4172 4173 4174 4175 4176
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

4177
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
4178 4179 4180 4181 4182 4183 4184
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

4185 4186
    blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity);
4187 4188

    // current group has no more result to return
4189
    if (pResBlock->info.rows > 0) {
4190 4191
      // 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
4192 4193
      if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
        return pResBlock;
4194 4195
      }

4196
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
4197 4198
      if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
        return pResBlock;
4199 4200 4201
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
4202
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
4203 4204
      if (pResBlock->info.rows > pResultInfo->threshold) {
        return pResBlock;
4205 4206 4207 4208 4209 4210 4211 4212
      }
    } else {
      return NULL;
    }
  }
}

// todo set the attribute of query scan count
H
Haojun Liao 已提交
4213
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
L
Liu Jicong 已提交
4214
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228
    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;
  }

4229
  if (pOperator->fpSet.closeFn != NULL) {
4230
    pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfExprs);
4231 4232
  }

H
Haojun Liao 已提交
4233
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
4234
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
4235
      destroyOperatorInfo(pOperator->pDownstream[i]);
4236 4237
    }

wafwerar's avatar
wafwerar 已提交
4238
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
4239
    pOperator->numOfDownstream = 0;
4240 4241
  }

H
Haojun Liao 已提交
4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252
  if (pOperator->pExpr != NULL) {
    for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
      SExprInfo* pExprInfo = &pOperator->pExpr[i];
      if (pExprInfo->pExpr->nodeType == QUERY_NODE_COLUMN) {
        taosMemoryFree(pExprInfo->base.pParam[0].pCol);
      }
      taosMemoryFree(pExprInfo->base.pParam);
      taosMemoryFree(pExprInfo->pExpr);
    }
  }

D
fix bug  
dapan 已提交
4253
  taosMemoryFreeClear(pOperator->pExpr);
wafwerar's avatar
wafwerar 已提交
4254 4255
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
4256 4257
}

dengyihao's avatar
dengyihao 已提交
4258 4259
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                         const char* pKey) {
4260 4261
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

dengyihao's avatar
dengyihao 已提交
4262 4263
  pAggSup->resultRowSize = getResultRowSize(pCtx, numOfOutput);
  pAggSup->keyBuf = taosMemoryCalloc(1, keyBufSize + POINTER_BYTES + sizeof(int64_t));
4264 4265
  pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK);

H
Haojun Liao 已提交
4266
  if (pAggSup->keyBuf == NULL || pAggSup->pResultRowHashTable == NULL) {
4267 4268 4269
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
4270
  uint32_t defaultPgsz = 4096;
X
Xiaoyu Wang 已提交
4271
  while (defaultPgsz < pAggSup->resultRowSize * 4) {
H
Haojun Liao 已提交
4272 4273 4274 4275 4276 4277 4278 4279 4280 4281
    defaultPgsz <<= 1u;
  }

  // at least four pages need to be in buffer
  int32_t defaultBufsz = 4096 * 256;
  if (defaultBufsz <= defaultPgsz) {
    defaultBufsz = defaultPgsz * 4;
  }

  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, defaultPgsz, defaultBufsz, pKey, "/tmp/");
H
Haojun Liao 已提交
4282 4283 4284 4285
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

4286 4287 4288
  return TSDB_CODE_SUCCESS;
}

4289
void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
4290
  taosMemoryFreeClear(pAggSup->keyBuf);
4291
  taosHashCleanup(pAggSup->pResultRowHashTable);
H
Haojun Liao 已提交
4292
  destroyDiskbasedBuf(pAggSup->pResultBuf);
4293 4294
}

H
Haojun Liao 已提交
4295
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
4296
                    SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey) {
4297
  pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
4298 4299
  pBasicInfo->pRes = pResultBlock;

4300
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, keyBufSize, pkey);
4301

L
Liu Jicong 已提交
4302
  for (int32_t i = 0; i < numOfCols; ++i) {
4303 4304 4305
    pBasicInfo->pCtx[i].pBuf = pAggSup->pResultBuf;
  }

4306
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
4307 4308
}

4309 4310 4311 4312 4313 4314 4315 4316 4317
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 已提交
4318
static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) {
L
Liu Jicong 已提交
4319 4320 4321 4322
  if (pTableGroupInfo->numOfTables == 0) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
4323
  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
H
Haojun Liao 已提交
4324 4325
  if (pTableQueryInfo == NULL) {
    return NULL;
H
Haojun Liao 已提交
4326
  }
H
Haojun Liao 已提交
4327 4328

  int32_t index = 0;
L
Liu Jicong 已提交
4329
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
H
Haojun Liao 已提交
4330
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
L
Liu Jicong 已提交
4331
    for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
H
Haojun Liao 已提交
4332
      STableKeyInfo* pk = taosArrayGet(pa, j);
H
Haojun Liao 已提交
4333
      STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
L
Liu Jicong 已提交
4334
      pTQueryInfo->lastKey = pk->lastKey;
H
Haojun Liao 已提交
4335 4336
    }
  }
H
Haojun Liao 已提交
4337 4338

  STimeWindow win = {0, INT64_MAX};
4339
  createTableQueryInfo(pTableQueryInfo, win);
H
Haojun Liao 已提交
4340
  return pTableQueryInfo;
H
Haojun Liao 已提交
4341 4342
}

L
Liu Jicong 已提交
4343
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
4344
                                           SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
L
Liu Jicong 已提交
4345 4346
                                           int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo,
                                           const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
4347
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
4348
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4349 4350 4351
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
4352

4353
  int32_t numOfRows = 10;
dengyihao's avatar
dengyihao 已提交
4354
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
4355 4356

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
4357 4358
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResultBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
4359
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
L
Liu Jicong 已提交
4360
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4361 4362
    goto _error;
  }
H
Haojun Liao 已提交
4363

H
Haojun Liao 已提交
4364 4365 4366 4367
  int32_t numOfGroup = 10;  // todo replaced with true value
  pInfo->groupId = INT32_MIN;
  initResultRowInfo(&pInfo->binfo.resultRowInfo, numOfGroup);

4368 4369
  pInfo->pScalarExprInfo = pScalarExprInfo;
  pInfo->numOfScalarExpr = numOfScalarExpr;
4370 4371 4372
  if (pInfo->pScalarExprInfo != NULL) {
    pInfo->pScalarCtx = createSqlFunctionCtx(pScalarExprInfo, numOfCols, &pInfo->rowCellInfoOffset);
  }
4373

dengyihao's avatar
dengyihao 已提交
4374
  pOperator->name = "TableAggregate";
X
Xiaoyu Wang 已提交
4375
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
4376
  pOperator->blocking = true;
dengyihao's avatar
dengyihao 已提交
4377 4378 4379
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
4380
  pOperator->numOfExprs = numOfCols;
dengyihao's avatar
dengyihao 已提交
4381
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
4382

4383 4384
  pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
H
Haojun Liao 已提交
4385 4386 4387 4388 4389

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

  return pOperator;
L
Liu Jicong 已提交
4392
_error:
H
Haojun Liao 已提交
4393
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
4394 4395
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4396 4397
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
4398 4399
}

H
Haojun Liao 已提交
4400
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
4401 4402
  assert(pInfo != NULL);

4403
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
4404
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
4405 4406

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
4407
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
4408 4409
}

H
Haojun Liao 已提交
4410
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4411
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
4412 4413
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
4414

H
Haojun Liao 已提交
4415
void destroyMergeJoinOperator(void* param, int32_t numOfOutput) {
X
Xiaoyu Wang 已提交
4416
  SJoinOperatorInfo* pJoinOperator = (SJoinOperatorInfo*)param;
H
Haojun Liao 已提交
4417 4418
}

H
Haojun Liao 已提交
4419
void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4420
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
4421 4422
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
4423

H
Haojun Liao 已提交
4424
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4425
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
4426
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
4427
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
4428
  taosMemoryFreeClear(pInfo->p);
4429 4430
}

H
Haojun Liao 已提交
4431
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
D
fix bug  
dapan 已提交
4432 4433 4434
  if (NULL == param) {
    return;
  }
L
Liu Jicong 已提交
4435
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
4436
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
H
Haojun Liao 已提交
4437
  cleanupAggSup(&pInfo->aggSup);
H
Haojun Liao 已提交
4438
  taosArrayDestroy(pInfo->pPseudoColInfo);
4439 4440
}

H
Haojun Liao 已提交
4441
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4442
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
4443 4444 4445 4446 4447 4448 4449 4450 4451
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

H
Haojun Liao 已提交
4452 4453
static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols) {
  SArray* pList = taosArrayInit(4, sizeof(int32_t));
dengyihao's avatar
dengyihao 已提交
4454
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
4455 4456 4457 4458 4459 4460 4461 4462
    if (fmIsPseudoColumnFunc(pCtx[i].functionId)) {
      taosArrayPush(pList, &i);
    }
  }

  return pList;
}

L
Liu Jicong 已提交
4463
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
dengyihao's avatar
dengyihao 已提交
4464 4465
                                         SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit,
                                         SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4466
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
4467
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4468 4469 4470
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
4471

dengyihao's avatar
dengyihao 已提交
4472 4473 4474
  pInfo->limit = *pLimit;
  pInfo->slimit = *pSlimit;
  pInfo->curOffset = pLimit->offset;
H
Haojun Liao 已提交
4475 4476
  pInfo->curSOffset = pSlimit->offset;

H
Haojun Liao 已提交
4477
  pInfo->binfo.pRes = pResBlock;
H
Haojun Liao 已提交
4478 4479 4480

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
4481
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
4482 4483 4484

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

dengyihao's avatar
dengyihao 已提交
4488
  pOperator->name = "ProjectOperator";
H
Haojun Liao 已提交
4489
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
4490
  pOperator->blocking = false;
dengyihao's avatar
dengyihao 已提交
4491 4492 4493
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
4494
  pOperator->numOfExprs = num;
4495

L
Liu Jicong 已提交
4496 4497
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL,
                                         destroyProjectOperatorInfo, NULL, NULL, NULL);
L
Liu Jicong 已提交
4498 4499

  pOperator->pTaskInfo = pTaskInfo;
4500
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
4501
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4502 4503
    goto _error;
  }
4504 4505

  return pOperator;
H
Haojun Liao 已提交
4506

L
Liu Jicong 已提交
4507
_error:
H
Haojun Liao 已提交
4508 4509
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
4510 4511
}

4512
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, SNodeListNode* pValNode,
L
Liu Jicong 已提交
4513
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
4514
  SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pValNode);
H
Haojun Liao 已提交
4515 4516

  STimeWindow w = TSWINDOW_INITIALIZER;
4517
  getAlignQueryTimeWindow(pInterval, pInterval->precision, win.skey, &w);
H
Haojun Liao 已提交
4518 4519

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

wafwerar's avatar
wafwerar 已提交
4522
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
4523 4524 4525 4526 4527 4528 4529
  if (pInfo->pFillInfo == NULL || pInfo->p == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  } else {
    return TSDB_CODE_SUCCESS;
  }
}

L
Liu Jicong 已提交
4530
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
X
Xiaoyu Wang 已提交
4531 4532 4533
                                      SInterval* pInterval, STimeWindow* pWindow, SSDataBlock* pResBlock,
                                      int32_t fillType, SNodeListNode* pValueNode, bool multigroupResult,
                                      SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4534
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
4535
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4536

L
Liu Jicong 已提交
4537
  pInfo->pRes = pResBlock;
4538 4539
  pInfo->multigroupResult = multigroupResult;

4540 4541
  int32_t type = TSDB_FILL_NONE;
  switch (fillType) {
dengyihao's avatar
dengyihao 已提交
4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559
    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;
4560 4561 4562 4563
    default:
      type = TSDB_FILL_NONE;
  }

H
Haojun Liao 已提交
4564
  SResultInfo* pResultInfo = &pOperator->resultInfo;
4565 4566
  initResultSizeInfo(pOperator, 4096);

X
Xiaoyu Wang 已提交
4567 4568
  int32_t code = initFillInfo(pInfo, pExpr, numOfCols, pValueNode, *pWindow, pResultInfo->capacity, pTaskInfo->id.str,
                              pInterval, type);
4569 4570 4571
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4572

dengyihao's avatar
dengyihao 已提交
4573
  pOperator->name = "FillOperator";
4574
  pOperator->blocking = false;
dengyihao's avatar
dengyihao 已提交
4575
  pOperator->status = OP_NOT_OPENED;
4576
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL;
dengyihao's avatar
dengyihao 已提交
4577
  pOperator->pExpr = pExpr;
4578
  pOperator->numOfExprs = numOfCols;
dengyihao's avatar
dengyihao 已提交
4579
  pOperator->info = pInfo;
H
Haojun Liao 已提交
4580

L
Liu Jicong 已提交
4581 4582
  pOperator->fpSet =
      createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo, NULL, NULL, NULL);
4583
  pOperator->pTaskInfo = pTaskInfo;
4584
  code = appendDownstream(pOperator, &downstream, 1);
4585
  return pOperator;
H
Haojun Liao 已提交
4586

L
Liu Jicong 已提交
4587
_error:
wafwerar's avatar
wafwerar 已提交
4588 4589
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
4590
  return NULL;
4591 4592
}

L
Liu Jicong 已提交
4593 4594
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
4595
  SResSchema s = {0};
dengyihao's avatar
dengyihao 已提交
4596 4597 4598 4599
  s.scale = scale;
  s.type = type;
  s.bytes = bytes;
  s.slotId = slotId;
H
Haojun Liao 已提交
4600
  s.precision = precision;
H
Haojun Liao 已提交
4601 4602 4603 4604
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
4605

4606
static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDataType* pType) {
H
Haojun Liao 已提交
4607 4608 4609 4610 4611 4612
  SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn));
  if (pCol == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

dengyihao's avatar
dengyihao 已提交
4613
  pCol->slotId = slotId;
4614 4615 4616 4617
  pCol->colId  = colId;
  pCol->bytes  = pType->bytes;
  pCol->type   = pType->type;
  pCol->scale  = pType->scale;
dengyihao's avatar
dengyihao 已提交
4618
  pCol->precision = pType->precision;
H
Haojun Liao 已提交
4619 4620 4621 4622 4623
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
4624
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
4625
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
4626 4627 4628 4629
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
4630

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

L
Liu Jicong 已提交
4634
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
4635 4636 4637 4638 4639 4640
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
4641

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

wafwerar's avatar
wafwerar 已提交
4644
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
4645
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
4646
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
4647

4648
    int32_t type = nodeType(pTargetNode->pExpr);
H
Haojun Liao 已提交
4649
    // it is a project query, or group by column
4650
    if (type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
4651
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
4652
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
4653

G
Ganlin Zhao 已提交
4654 4655 4656
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
4657
      SDataType* pType = &pColNode->node.resType;
dengyihao's avatar
dengyihao 已提交
4658 4659
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pColNode->colName);
4660
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType);
H
Haojun Liao 已提交
4661
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
4662
    } else if (type == QUERY_NODE_VALUE) {
4663 4664 4665 4666 4667 4668 4669
      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 已提交
4670 4671
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pValNode->node.aliasName);
4672 4673
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
      valueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
4674
    } else if (type == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
4675
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
4676 4677 4678
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

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

H
Haojun Liao 已提交
4682
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
4683
      pExp->pExpr->_function.pFunctNode = pFuncNode;
4684

dengyihao's avatar
dengyihao 已提交
4685 4686
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699
#if 1
      // todo refactor: add the parameter for tbname function
      if (strcmp(pExp->pExpr->_function.functionName, "tbname") == 0) {
        pFuncNode->pParameterList = nodesMakeList();
        ASSERT(LIST_LENGTH(pFuncNode->pParameterList) == 0);
        SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
        if (NULL == res) { // todo handle error
        } else {
          res->node.resType = (SDataType) {.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
          nodesListAppend(pFuncNode->pParameterList, res);
        }
      }
#endif
H
Haojun Liao 已提交
4700 4701

      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
4702 4703 4704 4705

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

H
Haojun Liao 已提交
4706
      for (int32_t j = 0; j < numOfParam; ++j) {
4707
        SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
4708
        if (p1->type == QUERY_NODE_COLUMN) {
dengyihao's avatar
dengyihao 已提交
4709
          SColumnNode* pcn = (SColumnNode*)p1;
G
Ganlin Zhao 已提交
4710 4711

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
4712
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType);
G
Ganlin Zhao 已提交
4713 4714 4715
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
4716
          valueNodeToVariant(pvn, &pExp->base.pParam[j].param);
G
Ganlin Zhao 已提交
4717
        }
H
Haojun Liao 已提交
4718
      }
4719
    } else if (type == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
4720
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
4721
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
4722

G
Ganlin Zhao 已提交
4723 4724 4725
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

4726
      SDataType* pType = &pNode->node.resType;
dengyihao's avatar
dengyihao 已提交
4727 4728
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pNode->node.aliasName);
4729 4730 4731
      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
4732 4733 4734
    }
  }

H
Haojun Liao 已提交
4735
  return pExprs;
H
Haojun Liao 已提交
4736 4737
}

4738
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model) {
wafwerar's avatar
wafwerar 已提交
4739
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
4740
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
4741

4742
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
4743
  pTaskInfo->id.queryId = queryId;
dengyihao's avatar
dengyihao 已提交
4744
  pTaskInfo->execModel = model;
H
Haojun Liao 已提交
4745

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

4750 4751
  return pTaskInfo;
}
H
Haojun Liao 已提交
4752

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

L
Liu Jicong 已提交
4756 4757
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                                  uint64_t queryId, uint64_t taskId);
4758
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
H
Haojun Liao 已提交
4759
static SArray* extractColumnInfo(SNodeList* pNodeList);
4760

4761
static SArray* createSortInfo(SNodeList* pNodeList);
4762
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
4763
static void    setJoinColumnInfo(SColumnInfo* pColumn, const SColumnNode* pColumnNode);
4764

H
Haojun Liao 已提交
4765
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
4766
                                  uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
4767 4768
  int32_t type = nodeType(pPhyNode);

X
Xiaoyu Wang 已提交
4769
  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
H
Haojun Liao 已提交
4770
    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
dengyihao's avatar
dengyihao 已提交
4771
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
4772

H
Haojun Liao 已提交
4773
      tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
4774
      if (pDataReader == NULL && terrno != 0) {
4775 4776
        return NULL;
      }
4777

4778
      SOperatorInfo* pOperator = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
4779

4780 4781
      STableScanInfo* pScanInfo = pOperator->info;
      pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
4782

4783
      return pOperator;
H
Haojun Liao 已提交
4784
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
H
Haojun Liao 已提交
4785
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
4786
      SSDataBlock*        pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
4787
      return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
H
Haojun Liao 已提交
4788
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
H
Haojun Liao 已提交
4789
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
5
54liuyao 已提交
4790
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
4791

5
54liuyao 已提交
4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806
      int32_t     numOfCols = 0;

      tsdbReaderT pDataReader = NULL;
      if (pHandle->vnode) {
        pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
      } else {
        doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, 
            queryId, taskId);
      }
      if (pDataReader == NULL && terrno != 0) {
        qDebug("pDataReader is     NULL");
        // return NULL;
      } else {
        qDebug("pDataReader is not NULL");
      }
H
Haojun Liao 已提交
4807

4808
      SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;
5
54liuyao 已提交
4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826

      SArray* pColList = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
      SSDataBlock* pResBlockDumy = createResDataBlock(pDescNode);

      SQueryTableDataCond cond = {0};
      int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }

      SInterval      interval = extractIntervalInfo(pTableScanNode);
      SOperatorInfo* pOperatorDumy = createTableScanOperatorInfo(
          pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList,
          pResBlockDumy, pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo);

      // int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo,
      //                                   queryId, taskId);
      SArray* tableIdList = extractTableIdList(pTableGroupInfo);
X
Xiaoyu Wang 已提交
4827
      SSDataBlock*        pResBlock = createResDataBlock(pDescNode);
4828

X
Xiaoyu Wang 已提交
4829
      SArray*        pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
5
54liuyao 已提交
4830 4831
      SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pDataReader, pResBlock, pCols, tableIdList, pTaskInfo,
                                                              pScanPhyNode->node.pConditions, pOperatorDumy, &interval);
4832
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
4833
      return pOperator;
H
Haojun Liao 已提交
4834
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
L
Liu Jicong 已提交
4835
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
L
Liu Jicong 已提交
4836
      SScanPhysiNode*            pScanNode = &pSysScanPhyNode->scan;
H
Haojun Liao 已提交
4837

4838 4839 4840
      SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;

      SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4841

4842
      int32_t numOfOutputCols = 0;
4843
      SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &numOfOutputCols, COL_MATCH_FROM_COL_ID);
L
Liu Jicong 已提交
4844
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
L
Liu Jicong 已提交
4845 4846
          pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet, colList,
          pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
4847
      return pOperator;
4848
    } else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) {
X
Xiaoyu Wang 已提交
4849
      STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode;
4850 4851 4852 4853

      SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;

      SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4854

X
Xiaoyu Wang 已提交
4855 4856
      int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo,
                                        queryId, taskId);
4857 4858 4859 4860
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }

X
Xiaoyu Wang 已提交
4861
      int32_t    num = 0;
4862 4863 4864
      SExprInfo* pExprInfo = createExprInfo(pScanPhyNode->pScanPseudoCols, NULL, &num);

      int32_t numOfOutputCols = 0;
X
Xiaoyu Wang 已提交
4865 4866
      SArray* colList =
          extractColMatchInfo(pScanPhyNode->pScanPseudoCols, pDescNode, &numOfOutputCols, COL_MATCH_FROM_COL_ID);
4867

X
Xiaoyu Wang 已提交
4868 4869
      SOperatorInfo* pOperator =
          createTagScanOperatorInfo(pHandle, pExprInfo, num, pResBlock, colList, pTableGroupInfo, pTaskInfo);
4870
      return pOperator;
H
Haojun Liao 已提交
4871 4872
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
4873 4874 4875
    }
  }

4876 4877
  int32_t num = 0;
  size_t  size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
4878

4879
  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
dengyihao's avatar
dengyihao 已提交
4880
  for (int32_t i = 0; i < size; ++i) {
4881 4882
    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
4883 4884 4885
    if (ops[i] == NULL) {
      return NULL;
    }
4886
  }
H
Haojun Liao 已提交
4887

4888
  SOperatorInfo* pOptr = NULL;
H
Haojun Liao 已提交
4889
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
dengyihao's avatar
dengyihao 已提交
4890 4891
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*)pPhyNode;
    SExprInfo*         pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);
H
Haojun Liao 已提交
4892

4893
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
dengyihao's avatar
dengyihao 已提交
4894 4895
    SLimit       limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
    SLimit       slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
4896
    pOptr = createProjectOperatorInfo(ops[0], pExprInfo, num, pResBlock, &limit, &slimit, pTaskInfo);
H
Haojun Liao 已提交
4897 4898 4899
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == type) {
    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
    SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
4900
    SSDataBlock*   pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
4901

dengyihao's avatar
dengyihao 已提交
4902
    int32_t    numOfScalarExpr = 0;
4903 4904 4905 4906 4907
    SExprInfo* pScalarExprInfo = NULL;
    if (pAggNode->pExprs != NULL) {
      pScalarExprInfo = createExprInfo(pAggNode->pExprs, NULL, &numOfScalarExpr);
    }

H
Haojun Liao 已提交
4908 4909
    if (pAggNode->pGroupKeys != NULL) {
      SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
dengyihao's avatar
dengyihao 已提交
4910 4911
      pOptr = createGroupOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pAggNode->node.pConditions,
                                      pScalarExprInfo, numOfScalarExpr, pTaskInfo, NULL);
H
Haojun Liao 已提交
4912
    } else {
dengyihao's avatar
dengyihao 已提交
4913 4914
      pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr,
                                          pTaskInfo, pTableGroupInfo);
H
Haojun Liao 已提交
4915
    }
X
Xiaoyu Wang 已提交
4916
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type || QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
H
Haojun Liao 已提交
4917
    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
4918

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

dengyihao's avatar
dengyihao 已提交
4922 4923 4924 4925 4926 4927
    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 已提交
4928

dengyihao's avatar
dengyihao 已提交
4929 4930
    STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
                             .calTrigger = pIntervalPhyNode->window.triggerType};
4931

4932 4933 4934 4935
    int32_t tsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
    pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, &as, pTableGroupInfo,
                                       pTaskInfo);

H
Haojun Liao 已提交
4936
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
H
Haojun Liao 已提交
4937
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
4938

4939 4940 4941
    SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;

    SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4942
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys);
4943 4944

    int32_t    numOfCols = 0;
4945 4946 4947
    SExprInfo* pExprInfo = createExprInfo(pSortPhyNode->pExprs, NULL, &numOfCols);

    int32_t numOfOutputCols = 0;
4948
    SArray* pColList = extractColMatchInfo(pSortPhyNode->pTargets, pDescNode, &numOfOutputCols, COL_MATCH_FROM_SLOT_ID);
4949

4950
    pOptr = createSortOperatorInfo(ops[0], pResBlock, info, pExprInfo, numOfCols, pColList, pTaskInfo);
H
Haojun Liao 已提交
4951
  } else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
H
Haojun Liao 已提交
4952 4953
    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

X
Xiaoyu Wang 已提交
4954 4955
    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};
4956

H
Haojun Liao 已提交
4957
    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
4958
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4959 4960
    int32_t      tsSlotId = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;

X
Xiaoyu Wang 已提交
4961 4962
    pOptr =
        createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, tsSlotId, &as, pTaskInfo);
H
Haojun Liao 已提交
4963
  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
dengyihao's avatar
dengyihao 已提交
4964 4965 4966
    SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
    SArray*              pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
    SSDataBlock*         pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4967 4968

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

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

dengyihao's avatar
dengyihao 已提交
4975
    SExprInfo*   pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &num);
4976
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4977 4978 4979
    int32_t      tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId;

    pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, tsSlotId, pTaskInfo);
4980
  } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
dengyihao's avatar
dengyihao 已提交
4981 4982
    SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4983 4984

    SExprInfo* pExprInfo = createExprInfo(pJoinNode->pTargets, NULL, &num);
H
Haojun Liao 已提交
4985
    pOptr = createMergeJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
4986 4987
  } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) {
    SFillPhysiNode* pFillNode = (SFillPhysiNode*)pPhyNode;
X
Xiaoyu Wang 已提交
4988 4989
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
    SExprInfo*      pExprInfo = createExprInfo(pFillNode->pTargets, NULL, &num);
4990

4991
    SInterval* pInterval = &((SIntervalAggOperatorInfo*)ops[0]->info)->interval;
X
Xiaoyu Wang 已提交
4992 4993
    pOptr = createFillOperatorInfo(ops[0], pExprInfo, num, pInterval, &pFillNode->timeRange, pResBlock, pFillNode->mode,
                                   (SNodeListNode*)pFillNode->pValues, false, pTaskInfo);
H
Haojun Liao 已提交
4994 4995
  } else {
    ASSERT(0);
H
Haojun Liao 已提交
4996
  }
4997 4998 4999

  taosMemoryFree(ops);
  return pOptr;
5000
}
H
Haojun Liao 已提交
5001

5002
int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode) {
5003 5004 5005 5006 5007 5008
  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 已提交
5009
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
5010 5011 5012 5013 5014 5015
    return terrno;
  }

  pCond->twindow = pTableScanNode->scanRange;

#if 1
L
Liu Jicong 已提交
5016
  // todo work around a problem, remove it later
5017 5018
  if ((pCond->order == TSDB_ORDER_ASC && pCond->twindow.skey > pCond->twindow.ekey) ||
      (pCond->order == TSDB_ORDER_DESC && pCond->twindow.skey < pCond->twindow.ekey)) {
wafwerar's avatar
wafwerar 已提交
5019
    TSWAP(pCond->twindow.skey, pCond->twindow.ekey);
H
Haojun Liao 已提交
5020
  }
5021
#endif
H
Haojun Liao 已提交
5022

5023 5024
  pCond->type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
  //  pCond->type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
5025

H
Haojun Liao 已提交
5026
  int32_t j = 0;
5027
  for (int32_t i = 0; i < pCond->numOfCols; ++i) {
H
Haojun Liao 已提交
5028 5029
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
5030 5031 5032
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
5033

5034 5035 5036
    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 已提交
5037
    j += 1;
H
Haojun Liao 已提交
5038 5039
  }

5040 5041
  pCond->numOfCols = j;
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
5042
}
H
Haojun Liao 已提交
5043

H
Haojun Liao 已提交
5044
SArray* extractColumnInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
5045
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
5046 5047 5048 5049 5050 5051
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
5052 5053
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
H
Haojun Liao 已提交
5054

5055 5056 5057 5058 5059
    if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN) {
      SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;

      // todo extract method
      SColumn c = {0};
L
Liu Jicong 已提交
5060 5061 5062 5063 5064
      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;
5065 5066 5067 5068
      c.precision = pColNode->node.resType.precision;

      taosArrayPush(pList, &c);
    } else if (nodeType(pNode->pExpr) == QUERY_NODE_VALUE) {
L
Liu Jicong 已提交
5069 5070
      SValueNode* pValNode = (SValueNode*)pNode->pExpr;
      SColumn     c = {0};
5071
      c.slotId = pNode->slotId;
L
Liu Jicong 已提交
5072 5073 5074 5075
      c.colId = pNode->slotId;
      c.type = pValNode->node.type;
      c.bytes = pValNode->node.resType.bytes;
      c.scale = pValNode->node.resType.scale;
5076 5077 5078 5079
      c.precision = pValNode->node.resType.precision;

      taosArrayPush(pList, &c);
    }
H
Haojun Liao 已提交
5080 5081 5082 5083 5084
  }

  return pList;
}

5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098
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 已提交
5099 5100 5101
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
5102 5103 5104 5105 5106 5107 5108 5109 5110
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;

    taosArrayPush(pList, &c);
  }

  return pList;
}

5111
SArray* createSortInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
5112
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
5113 5114 5115 5116 5117 5118
  SArray* pList = taosArrayInit(numOfCols, sizeof(SBlockOrderInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

L
Liu Jicong 已提交
5119
  for (int32_t i = 0; i < numOfCols; ++i) {
5120
    SOrderByExprNode* pSortKey = (SOrderByExprNode*)nodesListGetNode(pNodeList, i);
L
Liu Jicong 已提交
5121 5122
    SBlockOrderInfo   bi = {0};
    bi.order = (pSortKey->order == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
H
Haojun Liao 已提交
5123 5124 5125
    bi.nullFirst = (pSortKey->nullOrder == NULL_ORDER_FIRST);

    SColumnNode* pColNode = (SColumnNode*)pSortKey->pExpr;
5126
    bi.slotId = pColNode->slotId;
H
Haojun Liao 已提交
5127 5128 5129 5130 5131 5132
    taosArrayPush(pList, &bi);
  }

  return pList;
}

X
Xiaoyu Wang 已提交
5133 5134
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols,
                            int32_t type) {
L
Liu Jicong 已提交
5135
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
5136 5137 5138 5139 5140 5141
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
5142 5143 5144
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
5145 5146

    SColMatchInfo c = {0};
X
Xiaoyu Wang 已提交
5147 5148 5149 5150
    c.output = true;
    c.colId = pColNode->colId;
    c.srcSlotId = pColNode->slotId;
    c.matchType = type;
H
Haojun Liao 已提交
5151 5152 5153 5154
    c.targetSlotId = pNode->slotId;
    taosArrayPush(pList, &c);
  }

H
Haojun Liao 已提交
5155 5156
  *numOfOutputCols = 0;
  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
5157 5158
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
5159

5160
    // todo: add reserve flag check
5161 5162
    // it is a column reserved for the arithmetic expression calculation
    if (pNode->slotId >= numOfCols) {
5163 5164 5165 5166
      (*numOfOutputCols) += 1;
      continue;
    }

H
Haojun Liao 已提交
5167
    SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
H
Haojun Liao 已提交
5168 5169 5170 5171 5172
    if (pNode->output) {
      (*numOfOutputCols) += 1;
    } else {
      info->output = false;
    }
H
Haojun Liao 已提交
5173 5174
  }

H
Haojun Liao 已提交
5175 5176 5177
  return pList;
}

dengyihao's avatar
dengyihao 已提交
5178 5179
int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                           uint64_t queryId, uint64_t taskId) {
5180
  int32_t code = 0;
H
Haojun Liao 已提交
5181
  if (tableType == TSDB_SUPER_TABLE) {
H
Haojun Liao 已提交
5182
    code = tsdbQuerySTableByTagCond(metaHandle, tableUid, 0, NULL, 0, 0, NULL, pGroupInfo, NULL, 0, queryId, taskId);
H
Haojun Liao 已提交
5183
  } else {  // Create one table group.
H
Haojun Liao 已提交
5184
    code = tsdbGetOneTableGroup(metaHandle, tableUid, 0, pGroupInfo);
5185 5186 5187 5188
  }

  return code;
}
H
Haojun Liao 已提交
5189

5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207
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 已提交
5208 5209
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                               STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId) {
5210
  uint64_t uid = pTableScanNode->scan.uid;
L
Liu Jicong 已提交
5211 5212
  int32_t  code =
      doCreateTableGroup(pHandle->meta, pTableScanNode->scan.tableType, uid, pTableGroupInfo, queryId, taskId);
5213 5214
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
H
Haojun Liao 已提交
5215
  }
H
Haojun Liao 已提交
5216

H
Haojun Liao 已提交
5217
  if (pTableGroupInfo->numOfTables == 0) {
H
Haojun Liao 已提交
5218
    code = 0;
L
Liu Jicong 已提交
5219
    qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
H
Haojun Liao 已提交
5220 5221
    goto _error;
  }
H
Haojun Liao 已提交
5222

5223 5224 5225 5226
  SQueryTableDataCond cond = {0};
  code = initQueryTableDataCond(&cond, pTableScanNode);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
X
Xiaoyu Wang 已提交
5227
  }
5228

5229
  return tsdbQueryTables(pHandle->vnode, &cond, pTableGroupInfo, queryId, taskId);
H
Haojun Liao 已提交
5230

L
Liu Jicong 已提交
5231
_error:
H
Haojun Liao 已提交
5232 5233 5234 5235
  terrno = code;
  return NULL;
}

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

H
Haojun Liao 已提交
5240
  int32_t code = TSDB_CODE_SUCCESS;
5241
  *pTaskInfo = createExecTaskInfo(queryId, taskId, model);
H
Haojun Liao 已提交
5242 5243 5244 5245
  if (*pTaskInfo == NULL) {
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    goto _complete;
  }
H
Haojun Liao 已提交
5246

L
Liu Jicong 已提交
5247 5248
  (*pTaskInfo)->pRoot =
      createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoGroupInfo);
D
dapan1121 已提交
5249
  if (NULL == (*pTaskInfo)->pRoot) {
L
Liu Jicong 已提交
5250
    code = terrno;
D
dapan1121 已提交
5251 5252
    goto _complete;
  }
H
Haojun Liao 已提交
5253

5254
  if ((*pTaskInfo)->pRoot == NULL) {
H
Haojun Liao 已提交
5255
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
H
Haojun Liao 已提交
5256
    goto _complete;
5257 5258
  }

H
Haojun Liao 已提交
5259 5260
  return code;

H
Haojun Liao 已提交
5261
_complete:
wafwerar's avatar
wafwerar 已提交
5262
  taosMemoryFreeClear(*pTaskInfo);
H
Haojun Liao 已提交
5263 5264 5265

  terrno = code;
  return code;
H
Haojun Liao 已提交
5266 5267
}

H
Haojun Liao 已提交
5268
void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo) {
5269 5270 5271 5272 5273 5274 5275 5276
  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 已提交
5277 5278 5279 5280 5281 5282 5283 5284 5285 5286
  //  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;
  //  }
5287 5288

  pResultInfo->threshold = (int32_t)(pResultInfo->capacity * THRESHOLD_RATIO);
H
Haojun Liao 已提交
5289
  pResultInfo->totalRows = 0;
5290 5291
}

L
Liu Jicong 已提交
5292
// TODO refactor
5293
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
L
Liu Jicong 已提交
5294 5295 5296
  if (pFilter == NULL || numOfFilters == 0) {
    return;
  }
5297

L
Liu Jicong 已提交
5298 5299 5300
  for (int32_t i = 0; i < numOfFilters; i++) {
    if (pFilter[i].filterstr && pFilter[i].pz) {
      taosMemoryFree((void*)(pFilter[i].pz));
5301
    }
L
Liu Jicong 已提交
5302
  }
5303

L
Liu Jicong 已提交
5304
  taosMemoryFree(pFilter);
5305 5306 5307 5308
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
  if (pTableqinfoGroupInfo->pGroupList != NULL) {
L
Liu Jicong 已提交
5309
    int32_t numOfGroups = (int32_t)taosArrayGetSize(pTableqinfoGroupInfo->pGroupList);
5310
    for (int32_t i = 0; i < numOfGroups; ++i) {
L
Liu Jicong 已提交
5311
      SArray* p = taosArrayGetP(pTableqinfoGroupInfo->pGroupList, i);
5312 5313

      size_t num = taosArrayGetSize(p);
L
Liu Jicong 已提交
5314
      for (int32_t j = 0; j < num; ++j) {
5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330
        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 已提交
5331
void doDestroyTask(SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
5332 5333
  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));

H
Haojun Liao 已提交
5334
  doDestroyTableQueryInfo(&pTaskInfo->tableqinfoGroupInfo);
H
Haojun Liao 已提交
5335
  destroyOperatorInfo(pTaskInfo->pRoot);
L
Liu Jicong 已提交
5336 5337
  //  taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
  //  taosHashCleanup(pTaskInfo->summary.operatorProfResults);
5338

wafwerar's avatar
wafwerar 已提交
5339 5340 5341
  taosMemoryFreeClear(pTaskInfo->sql);
  taosMemoryFreeClear(pTaskInfo->id.str);
  taosMemoryFreeClear(pTaskInfo);
5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353
}

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 已提交
5354
      int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366
      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 已提交
5367 5368
  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
  return (int64_t)(s1 * 1.5 * numOfTables);
5369 5370 5371 5372 5373 5374 5375
}

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 已提交
5376
    while (1) {
5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402
      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 已提交
5403

dengyihao's avatar
dengyihao 已提交
5404 5405
int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo** pRes, int32_t* capacity,
                                   int32_t* resNum) {
D
dapan1121 已提交
5406 5407
  if (*resNum >= *capacity) {
    *capacity += 10;
dengyihao's avatar
dengyihao 已提交
5408

D
dapan1121 已提交
5409 5410
    *pRes = taosMemoryRealloc(*pRes, (*capacity) * sizeof(SExplainExecInfo));
    if (NULL == *pRes) {
D
dapan1121 已提交
5411
      qError("malloc %d failed", (*capacity) * (int32_t)sizeof(SExplainExecInfo));
D
dapan1121 已提交
5412 5413 5414 5415
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

D
dapan1121 已提交
5416 5417 5418 5419
  (*pRes)[*resNum].numOfRows = operatorInfo->resultInfo.totalRows;
  (*pRes)[*resNum].startupCost = operatorInfo->cost.openCost;
  (*pRes)[*resNum].totalCost = operatorInfo->cost.totalCost;

5420 5421
  if (operatorInfo->fpSet.getExplainFn) {
    int32_t code = (*operatorInfo->fpSet.getExplainFn)(operatorInfo, &(*pRes)->verboseInfo);
D
dapan1121 已提交
5422 5423 5424 5425 5426
    if (code) {
      qError("operator getExplainFn failed, error:%s", tstrerror(code));
      return code;
    }
  }
dengyihao's avatar
dengyihao 已提交
5427

D
dapan1121 已提交
5428
  ++(*resNum);
dengyihao's avatar
dengyihao 已提交
5429

D
dapan1121 已提交
5430
  int32_t code = 0;
D
dapan1121 已提交
5431 5432
  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pRes, capacity, resNum);
D
dapan1121 已提交
5433 5434 5435 5436 5437 5438 5439
    if (code) {
      taosMemoryFreeClear(*pRes);
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
5440 5441
}

5442
static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator) {
5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454
  SJoinOperatorInfo* pJoinInfo = pOperator->info;

  SSDataBlock* pRes = pJoinInfo->pRes;
  blockDataCleanup(pRes);
  blockDataEnsureCapacity(pRes, 4096);

  int32_t nrows = 0;

  while (1) {
    if (pJoinInfo->pLeft == NULL || pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
      SOperatorInfo* ds1 = pOperator->pDownstream[0];
      publishOperatorProfEvent(ds1, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5455
      pJoinInfo->pLeft = ds1->fpSet.getNextFn(ds1);
5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467
      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);
5468
      pJoinInfo->pRight = ds2->fpSet.getNextFn(ds2);
5469 5470 5471 5472 5473 5474 5475 5476 5477 5478
      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 已提交
5479
    char*            pLeftVal = colDataGetData(pLeftCol, pJoinInfo->leftPos);
5480 5481

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

    // only the timestamp match support for ordinary table
dengyihao's avatar
dengyihao 已提交
5485 5486
    ASSERT(pLeftCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
    if (*(int64_t*)pLeftVal == *(int64_t*)pRightVal) {
5487
      for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
dengyihao's avatar
dengyihao 已提交
5488
        SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, i);
5489

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

dengyihao's avatar
dengyihao 已提交
5492 5493
        int32_t blockId = pExprInfo->base.pParam[0].pCol->dataBlockId;
        int32_t slotId = pExprInfo->base.pParam[0].pCol->slotId;
5494

dengyihao's avatar
dengyihao 已提交
5495 5496 5497 5498 5499 5500
        SColumnInfoData* pSrc = NULL;
        if (pJoinInfo->pLeft->info.blockId == blockId) {
          pSrc = taosArrayGet(pJoinInfo->pLeft->pDataBlock, slotId);
        } else {
          pSrc = taosArrayGet(pJoinInfo->pRight->pDataBlock, slotId);
        }
5501

dengyihao's avatar
dengyihao 已提交
5502 5503 5504 5505 5506
        if (colDataIsNull_s(pSrc, pJoinInfo->leftPos)) {
          colDataAppendNULL(pDst, nrows);
        } else {
          char* p = colDataGetData(pSrc, pJoinInfo->leftPos);
          colDataAppend(pDst, nrows, p, false);
5507
        }
dengyihao's avatar
dengyihao 已提交
5508
      }
5509

dengyihao's avatar
dengyihao 已提交
5510 5511
      pJoinInfo->leftPos += 1;
      pJoinInfo->rightPos += 1;
5512

dengyihao's avatar
dengyihao 已提交
5513 5514 5515
      nrows += 1;
    } else if (*(int64_t*)pLeftVal < *(int64_t*)pRightVal) {
      pJoinInfo->leftPos += 1;
D
dapan1121 已提交
5516

dengyihao's avatar
dengyihao 已提交
5517 5518
      if (pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
        continue;
5519
      }
dengyihao's avatar
dengyihao 已提交
5520 5521 5522 5523
    } else if (*(int64_t*)pLeftVal > *(int64_t*)pRightVal) {
      pJoinInfo->rightPos += 1;
      if (pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
        continue;
5524
      }
dengyihao's avatar
dengyihao 已提交
5525
    }
5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536

    // 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;
}

H
Haojun Liao 已提交
5537
SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
X
Xiaoyu Wang 已提交
5538 5539
                                           int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
                                           SExecTaskInfo* pTaskInfo) {
5540
  SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
dengyihao's avatar
dengyihao 已提交
5541
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
5542 5543 5544 5545
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }

5546
  initResultSizeInfo(pOperator, 4096);
5547

X
Xiaoyu Wang 已提交
5548 5549
  pInfo->pRes = pResBlock;
  pOperator->name = "MergeJoinOperator";
5550
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_JOIN;
X
Xiaoyu Wang 已提交
5551 5552 5553
  pOperator->blocking = false;
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
5554
  pOperator->numOfExprs = numOfCols;
X
Xiaoyu Wang 已提交
5555
  pOperator->info = pInfo;
dengyihao's avatar
dengyihao 已提交
5556
  pOperator->pTaskInfo = pTaskInfo;
5557

5558 5559 5560 5561
  SOperatorNode* pNode = (SOperatorNode*)pOnCondition;
  setJoinColumnInfo(&pInfo->leftCol, (SColumnNode*)pNode->pLeft);
  setJoinColumnInfo(&pInfo->rightCol, (SColumnNode*)pNode->pRight);

L
Liu Jicong 已提交
5562
  pOperator->fpSet =
H
Haojun Liao 已提交
5563
      createOperatorFpSet(operatorDummyOpenFn, doMergeJoin, NULL, NULL, destroyMergeJoinOperator, NULL, NULL, NULL);
5564
  int32_t code = appendDownstream(pOperator, pDownstream, numOfDownstream);
5565 5566 5567 5568
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

5569 5570
  return pOperator;

dengyihao's avatar
dengyihao 已提交
5571
_error:
5572 5573 5574 5575
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
dengyihao's avatar
dengyihao 已提交
5576
}
5577 5578

void setJoinColumnInfo(SColumnInfo* pColumn, const SColumnNode* pColumnNode) {
X
Xiaoyu Wang 已提交
5579 5580 5581
  pColumn->slotId = pColumnNode->slotId;
  pColumn->type = pColumnNode->node.resType.type;
  pColumn->bytes = pColumnNode->node.resType.bytes;
5582
  pColumn->precision = pColumnNode->node.resType.precision;
X
Xiaoyu Wang 已提交
5583
  pColumn->scale = pColumnNode->node.resType.scale;
5584
}