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

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

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

30
#include "executorimpl.h"
dengyihao's avatar
dengyihao 已提交
31
#include "index.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
  }
}

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

dengyihao's avatar
dengyihao 已提交
90
#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
wmmhello's avatar
wmmhello 已提交
91
//#define GET_NUM_OF_TABLEGROUP(q)    taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
92 93
#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 102
}

static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes);

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

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

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

X
Xiaoyu Wang 已提交
109
static void releaseQueryBuf(size_t numOfTables);
110

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

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 已提交
118

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

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

125
void doSetOperatorCompleted(SOperatorInfo* pOperator) {
126
  pOperator->status = OP_EXEC_DONE;
127

128
  pOperator->cost.totalCost = (taosGetTimestampUs() - pOperator->pTaskInfo->cost.start * 1000) / 1000.0;
H
Haojun Liao 已提交
129
  if (pOperator->pTaskInfo != NULL) {
130
    setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
131 132
  }
}
133

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

140
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t streamFn,
L
Liu Jicong 已提交
141
                                   __optr_fn_t cleanup, __optr_close_fn_t closeFn, __optr_encode_fn_t encode,
142
                                   __optr_decode_fn_t decode, __optr_explain_fn_t explain) {
143 144 145 146 147 148 149 150 151 152 153 154 155 156
  SOperatorFpSet fpSet = {
      ._openFn = openFn,
      .getNextFn = nextFn,
      .getStreamResFn = streamFn,
      .cleanupFn = cleanup,
      .closeFn = closeFn,
      .encodeResultRow = encode,
      .decodeResultRow = decode,
      .getExplainFn = explain,
  };

  return fpSet;
}

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

X
Xiaoyu Wang 已提交
159 160 161
static int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo,
                                  SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, const int32_t* rowCellOffset,
                                  SqlFunctionCtx* pCtx, int32_t numOfExprs);
H
Haojun Liao 已提交
162

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

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

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

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

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

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

  int16_t offset = supporter->dataOffset;
187
  return 0;
X
Xiaoyu Wang 已提交
188 189
  //  char*   in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
  //  char*   in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
190

X
Xiaoyu Wang 已提交
191
  //  return (in1 != NULL && in2 != NULL) ? supporter->comFunc(in1, in2) : 0;
192 193
}

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

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

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

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

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

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

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

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

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

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

  return true;
}

L
Liu Jicong 已提交
242 243
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
                                int16_t bytes, bool masterscan, uint64_t uid) {
244 245 246
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);

L
Liu Jicong 已提交
247 248
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
249 250 251 252 253 254 255 256 257 258 259

  // 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 已提交
260
        //        existed = (pResultRowInfo->pResult[0] == (*p1));
261 262
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid, pResultRowInfo);
L
Liu Jicong 已提交
263 264
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
265 266 267 268 269 270 271 272 273 274 275 276 277 278
        if (index != NULL) {
          existed = true;
        } else {
          existed = false;
        }
      }
    }

    return existed;
  }

  return p1 != NULL;
}

279
SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
L
Liu Jicong 已提交
280
  SFilePage* pData = NULL;
281 282 283 284 285 286 287 288 289 290 291 292 293

  // 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 已提交
294
    if (pData->num + interBufSize > getBufPageSize(pResultBuf)) {
295 296 297 298 299 300 301 302 303 304 305 306 307 308
      // 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;
  }

309 310
  setBufPageDirty(pData, true);

311 312 313 314 315
  // 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 已提交
316
  pData->num += interBufSize;
317 318 319 320

  return pResultRow;
}

321 322 323 324 325 326 327
/**
 * the struct of key in hash table
 * +----------+---------------+
 * | group id |   key data    |
 * | 8 bytes  | actual length |
 * +----------+---------------+
 */
328 329 330
SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, char* pData,
                                   int16_t bytes, bool masterscan, uint64_t groupId, SExecTaskInfo* pTaskInfo,
                                   bool isIntervalQuery, SAggSupporter* pSup) {
331
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
H
Haojun Liao 已提交
332

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

336 337
  SResultRow* pResult = NULL;

H
Haojun Liao 已提交
338 339
  // in case of repeat scan/reverse scan, no new time window added.
  if (isIntervalQuery) {
340 341
    if (masterscan && p1 != NULL) {  // the *p1 may be NULL in case of sliding+offset exists.
      pResult = getResultRowByPos(pResultBuf, p1);
342
      ASSERT(pResult->pageId == p1->pageId && pResult->offset == p1->offset);
H
Haojun Liao 已提交
343 344
    }
  } else {
dengyihao's avatar
dengyihao 已提交
345 346
    // In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
    // pResultRowInfo object.
H
Haojun Liao 已提交
347
    if (p1 != NULL) {
348
      // todo
349
      pResult = getResultRowByPos(pResultBuf, p1);
350
      ASSERT(pResult->pageId == p1->pageId && pResult->offset == p1->offset);
H
Haojun Liao 已提交
351 352 353
    }
  }

L
Liu Jicong 已提交
354
  // 1. close current opened time window
355
  if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
L
Liu Jicong 已提交
356
                                                                 pResult->offset != pResultRowInfo->cur.offset))) {
357
    SResultRowPosition pos = pResultRowInfo->cur;
X
Xiaoyu Wang 已提交
358
    SFilePage*         pPage = getBufPage(pResultBuf, pos.pageId);
359 360 361 362 363
    releaseBufPage(pResultBuf, pPage);
  }

  // allocate a new buffer page
  if (pResult == NULL) {
H
Haojun Liao 已提交
364
    ASSERT(pSup->resultRowSize > 0);
365 366
    pResult = getNewResultRow(pResultBuf, groupId, pSup->resultRowSize);

367
    initResultRow(pResult);
H
Haojun Liao 已提交
368

369 370
    // add a new result set for a new group
    SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
X
Xiaoyu Wang 已提交
371 372
    taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos,
                sizeof(SResultRowPosition));
H
Haojun Liao 已提交
373 374
  }

375 376 377
  // 2. set the new time window to be the new active time window
  pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};

H
Haojun Liao 已提交
378
  // too many time window in query
379
  if (taosHashGetSize(pSup->pResultRowHashTable) > MAX_INTERVAL_TIME_WINDOW) {
H
Haojun Liao 已提交
380 381 382
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
  }

H
Haojun Liao 已提交
383
  return pResult;
H
Haojun Liao 已提交
384 385
}

386
// get the correct time window according to the handled timestamp
L
Liu Jicong 已提交
387
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo* pResultRowInfo, int64_t ts, STaskAttr* pQueryAttr) {
388
  STimeWindow w = {0};
H
Haojun Liao 已提交
389
#if 0
L
Liu Jicong 已提交
390 391
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
                                       //    getInitialStartTimeWindow(pQueryAttr, ts, &w);
392 393

    if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') {
L
Liu Jicong 已提交
394 395 396
      w.ekey =
          taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) -
          1;
397 398 399 400
    } else {
      w.ekey = w.skey + pQueryAttr->interval.interval - 1;
    }
  } else {
H
Haojun Liao 已提交
401
    w = pRow->win;
402 403 404 405 406 407 408 409 410
  }

  /*
   * 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 已提交
411
#endif
412 413 414 415 416

  return w;
}

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

L
Liu Jicong 已提交
422
  SFilePage* pData = NULL;
423 424 425 426 427 428

  // 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 已提交
429
    pData = getNewBufPage(pResultBuf, tid, &pageId);
430
    pData->num = sizeof(SFilePage);
431 432
  } else {
    SPageInfo* pi = getLastPageInfo(list);
433
    pData = getBufPage(pResultBuf, getPageId(pi));
434
    pageId = getPageId(pi);
435

436
    if (pData->num + size > getBufPageSize(pResultBuf)) {
437
      // release current page first, and prepare the next one
438
      releaseBufPageInfo(pResultBuf, pi);
439

H
Haojun Liao 已提交
440
      pData = getNewBufPage(pResultBuf, tid, &pageId);
441
      if (pData != NULL) {
442
        pData->num = sizeof(SFilePage);
443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
      }
    }
  }

  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 已提交
463 464 465
static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, STimeWindow* win,
                                    bool masterscan, SResultRow** pResult, int64_t groupId, SqlFunctionCtx* pCtx,
                                    int32_t numOfOutput, int32_t* rowCellInfoOffset) {
466
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
467
  return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char*)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
468 469
}

dengyihao's avatar
dengyihao 已提交
470 471
static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey, bool ascQuery,
                                   bool timeWindowInterpo) {
472
  int64_t skey = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
473
#if 0
474 475
  int32_t i = 0;
  for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
476
    SResultRow* pResult = pResultRowInfo->pResult[i];
477 478 479 480 481 482
    if (pResult->closed) {
      break;
    }

    // new closed result rows
    if (timeWindowInterpo) {
L
Liu Jicong 已提交
483 484 485
      if (pResult->endInterp &&
          ((pResult->win.skey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery))) {
        if (i > 0) {  // the first time window, the startInterp is false.
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
          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 已提交
505
      //      assert(pResultRowInfo->current == NULL);
506 507 508 509 510 511 512
      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 已提交
513
      SResultRow* pResult = pResultRowInfo->pResult[i];
514 515 516 517 518 519 520 521 522 523 524
      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 已提交
525
#endif
526
}
527
//
dengyihao's avatar
dengyihao 已提交
528
// static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
529 530 531 532 533 534 535 536 537
//                                           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);
//  }
//}
538

539
//  query_range_start, query_range_end, window_duration, window_start, window_end
540
void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow) {
541 542 543
  pColData->info.type = TSDB_DATA_TYPE_TIMESTAMP;
  pColData->info.bytes = sizeof(int64_t);

544
  colInfoDataEnsureCapacity(pColData, 0, 5);
545 546 547 548 549 550 551 552 553
  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);
}

X
Xiaoyu Wang 已提交
554 555 556
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin,
                      SColumnInfoData* pTimeWindowData, int32_t offset, int32_t forwardStep, TSKEY* tsCol,
                      int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
557
  for (int32_t k = 0; k < numOfOutput; ++k) {
H
Haojun Liao 已提交
558
    // keep it temporarily
559
    // todo no need this??
dengyihao's avatar
dengyihao 已提交
560 561
    bool    hasAgg = pCtx[k].input.colDataAggIsSet;
    int32_t numOfRows = pCtx[k].input.numOfRows;
H
Haojun Liao 已提交
562
    int32_t startOffset = pCtx[k].input.startRowIndex;
563

564
    pCtx[k].input.startRowIndex = offset;
565
    pCtx[k].input.numOfRows = forwardStep;
566 567

    if (tsCol != NULL) {
H
Haojun Liao 已提交
568
      pCtx[k].ptsList = tsCol;
569 570 571 572
    }

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

577 578
    if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
      SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
579 580

      char* p = GET_ROWCELL_INTERBUF(pEntryInfo);
581

582
      SColumnInfoData idata = {0};
dengyihao's avatar
dengyihao 已提交
583
      idata.info.type = TSDB_DATA_TYPE_BIGINT;
584
      idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
dengyihao's avatar
dengyihao 已提交
585
      idata.pData = p;
586 587 588 589

      SScalarParam out = {.columnData = &idata};
      SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
      pCtx[k].sfp.process(&tw, 1, &out);
590
      pEntryInfo->numOfRes = 1;
591 592 593 594 595 596 597 598 599 600
    } else {
      int32_t code = TSDB_CODE_SUCCESS;
      if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
        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);
        }
601
      }
602

603 604 605 606 607
      // restore it
      pCtx[k].input.colDataAggIsSet = hasAgg;
      pCtx[k].input.startRowIndex = startOffset;
      pCtx[k].input.numOfRows = numOfRows;
    }
608 609 610
  }
}

L
Liu Jicong 已提交
611
static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* pWindow) {
dengyihao's avatar
dengyihao 已提交
612
  TSKEY   ekey = -1;
613 614
  int32_t order = TSDB_ORDER_ASC;
  if (order == TSDB_ORDER_ASC) {
615 616 617 618 619 620 621 622 623 624 625 626 627 628
    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 已提交
629
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
630
                                   int32_t scanFlag, bool createDummyCol);
631

dengyihao's avatar
dengyihao 已提交
632 633
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
                                    int32_t order) {
634
  for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
635
    pCtx[i].order = order;
636
    pCtx[i].input.numOfRows = pBlock->info.rows;
637
    setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
638 639 640
  }
}

X
Xiaoyu Wang 已提交
641 642
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                       int32_t scanFlag, bool createDummyCol) {
643
  if (pBlock->pBlockAgg != NULL) {
H
Haojun Liao 已提交
644
    doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
645
  } else {
646
    doSetInputDataBlock(pOperator, pCtx, pBlock, order, scanFlag, createDummyCol);
H
Haojun Liao 已提交
647
  }
648 649
}

L
Liu Jicong 已提交
650 651
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t paramIndex,
                                             int32_t numOfRows) {
652 653 654 655 656 657 658 659
  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)
660 661
    pColInfo->info.type = pFuncParam->param.nType;
    pColInfo->info.bytes = pFuncParam->param.nLen;
662 663

    pInput->pData[paramIndex] = pColInfo;
664 665
  } else {
    pColInfo = pInput->pData[paramIndex];
666 667
  }

668
  colInfoDataEnsureCapacity(pColInfo, 0, numOfRows);
669

670
  int8_t type = pFuncParam->param.nType;
671 672
  if (type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_UBIGINT) {
    int64_t v = pFuncParam->param.i;
dengyihao's avatar
dengyihao 已提交
673
    for (int32_t i = 0; i < numOfRows; ++i) {
674 675 676 677
      colDataAppendInt64(pColInfo, i, &v);
    }
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
dengyihao's avatar
dengyihao 已提交
678
    for (int32_t i = 0; i < numOfRows; ++i) {
679 680
      colDataAppendDouble(pColInfo, i, &v);
    }
681
  } else if (type == TSDB_DATA_TYPE_VARCHAR) {
L
Liu Jicong 已提交
682
    char* tmp = taosMemoryMalloc(pFuncParam->param.nLen + VARSTR_HEADER_SIZE);
683
    STR_WITH_SIZE_TO_VARSTR(tmp, pFuncParam->param.pz, pFuncParam->param.nLen);
L
Liu Jicong 已提交
684
    for (int32_t i = 0; i < numOfRows; ++i) {
685 686
      colDataAppend(pColInfo, i, tmp, false);
    }
687 688 689 690 691
  }

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
692
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
X
Xiaoyu Wang 已提交
693
                                   int32_t scanFlag, bool createDummyCol) {
694 695
  int32_t code = TSDB_CODE_SUCCESS;

696
  for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
L
Liu Jicong 已提交
697
    pCtx[i].order = order;
698 699
    pCtx[i].input.numOfRows = pBlock->info.rows;

L
Liu Jicong 已提交
700
    pCtx[i].pSrcBlock = pBlock;
X
Xiaoyu Wang 已提交
701
    pCtx[i].scanFlag = scanFlag;
H
Haojun Liao 已提交
702

703
    SInputColumnInfoData* pInput = &pCtx[i].input;
704
    pInput->uid = pBlock->info.uid;
C
Cary Xu 已提交
705
    pInput->colDataAggIsSet = false;
706

707 708
    SExprInfo* pOneExpr = &pOperator->pExpr[i];
    for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
dengyihao's avatar
dengyihao 已提交
709
      SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
G
Ganlin Zhao 已提交
710 711
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
dengyihao's avatar
dengyihao 已提交
712
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
713 714 715
        pInput->totalRows = pBlock->info.rows;
        pInput->numOfRows = pBlock->info.rows;
        pInput->startRowIndex = 0;
716

717
        // NOTE: the last parameter is the primary timestamp column
718 719 720
        if (fmIsTimelineFunc(pCtx[i].functionId) && (j == pOneExpr->base.numOfParams - 1)) {
          pInput->pPTS = pInput->pData[j];
        }
721 722
        ASSERT(pInput->pData[j] != NULL);
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
723 724 725
        // 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) {
726 727 728 729
          pInput->totalRows = pBlock->info.rows;
          pInput->numOfRows = pBlock->info.rows;
          pInput->startRowIndex = 0;

730
          code = doCreateConstantValColumnInfo(pInput, pFuncParam, j, pBlock->info.rows);
731 732 733
          if (code != TSDB_CODE_SUCCESS) {
            return code;
          }
734
        }
G
Ganlin Zhao 已提交
735 736
      }
    }
H
Haojun Liao 已提交
737
  }
738 739

  return code;
H
Haojun Liao 已提交
740 741
}

742
static int32_t doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
743
  for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
H
Haojun Liao 已提交
744
    if (functionNeedToExecute(&pCtx[k])) {
745
      // todo add a dummy funtion to avoid process check
746 747 748 749 750 751 752 753
      if (pCtx[k].fpSet.process == NULL) {
        continue;
      }

      int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
      if (code != TSDB_CODE_SUCCESS) {
        qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
        return code;
754
      }
755 756
    }
  }
757 758

  return TSDB_CODE_SUCCESS;
759 760
}

H
Haojun Liao 已提交
761
static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, SArray* pPseudoList) {
dengyihao's avatar
dengyihao 已提交
762
  size_t num = (pPseudoList != NULL) ? taosArrayGetSize(pPseudoList) : 0;
H
Haojun Liao 已提交
763 764 765 766 767
  for (int32_t i = 0; i < num; ++i) {
    pCtx[i].pOutput = taosArrayGet(pResult->pDataBlock, i);
  }
}

768
int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
X
Xiaoyu Wang 已提交
769
                              int32_t numOfOutput, SArray* pPseudoList) {
H
Haojun Liao 已提交
770
  setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
H
Haojun Liao 已提交
771
  pResult->info.groupId = pSrcBlock->info.groupId;
H
Haojun Liao 已提交
772

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

777 778
  int32_t numOfRows = 0;

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

L
Liu Jicong 已提交
783
    if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) {  // it is a project query
784
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
785
      if (pResult->info.rows > 0 && !createNewColModel) {
X
Xiaoyu Wang 已提交
786 787
        colDataMergeCol(pColInfoData, pResult->info.rows, &pResult->info.capacity, pfCtx->input.pData[0],
                        pfCtx->input.numOfRows);
788 789 790
      } else {
        colDataAssign(pColInfoData, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      }
791

792
      numOfRows = pfCtx->input.numOfRows;
793
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_VALUE) {
794
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
795

dengyihao's avatar
dengyihao 已提交
796
      int32_t offset = createNewColModel ? 0 : pResult->info.rows;
797
      for (int32_t i = 0; i < pSrcBlock->info.rows; ++i) {
dengyihao's avatar
dengyihao 已提交
798 799 800
        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);
801
      }
802 803

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

808
      SColumnInfoData* pResColData = taosArrayGet(pResult->pDataBlock, outputSlotId);
809
      SColumnInfoData  idata = {.info = pResColData->info, .hasNull = true};
810

811
      SScalarParam dest = {.columnData = &idata};
X
Xiaoyu Wang 已提交
812
      int32_t      code = scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);
813 814 815 816
      if (code != TSDB_CODE_SUCCESS) {
        taosArrayDestroy(pBlockList);
        return code;
      }
817

dengyihao's avatar
dengyihao 已提交
818
      int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
819
      colInfoDataEnsureCapacity(pResColData, startOffset, pResult->info.capacity);
820
      colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
821 822

      numOfRows = dest.numOfRows;
823 824
      taosArrayDestroy(pBlockList);
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) {
825
      ASSERT(!fmIsAggFunc(pfCtx->functionId));
826

827 828
      // _rowts/_c0, not tbname column
      if (fmIsPseudoColumnFunc(pfCtx->functionId) && (!fmIsScanPseudoColumnFunc(pfCtx->functionId))) {
H
Haojun Liao 已提交
829
        // do nothing
X
Xiaoyu Wang 已提交
830
      } else if (fmIsIndefiniteRowsFunc(pfCtx->functionId)) {
dengyihao's avatar
dengyihao 已提交
831
        SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[k]);
832
        pfCtx->fpSet.init(&pCtx[k], pResInfo);
833

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

837
        // set the timestamp(_rowts) output buffer
838 839
        if (taosArrayGetSize(pPseudoList) > 0) {
          int32_t* outputColIndex = taosArrayGet(pPseudoList, 0);
840
          pfCtx->pTsOutput = (SColumnInfoData*)pCtx[*outputColIndex].pOutput;
841
        }
H
Haojun Liao 已提交
842

843
        numOfRows = pfCtx->fpSet.process(pfCtx);
H
Haojun Liao 已提交
844 845 846
      } else {
        SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
        taosArrayPush(pBlockList, &pSrcBlock);
G
Ganlin Zhao 已提交
847

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

851
        SScalarParam dest = {.columnData = &idata};
X
Xiaoyu Wang 已提交
852
        int32_t      code = scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
853 854 855 856
        if (code != TSDB_CODE_SUCCESS) {
          taosArrayDestroy(pBlockList);
          return code;
        }
857

dengyihao's avatar
dengyihao 已提交
858
        int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
859
        colInfoDataEnsureCapacity(pResColData, startOffset, pResult->info.capacity);
860
        colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
861 862

        numOfRows = dest.numOfRows;
H
Haojun Liao 已提交
863 864
        taosArrayDestroy(pBlockList);
      }
865
    } else {
866
      ASSERT(0);
867 868
    }
  }
869

870 871 872
  if (!createNewColModel) {
    pResult->info.rows += numOfRows;
  }
873 874

  return TSDB_CODE_SUCCESS;
875 876
}

877 878 879
static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
  if (IS_VAR_DATA_TYPE(type)) {
    // todo disable this
880

881 882 883 884 885 886 887 888 889
    //    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);
890

891 892
    pResultRow->win.skey = v;
    pResultRow->win.ekey = v;
893 894 895
  }
}

896 897 898 899 900
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;
901

902 903 904
  SResultRow* pResultRow =
      doSetResultOutBufByKey(pBuf, pResultRowInfo, (char*)pData, bytes, true, groupId, pTaskInfo, false, pAggSup);
  assert(pResultRow != NULL);
905

906
  setResultRowKey(pResultRow, pData, type);
907
  setResultRowInitCtx(pResultRow, pCtx, numOfCols, binfo->rowCellInfoOffset);
908
  return TSDB_CODE_SUCCESS;
909 910
}

5
54liuyao 已提交
911
bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
912
  struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
913

914 915 916 917 918
  // in case of timestamp column, always generated results.
  int32_t functionId = pCtx->functionId;
  if (functionId == -1) {
    return false;
  }
919

920 921
  if (pCtx->scanFlag == REPEAT_SCAN) {
    return fmIsRepeatScanFunc(pCtx->functionId);
922 923
  }

924 925
  if (isRowEntryCompleted(pResInfo)) {
    return false;
926 927
  }

X
Xiaoyu Wang 已提交
928 929 930 931 932 933 934 935
  //  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;
  //  }
936

937 938 939 940 941
  // 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;
  //  }
942 943 944 945

  return true;
}

946 947 948 949 950 951 952
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;
    }
953

954 955 956
    // Set the correct column info (data type and bytes)
    pInput->pData[paramIndex]->info.type = type;
    pInput->pData[paramIndex]->info.bytes = tDataTypes[type].bytes;
957
  }
H
Haojun Liao 已提交
958

959 960 961 962 963 964
  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;
965 966
    }
  } else {
967
    da = pInput->pColumnDataAgg[paramIndex];
968 969
  }

970
  ASSERT(!IS_VAR_DATA_TYPE(type));
971

972 973 974 975 976 977
  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};
978

979 980 981 982 983 984 985 986 987 988 989 990
    *(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
991
  } else {
992
    ASSERT(0);
993 994
  }

995 996
  return TSDB_CODE_SUCCESS;
}
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007

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;

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

1011 1012
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
1013 1014 1015 1016
        pInput->pColumnDataAgg[j] = pBlock->pBlockAgg[slotId];
        if (pInput->pColumnDataAgg[j] == NULL) {
          pInput->colDataAggIsSet = false;
        }
1017 1018 1019 1020

        // 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);
1021 1022
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
        doCreateConstantValColumnAggInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
1023 1024
      }
    }
1025
  } else {
1026
    pInput->colDataAggIsSet = false;
1027 1028 1029
  }

  // set the statistics data for primary time stamp column
1030 1031 1032 1033 1034
  //  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;
  //  }
1035 1036 1037
}

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

H
Haojun Liao 已提交
1041
  SqlFunctionCtx*  p = NULL;
1042 1043
  SqlFunctionCtx** pValCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
  if (pValCtx == NULL) {
1044 1045 1046 1047
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
1048 1049
    if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
      pValCtx[num++] = &pCtx[i];
X
Xiaoyu Wang 已提交
1050
    } else if (fmIsSelectFunc(pCtx[i].functionId)) {
1051
      p = &pCtx[i];
1052
    }
X
Xiaoyu Wang 已提交
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
    //    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
    //    }
1063
  }
1064

1065
  if (p != NULL) {
1066
    p->subsidiaries.pCtx = pValCtx;
1067
    p->subsidiaries.num = num;
1068
  } else {
1069
    taosMemoryFreeClear(pValCtx);
1070 1071 1072 1073 1074
  }

  return TSDB_CODE_SUCCESS;
}

1075
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) {
L
Liu Jicong 已提交
1076
  SqlFunctionCtx* pFuncCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
H
Haojun Liao 已提交
1077 1078 1079 1080
  if (pFuncCtx == NULL) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
1081
  *rowCellInfoOffset = taosMemoryCalloc(numOfOutput, sizeof(int32_t));
H
Haojun Liao 已提交
1082
  if (*rowCellInfoOffset == 0) {
wafwerar's avatar
wafwerar 已提交
1083
    taosMemoryFreeClear(pFuncCtx);
H
Haojun Liao 已提交
1084 1085 1086 1087
    return NULL;
  }

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

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

1093
    pCtx->functionId = -1;
1094
    pCtx->curBufPage = -1;
L
Liu Jicong 已提交
1095
    pCtx->pExpr = pExpr;
1096

H
Haojun Liao 已提交
1097
    if (pExpr->pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1098
      SFuncExecEnv env = {0};
H
Haojun Liao 已提交
1099 1100
      pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;

X
Xiaoyu Wang 已提交
1101
      if (fmIsAggFunc(pCtx->functionId) || fmIsIndefiniteRowsFunc(pCtx->functionId)) {
1102 1103 1104 1105
        bool isUdaf = fmIsUserDefinedFunc(pCtx->functionId);
        if (!isUdaf) {
          fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
        } else {
1106
          char* udfName = pExpr->pExpr->_function.pFunctNode->functionName;
1107 1108 1109
          strncpy(pCtx->udfName, udfName, strlen(udfName));
          fmGetUdafExecFuncs(pCtx->functionId, &pCtx->fpSet);
        }
1110 1111 1112
        pCtx->fpSet.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
      } else {
        fmGetScalarFuncExecFuncs(pCtx->functionId, &pCtx->sfp);
1113 1114 1115
        if (pCtx->sfp.getEnv != NULL) {
          pCtx->sfp.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
        }
1116
      }
H
Haojun Liao 已提交
1117
      pCtx->resDataInfo.interBufSize = env.calcMemSize;
1118 1119
    } else if (pExpr->pExpr->nodeType == QUERY_NODE_COLUMN || pExpr->pExpr->nodeType == QUERY_NODE_OPERATOR ||
               pExpr->pExpr->nodeType == QUERY_NODE_VALUE) {
H
Haojun Liao 已提交
1120
      // for simple column, the result buffer needs to hold at least one element.
1121
      pCtx->resDataInfo.interBufSize = pFunct->resSchema.bytes;
H
Haojun Liao 已提交
1122
    }
H
Haojun Liao 已提交
1123

H
Haojun Liao 已提交
1124
    pCtx->input.numOfInputCols = pFunct->numOfParams;
wafwerar's avatar
wafwerar 已提交
1125 1126
    pCtx->input.pData = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
    pCtx->input.pColumnDataAgg = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
H
Haojun Liao 已提交
1127

1128
    pCtx->pTsOutput = NULL;
L
Liu Jicong 已提交
1129
    pCtx->resDataInfo.bytes = pFunct->resSchema.bytes;
1130
    pCtx->resDataInfo.type = pFunct->resSchema.type;
L
Liu Jicong 已提交
1131
    pCtx->order = TSDB_ORDER_ASC;
1132
    pCtx->start.key = INT64_MIN;
L
Liu Jicong 已提交
1133
    pCtx->end.key = INT64_MIN;
1134
    pCtx->numOfParams = pExpr->base.numOfParams;
H
Haojun Liao 已提交
1135

1136
    pCtx->param = pFunct->pParam;
dengyihao's avatar
dengyihao 已提交
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
    //    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 已提交
1171 1172
  }

L
Liu Jicong 已提交
1173 1174 1175
  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 已提交
1176
  }
H
Haojun Liao 已提交
1177

1178
  setSelectValueColumnInfo(pFuncCtx, numOfOutput);
H
Haojun Liao 已提交
1179 1180 1181
  return pFuncCtx;
}

1182
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1183 1184 1185 1186 1187 1188
  if (pCtx == NULL) {
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    for (int32_t j = 0; j < pCtx[i].numOfParams; ++j) {
1189
      taosVariantDestroy(&pCtx[i].param[j].param);
1190 1191
    }

1192
    taosMemoryFreeClear(pCtx[i].subsidiaries.pCtx);
H
Haojun Liao 已提交
1193 1194
    taosMemoryFree(pCtx[i].input.pData);
    taosMemoryFree(pCtx[i].input.pColumnDataAgg);
1195 1196
  }

wafwerar's avatar
wafwerar 已提交
1197
  taosMemoryFreeClear(pCtx);
1198 1199 1200
  return NULL;
}

L
Liu Jicong 已提交
1201
bool isTaskKilled(SExecTaskInfo* pTaskInfo) {
1202 1203
  // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
  // abort current query execution.
L
Liu Jicong 已提交
1204 1205
  if (pTaskInfo->owner != 0 &&
      ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec())
1206 1207
      /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) {
    assert(pTaskInfo->cost.start != 0);
L
Liu Jicong 已提交
1208 1209 1210
    //    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;
1211 1212 1213 1214 1215
  }

  return false;
}

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

L
Liu Jicong 已提交
1218
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
1219 1220
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
X
Xiaoyu Wang 已提交
1221 1222 1223
    //    if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) {
    //      continue;
    //    }
1224 1225 1226 1227

    return false;
  }

1228 1229
  int32_t order = TSDB_ORDER_ASC;
  if (order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) {
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
    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 已提交
1249
// todo refactor : return window
1250
void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, STimeWindow* win) {
H
Haojun Liao 已提交
1251
  win->skey = taosTimeTruncate(key, pInterval, precision);
1252 1253

  /*
H
Haojun Liao 已提交
1254
   * if the realSkey > INT64_MAX - pInterval->interval, the query duration between
1255 1256
   * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
   */
