executorimpl.c 200.8 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].scanFlag  = 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 int32_t 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
      pCtx[k].startTs = startTs;
      // todo add a dummy funtion to avoid process check
      if (pCtx[k].fpSet.process != NULL) {
835 836
        int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
        if (code != TSDB_CODE_SUCCESS) {
837 838
          qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
          return code;
839
        }
840
      }
841 842
    }
  }
843 844

  return TSDB_CODE_SUCCESS;
845 846
}

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

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

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

863 864
  int32_t numOfRows = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
955 956
}

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

961 962 963 964 965 966 967 968 969
    //    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);
970

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

976 977 978 979 980
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;
981

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

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

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

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

1000 1001
  if (pCtx->scanFlag == REPEAT_SCAN) {
    return fmIsRepeatScanFunc(pCtx->functionId);
1002 1003
  }

1004 1005
  if (isRowEntryCompleted(pResInfo)) {
    return false;
1006 1007
  }

1008 1009 1010 1011 1012 1013 1014 1015
//  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;
//  }
1016

1017 1018 1019 1020 1021
  // 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;
  //  }
1022 1023 1024 1025

  return true;
}

1026 1027 1028 1029 1030 1031 1032
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;
    }
1033

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

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

1050
  ASSERT(!IS_VAR_DATA_TYPE(type));
1051

1052 1053 1054 1055 1056 1057
  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};
1058

1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
    *(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
1071
  } else {
1072
    ASSERT(0);
1073 1074
  }

1075 1076
  return TSDB_CODE_SUCCESS;
}
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087

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;

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

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

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

1173
    pCtx->functionId = -1;
1174
    pCtx->curBufPage = -1;
L
Liu Jicong 已提交
1175
    pCtx->pExpr = pExpr;
1176

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

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

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

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

1216
    pCtx->param = pFunct->pParam;
dengyihao's avatar
dengyihao 已提交
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 1248 1249 1250
    //    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 已提交
1251 1252
  }

L
Liu Jicong 已提交
1253 1254 1255
  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 已提交
1256
  }
H
Haojun Liao 已提交
1257

1258
  setSelectValueColumnInfo(pFuncCtx, numOfOutput);
H
Haojun Liao 已提交
1259 1260 1261
  return pFuncCtx;
}

1262
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1263 1264 1265 1266 1267 1268
  if (pCtx == NULL) {
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    for (int32_t j = 0; j < pCtx[i].numOfParams; ++j) {
1269
      taosVariantDestroy(&pCtx[i].param[j].param);
1270 1271 1272
    }

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

wafwerar's avatar
wafwerar 已提交
1278
  taosMemoryFreeClear(pCtx);
1279 1280 1281
  return NULL;
}

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

  return false;
}

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

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

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

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

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

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

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

  return status;
}

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

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

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

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

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

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

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

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

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

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

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

L
Liu Jicong 已提交
1538 1539
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
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 1601 1602 1603
      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 已提交
1604
static void         doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes);
1605 1606

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

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

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

  return status;
}

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

H
Haojun Liao 已提交
1634
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
1635
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
1636

L
Liu Jicong 已提交
1637 1638
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
1639

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return NULL;
}

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

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

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

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

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

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

      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);
  }
1864
#endif
1865 1866
}

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

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

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

L
Liu Jicong 已提交
1897
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
1898 1899 1900 1901
  if (pTableQueryInfo == NULL) {
    return;
  }

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

L
Liu Jicong 已提交
1905 1906
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
1907 1908

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

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

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

H
Haojun Liao 已提交
1936
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
1937
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
1938

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

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

L
Liu Jicong 已提交
1949
    pCtx[i].resultInfo = pEntry;
1950
    pCtx[i].scanFlag = stage;
H
Haojun Liao 已提交
1951 1952

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

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

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

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

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

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

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

H
Haojun Liao 已提交
2035
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
2036 2037 2038
  }
}

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

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

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

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

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

      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
2072
    }