1257 1258
  win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
  if (win->ekey < win->skey) {
1259 1260 1261 1262
    win->ekey = INT64_MAX;
  }
}

L
Liu Jicong 已提交
1263
static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
1264 1265 1266
  bool hasFirstLastFunc = false;
  bool hasOtherFunc = false;

1267
  if (status == BLK_DATA_DATA_LOAD || status == BLK_DATA_FILTEROUT) {
1268 1269 1270 1271 1272
    return status;
  }

  for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQuery->pExpr1[i]);
1273
#if 0
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
    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;
    }
1284
#endif
1285 1286
  }

1287
  if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
L
Liu Jicong 已提交
1288
    if (!hasOtherFunc) {
1289
      return BLK_DATA_FILTEROUT;
1290
    } else {
1291
      return BLK_DATA_DATA_LOAD;
1292 1293 1294 1295 1296 1297
    }
  }

  return status;
}

L
Liu Jicong 已提交
1298 1299
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
//   STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
H
Haojun Liao 已提交
1300
//
L
Liu Jicong 已提交
1301 1302 1303 1304
//   // 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 已提交
1305
//
L
Liu Jicong 已提交
1306 1307 1308 1309 1310
//   // 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 已提交
1311
//
L
Liu Jicong 已提交
1312 1313
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
wafwerar's avatar
wafwerar 已提交
1314
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
L
Liu Jicong 已提交
1315
//     }
H
Haojun Liao 已提交
1316
//
L
Liu Jicong 已提交
1317 1318 1319
//     pQueryAttr->needReverseScan = false;
//     return;
//   }
H
Haojun Liao 已提交
1320
//
L
Liu Jicong 已提交
1321 1322 1323
//   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 已提交
1324
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
L
Liu Jicong 已提交
1325
//     }
H
Haojun Liao 已提交
1326
//
L
Liu Jicong 已提交
1327 1328 1329 1330
//     pQueryAttr->needReverseScan = false;
//     doUpdateLastKey(pQueryAttr);
//     return;
//   }
H
Haojun Liao 已提交
1331
//
L
Liu Jicong 已提交
1332 1333 1334 1335 1336 1337
//   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 已提交
1338
//
L
Liu Jicong 已提交
1339 1340 1341
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     return;
//   }
H
Haojun Liao 已提交
1342
//
L
Liu Jicong 已提交
1343 1344 1345 1346
//   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 已提交
1347 1348
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
wafwerar's avatar
wafwerar 已提交
1349
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359
//        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 已提交
1360
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
//        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 已提交
1373 1374
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
1375
//
wafwerar's avatar
wafwerar 已提交
1376
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1377 1378 1379 1380 1381 1382 1383 1384
//          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 已提交
1385 1386
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
1387
//
wafwerar's avatar
wafwerar 已提交
1388
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
H
Haojun Liao 已提交
1389 1390 1391 1392 1393 1394 1395 1396 1397
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_DESC;
//        pQueryAttr->needReverseScan = false;
//      }
//    }
//  }
//}
1398

L
Liu Jicong 已提交
1399 1400 1401
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
//   STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
1402
//
L
Liu Jicong 已提交
1403 1404 1405
//   if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
//     return true;
//   }
1406
//
L
Liu Jicong 已提交
1407 1408
//   return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
1409

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

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

1416
  if (true) {
L
Liu Jicong 已提交
1417
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
1418 1419 1420 1421 1422 1423
    assert(w.ekey >= pBlockInfo->window.skey);

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

L
Liu Jicong 已提交
1424 1425
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
      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 已提交
1436
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
1437 1438 1439 1440 1441 1442
    assert(w.skey <= pBlockInfo->window.ekey);

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

L
Liu Jicong 已提交
1443 1444
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
      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 uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
1509
  SqlFunctionCtx* pCtx = pTableScanInfo->pCtx;
1510
  uint32_t        status = BLK_DATA_NOT_LOAD;
1511 1512 1513 1514

  int32_t numOfOutput = pTableScanInfo->numOfOutput;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;
H
Haojun Liao 已提交
1515
    int32_t colId = pTableScanInfo->pExpr[i].base.pParam[0].pCol->colId;
1516 1517 1518

    // group by + first/last should not apply the first/last block filter
    if (functionId < 0) {
1519
      status |= BLK_DATA_DATA_LOAD;
1520 1521
      return status;
    } else {
L
Liu Jicong 已提交
1522
      //      status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
1523
      //      if ((status & BLK_DATA_DATA_LOAD) == BLK_DATA_DATA_LOAD) {
L
Liu Jicong 已提交
1524 1525
      //        return status;
      //      }
1526 1527 1528 1529 1530 1531
    }
  }

  return status;
}

L
Liu Jicong 已提交
1532 1533
int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                              uint32_t* status) {
1534
  *status = BLK_DATA_NOT_LOAD;
1535

H
Haojun Liao 已提交
1536
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
1537
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
1538

L
Liu Jicong 已提交
1539 1540
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
1541

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

1544 1545
//  pCost->totalBlocks += 1;
//  pCost->totalRows += pBlock->info.rows;
H
Haojun Liao 已提交
1546
#if 0
1547 1548 1549
  // 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 已提交
1550
      (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) {
1551
    (*status) = BLK_DATA_DATA_LOAD;
1552 1553 1554
  }

  // check if this data block is required to load
1555
  if ((*status) != BLK_DATA_DATA_LOAD) {
1556 1557 1558 1559 1560 1561 1562
    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 已提交
1563
      bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586
      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 {
1587
      (*status) = BLK_DATA_DATA_LOAD;
1588 1589 1590 1591
    }
  }

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

1594
  if ((*status) == BLK_DATA_NOT_LOAD || (*status) == BLK_DATA_FILTEROUT) {
1595 1596
    //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//           pBlockInfo->window.ekey, pBlockInfo->rows);
1597
    pCost->skipBlocks += 1;
1598
  } else if ((*status) == BLK_DATA_SMA_LOAD) {
1599 1600
    // this function never returns error?
    pCost->loadBlockStatis += 1;
1601
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
1602 1603

    if (pBlock->pBlockAgg == NULL) {  // data block statistics does not exist, load data block
1604
//      pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
1605 1606 1607
      pCost->totalCheckedRows += pBlock->info.rows;
    }
  } else {
1608
    assert((*status) == BLK_DATA_DATA_LOAD);
1609 1610 1611

    // load the data block statistics to perform further filter
    pCost->loadBlockStatis += 1;
1612
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
1613 1614 1615 1616 1617 1618

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

H
Haojun Liao 已提交
1619
          bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
          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
1637
            pCost->skipBlocks += 1;
1638 1639
            //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
//                   pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
1640
            (*status) = BLK_DATA_FILTEROUT;
1641 1642 1643 1644 1645 1646 1647 1648
            return TSDB_CODE_SUCCESS;
          }
        }
      }
    }

    // current block has been discard due to filter applied
//    if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
1649
//      pCost->skipBlocks += 1;
1650 1651
//      qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//             pBlockInfo->window.ekey, pBlockInfo->rows);
1652
//      (*status) = BLK_DATA_FILTEROUT;
1653 1654 1655 1656 1657
//      return TSDB_CODE_SUCCESS;
//    }

    pCost->totalCheckedRows += pBlockInfo->rows;
    pCost->loadBlocks += 1;
1658
//    pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
1659 1660 1661 1662 1663 1664 1665
//    if (pBlock->pDataBlock == NULL) {
//      return terrno;
//    }

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

1667 1668 1669 1670
//    if (pQueryAttr->pFilters != NULL || pRuntimeEnv->pTsBuf != NULL) {
//      filterColRowsInDataBlock(pRuntimeEnv, pBlock, ascQuery);
//    }
  }
H
Haojun Liao 已提交
1671
#endif
1672 1673 1674
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
1675
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
1676 1677 1678 1679
  if (pTableQueryInfo == NULL) {
    return;
  }

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

L
Liu Jicong 已提交
1683 1684
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
1685 1686

  // set the index to be the end slot of result rows array
dengyihao's avatar
dengyihao 已提交
1687 1688 1689 1690 1691 1692
  //  SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->size > 0) {
  //    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  //  } else {
  //    pResultRowInfo->curPos = -1;
  //  }
1693 1694
}

H
Haojun Liao 已提交
1695
void initResultRow(SResultRow* pResultRow) {
X
Xiaoyu Wang 已提交
1696
  //  pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
1697 1698 1699 1700 1701
}

/*
 * 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 已提交
1702 1703 1704
 * +------------+-----------------result column 1------------+------------------result column 2-----------+
 * | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2|
 * +------------+--------------------------------------------+--------------------------------------------+
1705 1706
 *           offset[0]                                  offset[1]                                   offset[2]
 */
1707
// TODO refactor: some function move away
X
Xiaoyu Wang 已提交
1708 1709
void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, int32_t numOfExprs,
                             SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
1710 1711 1712
  SqlFunctionCtx* pCtx = pInfo->pCtx;
  SSDataBlock*    pDataBlock = pInfo->pRes;
  int32_t*        rowCellInfoOffset = pInfo->rowCellInfoOffset;
H
Haojun Liao 已提交
1713

H
Haojun Liao 已提交
1714
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
1715
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
1716

L
Liu Jicong 已提交
1717 1718
  int64_t     tid = 0;
  int64_t     groupId = 0;
1719 1720
  SResultRow* pRow = doSetResultOutBufByKey(pSup->pResultBuf, pResultRowInfo, (char*)&tid, sizeof(tid), true, groupId,
                                            pTaskInfo, false, pSup);
H
Haojun Liao 已提交
1721

1722
  for (int32_t i = 0; i < numOfExprs; ++i) {
H
Haojun Liao 已提交
1723 1724 1725
    struct SResultRowEntryInfo* pEntry = getResultCell(pRow, i, rowCellInfoOffset);
    cleanupResultRowEntry(pEntry);

L
Liu Jicong 已提交
1726
    pCtx[i].resultInfo = pEntry;
1727
    pCtx[i].scanFlag = stage;
H
Haojun Liao 已提交
1728 1729
  }

1730
  initCtxOutputBuffer(pCtx, numOfExprs);
H
Haojun Liao 已提交
1731 1732
}

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

L
Liu Jicong 已提交
1736
  int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5;  // extra output buffer
1737
  if ((*bufCapacity) < newSize) {
L
Liu Jicong 已提交
1738 1739
    for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
1740

wafwerar's avatar
wafwerar 已提交
1741
      char* p = taosMemoryRealloc(pColInfo->pData, newSize * pColInfo->info.bytes);
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
      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 已提交
1755
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
1756 1757 1758 1759
    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;
1760
#if 0
L
Liu Jicong 已提交
1761 1762
    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
        functionId == FUNCTION_DERIVATIVE) {
dengyihao's avatar
dengyihao 已提交
1763
      //      if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
1764
    }
1765
#endif
1766 1767 1768
  }
}

H
Haojun Liao 已提交
1769
void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size) {
1770 1771
  for (int32_t j = 0; j < size; ++j) {
    struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
dengyihao's avatar
dengyihao 已提交
1772 1773
    if (isRowEntryInitialized(pResInfo) || fmIsPseudoColumnFunc(pCtx[j].functionId) || pCtx[j].functionId == -1 ||
        fmIsScalarFunc(pCtx[j].functionId)) {
1774 1775 1776
      continue;
    }

H
Haojun Liao 已提交
1777
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
1778 1779 1780
  }
}

L
Liu Jicong 已提交
1781
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
1782
  if (status == TASK_NOT_COMPLETED) {
H
Haojun Liao 已提交
1783
    pTaskInfo->status = status;
1784 1785
  } else {
    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
1786
    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
1787
    pTaskInfo->status |= status;
1788 1789 1790
  }
}

L
Liu Jicong 已提交
1791
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
1792 1793 1794 1795
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
1796
  //  taosVariantDestroy(&pTableQueryInfo->tag);
dengyihao's avatar
dengyihao 已提交
1797
  //  cleanupResultRowInfo(&pTableQueryInfo->resInfo);
1798 1799
}

1800
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) {
1801 1802 1803 1804 1805 1806 1807
  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;
    }
1808 1809 1810 1811 1812

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

1813 1814 1815 1816 1817 1818
    if (!pResInfo->initialized) {
      if (pCtx[i].functionId != -1) {
        pCtx[i].fpSet.init(&pCtx[i], pResInfo);
      } else {
        pResInfo->initialized = true;
      }
1819 1820 1821 1822
    }
  }
}

1823
static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep);
1824 1825

void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
1826 1827 1828 1829 1830
  if (pFilterNode == NULL) {
    return;
  }

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

H
Haojun Liao 已提交
1832
  // todo move to the initialization function
H
Haojun Liao 已提交
1833
  int32_t code = filterInitFromNode((SNode*)pFilterNode, &filter, 0);
1834 1835 1836 1837 1838

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

  int8_t* rowRes = NULL;
1839

1840
  // todo the keep seems never to be True??
1841
  bool keep = filterExecute(filter, pBlock, &rowRes, NULL, param1.numOfCols);
D
dapan1121 已提交
1842
  filterFreeInfo(filter);
1843

1844
  extractQualifiedTupleByFilterResult(pBlock, rowRes, keep);
1845
  blockDataUpdateTsWindow(pBlock, 0);
1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856
}

void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep) {
  if (keep) {
    return;
  }

  if (rowRes != NULL) {
    SSDataBlock* px = createOneDataBlock(pBlock, false);
    blockDataEnsureCapacity(px, pBlock->info.rows);

1857 1858
    int32_t totalRows = pBlock->info.rows;

1859 1860 1861 1862
    for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
      SColumnInfoData* pDst = taosArrayGet(px->pDataBlock, i);
      SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, i);

1863 1864 1865 1866 1867
      // it is a reserved column for scalar function, and no data in this column yet.
      if (pSrc->pData == NULL) {
        continue;
      }

1868
      int32_t numOfRows = 0;
1869
      for (int32_t j = 0; j < totalRows; ++j) {
D
dapan1121 已提交
1870 1871 1872
        if (rowRes[j] == 0) {
          continue;
        }
1873

D
dapan1121 已提交
1874
        if (colDataIsNull_s(pSrc, j)) {
1875
          colDataAppendNULL(pDst, numOfRows);
D
dapan1121 已提交
1876
        } else {
1877
          colDataAppend(pDst, numOfRows, colDataGetData(pSrc, j), false);
D
dapan1121 已提交
1878
        }
1879
        numOfRows += 1;
H
Haojun Liao 已提交
1880
      }
1881

1882 1883 1884 1885 1886 1887
      if (pBlock->info.rows == totalRows) {
        pBlock->info.rows = numOfRows;
      } else {
        ASSERT(pBlock->info.rows == numOfRows);
      }

1888 1889 1890 1891 1892
      *pSrc = *pDst;
    }
  } else {
    // do nothing
    pBlock->info.rows = 0;
1893 1894 1895
  }
}

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

1901 1902
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
1903
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
1904

1905
  SResultRow* pResultRow = doSetResultOutBufByKey(pAggInfo->aggSup.pResultBuf, pResultRowInfo, (char*)&groupId,
L
Liu Jicong 已提交
1906
                                                  sizeof(groupId), true, groupId, pTaskInfo, false, &pAggInfo->aggSup);
L
Liu Jicong 已提交
1907
  assert(pResultRow != NULL);