2073 2074 2075

    releaseBufPage(pBuf, bufPage);
  }
2076 2077
}

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

L
Liu Jicong 已提交
2084
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
2085 2086 2087 2088
  if (pTableQueryInfo == NULL) {
    return;
  }

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

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

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

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

2116 2117 2118 2119 2120 2121
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
  if (pFilterNode == NULL) {
    return;
  }

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

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

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

2133
  SSDataBlock* px = createOneDataBlock(pBlock, false);
2134 2135
  blockDataEnsureCapacity(px, pBlock->info.rows);

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

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

    *pSrc = *pDst;
  }

  pBlock->info.rows = numOfRow;
2166
  blockDataUpdateTsWindow(pBlock);
2167 2168
}

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

2174 2175
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
2176
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
2177

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

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

2194
  setResultRowInitCtx(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
2195 2196
}

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

H
Haojun Liao 已提交
2202
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, groupId, pTaskInfo);
2203 2204

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

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

  int32_t start = 0;
2222
  int32_t step = 1;
2223

L
Liu Jicong 已提交
2224
  // qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
2225 2226 2227 2228 2229 2230 2231 2232 2233
  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 已提交
2234 2235
    SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
    SFilePage*  page = getBufPage(pBuf, pPos->pos.pageId);
2236

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

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

    pGroupResInfo->index += 1;

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

2254
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
2255 2256 2257
      if (pCtx[j].fpSet.finalize) {
        int32_t code = TSDB_CODE_SUCCESS;
        code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
2258
        if (TAOS_FAILED(code)) {
2259 2260 2261 2262
          qError("%s build result data block error, code %s", GET_TASKID(taskInfo), tstrerror(code));
          taskInfo->code = code;
          longjmp(taskInfo->env, code);
        }
2263 2264
      } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
        // do nothing, todo refactor
2265
      } else {
2266 2267 2268 2269 2270 2271 2272
        // 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);
          }
2273
      }
2274 2275
    }

2276 2277
    releaseBufPage(pBuf, page);

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

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

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

X
Xiaoyu Wang 已提交
2293 2294 2295
  int32_t*        rowCellOffset = pbInfo->rowCellInfoOffset;
  SSDataBlock*    pBlock = pbInfo->pRes;
  SqlFunctionCtx* pCtx = pbInfo->pCtx;
2296

2297
  blockDataCleanup(pBlock);
2298 2299 2300 2301
  if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
    return;
  }

2302
  int32_t orderType = TSDB_ORDER_ASC;
2303
  doCopyToSDataBlock(taskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
2304

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

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

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

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

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

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

2344 2345
  int32_t numOfRows = (int32_t)taosFillResultDataBlock(pFillInfo, pBlock, capacity - pBlock->info.rows);
  pBlock->info.rows += numOfRows;
2346

2347
  return pBlock->info.rows;
2348 2349
}

2350
void publishOperatorProfEvent(SOperatorInfo* pOperator, EQueryProfEventType eventType) {
2351 2352
  SQueryProfEvent event = {0};

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

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

2367 2368
  if (pTaskInfo->cost.queryProfEvents) {
    taosArrayPush(pTaskInfo->cost.queryProfEvents, &event);
2369 2370 2371
  }
}

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

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

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

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

L
Liu Jicong 已提交
2446 2447
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
2448

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

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

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

2467 2468
  SFileBlockLoadRecorder* pRecorder = pSummary->pRecoder;
  if (pSummary->pRecoder != NULL) {
X
Xiaoyu Wang 已提交
2469 2470
    qDebug("%s :cost summary: elapsed time:%" PRId64 " us, first merge:%" PRId64
           " us, total blocks:%d, "
2471 2472 2473 2474
           "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 已提交
2475 2476 2477
  // 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);
2478 2479 2480 2481

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

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

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

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

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

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
2743 2744 2745 2746
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);

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

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

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

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

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

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

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

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

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

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

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

L
Liu Jicong 已提交
2837 2838
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
2839

L
Liu Jicong 已提交
2840 2841
  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);
2842 2843 2844 2845 2846 2847 2848

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

2857 2858 2859 2860 2861
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
2862

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

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

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

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

L
Liu Jicong 已提交
2899
    int32_t dataLen = *(int32_t*)pData;
2900 2901
    pData += sizeof(int32_t);

L
Liu Jicong 已提交
2902
    pRes->info.groupId = *(uint64_t*)pData;
2903 2904
    pData += sizeof(uint64_t);

H
Haojun Liao 已提交
2905 2906
    int32_t* colLen = (int32_t*)pData;

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

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

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

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

2928 2929 2930 2931
      if (colLen[i] > 0) {
        memcpy(pColInfoData->pData, pStart, colLen[i]);
      }

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

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

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

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

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

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

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

H
Haojun Liao 已提交
2970
    blockDataEnsureCapacity(pBlock, numOfRows);
2971

L
Liu Jicong 已提交
2972 2973
    int32_t  dataLen = *(int32_t*)pStart;
    uint64_t groupId = *(uint64_t*)(pStart + sizeof(int32_t));
2974 2975
    pStart += sizeof(int32_t) + sizeof(uint64_t);

L
Liu Jicong 已提交
2976
    int32_t* colLen = (int32_t*)(pStart);
2977 2978 2979 2980
    pStart += sizeof(int32_t) * numOfCols;

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

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

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

H
Haojun Liao 已提交
3008
  pRes->info.rows = numOfRows;
3009
  blockDataUpdateTsWindow(pRes);
3010

3011
  int64_t el = taosGetTimestampUs() - startTs;
3012

H
Haojun Liao 已提交
3013 3014
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
3015

H
Haojun Liao 已提交
3016 3017 3018
  if (total != NULL) {
    *total += numOfRows;
  }
3019

H
Haojun Liao 已提交
3020
  pLoadInfo->totalElapsed += el;
3021 3022
  return TSDB_CODE_SUCCESS;
}
3023

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

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

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

  doSetOperatorCompleted(pOperator);
  return NULL;
}

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

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

3057
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
3058 3059 3060
        continue;
      }

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

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

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

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

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

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

L
Liu Jicong 已提交
3125
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3126 3127 3128
  int64_t startTs = taosGetTimestampUs();

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

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

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

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

L
Liu Jicong 已提交
3149
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3150 3151 3152
  int64_t startTs = taosGetTimestampUs();

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

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

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

H
Haojun Liao 已提交
3168
  return TSDB_CODE_SUCCESS;
3169 3170
}

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

L
Liu Jicong 已提交
3175
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3176
  int64_t startTs = taosGetTimestampUs();
3177

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

3183 3184 3185
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

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

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

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

3204
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3205 3206 3207
      pExchangeInfo->current += 1;
      continue;
    }
H
Haojun Liao 已提交
3208

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

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

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

    return pExchangeInfo->pResult;
  }
3232 3233
}

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

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

3249
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
3250 3251 3252
  return TSDB_CODE_SUCCESS;
}

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

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

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

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

  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
3275
    return concurrentlyLoadRemoteData(pOperator);
3276
  }
H
Haojun Liao 已提交
3277

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

  terrno = pTaskInfo->code;
  return NULL;
3285
#endif
H
Haojun Liao 已提交
3286
}
3287

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

dengyihao's avatar
dengyihao 已提交
3339
  pInfo->pResult = pBlock;
3340 3341 3342
  pInfo->seqLoadData = true;

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

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

L
Liu Jicong 已提交
3352 3353
  pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
                                         destroyExchangeOperatorInfo, NULL, NULL, NULL);
3354
  pInfo->pTransporter = pTransporter;
3355

3356
  return pOperator;
H
Haojun Liao 已提交
3357

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

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

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

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

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
3378
    tsortDestroySortHandle(pInfo->pSortHandle);
3379 3380
  }

H
Haojun Liao 已提交
3381
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
3382
  cleanupAggSup(&pInfo->aggSup);