1908 1909 1910 1911 1912 1913

  /*
   * 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 已提交
1914 1915
    int32_t ret =
        addNewWindowResultBuf(pResultRow, pAggInfo->aggSup.pResultBuf, groupId, pAggInfo->binfo.pRes->info.rowSize);
1916 1917 1918 1919 1920
    if (ret != TSDB_CODE_SUCCESS) {
      return;
    }
  }

1921
  setResultRowInitCtx(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
1922 1923
}

H
Haojun Liao 已提交
1924 1925
void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* pTaskInfo, SAggOperatorInfo* pAggInfo) {
  if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
1926 1927 1928
    return;
  }

H
Haojun Liao 已提交
1929
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, groupId, pTaskInfo);
1930 1931

  // record the current active group id
H
Haojun Liao 已提交
1932
  pAggInfo->groupId = groupId;
1933 1934
}

1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947
static void doUpdateNumOfRows(SResultRow* pRow, int32_t numOfExprs, const int32_t* rowCellOffset) {
  for (int32_t j = 0; j < numOfExprs; ++j) {
    struct SResultRowEntryInfo* pResInfo = getResultCell(pRow, j, rowCellOffset);
    if (!isRowEntryInitialized(pResInfo)) {
      continue;
    }

    if (pRow->numOfRows < pResInfo->numOfRes) {
      pRow->numOfRows = pResInfo->numOfRes;
    }
  }
}

X
Xiaoyu Wang 已提交
1948 1949 1950
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
                           SGroupResInfo* pGroupResInfo, const int32_t* rowCellOffset, SqlFunctionCtx* pCtx,
                           int32_t numOfExprs) {
1951
  int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
1952
  int32_t start = pGroupResInfo->index;
1953

1954
  for (int32_t i = start; i < numOfRows; i += 1) {
L
Liu Jicong 已提交
1955 1956
    SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
    SFilePage*  page = getBufPage(pBuf, pPos->pos.pageId);
1957

1958
    SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
1959 1960

    doUpdateNumOfRows(pRow, numOfExprs, rowCellOffset);
1961 1962
    if (pRow->numOfRows == 0) {
      pGroupResInfo->index += 1;
1963
      releaseBufPage(pBuf, page);
1964 1965 1966
      continue;
    }

1967 1968 1969 1970 1971
    if (pBlock->info.groupId == 0) {
      pBlock->info.groupId = pPos->groupId;
    } else {
      // current value belongs to different group, it can't be packed into one datablock
      if (pBlock->info.groupId != pPos->groupId) {
1972
        releaseBufPage(pBuf, page);
1973 1974 1975 1976
        break;
      }
    }

1977
    if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
1978
      releaseBufPage(pBuf, page);
1979 1980 1981 1982 1983
      break;
    }

    pGroupResInfo->index += 1;

1984
    for (int32_t j = 0; j < numOfExprs; ++j) {
1985 1986
      int32_t slotId = pExprInfo[j].base.resSchema.slotId;

1987
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
1988
      if (pCtx[j].fpSet.finalize) {
1989
        int32_t code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
1990
        if (TAOS_FAILED(code)) {
1991 1992
          qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
          longjmp(pTaskInfo->env, code);
1993
        }
1994 1995
      } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
        // do nothing, todo refactor
1996
      } else {
1997 1998
        // 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.
X
Xiaoyu Wang 已提交
1999 2000 2001 2002 2003
        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);
        }
2004
      }
2005 2006
    }

2007
    releaseBufPage(pBuf, page);
2008 2009
    pBlock->info.rows += pRow->numOfRows;
    if (pBlock->info.rows >= pBlock->info.capacity) {  // output buffer is full
2010 2011 2012 2013
      break;
    }
  }

X
Xiaoyu Wang 已提交
2014 2015
  qDebug("%s result generated, rows:%d, groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
         pBlock->info.groupId);
2016
  blockDataUpdateTsWindow(pBlock, 0);
2017 2018 2019
  return 0;
}

X
Xiaoyu Wang 已提交
2020 2021 2022 2023
void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
                            SDiskbasedBuf* pBuf) {
  SExprInfo*     pExprInfo = pOperator->pExpr;
  int32_t        numOfExprs = pOperator->numOfExprs;
2024 2025
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;

X
Xiaoyu Wang 已提交
2026 2027 2028
  int32_t*        rowCellOffset = pbInfo->rowCellInfoOffset;
  SSDataBlock*    pBlock = pbInfo->pRes;
  SqlFunctionCtx* pCtx = pbInfo->pCtx;
2029

2030
  blockDataCleanup(pBlock);
2031
  if (!hashRemainDataInGroupInfo(pGroupResInfo)) {
2032 2033 2034
    return;
  }

2035 2036
  // clear the existed group id
  pBlock->info.groupId = 0;
2037
  doCopyToSDataBlock(pTaskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, rowCellOffset, pCtx, numOfExprs);
2038 2039
}

L
Liu Jicong 已提交
2040 2041
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
                                        int32_t* rowCellInfoOffset) {
2042
  // update the number of result for each, only update the number of rows for the corresponding window result.
L
Liu Jicong 已提交
2043 2044 2045
  //  if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
  //    return;
  //  }
H
Haojun Liao 已提交
2046
#if 0
2047
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
L
Liu Jicong 已提交
2048
    SResultRow* pResult = pResultRowInfo->pResult[i];
2049 2050 2051 2052 2053 2054 2055

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

2056 2057
      SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
      pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
2058 2059
    }
  }
H
Haojun Liao 已提交
2060
#endif
2061 2062
}

L
Liu Jicong 已提交
2063
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
2064 2065
  int32_t colSize = pColRes->info.bytes * numOfRows;
  return (*(tDataTypes[pColRes->info.type].compFunc))(pColRes->pData, colSize, numOfRows, data,
L
Liu Jicong 已提交
2066
                                                      colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
2067 2068
}

2069
int32_t doFillTimeIntervalGapsInResults(struct SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t capacity) {
L
Liu Jicong 已提交
2070 2071 2072 2073
  //  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);
  //  }
2074

2075 2076
  int32_t numOfRows = (int32_t)taosFillResultDataBlock(pFillInfo, pBlock, capacity - pBlock->info.rows);
  pBlock->info.rows += numOfRows;
2077

2078
  return pBlock->info.rows;
2079 2080
}

L
Liu Jicong 已提交
2081 2082
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
2083

L
Liu Jicong 已提交
2084 2085 2086
  //  uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
  //  hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
  //  pSummary->hashSize = hashSize;
2087 2088 2089 2090

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

L
Liu Jicong 已提交
2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101
  //  SResultRowPool* p = pTaskInfo->pool;
  //  if (p != NULL) {
  //    pSummary->winInfoSize = getResultRowPoolMemSize(p);
  //    pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
  //  } else {
  //    pSummary->winInfoSize = 0;
  //    pSummary->numOfTimeWindows = 0;
  //  }
  //
  //  calculateOperatorProfResults(pQInfo);

2102 2103
  SFileBlockLoadRecorder* pRecorder = pSummary->pRecoder;
  if (pSummary->pRecoder != NULL) {
X
Xiaoyu Wang 已提交
2104 2105
    qDebug("%s :cost summary: elapsed time:%" PRId64 " us, first merge:%" PRId64
           " us, total blocks:%d, "
2106 2107 2108 2109
           "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 已提交
2110 2111 2112
  // 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);
2113 2114
}

L
Liu Jicong 已提交
2115 2116 2117
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
2118
//
L
Liu Jicong 已提交
2119
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2120
//
L
Liu Jicong 已提交
2121 2122 2123 2124
//   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;
//   }
2125
//
L
Liu Jicong 已提交
2126 2127 2128 2129 2130
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
//   } else {
//     pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
//   }
2131
//
L
Liu Jicong 已提交
2132
//   assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
2133
//
L
Liu Jicong 已提交
2134 2135
//   SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//   SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2136
//
L
Liu Jicong 已提交
2137 2138
//   // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
//   TSKEY *keys = (TSKEY *) pColInfoData->pData;
2139
//
L
Liu Jicong 已提交
2140 2141 2142
//   // update the offset value
//   pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
//   pQueryAttr->limit.offset = 0;
2143
//
L
Liu Jicong 已提交
2144
//   int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
2145
//
L
Liu Jicong 已提交
2146 2147 2148 2149
//   //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);
// }
2150

L
Liu Jicong 已提交
2151 2152
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2153
//
L
Liu Jicong 已提交
2154 2155 2156
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
//     return;
//   }
2157
//
L
Liu Jicong 已提交
2158 2159
//   pQueryAttr->pos = 0;
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2160
//
L
Liu Jicong 已提交
2161 2162
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//   TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
2163
//
L
Liu Jicong 已提交
2164 2165 2166 2167 2168
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pTsdbReadHandle)) {
//     if (isTaskKilled(pRuntimeEnv->qinfo)) {
//       longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
//     }
2169
//
L
Liu Jicong 已提交
2170
//     tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
2171
//
L
Liu Jicong 已提交
2172 2173 2174 2175
//     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;
2176
//
L
Liu Jicong 已提交
2177 2178 2179 2180 2181 2182 2183
//       //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;
//     }
//   }
2184
//
L
Liu Jicong 已提交
2185 2186 2187 2188 2189 2190 2191 2192 2193
//   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;
2194
//
L
Liu Jicong 已提交
2195 2196 2197
//   assert(pQueryAttr->limit.offset == 0);
//   STimeWindow tw = *win;
//   getNextTimeWindow(pQueryAttr, &tw);
2198
//
L
Liu Jicong 已提交
2199 2200
//   if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
//       (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
2201
//
L
Liu Jicong 已提交
2202 2203 2204 2205
//     // 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);
2206
//
L
Liu Jicong 已提交
2207 2208 2209 2210
//     tw = *win;
//     int32_t startPos =
//         getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
//     assert(startPos >= 0);
2211
//
L
Liu Jicong 已提交
2212 2213
//     // set the abort info
//     pQueryAttr->pos = startPos;
2214
//
L
Liu Jicong 已提交
2215 2216 2217 2218
//     // reset the query start timestamp
//     pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
//     pQueryAttr->window.skey = pTableQueryInfo->win.skey;
//     TSKEY key = pTableQueryInfo->win.skey;
2219
//
L
Liu Jicong 已提交
2220 2221
//     pWindowResInfo->prevSKey = tw.skey;
//     int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
2222
//
L
Liu Jicong 已提交
2223 2224
//     int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//     pRuntimeEnv->resultRowInfo.curIndex = index;  // restore the window index
2225
//
L
Liu Jicong 已提交
2226 2227 2228 2229
//     //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);
2230
//
L
Liu Jicong 已提交
2231 2232 2233 2234 2235
//     return key;
//   } else {  // do nothing
//     pQueryAttr->window.skey      = tw.skey;
//     pWindowResInfo->prevSKey = tw.skey;
//     pTableQueryInfo->lastKey = tw.skey;
2236
//
L
Liu Jicong 已提交
2237 2238
//     return tw.skey;
//   }
2239
//
L
Liu Jicong 已提交
2240 2241 2242 2243 2244 2245 2246 2247 2248 2249
//   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);
//   }
2250
//
L
Liu Jicong 已提交
2251 2252 2253 2254 2255
//   // 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;
//   }
2256
//
L
Liu Jicong 已提交
2257 2258 2259 2260 2261 2262 2263
//   /*
//    * 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);
2264
//
L
Liu Jicong 已提交
2265 2266
//   STimeWindow w = TSWINDOW_INITIALIZER;
//   bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2267
//
L
Liu Jicong 已提交
2268 2269
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//   STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
2270
//
L
Liu Jicong 已提交
2271 2272 2273
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
//     tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
2274
//
L
Liu Jicong 已提交
2275 2276 2277 2278 2279 2280 2281 2282 2283
//     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;
//     }
2284
//
L
Liu Jicong 已提交
2285 2286
//     // the first time window
//     STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
2287
//
L
Liu Jicong 已提交
2288 2289
//     while (pQueryAttr->limit.offset > 0) {
//       STimeWindow tw = win;
2290
//
L
Liu Jicong 已提交
2291 2292 2293
//       if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
//         pQueryAttr->limit.offset -= 1;
//         pWindowResInfo->prevSKey = win.skey;
2294
//
L
Liu Jicong 已提交
2295 2296 2297 2298 2299 2300
//         // 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;
//         }
//       }
2301
//
L
Liu Jicong 已提交
2302 2303 2304 2305
//       if (pQueryAttr->limit.offset == 0) {
//         *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//         return true;
//       }
2306
//
L
Liu Jicong 已提交
2307 2308
//       // current window does not ended in current data block, try next data block
//       getNextTimeWindow(pQueryAttr, &tw);
2309
//
L
Liu Jicong 已提交
2310 2311 2312 2313 2314 2315 2316 2317 2318
//       /*
//        * 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)) {
2319
//
L
Liu Jicong 已提交
2320 2321
//         SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//         SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2322
//
L
Liu Jicong 已提交
2323 2324 2325
//         if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
//           pQueryAttr->limit.offset -= 1;
//         }
2326
//
L
Liu Jicong 已提交
2327 2328 2329 2330 2331 2332 2333 2334
//         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);
2335
//
L
Liu Jicong 已提交
2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346
//           // 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.
//       }
//     }
//   }
2347
//
L
Liu Jicong 已提交
2348 2349 2350 2351
//   // check for error
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
2352
//
L
Liu Jicong 已提交
2353 2354
//   return true;
// }
2355

2356
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
H
Haojun Liao 已提交
2357
  if (p->pDownstream == NULL) {
H
Haojun Liao 已提交
2358
    assert(p->numOfDownstream == 0);
2359 2360
  }

wafwerar's avatar
wafwerar 已提交
2361
  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
2362 2363 2364 2365 2366 2367 2368
  if (p->pDownstream == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
2369 2370
}

wmmhello's avatar
wmmhello 已提交
2371
static void doDestroyTableList(STableListInfo* pTableqinfoList);
2372

2373
static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) {
H
Haojun Liao 已提交
2374 2375
#if 0
    if (order == TSDB_ORDER_ASC) {
2376 2377
    assert(
        (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
2378 2379
        (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey));
2380 2381 2382
  } else {
    assert(
        (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
2383 2384
        (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey));
2385
  }
H
Haojun Liao 已提交
2386
#endif
2387 2388
}

L
Liu Jicong 已提交
2389 2390 2391 2392
// 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;
2393
//
L
Liu Jicong 已提交
2394 2395 2396
//   if (pTableQueryInfo->pTable == NULL) {
//     return;
//   }
2397
//
L
Liu Jicong 已提交
2398 2399 2400 2401 2402 2403 2404 2405 2406
//   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));
//   }
// }
2407

2408
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
L
Liu Jicong 已提交
2409
  SSourceDataInfo* pSourceDataInfo = (SSourceDataInfo*)param;
H
Haojun Liao 已提交
2410 2411
  if (code == TSDB_CODE_SUCCESS) {
    pSourceDataInfo->pRsp = pMsg->pData;
2412

H
Haojun Liao 已提交
2413 2414
    SRetrieveTableRsp* pRsp = pSourceDataInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
dengyihao's avatar
dengyihao 已提交
2415
    pRsp->compLen = htonl(pRsp->compLen);
2416
    pRsp->numOfCols = htonl(pRsp->numOfCols);
dengyihao's avatar
dengyihao 已提交
2417
    pRsp->useconds = htobe64(pRsp->useconds);
H
Haojun Liao 已提交
2418 2419 2420
  } else {
    pSourceDataInfo->code = code;
  }
H
Haojun Liao 已提交
2421

H
Haojun Liao 已提交
2422
  pSourceDataInfo->status = EX_SOURCE_DATA_READY;
2423
  tsem_post(&pSourceDataInfo->pEx->ready);
wmmhello's avatar
wmmhello 已提交
2424
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
2425 2426 2427 2428
}

static void destroySendMsgInfo(SMsgSendInfo* pMsgBody) {
  assert(pMsgBody != NULL);
wafwerar's avatar
wafwerar 已提交
2429 2430
  taosMemoryFreeClear(pMsgBody->msgInfo.pData);
  taosMemoryFreeClear(pMsgBody);
H
Haojun Liao 已提交
2431 2432
}

S
Shengliang Guan 已提交
2433
void qProcessFetchRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
S
Shengliang Guan 已提交
2434 2435
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->info.ahandle;
  assert(pMsg->info.ahandle != NULL);
H
Haojun Liao 已提交
2436 2437 2438 2439

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

  if (pMsg->contLen > 0) {
wafwerar's avatar
wafwerar 已提交
2440
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
H
Haojun Liao 已提交
2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451
    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);
2452 2453
}

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

wafwerar's avatar
wafwerar 已提交
2457
  SResFetchReq* pMsg = taosMemoryCalloc(1, sizeof(SResFetchReq));
2458 2459 2460 2461
  if (NULL == pMsg) {
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
  }
2462

L
Liu Jicong 已提交
2463 2464
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
2465

L
Liu Jicong 已提交
2466 2467
  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);
2468 2469 2470 2471 2472 2473 2474

  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 已提交
2475
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
2476
  if (NULL == pMsgSendInfo) {
wafwerar's avatar
wafwerar 已提交
2477
    taosMemoryFreeClear(pMsg);
2478 2479 2480
    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 已提交
2481 2482
  }

2483 2484 2485 2486 2487
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
2488

2489
  int64_t transporterId = 0;
L
Liu Jicong 已提交
2490
  int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
2491 2492 2493
  return TSDB_CODE_SUCCESS;
}

2494
// NOTE: sources columns are more than the destination SSDatablock columns.
2495
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
2496 2497 2498
  size_t numOfSrcCols = taosArrayGetSize(pCols);

  int32_t i = 0, j = 0;
L
Liu Jicong 已提交
2499
  while (i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518
    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);
    }
  }
}

2519
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
dengyihao's avatar
dengyihao 已提交
2520 2521
                                  int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
                                  SArray* pColList) {
H
Haojun Liao 已提交
2522
  if (pColList == NULL) {  // data from other sources
2523
    blockCompressDecode(pRes, numOfOutput, numOfRows, pData);
H
Haojun Liao 已提交
2524
  } else {  // extract data according to pColList
2525
    ASSERT(numOfOutput == taosArrayGetSize(pColList));
2526 2527 2528 2529 2530
    char* pStart = pData;

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

2531
    // todo refactor:extract method
2532
    SSysTableSchema* pSchema = (SSysTableSchema*)pStart;
dengyihao's avatar
dengyihao 已提交
2533
    for (int32_t i = 0; i < numOfCols; ++i) {
2534 2535 2536 2537 2538 2539 2540
      SSysTableSchema* p = (SSysTableSchema*)pStart;

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

H
Haojun Liao 已提交
2541 2542 2543 2544
    SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
    pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
    pBlock->info.numOfCols = numOfCols;

dengyihao's avatar
dengyihao 已提交
2545
    for (int32_t i = 0; i < numOfCols; ++i) {
2546
      SColumnInfoData idata = {0};
2547

X
Xiaoyu Wang 已提交
2548
      idata.info.type = pSchema[i].type;
2549 2550
      idata.info.bytes = pSchema[i].bytes;
      idata.info.colId = pSchema[i].colId;
X
Xiaoyu Wang 已提交
2551
      idata.hasNull = true;
2552

H
Haojun Liao 已提交
2553
      taosArrayPush(pBlock->pDataBlock, &idata);
2554
      if (IS_VAR_DATA_TYPE(idata.info.type)) {
H
Haojun Liao 已提交
2555
        pBlock->info.hasVarCol = true;
2556 2557 2558
      }
    }

H
Haojun Liao 已提交
2559
    blockDataEnsureCapacity(pBlock, numOfRows);
2560

L
Liu Jicong 已提交
2561 2562
    int32_t  dataLen = *(int32_t*)pStart;
    uint64_t groupId = *(uint64_t*)(pStart + sizeof(int32_t));
2563 2564
    pStart += sizeof(int32_t) + sizeof(uint64_t);

L
Liu Jicong 已提交
2565
    int32_t* colLen = (int32_t*)(pStart);
2566 2567 2568 2569
    pStart += sizeof(int32_t) * numOfCols;

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

H
Haojun Liao 已提交
2572
      SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588
      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 已提交
2589 2590

    // data from mnode
H
Haojun Liao 已提交
2591 2592 2593
    relocateColumnData(pRes, pColList, pBlock->pDataBlock);
    taosArrayDestroy(pBlock->pDataBlock);
    taosMemoryFree(pBlock);
X
Xiaoyu Wang 已提交
2594
    //    blockDataDestroy(pBlock);
2595
  }
2596

H
Haojun Liao 已提交
2597
  pRes->info.rows = numOfRows;
2598 2599 2600

  // todo move this to time window aggregator, since the primary timestamp may not be known by exchange operator.
  blockDataUpdateTsWindow(pRes, 0);
2601

2602
  int64_t el = taosGetTimestampUs() - startTs;
2603

H
Haojun Liao 已提交
2604 2605
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
2606

H
Haojun Liao 已提交
2607 2608 2609
  if (total != NULL) {
    *total += numOfRows;
  }
2610

H
Haojun Liao 已提交
2611
  pLoadInfo->totalElapsed += el;
2612 2613
  return TSDB_CODE_SUCCESS;
}
2614

L
Liu Jicong 已提交
2615 2616
static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
2617
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
2618

2619
  int64_t              el = taosGetTimestampUs() - startTs;
H
Haojun Liao 已提交
2620
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
2621

H
Haojun Liao 已提交
2622
  pLoadInfo->totalElapsed += el;
H
Haojun Liao 已提交
2623

2624
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
L
Liu Jicong 已提交
2625 2626 2627
  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);
2628 2629 2630 2631 2632

  doSetOperatorCompleted(pOperator);
  return NULL;
}

L
Liu Jicong 已提交
2633 2634
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
                                                   SExecTaskInfo* pTaskInfo) {
2635 2636 2637 2638 2639 2640 2641 2642 2643
  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);

2644
      if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
2645
        completed += 1;
H
Haojun Liao 已提交
2646 2647
        continue;
      }
2648

2649
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
2650 2651 2652
        continue;
      }

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

L
Liu Jicong 已提交
2656
      SSDataBlock*         pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
2657
      SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
2658
      if (pRsp->numOfRows == 0) {
L
Liu Jicong 已提交
2659 2660
        qDebug("%s vgId:%d, taskID:0x%" PRIx64 " index:%d completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
               " try next",
2661
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, i + 1, pDataInfo->totalRows,
H
Haojun Liao 已提交
2662
               pExchangeInfo->loadInfo.totalRows);
2663
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
2664
        completed += 1;
D
dapan1121 已提交
2665
        taosMemoryFreeClear(pDataInfo->pRsp);
2666 2667
        continue;
      }
H
Haojun Liao 已提交
2668

H
Haojun Liao 已提交
2669
      SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
X
Xiaoyu Wang 已提交
2670 2671
      code = setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                       pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
2672
      if (code != 0) {
2673
        taosMemoryFreeClear(pDataInfo->pRsp);
2674 2675 2676
        goto _error;
      }

2677 2678 2679
      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 已提交
2680 2681
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
               pLoadInfo->totalRows, pLoadInfo->totalSize, i + 1, totalSources);
2682
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
2683
      } else {
dengyihao's avatar
dengyihao 已提交
2684 2685
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64
               ", totalBytes:%" PRIu64,
H
Haojun Liao 已提交
2686 2687
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
               pLoadInfo->totalSize);
2688 2689
      }

2690 2691
      if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED) {
        pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
2692 2693
        code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
        if (code != TSDB_CODE_SUCCESS) {
2694
          taosMemoryFreeClear(pDataInfo->pRsp);
2695 2696 2697 2698
          goto _error;
        }
      }

D
dapan1121 已提交
2699
      taosMemoryFreeClear(pDataInfo->pRsp);
2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712
      return pExchangeInfo->pResult;
    }

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

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

L
Liu Jicong 已提交
2713 2714 2715
static SSDataBlock* concurrentlyLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
2716

H
Haojun Liao 已提交
2717 2718 2719
  if (pOperator->status == OP_RES_TO_RETURN) {
    return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
  }
2720

L
Liu Jicong 已提交
2721
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
2722 2723 2724
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
2725
  for (int32_t i = 0; i < totalSources; ++i) {
2726 2727
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
2728
      return NULL;
2729 2730 2731 2732
    }
  }

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

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
2737 2738
  pOperator->status = OP_RES_TO_RETURN;
  return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
2739 2740
}

L
Liu Jicong 已提交
2741 2742 2743
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
2744

L
Liu Jicong 已提交
2745
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
2746 2747 2748
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
2749
  for (int32_t i = 0; i < totalSources; ++i) {
2750 2751
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
2752 2753
      pTaskInfo->code = code;
      return code;
2754 2755 2756 2757
    }
  }

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

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

H
Haojun Liao 已提交
2764
  return TSDB_CODE_SUCCESS;
2765 2766
}

L
Liu Jicong 已提交
2767 2768 2769
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
2770

L
Liu Jicong 已提交
2771
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
2772
  int64_t startTs = taosGetTimestampUs();
2773

L
Liu Jicong 已提交
2774
  while (1) {
2775 2776
    if (pExchangeInfo->current >= totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
2777
    }
2778

2779 2780 2781
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

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

H
Haojun Liao 已提交
2785
    if (pDataInfo->code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
dengyihao 已提交
2786 2787
      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 已提交
2788 2789 2790 2791
      pOperator->pTaskInfo->code = pDataInfo->code;
      return NULL;
    }

L
Liu Jicong 已提交
2792
    SRetrieveTableRsp*   pRsp = pDataInfo->pRsp;
H
Haojun Liao 已提交
2793
    SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
2794
    if (pRsp->numOfRows == 0) {
dengyihao's avatar
dengyihao 已提交
2795 2796
      qDebug("%s vgId:%d, taskID:0x%" PRIx64 " %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
             " try next",
2797
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
H
Haojun Liao 已提交
2798
             pDataInfo->totalRows, pLoadInfo->totalRows);
H
Haojun Liao 已提交
2799

2800
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
2801
      pExchangeInfo->current += 1;
D
dapan1121 已提交
2802
      taosMemoryFreeClear(pDataInfo->pRsp);
2803 2804
      continue;
    }
H
Haojun Liao 已提交
2805

L
Liu Jicong 已提交
2806
    SSDataBlock*       pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
2807
    SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
2808 2809
    int32_t            code =
        setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
2810
                                  pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
2811 2812

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

2818
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
2819 2820
      pExchangeInfo->current += 1;
    } else {
L
Liu Jicong 已提交
2821 2822 2823 2824
      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);
2825 2826
    }

2827
    pOperator->resultInfo.totalRows += pRes->info.rows;
2828
    taosMemoryFreeClear(pDataInfo->pRsp);
2829 2830
    return pExchangeInfo->pResult;
  }
2831 2832
}

L
Liu Jicong 已提交
2833
static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
2834
  if (OPTR_IS_OPENED(pOperator)) {
H
Haojun Liao 已提交
2835 2836 2837
    return TSDB_CODE_SUCCESS;
  }

2838 2839
  int64_t st = taosGetTimestampUs();

L
Liu Jicong 已提交
2840
  SExchangeInfo* pExchangeInfo = pOperator->info;
2841
  if (!pExchangeInfo->seqLoadData) {
H
Haojun Liao 已提交
2842 2843 2844 2845 2846 2847
    int32_t code = prepareConcurrentlyLoad(pOperator);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

2848
  OPTR_SET_OPENED(pOperator);
2849
  pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0;
H
Haojun Liao 已提交
2850 2851 2852
  return TSDB_CODE_SUCCESS;
}

2853
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
2854 2855
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
2856

2857
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
2858
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
2859 2860
    return NULL;
  }
2861

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

2865
  if (pOperator->status == OP_EXEC_DONE) {
L
Liu Jicong 已提交
2866 2867 2868
    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);
2869 2870 2871 2872 2873 2874
    return NULL;
  }

  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
2875
    return concurrentlyLoadRemoteData(pOperator);
2876
  }
H
Haojun Liao 已提交
2877
}
2878

H
Haojun Liao 已提交
2879
static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
2880
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
H
Haojun Liao 已提交
2881 2882
  if (pInfo->pSourceDataInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
2883 2884
  }

L
Liu Jicong 已提交
2885
  for (int32_t i = 0; i < numOfSources; ++i) {
2886
    SSourceDataInfo dataInfo = {0};
H
Haojun Liao 已提交
2887
    dataInfo.status = EX_SOURCE_DATA_NOT_READY;
L
Liu Jicong 已提交
2888 2889
    dataInfo.pEx = pInfo;
    dataInfo.index = i;
2890

H
Haojun Liao 已提交
2891 2892 2893 2894 2895 2896 2897 2898 2899 2900
    void* ret = taosArrayPush(pInfo->pSourceDataInfo, &dataInfo);
    if (ret == NULL) {
      taosArrayDestroy(pInfo->pSourceDataInfo);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
2901
SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, const SNodeList* pSources, SSDataBlock* pBlock,
2902
                                          SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
2903
  SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
wafwerar's avatar
wafwerar 已提交
2904
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
2905
  if (pInfo == NULL || pOperator == NULL) {
2906
    goto _error;
H
Haojun Liao 已提交
2907 2908
  }

H
Haojun Liao 已提交
2909
  size_t numOfSources = LIST_LENGTH(pSources);
H
Haojun Liao 已提交
2910
  pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
H
Haojun Liao 已提交
2911 2912 2913
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
  if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
    goto _error;
H
Haojun Liao 已提交
2914 2915
  }

L
Liu Jicong 已提交
2916 2917
  for (int32_t i = 0; i < numOfSources; ++i) {
    SNodeListNode* pNode = nodesListGetNode((SNodeList*)pSources, i);
H
Haojun Liao 已提交
2918 2919
    taosArrayPush(pInfo->pSources, pNode);
  }
2920

H
Haojun Liao 已提交
2921 2922 2923
  int32_t code = initDataSource(numOfSources, pInfo);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
2924
  }
H
Haojun Liao 已提交
2925

dengyihao's avatar
dengyihao 已提交
2926
  pInfo->pResult = pBlock;
2927 2928 2929
  pInfo->seqLoadData = true;

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

2931
  pOperator->name = "ExchangeOperator";
X
Xiaoyu Wang 已提交
2932
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
2933 2934 2935 2936 2937
  pOperator->blocking = false;
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfExprs = pBlock->info.numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
2938

L
Liu Jicong 已提交
2939 2940
  pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
                                         destroyExchangeOperatorInfo, NULL, NULL, NULL);
2941
  pInfo->pTransporter = pTransporter;
2942
  return pOperator;
H
Haojun Liao 已提交
2943

L
Liu Jicong 已提交
2944
_error:
H
Haojun Liao 已提交
2945
  if (pInfo != NULL) {
H
Haojun Liao 已提交
2946
    destroyExchangeOperatorInfo(pInfo, numOfSources);
H
Haojun Liao 已提交
2947 2948
  }

wafwerar's avatar
wafwerar 已提交
2949 2950
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
2951
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
2952
  return NULL;
2953 2954
}

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

2958
static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
2959
  SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*)param;
H
Haojun Liao 已提交
2960
  taosArrayDestroy(pInfo->pSortInfo);
2961 2962 2963
  taosArrayDestroy(pInfo->groupInfo);

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
2964
    tsortDestroySortHandle(pInfo->pSortHandle);
2965 2966
  }

H
Haojun Liao 已提交
2967
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
2968
  cleanupAggSup(&pInfo->aggSup);
2969
}
H
Haojun Liao 已提交
2970

L
Liu Jicong 已提交
2971
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
2972 2973 2974 2975
  size_t size = taosArrayGetSize(groupInfo);
  if (size == 0) {
    return true;
  }
2976

2977 2978
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
2979

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

2983 2984 2985
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
2986

2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999
    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;
      }
3000 3001 3002
    }
  }

3003
  return 0;
3004 3005
}

L
Liu Jicong 已提交
3006 3007 3008
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
X
Xiaoyu Wang 已提交
3009
                                             //    pCtx[j].startRow = rowIndex;
3010 3011
  }

3012 3013
  for (int32_t j = 0; j < numOfExpr; ++j) {
    int32_t functionId = pCtx[j].functionId;
L
Liu Jicong 已提交
3014 3015 3016 3017 3018 3019 3020 3021 3022
    //    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]);
    //    }
3023
  }
3024
}
3025

L
Liu Jicong 已提交
3026 3027
static void doFinalizeResultImpl(SqlFunctionCtx* pCtx, int32_t numOfExpr) {
  for (int32_t j = 0; j < numOfExpr; ++j) {
3028 3029 3030 3031
    int32_t functionId = pCtx[j].functionId;
    //    if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
    //      continue;
    //    }
3032

3033 3034 3035 3036
    //    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 已提交
3037
    //    pCtx[j].fpSet.finalize(&pCtx[j]);
3038 3039
  }
}
3040

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

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

3048 3049 3050
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
3051

3052 3053
  return true;
}
3054

3055 3056
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
3057

3058
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
L
Liu Jicong 已提交
3059
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
X
Xiaoyu Wang 已提交
3060
    //    pCtx[i].size = 1;
3061
  }
3062

L
Liu Jicong 已提交
3063
  for (int32_t i = 0; i < pBlock->info.rows; ++i) {
3064 3065 3066 3067 3068 3069 3070 3071 3072
    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);
3073 3074
        int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
        //        setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
3075

3076
        // TODO check for available buffer;
H
Haojun Liao 已提交
3077

3078 3079 3080 3081 3082
        // next group info data
        pInfo->binfo.pRes->info.rows += numOfRows;
        for (int32_t j = 0; j < numOfExpr; ++j) {
          if (pCtx[j].functionId < 0) {
            continue;
3083
          }
3084

H
Haojun Liao 已提交
3085
          pCtx[j].fpSet.process(&pCtx[j]);
3086
        }
3087 3088 3089

        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
        pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
H
Haojun Liao 已提交
3090
      }
3091 3092 3093 3094
    }
  }
}

3095 3096
static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
3097
  SSortHandle*              pHandle = pInfo->pSortHandle;
3098

3099
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes, false);
3100
  blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
3101

L
Liu Jicong 已提交
3102
  while (1) {
3103
    blockDataCleanup(pDataBlock);
3104
    while (1) {
H
Haojun Liao 已提交
3105
      STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
3106 3107
      if (pTupleHandle == NULL) {
        break;
3108
      }
3109

3110 3111
      // build datablock for merge for one group
      appendOneRowToDataBlock(pDataBlock, pTupleHandle);
3112
      if (pDataBlock->info.rows >= pOperator->resultInfo.capacity) {
3113 3114
        break;
      }
3115
    }
3116

3117 3118 3119
    if (pDataBlock->info.rows == 0) {
      break;
    }
3120

3121
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
L
Liu Jicong 已提交
3122 3123
    //  updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
    //  pOperator->pRuntimeEnv, true);
3124
    doMergeImpl(pOperator, pOperator->numOfExprs, pDataBlock);
3125 3126
    // flush to tuple store, and after all data have been handled, return to upstream node or sink node
  }
3127

3128 3129 3130
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfExprs);
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
3131

3132
  // TODO check for available buffer;
3133

3134 3135
  // next group info data
  pInfo->binfo.pRes->info.rows += numOfRows;
L
Liu Jicong 已提交
3136
  return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
3137
}
3138

3139
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
3140 3141
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
3142 3143
  }

L
Liu Jicong 已提交
3144
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
3145
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
3146
  if (pOperator->status == OP_RES_TO_RETURN) {
3147
    return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity, NULL);
3148 3149
  }

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

3154
  tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL);
3155

L
Liu Jicong 已提交
3156
  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
wmmhello's avatar
wmmhello 已提交
3157
    SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
H
Haojun Liao 已提交
3158
    ps->param = pOperator->pDownstream[i];
H
Haojun Liao 已提交
3159
    tsortAddSource(pInfo->pSortHandle, ps);
3160 3161
  }

H
Haojun Liao 已提交
3162
  int32_t code = tsortOpen(pInfo->pSortHandle);
3163
  if (code != TSDB_CODE_SUCCESS) {
3164
    longjmp(pTaskInfo->env, terrno);
3165 3166
  }

H
Haojun Liao 已提交
3167
  pOperator->status = OP_RES_TO_RETURN;
3168
  return doMerge(pOperator);
3169
}
3170

L
Liu Jicong 已提交
3171 3172
static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo,
                            SSortedMergeOperatorInfo* pInfo) {
3173 3174
  if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) {
    return 0;
H
Haojun Liao 已提交
3175 3176
  }

3177 3178 3179 3180 3181 3182 3183 3184
  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 已提交
3185 3186
  size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo);
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
3187
    SColumn* pCol = taosArrayGet(pGroupInfo, i);
L
Liu Jicong 已提交
3188
    for (int32_t j = 0; j < numOfCols; ++j) {
H
Haojun Liao 已提交
3189
      SExprInfo* pe = &pExprInfo[j];
3190
      if (pe->base.resSchema.slotId == pCol->colId) {
3191 3192
        taosArrayPush(plist, pCol);
        taosArrayPush(pInfo->groupInfo, &j);
H
Haojun Liao 已提交
3193
        len += pCol->bytes;
3194 3195
        break;
      }
H
Haojun Liao 已提交
3196 3197 3198
    }
  }

3199
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
3200

wafwerar's avatar
wafwerar 已提交
3201
  pInfo->groupVal = taosMemoryCalloc(1, (POINTER_BYTES * numOfGroupCol + len));
3202 3203 3204 3205
  if (pInfo->groupVal == NULL) {
    taosArrayDestroy(plist);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
3206

3207
  int32_t offset = 0;
L
Liu Jicong 已提交
3208 3209
  char*   start = (char*)(pInfo->groupVal + (POINTER_BYTES * numOfGroupCol));
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
3210 3211
    pInfo->groupVal[i] = start + offset;
    SColumn* pCol = taosArrayGet(plist, i);
H
Haojun Liao 已提交
3212
    offset += pCol->bytes;
3213
  }
H
Haojun Liao 已提交
3214

3215
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
3216

3217 3218
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
3219

L
Liu Jicong 已提交
3220 3221 3222
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                             int32_t num, SArray* pSortInfo, SArray* pGroupInfo,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
3223
  SSortedMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortedMergeOperatorInfo));
L
Liu Jicong 已提交
3224
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
3225
  if (pInfo == NULL || pOperator == NULL) {
3226
    goto _error;
3227
  }
H
Haojun Liao 已提交
3228

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

3232 3233 3234
  if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
3235

dengyihao's avatar
dengyihao 已提交
3236
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
3237
  int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, keyBufSize, pTaskInfo->id.str);
3238 3239 3240
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
3241

H
Haojun Liao 已提交
3242
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, num, pTaskInfo);
H
Haojun Liao 已提交
3243
  code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo);
3244 3245 3246
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
3247

L
Liu Jicong 已提交
3248 3249 3250 3251 3252
  //  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 已提交
3253

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

L
Liu Jicong 已提交
3256
  pOperator->name = "SortedMerge";
X
Xiaoyu Wang 已提交
3257
  // pOperator->operatorType = OP_SortedMerge;
3258
  pOperator->blocking = true;
L
Liu Jicong 已提交
3259 3260
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
3261
  pOperator->numOfExprs = num;
L
Liu Jicong 已提交
3262
  pOperator->pExpr = pExprInfo;
H
Haojun Liao 已提交
3263

L
Liu Jicong 已提交
3264
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
3265

3266 3267
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSortedMerge, NULL, NULL, destroySortedMergeOperatorInfo,
                                         NULL, NULL, NULL);
3268 3269 3270
  code = appendDownstream(pOperator, downstream, numOfDownstream);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
3271
  }
H
Haojun Liao 已提交
3272

3273
  return pOperator;
H
Haojun Liao 已提交
3274

L
Liu Jicong 已提交
3275
_error:
3276
  if (pInfo != NULL) {
H
Haojun Liao 已提交
3277
    destroySortedMergeOperatorInfo(pInfo, num);
H
Haojun Liao 已提交
3278 3279
  }

wafwerar's avatar
wafwerar 已提交
3280 3281
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
3282 3283
  terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
  return NULL;
H
Haojun Liao 已提交
3284 3285
}

X
Xiaoyu Wang 已提交
3286
int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scanFlag) {
3287
  // todo add more information about exchange operation
3288
  int32_t type = pOperator->operatorType;
X
Xiaoyu Wang 已提交
3289
  if (type == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE || type == QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN ||
3290
      type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN) {
3291 3292 3293
    *order = TSDB_ORDER_ASC;
    *scanFlag = MAIN_SCAN;
    return TSDB_CODE_SUCCESS;
3294
  } else if (type == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
3295 3296 3297 3298 3299
    STableScanInfo* pTableScanInfo = pOperator->info;
    *order = pTableScanInfo->cond.order;
    *scanFlag = pTableScanInfo->scanFlag;
    return TSDB_CODE_SUCCESS;
  } else {
H
Haojun Liao 已提交
3300
    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
3301
      return TSDB_CODE_INVALID_PARA;
H
Haojun Liao 已提交
3302
    } else {
3303
      return getTableScanInfo(pOperator->pDownstream[0], order, scanFlag);
3304 3305 3306
    }
  }
}
3307 3308

// this is a blocking operator
L
Liu Jicong 已提交
3309
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
3310 3311
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
3312 3313
  }

H
Haojun Liao 已提交
3314
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
3315
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
3316

dengyihao's avatar
dengyihao 已提交
3317
  SOptrBasicInfo* pInfo = &pAggInfo->binfo;
X
Xiaoyu Wang 已提交
3318
  SOperatorInfo*  downstream = pOperator->pDownstream[0];
3319

3320 3321
  int64_t st = taosGetTimestampUs();

3322 3323 3324
  int32_t order = TSDB_ORDER_ASC;
  int32_t scanFlag = MAIN_SCAN;

H
Haojun Liao 已提交
3325
  while (1) {
3326
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
3327 3328 3329 3330
    if (pBlock == NULL) {
      break;
    }

3331 3332 3333 3334
    int32_t code = getTableScanInfo(pOperator, &order, &scanFlag);
    if (code != TSDB_CODE_SUCCESS) {
      longjmp(pTaskInfo->env, code);
    }
3335

3336 3337
    // there is an scalar expression that needs to be calculated before apply the group aggregation.
    if (pAggInfo->pScalarExprInfo != NULL) {
3338
      code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx,
3339
                                   pAggInfo->numOfScalarExpr, NULL);
3340
      if (code != TSDB_CODE_SUCCESS) {
3341
        longjmp(pTaskInfo->env, code);
3342
      }
3343 3344
    }

3345
    // the pDataBlock are always the same one, no need to call this again
3346
    setExecutionContext(pOperator->numOfExprs, pBlock->info.groupId, pTaskInfo, pAggInfo);
3347
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, true);
3348 3349 3350 3351
    code = doAggregateImpl(pOperator, 0, pInfo->pCtx);
    if (code != 0) {
      longjmp(pTaskInfo->env, code);
    }
3352

dengyihao's avatar
dengyihao 已提交
3353
#if 0  // test for encode/decode result info
3354
    if(pOperator->fpSet.encodeResultRow){
3355 3356
      char *result = NULL;
      int32_t length = 0;
3357 3358
      pOperator->fpSet.encodeResultRow(pOperator, &result, &length);
      SAggSupporter* pSup = &pAggInfo->aggSup;
3359 3360
      taosHashClear(pSup->pResultRowHashTable);
      pInfo->resultRowInfo.size = 0;
3361
      pOperator->fpSet.decodeResultRow(pOperator, result);
3362 3363 3364
      if(result){
        taosMemoryFree(result);
      }
3365
    }
3366
#endif
3367 3368
  }

H
Haojun Liao 已提交
3369
  closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
3370
  initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, 0);
H
Haojun Liao 已提交
3371
  OPTR_SET_OPENED(pOperator);
3372

3373
  pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0;
H
Haojun Liao 已提交
3374 3375 3376
  return TSDB_CODE_SUCCESS;
}

3377
static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
3378
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
3379 3380 3381 3382 3383 3384
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;

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

L
Liu Jicong 已提交
3385
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3386
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
H
Haojun Liao 已提交
3387
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
3388
    doSetOperatorCompleted(pOperator);
H
Haojun Liao 已提交
3389 3390 3391
    return NULL;
  }

H
Haojun Liao 已提交
3392
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
3393
  doBuildResultDatablock(pOperator, pInfo, &pAggInfo->groupResInfo, pAggInfo->aggSup.pResultBuf);
3394
  if (pInfo->pRes->info.rows == 0 || !hashRemainDataInGroupInfo(&pAggInfo->groupResInfo)) {
H
Haojun Liao 已提交
3395 3396
    doSetOperatorCompleted(pOperator);
  }
3397

3398
  size_t rows = blockDataGetNumOfRows(pInfo->pRes);  // pInfo->pRes : NULL;
3399 3400
  pOperator->resultInfo.totalRows += rows;

3401
  return (rows == 0) ? NULL : pInfo->pRes;
3402 3403
}

wmmhello's avatar
wmmhello 已提交
3404
int32_t aggEncodeResultRow(SOperatorInfo* pOperator, char** result, int32_t* length) {
3405
  if (result == NULL || length == NULL) {
wmmhello's avatar
wmmhello 已提交
3406 3407 3408
    return TSDB_CODE_TSC_INVALID_INPUT;
  }
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)(pOperator->info);
3409 3410 3411 3412 3413
  SAggSupporter*  pSup = (SAggSupporter*)POINTER_SHIFT(pOperator->info, sizeof(SOptrBasicInfo));
  int32_t         size = taosHashGetSize(pSup->pResultRowHashTable);
  size_t          keyLen = sizeof(uint64_t) * 2;  // estimate the key length
  int32_t         totalSize =
      sizeof(int32_t) + sizeof(int32_t) + size * (sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize);
wmmhello's avatar
wmmhello 已提交
3414

wmmhello's avatar
wmmhello 已提交
3415
  *result = (char*)taosMemoryCalloc(1, totalSize);
L
Liu Jicong 已提交
3416
  if (*result == NULL) {
wmmhello's avatar
wmmhello 已提交
3417
    return TSDB_CODE_OUT_OF_MEMORY;
wmmhello's avatar
wmmhello 已提交
3418
  }
wmmhello's avatar
wmmhello 已提交
3419

wmmhello's avatar
wmmhello 已提交
3420
  int32_t offset = sizeof(int32_t);
wmmhello's avatar
wmmhello 已提交
3421 3422
  *(int32_t*)(*result + offset) = size;
  offset += sizeof(int32_t);
3423 3424

  // prepare memory
3425
  SResultRowPosition* pos = &pInfo->resultRowInfo.cur;
dengyihao's avatar
dengyihao 已提交
3426 3427
  void*               pPage = getBufPage(pSup->pResultBuf, pos->pageId);
  SResultRow*         pRow = (SResultRow*)((char*)pPage + pos->offset);
3428 3429 3430
  setBufPageDirty(pPage, true);
  releaseBufPage(pSup->pResultBuf, pPage);

dengyihao's avatar
dengyihao 已提交
3431
  void* pIter = taosHashIterate(pSup->pResultRowHashTable, NULL);
wmmhello's avatar
wmmhello 已提交
3432
  while (pIter) {
dengyihao's avatar
dengyihao 已提交
3433
    void*               key = taosHashGetKey(pIter, &keyLen);
3434
    SResultRowPosition* p1 = (SResultRowPosition*)pIter;
3435

dengyihao's avatar
dengyihao 已提交
3436
    pPage = (SFilePage*)getBufPage(pSup->pResultBuf, p1->pageId);
3437
    pRow = (SResultRow*)((char*)pPage + p1->offset);
3438 3439
    setBufPageDirty(pPage, true);
    releaseBufPage(pSup->pResultBuf, pPage);
wmmhello's avatar
wmmhello 已提交
3440 3441 3442

    // recalculate the result size
    int32_t realTotalSize = offset + sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize;
L
Liu Jicong 已提交
3443
    if (realTotalSize > totalSize) {
wmmhello's avatar
wmmhello 已提交
3444
      char* tmp = (char*)taosMemoryRealloc(*result, realTotalSize);
L
Liu Jicong 已提交
3445
      if (tmp == NULL) {
wafwerar's avatar
wafwerar 已提交
3446
        taosMemoryFree(*result);
wmmhello's avatar
wmmhello 已提交
3447
        *result = NULL;
wmmhello's avatar
wmmhello 已提交
3448
        return TSDB_CODE_OUT_OF_MEMORY;
L
Liu Jicong 已提交
3449
      } else {
wmmhello's avatar
wmmhello 已提交
3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461
        *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);
3462
    memcpy(*result + offset, pRow, pSup->resultRowSize);
wmmhello's avatar
wmmhello 已提交
3463 3464 3465 3466 3467
    offset += pSup->resultRowSize;

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

wmmhello's avatar
wmmhello 已提交
3468 3469 3470 3471
  *(int32_t*)(*result) = offset;
  *length = offset;

  return TDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
3472 3473
}

3474
int32_t aggDecodeResultRow(SOperatorInfo* pOperator, char* result) {
3475
  if (result == NULL) {
wmmhello's avatar
wmmhello 已提交
3476
    return TSDB_CODE_TSC_INVALID_INPUT;
wmmhello's avatar
wmmhello 已提交
3477
  }
wmmhello's avatar
wmmhello 已提交
3478
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)(pOperator->info);
3479
  SAggSupporter*  pSup = (SAggSupporter*)POINTER_SHIFT(pOperator->info, sizeof(SOptrBasicInfo));
wmmhello's avatar
wmmhello 已提交
3480 3481

  //  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
3482
  int32_t length = *(int32_t*)(result);
wmmhello's avatar
wmmhello 已提交
3483
  int32_t offset = sizeof(int32_t);
3484 3485 3486 3487

  int32_t count = *(int32_t*)(result + offset);
  offset += sizeof(int32_t);

L
Liu Jicong 已提交
3488
  while (count-- > 0 && length > offset) {
wmmhello's avatar
wmmhello 已提交
3489 3490 3491
    int32_t keyLen = *(int32_t*)(result + offset);
    offset += sizeof(int32_t);

L
Liu Jicong 已提交
3492
    uint64_t    tableGroupId = *(uint64_t*)(result + offset);
3493
    SResultRow* resultRow = getNewResultRow(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
L
Liu Jicong 已提交
3494
    if (!resultRow) {
wmmhello's avatar
wmmhello 已提交
3495
      return TSDB_CODE_TSC_INVALID_INPUT;
wmmhello's avatar
wmmhello 已提交
3496
    }
3497

wmmhello's avatar
wmmhello 已提交
3498
    // add a new result set for a new group
3499 3500
    SResultRowPosition pos = {.pageId = resultRow->pageId, .offset = resultRow->offset};
    taosHashPut(pSup->pResultRowHashTable, result + offset, keyLen, &pos, sizeof(SResultRowPosition));
wmmhello's avatar
wmmhello 已提交
3501 3502 3503

    offset += keyLen;
    int32_t valueLen = *(int32_t*)(result + offset);
L
Liu Jicong 已提交
3504
    if (valueLen != pSup->resultRowSize) {
wmmhello's avatar
wmmhello 已提交
3505
      return TSDB_CODE_TSC_INVALID_INPUT;
wmmhello's avatar
wmmhello 已提交
3506 3507 3508 3509 3510 3511 3512 3513 3514 3515
    }
    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);
dengyihao's avatar
dengyihao 已提交
3516
    pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
wmmhello's avatar
wmmhello 已提交
3517 3518
  }

L
Liu Jicong 已提交
3519
  if (offset != length) {
wmmhello's avatar
wmmhello 已提交
3520
    return TSDB_CODE_TSC_INVALID_INPUT;
wmmhello's avatar
wmmhello 已提交
3521
  }
wmmhello's avatar
wmmhello 已提交
3522
  return TDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
3523 3524
}

3525 3526
enum {
  PROJECT_RETRIEVE_CONTINUE = 0x1,
L
Liu Jicong 已提交
3527
  PROJECT_RETRIEVE_DONE = 0x2,
3528 3529 3530 3531 3532
};

static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
L
Liu Jicong 已提交
3533
  SSDataBlock*          pRes = pInfo->pRes;
3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581

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

3582 3583 3584
  // 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);
3585 3586 3587 3588 3589

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

3590
    return PROJECT_RETRIEVE_DONE;
3591
  }
3592

3593
  // todo optimize performance
3594 3595
  // 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 已提交
3596 3597
  if (pRes->info.rows >= pOperator->resultInfo.threshold || pProjectInfo->slimit.offset != -1 ||
      pProjectInfo->slimit.limit != -1) {
3598
    return PROJECT_RETRIEVE_DONE;
L
Liu Jicong 已提交
3599
  } else {  // not full enough, continue to accumulate the output data in the buffer.
3600 3601 3602 3603
    return PROJECT_RETRIEVE_CONTINUE;
  }
}

3604
static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
3605
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
L
Liu Jicong 已提交
3606
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
3607 3608

  SSDataBlock* pRes = pInfo->pRes;
3609
  blockDataCleanup(pRes);
3610

3611
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3612 3613 3614
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }
dengyihao's avatar
dengyihao 已提交
3615

H
Haojun Liao 已提交
3616
#if 0
3617 3618 3619 3620 3621
  if (pProjectInfo->existDataBlock) {  // TODO refactor
    SSDataBlock* pBlock = pProjectInfo->existDataBlock;
    pProjectInfo->existDataBlock = NULL;

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

H
Haojun Liao 已提交
3624
    blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
3625
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs);
L
Liu Jicong 已提交
3626
    if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
3627 3628
      copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfExprs);
      resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfExprs);
3629 3630 3631
      return pRes;
    }
  }
H
Haojun Liao 已提交
3632
#endif
3633

3634
  int64_t st = 0;
3635 3636 3637
  int32_t order = 0;
  int32_t scanFlag = 0;

3638 3639 3640 3641
  if (pOperator->cost.openCost == 0) {
    st = taosGetTimestampUs();
  }

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

L
Liu Jicong 已提交
3644
  while (1) {
H
Haojun Liao 已提交
3645
    // The downstream exec may change the value of the newgroup, so use a local variable instead.
3646
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
3647
    if (pBlock == NULL) {
3648
      doSetOperatorCompleted(pOperator);
3649 3650 3651
      break;
    }

3652
#if 0
3653
    // Return result of the previous group in the firstly.
3654
    if (false) {
3655 3656 3657
      if (pRes->info.rows > 0) {
        pProjectInfo->existDataBlock = pBlock;
        break;
L
Liu Jicong 已提交
3658
      } else {  // init output buffer for a new group data
3659
        initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfExprs);
3660 3661
      }
    }
3662
#endif
3663 3664

    // the pDataBlock are always the same one, no need to call this again
3665
    int32_t code = getTableScanInfo(pOperator->pDownstream[0], &order, &scanFlag);
3666 3667 3668
    if (code != TSDB_CODE_SUCCESS) {
      longjmp(pTaskInfo->env, code);
    }
3669

3670 3671
    doFilter(pProjectInfo->pFilterNode, pBlock);

3672
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, false);
3673 3674
    blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);

X
Xiaoyu Wang 已提交
3675 3676
    code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs,
                                 pProjectInfo->pPseudoColInfo);
3677 3678
    if (code != TSDB_CODE_SUCCESS) {
      longjmp(pTaskInfo->env, code);
3679 3680
    }

3681 3682
    int32_t status = handleLimitOffset(pOperator, pBlock);
    if (status == PROJECT_RETRIEVE_CONTINUE) {
H
Haojun Liao 已提交
3683
      continue;
L
Liu Jicong 已提交
3684
    } else if (status == PROJECT_RETRIEVE_DONE) {
3685 3686 3687
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
3688

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

3691 3692 3693 3694
  size_t rows = pInfo->pRes->info.rows;
  pOperator->resultInfo.totalRows += rows;

  if (pOperator->cost.openCost == 0) {
3695
    pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0;
3696 3697
  }

3698
  return (rows > 0) ? pInfo->pRes : NULL;
3699 3700
}

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

L
Liu Jicong 已提交
3705 3706
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
3707 3708
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

3709
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
3710 3711
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

3712
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity);
3713 3714 3715 3716
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
3717 3718
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
3719 3720
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
3721
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity);
H
Haojun Liao 已提交
3722
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
3723 3724 3725 3726 3727 3728
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
3729
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
3730 3731 3732
  }
}

3733
static SSDataBlock* doFill(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
3734 3735
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
3736

H
Haojun Liao 已提交
3737
  SResultInfo* pResultInfo = &pOperator->resultInfo;
3738 3739 3740
  SSDataBlock* pResBlock = pInfo->pRes;

  blockDataCleanup(pResBlock);
3741 3742 3743 3744
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

3745
  // todo handle different group data interpolation
X
Xiaoyu Wang 已提交
3746 3747
  bool  n = false;
  bool* newgroup = &n;
3748
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
3749 3750
  if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
    return pResBlock;
H
Haojun Liao 已提交
3751
  }
3752

H
Haojun Liao 已提交
3753
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
3754
  while (1) {
3755
    SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream);
3756 3757 3758 3759 3760 3761 3762 3763 3764 3765
    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
3766
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
3767 3768 3769 3770 3771 3772 3773
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

3774
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
3775 3776 3777 3778 3779 3780 3781
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

3782 3783
    blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity);
3784 3785

    // current group has no more result to return
3786
    if (pResBlock->info.rows > 0) {
3787 3788
      // 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
3789 3790
      if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
        return pResBlock;
3791 3792
      }

3793
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
3794 3795
      if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
        return pResBlock;
3796 3797 3798
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
3799
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
3800 3801
      if (pResBlock->info.rows > pResultInfo->threshold) {
        return pResBlock;
3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813
      }
    } else {
      return NULL;
    }
  }
}

static void destroyOperatorInfo(SOperatorInfo* pOperator) {
  if (pOperator == NULL) {
    return;
  }

3814
  if (pOperator->fpSet.closeFn != NULL) {
3815
    pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfExprs);
3816 3817
  }

H
Haojun Liao 已提交
3818
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
3819
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
3820
      destroyOperatorInfo(pOperator->pDownstream[i]);
3821 3822
    }

wafwerar's avatar
wafwerar 已提交
3823
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
3824
    pOperator->numOfDownstream = 0;
3825 3826
  }

H
Haojun Liao 已提交
3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837
  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 已提交
3838
  taosMemoryFreeClear(pOperator->pExpr);
wafwerar's avatar
wafwerar 已提交
3839 3840
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
3841 3842
}

3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857
int32_t getBufferPgSize(int32_t rowSize, uint32_t* defaultPgsz, uint32_t* defaultBufsz) {
  *defaultPgsz = 4096;
  while (*defaultPgsz < rowSize * 4) {
    *defaultPgsz <<= 1u;
  }

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

  return 0;
}

dengyihao's avatar
dengyihao 已提交
3858 3859
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                         const char* pKey) {
3860 3861
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

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

H
Haojun Liao 已提交
3866
  if (pAggSup->keyBuf == NULL || pAggSup->pResultRowHashTable == NULL) {
3867 3868 3869
    return TSDB_CODE_OUT_OF_MEMORY;
  }

dengyihao's avatar
dengyihao 已提交
3870
  uint32_t defaultPgsz = 0;
3871 3872
  uint32_t defaultBufsz = 0;
  getBufferPgSize(pAggSup->resultRowSize, &defaultPgsz, &defaultBufsz);
H
Haojun Liao 已提交
3873

3874
  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, defaultPgsz, defaultBufsz, pKey, TD_TMP_DIR_PATH);
H
Haojun Liao 已提交
3875 3876 3877 3878
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

3879 3880 3881
  return TSDB_CODE_SUCCESS;
}

3882
void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
3883
  taosMemoryFreeClear(pAggSup->keyBuf);
3884
  taosHashCleanup(pAggSup->pResultRowHashTable);
H
Haojun Liao 已提交
3885
  destroyDiskbasedBuf(pAggSup->pResultBuf);
3886 3887
}

H
Haojun Liao 已提交
3888
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
3889
                    SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey) {
3890
  pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
3891 3892
  pBasicInfo->pRes = pResultBlock;

3893
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, keyBufSize, pkey);
3894

L
Liu Jicong 已提交
3895
  for (int32_t i = 0; i < numOfCols; ++i) {
3896 3897 3898
    pBasicInfo->pCtx[i].pBuf = pAggSup->pResultBuf;
  }

3899
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
3900 3901
}

3902 3903 3904 3905 3906 3907 3908 3909 3910
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;
  }
}

dengyihao's avatar
dengyihao 已提交
3911
// static STableQueryInfo* initTableQueryInfo(const STableListInfo* pTableListInfo) {
wmmhello's avatar
wmmhello 已提交
3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930
//  int32_t size = taosArrayGetSize(pTableListInfo->pTableList);
//  if (size == 0) {
//    return NULL;
//  }
//
//  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(size, sizeof(STableQueryInfo));
//  if (pTableQueryInfo == NULL) {
//    return NULL;
//  }
//
//  for (int32_t j = 0; j < size; ++j) {
//    STableKeyInfo*   pk = taosArrayGet(pTableListInfo->pTableList, j);
//    STableQueryInfo* pTQueryInfo = &pTableQueryInfo[j];
//    pTQueryInfo->lastKey = pk->lastKey;
//  }
//
//  pTableQueryInfo->lastKey = 0;
//  return pTableQueryInfo;
//}
H
Haojun Liao 已提交
3931

L
Liu Jicong 已提交
3932
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
3933
                                           SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
wmmhello's avatar
wmmhello 已提交
3934
                                           int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
3935
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
3936
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
3937 3938 3939
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
3940

3941
  int32_t numOfRows = 1024;
dengyihao's avatar
dengyihao 已提交
3942
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
3943 3944

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
3945 3946
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResultBlock, keyBufSize, pTaskInfo->id.str);
L
Liu Jicong 已提交
3947
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
3948 3949
    goto _error;
  }
H
Haojun Liao 已提交
3950

H
Haojun Liao 已提交
3951 3952 3953 3954
  int32_t numOfGroup = 10;  // todo replaced with true value
  pInfo->groupId = INT32_MIN;
  initResultRowInfo(&pInfo->binfo.resultRowInfo, numOfGroup);

3955 3956
  pInfo->pScalarExprInfo = pScalarExprInfo;
  pInfo->numOfScalarExpr = numOfScalarExpr;
3957
  if (pInfo->pScalarExprInfo != NULL) {
3958
    pInfo->pScalarCtx = createSqlFunctionCtx(pScalarExprInfo, numOfScalarExpr, &pInfo->rowCellInfoOffset);
3959
  }
3960

dengyihao's avatar
dengyihao 已提交
3961
  pOperator->name = "TableAggregate";
X
Xiaoyu Wang 已提交
3962
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
3963
  pOperator->blocking = true;
dengyihao's avatar
dengyihao 已提交
3964 3965 3966
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
3967
  pOperator->numOfExprs = numOfCols;
dengyihao's avatar
dengyihao 已提交
3968
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
3969

3970 3971
  pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
H
Haojun Liao 已提交
3972 3973 3974 3975 3976

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

  return pOperator;
L
Liu Jicong 已提交
3979
_error:
H
Haojun Liao 已提交
3980
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
3981 3982
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
3983 3984
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
3985 3986
}

H
Haojun Liao 已提交
3987
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
3988 3989
  assert(pInfo != NULL);

3990
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
3991
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
3992 3993

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
3994
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
3995 3996
}

H
Haojun Liao 已提交
3997
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
3998
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
3999 4000
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
4001 4002

void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4003
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
4004 4005
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
4006

H
Haojun Liao 已提交
4007
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4008
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
4009
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
4010
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
4011
  taosMemoryFreeClear(pInfo->p);
4012 4013
}

H
Haojun Liao 已提交
4014
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
D
fix bug  
dapan 已提交
4015 4016 4017
  if (NULL == param) {
    return;
  }
L
Liu Jicong 已提交
4018
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
4019
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
H
Haojun Liao 已提交
4020
  cleanupAggSup(&pInfo->aggSup);
H
Haojun Liao 已提交
4021
  taosArrayDestroy(pInfo->pPseudoColInfo);
4022 4023
}

H
Haojun Liao 已提交
4024
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4025
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
4026 4027 4028 4029 4030 4031 4032 4033 4034
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

H
Haojun Liao 已提交
4035 4036
static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols) {
  SArray* pList = taosArrayInit(4, sizeof(int32_t));
dengyihao's avatar
dengyihao 已提交
4037
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
4038 4039 4040 4041 4042 4043 4044 4045
    if (fmIsPseudoColumnFunc(pCtx[i].functionId)) {
      taosArrayPush(pList, &i);
    }
  }

  return pList;
}

L
Liu Jicong 已提交
4046
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
4047
                                         SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit, SNode* pCondition,
dengyihao's avatar
dengyihao 已提交
4048
                                         SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4049
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
4050
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4051 4052 4053
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
4054

4055 4056 4057
  pInfo->limit      = *pLimit;
  pInfo->slimit     = *pSlimit;
  pInfo->curOffset  = pLimit->offset;
H
Haojun Liao 已提交
4058
  pInfo->curSOffset = pSlimit->offset;
H
Haojun Liao 已提交
4059
  pInfo->binfo.pRes = pResBlock;
4060
  pInfo->pFilterNode= pCondition;
H
Haojun Liao 已提交
4061 4062 4063

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
4064
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
4065

4066 4067 4068 4069 4070
  // Make sure the size of SSDataBlock will never exceed the size of 2MB.
  int32_t TWOMB = 2 * 1024 * 1024;
  if (numOfRows * pResBlock->info.rowSize > TWOMB) {
    numOfRows = TWOMB / pResBlock->info.rowSize;
  }
4071
  initResultSizeInfo(pOperator, numOfRows);
4072

4073
  initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
4074
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, numOfCols, pTaskInfo);
4075

X
Xiaoyu Wang 已提交
4076 4077
  pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pInfo->binfo.pCtx, numOfCols);
  pOperator->name = "ProjectOperator";
H
Haojun Liao 已提交
4078
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
X
Xiaoyu Wang 已提交
4079 4080 4081 4082 4083 4084
  pOperator->blocking = false;
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfExprs = num;
  pOperator->pTaskInfo = pTaskInfo;
4085

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

4089
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
4090
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4091 4092
    goto _error;
  }
4093 4094

  return pOperator;
H
Haojun Liao 已提交
4095

L
Liu Jicong 已提交
4096
_error:
H
Haojun Liao 已提交
4097 4098
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
4099 4100
}

4101
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, SNodeListNode* pValNode,
L
Liu Jicong 已提交
4102
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
4103
  SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pValNode);
H
Haojun Liao 已提交
4104 4105

  STimeWindow w = TSWINDOW_INITIALIZER;
4106
  getAlignQueryTimeWindow(pInterval, pInterval->precision, win.skey, &w);
H
Haojun Liao 已提交
4107 4108

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

wafwerar's avatar
wafwerar 已提交
4111
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
4112 4113 4114 4115 4116 4117 4118
  if (pInfo->pFillInfo == NULL || pInfo->p == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  } else {
    return TSDB_CODE_SUCCESS;
  }
}

L
Liu Jicong 已提交
4119
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
X
Xiaoyu Wang 已提交
4120 4121 4122
                                      SInterval* pInterval, STimeWindow* pWindow, SSDataBlock* pResBlock,
                                      int32_t fillType, SNodeListNode* pValueNode, bool multigroupResult,
                                      SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4123
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
4124
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4125

L
Liu Jicong 已提交
4126
  pInfo->pRes = pResBlock;
4127 4128
  pInfo->multigroupResult = multigroupResult;

4129 4130
  int32_t type = TSDB_FILL_NONE;
  switch (fillType) {
dengyihao's avatar
dengyihao 已提交
4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148
    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;
4149 4150 4151 4152
    default:
      type = TSDB_FILL_NONE;
  }

H
Haojun Liao 已提交
4153
  SResultInfo* pResultInfo = &pOperator->resultInfo;
4154 4155
  initResultSizeInfo(pOperator, 4096);

X
Xiaoyu Wang 已提交
4156 4157
  int32_t code = initFillInfo(pInfo, pExpr, numOfCols, pValueNode, *pWindow, pResultInfo->capacity, pTaskInfo->id.str,
                              pInterval, type);
4158 4159 4160
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4161

dengyihao's avatar
dengyihao 已提交
4162
  pOperator->name = "FillOperator";
4163
  pOperator->blocking = false;
dengyihao's avatar
dengyihao 已提交
4164
  pOperator->status = OP_NOT_OPENED;
4165
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL;
dengyihao's avatar
dengyihao 已提交
4166
  pOperator->pExpr = pExpr;
4167
  pOperator->numOfExprs = numOfCols;
dengyihao's avatar
dengyihao 已提交
4168
  pOperator->info = pInfo;
H
Haojun Liao 已提交
4169

L
Liu Jicong 已提交
4170 4171
  pOperator->fpSet =
      createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo, NULL, NULL, NULL);
4172
  pOperator->pTaskInfo = pTaskInfo;
4173
  code = appendDownstream(pOperator, &downstream, 1);
4174
  return pOperator;
H
Haojun Liao 已提交
4175

L
Liu Jicong 已提交
4176
_error:
wafwerar's avatar
wafwerar 已提交
4177 4178
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
4179
  return NULL;
4180 4181
}

L
Liu Jicong 已提交
4182 4183
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
4184
  SResSchema s = {0};
dengyihao's avatar
dengyihao 已提交
4185 4186 4187 4188
  s.scale = scale;
  s.type = type;
  s.bytes = bytes;
  s.slotId = slotId;
H
Haojun Liao 已提交
4189
  s.precision = precision;
H
Haojun Liao 已提交
4190 4191 4192 4193
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
4194

4195
static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDataType* pType) {
H
Haojun Liao 已提交
4196 4197 4198 4199 4200 4201
  SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn));
  if (pCol == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

dengyihao's avatar
dengyihao 已提交
4202
  pCol->slotId = slotId;
X
Xiaoyu Wang 已提交
4203 4204 4205 4206
  pCol->colId = colId;
  pCol->bytes = pType->bytes;
  pCol->type = pType->type;
  pCol->scale = pType->scale;
dengyihao's avatar
dengyihao 已提交
4207
  pCol->precision = pType->precision;
H
Haojun Liao 已提交
4208 4209 4210 4211 4212
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
4213
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
4214
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
4215 4216 4217 4218
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
4219

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

L
Liu Jicong 已提交
4223
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
4224 4225 4226 4227 4228 4229
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
4230

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

wafwerar's avatar
wafwerar 已提交
4233
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
4234
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
4235
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
4236

4237
    int32_t type = nodeType(pTargetNode->pExpr);
H
Haojun Liao 已提交
4238
    // it is a project query, or group by column
4239
    if (type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
4240
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
4241
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
4242

G
Ganlin Zhao 已提交
4243 4244 4245
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
4246
      SDataType* pType = &pColNode->node.resType;
dengyihao's avatar
dengyihao 已提交
4247 4248
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pColNode->colName);
4249
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType);
H
Haojun Liao 已提交
4250
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
4251
    } else if (type == QUERY_NODE_VALUE) {
4252 4253 4254 4255 4256 4257 4258
      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 已提交
4259 4260
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pValNode->node.aliasName);
4261
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
X
Xiaoyu Wang 已提交
4262
      nodesValueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
4263
    } else if (type == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
4264
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
4265 4266 4267
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

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

H
Haojun Liao 已提交
4271
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
4272
      pExp->pExpr->_function.pFunctNode = pFuncNode;
4273

dengyihao's avatar
dengyihao 已提交
4274 4275
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
4276 4277 4278 4279 4280
#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);
X
Xiaoyu Wang 已提交
4281 4282
        SValueNode* res = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
        if (NULL == res) {  // todo handle error
4283
        } else {
X
Xiaoyu Wang 已提交
4284
          res->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
4285 4286 4287 4288
          nodesListAppend(pFuncNode->pParameterList, res);
        }
      }
#endif
H
Haojun Liao 已提交
4289 4290

      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
4291 4292 4293 4294

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

H
Haojun Liao 已提交
4295
      for (int32_t j = 0; j < numOfParam; ++j) {
4296
        SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
4297
        if (p1->type == QUERY_NODE_COLUMN) {
dengyihao's avatar
dengyihao 已提交
4298
          SColumnNode* pcn = (SColumnNode*)p1;
G
Ganlin Zhao 已提交
4299 4300

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
4301
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType);
G
Ganlin Zhao 已提交
4302 4303 4304
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
X
Xiaoyu Wang 已提交
4305
          nodesValueNodeToVariant(pvn, &pExp->base.pParam[j].param);
G
Ganlin Zhao 已提交
4306
        }
H
Haojun Liao 已提交
4307
      }
4308
    } else if (type == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
4309
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
4310
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
4311

G
Ganlin Zhao 已提交
4312 4313 4314
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

4315
      SDataType* pType = &pNode->node.resType;
dengyihao's avatar
dengyihao 已提交
4316 4317
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pNode->node.aliasName);
4318 4319 4320
      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
4321 4322 4323
    }
  }

H
Haojun Liao 已提交
4324
  return pExprs;
H
Haojun Liao 已提交
4325 4326
}

D
dapan1121 已提交
4327
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model, char* dbFName) {
wafwerar's avatar
wafwerar 已提交
4328
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
4329
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
4330

D
dapan1121 已提交
4331
  pTaskInfo->schemaVer.dbname = strdup(dbFName);
4332
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
4333
  pTaskInfo->id.queryId = queryId;
dengyihao's avatar
dengyihao 已提交
4334
  pTaskInfo->execModel = model;
H
Haojun Liao 已提交
4335

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

4340 4341
  return pTaskInfo;
}
H
Haojun Liao 已提交
4342

L
Liu Jicong 已提交
4343
static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
dengyihao's avatar
dengyihao 已提交
4344 4345
                                      STableListInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId,
                                      SNode* pTagCond);
H
Haojun Liao 已提交
4346

dengyihao's avatar
dengyihao 已提交
4347 4348
static int32_t getTableList(void* metaHandle, int32_t tableType, uint64_t tableUid, STableListInfo* pListInfo,
                            SNode* pTagCond);
wmmhello's avatar
wmmhello 已提交
4349
static SArray* extractTableIdList(const STableListInfo* pTableGroupInfo);
H
Haojun Liao 已提交
4350
static SArray* extractColumnInfo(SNodeList* pNodeList);
4351

4352
static SArray* createSortInfo(SNodeList* pNodeList);
4353
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
4354

X
Xiaoyu Wang 已提交
4355
void extractTableSchemaVersion(SReadHandle* pHandle, uint64_t uid, SExecTaskInfo* pTaskInfo) {
4356 4357 4358 4359 4360 4361 4362
  SMetaReader mr = {0};
  metaReaderInit(&mr, pHandle->meta, 0);
  metaGetTableEntryByUid(&mr, uid);

  pTaskInfo->schemaVer.tablename = strdup(mr.me.name);

  if (mr.me.type == TSDB_SUPER_TABLE) {
4363 4364
    pTaskInfo->schemaVer.sversion = mr.me.stbEntry.schemaRow.version;
    pTaskInfo->schemaVer.tversion = mr.me.stbEntry.schemaTag.version;
4365 4366 4367
  } else if (mr.me.type == TSDB_CHILD_TABLE) {
    tb_uid_t suid = mr.me.ctbEntry.suid;
    metaGetTableEntryByUid(&mr, suid);
4368 4369
    pTaskInfo->schemaVer.sversion = mr.me.stbEntry.schemaRow.version;
    pTaskInfo->schemaVer.tversion = mr.me.stbEntry.schemaTag.version;
4370
  } else {
4371
    pTaskInfo->schemaVer.sversion = mr.me.ntbEntry.schemaRow.version;
4372
  }
4373 4374

  metaReaderClear(&mr);
4375 4376
}

H
Haojun Liao 已提交
4377
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
wmmhello's avatar
wmmhello 已提交
4378
                                  uint64_t queryId, uint64_t taskId, STableListInfo* pTableListInfo, SNode* pTagCond) {
4379 4380
  int32_t type = nodeType(pPhyNode);

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

dengyihao's avatar
dengyihao 已提交
4385
      tsdbReaderT pDataReader =
dengyihao's avatar
dengyihao 已提交
4386
          doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId, pTagCond);
4387
      if (pDataReader == NULL && terrno != 0) {
4388 4389
        return NULL;
      }
wmmhello's avatar
wmmhello 已提交
4390
      SArray* groupKyes = extractPartitionColInfo(pTableScanNode->pPartitionKeys);
4391
      extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
X
Xiaoyu Wang 已提交
4392 4393
      SOperatorInfo* pOperator =
          createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, groupKyes, pTaskInfo);
4394

4395 4396
      STableScanInfo* pScanInfo = pOperator->info;
      pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
4397

4398
      return pOperator;
H
Haojun Liao 已提交
4399
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
H
Haojun Liao 已提交
4400
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
4401
      SSDataBlock*        pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
4402
      return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
H
Haojun Liao 已提交
4403
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
X
Xiaoyu Wang 已提交
4404
      SScanPhysiNode*      pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
5
54liuyao 已提交
4405
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
4406 4407
      STimeWindowAggSupp   twSup = {
            .waterMark = pTableScanNode->watermark, .calTrigger = pTableScanNode->triggerType, .maxTs = INT64_MIN};
5
54liuyao 已提交
4408 4409
      tsdbReaderT pDataReader = NULL;
      if (pHandle->vnode) {
wmmhello's avatar
wmmhello 已提交
4410
        pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId, pTagCond);
wmmhello's avatar
wmmhello 已提交
4411 4412
      } else {
        getTableList(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableListInfo, pTagCond);
5
54liuyao 已提交
4413
      }
4414

5
54liuyao 已提交
4415
      if (pDataReader == NULL && terrno != 0) {
4416
        qDebug("%s pDataReader is NULL", GET_TASKID(pTaskInfo));
5
54liuyao 已提交
4417 4418
        // return NULL;
      } else {
4419
        qDebug("%s pDataReader is not NULL", GET_TASKID(pTaskInfo));
5
54liuyao 已提交
4420
      }
X
Xiaoyu Wang 已提交
4421
      SArray* tableIdList = extractTableIdList(pTableListInfo);
H
Haojun Liao 已提交
4422

X
Xiaoyu Wang 已提交
4423 4424
      SOperatorInfo* pOperator =
          createStreamScanOperatorInfo(pDataReader, pHandle, tableIdList, pTableScanNode, pTaskInfo, &twSup);
5
54liuyao 已提交
4425

4426
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
4427
      return pOperator;
H
Haojun Liao 已提交
4428
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
L
Liu Jicong 已提交
4429
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
L
Liu Jicong 已提交
4430
      SScanPhysiNode*            pScanNode = &pSysScanPhyNode->scan;
H
Haojun Liao 已提交
4431

4432 4433 4434
      SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;

      SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4435

4436
      int32_t numOfOutputCols = 0;
X
Xiaoyu Wang 已提交
4437 4438
      SArray* colList =
          extractColMatchInfo(pScanNode->pScanCols, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_COL_ID);
L
Liu Jicong 已提交
4439
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
L
Liu Jicong 已提交
4440 4441
          pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet, colList,
          pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
4442
      return pOperator;
4443
    } else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) {
X
Xiaoyu Wang 已提交
4444
      STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode;
4445 4446 4447 4448

      SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;

      SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4449

wmmhello's avatar
wmmhello 已提交
4450
      int32_t code = getTableList(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableListInfo, pTagCond);
4451 4452 4453 4454
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }

X
Xiaoyu Wang 已提交
4455
      int32_t    num = 0;
4456 4457 4458
      SExprInfo* pExprInfo = createExprInfo(pScanPhyNode->pScanPseudoCols, NULL, &num);

      int32_t numOfOutputCols = 0;
X
Xiaoyu Wang 已提交
4459 4460
      SArray* colList = extractColMatchInfo(pScanPhyNode->pScanPseudoCols, pDescNode, &numOfOutputCols, pTaskInfo,
                                            COL_MATCH_FROM_COL_ID);
4461

X
Xiaoyu Wang 已提交
4462
      SOperatorInfo* pOperator =
wmmhello's avatar
wmmhello 已提交
4463
          createTagScanOperatorInfo(pHandle, pExprInfo, num, pResBlock, colList, pTableListInfo, pTaskInfo);
4464
      return pOperator;
H
Haojun Liao 已提交
4465 4466
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
4467 4468 4469
    }
  }

4470 4471
  int32_t num = 0;
  size_t  size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
4472

4473
  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
dengyihao's avatar
dengyihao 已提交
4474
  for (int32_t i = 0; i < size; ++i) {
4475
    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
wmmhello's avatar
wmmhello 已提交
4476
    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableListInfo, pTagCond);
4477 4478 4479
    if (ops[i] == NULL) {
      return NULL;
    }
4480
  }
H
Haojun Liao 已提交
4481

4482
  SOperatorInfo* pOptr = NULL;
H
Haojun Liao 已提交
4483
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
dengyihao's avatar
dengyihao 已提交
4484 4485
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*)pPhyNode;
    SExprInfo*         pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);
H
Haojun Liao 已提交
4486

4487
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
dengyihao's avatar
dengyihao 已提交
4488 4489
    SLimit       limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
    SLimit       slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
4490
    pOptr = createProjectOperatorInfo(ops[0], pExprInfo, num, pResBlock, &limit, &slimit, pProjPhyNode->node.pConditions, pTaskInfo);
H
Haojun Liao 已提交
4491 4492 4493
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == type) {
    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
    SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
4494
    SSDataBlock*   pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
4495

dengyihao's avatar
dengyihao 已提交
4496
    int32_t    numOfScalarExpr = 0;
4497 4498 4499 4500 4501
    SExprInfo* pScalarExprInfo = NULL;
    if (pAggNode->pExprs != NULL) {
      pScalarExprInfo = createExprInfo(pAggNode->pExprs, NULL, &numOfScalarExpr);
    }

H
Haojun Liao 已提交
4502 4503
    if (pAggNode->pGroupKeys != NULL) {
      SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
dengyihao's avatar
dengyihao 已提交
4504
      pOptr = createGroupOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pAggNode->node.pConditions,
wmmhello's avatar
wmmhello 已提交
4505
                                      pScalarExprInfo, numOfScalarExpr, pTaskInfo);
H
Haojun Liao 已提交
4506
    } else {
dengyihao's avatar
dengyihao 已提交
4507 4508
      pOptr =
          createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr, pTaskInfo);
H
Haojun Liao 已提交
4509
    }
X
Xiaoyu Wang 已提交
4510
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type || QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
H
Haojun Liao 已提交
4511
    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
4512

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

dengyihao's avatar
dengyihao 已提交
4516 4517 4518 4519 4520 4521
    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 已提交
4522

X
Xiaoyu Wang 已提交
4523 4524 4525 4526 4527 4528
    STimeWindowAggSupp as = {
        .waterMark = pIntervalPhyNode->window.watermark,
        .calTrigger = pIntervalPhyNode->window.triggerType,
        .maxTs = INT64_MIN,
        .winMap = NULL,
    };
5
54liuyao 已提交
4529 4530 4531 4532 4533 4534
    if (isSmaStream(pIntervalPhyNode->window.triggerType)) {
      if (FLT_LESS(pIntervalPhyNode->window.filesFactor, 1.000000)) {
        as.calTrigger = STREAM_TRIGGER_AT_ONCE_SMA;
      } else {
        _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
        as.winMap = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
X
Xiaoyu Wang 已提交
4535
        as.waterMark = getSmaWaterMark(interval.interval, pIntervalPhyNode->window.filesFactor);
5
54liuyao 已提交
4536 4537 4538
        as.calTrigger = STREAM_TRIGGER_WINDOW_CLOSE_SMA;
      }
    }
4539

4540
    int32_t tsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
wmmhello's avatar
wmmhello 已提交
4541
    pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, &as, pTaskInfo);
4542

H
Haojun Liao 已提交
4543
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
H
Haojun Liao 已提交
4544
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
4545

4546 4547 4548
    SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;

    SSDataBlock* pResBlock = createResDataBlock(pDescNode);
4549
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys);
4550 4551

    int32_t    numOfCols = 0;
4552 4553 4554
    SExprInfo* pExprInfo = createExprInfo(pSortPhyNode->pExprs, NULL, &numOfCols);

    int32_t numOfOutputCols = 0;
X
Xiaoyu Wang 已提交
4555 4556
    SArray* pColList =
        extractColMatchInfo(pSortPhyNode->pTargets, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_SLOT_ID);
4557

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

X
Xiaoyu Wang 已提交
4562 4563
    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};
4564

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

X
Xiaoyu Wang 已提交
4569 4570
    pOptr =
        createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, tsSlotId, &as, pTaskInfo);
5
54liuyao 已提交
4571 4572 4573 4574 4575 4576 4577 4578 4579 4580
  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION_WINDOW == type) {
    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};

    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
    int32_t      tsSlotId = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;

4581 4582
    pOptr = createStreamSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, tsSlotId, &as,
                                               pTaskInfo);
5
54liuyao 已提交
4583

H
Haojun Liao 已提交
4584
  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
dengyihao's avatar
dengyihao 已提交
4585 4586 4587
    SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
    SArray*              pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
    SSDataBlock*         pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4588 4589

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

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

dengyihao's avatar
dengyihao 已提交
4596
    SExprInfo*   pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &num);
4597
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4598 4599
    int32_t      tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId;

4600
    SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pStateNode->pStateKey)->pExpr;
X
Xiaoyu Wang 已提交
4601
    SColumn      col = extractColumnFromColumnNode(pColNode);
4602
    pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, tsSlotId, &col, pTaskInfo);
5
54liuyao 已提交
4603 4604
  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE_WINDOW == type) {
    pOptr = createStreamStateAggOperatorInfo(ops[0], pPhyNode, pTaskInfo);
4605
  } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
dengyihao's avatar
dengyihao 已提交
4606 4607
    SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
4608 4609

    SExprInfo* pExprInfo = createExprInfo(pJoinNode->pTargets, NULL, &num);
H
Haojun Liao 已提交
4610
    pOptr = createMergeJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
4611 4612
  } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) {
    SFillPhysiNode* pFillNode = (SFillPhysiNode*)pPhyNode;
X
Xiaoyu Wang 已提交
4613 4614
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
    SExprInfo*      pExprInfo = createExprInfo(pFillNode->pTargets, NULL, &num);
4615

4616
    SInterval* pInterval = &((SIntervalAggOperatorInfo*)ops[0]->info)->interval;
X
Xiaoyu Wang 已提交
4617 4618
    pOptr = createFillOperatorInfo(ops[0], pExprInfo, num, pInterval, &pFillNode->timeRange, pResBlock, pFillNode->mode,
                                   (SNodeListNode*)pFillNode->pValues, false, pTaskInfo);
H
Haojun Liao 已提交
4619 4620
  } else {
    ASSERT(0);
H
Haojun Liao 已提交
4621
  }
4622 4623 4624

  taosMemoryFree(ops);
  return pOptr;
4625
}
H
Haojun Liao 已提交
4626

4627
int32_t compareTimeWindow(const void* p1, const void* p2, const void* param) {
dengyihao's avatar
dengyihao 已提交
4628 4629 4630
  const SQueryTableDataCond* pCond = param;
  const STimeWindow*         pWin1 = p1;
  const STimeWindow*         pWin2 = p2;
4631 4632 4633 4634 4635 4636 4637 4638
  if (pCond->order == TSDB_ORDER_ASC) {
    return pWin1->skey - pWin2->skey;
  } else if (pCond->order == TSDB_ORDER_DESC) {
    return pWin2->skey - pWin1->skey;
  }
  return 0;
}

4639
int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode) {
4640 4641 4642 4643 4644 4645
  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 已提交
4646
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
4647 4648 4649
    return terrno;
  }

dengyihao's avatar
dengyihao 已提交
4650 4651
  // pCond->twindow = pTableScanNode->scanRange;
  // TODO: get it from stable scan node
4652 4653 4654
  pCond->numOfTWindows = 1;
  pCond->twindows = taosMemoryCalloc(pCond->numOfTWindows, sizeof(STimeWindow));
  pCond->twindows[0] = pTableScanNode->scanRange;
4655 4656

#if 1
L
Liu Jicong 已提交
4657
  // todo work around a problem, remove it later
4658 4659 4660 4661 4662
  for (int32_t i = 0; i < pCond->numOfTWindows; ++i) {
    if ((pCond->order == TSDB_ORDER_ASC && pCond->twindows[i].skey > pCond->twindows[i].ekey) ||
        (pCond->order == TSDB_ORDER_DESC && pCond->twindows[i].skey < pCond->twindows[i].ekey)) {
      TSWAP(pCond->twindows[i].skey, pCond->twindows[i].ekey);
    }
H
Haojun Liao 已提交
4663
  }
4664
#endif
H
Haojun Liao 已提交
4665

4666 4667 4668 4669 4670 4671
  for (int32_t i = 0; i < pCond->numOfTWindows; ++i) {
    if ((pCond->order == TSDB_ORDER_ASC && pCond->twindows[i].skey > pCond->twindows[i].ekey) ||
        (pCond->order == TSDB_ORDER_DESC && pCond->twindows[i].skey < pCond->twindows[i].ekey)) {
      TSWAP(pCond->twindows[i].skey, pCond->twindows[i].ekey);
    }
  }
dengyihao's avatar
dengyihao 已提交
4672
  taosqsort(pCond->twindows, pCond->numOfTWindows, sizeof(STimeWindow), pCond, compareTimeWindow);
4673

4674 4675
  pCond->type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
  //  pCond->type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
4676

H
Haojun Liao 已提交
4677
  int32_t j = 0;
4678
  for (int32_t i = 0; i < pCond->numOfCols; ++i) {
H
Haojun Liao 已提交
4679 4680
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
4681 4682 4683
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
4684

4685 4686 4687
    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 已提交
4688
    j += 1;
H
Haojun Liao 已提交
4689 4690
  }

4691 4692
  pCond->numOfCols = j;
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
4693
}
H
Haojun Liao 已提交
4694

4695 4696
SColumn extractColumnFromColumnNode(SColumnNode* pColNode) {
  SColumn c = {0};
X
Xiaoyu Wang 已提交
4697 4698 4699 4700 4701
  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;
4702 4703 4704 4705
  c.precision = pColNode->node.resType.precision;
  return c;
}

H
Haojun Liao 已提交
4706
SArray* extractColumnInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
4707
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
4708 4709 4710 4711 4712 4713
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

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

4717 4718 4719
    if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN) {
      SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;

4720
      SColumn c = extractColumnFromColumnNode(pColNode);
4721 4722
      taosArrayPush(pList, &c);
    } else if (nodeType(pNode->pExpr) == QUERY_NODE_VALUE) {
L
Liu Jicong 已提交
4723 4724
      SValueNode* pValNode = (SValueNode*)pNode->pExpr;
      SColumn     c = {0};
4725
      c.slotId = pNode->slotId;
L
Liu Jicong 已提交
4726 4727 4728 4729
      c.colId = pNode->slotId;
      c.type = pValNode->node.type;
      c.bytes = pValNode->node.resType.bytes;
      c.scale = pValNode->node.resType.scale;
4730 4731 4732 4733
      c.precision = pValNode->node.resType.precision;

      taosArrayPush(pList, &c);
    }
H
Haojun Liao 已提交
4734 4735 4736 4737 4738
  }

  return pList;
}

4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752
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 已提交
4753 4754 4755
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
4756 4757 4758 4759 4760 4761 4762 4763 4764
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;

    taosArrayPush(pList, &c);
  }

  return pList;
}

4765
SArray* createSortInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
4766
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
4767 4768 4769 4770 4771 4772
  SArray* pList = taosArrayInit(numOfCols, sizeof(SBlockOrderInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

L
Liu Jicong 已提交
4773
  for (int32_t i = 0; i < numOfCols; ++i) {
4774
    SOrderByExprNode* pSortKey = (SOrderByExprNode*)nodesListGetNode(pNodeList, i);
L
Liu Jicong 已提交
4775 4776
    SBlockOrderInfo   bi = {0};
    bi.order = (pSortKey->order == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
H
Haojun Liao 已提交
4777 4778 4779
    bi.nullFirst = (pSortKey->nullOrder == NULL_ORDER_FIRST);

    SColumnNode* pColNode = (SColumnNode*)pSortKey->pExpr;
4780
    bi.slotId = pColNode->slotId;
H
Haojun Liao 已提交
4781 4782 4783 4784 4785 4786
    taosArrayPush(pList, &bi);
  }

  return pList;
}

X
Xiaoyu Wang 已提交
4787
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols,
4788
                            SExecTaskInfo* pTaskInfo, int32_t type) {
L
Liu Jicong 已提交
4789
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
4790 4791 4792 4793 4794 4795
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
4796 4797 4798
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
4799 4800

    SColMatchInfo c = {0};
X
Xiaoyu Wang 已提交
4801 4802 4803 4804
    c.output = true;
    c.colId = pColNode->colId;
    c.srcSlotId = pColNode->slotId;
    c.matchType = type;
H
Haojun Liao 已提交
4805 4806 4807 4808
    c.targetSlotId = pNode->slotId;
    taosArrayPush(pList, &c);
  }

H
Haojun Liao 已提交
4809 4810
  *numOfOutputCols = 0;
  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
4811 4812
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
4813

4814
    // todo: add reserve flag check
4815 4816
    // it is a column reserved for the arithmetic expression calculation
    if (pNode->slotId >= numOfCols) {
4817 4818 4819 4820
      (*numOfOutputCols) += 1;
      continue;
    }

H
Haojun Liao 已提交
4821
    SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
H
Haojun Liao 已提交
4822 4823 4824 4825 4826
    if (pNode->output) {
      (*numOfOutputCols) += 1;
    } else {
      info->output = false;
    }
H
Haojun Liao 已提交
4827 4828
  }

H
Haojun Liao 已提交
4829 4830 4831
  return pList;
}

dengyihao's avatar
dengyihao 已提交
4832 4833
int32_t getTableList(void* metaHandle, int32_t tableType, uint64_t tableUid, STableListInfo* pListInfo,
                     SNode* pTagCond) {
wmmhello's avatar
wmmhello 已提交
4834
  int32_t code = TSDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
4835
  pListInfo->pTableList = taosArrayInit(8, sizeof(STableKeyInfo));
wmmhello's avatar
wmmhello 已提交
4836

wmmhello's avatar
wmmhello 已提交
4837
  if (tableType == TSDB_SUPER_TABLE) {
dengyihao's avatar
dengyihao 已提交
4838
    if (pTagCond) {
dengyihao's avatar
dengyihao 已提交
4839
      SIndexMetaArg metaArg = {.metaEx = metaHandle, .metaHandle = tsdbGetIdx(metaHandle), .suid = tableUid};
dengyihao's avatar
dengyihao 已提交
4840

wmmhello's avatar
wmmhello 已提交
4841
      SArray* res = taosArrayInit(8, sizeof(uint64_t));
dengyihao's avatar
dengyihao 已提交
4842
      code = doFilterTag(pTagCond, &metaArg, res);
wmmhello's avatar
wmmhello 已提交
4843
      if (code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
dengyihao 已提交
4844
        qError("failed  to  get tableIds, reason: %s, suid: %" PRIu64 "", tstrerror(code), tableUid);
wmmhello's avatar
wmmhello 已提交
4845
        taosArrayDestroy(res);
wmmhello's avatar
wmmhello 已提交
4846
        terrno = code;
wmmhello's avatar
wmmhello 已提交
4847
        return code;
dengyihao's avatar
dengyihao 已提交
4848
      } else {
dengyihao's avatar
dengyihao 已提交
4849
        qDebug("sucess to  get tableIds, size: %d, suid: %" PRIu64 "", (int)taosArrayGetSize(res), tableUid);
wmmhello's avatar
wmmhello 已提交
4850
      }
dengyihao's avatar
dengyihao 已提交
4851
      for (int i = 0; i < taosArrayGetSize(res); i++) {
wmmhello's avatar
wmmhello 已提交
4852 4853 4854 4855
        STableKeyInfo info = {.lastKey = TSKEY_INITIAL_VAL, .uid = *(uint64_t*)taosArrayGet(res, i)};
        taosArrayPush(pListInfo->pTableList, &info);
      }
      taosArrayDestroy(res);
dengyihao's avatar
dengyihao 已提交
4856
    } else {
wmmhello's avatar
wmmhello 已提交
4857
      code = tsdbGetAllTableList(metaHandle, tableUid, pListInfo->pTableList);
wmmhello's avatar
wmmhello 已提交
4858
    }
H
Haojun Liao 已提交
4859
  } else {  // Create one table group.
wmmhello's avatar
wmmhello 已提交
4860 4861
    STableKeyInfo info = {.lastKey = 0, .uid = tableUid};
    taosArrayPush(pListInfo->pTableList, &info);
4862 4863 4864 4865
  }

  return code;
}
H
Haojun Liao 已提交
4866

wmmhello's avatar
wmmhello 已提交
4867
SArray* extractTableIdList(const STableListInfo* pTableGroupInfo) {
4868 4869
  SArray* tableIdList = taosArrayInit(4, sizeof(uint64_t));

wmmhello's avatar
wmmhello 已提交
4870 4871 4872 4873
  // Transfer the Array of STableKeyInfo into uid list.
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pTableList); ++i) {
    STableKeyInfo* pkeyInfo = taosArrayGet(pTableGroupInfo->pTableList, i);
    taosArrayPush(tableIdList, &pkeyInfo->uid);
4874 4875 4876 4877 4878
  }

  return tableIdList;
}

L
Liu Jicong 已提交
4879
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
wmmhello's avatar
wmmhello 已提交
4880
                               STableListInfo* pTableListInfo, uint64_t queryId, uint64_t taskId, SNode* pTagCond) {
dengyihao's avatar
dengyihao 已提交
4881 4882
  int32_t code =
      getTableList(pHandle->meta, pTableScanNode->scan.tableType, pTableScanNode->scan.uid, pTableListInfo, pTagCond);
wmmhello's avatar
wmmhello 已提交
4883 4884 4885 4886 4887 4888 4889 4890 4891 4892
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

  if (taosArrayGetSize(pTableListInfo->pTableList) == 0) {
    code = 0;
    qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
    goto _error;
  }

4893
  SQueryTableDataCond cond = {0};
wmmhello's avatar
wmmhello 已提交
4894
  code = initQueryTableDataCond(&cond, pTableScanNode);
4895
  if (code != TSDB_CODE_SUCCESS) {
wmmhello's avatar
wmmhello 已提交
4896
    goto _error;
X
Xiaoyu Wang 已提交
4897
  }
4898

wmmhello's avatar
wmmhello 已提交
4899
  return tsdbQueryTables(pHandle->vnode, &cond, pTableListInfo, queryId, taskId);
wmmhello's avatar
wmmhello 已提交
4900 4901 4902 4903

_error:
  terrno = code;
  return NULL;
H
Haojun Liao 已提交
4904 4905
}

4906
int32_t encodeOperator(SOperatorInfo* ops, char** result, int32_t* length) {
wmmhello's avatar
wmmhello 已提交
4907
  int32_t code = TDB_CODE_SUCCESS;
4908
  char*   pCurrent = NULL;
wmmhello's avatar
wmmhello 已提交
4909
  int32_t currLength = 0;
4910 4911
  if (ops->fpSet.encodeResultRow) {
    if (result == NULL || length == NULL) {
wmmhello's avatar
wmmhello 已提交
4912 4913 4914
      return TSDB_CODE_TSC_INVALID_INPUT;
    }
    code = ops->fpSet.encodeResultRow(ops, &pCurrent, &currLength);
wmmhello's avatar
wmmhello 已提交
4915

4916 4917
    if (code != TDB_CODE_SUCCESS) {
      if (*result != NULL) {
wmmhello's avatar
wmmhello 已提交
4918 4919 4920 4921 4922
        taosMemoryFree(*result);
        *result = NULL;
      }
      return code;
    }
wmmhello's avatar
wmmhello 已提交
4923

4924
    if (*result == NULL) {
wmmhello's avatar
wmmhello 已提交
4925
      *result = (char*)taosMemoryCalloc(1, currLength + sizeof(int32_t));
wmmhello's avatar
wmmhello 已提交
4926 4927 4928 4929 4930 4931
      if (*result == NULL) {
        taosMemoryFree(pCurrent);
        return TSDB_CODE_OUT_OF_MEMORY;
      }
      memcpy(*result + sizeof(int32_t), pCurrent, currLength);
      *(int32_t*)(*result) = currLength + sizeof(int32_t);
4932
    } else {
wmmhello's avatar
wmmhello 已提交
4933
      int32_t sizePre = *(int32_t*)(*result);
4934
      char*   tmp = (char*)taosMemoryRealloc(*result, sizePre + currLength);
wmmhello's avatar
wmmhello 已提交
4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946
      if (tmp == NULL) {
        taosMemoryFree(pCurrent);
        taosMemoryFree(*result);
        *result = NULL;
        return TSDB_CODE_OUT_OF_MEMORY;
      }
      *result = tmp;
      memcpy(*result + sizePre, pCurrent, currLength);
      *(int32_t*)(*result) += currLength;
    }
    taosMemoryFree(pCurrent);
    *length = *(int32_t*)(*result);
wmmhello's avatar
wmmhello 已提交
4947 4948
  }

wmmhello's avatar
wmmhello 已提交
4949 4950
  for (int32_t i = 0; i < ops->numOfDownstream; ++i) {
    code = encodeOperator(ops->pDownstream[i], result, length);
4951
    if (code != TDB_CODE_SUCCESS) {
wmmhello's avatar
wmmhello 已提交
4952
      return code;
wmmhello's avatar
wmmhello 已提交
4953 4954
    }
  }
wmmhello's avatar
wmmhello 已提交
4955
  return TDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
4956 4957
}

4958
int32_t decodeOperator(SOperatorInfo* ops, char* result, int32_t length) {
wmmhello's avatar
wmmhello 已提交
4959
  int32_t code = TDB_CODE_SUCCESS;
4960 4961
  if (ops->fpSet.decodeResultRow) {
    if (result == NULL) {
wmmhello's avatar
wmmhello 已提交
4962 4963
      return TSDB_CODE_TSC_INVALID_INPUT;
    }
4964 4965 4966
    ASSERT(length == *(int32_t*)result);
    char* data = result + sizeof(int32_t);
    code = ops->fpSet.decodeResultRow(ops, data);
4967
    if (code != TDB_CODE_SUCCESS) {
wmmhello's avatar
wmmhello 已提交
4968 4969
      return code;
    }
wmmhello's avatar
wmmhello 已提交
4970

wmmhello's avatar
wmmhello 已提交
4971
    int32_t totalLength = *(int32_t*)result;
4972 4973
    int32_t dataLength = *(int32_t*)data;

4974
    if (totalLength == dataLength + sizeof(int32_t)) {  // the last data
wmmhello's avatar
wmmhello 已提交
4975 4976
      result = NULL;
      length = 0;
4977
    } else {
wmmhello's avatar
wmmhello 已提交
4978 4979 4980 4981
      result += dataLength;
      *(int32_t*)(result) = totalLength - dataLength;
      length = totalLength - dataLength;
    }
wmmhello's avatar
wmmhello 已提交
4982 4983
  }

wmmhello's avatar
wmmhello 已提交
4984 4985
  for (int32_t i = 0; i < ops->numOfDownstream; ++i) {
    code = decodeOperator(ops->pDownstream[i], result, length);
4986
    if (code != TDB_CODE_SUCCESS) {
wmmhello's avatar
wmmhello 已提交
4987
      return code;
wmmhello's avatar
wmmhello 已提交
4988 4989
    }
  }
wmmhello's avatar
wmmhello 已提交
4990
  return TDB_CODE_SUCCESS;
wmmhello's avatar
wmmhello 已提交
4991 4992
}

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

H
Haojun Liao 已提交
4997
  int32_t code = TSDB_CODE_SUCCESS;
D
dapan1121 已提交
4998
  *pTaskInfo = createExecTaskInfo(queryId, taskId, model, pPlan->dbFName);
H
Haojun Liao 已提交
4999 5000 5001 5002
  if (*pTaskInfo == NULL) {
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    goto _complete;
  }
H
Haojun Liao 已提交
5003

dengyihao's avatar
dengyihao 已提交
5004
  (*pTaskInfo)->pRoot = createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId,
dengyihao's avatar
dengyihao 已提交
5005
                                           &(*pTaskInfo)->tableqinfoList, pPlan->pTagCond);
D
dapan1121 已提交
5006
  if (NULL == (*pTaskInfo)->pRoot) {
L
Liu Jicong 已提交
5007
    code = terrno;
D
dapan1121 已提交
5008 5009
    goto _complete;
  }
H
Haojun Liao 已提交
5010

5011
  if ((*pTaskInfo)->pRoot == NULL) {
H
Haojun Liao 已提交
5012
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
H
Haojun Liao 已提交
5013
    goto _complete;
5014 5015
  }

H
Haojun Liao 已提交
5016 5017
  return code;

H
Haojun Liao 已提交
5018
_complete:
wafwerar's avatar
wafwerar 已提交
5019
  taosMemoryFreeClear(*pTaskInfo);
H
Haojun Liao 已提交
5020 5021 5022

  terrno = code;
  return code;
H
Haojun Liao 已提交
5023 5024
}

H
Haojun Liao 已提交
5025
void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo) {
5026 5027 5028 5029 5030 5031 5032 5033
  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 已提交
5034 5035 5036 5037 5038 5039 5040 5041 5042 5043
  //  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;
  //  }
5044 5045

  pResultInfo->threshold = (int32_t)(pResultInfo->capacity * THRESHOLD_RATIO);
H
Haojun Liao 已提交
5046
  pResultInfo->totalRows = 0;
5047 5048
}

L
Liu Jicong 已提交
5049
// TODO refactor
5050
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
L
Liu Jicong 已提交
5051 5052 5053
  if (pFilter == NULL || numOfFilters == 0) {
    return;
  }
5054

L
Liu Jicong 已提交
5055 5056 5057
  for (int32_t i = 0; i < numOfFilters; i++) {
    if (pFilter[i].filterstr && pFilter[i].pz) {
      taosMemoryFree((void*)(pFilter[i].pz));
5058
    }
L
Liu Jicong 已提交
5059
  }
5060

L
Liu Jicong 已提交
5061
  taosMemoryFree(pFilter);
5062 5063
}

wmmhello's avatar
wmmhello 已提交
5064 5065 5066
static void doDestroyTableList(STableListInfo* pTableqinfoList) {
  taosArrayDestroy(pTableqinfoList->pTableList);
  taosHashCleanup(pTableqinfoList->map);
5067

wmmhello's avatar
wmmhello 已提交
5068 5069
  pTableqinfoList->pTableList = NULL;
  pTableqinfoList->map = NULL;
5070 5071
}

L
Liu Jicong 已提交
5072
void doDestroyTask(SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
5073 5074
  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));

wmmhello's avatar
wmmhello 已提交
5075
  doDestroyTableList(&pTaskInfo->tableqinfoList);
H
Haojun Liao 已提交
5076
  destroyOperatorInfo(pTaskInfo->pRoot);
L
Liu Jicong 已提交
5077 5078
  //  taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
  //  taosHashCleanup(pTaskInfo->summary.operatorProfResults);
5079

5080 5081
  taosMemoryFree(pTaskInfo->schemaVer.dbname);
  taosMemoryFree(pTaskInfo->schemaVer.tablename);
wafwerar's avatar
wafwerar 已提交
5082 5083 5084
  taosMemoryFreeClear(pTaskInfo->sql);
  taosMemoryFreeClear(pTaskInfo->id.str);
  taosMemoryFreeClear(pTaskInfo);
5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096
}

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 已提交
5097
      int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109
      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 已提交
5110 5111
  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
  return (int64_t)(s1 * 1.5 * numOfTables);
5112 5113 5114 5115 5116 5117 5118
}

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 已提交
5119
    while (1) {
5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145
      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 已提交
5146

dengyihao's avatar
dengyihao 已提交
5147 5148
int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo** pRes, int32_t* capacity,
                                   int32_t* resNum) {
D
dapan1121 已提交
5149 5150
  if (*resNum >= *capacity) {
    *capacity += 10;
dengyihao's avatar
dengyihao 已提交
5151

D
dapan1121 已提交
5152 5153
    *pRes = taosMemoryRealloc(*pRes, (*capacity) * sizeof(SExplainExecInfo));
    if (NULL == *pRes) {
D
dapan1121 已提交
5154
      qError("malloc %d failed", (*capacity) * (int32_t)sizeof(SExplainExecInfo));
D
dapan1121 已提交
5155 5156 5157 5158
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

5159 5160 5161 5162 5163
  SExplainExecInfo* pInfo = &(*pRes)[*resNum];

  pInfo->numOfRows = operatorInfo->resultInfo.totalRows;
  pInfo->startupCost = operatorInfo->cost.openCost;
  pInfo->totalCost = operatorInfo->cost.totalCost;
D
dapan1121 已提交
5164

5165
  if (operatorInfo->fpSet.getExplainFn) {
5166
    int32_t code = operatorInfo->fpSet.getExplainFn(operatorInfo, &pInfo->verboseInfo, &pInfo->verboseLen);
D
dapan1121 已提交
5167
    if (code) {
5168
      qError("%s operator getExplainFn failed, code:%s", GET_TASKID(operatorInfo->pTaskInfo), tstrerror(code));
D
dapan1121 已提交
5169 5170
      return code;
    }
5171 5172 5173
  } else {
    pInfo->verboseLen = 0;
    pInfo->verboseInfo = NULL;
D
dapan1121 已提交
5174
  }
dengyihao's avatar
dengyihao 已提交
5175

D
dapan1121 已提交
5176
  ++(*resNum);
dengyihao's avatar
dengyihao 已提交
5177

D
dapan1121 已提交
5178
  int32_t code = 0;
D
dapan1121 已提交
5179 5180
  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pRes, capacity, resNum);
D
dapan1121 已提交
5181 5182 5183 5184 5185 5186 5187
    if (code) {
      taosMemoryFreeClear(*pRes);
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
5188
}
5
54liuyao 已提交
5189

5
54liuyao 已提交
5190 5191
int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, const char* pKey,
    size_t size) {
5
54liuyao 已提交
5192 5193
  pSup->keySize = sizeof(int64_t) + sizeof(TSKEY);
  pSup->pKeyBuf = taosMemoryCalloc(1, pSup->keySize);
5
54liuyao 已提交
5194
  pSup->pResultRows = taosArrayInit(1024, size);
5
54liuyao 已提交
5195 5196 5197 5198
  if (pSup->pKeyBuf == NULL || pSup->pResultRows == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

5
54liuyao 已提交
5199 5200
  pSup->pScanWindow = taosArrayInit(4, sizeof(STimeWindow));

5
54liuyao 已提交
5201 5202 5203 5204 5205 5206 5207 5208 5209
  int32_t pageSize = 4096;
  while (pageSize < pSup->resultRowSize * 4) {
    pageSize <<= 1u;
  }
  // at least four pages need to be in buffer
  int32_t bufSize = 4096 * 256;
  if (bufSize <= pageSize) {
    bufSize = pageSize * 4;
  }
wafwerar's avatar
wafwerar 已提交
5210
  return createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, pKey, TD_TMP_DIR_PATH);
5
54liuyao 已提交
5211
}
5
54liuyao 已提交
5212

5
54liuyao 已提交
5213 5214 5215 5216 5217 5218 5219 5220
int32_t initSessionAggSupporter(SStreamAggSupporter* pSup, const char* pKey) {
  return initStreamAggSupporter(pSup, pKey, sizeof(SResultWindowInfo));
}

int32_t initStateAggSupporter(SStreamAggSupporter* pSup, const char* pKey) {
  return initStreamAggSupporter(pSup, pKey, sizeof(SStateWindowInfo));
}

5
54liuyao 已提交
5221 5222
int64_t getSmaWaterMark(int64_t interval, double filesFactor) {
  int64_t waterMark = 0;
X
Xiaoyu Wang 已提交
5223
  ASSERT(FLT_GREATEREQUAL(filesFactor, 0.000000));
5
54liuyao 已提交
5224 5225 5226 5227 5228
  waterMark = -1 * filesFactor;
  return waterMark;
}

bool isSmaStream(int8_t triggerType) {
X
Xiaoyu Wang 已提交
5229
  if (triggerType == STREAM_TRIGGER_AT_ONCE || triggerType == STREAM_TRIGGER_WINDOW_CLOSE) {
5
54liuyao 已提交
5230 5231 5232
    return false;
  }
  return true;
5
54liuyao 已提交
5233
}