3383
}
H
Haojun Liao 已提交
3384

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

3391 3392
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
3393

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

3397 3398 3399
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
3400

3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413
    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;
      }
3414 3415 3416
    }
  }

3417
  return 0;
3418 3419
}

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

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

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

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

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

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

3462 3463 3464
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
3465

3466 3467
  return true;
}
3468

3469 3470
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
3471

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

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

3490
        // TODO check for available buffer;
H
Haojun Liao 已提交
3491

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

H
Haojun Liao 已提交
3499
          pCtx[j].fpSet.process(&pCtx[j]);
3500
        }
3501 3502 3503

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

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

3513
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes, false);
3514
  blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
3515

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

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

3531 3532 3533
    if (pDataBlock->info.rows == 0) {
      break;
    }
3534

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

3542 3543 3544
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfExprs);
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
3545

3546
  // TODO check for available buffer;
3547

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

3553
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
3554 3555
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
3556 3557
  }

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

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

3568
  tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL);
3569

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

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

H
Haojun Liao 已提交
3581
  pOperator->status = OP_RES_TO_RETURN;
3582
  return doMerge(pOperator);
3583
}
3584

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

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

3613
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
3614

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

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

3629
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
3630

3631 3632
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
3633

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

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

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

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

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

L
Liu Jicong 已提交
3662 3663 3664 3665 3666
  //  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 已提交
3667

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

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

L
Liu Jicong 已提交
3678
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
3679

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

3687
  return pOperator;
H
Haojun Liao 已提交
3688

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

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

3700
int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scanFlag) {
3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711
  // 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 已提交
3712
    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
3713
      return TSDB_CODE_INVALID_PARA;
H
Haojun Liao 已提交
3714
    } else {
3715
      return getTableScanInfo(pOperator->pDownstream[0], order, scanFlag);
3716 3717 3718
    }
  }
}
3719 3720

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

H
Haojun Liao 已提交
3726
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
3727
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
3728

dengyihao's avatar
dengyihao 已提交
3729
  SOptrBasicInfo* pInfo = &pAggInfo->binfo;
H
Haojun Liao 已提交
3730
  SOperatorInfo* downstream = pOperator->pDownstream[0];
3731

3732 3733 3734
  int32_t order = TSDB_ORDER_ASC;
  int32_t scanFlag = MAIN_SCAN;

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

    if (pBlock == NULL) {
      break;
    }

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

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

3758
    // the pDataBlock are always the same one, no need to call this again
3759
    setExecutionContext(pOperator->numOfExprs, pBlock->info.groupId, pTaskInfo, pAggInfo);
3760
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, true);
3761 3762 3763 3764
    code = doAggregateImpl(pOperator, 0, pInfo->pCtx);
    if (code != 0) {
      longjmp(pTaskInfo->env, code);
    }
3765

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
L
Liu Jicong 已提交
3937
  SSDataBlock*          pRes = pInfo->pRes;
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 3985

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

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

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

3994
    return PROJECT_RETRIEVE_DONE;
3995
  }
3996

3997
  // todo optimize performance
3998 3999
  // 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 已提交
4000 4001
  if (pRes->info.rows >= pOperator->resultInfo.threshold || pProjectInfo->slimit.offset != -1 ||
      pProjectInfo->slimit.limit != -1) {
4002
    return PROJECT_RETRIEVE_DONE;
L
Liu Jicong 已提交
4003
  } else {  // not full enough, continue to accumulate the output data in the buffer.
4004 4005 4006 4007
    return PROJECT_RETRIEVE_CONTINUE;
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

4070 4071
    // todo set tags

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

H
Haojun Liao 已提交
4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253
  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 已提交
4254
  taosMemoryFreeClear(pOperator->pExpr);
wafwerar's avatar
wafwerar 已提交
4255 4256
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
4257 4258
}

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

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

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

H
Haojun Liao 已提交
4271
  uint32_t defaultPgsz = 4096;
X
Xiaoyu Wang 已提交
4272
  while (defaultPgsz < pAggSup->resultRowSize * 4) {
H
Haojun Liao 已提交
4273 4274 4275 4276 4277 4278 4279 4280 4281 4282
    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 已提交
4283 4284 4285 4286
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

4287 4288 4289
  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  tsem_destroy(&pExInfo->ready);
}

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

  return pList;
}

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

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

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

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

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

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

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

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

  return pOperator;
H
Haojun Liao 已提交
4507

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return s;
}
H
Haojun Liao 已提交
4606

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

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

  return pCol;
}

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

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

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

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

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

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

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

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

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

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

dengyihao's avatar
dengyihao 已提交
4686 4687
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700
#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 已提交
4701 4702

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4793
      int32_t numOfCols = 0;
5
54liuyao 已提交
4794 4795 4796 4797 4798 4799 4800 4801

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

5
54liuyao 已提交
4803 4804 4805 4806 4807 4808
      if (pDataReader == NULL && terrno != 0) {
        qDebug("pDataReader is     NULL");
        // return NULL;
      } else {
        qDebug("pDataReader is not NULL");
      }
H
Haojun Liao 已提交
4809

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

      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);
4822
      SOperatorInfo* pOperatorDumy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
5
54liuyao 已提交
4823 4824

      SArray* tableIdList = extractTableIdList(pTableGroupInfo);
X
Xiaoyu Wang 已提交
4825
      SSDataBlock*        pResBlock = createResDataBlock(pDescNode);
4826

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

4836 4837 4838
      SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;

      SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4839

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

      SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;

      SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4852

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4937 4938 4939
    SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;

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

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

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

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

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

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

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

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

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

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

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

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

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

  taosMemoryFree(ops);
  return pOptr;
4998
}
H
Haojun Liao 已提交
4999

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

  pCond->twindow = pTableScanNode->scanRange;

#if 1
L
Liu Jicong 已提交
5014
  // todo work around a problem, remove it later
5015 5016
  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 已提交
5017
    TSWAP(pCond->twindow.skey, pCond->twindow.ekey);
H
Haojun Liao 已提交
5018
  }
5019
#endif
H
Haojun Liao 已提交
5020

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

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

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

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

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

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

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

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

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

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

  return pList;
}

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

    taosArrayPush(pList, &c);
  }

  return pList;
}

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

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

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

  return pList;
}

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

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

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

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

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

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

H
Haojun Liao 已提交
5173 5174 5175
  return pList;
}

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

  return code;
}
H
Haojun Liao 已提交
5187

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

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

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

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

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

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

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

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

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

H
Haojun Liao 已提交
5257 5258
  return code;

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

  terrno = code;
  return code;
H
Haojun Liao 已提交
5264 5265
}

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

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

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

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

L
Liu Jicong 已提交
5302
  taosMemoryFree(pFilter);
5303 5304 5305 5306
}

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

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

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

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

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

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

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

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

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

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

D
dapan1121 已提交
5426
  ++(*resNum);
dengyihao's avatar
dengyihao 已提交
5427

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

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
5438 5439
}

5440
static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator) {
5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452
  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);
5453
      pJoinInfo->pLeft = ds1->fpSet.getNextFn(ds1);
5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465
      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);
5466
      pJoinInfo->pRight = ds2->fpSet.getNextFn(ds2);
5467 5468 5469 5470 5471 5472 5473 5474 5475 5476
      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 已提交
5477
    char*            pLeftVal = colDataGetData(pLeftCol, pJoinInfo->leftPos);
5478 5479

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

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

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

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

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

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

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

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

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

    // 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 已提交
5535
SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
X
Xiaoyu Wang 已提交
5536 5537
                                           int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
                                           SExecTaskInfo* pTaskInfo) {
5538
  SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
dengyihao's avatar
dengyihao 已提交
5539
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
5540 5541 5542 5543
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }

5544
  initResultSizeInfo(pOperator, 4096);
5545

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

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

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

5567 5568
  return pOperator;

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

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