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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; }

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

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

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

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

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

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

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

  tw->ekey -= 1;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

dengyihao's avatar
dengyihao 已提交
231 232 233
static int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
                                  SGroupResInfo* pGroupResInfo, int32_t orderType, int32_t* rowCellOffset,
                                  SqlFunctionCtx* pCtx);
H
Haojun Liao 已提交
234

235
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
H
Haojun Liao 已提交
236
static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo);
dengyihao's avatar
dengyihao 已提交
237 238
static void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId,
                                     SExecTaskInfo* pTaskInfo);
239

H
Haojun Liao 已提交
240
SArray* getOrderCheckColumns(STaskAttr* pQuery);
241 242

typedef struct SRowCompSupporter {
L
Liu Jicong 已提交
243 244 245
  STaskRuntimeEnv* pRuntimeEnv;
  int16_t          dataOffset;
  __compar_fn_t    comFunc;
246 247
} SRowCompSupporter;

L
Liu Jicong 已提交
248 249 250
static int compareRowData(const void* a, const void* b, const void* userData) {
  const SResultRow* pRow1 = (const SResultRow*)a;
  const SResultRow* pRow2 = (const SResultRow*)b;
251

L
Liu Jicong 已提交
252 253
  SRowCompSupporter* supporter = (SRowCompSupporter*)userData;
  STaskRuntimeEnv*   pRuntimeEnv = supporter->pRuntimeEnv;
254

L
Liu Jicong 已提交
255 256
  SFilePage* page1 = getBufPage(pRuntimeEnv->pResultBuf, pRow1->pageId);
  SFilePage* page2 = getBufPage(pRuntimeEnv->pResultBuf, pRow2->pageId);
257 258

  int16_t offset = supporter->dataOffset;
L
Liu Jicong 已提交
259 260
  char*   in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
  char*   in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
261 262 263 264

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

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

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

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

L
Liu Jicong 已提交
275
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
276
    SColumnInfoData idata = {{0}};
L
Liu Jicong 已提交
277
    SSlotDescNode*  pDescNode = nodesListGetNode(pNode->pSlots, i);
H
Haojun Liao 已提交
278 279
    if (!pDescNode->output) {
      continue;
H
Haojun Liao 已提交
280
    }
H
Haojun Liao 已提交
281

dengyihao's avatar
dengyihao 已提交
282
    idata.info.type = pDescNode->dataType.type;
L
Liu Jicong 已提交
283 284
    idata.info.bytes = pDescNode->dataType.bytes;
    idata.info.scale = pDescNode->dataType.scale;
H
Haojun Liao 已提交
285
    idata.info.slotId = pDescNode->slotId;
H
Haojun Liao 已提交
286 287
    idata.info.precision = pDescNode->dataType.precision;

H
Hongze Cheng 已提交
288 289 290 291
    if (IS_VAR_DATA_TYPE(idata.info.type)) {
      pBlock->info.hasVarCol = true;
    }

H
Haojun Liao 已提交
292
    taosArrayPush(pBlock->pDataBlock, &idata);
H
Haojun Liao 已提交
293
  }
H
Haojun Liao 已提交
294

295
  pBlock->info.numOfCols = taosArrayGetSize(pBlock->pDataBlock);
H
Haojun Liao 已提交
296
  return pBlock;
H
Haojun Liao 已提交
297 298
}

L
Liu Jicong 已提交
299
static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
dengyihao's avatar
dengyihao 已提交
300 301
  if (TSDB_COL_IS_TAG(pColumn->flag) || TSDB_COL_IS_UD_COL(pColumn->flag) ||
      pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
302 303 304 305 306 307 308 309 310 311
    return false;
  }

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

  return true;
}

H
Haojun Liao 已提交
312
static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) {
313 314
  int64_t newCapacity = 0;

315 316 317 318 319 320 321 322 323 324 325
  // more than the capacity, reallocate the resources
  if (pResultRowInfo->size < pResultRowInfo->capacity) {
    return;
  }

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

326
  if (newCapacity <= pResultRowInfo->capacity) {
H
Haojun Liao 已提交
327 328 329
    newCapacity += 4;
  }

330 331 332 333 334 335
  char* p = taosMemoryRealloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition));
  if (p == NULL) {
    longjmp(env, TSDB_CODE_OUT_OF_MEMORY);
  }

  pResultRowInfo->pPosition = (SResultRowPosition*)p;
336 337

  int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity;
wmmhello's avatar
wmmhello 已提交
338
  memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition) * inc);
339 340 341
  pResultRowInfo->capacity = (int32_t)newCapacity;
}

L
Liu Jicong 已提交
342 343
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
                                int16_t bytes, bool masterscan, uint64_t uid) {
344 345 346
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);

L
Liu Jicong 已提交
347 348
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
349 350 351 352 353 354 355 356 357 358 359

  // 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 已提交
360
        //        existed = (pResultRowInfo->pResult[0] == (*p1));
361 362
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid, pResultRowInfo);
L
Liu Jicong 已提交
363 364
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
365 366 367 368 369 370 371 372 373 374 375 376 377 378
        if (index != NULL) {
          existed = true;
        } else {
          existed = false;
        }
      }
    }

    return existed;
  }

  return p1 != NULL;
}

379
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
L
Liu Jicong 已提交
380
  SFilePage* pData = NULL;
381 382 383 384 385 386 387 388 389 390 391 392 393

  // 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 已提交
394
    if (pData->num + interBufSize > getBufPageSize(pResultBuf)) {
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
      // release current page first, and prepare the next one
      releaseBufPageInfo(pResultBuf, pi);

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

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

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

wmmhello's avatar
wmmhello 已提交
414
  pData->num += interBufSize;
415 416 417 418

  return pResultRow;
}

419 420 421 422 423 424 425
/**
 * the struct of key in hash table
 * +----------+---------------+
 * | group id |   key data    |
 * | 8 bytes  | actual length |
 * +----------+---------------+
 */
426
static SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, int64_t uid,
427
                                             char* pData, int16_t bytes, bool masterscan, uint64_t groupId,
L
Liu Jicong 已提交
428
                                             SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup) {
429
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
H
Haojun Liao 已提交
430

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

434 435
  SResultRow* pResult = NULL;

H
Haojun Liao 已提交
436 437
  // in case of repeat scan/reverse scan, no new time window added.
  if (isIntervalQuery) {
438 439
    if (masterscan && p1 != NULL) {  // the *p1 may be NULL in case of sliding+offset exists.
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
440 441
    }
  } else {
dengyihao's avatar
dengyihao 已提交
442 443
    // In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
    // pResultRowInfo object.
H
Haojun Liao 已提交
444
    if (p1 != NULL) {
445
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
446 447 448
    }
  }

H
Haojun Liao 已提交
449
    // 1. close current opened time window
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
  if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
                                            pResult->offset != pResultRowInfo->cur.offset))) {
    // todo extract function
    SResultRowPosition pos = pResultRowInfo->cur;
    SFilePage*         pPage = getBufPage(pResultBuf, pos.pageId);
    SResultRow*        pRow = (SResultRow*)((char*)pPage + pos.offset);
    closeResultRow(pRow);
    releaseBufPage(pResultBuf, pPage);
  }

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

466 467 468
    // add a new result set for a new group
    SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
    taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos, sizeof(SResultRowPosition));
H
Haojun Liao 已提交
469 470
  }

471 472 473 474 475
  // 2. set the new time window to be the new active time window
  pResultRowInfo->pPosition[pResultRowInfo->size++] =
      (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
  pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};

H
Haojun Liao 已提交
476 477 478 479 480
  // too many time window in query
  if (pResultRowInfo->size > MAX_INTERVAL_TIME_WINDOW) {
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
  }

H
Haojun Liao 已提交
481
  return pResult;
H
Haojun Liao 已提交
482 483
}

dengyihao's avatar
dengyihao 已提交
484 485
static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, TSKEY ts, STimeWindow* w,
                                      bool ascQuery) {
H
Haojun Liao 已提交
486
  if (ascQuery) {
487
    getAlignQueryTimeWindow(pInterval, precision, ts, w);
488 489
  } else {
    // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
490
    getAlignQueryTimeWindow(pInterval, precision, ts, w);
491 492

    int64_t key = w->skey;
L
Liu Jicong 已提交
493
    while (key < ts) {  // moving towards end
494
      key = taosTimeAdd(key, pInterval->sliding, pInterval->slidingUnit, precision);
495 496 497 498 499 500 501 502 503 504
      if (key >= ts) {
        break;
      }

      w->skey = key;
    }
  }
}

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

509
  if (pResultRowInfo->cur.pageId == -1) {  // the first window, from the previous stored value
510
    getInitialStartTimeWindow(pInterval, precision, ts, &w, true);
511
    w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
512
  } else {
513
    w = getResultRowByPos(pBuf, &pResultRowInfo->cur)->win;
514 515 516
  }

  if (w.skey > ts || w.ekey < ts) {
H
Haojun Liao 已提交
517 518 519
    if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
      w.skey = taosTimeTruncate(ts, pInterval, precision);
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
520 521 522 523
    } else {
      int64_t st = w.skey;

      if (st > ts) {
H
Haojun Liao 已提交
524
        st -= ((st - ts + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
525 526
      }

H
Haojun Liao 已提交
527
      int64_t et = st + pInterval->interval - 1;
528
      if (et < ts) {
H
Haojun Liao 已提交
529
        st += ((ts - et + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
530 531 532
      }

      w.skey = st;
533
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
534 535 536 537 538 539
    }
  }
  return w;
}

// get the correct time window according to the handled timestamp
L
Liu Jicong 已提交
540
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo* pResultRowInfo, int64_t ts, STaskAttr* pQueryAttr) {
541
  STimeWindow w = {0};
H
Haojun Liao 已提交
542
#if 0
L
Liu Jicong 已提交
543 544
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
                                       //    getInitialStartTimeWindow(pQueryAttr, ts, &w);
545 546

    if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') {
L
Liu Jicong 已提交
547 548 549
      w.ekey =
          taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) -
          1;
550 551 552 553
    } else {
      w.ekey = w.skey + pQueryAttr->interval.interval - 1;
    }
  } else {
H
Haojun Liao 已提交
554
    w = pRow->win;
555 556 557 558 559 560 561 562 563
  }

  /*
   * 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 已提交
564
#endif
565 566 567 568 569

  return w;
}

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

L
Liu Jicong 已提交
575
  SFilePage* pData = NULL;
576 577 578 579 580 581

  // 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 已提交
582
    pData = getNewBufPage(pResultBuf, tid, &pageId);
583
    pData->num = sizeof(SFilePage);
584 585
  } else {
    SPageInfo* pi = getLastPageInfo(list);
586
    pData = getBufPage(pResultBuf, getPageId(pi));
587
    pageId = getPageId(pi);
588

589
    if (pData->num + size > getBufPageSize(pResultBuf)) {
590
      // release current page first, and prepare the next one
591
      releaseBufPageInfo(pResultBuf, pi);
592

H
Haojun Liao 已提交
593
      pData = getNewBufPage(pResultBuf, tid, &pageId);
594
      if (pData != NULL) {
595
        pData->num = sizeof(SFilePage);
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
      }
    }
  }

  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 已提交
616 617 618
static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, STimeWindow* win,
                                    bool masterscan, SResultRow** pResult, int64_t groupId, SqlFunctionCtx* pCtx,
                                    int32_t numOfOutput, int32_t* rowCellInfoOffset) {
619
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
620
  return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char*)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
621 622
}

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

L
Liu Jicong 已提交
626 627 628 629
static int32_t setResultOutputBufByKey_rv(SResultRowInfo* pResultRowInfo, int64_t id, STimeWindow* win, bool masterscan,
                                          SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx,
                                          int32_t numOfOutput, int32_t* rowCellInfoOffset, SAggSupporter* pAggSup,
                                          SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
630
  assert(win->skey <= win->ekey);
631
  SResultRow* pResultRow = doSetResultOutBufByKey(pAggSup->pResultBuf, pResultRowInfo, id, (char*)&win->skey,
L
Liu Jicong 已提交
632
                                                     TSDB_KEYSIZE, masterscan, tableGroupId, pTaskInfo, true, pAggSup);
H
Haojun Liao 已提交
633 634 635 636 637 638 639 640 641

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

  // set time window for current result
  pResultRow->win = (*win);
  *pResult = pResultRow;
H
Haojun Liao 已提交
642
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
H
Haojun Liao 已提交
643 644 645
  return TSDB_CODE_SUCCESS;
}

646 647 648 649 650
static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
  assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
  if (type == RESULT_ROW_START_INTERP) {
    pResult->startInterp = true;
  } else {
L
Liu Jicong 已提交
651
    pResult->endInterp = true;
652 653 654 655 656 657 658 659
  }
}

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

L
Liu Jicong 已提交
664 665
static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey,
                                                   int16_t pos, int16_t order, int64_t* pData) {
666 667 668
  int32_t forwardStep = 0;

  if (order == TSDB_ORDER_ASC) {
L
Liu Jicong 已提交
669
    int32_t end = searchFn((char*)&pData[pos], numOfRows - pos, ekey, order);
670 671 672 673 674 675 676 677
    if (end >= 0) {
      forwardStep = end;

      if (pData[end + pos] == ekey) {
        forwardStep += 1;
      }
    }
  } else {
L
Liu Jicong 已提交
678
    int32_t end = searchFn((char*)pData, pos + 1, ekey, order);
679 680 681 682 683 684 685 686 687 688 689 690 691
    if (end >= 0) {
      forwardStep = pos - end;

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

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

dengyihao's avatar
dengyihao 已提交
692 693
static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey, bool ascQuery,
                                   bool timeWindowInterpo) {
694
  int64_t skey = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
695
#if 0
696 697
  int32_t i = 0;
  for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
698
    SResultRow* pResult = pResultRowInfo->pResult[i];
699 700 701 702 703 704
    if (pResult->closed) {
      break;
    }

    // new closed result rows
    if (timeWindowInterpo) {
L
Liu Jicong 已提交
705 706 707
      if (pResult->endInterp &&
          ((pResult->win.skey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery))) {
        if (i > 0) {  // the first time window, the startInterp is false.
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
          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 已提交
727
      //      assert(pResultRowInfo->current == NULL);
728 729 730 731 732 733 734
      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 已提交
735
      SResultRow* pResult = pResultRowInfo->pResult[i];
736 737 738 739 740 741 742 743 744 745 746
      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 已提交
747
#endif
748
}
749
//
dengyihao's avatar
dengyihao 已提交
750
// static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
751 752 753 754 755 756 757 758 759
//                                           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);
//  }
//}
760

L
Liu Jicong 已提交
761 762 763
static int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos,
                                        TSKEY ekey, __block_search_fn_t searchFn, STableQueryInfo* item,
                                        int32_t order) {
764 765
  assert(startPos >= 0 && startPos < pDataBlockInfo->rows);

L
Liu Jicong 已提交
766 767
  int32_t num = -1;
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
768

H
Haojun Liao 已提交
769
  if (order == TSDB_ORDER_ASC) {
770 771
    if (ekey < pDataBlockInfo->window.ekey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
772
      if (item != NULL) {
773 774 775 776
        item->lastKey = pPrimaryColumn[startPos + (num - 1)] + step;
      }
    } else {
      num = pDataBlockInfo->rows - startPos;
H
Haojun Liao 已提交
777
      if (item != NULL) {
778 779 780 781 782 783
        item->lastKey = pDataBlockInfo->window.ekey + step;
      }
    }
  } else {  // desc
    if (ekey > pDataBlockInfo->window.skey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
784
      if (item != NULL) {
785 786 787 788
        item->lastKey = pPrimaryColumn[startPos - (num - 1)] + step;
      }
    } else {
      num = startPos + 1;
H
Haojun Liao 已提交
789
      if (item != NULL) {
790 791 792 793 794 795 796 797 798
        item->lastKey = pDataBlockInfo->window.skey + step;
      }
    }
  }

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

799 800 801 802 803
//  query_range_start, query_range_end, window_duration, window_start, window_end
static void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow) {
  pColData->info.type = TSDB_DATA_TYPE_TIMESTAMP;
  pColData->info.bytes = sizeof(int64_t);

804
  colInfoDataEnsureCapacity(pColData, 0, 5);
805 806 807 808 809 810 811 812 813
  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);
}

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

818
  int64_t duration = pWin->ekey - pWin->skey + delta;
dengyihao's avatar
dengyihao 已提交
819 820 821
  ts[2] = duration;            // set the duration
  ts[3] = pWin->skey;          // window start key
  ts[4] = pWin->ekey + delta;  // window end key
822 823
}

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

H
Haojun Liao 已提交
829
    // keep it temporarily
dengyihao's avatar
dengyihao 已提交
830 831
    bool    hasAgg = pCtx[k].input.colDataAggIsSet;
    int32_t numOfRows = pCtx[k].input.numOfRows;
H
Haojun Liao 已提交
832
    int32_t startOffset = pCtx[k].input.startRowIndex;
833

H
Haojun Liao 已提交
834
    int32_t pos = (order == TSDB_ORDER_ASC) ? offset : offset - (forwardStep - 1);
835 836
    pCtx[k].input.startRowIndex = pos;
    pCtx[k].input.numOfRows = forwardStep;
837 838

    if (tsCol != NULL) {
H
Haojun Liao 已提交
839
      pCtx[k].ptsList = tsCol;
840 841 842 843 844 845 846 847
    }

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

848 849
    if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
      SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
dengyihao's avatar
dengyihao 已提交
850
      char*                p = GET_ROWCELL_INTERBUF(pEntryInfo);
851

852
      SColumnInfoData idata = {0};
dengyihao's avatar
dengyihao 已提交
853
      idata.info.type = TSDB_DATA_TYPE_BIGINT;
854
      idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
dengyihao's avatar
dengyihao 已提交
855
      idata.pData = p;
856 857 858 859

      SScalarParam out = {.columnData = &idata};
      SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
      pCtx[k].sfp.process(&tw, 1, &out);
860 861 862 863
      pEntryInfo->numOfRes = 1;
      continue;
    }

H
Haojun Liao 已提交
864
    if (functionNeedToExecute(&pCtx[k])) {
865
      pCtx[k].fpSet.process(&pCtx[k]);
866 867 868
    }

    // restore it
869 870 871
    pCtx[k].input.colDataAggIsSet = hasAgg;
    pCtx[k].input.startRowIndex = startOffset;
    pCtx[k].input.numOfRows = numOfRows;
872 873 874
  }
}

H
Haojun Liao 已提交
875 876 877
static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo,
                                      TSKEY* primaryKeys, int32_t prevPosition, STableIntervalOperatorInfo* pInfo) {
  int32_t order = pInfo->order;
L
Liu Jicong 已提交
878
  bool    ascQuery = (order == TSDB_ORDER_ASC);
H
Haojun Liao 已提交
879

880
  int32_t precision = pInterval->precision;
H
Haojun Liao 已提交
881
  getNextTimeWindow(pInterval, precision, order, pNext);
882 883

  // next time window is not in current block
H
Haojun Liao 已提交
884 885
  if ((pNext->skey > pDataBlockInfo->window.ekey && order == TSDB_ORDER_ASC) ||
      (pNext->ekey < pDataBlockInfo->window.skey && order == TSDB_ORDER_DESC)) {
886 887 888
    return -1;
  }

L
Liu Jicong 已提交
889
  TSKEY   startKey = ascQuery ? pNext->skey : pNext->ekey;
890 891 892
  int32_t startPos = 0;

  // tumbling time window query, a special case of sliding time window query
H
Haojun Liao 已提交
893 894
  if (pInterval->sliding == pInterval->interval && prevPosition != -1) {
    int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
895 896
    startPos = prevPosition + factor;
  } else {
H
Haojun Liao 已提交
897
    if (startKey <= pDataBlockInfo->window.skey && ascQuery) {
898
      startPos = 0;
H
Haojun Liao 已提交
899
    } else if (startKey >= pDataBlockInfo->window.ekey && !ascQuery) {
900 901
      startPos = pDataBlockInfo->rows - 1;
    } else {
L
Liu Jicong 已提交
902
      startPos = binarySearchForKey((char*)primaryKeys, pDataBlockInfo->rows, startKey, order);
903 904 905 906
    }
  }

  /* interp query with fill should not skip time window */
L
Liu Jicong 已提交
907 908 909
  //  if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
  //    return startPos;
  //  }
910 911 912 913 914 915

  /*
   * This time window does not cover any data, try next time window,
   * this case may happen when the time window is too small
   */
  if (primaryKeys == NULL) {
H
Haojun Liao 已提交
916
    if (ascQuery) {
917 918 919 920 921
      assert(pDataBlockInfo->window.skey <= pNext->ekey);
    } else {
      assert(pDataBlockInfo->window.ekey >= pNext->skey);
    }
  } else {
H
Haojun Liao 已提交
922
    if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
923
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
924 925 926
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
927
      } else {
L
Liu Jicong 已提交
928
        pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
H
Haojun Liao 已提交
929
        pNext->skey = pNext->ekey - pInterval->interval + 1;
930
      }
H
Haojun Liao 已提交
931
    } else if ((!ascQuery) && primaryKeys[startPos] < pNext->skey) {
932
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
933 934 935
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
936
      } else {
H
Haojun Liao 已提交
937 938
        pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
        pNext->ekey = pNext->skey + pInterval->interval - 1;
939 940 941 942 943 944 945
      }
    }
  }

  return startPos;
}

L
Liu Jicong 已提交
946
static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* pWindow) {
dengyihao's avatar
dengyihao 已提交
947
  TSKEY   ekey = -1;
948 949
  int32_t order = TSDB_ORDER_ASC;
  if (order == TSDB_ORDER_ASC) {
950 951 952 953 954 955 956 957 958 959 960 961 962 963
    ekey = pWindow->ekey;
    if (ekey > pQueryAttr->window.ekey) {
      ekey = pQueryAttr->window.ekey;
    }
  } else {
    ekey = pWindow->skey;
    if (ekey < pQueryAttr->window.ekey) {
      ekey = pQueryAttr->window.ekey;
    }
  }

  return ekey;
}

H
Haojun Liao 已提交
964
static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t type) {
965 966 967 968 969 970 971 972 973 974 975
  if (type == RESULT_ROW_START_INTERP) {
    for (int32_t k = 0; k < numOfOutput; ++k) {
      pCtx[k].start.key = INT64_MIN;
    }
  } else {
    for (int32_t k = 0; k < numOfOutput; ++k) {
      pCtx[k].end.key = INT64_MIN;
    }
  }
}

H
Haojun Liao 已提交
976
static void saveDataBlockLastRow(char** pRow, SArray* pDataBlock, int32_t rowIndex, int32_t numOfCols) {
977 978 979 980
  if (pDataBlock == NULL) {
    return;
  }

H
Haojun Liao 已提交
981
  for (int32_t k = 0; k < numOfCols; ++k) {
L
Liu Jicong 已提交
982
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, k);
H
Haojun Liao 已提交
983
    memcpy(pRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes);
984 985 986
  }
}

H
Haojun Liao 已提交
987
static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols, int32_t rows, bool ascQuery) {
988 989
  TSKEY ts = TSKEY_INITIAL_VAL;
  if (tsCols == NULL) {
L
Liu Jicong 已提交
990
    ts = ascQuery ? win->skey : win->ekey;
991
  } else {
L
Liu Jicong 已提交
992
    int32_t offset = ascQuery ? 0 : rows - 1;
993 994 995 996 997 998
    ts = tsCols[offset];
  }

  return ts;
}

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

dengyihao's avatar
dengyihao 已提交
1002 1003
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
                                    int32_t order) {
1004 1005
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
    pCtx[i].order = order;
L
Liu Jicong 已提交
1006
    pCtx[i].size = pBlock->info.rows;
1007
    setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
1008 1009 1010
  }
}

dengyihao's avatar
dengyihao 已提交
1011 1012
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                       bool createDummyCol) {
1013
  if (pBlock->pBlockAgg != NULL) {
H
Haojun Liao 已提交
1014
    doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
1015
  } else {
1016
    doSetInputDataBlock(pOperator, pCtx, pBlock, order, createDummyCol);
H
Haojun Liao 已提交
1017
  }
1018 1019
}

dengyihao's avatar
dengyihao 已提交
1020 1021
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t type,
                                             int32_t paramIndex, int32_t numOfRows) {
1022 1023 1024 1025 1026 1027 1028 1029
  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)
dengyihao's avatar
dengyihao 已提交
1030 1031
    pColInfo->info.type = type;
    pColInfo->info.bytes = tDataTypes[type].bytes;
1032 1033

    pInput->pData[paramIndex] = pColInfo;
1034 1035
  } else {
    pColInfo = pInput->pData[paramIndex];
1036 1037 1038
  }

  ASSERT(!IS_VAR_DATA_TYPE(type));
1039
  colInfoDataEnsureCapacity(pColInfo, 0, numOfRows);
1040 1041 1042

  if (type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_UBIGINT) {
    int64_t v = pFuncParam->param.i;
dengyihao's avatar
dengyihao 已提交
1043
    for (int32_t i = 0; i < numOfRows; ++i) {
1044 1045 1046 1047
      colDataAppendInt64(pColInfo, i, &v);
    }
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
dengyihao's avatar
dengyihao 已提交
1048
    for (int32_t i = 0; i < numOfRows; ++i) {
1049 1050 1051 1052 1053 1054 1055
      colDataAppendDouble(pColInfo, i, &v);
    }
  }

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
1056 1057
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                                   bool createDummyCol) {
1058 1059
  int32_t code = TSDB_CODE_SUCCESS;

1060
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
1061 1062 1063
    pCtx[i].order      = order;
    pCtx[i].size       = pBlock->info.rows;
    pCtx[i].pSrcBlock  = pBlock;
H
Haojun Liao 已提交
1064 1065
    pCtx[i].currentStage = MAIN_SCAN;

1066
    SInputColumnInfoData* pInput = &pCtx[i].input;
1067
    pInput->uid = pBlock->info.uid;
C
Cary Xu 已提交
1068
    pInput->colDataAggIsSet = false;
1069

1070 1071
    SExprInfo* pOneExpr = &pOperator->pExpr[i];
    for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
dengyihao's avatar
dengyihao 已提交
1072
      SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
G
Ganlin Zhao 已提交
1073 1074
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
dengyihao's avatar
dengyihao 已提交
1075
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
1076 1077 1078
        pInput->totalRows = pBlock->info.rows;
        pInput->numOfRows = pBlock->info.rows;
        pInput->startRowIndex = 0;
1079

dengyihao's avatar
dengyihao 已提交
1080
        pInput->pPTS = taosArrayGet(pBlock->pDataBlock, 0);  // todo set the correct timestamp column
1081 1082
        ASSERT(pInput->pData[j] != NULL);
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
1083 1084 1085
        // 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) {
1086 1087 1088 1089
          pInput->totalRows = pBlock->info.rows;
          pInput->numOfRows = pBlock->info.rows;
          pInput->startRowIndex = 0;

1090 1091 1092 1093
          code = doCreateConstantValColumnInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
          if (code != TSDB_CODE_SUCCESS) {
            return code;
          }
1094
        }
G
Ganlin Zhao 已提交
1095 1096
      }
    }
H
Haojun Liao 已提交
1097

H
Haojun Liao 已提交
1098
    //    setBlockStatisInfo(&pCtx[i], pBlock, pOperator->pExpr[i].base.pColumns);
H
Haojun Liao 已提交
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
    //      uint32_t flag = pOperator->pExpr[i].base.pParam[0].pCol->flag;
    //      if (TSDB_COL_IS_NORMAL_COL(flag) /*|| (pCtx[i].functionId == FUNCTION_BLKINFO) ||
    //          (TSDB_COL_IS_TAG(flag) && pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)*/) {

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

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

  return code;
H
Haojun Liao 已提交
1139 1140 1141
}

static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
1142
  for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
H
Haojun Liao 已提交
1143
    if (functionNeedToExecute(&pCtx[k])) {
L
Liu Jicong 已提交
1144
      pCtx[k].startTs = startTs;  // this can be set during create the struct
H
Haojun Liao 已提交
1145
      pCtx[k].fpSet.process(&pCtx[k]);
1146 1147 1148 1149
    }
  }
}

H
Haojun Liao 已提交
1150
static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, SArray* pPseudoList) {
dengyihao's avatar
dengyihao 已提交
1151
  size_t num = (pPseudoList != NULL) ? taosArrayGetSize(pPseudoList) : 0;
H
Haojun Liao 已提交
1152 1153 1154 1155 1156
  for (int32_t i = 0; i < num; ++i) {
    pCtx[i].pOutput = taosArrayGet(pResult->pDataBlock, i);
  }
}

dengyihao's avatar
dengyihao 已提交
1157 1158
void projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
                           int32_t numOfOutput, SArray* pPseudoList) {
H
Haojun Liao 已提交
1159
  setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
H
Haojun Liao 已提交
1160
  pResult->info.groupId = pSrcBlock->info.groupId;
H
Haojun Liao 已提交
1161

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

1166 1167
  int32_t numOfRows = 0;

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

L
Liu Jicong 已提交
1172
    if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) {  // it is a project query
1173
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
1174
      if (pResult->info.rows > 0 && !createNewColModel) {
1175 1176 1177 1178
        colDataMergeCol(pColInfoData, pResult->info.rows, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      } else {
        colDataAssign(pColInfoData, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      }
1179

1180
      numOfRows = pfCtx->input.numOfRows;
1181
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_VALUE) {
1182
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
1183

dengyihao's avatar
dengyihao 已提交
1184
      int32_t offset = createNewColModel ? 0 : pResult->info.rows;
1185
      for (int32_t i = 0; i < pSrcBlock->info.rows; ++i) {
dengyihao's avatar
dengyihao 已提交
1186 1187 1188
        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);
1189
      }
1190 1191

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

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

1199
      SScalarParam dest = {.columnData = &idata};
1200 1201
      scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);

dengyihao's avatar
dengyihao 已提交
1202
      int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
1203
      colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
1204 1205

      numOfRows = dest.numOfRows;
1206 1207
      taosArrayDestroy(pBlockList);
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) {
1208
      ASSERT(!fmIsAggFunc(pfCtx->functionId));
1209

1210
      if (fmIsPseudoColumnFunc(pfCtx->functionId)) {
H
Haojun Liao 已提交
1211
        // do nothing
1212
      } else if (fmIsNonstandardSQLFunc(pfCtx->functionId)) {
H
Haojun Liao 已提交
1213
        // todo set the correct timestamp column
1214
        pfCtx->input.pPTS = taosArrayGet(pSrcBlock->pDataBlock, 1);
1215

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

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

1222
        // set the timestamp(_rowts) output buffer
1223 1224
        if (taosArrayGetSize(pPseudoList) > 0) {
          int32_t* outputColIndex = taosArrayGet(pPseudoList, 0);
1225
          pfCtx->pTsOutput = (SColumnInfoData*)pCtx[*outputColIndex].pOutput;
1226
        }
H
Haojun Liao 已提交
1227

1228
        numOfRows = pfCtx->fpSet.process(pfCtx);
H
Haojun Liao 已提交
1229 1230 1231
      } else {
        SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
        taosArrayPush(pBlockList, &pSrcBlock);
G
Ganlin Zhao 已提交
1232

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

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

dengyihao's avatar
dengyihao 已提交
1239
        int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
1240
        colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
1241 1242

        numOfRows = dest.numOfRows;
H
Haojun Liao 已提交
1243 1244
        taosArrayDestroy(pBlockList);
      }
1245
    } else {
1246
      ASSERT(0);
1247 1248
    }
  }
1249

1250 1251 1252
  if (!createNewColModel) {
    pResult->info.rows += numOfRows;
  }
1253 1254 1255 1256
}

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

H
Haojun Liao 已提交
1259
  SqlFunctionCtx* pCtx = pInfo->pCtx;
1260 1261 1262 1263 1264 1265 1266 1267

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

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

L
Liu Jicong 已提交
1272
    //    assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
1273 1274 1275
    double v1 = 0, v2 = 0, v = 0;

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

L
Liu Jicong 已提交
1281
    GET_TYPED_DATA(v2, double, pColInfo->info.type, (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes);
1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292

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

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

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

L
Liu Jicong 已提交
1298
          pCtx[k].end.ptr = (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes;
1299 1300 1301
        }
      }
    } else if (functionId == FUNCTION_TWA) {
L
Liu Jicong 已提交
1302 1303 1304
      SPoint point1 = (SPoint){.key = prevTs, .val = &v1};
      SPoint point2 = (SPoint){.key = curTs, .val = &v2};
      SPoint point = (SPoint){.key = windowKey, .val = &v};
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318

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

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

H
Haojun Liao 已提交
1319
static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t pos,
dengyihao's avatar
dengyihao 已提交
1320 1321
                                              int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols,
                                              STimeWindow* win) {
H
Haojun Liao 已提交
1322
  bool  ascQuery = true;
L
Liu Jicong 已提交
1323
  TSKEY curTs = tsCols[pos];
dengyihao's avatar
dengyihao 已提交
1324
  TSKEY lastTs = 0;  //*(TSKEY*)pRuntimeEnv->prevRow[0];
1325 1326 1327

  // lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
  // start exactly from this point, no need to do interpolation
L
Liu Jicong 已提交
1328
  TSKEY key = ascQuery ? win->skey : win->ekey;
1329 1330 1331 1332 1333 1334 1335 1336 1337 1338
  if (key == curTs) {
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
    return true;
  }

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

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

dengyihao's avatar
dengyihao 已提交
1342 1343
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, key,
                            RESULT_ROW_START_INTERP);
1344 1345 1346
  return true;
}

L
Liu Jicong 已提交
1347 1348 1349
static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t endRowIndex,
                                            SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
                                            STimeWindow* win) {
H
Haojun Liao 已提交
1350 1351
  int32_t order = TSDB_ORDER_ASC;
  int32_t numOfOutput = pOperatorInfo->numOfOutput;
1352

L
Liu Jicong 已提交
1353
  TSKEY actualEndKey = tsCols[endRowIndex];
H
Haojun Liao 已提交
1354
  TSKEY key = order ? win->ekey : win->skey;
1355 1356

  // not ended in current data block, do not invoke interpolation
dengyihao's avatar
dengyihao 已提交
1357 1358
  if ((key > blockEkey /*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/) ||
      (key < blockEkey /*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/)) {
1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
    setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP);
    return false;
  }

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

H
Haojun Liao 已提交
1369
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
1370 1371 1372 1373 1374
  int32_t nextRowIndex = endRowIndex + step;
  assert(nextRowIndex >= 0);

  TSKEY nextKey = tsCols[nextRowIndex];
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, actualEndKey, endRowIndex, nextKey,
L
Liu Jicong 已提交
1375
                            nextRowIndex, key, RESULT_ROW_END_INTERP);
1376 1377 1378
  return true;
}

H
Haojun Liao 已提交
1379
static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SqlFunctionCtx* pCtx,
L
Liu Jicong 已提交
1380 1381
                                        SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep,
                                        int32_t order, bool timeWindowInterpo) {
H
Haojun Liao 已提交
1382
  if (!timeWindowInterpo) {
1383 1384 1385 1386
    return;
  }

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

L
Liu Jicong 已提交
1389 1390
  if (pBlock->pDataBlock == NULL) {
    //    tscError("pBlock->pDataBlock == NULL");
1391 1392
    return;
  }
H
Haojun Liao 已提交
1393

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

L
Liu Jicong 已提交
1396 1397 1398
  TSKEY* tsCols = (TSKEY*)(pColInfo->pData);
  bool   done = resultRowInterpolated(pResult, RESULT_ROW_START_INTERP);
  if (!done) {  // it is not interpolated, now start to generated the interpolated value
1399
    int32_t startRowIndex = startPos;
L
Liu Jicong 已提交
1400
    bool    interp = setTimeWindowInterpolationStartTs(pOperatorInfo, pCtx, startRowIndex, pBlock->info.rows,
dengyihao's avatar
dengyihao 已提交
1401
                                                    pBlock->pDataBlock, tsCols, win);
1402 1403 1404 1405
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1406
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1407 1408 1409
  }

  // point interpolation does not require the end key time window interpolation.
L
Liu Jicong 已提交
1410 1411 1412
  //  if (pointInterpQuery) {
  //    return;
  //  }
1413 1414 1415 1416 1417 1418

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

L
Liu Jicong 已提交
1419 1420 1421
    TSKEY endKey = (order == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey;
    bool  interp =
        setTimeWindowInterpolationEndTs(pOperatorInfo, pCtx, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
1422 1423 1424 1425
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1426
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_END_INTERP);
1427 1428 1429
  }
}

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

H
Haojun Liao 已提交
1434
  SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
L
Liu Jicong 已提交
1435
  int32_t        numOfOutput = pOperatorInfo->numOfOutput;
1436

1437 1438
  SArray* pUpdated = NULL;
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1439
    pUpdated = taosArrayInit(4, POINTER_BYTES);
1440 1441
  }

H
Haojun Liao 已提交
1442
  int32_t step = 1;
1443
  bool    ascScan = true;
1444

dengyihao's avatar
dengyihao 已提交
1445
  //  int32_t prevIndex = pResultRowInfo->curPos;
1446 1447 1448

  TSKEY* tsCols = NULL;
  if (pSDataBlock->pDataBlock != NULL) {
1449
    SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
L
Liu Jicong 已提交
1450
    tsCols = (int64_t*)pColDataInfo->pData;
1451 1452
  }

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

dengyihao's avatar
dengyihao 已提交
1456 1457
  STimeWindow win = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval,
                                        pInfo->interval.precision, &pInfo->win);
L
Liu Jicong 已提交
1458
  bool        masterScan = true;
1459 1460

  SResultRow* pResult = NULL;
L
Liu Jicong 已提交
1461
  int32_t     ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult,
dengyihao's avatar
dengyihao 已提交
1462 1463
                                           tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset,
                                           &pInfo->aggSup, pTaskInfo);
1464
  if (ret != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1465
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1466 1467
  }

1468
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1469 1470 1471 1472 1473
    SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
    pos->groupId = tableGroupId;
    pos->pos     = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset};
    *(int64_t*) pos->key = pResult->win.skey;

1474 1475 1476
    taosArrayPush(pUpdated, &pos);
  }

1477
  int32_t forwardStep = 0;
H
Haojun Liao 已提交
1478
  TSKEY   ekey = win.ekey;
1479
  forwardStep =
H
Haojun Liao 已提交
1480
      getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1481 1482

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

#if 0
H
Haojun Liao 已提交
1486
  if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
1487 1488 1489
    for (int32_t j = prevIndex; j < curIndex; ++j) {  // previous time window may be all closed already.
      SResultRow* pRes = getResultRow(pResultRowInfo, j);
      if (pRes->closed) {
1490
        assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
1491 1492 1493
        continue;
      }

L
Liu Jicong 已提交
1494 1495 1496 1497 1498 1499 1500
      STimeWindow w = pRes->win;
      ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &w, masterScan, &pResult, tableGroupId,
                                       pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                       pTaskInfo);
      if (ret != TSDB_CODE_SUCCESS) {
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
      }
1501

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

L
Liu Jicong 已提交
1506 1507
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
      setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1508

1509
      doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
L
Liu Jicong 已提交
1510
    }
1511 1512

    // restore current time window
L
Liu Jicong 已提交
1513 1514 1515
    ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
                                     pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                     pTaskInfo);
1516
    if (ret != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1517
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1518 1519
    }
  }
H
Haojun Liao 已提交
1520
#endif
1521 1522

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

1526
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &win, true);
dengyihao's avatar
dengyihao 已提交
1527 1528
  doApplyFunctions(pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
                   pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1529 1530 1531 1532

  STimeWindow nextWin = win;
  while (1) {
    int32_t prevEndPos = (forwardStep - 1) * step + startPos;
H
Haojun Liao 已提交
1533
    startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, pInfo);
1534 1535 1536 1537 1538
    if (startPos < 0) {
      break;
    }

    // null data, failed to allocate more memory buffer
L
Liu Jicong 已提交
1539 1540 1541
    int32_t code = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &nextWin, masterScan, &pResult,
                                              tableGroupId, pInfo->binfo.pCtx, numOfOutput,
                                              pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1542
    if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1543
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1544 1545
    }

1546
    if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1547 1548 1549 1550 1551
      SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
      pos->groupId = tableGroupId;
      pos->pos     = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset};
      *(int64_t*) pos->key = pResult->win.skey;

1552 1553 1554
      taosArrayPush(pUpdated, &pos);
    }

L
Liu Jicong 已提交
1555 1556 1557
    ekey = nextWin.ekey;  // reviseWindowEkey(pQueryAttr, &nextWin);
    forwardStep =
        getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1558 1559

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

1563
    updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
dengyihao's avatar
dengyihao 已提交
1564 1565
    doApplyFunctions(pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
                     pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1566 1567
  }

H
Haojun Liao 已提交
1568
  if (pInfo->timeWindowInterpo) {
1569
    int32_t rowIndex = ascScan ? (pSDataBlock->info.rows - 1) : 0;
H
Haojun Liao 已提交
1570
    saveDataBlockLastRow(pInfo->pRow, pSDataBlock->pDataBlock, rowIndex, pSDataBlock->info.numOfCols);
1571 1572
  }

1573
  return pUpdated;
L
Liu Jicong 已提交
1574
  //  updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
1575 1576
}

1577
static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts) {
dengyihao's avatar
dengyihao 已提交
1578 1579
  pRowSup->win.ekey = ts;
  pRowSup->prevTs = ts;
1580
  pRowSup->numOfRows += 1;
1581 1582
}

1583 1584
static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsList, int32_t rowIndex) {
  pRowSup->startRowIndex = rowIndex;
dengyihao's avatar
dengyihao 已提交
1585 1586
  pRowSup->numOfRows = 0;
  pRowSup->win.skey = tsList[rowIndex];
1587 1588
}

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

1593
  // todo find the correct time stamp column slot
1594
  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
1595

1596 1597 1598
  bool    masterScan = true;
  int32_t numOfOutput = pOperator->numOfOutput;
  int64_t gid = pBlock->info.groupId;
1599

H
Haojun Liao 已提交
1600
  int64_t gap = pInfo->gap;
1601

1602
  if (!pInfo->reptScan) {
1603
    pInfo->reptScan = true;
1604
    pInfo->winSup.prevTs = INT64_MIN;
1605 1606
  }

1607 1608 1609
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;

1610
  // In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
1611
  TSKEY* tsList = (TSKEY*)pColInfoData->pData;
1612
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
1613 1614 1615 1616
    if (pInfo->winSup.prevTs == INT64_MIN) {
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
    } else if (tsList[j] - pRowSup->prevTs <= gap && (tsList[j] - pRowSup->prevTs) >= 0) {
1617
      // The gap is less than the threshold, so it belongs to current session window that has been opened already.
1618 1619 1620
      doKeepTuple(pRowSup, tsList[j]);
      if (j == 0 && pRowSup->startRowIndex != 0) {
        pRowSup->startRowIndex = 0;
1621 1622 1623
      }
    } else {  // start a new session window
      SResultRow* pResult = NULL;
1624 1625

      // keep the time window for the closed time window.
1626
      STimeWindow window = pRowSup->win;
1627

1628
      pRowSup->win.ekey = pRowSup->win.skey;
L
Liu Jicong 已提交
1629
      int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &window, masterScan,
dengyihao's avatar
dengyihao 已提交
1630 1631
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1632
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1633
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1634 1635
      }

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

1641
      // here we start a new session window
1642 1643
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
1644 1645 1646 1647
    }
  }

  SResultRow* pResult = NULL;
1648
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
1649 1650 1651
  int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &pRowSup->win, masterScan,
                                           &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                           pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1652
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1653
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1654 1655
  }

1656
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
dengyihao's avatar
dengyihao 已提交
1657 1658
  doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                   pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1659 1660 1661 1662
}

static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
  if (IS_VAR_DATA_TYPE(type)) {
1663
    // todo disable this
dengyihao's avatar
dengyihao 已提交
1664 1665 1666 1667 1668 1669
    //    if (pResultRow->key == NULL) {
    //      pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
    //      varDataCopy(pResultRow->key, pData);
    //    } else {
    //      ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
    //    }
1670 1671 1672 1673 1674 1675 1676 1677 1678
  } else {
    int64_t v = -1;
    GET_TYPED_DATA(v, int64_t, type, pData);

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

1679
int32_t setGroupResultOutputBuf(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type, int16_t bytes,
dengyihao's avatar
dengyihao 已提交
1680 1681
                                int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo,
                                SAggSupporter* pAggSup) {
L
Liu Jicong 已提交
1682 1683
  SResultRowInfo* pResultRowInfo = &binfo->resultRowInfo;
  SqlFunctionCtx* pCtx = binfo->pCtx;
1684

1685
  SResultRow* pResultRow = doSetResultOutBufByKey(pBuf, pResultRowInfo, groupId, (char*)pData, bytes, true, groupId,
H
Haojun Liao 已提交
1686
                                                     pTaskInfo, false, pAggSup);
L
Liu Jicong 已提交
1687
  assert(pResultRow != NULL);
1688 1689

  setResultRowKey(pResultRow, pData, type);
H
Haojun Liao 已提交
1690
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfCols, binfo->rowCellInfoOffset);
1691 1692 1693
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
1694 1695
static bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
  struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
1696 1697 1698

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

1703
  if (isRowEntryCompleted(pResInfo)) {
1704 1705 1706 1707
    return false;
  }

  if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
L
Liu Jicong 已提交
1708
    //    return QUERY_IS_ASC_QUERY(pQueryAttr);
1709 1710 1711 1712
  }

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

  // in the reverse table scan, only the following functions need to be executed
L
Liu Jicong 已提交
1717 1718 1719 1720
  //  if (IS_REVERSE_SCAN(pRuntimeEnv) ||
  //      (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
  //    return false;
  //  }
1721 1722 1723 1724

  return true;
}

dengyihao's avatar
dengyihao 已提交
1725 1726
static int32_t doCreateConstantValColumnAggInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t type,
                                                int32_t paramIndex, int32_t numOfRows) {
1727 1728 1729 1730 1731 1732 1733
  if (pInput->pData[paramIndex] == NULL) {
    pInput->pData[paramIndex] = taosMemoryCalloc(1, sizeof(SColumnInfoData));
    if (pInput->pData[paramIndex] == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }

    // Set the correct column info (data type and bytes)
dengyihao's avatar
dengyihao 已提交
1734 1735
    pInput->pData[paramIndex]->info.type = type;
    pInput->pData[paramIndex]->info.bytes = tDataTypes[type].bytes;
1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
  }

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

  ASSERT(!IS_VAR_DATA_TYPE(type));

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

dengyihao's avatar
dengyihao 已提交
1758 1759 1760
    *(double*)&da->min = v;
    *(double*)&da->max = v;
    *(double*)&da->sum = v * numOfRows;
1761 1762 1763
  } else if (type == TSDB_DATA_TYPE_BOOL) {  // todo validate this data type
    bool v = pFuncParam->param.i;

dengyihao's avatar
dengyihao 已提交
1764 1765 1766 1767
    *da = (SColumnDataAgg){.numOfNull = 0, .maxIndex = 0, .minIndex = 0};
    *(bool*)&da->min = 0;
    *(bool*)&da->max = v;
    *(bool*)&da->sum = v * numOfRows;
1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
  } else if (type == TSDB_DATA_TYPE_TIMESTAMP) {
    // do nothing
  } else {
    ASSERT(0);
  }

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

1790 1791 1792
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
        pInput->pColumnDataAgg[j] = &pBlock->pBlockAgg[slotId];
1793 1794 1795 1796

        // 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);
1797 1798
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
        doCreateConstantValColumnAggInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
1799 1800
      }
    }
1801
  } else {
1802
    pInput->colDataAggIsSet = false;
1803 1804 1805
  }

  // set the statistics data for primary time stamp column
1806 1807 1808 1809 1810
  //  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;
  //  }
1811 1812 1813
}

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

H
Haojun Liao 已提交
1818
  SqlFunctionCtx*  p = NULL;
wafwerar's avatar
wafwerar 已提交
1819
  SqlFunctionCtx** pTagCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
1820 1821 1822 1823 1824 1825 1826 1827
  if (pTagCtx == NULL) {
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

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

    if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
H
Haojun Liao 已提交
1828
      tagLen += pCtx[i].resDataInfo.bytes;
1829
      pTagCtx[num++] = &pCtx[i];
L
Liu Jicong 已提交
1830
    } else if (1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/) {
1831 1832 1833 1834 1835 1836 1837 1838 1839 1840
      p = &pCtx[i];
    } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
      // tag function may be the group by tag column
      // ts may be the required primary timestamp column
      continue;
    } else {
      // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
    }
  }
  if (p != NULL) {
1841 1842
    p->subsidiaries.pCtx = pTagCtx;
    p->subsidiaries.num = num;
1843
  } else {
wafwerar's avatar
wafwerar 已提交
1844
    taosMemoryFreeClear(pTagCtx);
1845 1846 1847 1848 1849
  }

  return TSDB_CODE_SUCCESS;
}

1850
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) {
L
Liu Jicong 已提交
1851
  SqlFunctionCtx* pFuncCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
H
Haojun Liao 已提交
1852 1853 1854 1855
  if (pFuncCtx == NULL) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
1856
  *rowCellInfoOffset = taosMemoryCalloc(numOfOutput, sizeof(int32_t));
H
Haojun Liao 已提交
1857
  if (*rowCellInfoOffset == 0) {
wafwerar's avatar
wafwerar 已提交
1858
    taosMemoryFreeClear(pFuncCtx);
H
Haojun Liao 已提交
1859 1860 1861 1862
    return NULL;
  }

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

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

1868
    pCtx->functionId = -1;
1869 1870 1871
    pCtx->curBufPage = -1;
    pCtx->pExpr      = pExpr;

H
Haojun Liao 已提交
1872
    if (pExpr->pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1873
      SFuncExecEnv env = {0};
H
Haojun Liao 已提交
1874 1875
      pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;

H
Haojun Liao 已提交
1876
      if (fmIsAggFunc(pCtx->functionId) || fmIsNonstandardSQLFunc(pCtx->functionId)) {
1877 1878 1879 1880
        fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
        pCtx->fpSet.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
      } else {
        fmGetScalarFuncExecFuncs(pCtx->functionId, &pCtx->sfp);
1881 1882 1883
        if (pCtx->sfp.getEnv != NULL) {
          pCtx->sfp.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
        }
1884
      }
H
Haojun Liao 已提交
1885
      pCtx->resDataInfo.interBufSize = env.calcMemSize;
1886 1887 1888 1889
    } else if (pExpr->pExpr->nodeType == QUERY_NODE_COLUMN || pExpr->pExpr->nodeType == QUERY_NODE_OPERATOR ||
               pExpr->pExpr->nodeType == QUERY_NODE_VALUE) {
      // for simple column, the intermediate buffer needs to hold one element.
      pCtx->resDataInfo.interBufSize = pFunct->resSchema.bytes;
H
Haojun Liao 已提交
1890
    }
H
Haojun Liao 已提交
1891

H
Haojun Liao 已提交
1892
    pCtx->input.numOfInputCols = pFunct->numOfParams;
wafwerar's avatar
wafwerar 已提交
1893 1894
    pCtx->input.pData = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
    pCtx->input.pColumnDataAgg = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
H
Haojun Liao 已提交
1895

1896
    pCtx->pTsOutput = NULL;
L
Liu Jicong 已提交
1897
    pCtx->resDataInfo.bytes = pFunct->resSchema.bytes;
1898
    pCtx->resDataInfo.type = pFunct->resSchema.type;
1899
    pCtx->order     = TSDB_ORDER_ASC;
1900
    pCtx->start.key = INT64_MIN;
1901
    pCtx->end.key   = INT64_MIN;
1902
    pCtx->numOfParams = pExpr->base.numOfParams;
H
Haojun Liao 已提交
1903

1904
    pCtx->param = pFunct->pParam;
dengyihao's avatar
dengyihao 已提交
1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938
    //    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 已提交
1939 1940
  }

L
Liu Jicong 已提交
1941 1942 1943
  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 已提交
1944
  }
H
Haojun Liao 已提交
1945 1946 1947 1948 1949

  setCtxTagColumnInfo(pFuncCtx, numOfOutput);
  return pFuncCtx;
}

1950
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1951 1952 1953 1954 1955 1956
  if (pCtx == NULL) {
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    for (int32_t j = 0; j < pCtx[i].numOfParams; ++j) {
1957
      taosVariantDestroy(&pCtx[i].param[j].param);
1958 1959 1960
    }

    taosVariantDestroy(&pCtx[i].tag);
1961
    taosMemoryFreeClear(pCtx[i].subsidiaries.pCtx);
1962 1963
  }

wafwerar's avatar
wafwerar 已提交
1964
  taosMemoryFreeClear(pCtx);
1965 1966 1967
  return NULL;
}

L
Liu Jicong 已提交
1968
bool isTaskKilled(SExecTaskInfo* pTaskInfo) {
1969 1970
  // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
  // abort current query execution.
L
Liu Jicong 已提交
1971 1972
  if (pTaskInfo->owner != 0 &&
      ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec())
1973 1974
      /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) {
    assert(pTaskInfo->cost.start != 0);
L
Liu Jicong 已提交
1975 1976 1977
    //    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;
1978 1979 1980 1981 1982
  }

  return false;
}

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

L
Liu Jicong 已提交
1985
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
1986 1987 1988 1989 1990 1991 1992 1993 1994
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
    if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) {
      continue;
    }

    return false;
  }

1995 1996
  int32_t order = TSDB_ORDER_ASC;
  if (order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) {
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015
    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 已提交
2016
// todo refactor : return window
2017
void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, STimeWindow* win) {
H
Haojun Liao 已提交
2018
  win->skey = taosTimeTruncate(key, pInterval, precision);
2019 2020

  /*
H
Haojun Liao 已提交
2021
   * if the realSkey > INT64_MAX - pInterval->interval, the query duration between
2022 2023
   * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
   */
2024 2025
  win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
  if (win->ekey < win->skey) {
2026 2027 2028 2029
    win->ekey = INT64_MAX;
  }
}

L
Liu Jicong 已提交
2030
static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
2031 2032 2033
  bool hasFirstLastFunc = false;
  bool hasOtherFunc = false;

2034
  if (status == BLK_DATA_DATA_LOAD || status == BLK_DATA_FILTEROUT) {
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052
    return status;
  }

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

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

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

2053
  if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
L
Liu Jicong 已提交
2054
    if (!hasOtherFunc) {
2055
      return BLK_DATA_FILTEROUT;
2056
    } else {
2057
      return BLK_DATA_DATA_LOAD;
2058 2059 2060 2061 2062 2063
    }
  }

  return status;
}

L
Liu Jicong 已提交
2064 2065
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
//   STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
H
Haojun Liao 已提交
2066
//
L
Liu Jicong 已提交
2067 2068 2069 2070
//   // 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 已提交
2071
//
L
Liu Jicong 已提交
2072 2073 2074 2075 2076
//   // 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 已提交
2077
//
L
Liu Jicong 已提交
2078 2079 2080 2081
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2082
//
L
Liu Jicong 已提交
2083 2084 2085
//     pQueryAttr->needReverseScan = false;
//     return;
//   }
H
Haojun Liao 已提交
2086
//
L
Liu Jicong 已提交
2087 2088 2089 2090 2091
//   if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) {
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2092
//
L
Liu Jicong 已提交
2093 2094 2095 2096
//     pQueryAttr->needReverseScan = false;
//     doUpdateLastKey(pQueryAttr);
//     return;
//   }
H
Haojun Liao 已提交
2097
//
L
Liu Jicong 已提交
2098 2099 2100 2101 2102 2103
//   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 已提交
2104
//
L
Liu Jicong 已提交
2105 2106 2107
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     return;
//   }
H
Haojun Liao 已提交
2108
//
L
Liu Jicong 已提交
2109 2110 2111 2112
//   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 已提交
2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//        doUpdateLastKey(pQueryAttr);
//      }
//
//      pQueryAttr->order.order = TSDB_ORDER_ASC;
//      pQueryAttr->needReverseScan = false;
//    } else if (onlyLastQuery(pQueryAttr) && notContainSessionOrStateWindow(pQueryAttr)) {
//      if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//        //qDebug(msg, pQInfo->qId, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//        doUpdateLastKey(pQueryAttr);
//      }
//
//      pQueryAttr->order.order = TSDB_ORDER_DESC;
//      pQueryAttr->needReverseScan = false;
//    }
//
//  } else {  // interval query
//    if (stableQuery) {
//      if (onlyFirstQuery(pQueryAttr)) {
//        if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//          //qDebug(msg, pQInfo->qId, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC,
L
Liu Jicong 已提交
2139 2140
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2141 2142 2143 2144 2145 2146 2147 2148 2149 2150
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_ASC;
//        pQueryAttr->needReverseScan = false;
//      } else if (onlyLastQuery(pQueryAttr)) {
//        if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//          //qDebug(msg, pQInfo->qId, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC,
L
Liu Jicong 已提交
2151 2152
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_DESC;
//        pQueryAttr->needReverseScan = false;
//      }
//    }
//  }
//}
2164

H
Haojun Liao 已提交
2165 2166
static void getIntermediateBufInfo(STaskRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) {
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
L
Liu Jicong 已提交
2167
  int32_t    MIN_ROWS_PER_PAGE = 4;
2168

L
Liu Jicong 已提交
2169 2170
  *rowsize = (int32_t)(pQueryAttr->resultRowSize *
                       getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
2171 2172 2173 2174
  int32_t overhead = sizeof(SFilePage);

  // one page contains at least two rows
  *ps = DEFAULT_INTERN_BUF_PAGE_SIZE;
L
Liu Jicong 已提交
2175
  while (((*rowsize) * MIN_ROWS_PER_PAGE) > (*ps) - overhead) {
2176 2177 2178 2179 2180 2181
    *ps = ((*ps) << 1u);
  }
}

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

L
Liu Jicong 已提交
2182 2183 2184
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
//   STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2185
//
L
Liu Jicong 已提交
2186 2187 2188
//   if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
//     return true;
//   }
2189
//
L
Liu Jicong 已提交
2190 2191
//   return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
2192

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

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

2199
  if (true) {
L
Liu Jicong 已提交
2200
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
2201 2202 2203 2204 2205 2206
    assert(w.ekey >= pBlockInfo->window.skey);

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

L
Liu Jicong 已提交
2207 2208
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2209 2210 2211 2212 2213 2214 2215 2216 2217 2218
      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 已提交
2219
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
2220 2221 2222 2223 2224 2225
    assert(w.skey <= pBlockInfo->window.ekey);

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

L
Liu Jicong 已提交
2226 2227
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291
      if (w.ekey < pBlockInfo->window.skey) {
        break;
      }

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

  return false;
}

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

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

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

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

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

    start += len;
    len = 0;
  }

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

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

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

static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
2295
  SqlFunctionCtx* pCtx = pTableScanInfo->pCtx;
2296
  uint32_t        status = BLK_DATA_NOT_LOAD;
2297 2298 2299 2300

  int32_t numOfOutput = pTableScanInfo->numOfOutput;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;
H
Haojun Liao 已提交
2301
    int32_t colId = pTableScanInfo->pExpr[i].base.pParam[0].pCol->colId;
2302 2303 2304

    // group by + first/last should not apply the first/last block filter
    if (functionId < 0) {
2305
      status |= BLK_DATA_DATA_LOAD;
2306 2307
      return status;
    } else {
L
Liu Jicong 已提交
2308
      //      status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
2309
      //      if ((status & BLK_DATA_DATA_LOAD) == BLK_DATA_DATA_LOAD) {
L
Liu Jicong 已提交
2310 2311
      //        return status;
      //      }
2312 2313 2314 2315 2316 2317
    }
  }

  return status;
}

L
Liu Jicong 已提交
2318 2319
int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                              uint32_t* status) {
2320
  *status = BLK_DATA_NOT_LOAD;
2321

H
Haojun Liao 已提交
2322
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
2323
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
2324

L
Liu Jicong 已提交
2325 2326
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2327

H
Haojun Liao 已提交
2328
  STaskCostInfo* pCost = &pTaskInfo->cost;
2329 2330 2331

  pCost->totalBlocks += 1;
  pCost->totalRows += pBlock->info.rows;
H
Haojun Liao 已提交
2332
#if 0
2333 2334 2335
  // 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 已提交
2336
      (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) {
2337
    (*status) = BLK_DATA_DATA_LOAD;
2338 2339 2340
  }

  // check if this data block is required to load
2341
  if ((*status) != BLK_DATA_DATA_LOAD) {
2342 2343 2344 2345 2346 2347 2348
    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 已提交
2349
      bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372
      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 {
2373
      (*status) = BLK_DATA_DATA_LOAD;
2374 2375 2376 2377
    }
  }

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

2380
  if ((*status) == BLK_DATA_NOT_LOAD || (*status) == BLK_DATA_FILTEROUT) {
2381 2382
    //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//           pBlockInfo->window.ekey, pBlockInfo->rows);
2383
    pCost->skipBlocks += 1;
2384
  } else if ((*status) == BLK_DATA_SMA_LOAD) {
2385 2386
    // this function never returns error?
    pCost->loadBlockStatis += 1;
2387
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2388 2389

    if (pBlock->pBlockAgg == NULL) {  // data block statistics does not exist, load data block
2390
//      pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2391 2392 2393
      pCost->totalCheckedRows += pBlock->info.rows;
    }
  } else {
2394
    assert((*status) == BLK_DATA_DATA_LOAD);
2395 2396 2397

    // load the data block statistics to perform further filter
    pCost->loadBlockStatis += 1;
2398
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2399 2400 2401 2402 2403 2404

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

H
Haojun Liao 已提交
2405
          bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422
          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
2423
            pCost->skipBlocks += 1;
2424 2425
            //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
//                   pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
2426
            (*status) = BLK_DATA_FILTEROUT;
2427 2428 2429 2430 2431 2432 2433 2434
            return TSDB_CODE_SUCCESS;
          }
        }
      }
    }

    // current block has been discard due to filter applied
//    if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
2435
//      pCost->skipBlocks += 1;
2436 2437
//      qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//             pBlockInfo->window.ekey, pBlockInfo->rows);
2438
//      (*status) = BLK_DATA_FILTEROUT;
2439 2440 2441 2442 2443
//      return TSDB_CODE_SUCCESS;
//    }

    pCost->totalCheckedRows += pBlockInfo->rows;
    pCost->loadBlocks += 1;
2444
//    pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456
//    if (pBlock->pDataBlock == NULL) {
//      return terrno;
//    }

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

L
Liu Jicong 已提交
2461
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
2462 2463 2464 2465 2466 2467 2468 2469 2470
  int32_t midPos = -1;
  int32_t numOfRows;

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

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

L
Liu Jicong 已提交
2471
  TSKEY*  keyList = (TSKEY*)pValue;
2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524
  int32_t firstPos = 0;
  int32_t lastPos = num - 1;

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

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

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

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

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

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

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

  return midPos;
}

/*
H
Haojun Liao 已提交
2525
 * set tag value in SqlFunctionCtx
2526 2527
 * e.g.,tag information into input buffer
 */
L
Liu Jicong 已提交
2528
static void doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes) {
2529 2530 2531
  taosVariantDestroy(tag);

  char* val = NULL;
L
Liu Jicong 已提交
2532 2533 2534 2535 2536 2537
  //  if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
  //    val = tsdbGetTableName(pTable);
  //    assert(val != NULL);
  //  } else {
  //    val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
  //  }
2538 2539 2540 2541 2542 2543 2544 2545

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

  if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
    int32_t maxLen = bytes - VARSTR_HEADER_SIZE;
L
Liu Jicong 已提交
2546
    int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
2547
    taosVariantCreateFromBinary(tag, varDataVal(val), len, type);
L
Liu Jicong 已提交
2548
    // taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
2549 2550 2551 2552 2553 2554 2555 2556
  } else {
    taosVariantCreateFromBinary(tag, val, bytes, type);
  }
}

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

L
Liu Jicong 已提交
2557
  for (int32_t i = 0; i < numOfTags; ++i) {
2558 2559 2560 2561 2562 2563 2564 2565
    if (pTagColList[i].colId == colId) {
      return &pTagColList[i];
    }
  }

  return NULL;
}

L
Liu Jicong 已提交
2566 2567
void setTagValue(SOperatorInfo* pOperatorInfo, void* pTable, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
  SExprInfo* pExpr = pOperatorInfo->pExpr;
2568
  SExprInfo* pExprInfo = &pExpr[0];
L
Liu Jicong 已提交
2569
  int32_t    functionId = getExprFunctionId(pExprInfo);
2570
#if 0
2571 2572 2573
  if (pQueryAttr->numOfOutput == 1 && functionId == FUNCTION_TS_COMP && pQueryAttr->stableQuery) {
    assert(pExprInfo->base.numOfParams == 1);

L
Liu Jicong 已提交
2574
    //    int16_t      tagColId = (int16_t)pExprInfo->base.param[0].i;
H
Haojun Liao 已提交
2575
    int16_t      tagColId = -1;
2576 2577 2578
    SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);

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

2580 2581 2582 2583 2584 2585 2586 2587 2588
  } else {
    // set tag value, by which the results are aggregated.
    int32_t offset = 0;
    memset(pRuntimeEnv->tagVal, 0, pQueryAttr->tagLen);

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

      // ts_comp column required the tag value for join filter
H
Haojun Liao 已提交
2589
      if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.pParam[0].pCol->flag)) {
2590 2591 2592 2593
        continue;
      }

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

L
Liu Jicong 已提交
2597 2598 2599
      if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resSchema.type) ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_BOOL ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_TIMESTAMP) {
2600 2601 2602 2603
        memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i, pLocalExprInfo->base.resSchema.bytes);
      } else {
        if (pCtx[idx].tag.pz != NULL) {
          memcpy(pRuntimeEnv->tagVal + offset, pCtx[idx].tag.pz, pCtx[idx].tag.nLen);
L
Liu Jicong 已提交
2604
        }
2605 2606 2607 2608 2609 2610 2611 2612 2613 2614
      }

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

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

H
Haojun Liao 已提交
2618
void copyToSDataBlock(SSDataBlock* pBlock, int32_t* offset, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pResBuf) {
2619 2620 2621 2622 2623 2624 2625
  pBlock->info.rows = 0;

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

L
Liu Jicong 已提交
2631
    //    doCopyToSDataBlock(pResBuf, pGroupResInfo, TSDB_ORDER_ASC, pBlock, );
2632 2633 2634 2635 2636 2637 2638 2639 2640 2641

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

    // enough results in data buffer, return
L
Liu Jicong 已提交
2642 2643 2644
    //    if (pBlock->info.rows >= threshold) {
    //      break;
    //    }
2645 2646 2647
  }
}

L
Liu Jicong 已提交
2648
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
2649 2650 2651 2652
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2653 2654
  //  TSWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY);
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
2655

L
Liu Jicong 已提交
2656 2657
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
2658 2659

  // set the index to be the end slot of result rows array
dengyihao's avatar
dengyihao 已提交
2660 2661 2662 2663 2664 2665
  //  SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->size > 0) {
  //    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  //  } else {
  //    pResultRowInfo->curPos = -1;
  //  }
2666 2667
}

H
Haojun Liao 已提交
2668
void initResultRow(SResultRow* pResultRow) {
2669 2670 2671 2672 2673 2674
  pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
}

/*
 * The start of each column SResultRowEntryInfo is denote by RowCellInfoOffset.
 * Note that in case of top/bottom query, the whole multiple rows of result is treated as only one row of results.
H
Haojun Liao 已提交
2675 2676 2677
 * +------------+-----------------result column 1------------+------------------result column 2-----------+
 * | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2|
 * +------------+--------------------------------------------+--------------------------------------------+
2678 2679
 *           offset[0]                                  offset[1]                                   offset[2]
 */
2680
// TODO refactor: some function move away
H
Haojun Liao 已提交
2681
void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
2682 2683 2684
  SqlFunctionCtx* pCtx = pInfo->pCtx;
  SSDataBlock*    pDataBlock = pInfo->pRes;
  int32_t*        rowCellInfoOffset = pInfo->rowCellInfoOffset;
H
Haojun Liao 已提交
2685

H
Haojun Liao 已提交
2686
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
2687
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
2688

L
Liu Jicong 已提交
2689 2690
  int64_t     tid = 0;
  int64_t     groupId = 0;
2691
  SResultRow* pRow = doSetResultOutBufByKey(pSup->pResultBuf, pResultRowInfo, tid, (char*)&tid, sizeof(tid), true,
L
Liu Jicong 已提交
2692
                                               groupId, pTaskInfo, false, pSup);
H
Haojun Liao 已提交
2693 2694 2695 2696 2697

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

L
Liu Jicong 已提交
2698
    pCtx[i].resultInfo = pEntry;
H
Haojun Liao 已提交
2699 2700 2701
    pCtx[i].currentStage = stage;

    // set the timestamp output buffer for top/bottom/diff query
L
Liu Jicong 已提交
2702 2703
    //    int32_t fid = pCtx[i].functionId;
    //    if (fid == FUNCTION_TOP || fid == FUNCTION_BOTTOM || fid == FUNCTION_DIFF || fid == FUNCTION_DERIVATIVE) {
H
Haojun Liao 已提交
2704
    //      if (i > 0) pCtx[i].pTsOutput = pCtx[i-1].pOutput;
L
Liu Jicong 已提交
2705
    //    }
H
Haojun Liao 已提交
2706 2707 2708 2709 2710
  }

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

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

L
Liu Jicong 已提交
2714
  int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5;  // extra output buffer
2715
  if ((*bufCapacity) < newSize) {
L
Liu Jicong 已提交
2716 2717
    for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
2718

wafwerar's avatar
wafwerar 已提交
2719
      char* p = taosMemoryRealloc(pColInfo->pData, newSize * pColInfo->info.bytes);
2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732
      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 已提交
2733
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
2734 2735 2736 2737 2738
    pBInfo->pCtx[i].pOutput = pColInfo->pData + pColInfo->info.bytes * pDataBlock->info.rows;

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

L
Liu Jicong 已提交
2739 2740
    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
        functionId == FUNCTION_DERIVATIVE) {
dengyihao's avatar
dengyihao 已提交
2741
      //      if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
2742 2743 2744 2745
    }
  }
}

H
Haojun Liao 已提交
2746
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
2747 2748
  bool    needCopyTs = false;
  int32_t tsNum = 0;
L
Liu Jicong 已提交
2749
  char*   src = NULL;
2750 2751 2752 2753
  for (int32_t i = 0; i < numOfOutput; i++) {
    int32_t functionId = pCtx[i].functionId;
    if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) {
      needCopyTs = true;
L
Liu Jicong 已提交
2754 2755
      if (i > 0 && pCtx[i - 1].functionId == FUNCTION_TS_DUMMY) {
        SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1);  // find ts data
2756 2757
        src = pColRes->pData;
      }
L
Liu Jicong 已提交
2758
    } else if (functionId == FUNCTION_TS_DUMMY) {
2759 2760 2761 2762 2763 2764 2765 2766 2767 2768
      tsNum++;
    }
  }

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

  for (int32_t i = 0; i < numOfOutput; i++) {
    int32_t functionId = pCtx[i].functionId;
L
Liu Jicong 已提交
2769
    if (functionId == FUNCTION_TS_DUMMY) {
2770 2771 2772 2773 2774 2775
      SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i);
      memcpy(pColRes->pData, src, pColRes->info.bytes * pRes->info.rows);
    }
  }
}

H
Haojun Liao 已提交
2776
void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size) {
2777 2778
  for (int32_t j = 0; j < size; ++j) {
    struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
dengyihao's avatar
dengyihao 已提交
2779 2780
    if (isRowEntryInitialized(pResInfo) || fmIsPseudoColumnFunc(pCtx[j].functionId) || pCtx[j].functionId == -1 ||
        fmIsScalarFunc(pCtx[j].functionId)) {
2781 2782 2783
      continue;
    }

H
Haojun Liao 已提交
2784
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
2785 2786 2787
  }
}

L
Liu Jicong 已提交
2788
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
2789
  if (status == TASK_NOT_COMPLETED) {
H
Haojun Liao 已提交
2790
    pTaskInfo->status = status;
2791 2792
  } else {
    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
2793
    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
2794
    pTaskInfo->status |= status;
2795 2796 2797
  }
}

2798
// todo merged with the build group result.
L
Liu Jicong 已提交
2799 2800
void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf,
                                   SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) {
2801 2802 2803
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
    SResultRowPosition* pPos = &pResultRowInfo->pPosition[i];

L
Liu Jicong 已提交
2804
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pageId);
2805
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset);
H
Haojun Liao 已提交
2806 2807

    // TODO ignore the close status anyway.
dengyihao's avatar
dengyihao 已提交
2808 2809 2810
    //    if (!isResultRowClosed(pRow)) {
    //      continue;
    //    }
2811

2812
    for (int32_t j = 0; j < numOfOutput; ++j) {
2813 2814
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);

H
Haojun Liao 已提交
2815
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
H
Haojun Liao 已提交
2816
      if (!isRowEntryInitialized(pResInfo)) {
2817 2818 2819
        continue;
      }

H
Haojun Liao 已提交
2820
      if (pCtx[j].fpSet.process) {  // TODO set the dummy function, to avoid the check for null ptr.
dengyihao's avatar
dengyihao 已提交
2821
                                    //        pCtx[j].fpSet.finalize(&pCtx[j]);
H
Haojun Liao 已提交
2822
      }
2823 2824 2825 2826

      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
2827
    }
2828 2829 2830

    releaseBufPage(pBuf, bufPage);
  }
2831 2832
}

2833
// todo merged with the build group result.
2834 2835 2836 2837 2838
void finalizeUpdatedResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf, SArray* pUpdateList,
                           int32_t* rowCellInfoOffset) {
  size_t num = taosArrayGetSize(pUpdateList);

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

2841 2842 2843
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pos.pageId);
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->pos.offset);
//
2844 2845
    for (int32_t j = 0; j < numOfOutput; ++j) {
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);
2846
//
2847
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
2848 2849 2850 2851 2852 2853 2854 2855 2856
//      if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
//        continue;
//      }
//
//      if (pCtx[j].fpSet.process) {  // TODO set the dummy function.
////        pCtx[j].fpSet.finalize(&pCtx[j]);
//        pResInfo->initialized = true;
//      }
//
2857 2858 2859 2860 2861 2862 2863 2864 2865
      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
    }

    releaseBufPage(pBuf, bufPage);
  }
}

L
Liu Jicong 已提交
2866 2867
STableQueryInfo* createTableQueryInfo(void* buf, bool groupbyColumn, STimeWindow win) {
  STableQueryInfo* pTableQueryInfo = buf;
2868 2869 2870
  pTableQueryInfo->lastKey = win.skey;

  // set more initial size of interval/groupby query
L
Liu Jicong 已提交
2871 2872
  //  if (/*QUERY_IS_INTERVAL_QUERY(pQueryAttr) || */groupbyColumn) {
  int32_t initialSize = 128;
dengyihao's avatar
dengyihao 已提交
2873 2874 2875 2876
  //  int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize);
  //  if (code != TSDB_CODE_SUCCESS) {
  //    return NULL;
  //  }
L
Liu Jicong 已提交
2877 2878
  //  } else { // in other aggregate query, do not initialize the windowResInfo
  //  }
2879 2880 2881 2882

  return pTableQueryInfo;
}

L
Liu Jicong 已提交
2883
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
2884 2885 2886 2887
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2888
  //  taosVariantDestroy(&pTableQueryInfo->tag);
dengyihao's avatar
dengyihao 已提交
2889
  //  cleanupResultRowInfo(&pTableQueryInfo->resInfo);
2890 2891
}

dengyihao's avatar
dengyihao 已提交
2892 2893
void setResultRowOutputBufInitCtx_rv(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput,
                                     int32_t* rowCellInfoOffset) {
2894 2895 2896 2897 2898 2899 2900
  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;
    }
2901 2902 2903 2904 2905

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

2906 2907 2908 2909 2910 2911
    if (!pResInfo->initialized) {
      if (pCtx[i].functionId != -1) {
        pCtx[i].fpSet.init(&pCtx[i], pResInfo);
      } else {
        pResInfo->initialized = true;
      }
2912 2913 2914 2915
    }
  }
}

2916 2917 2918 2919 2920 2921
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
  if (pFilterNode == NULL) {
    return;
  }

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

H
Haojun Liao 已提交
2923
  // todo move to the initialization function
H
Haojun Liao 已提交
2924
  int32_t code = filterInitFromNode((SNode*)pFilterNode, &filter, 0);
2925 2926 2927 2928 2929 2930

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

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

2933
  SSDataBlock* px = createOneDataBlock(pBlock, false);
2934 2935
  blockDataEnsureCapacity(px, pBlock->info.rows);

H
Haojun Liao 已提交
2936
  // todo extract method
2937 2938 2939 2940
  int32_t numOfRow = 0;
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
    SColumnInfoData* pDst = taosArrayGet(px->pDataBlock, i);
    SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, i);
D
dapan1121 已提交
2941 2942 2943 2944 2945 2946 2947 2948 2949
    if (keep) {
      colDataAssign(pDst, pSrc, pBlock->info.rows);
      numOfRow = pBlock->info.rows;
    } else if (NULL != rowRes) {
      numOfRow = 0;
      for (int32_t j = 0; j < pBlock->info.rows; ++j) {
        if (rowRes[j] == 0) {
          continue;
        }
2950

D
dapan1121 已提交
2951 2952 2953 2954 2955 2956
        if (colDataIsNull_s(pSrc, j)) {
          colDataAppendNULL(pDst, numOfRow);
        } else {
          colDataAppend(pDst, numOfRow, colDataGetData(pSrc, j), false);
        }
        numOfRow += 1;
H
Haojun Liao 已提交
2957
      }
D
dapan1121 已提交
2958 2959
    } else {
      numOfRow = 0;
2960 2961 2962 2963 2964 2965
    }

    *pSrc = *pDst;
  }

  pBlock->info.rows = numOfRow;
2966
  blockDataUpdateTsWindow(pBlock);
2967 2968
}

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

2974 2975
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
2976
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
2977

2978
  SResultRow* pResultRow =
2979
      doSetResultOutBufByKey(pAggInfo->aggSup.pResultBuf, pResultRowInfo, uid, (char*)&groupId, sizeof(groupId),
H
Haojun Liao 已提交
2980
                                true, groupId, pTaskInfo, false, &pAggInfo->aggSup);
L
Liu Jicong 已提交
2981
  assert(pResultRow != NULL);
2982 2983 2984 2985 2986 2987

  /*
   * 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 已提交
2988 2989
    int32_t ret =
        addNewWindowResultBuf(pResultRow, pAggInfo->aggSup.pResultBuf, groupId, pAggInfo->binfo.pRes->info.rowSize);
2990 2991 2992 2993 2994
    if (ret != TSDB_CODE_SUCCESS) {
      return;
    }
  }

H
Haojun Liao 已提交
2995
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
2996 2997
}

H
Haojun Liao 已提交
2998 2999
void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* pTaskInfo, SAggOperatorInfo* pAggInfo) {
  if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
3000 3001 3002
    return;
  }

H
Haojun Liao 已提交
3003
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, groupId, pTaskInfo);
3004 3005

  // record the current active group id
H
Haojun Liao 已提交
3006
  pAggInfo->groupId = groupId;
3007 3008 3009 3010 3011
}

/*
 * There are two cases to handle:
 *
L
Liu Jicong 已提交
3012 3013
 * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including
 * pQueryAttr->lastKey, pQueryAttr->window.skey, and pQueryAttr->eKey.
3014 3015 3016 3017
 * 2. Query range is set and query is in progress. There may be another result with the same query ranges to be
 *    merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there
 *    is a previous result generated or not.
 */
3018
void setIntervalQueryRange(STableQueryInfo* pTableQueryInfo, TSKEY key, STimeWindow* pQRange) {
dengyihao's avatar
dengyihao 已提交
3019 3020 3021 3022
  //  SResultRowInfo*  pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->curPos != -1) {
  //    return;
  //  }
3023

dengyihao's avatar
dengyihao 已提交
3024 3025
  //  pTableQueryInfo->win.skey = key;
  //  STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
3026 3027 3028 3029 3030 3031 3032

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

L
Liu Jicong 已提交
3039 3040 3041 3042 3043 3044 3045
  //  if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
  //    if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
  //      assert(win.ekey == pQueryAttr->window.ekey);
  //    }
  //
  //    pResultRowInfo->prevSKey = w.skey;
  //  }
3046

L
Liu Jicong 已提交
3047
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
3048 3049 3050 3051 3052 3053 3054 3055 3056 3057
}

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

  int32_t start = 0;
  int32_t step = -1;

L
Liu Jicong 已提交
3066
  // qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077
  assert(orderType == TSDB_ORDER_ASC || orderType == TSDB_ORDER_DESC);

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

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

3081
    SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
3082 3083 3084 3085 3086
    if (pRow->numOfRows == 0) {
      pGroupResInfo->index += 1;
      continue;
    }

3087
    // TODO copy multiple rows?
3088
    int32_t numOfRowsToCopy = pRow->numOfRows;
3089
    if (numOfResult + numOfRowsToCopy >= pBlock->info.capacity) {
3090 3091 3092 3093 3094 3095
      break;
    }

    pGroupResInfo->index += 1;

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

3098 3099
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
      if (pCtx[j].fpSet.process) {
3100
        pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
3101 3102
      } else {
        SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
3103

3104 3105 3106
        char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
        colDataAppend(pColInfoData, pBlock->info.rows, in, pCtx[j].resultInfo->isNullRes);
      }
3107 3108
    }

3109 3110
    releaseBufPage(pBuf, page);

3111 3112
    pBlock->info.rows += pRow->numOfRows;
    if (pBlock->info.rows >= pBlock->info.capacity) {  // output buffer is full
3113 3114 3115 3116
      break;
    }
  }

L
Liu Jicong 已提交
3117
  // qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
3118
  blockDataUpdateTsWindow(pBlock);
3119 3120 3121
  return 0;
}

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

3126
  blockDataCleanup(pBlock);
3127 3128 3129 3130
  if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
    return;
  }

3131
  int32_t orderType = TSDB_ORDER_ASC;
3132
  doCopyToSDataBlock(pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
3133

H
Haojun Liao 已提交
3134 3135
  // add condition (pBlock->info.rows >= 1) just to runtime happy
  blockDataUpdateTsWindow(pBlock);
3136 3137
}

L
Liu Jicong 已提交
3138 3139
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
                                        int32_t* rowCellInfoOffset) {
3140
  // update the number of result for each, only update the number of rows for the corresponding window result.
L
Liu Jicong 已提交
3141 3142 3143
  //  if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
  //    return;
  //  }
H
Haojun Liao 已提交
3144
#if 0
3145
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
L
Liu Jicong 已提交
3146
    SResultRow* pResult = pResultRowInfo->pResult[i];
3147 3148 3149 3150 3151 3152 3153

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

3154 3155
      SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
      pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
3156 3157
    }
  }
H
Haojun Liao 已提交
3158
#endif
3159 3160
}

L
Liu Jicong 已提交
3161
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
3162 3163
  int32_t colSize = pColRes->info.bytes * numOfRows;
  return (*(tDataTypes[pColRes->info.type].compFunc))(pColRes->pData, colSize, numOfRows, data,
L
Liu Jicong 已提交
3164
                                                      colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
3165 3166
}

L
Liu Jicong 已提交
3167 3168 3169 3170 3171
int32_t doFillTimeIntervalGapsInResults(struct SFillInfo* pFillInfo, SSDataBlock* pOutput, int32_t capacity, void** p) {
  //  for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
  //    SColumnInfoData* pColInfoData = taosArrayGet(pOutput->pDataBlock, i);
  //    p[i] = pColInfoData->pData + (pColInfoData->info.bytes * pOutput->info.rows);
  //  }
3172 3173 3174 3175 3176 3177 3178

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

  return pOutput->info.rows;
}

3179
void publishOperatorProfEvent(SOperatorInfo* pOperator, EQueryProfEventType eventType) {
3180 3181
  SQueryProfEvent event = {0};

L
Liu Jicong 已提交
3182 3183
  event.eventType = eventType;
  event.eventTime = taosGetTimestampUs();
3184
  event.operatorType = pOperator->operatorType;
dengyihao's avatar
dengyihao 已提交
3185 3186 3187
  //    if (pQInfo->summary.queryProfEvents) {
  //      taosArrayPush(pQInfo->summary.queryProfEvents, &event);
  //    }
3188 3189
}

L
Liu Jicong 已提交
3190
void publishQueryAbortEvent(SExecTaskInfo* pTaskInfo, int32_t code) {
3191 3192 3193 3194 3195
  SQueryProfEvent event;
  event.eventType = QUERY_PROF_QUERY_ABORT;
  event.eventTime = taosGetTimestampUs();
  event.abortCode = code;

3196 3197
  if (pTaskInfo->cost.queryProfEvents) {
    taosArrayPush(pTaskInfo->cost.queryProfEvents, &event);
3198 3199 3200
  }
}

L
Liu Jicong 已提交
3201
typedef struct {
3202 3203 3204 3205 3206 3207 3208
  uint8_t operatorType;
  int64_t beginTime;
  int64_t endTime;
  int64_t selfTime;
  int64_t descendantsTime;
} SOperatorStackItem;

L
Liu Jicong 已提交
3209 3210
static void doOperatorExecProfOnce(SOperatorStackItem* item, SQueryProfEvent* event, SArray* opStack,
                                   SHashObj* profResults) {
3211 3212 3213 3214 3215 3216 3217 3218
  item->endTime = event->eventTime;
  item->selfTime = (item->endTime - item->beginTime) - (item->descendantsTime);

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

L
Liu Jicong 已提交
3219
  uint8_t              operatorType = item->operatorType;
3220 3221 3222 3223 3224 3225 3226 3227 3228
  SOperatorProfResult* result = taosHashGet(profResults, &operatorType, sizeof(operatorType));
  if (result != NULL) {
    result->sumRunTimes++;
    result->sumSelfTime += item->selfTime;
  } else {
    SOperatorProfResult opResult;
    opResult.operatorType = operatorType;
    opResult.sumSelfTime = item->selfTime;
    opResult.sumRunTimes = 1;
L
Liu Jicong 已提交
3229
    taosHashPut(profResults, &(operatorType), sizeof(operatorType), &opResult, sizeof(opResult));
3230 3231 3232
  }
}

3233
void calculateOperatorProfResults(void) {
dengyihao's avatar
dengyihao 已提交
3234 3235 3236 3237 3238 3239 3240 3241 3242
  //  if (pQInfo->summary.queryProfEvents == NULL) {
  //    // qDebug("QInfo:0x%"PRIx64" query prof events array is null", pQInfo->qId);
  //    return;
  //  }
  //
  //  if (pQInfo->summary.operatorProfResults == NULL) {
  //    // qDebug("QInfo:0x%"PRIx64" operator prof results hash is null", pQInfo->qId);
  //    return;
  //  }
3243 3244 3245 3246 3247

  SArray* opStack = taosArrayInit(32, sizeof(SOperatorStackItem));
  if (opStack == NULL) {
    return;
  }
3248
#if 0
L
Liu Jicong 已提交
3249
  size_t    size = taosArrayGetSize(pQInfo->summary.queryProfEvents);
3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270
  SHashObj* profResults = pQInfo->summary.operatorProfResults;

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

L
Liu Jicong 已提交
3275 3276
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
3277

L
Liu Jicong 已提交
3278 3279 3280
  //  uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
  //  hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
  //  pSummary->hashSize = hashSize;
3281 3282 3283 3284

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

L
Liu Jicong 已提交
3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304
  //  SResultRowPool* p = pTaskInfo->pool;
  //  if (p != NULL) {
  //    pSummary->winInfoSize = getResultRowPoolMemSize(p);
  //    pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
  //  } else {
  //    pSummary->winInfoSize = 0;
  //    pSummary->numOfTimeWindows = 0;
  //  }
  //
  //  calculateOperatorProfResults(pQInfo);

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

  if (pSummary->operatorProfResults) {
    SOperatorProfResult* opRes = taosHashIterate(pSummary->operatorProfResults, NULL);
    while (opRes != NULL) {
L
Liu Jicong 已提交
3309 3310
      // qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
      //             pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
3311 3312 3313 3314 3315
      opRes = taosHashIterate(pSummary->operatorProfResults, opRes);
    }
  }
}

L
Liu Jicong 已提交
3316 3317 3318
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
3319
//
L
Liu Jicong 已提交
3320
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3321
//
L
Liu Jicong 已提交
3322 3323 3324 3325
//   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;
//   }
3326
//
L
Liu Jicong 已提交
3327 3328 3329 3330 3331
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
//   } else {
//     pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
//   }
3332
//
L
Liu Jicong 已提交
3333
//   assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
3334
//
L
Liu Jicong 已提交
3335 3336
//   SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//   SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3337
//
L
Liu Jicong 已提交
3338 3339
//   // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
//   TSKEY *keys = (TSKEY *) pColInfoData->pData;
3340
//
L
Liu Jicong 已提交
3341 3342 3343
//   // update the offset value
//   pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
//   pQueryAttr->limit.offset = 0;
3344
//
L
Liu Jicong 已提交
3345
//   int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
3346
//
L
Liu Jicong 已提交
3347 3348 3349 3350
//   //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);
// }
3351

L
Liu Jicong 已提交
3352 3353
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
3354
//
L
Liu Jicong 已提交
3355 3356 3357
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
//     return;
//   }
3358
//
L
Liu Jicong 已提交
3359 3360
//   pQueryAttr->pos = 0;
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3361
//
L
Liu Jicong 已提交
3362 3363
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//   TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
3364
//
L
Liu Jicong 已提交
3365 3366 3367 3368 3369
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pTsdbReadHandle)) {
//     if (isTaskKilled(pRuntimeEnv->qinfo)) {
//       longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
//     }
3370
//
L
Liu Jicong 已提交
3371
//     tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
3372
//
L
Liu Jicong 已提交
3373 3374 3375 3376
//     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;
3377
//
L
Liu Jicong 已提交
3378 3379 3380 3381 3382 3383 3384
//       //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;
//     }
//   }
3385
//
L
Liu Jicong 已提交
3386 3387 3388 3389 3390 3391 3392 3393 3394
//   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;
3395
//
L
Liu Jicong 已提交
3396 3397 3398
//   assert(pQueryAttr->limit.offset == 0);
//   STimeWindow tw = *win;
//   getNextTimeWindow(pQueryAttr, &tw);
3399
//
L
Liu Jicong 已提交
3400 3401
//   if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
//       (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
3402
//
L
Liu Jicong 已提交
3403 3404 3405 3406
//     // 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);
3407
//
L
Liu Jicong 已提交
3408 3409 3410 3411
//     tw = *win;
//     int32_t startPos =
//         getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
//     assert(startPos >= 0);
3412
//
L
Liu Jicong 已提交
3413 3414
//     // set the abort info
//     pQueryAttr->pos = startPos;
3415
//
L
Liu Jicong 已提交
3416 3417 3418 3419
//     // reset the query start timestamp
//     pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
//     pQueryAttr->window.skey = pTableQueryInfo->win.skey;
//     TSKEY key = pTableQueryInfo->win.skey;
3420
//
L
Liu Jicong 已提交
3421 3422
//     pWindowResInfo->prevSKey = tw.skey;
//     int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
3423
//
L
Liu Jicong 已提交
3424 3425
//     int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//     pRuntimeEnv->resultRowInfo.curIndex = index;  // restore the window index
3426
//
L
Liu Jicong 已提交
3427 3428 3429 3430
//     //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);
3431
//
L
Liu Jicong 已提交
3432 3433 3434 3435 3436
//     return key;
//   } else {  // do nothing
//     pQueryAttr->window.skey      = tw.skey;
//     pWindowResInfo->prevSKey = tw.skey;
//     pTableQueryInfo->lastKey = tw.skey;
3437
//
L
Liu Jicong 已提交
3438 3439
//     return tw.skey;
//   }
3440
//
L
Liu Jicong 已提交
3441 3442 3443 3444 3445 3446 3447 3448 3449 3450
//   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);
//   }
3451
//
L
Liu Jicong 已提交
3452 3453 3454 3455 3456
//   // 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;
//   }
3457
//
L
Liu Jicong 已提交
3458 3459 3460 3461 3462 3463 3464
//   /*
//    * 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);
3465
//
L
Liu Jicong 已提交
3466 3467
//   STimeWindow w = TSWINDOW_INITIALIZER;
//   bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
3468
//
L
Liu Jicong 已提交
3469 3470
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//   STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
3471
//
L
Liu Jicong 已提交
3472 3473 3474
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
//     tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
3475
//
L
Liu Jicong 已提交
3476 3477 3478 3479 3480 3481 3482 3483 3484
//     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;
//     }
3485
//
L
Liu Jicong 已提交
3486 3487
//     // the first time window
//     STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
3488
//
L
Liu Jicong 已提交
3489 3490
//     while (pQueryAttr->limit.offset > 0) {
//       STimeWindow tw = win;
3491
//
L
Liu Jicong 已提交
3492 3493 3494
//       if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
//         pQueryAttr->limit.offset -= 1;
//         pWindowResInfo->prevSKey = win.skey;
3495
//
L
Liu Jicong 已提交
3496 3497 3498 3499 3500 3501
//         // 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;
//         }
//       }
3502
//
L
Liu Jicong 已提交
3503 3504 3505 3506
//       if (pQueryAttr->limit.offset == 0) {
//         *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//         return true;
//       }
3507
//
L
Liu Jicong 已提交
3508 3509
//       // current window does not ended in current data block, try next data block
//       getNextTimeWindow(pQueryAttr, &tw);
3510
//
L
Liu Jicong 已提交
3511 3512 3513 3514 3515 3516 3517 3518 3519
//       /*
//        * 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)) {
3520
//
L
Liu Jicong 已提交
3521 3522
//         SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//         SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3523
//
L
Liu Jicong 已提交
3524 3525 3526
//         if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
//           pQueryAttr->limit.offset -= 1;
//         }
3527
//
L
Liu Jicong 已提交
3528 3529 3530 3531 3532 3533 3534 3535
//         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);
3536
//
L
Liu Jicong 已提交
3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547
//           // 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.
//       }
//     }
//   }
3548
//
L
Liu Jicong 已提交
3549 3550 3551 3552
//   // check for error
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
3553
//
L
Liu Jicong 已提交
3554 3555
//   return true;
// }
3556

3557
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
H
Haojun Liao 已提交
3558
  if (p->pDownstream == NULL) {
H
Haojun Liao 已提交
3559
    assert(p->numOfDownstream == 0);
3560 3561
  }

wafwerar's avatar
wafwerar 已提交
3562
  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
3563 3564 3565 3566 3567 3568 3569
  if (p->pDownstream == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
3570 3571 3572 3573
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);

3574
static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) {
H
Haojun Liao 已提交
3575 3576
#if 0
    if (order == TSDB_ORDER_ASC) {
3577 3578
    assert(
        (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
3579 3580
        (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey));
3581 3582 3583
  } else {
    assert(
        (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
3584 3585
        (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey));
3586
  }
H
Haojun Liao 已提交
3587
#endif
3588 3589
}

3590 3591
// SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
//   SQueryTableDataCond cond = {
L
Liu Jicong 已提交
3592 3593 3594 3595 3596 3597
//       .colList   = pQueryAttr->tableCols,
//       .order     = pQueryAttr->order.order,
//       .numOfCols = pQueryAttr->numOfCols,
//       .type      = BLOCK_LOAD_OFFSET_SEQ_ORDER,
//       .loadExternalRows = false,
//   };
3598
//
L
Liu Jicong 已提交
3599 3600 3601
//   TIME_WINDOW_COPY(cond.twindow, *win);
//   return cond;
// }
3602 3603 3604

static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo) {
  STableIdInfo tidInfo;
L
Liu Jicong 已提交
3605 3606 3607 3608 3609
  //  STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
  //
  //  tidInfo.uid = id->uid;
  //  tidInfo.tid = id->tid;
  //  tidInfo.key = pTableQueryInfo->lastKey;
3610 3611 3612 3613

  return tidInfo;
}

L
Liu Jicong 已提交
3614 3615 3616 3617
// 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;
3618
//
L
Liu Jicong 已提交
3619 3620 3621
//   if (pTableQueryInfo->pTable == NULL) {
//     return;
//   }
3622
//
L
Liu Jicong 已提交
3623 3624 3625 3626 3627 3628 3629 3630 3631
//   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));
//   }
// }
3632

3633
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
L
Liu Jicong 已提交
3634
  SSourceDataInfo* pSourceDataInfo = (SSourceDataInfo*)param;
H
Haojun Liao 已提交
3635 3636
  if (code == TSDB_CODE_SUCCESS) {
    pSourceDataInfo->pRsp = pMsg->pData;
3637

H
Haojun Liao 已提交
3638 3639
    SRetrieveTableRsp* pRsp = pSourceDataInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
dengyihao's avatar
dengyihao 已提交
3640 3641
    pRsp->compLen = htonl(pRsp->compLen);
    pRsp->useconds = htobe64(pRsp->useconds);
H
Haojun Liao 已提交
3642 3643 3644
  } else {
    pSourceDataInfo->code = code;
  }
H
Haojun Liao 已提交
3645

H
Haojun Liao 已提交
3646
  pSourceDataInfo->status = EX_SOURCE_DATA_READY;
3647
  tsem_post(&pSourceDataInfo->pEx->ready);
wmmhello's avatar
wmmhello 已提交
3648
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
3649 3650 3651 3652
}

static void destroySendMsgInfo(SMsgSendInfo* pMsgBody) {
  assert(pMsgBody != NULL);
wafwerar's avatar
wafwerar 已提交
3653 3654
  taosMemoryFreeClear(pMsgBody->msgInfo.pData);
  taosMemoryFreeClear(pMsgBody);
H
Haojun Liao 已提交
3655 3656
}

S
Shengliang Guan 已提交
3657
void qProcessFetchRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
L
Liu Jicong 已提交
3658
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->ahandle;
H
Haojun Liao 已提交
3659 3660 3661 3662 3663
  assert(pMsg->ahandle != NULL);

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

  if (pMsg->contLen > 0) {
wafwerar's avatar
wafwerar 已提交
3664
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
H
Haojun Liao 已提交
3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675
    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);
3676 3677
}

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

wafwerar's avatar
wafwerar 已提交
3681
  SResFetchReq* pMsg = taosMemoryCalloc(1, sizeof(SResFetchReq));
3682 3683 3684 3685
  if (NULL == pMsg) {
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
  }
3686

L
Liu Jicong 已提交
3687 3688
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
3689

L
Liu Jicong 已提交
3690 3691
  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);
3692 3693 3694 3695 3696 3697 3698

  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 已提交
3699
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
3700
  if (NULL == pMsgSendInfo) {
wafwerar's avatar
wafwerar 已提交
3701
    taosMemoryFreeClear(pMsg);
3702 3703 3704
    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 已提交
3705 3706
  }

3707 3708 3709 3710 3711
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
3712

3713
  int64_t transporterId = 0;
L
Liu Jicong 已提交
3714
  int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
3715 3716 3717
  return TSDB_CODE_SUCCESS;
}

3718 3719
// TODO if only one or two columns required, how to extract data?
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
dengyihao's avatar
dengyihao 已提交
3720 3721
                                  int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
                                  SArray* pColList) {
H
Haojun Liao 已提交
3722
  blockDataEnsureCapacity(pRes, numOfRows);
3723

H
Haojun Liao 已提交
3724
  if (pColList == NULL) {  // data from other sources
3725 3726 3727 3728 3729 3730
    int32_t dataLen = *(int32_t*) pData;
    pData += sizeof(int32_t);

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

H
Haojun Liao 已提交
3731 3732
    int32_t* colLen = (int32_t*)pData;

3733
    char* pStart = pData + sizeof(int32_t) * numOfOutput;
3734
    for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
3735 3736 3737
      colLen[i] = htonl(colLen[i]);
      ASSERT(colLen[i] > 0);

3738
      SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
H
Haojun Liao 已提交
3739 3740 3741
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
        pColInfoData->varmeta.length = colLen[i];
        pColInfoData->varmeta.allocLen = colLen[i];
3742

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

wafwerar's avatar
wafwerar 已提交
3746
        pColInfoData->pData = taosMemoryMalloc(colLen[i]);
H
Haojun Liao 已提交
3747 3748 3749
      } else {
        memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
        pStart += BitmapLen(numOfRows);
3750
      }
H
Haojun Liao 已提交
3751 3752

      memcpy(pColInfoData->pData, pStart, colLen[i]);
3753 3754 3755
      //TODO setting this flag to true temporarily so aggregate function on stable will
      //examine NULL value for non-primary key column
      pColInfoData->hasNull = true;
H
Haojun Liao 已提交
3756
      pStart += colLen[i];
3757
    }
H
Haojun Liao 已提交
3758
  } else {  // extract data according to pColList
3759
    ASSERT(numOfOutput == taosArrayGetSize(pColList));
3760 3761 3762 3763 3764 3765
    char* pStart = pData;

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

    SSysTableSchema* pSchema = (SSysTableSchema*)pStart;
dengyihao's avatar
dengyihao 已提交
3766
    for (int32_t i = 0; i < numOfCols; ++i) {
3767 3768 3769 3770 3771 3772 3773 3774
      SSysTableSchema* p = (SSysTableSchema*)pStart;

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

    SSDataBlock block = {.pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData)), .info.numOfCols = numOfCols};
dengyihao's avatar
dengyihao 已提交
3775
    for (int32_t i = 0; i < numOfCols; ++i) {
3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788
      SColumnInfoData idata = {0};
      idata.info.type = pSchema[i].type;
      idata.info.bytes = pSchema[i].bytes;
      idata.info.colId = pSchema[i].colId;

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

    blockDataEnsureCapacity(&block, numOfRows);

3789 3790 3791 3792 3793
    int32_t dataLen = *(int32_t*) pStart;
    uint64_t groupId = *(uint64_t*) (pStart + sizeof(int32_t));
    pStart += sizeof(int32_t) + sizeof(uint64_t);

    int32_t* colLen = (int32_t*) (pStart);
3794 3795 3796 3797
    pStart += sizeof(int32_t) * numOfCols;

    for (int32_t i = 0; i < numOfCols; ++i) {
      colLen[i] = htonl(colLen[i]);
3798
      ASSERT(colLen[i] >= 0);
3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816

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

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

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

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

    // data from mnode
3819 3820 3821
    for (int32_t i = 0; i < numOfCols; ++i) {
      SColumnInfoData* pSrc = taosArrayGet(block.pDataBlock, i);

L
Liu Jicong 已提交
3822 3823
      for (int32_t j = 0; j < numOfOutput; ++j) {
        int16_t colIndex = *(int16_t*)taosArrayGet(pColList, j);
3824

3825 3826
        if (colIndex - 1 == i) {
          SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, j);
3827
          colDataAssign(pColInfoData, pSrc, numOfRows);
3828 3829 3830
          break;
        }
      }
3831
    }
3832
  }
3833

H
Haojun Liao 已提交
3834
  pRes->info.rows = numOfRows;
3835
  blockDataUpdateTsWindow(pRes);
3836

3837
  int64_t el = taosGetTimestampUs() - startTs;
3838

H
Haojun Liao 已提交
3839 3840
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
3841

H
Haojun Liao 已提交
3842 3843 3844
  if (total != NULL) {
    *total += numOfRows;
  }
3845

H
Haojun Liao 已提交
3846
  pLoadInfo->totalElapsed += el;
3847 3848
  return TSDB_CODE_SUCCESS;
}
3849

L
Liu Jicong 已提交
3850 3851
static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
3852
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3853

L
Liu Jicong 已提交
3854
  int64_t              el = taosGetTimestampUs() - startTs;
H
Haojun Liao 已提交
3855 3856
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
  pLoadInfo->totalElapsed += el;
H
Haojun Liao 已提交
3857

3858
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
L
Liu Jicong 已提交
3859 3860 3861
  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);
3862 3863 3864 3865 3866

  doSetOperatorCompleted(pOperator);
  return NULL;
}

L
Liu Jicong 已提交
3867 3868
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
                                                   SExecTaskInfo* pTaskInfo) {
3869 3870 3871 3872 3873 3874 3875 3876 3877
  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);

3878
      if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
3879
        completed += 1;
H
Haojun Liao 已提交
3880 3881
        continue;
      }
3882

3883
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
3884 3885 3886
        continue;
      }

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

L
Liu Jicong 已提交
3890
      SSDataBlock*         pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
3891
      SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
3892
      if (pRsp->numOfRows == 0) {
L
Liu Jicong 已提交
3893 3894
        qDebug("%s vgId:%d, taskID:0x%" PRIx64 " index:%d completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
               " try next",
3895
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, i + 1, pDataInfo->totalRows,
H
Haojun Liao 已提交
3896
               pExchangeInfo->loadInfo.totalRows);
3897
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3898 3899 3900
        completed += 1;
        continue;
      }
H
Haojun Liao 已提交
3901

H
Haojun Liao 已提交
3902
      SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
3903 3904 3905
      code =
          setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                    pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
3906
      if (code != 0) {
3907 3908 3909
        goto _error;
      }

3910 3911 3912
      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 已提交
3913 3914
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
               pLoadInfo->totalRows, pLoadInfo->totalSize, i + 1, totalSources);
3915
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3916
      } else {
dengyihao's avatar
dengyihao 已提交
3917 3918
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64
               ", totalBytes:%" PRIu64,
H
Haojun Liao 已提交
3919 3920
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
               pLoadInfo->totalSize);
3921 3922
      }

3923 3924
      if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED) {
        pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943
        code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
        if (code != TSDB_CODE_SUCCESS) {
          goto _error;
        }
      }

      return pExchangeInfo->pResult;
    }

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

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

L
Liu Jicong 已提交
3944 3945 3946
static SSDataBlock* concurrentlyLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3947

H
Haojun Liao 已提交
3948 3949 3950
  if (pOperator->status == OP_RES_TO_RETURN) {
    return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
  }
3951

L
Liu Jicong 已提交
3952
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3953 3954 3955
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
3956
  for (int32_t i = 0; i < totalSources; ++i) {
3957 3958
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
3959
      return NULL;
3960 3961 3962 3963
    }
  }

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

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
3968 3969
  pOperator->status = OP_RES_TO_RETURN;
  return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
3970 3971
}

L
Liu Jicong 已提交
3972 3973 3974
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3975

L
Liu Jicong 已提交
3976
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
3977 3978 3979
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
3980
  for (int32_t i = 0; i < totalSources; ++i) {
3981 3982
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
3983 3984
      pTaskInfo->code = code;
      return code;
3985 3986 3987 3988
    }
  }

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

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

H
Haojun Liao 已提交
3995
  return TSDB_CODE_SUCCESS;
3996 3997
}

L
Liu Jicong 已提交
3998 3999 4000
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4001

L
Liu Jicong 已提交
4002
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4003
  int64_t startTs = taosGetTimestampUs();
4004

L
Liu Jicong 已提交
4005
  while (1) {
4006 4007
    if (pExchangeInfo->current >= totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
4008
    }
4009

4010 4011 4012
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

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

H
Haojun Liao 已提交
4016
    if (pDataInfo->code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
dengyihao 已提交
4017 4018
      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 已提交
4019 4020 4021 4022
      pOperator->pTaskInfo->code = pDataInfo->code;
      return NULL;
    }

L
Liu Jicong 已提交
4023
    SRetrieveTableRsp*   pRsp = pDataInfo->pRsp;
H
Haojun Liao 已提交
4024
    SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
4025
    if (pRsp->numOfRows == 0) {
dengyihao's avatar
dengyihao 已提交
4026 4027
      qDebug("%s vgId:%d, taskID:0x%" PRIx64 " %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
             " try next",
4028
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
H
Haojun Liao 已提交
4029
             pDataInfo->totalRows, pLoadInfo->totalRows);
H
Haojun Liao 已提交
4030

4031
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4032 4033 4034
      pExchangeInfo->current += 1;
      continue;
    }
H
Haojun Liao 已提交
4035

L
Liu Jicong 已提交
4036
    SSDataBlock*       pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
4037
    SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
4038 4039 4040
    int32_t            code =
        setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                  pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
4041 4042

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

4048
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4049 4050
      pExchangeInfo->current += 1;
    } else {
L
Liu Jicong 已提交
4051 4052 4053 4054
      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);
4055 4056 4057 4058
    }

    return pExchangeInfo->pResult;
  }
4059 4060
}

L
Liu Jicong 已提交
4061
static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
4062
  if (OPTR_IS_OPENED(pOperator)) {
H
Haojun Liao 已提交
4063 4064 4065
    return TSDB_CODE_SUCCESS;
  }

L
Liu Jicong 已提交
4066
  SExchangeInfo* pExchangeInfo = pOperator->info;
H
Haojun Liao 已提交
4067 4068 4069 4070 4071 4072 4073 4074 4075
  if (pExchangeInfo->seqLoadData) {
    // do nothing for sequentially load data
  } else {
    int32_t code = prepareConcurrentlyLoad(pOperator);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

4076
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
4077 4078 4079
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4080 4081 4082
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4083

4084 4085
  pTaskInfo->code = pOperator->_openFn(pOperator);
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4086 4087
    return NULL;
  }
4088

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

4092
  if (pOperator->status == OP_EXEC_DONE) {
L
Liu Jicong 已提交
4093 4094 4095
    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);
4096 4097 4098 4099
    return NULL;
  }

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

4101 4102 4103
  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
4104
    return concurrentlyLoadRemoteData(pOperator);
4105
  }
H
Haojun Liao 已提交
4106

4107
#if 0
H
Haojun Liao 已提交
4108
  _error:
wafwerar's avatar
wafwerar 已提交
4109 4110
  taosMemoryFreeClear(pMsg);
  taosMemoryFreeClear(pMsgSendInfo);
H
Haojun Liao 已提交
4111 4112 4113

  terrno = pTaskInfo->code;
  return NULL;
4114
#endif
H
Haojun Liao 已提交
4115
}
4116

H
Haojun Liao 已提交
4117
static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
4118
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
H
Haojun Liao 已提交
4119 4120
  if (pInfo->pSourceDataInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
4121 4122
  }

L
Liu Jicong 已提交
4123
  for (int32_t i = 0; i < numOfSources; ++i) {
4124
    SSourceDataInfo dataInfo = {0};
H
Haojun Liao 已提交
4125
    dataInfo.status = EX_SOURCE_DATA_NOT_READY;
L
Liu Jicong 已提交
4126 4127
    dataInfo.pEx = pInfo;
    dataInfo.index = i;
4128

H
Haojun Liao 已提交
4129 4130 4131 4132 4133 4134 4135 4136 4137 4138
    void* ret = taosArrayPush(pInfo->pSourceDataInfo, &dataInfo);
    if (ret == NULL) {
      taosArrayDestroy(pInfo->pSourceDataInfo);
      return TSDB_CODE_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
4139
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
4140
  SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
wafwerar's avatar
wafwerar 已提交
4141
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4142 4143

  if (pInfo == NULL || pOperator == NULL) {
wafwerar's avatar
wafwerar 已提交
4144 4145
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4146 4147
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
H
Haojun Liao 已提交
4148 4149
  }

H
Haojun Liao 已提交
4150
  size_t numOfSources = LIST_LENGTH(pSources);
H
Haojun Liao 已提交
4151
  pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
H
Haojun Liao 已提交
4152 4153 4154
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
  if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
    goto _error;
H
Haojun Liao 已提交
4155 4156
  }

L
Liu Jicong 已提交
4157 4158
  for (int32_t i = 0; i < numOfSources; ++i) {
    SNodeListNode* pNode = nodesListGetNode((SNodeList*)pSources, i);
H
Haojun Liao 已提交
4159 4160
    taosArrayPush(pInfo->pSources, pNode);
  }
4161

H
Haojun Liao 已提交
4162 4163 4164
  int32_t code = initDataSource(numOfSources, pInfo);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4165
  }
H
Haojun Liao 已提交
4166

dengyihao's avatar
dengyihao 已提交
4167
  pInfo->pResult = pBlock;
4168 4169 4170
  pInfo->seqLoadData = true;

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

dengyihao's avatar
dengyihao 已提交
4172
  pOperator->name = "ExchangeOperator";
X
Xiaoyu Wang 已提交
4173
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
4174
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
4175 4176 4177 4178 4179 4180 4181
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = pBlock->info.numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->_openFn = prepareLoadRemoteData;  // assign a dummy function.
  pOperator->getNextFn = doLoadRemoteData;
  pOperator->closeFn = destroyExchangeOperatorInfo;
4182

S
Shengliang Guan 已提交
4183
#if 1
L
Liu Jicong 已提交
4184
  {  // todo refactor
H
Haojun Liao 已提交
4185 4186 4187
    SRpcInit rpcInit;
    memset(&rpcInit, 0, sizeof(rpcInit));
    rpcInit.localPort = 0;
H
Haojun Liao 已提交
4188
    rpcInit.label = "EX";
H
Haojun Liao 已提交
4189
    rpcInit.numOfThreads = 1;
S
Shengliang Guan 已提交
4190
    rpcInit.cfp = qProcessFetchRsp;
S
Shengliang Guan 已提交
4191
    rpcInit.sessions = tsMaxConnections;
H
Haojun Liao 已提交
4192
    rpcInit.connType = TAOS_CONN_CLIENT;
L
Liu Jicong 已提交
4193
    rpcInit.user = (char*)"root";
S
Shengliang Guan 已提交
4194
    rpcInit.idleTime = tsShellActivityTimer * 1000;
H
Haojun Liao 已提交
4195
    rpcInit.ckey = "key";
S
Shengliang Guan 已提交
4196
    rpcInit.spi = 1;
L
Liu Jicong 已提交
4197
    rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
H
Haojun Liao 已提交
4198 4199 4200

    pInfo->pTransporter = rpcOpen(&rpcInit);
    if (pInfo->pTransporter == NULL) {
L
Liu Jicong 已提交
4201
      return NULL;  // todo
H
Haojun Liao 已提交
4202 4203
    }
  }
S
Shengliang 已提交
4204
#endif
4205

4206
  return pOperator;
H
Haojun Liao 已提交
4207

L
Liu Jicong 已提交
4208
_error:
H
Haojun Liao 已提交
4209
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4210
    destroyExchangeOperatorInfo(pInfo, numOfSources);
H
Haojun Liao 已提交
4211 4212
  }

wafwerar's avatar
wafwerar 已提交
4213 4214
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4215
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
4216
  return NULL;
4217 4218
}

dengyihao's avatar
dengyihao 已提交
4219 4220
static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                                const char* pKey);
H
Haojun Liao 已提交
4221
static void    cleanupAggSup(SAggSupporter* pAggSup);
4222

4223
static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4224
  SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*)param;
H
Haojun Liao 已提交
4225
  taosArrayDestroy(pInfo->pSortInfo);
4226 4227 4228
  taosArrayDestroy(pInfo->groupInfo);

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
4229
    tsortDestroySortHandle(pInfo->pSortHandle);
4230 4231
  }

H
Haojun Liao 已提交
4232
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
4233
  cleanupAggSup(&pInfo->aggSup);
4234
}
H
Haojun Liao 已提交
4235

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

X
Xiaoyu Wang 已提交
4239
  *dst = *src;
4240

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

L
Liu Jicong 已提交
4245 4246 4247 4248
  //  memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
  //  for (int32_t j = 0; j < src->base.numOfParams; ++j) {
  //    taosVariantAssign(&dst->base.param[j], &src->base.param[j]);
  //  }
X
Xiaoyu Wang 已提交
4249
}
4250

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

H
Haojun Liao 已提交
4256
    bool isNull = tsortIsNullVal(pTupleHandle, i);
H
Haojun Liao 已提交
4257 4258 4259
    if (isNull) {
      colDataAppend(pColInfo, pBlock->info.rows, NULL, true);
    } else {
H
Haojun Liao 已提交
4260
      char* pData = tsortGetValue(pTupleHandle, i);
H
Haojun Liao 已提交
4261 4262
      colDataAppend(pColInfo, pBlock->info.rows, pData, false);
    }
4263 4264
  }

4265 4266
  pBlock->info.rows += 1;
}
4267

H
Haojun Liao 已提交
4268
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity) {
4269
  blockDataCleanup(pDataBlock);
D
dapan1121 已提交
4270
  blockDataEnsureCapacity(pDataBlock, capacity);
4271

wmmhello's avatar
wmmhello 已提交
4272 4273
  blockDataEnsureCapacity(pDataBlock, capacity);

L
Liu Jicong 已提交
4274
  while (1) {
H
Haojun Liao 已提交
4275
    STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4276 4277 4278
    if (pTupleHandle == NULL) {
      break;
    }
4279

4280 4281 4282
    appendOneRowToDataBlock(pDataBlock, pTupleHandle);
    if (pDataBlock->info.rows >= capacity) {
      return pDataBlock;
H
Haojun Liao 已提交
4283 4284
    }
  }
4285

L
Liu Jicong 已提交
4286
  return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
4287
}
4288

4289
SSDataBlock* loadNextDataBlock(void* param) {
L
Liu Jicong 已提交
4290 4291
  SOperatorInfo* pOperator = (SOperatorInfo*)param;
  bool           newgroup = false;
H
Haojun Liao 已提交
4292
  return pOperator->getNextFn(pOperator, &newgroup);
4293 4294
}

L
Liu Jicong 已提交
4295
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
4296 4297 4298 4299
  size_t size = taosArrayGetSize(groupInfo);
  if (size == 0) {
    return true;
  }
4300

4301 4302
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
4303

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

4307 4308 4309
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
4310

4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323
    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;
      }
4324 4325 4326
    }
  }

4327
  return 0;
4328 4329
}

L
Liu Jicong 已提交
4330 4331 4332
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
4333
    pCtx[j].startRow = rowIndex;
4334 4335
  }

4336 4337
  for (int32_t j = 0; j < numOfExpr; ++j) {
    int32_t functionId = pCtx[j].functionId;
L
Liu Jicong 已提交
4338 4339 4340 4341 4342 4343 4344 4345 4346
    //    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]);
    //    }
4347
  }
4348
}
4349

L
Liu Jicong 已提交
4350 4351
static void doFinalizeResultImpl(SqlFunctionCtx* pCtx, int32_t numOfExpr) {
  for (int32_t j = 0; j < numOfExpr; ++j) {
4352 4353 4354 4355
    int32_t functionId = pCtx[j].functionId;
    //    if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
    //      continue;
    //    }
4356

4357 4358 4359 4360
    //    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 已提交
4361
    //    pCtx[j].fpSet.finalize(&pCtx[j]);
4362 4363
  }
}
4364

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

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

4372 4373 4374
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
4375

4376 4377
  return true;
}
4378

4379 4380
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
4381

4382
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
L
Liu Jicong 已提交
4383
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
4384 4385
    pCtx[i].size = 1;
  }
4386

L
Liu Jicong 已提交
4387
  for (int32_t i = 0; i < pBlock->info.rows; ++i) {
4388 4389 4390 4391 4392 4393 4394 4395 4396
    if (!pInfo->hasGroupVal) {
      ASSERT(i == 0);
      doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
      pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
    } else {
      if (needToMerge(pBlock, pInfo->groupInfo, pInfo->groupVal, i)) {
        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
      } else {
        doFinalizeResultImpl(pCtx, numOfExpr);
H
Haojun Liao 已提交
4397
        int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4398
        //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4399

4400
        // TODO check for available buffer;
H
Haojun Liao 已提交
4401

4402 4403 4404 4405 4406
        // next group info data
        pInfo->binfo.pRes->info.rows += numOfRows;
        for (int32_t j = 0; j < numOfExpr; ++j) {
          if (pCtx[j].functionId < 0) {
            continue;
4407
          }
4408

H
Haojun Liao 已提交
4409
          pCtx[j].fpSet.process(&pCtx[j]);
4410
        }
4411 4412 4413

        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
        pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
H
Haojun Liao 已提交
4414
      }
4415 4416 4417 4418
    }
  }
}

4419 4420
static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
4421
  SSortHandle*              pHandle = pInfo->pSortHandle;
4422

4423
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes, false);
4424
  blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
4425

L
Liu Jicong 已提交
4426
  while (1) {
4427
    blockDataCleanup(pDataBlock);
4428
    while (1) {
H
Haojun Liao 已提交
4429
      STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4430 4431
      if (pTupleHandle == NULL) {
        break;
4432
      }
4433

4434 4435
      // build datablock for merge for one group
      appendOneRowToDataBlock(pDataBlock, pTupleHandle);
4436
      if (pDataBlock->info.rows >= pOperator->resultInfo.capacity) {
4437 4438
        break;
      }
4439
    }
4440

4441 4442 4443
    if (pDataBlock->info.rows == 0) {
      break;
    }
4444

4445
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, true);
L
Liu Jicong 已提交
4446 4447
    //  updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
    //  pOperator->pRuntimeEnv, true);
4448 4449 4450
    doMergeImpl(pOperator, pOperator->numOfOutput, pDataBlock);
    // flush to tuple store, and after all data have been handled, return to upstream node or sink node
  }
4451

4452
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
4453
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4454
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4455

4456
  // TODO check for available buffer;
4457

4458 4459
  // next group info data
  pInfo->binfo.pRes->info.rows += numOfRows;
L
Liu Jicong 已提交
4460
  return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
4461
}
4462

L
Liu Jicong 已提交
4463
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator, bool* newgroup) {
4464 4465
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
4466 4467
  }

L
Liu Jicong 已提交
4468
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
4469
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
4470
  if (pOperator->status == OP_RES_TO_RETURN) {
4471
    return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity);
4472 4473
  }

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

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

L
Liu Jicong 已提交
4480
  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
wmmhello's avatar
wmmhello 已提交
4481
    SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
H
Haojun Liao 已提交
4482
    ps->param = pOperator->pDownstream[i];
H
Haojun Liao 已提交
4483
    tsortAddSource(pInfo->pSortHandle, ps);
4484 4485
  }

H
Haojun Liao 已提交
4486
  int32_t code = tsortOpen(pInfo->pSortHandle);
4487
  if (code != TSDB_CODE_SUCCESS) {
4488
    longjmp(pTaskInfo->env, terrno);
4489 4490
  }

H
Haojun Liao 已提交
4491
  pOperator->status = OP_RES_TO_RETURN;
4492
  return doMerge(pOperator);
4493
}
4494

L
Liu Jicong 已提交
4495 4496
static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo,
                            SSortedMergeOperatorInfo* pInfo) {
4497 4498
  if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) {
    return 0;
H
Haojun Liao 已提交
4499 4500
  }

4501 4502 4503 4504 4505 4506 4507 4508
  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 已提交
4509 4510
  size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo);
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4511
    SColumn* pCol = taosArrayGet(pGroupInfo, i);
L
Liu Jicong 已提交
4512
    for (int32_t j = 0; j < numOfCols; ++j) {
H
Haojun Liao 已提交
4513
      SExprInfo* pe = &pExprInfo[j];
4514
      if (pe->base.resSchema.slotId == pCol->colId) {
4515 4516
        taosArrayPush(plist, pCol);
        taosArrayPush(pInfo->groupInfo, &j);
H
Haojun Liao 已提交
4517
        len += pCol->bytes;
4518 4519
        break;
      }
H
Haojun Liao 已提交
4520 4521 4522
    }
  }

4523
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
4524

wafwerar's avatar
wafwerar 已提交
4525
  pInfo->groupVal = taosMemoryCalloc(1, (POINTER_BYTES * numOfGroupCol + len));
4526 4527 4528 4529
  if (pInfo->groupVal == NULL) {
    taosArrayDestroy(plist);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
4530

4531
  int32_t offset = 0;
L
Liu Jicong 已提交
4532 4533
  char*   start = (char*)(pInfo->groupVal + (POINTER_BYTES * numOfGroupCol));
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4534 4535
    pInfo->groupVal[i] = start + offset;
    SColumn* pCol = taosArrayGet(plist, i);
H
Haojun Liao 已提交
4536
    offset += pCol->bytes;
4537
  }
H
Haojun Liao 已提交
4538

4539
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
4540

4541 4542
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
4543

L
Liu Jicong 已提交
4544 4545 4546
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                             int32_t num, SArray* pSortInfo, SArray* pGroupInfo,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4547
  SSortedMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortedMergeOperatorInfo));
L
Liu Jicong 已提交
4548
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
4549
  if (pInfo == NULL || pOperator == NULL) {
4550
    goto _error;
4551
  }
H
Haojun Liao 已提交
4552

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

4556 4557 4558
  if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
4559

dengyihao's avatar
dengyihao 已提交
4560
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
4561
  int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, keyBufSize, pTaskInfo->id.str);
4562 4563 4564
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4565

H
Haojun Liao 已提交
4566
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
H
Haojun Liao 已提交
4567
  code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo);
4568 4569 4570
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4571

L
Liu Jicong 已提交
4572 4573 4574 4575 4576
  //  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 已提交
4577

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

L
Liu Jicong 已提交
4580
  pOperator->name = "SortedMerge";
X
Xiaoyu Wang 已提交
4581
  // pOperator->operatorType = OP_SortedMerge;
4582
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
4583 4584 4585 4586
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = num;
  pOperator->pExpr = pExprInfo;
H
Haojun Liao 已提交
4587

L
Liu Jicong 已提交
4588 4589 4590
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->getNextFn = doSortedMerge;
  pOperator->closeFn = destroySortedMergeOperatorInfo;
H
Haojun Liao 已提交
4591

4592 4593 4594
  code = appendDownstream(pOperator, downstream, numOfDownstream);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4595
  }
H
Haojun Liao 已提交
4596

4597
  return pOperator;
H
Haojun Liao 已提交
4598

L
Liu Jicong 已提交
4599
_error:
4600
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4601
    destroySortedMergeOperatorInfo(pInfo, num);
H
Haojun Liao 已提交
4602 4603
  }

wafwerar's avatar
wafwerar 已提交
4604 4605
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
4606 4607
  terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
  return NULL;
H
Haojun Liao 已提交
4608 4609
}

L
Liu Jicong 已提交
4610
static SSDataBlock* doSort(SOperatorInfo* pOperator, bool* newgroup) {
4611 4612 4613 4614
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

L
Liu Jicong 已提交
4615
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
4616 4617
  SSortOperatorInfo* pInfo = pOperator->info;

H
Haojun Liao 已提交
4618
  if (pOperator->status == OP_RES_TO_RETURN) {
H
Haojun Liao 已提交
4619
    return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
H
Haojun Liao 已提交
4620 4621
  }

4622
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
dengyihao's avatar
dengyihao 已提交
4623 4624
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, pInfo->inputSlotMap, SORT_SINGLESOURCE_SORT,
                                             pInfo->bufPageSize, numOfBufPage, pInfo->pDataBlock, pTaskInfo->id.str);
4625

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

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

H
Haojun Liao 已提交
4632
  int32_t code = tsortOpen(pInfo->pSortHandle);
4633
  taosMemoryFreeClear(ps);
4634
  if (code != TSDB_CODE_SUCCESS) {
4635
    longjmp(pTaskInfo->env, terrno);
4636
  }
4637

H
Haojun Liao 已提交
4638
  pOperator->status = OP_RES_TO_RETURN;
H
Haojun Liao 已提交
4639
  return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
4640 4641
}

dengyihao's avatar
dengyihao 已提交
4642 4643
SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo,
                                      SArray* pIndexMap, SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
4644
  SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo));
L
Liu Jicong 已提交
4645
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
dengyihao's avatar
dengyihao 已提交
4646
  int32_t            rowSize = pResBlock->info.rowSize;
4647 4648

  if (pInfo == NULL || pOperator == NULL || rowSize > 100 * 1024 * 1024) {
wafwerar's avatar
wafwerar 已提交
4649 4650
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4651 4652 4653
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
  }
4654

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

wmmhello's avatar
wmmhello 已提交
4657
  pInfo->sortBufSize = pInfo->bufPageSize * 16;  // TODO dynamic set the available sort buffer
L
Liu Jicong 已提交
4658 4659 4660
  pInfo->numOfRowsInRes = 1024;
  pInfo->pDataBlock = pResBlock;
  pInfo->pSortInfo = pSortInfo;
4661
  pInfo->inputSlotMap = pIndexMap;
H
Haojun Liao 已提交
4662

dengyihao's avatar
dengyihao 已提交
4663
  pOperator->name = "SortOperator";
L
Liu Jicong 已提交
4664 4665
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
4666 4667
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
4668

dengyihao's avatar
dengyihao 已提交
4669 4670 4671
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->getNextFn = doSort;
  pOperator->closeFn = destroyOrderOperatorInfo;
4672

4673
  int32_t code = appendDownstream(pOperator, &downstream, 1);
4674
  return pOperator;
H
Haojun Liao 已提交
4675

dengyihao's avatar
dengyihao 已提交
4676
_error:
H
Haojun Liao 已提交
4677 4678 4679 4680
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  return NULL;
4681 4682
}

4683 4684
int32_t getTableScanOrder(SOperatorInfo* pOperator) {
  if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
H
Haojun Liao 已提交
4685
    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
4686
      return TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4687 4688
    } else {
      return getTableScanOrder(pOperator->pDownstream[0]);
4689 4690 4691 4692 4693 4694
    }
  }

  STableScanInfo* pTableScanInfo = pOperator->info;
  return pTableScanInfo->cond.order;
}
4695 4696

// this is a blocking operator
L
Liu Jicong 已提交
4697
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
4698 4699
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
4700 4701
  }

H
Haojun Liao 已提交
4702
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
4703
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
4704

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

H
Haojun Liao 已提交
4707
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4708
  SOperatorInfo* downstream = pOperator->pDownstream[0];
4709

H
Haojun Liao 已提交
4710 4711
  bool newgroup = true;
  while (1) {
H
Haojun Liao 已提交
4712
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
4713
    SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
4714
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
4715 4716 4717 4718

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
4719 4720 4721
    //    if (pAggInfo->current != NULL) {
    //      setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
4722

4723 4724
    // there is an scalar expression that needs to be calculated before apply the group aggregation.
    if (pAggInfo->pScalarExprInfo != NULL) {
dengyihao's avatar
dengyihao 已提交
4725 4726
      projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, pAggInfo->numOfScalarExpr,
                            NULL);
4727 4728
    }

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

dengyihao's avatar
dengyihao 已提交
4734
#if 0  // test for encode/decode result info
4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745
    if(pOperator->encodeResultRow){
      char *result = NULL;
      int32_t length = 0;
      SAggSupporter   *pSup = &pAggInfo->aggSup;
      pOperator->encodeResultRow(pOperator, pSup, pInfo, &result, &length);
      taosHashClear(pSup->pResultRowHashTable);
      pInfo->resultRowInfo.size = 0;
      pOperator->decodeResultRow(pOperator, pSup, pInfo, result, length);
      if(result){
        taosMemoryFree(result);
      }
4746
    }
4747
#endif
4748 4749
  }

H
Haojun Liao 已提交
4750 4751 4752
  closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pAggInfo->binfo.pCtx, pOperator->numOfOutput, pAggInfo->aggSup.pResultBuf,
                                &pAggInfo->binfo.resultRowInfo, pAggInfo->binfo.rowCellInfoOffset);
H
Haojun Liao 已提交
4753

4754
  initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, false);
H
Haojun Liao 已提交
4755 4756 4757 4758
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4759 4760
static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup) {
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
4761 4762 4763 4764 4765 4766
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;

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

L
Liu Jicong 已提交
4767
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
4768 4769 4770 4771 4772
  pTaskInfo->code = pOperator->_openFn(pOperator);
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
    return NULL;
  }

H
Haojun Liao 已提交
4773
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
4774 4775
  doBuildResultDatablock(pInfo->pRes, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf,
                         pInfo->rowCellInfoOffset, pInfo->pCtx);
H
Haojun Liao 已提交
4776 4777 4778
  if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
4779

H
Haojun Liao 已提交
4780
  doSetOperatorCompleted(pOperator);
L
Liu Jicong 已提交
4781
  return (blockDataGetNumOfRows(pInfo->pRes) != 0) ? pInfo->pRes : NULL;
4782 4783
}

dengyihao's avatar
dengyihao 已提交
4784 4785
void aggEncodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char** result,
                        int32_t* length) {
wmmhello's avatar
wmmhello 已提交
4786
  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
4787
  size_t  keyLen = sizeof(uint64_t) * 2;  // estimate the key length
wmmhello's avatar
wmmhello 已提交
4788
  int32_t totalSize = sizeof(int32_t) + size * (sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize);
wafwerar's avatar
wafwerar 已提交
4789
  *result = taosMemoryCalloc(1, totalSize);
L
Liu Jicong 已提交
4790
  if (*result == NULL) {
4791
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
wmmhello's avatar
wmmhello 已提交
4792 4793 4794
  }
  *(int32_t*)(*result) = size;
  int32_t offset = sizeof(int32_t);
4795 4796

  // prepare memory
4797
  SResultRowPosition* pos = &pInfo->resultRowInfo.cur;
dengyihao's avatar
dengyihao 已提交
4798 4799
  void*               pPage = getBufPage(pSup->pResultBuf, pos->pageId);
  SResultRow*         pRow = (SResultRow*)((char*)pPage + pos->offset);
4800 4801 4802
  setBufPageDirty(pPage, true);
  releaseBufPage(pSup->pResultBuf, pPage);

dengyihao's avatar
dengyihao 已提交
4803
  void* pIter = taosHashIterate(pSup->pResultRowHashTable, NULL);
wmmhello's avatar
wmmhello 已提交
4804
  while (pIter) {
dengyihao's avatar
dengyihao 已提交
4805
    void*               key = taosHashGetKey(pIter, &keyLen);
4806
    SResultRowPosition* p1 = (SResultRowPosition*)pIter;
4807

dengyihao's avatar
dengyihao 已提交
4808
    pPage = (SFilePage*)getBufPage(pSup->pResultBuf, p1->pageId);
4809
    pRow = (SResultRow*)((char*)pPage + p1->offset);
4810 4811
    setBufPageDirty(pPage, true);
    releaseBufPage(pSup->pResultBuf, pPage);
wmmhello's avatar
wmmhello 已提交
4812 4813 4814

    // recalculate the result size
    int32_t realTotalSize = offset + sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize;
L
Liu Jicong 已提交
4815 4816 4817
    if (realTotalSize > totalSize) {
      char* tmp = taosMemoryRealloc(*result, realTotalSize);
      if (tmp == NULL) {
wmmhello's avatar
wmmhello 已提交
4818
        terrno = TSDB_CODE_OUT_OF_MEMORY;
wafwerar's avatar
wafwerar 已提交
4819
        taosMemoryFree(*result);
wmmhello's avatar
wmmhello 已提交
4820
        *result = NULL;
4821
        longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
L
Liu Jicong 已提交
4822
      } else {
wmmhello's avatar
wmmhello 已提交
4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834
        *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);
4835
    memcpy(*result + offset, pRow, pSup->resultRowSize);
wmmhello's avatar
wmmhello 已提交
4836 4837 4838 4839 4840
    offset += pSup->resultRowSize;

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

L
Liu Jicong 已提交
4841
  if (length) {
wmmhello's avatar
wmmhello 已提交
4842 4843 4844 4845 4846
    *length = offset;
  }
  return;
}

dengyihao's avatar
dengyihao 已提交
4847 4848
bool aggDecodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char* result,
                        int32_t length) {
L
Liu Jicong 已提交
4849
  if (!result || length <= 0) {
wmmhello's avatar
wmmhello 已提交
4850 4851 4852 4853 4854 4855 4856
    return false;
  }

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

  int32_t offset = sizeof(int32_t);
L
Liu Jicong 已提交
4857
  while (count-- > 0 && length > offset) {
wmmhello's avatar
wmmhello 已提交
4858 4859 4860
    int32_t keyLen = *(int32_t*)(result + offset);
    offset += sizeof(int32_t);

L
Liu Jicong 已提交
4861 4862 4863
    uint64_t    tableGroupId = *(uint64_t*)(result + offset);
    SResultRow* resultRow = getNewResultRow_rv(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
    if (!resultRow) {
4864
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4865
    }
4866

wmmhello's avatar
wmmhello 已提交
4867
    // add a new result set for a new group
4868 4869
    SResultRowPosition pos = {.pageId = resultRow->pageId, .offset = resultRow->offset};
    taosHashPut(pSup->pResultRowHashTable, result + offset, keyLen, &pos, sizeof(SResultRowPosition));
wmmhello's avatar
wmmhello 已提交
4870 4871 4872

    offset += keyLen;
    int32_t valueLen = *(int32_t*)(result + offset);
L
Liu Jicong 已提交
4873
    if (valueLen != pSup->resultRowSize) {
4874
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4875 4876 4877 4878 4879 4880 4881 4882 4883 4884
    }
    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);
4885
    prepareResultListBuffer(&pInfo->resultRowInfo, pOperator->pTaskInfo->env);
dengyihao's avatar
dengyihao 已提交
4886
    //    pInfo->resultRowInfo.cur = pInfo->resultRowInfo.size;
4887 4888
//    pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
//        (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
dengyihao's avatar
dengyihao 已提交
4889
    pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
wmmhello's avatar
wmmhello 已提交
4890 4891
  }

L
Liu Jicong 已提交
4892
  if (offset != length) {
4893
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4894 4895 4896 4897
  }
  return true;
}

4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967
enum {
  PROJECT_RETRIEVE_CONTINUE = 0x1,
  PROJECT_RETRIEVE_DONE     = 0x2,
};

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

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

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

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

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

      return PROJECT_RETRIEVE_DONE;
    }

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

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

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

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

  if (pRes->info.rows >= pOperator->resultInfo.threshold) {

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

    return PROJECT_RETRIEVE_DONE;
  } else { // not full enough, continue to accumulate the output data in the buffer.
    return PROJECT_RETRIEVE_CONTINUE;
  }
}

L
Liu Jicong 已提交
4968
static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup) {
4969
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
L
Liu Jicong 已提交
4970
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
4971 4972

  SSDataBlock* pRes = pInfo->pRes;
4973
  blockDataCleanup(pRes);
4974 4975 4976 4977

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

H
Haojun Liao 已提交
4979
#if 0
4980 4981 4982 4983 4984 4985
  if (pProjectInfo->existDataBlock) {  // TODO refactor
    SSDataBlock* pBlock = pProjectInfo->existDataBlock;
    pProjectInfo->existDataBlock = NULL;
    *newgroup = true;

    // todo dynamic set tags
L
Liu Jicong 已提交
4986 4987 4988
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
4989 4990

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

H
Haojun Liao 已提交
4993
    blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
4994
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
L
Liu Jicong 已提交
4995
    if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
4996 4997 4998 4999 5000
      copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
      resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
      return pRes;
    }
  }
H
Haojun Liao 已提交
5001
#endif
5002

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

L
Liu Jicong 已提交
5005
  while (1) {
5006 5007
    bool prevVal = *newgroup;

H
Haojun Liao 已提交
5008
    // The downstream exec may change the value of the newgroup, so use a local variable instead.
H
Haojun Liao 已提交
5009 5010 5011
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5012 5013 5014

    if (pBlock == NULL) {
      *newgroup = prevVal;
5015
      setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5016 5017 5018 5019 5020 5021 5022 5023
      break;
    }

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

    // todo dynamic set tags
H
Haojun Liao 已提交
5030 5031 5032 5033
    //    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5034 5035

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

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

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

5044 5045
    int32_t status = handleLimitOffset(pOperator, pBlock);
    if (status == PROJECT_RETRIEVE_CONTINUE) {
H
Haojun Liao 已提交
5046
      continue;
5047
    } else if (status == PROJECT_RETRIEVE_DONE)  {
5048 5049 5050
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
5051

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

L
Liu Jicong 已提交
5054 5055
  //  copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
  return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
5056 5057
}

L
Liu Jicong 已提交
5058
static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
5059 5060
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
5061 5062
  }

dengyihao's avatar
dengyihao 已提交
5063
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
5064
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5065

5066
  int32_t order = TSDB_ORDER_ASC;
5067
  //  STimeWindow win = {0};
dengyihao's avatar
dengyihao 已提交
5068
  bool           newgroup = false;
H
Haojun Liao 已提交
5069
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5070

5071
  while (1) {
H
Haojun Liao 已提交
5072
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5073
    SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
5074
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5075 5076 5077 5078 5079

    if (pBlock == NULL) {
      break;
    }

5080
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
5081
    // the pDataBlock are always the same one, no need to call this again
5082
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
5083 5084 5085
    STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;

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

dengyihao's avatar
dengyihao 已提交
5088
#if 0  // test for encode/decode result info
5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099
    if(pOperator->encodeResultRow){
      char *result = NULL;
      int32_t length = 0;
      SAggSupporter   *pSup = &pInfo->aggSup;
      pOperator->encodeResultRow(pOperator, pSup, &pInfo->binfo, &result, &length);
      taosHashClear(pSup->pResultRowHashTable);
      pInfo->binfo.resultRowInfo.size = 0;
      pOperator->decodeResultRow(pOperator, pSup, &pInfo->binfo, result, length);
      if(result){
        taosMemoryFree(result);
      }
5100
    }
5101
#endif
5102 5103
  }

H
Haojun Liao 已提交
5104
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
L
Liu Jicong 已提交
5105 5106
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5107

5108
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5109 5110 5111 5112
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
5113
static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator, bool* newgroup) {
5114
  STableIntervalOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5115
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
5116 5117 5118 5119 5120

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

5121 5122
  SSDataBlock* pBlock = pInfo->binfo.pRes;

5123 5124
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
    return pOperator->getStreamResFn(pOperator, newgroup);
5125 5126 5127 5128 5129
  } else {
    pTaskInfo->code = pOperator->_openFn(pOperator);
    if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
      return NULL;
    }
5130

5131
    blockDataEnsureCapacity(pBlock, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5132 5133
    doBuildResultDatablock(pBlock, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5134

5135
    if (pBlock->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5136 5137
      doSetOperatorCompleted(pOperator);
    }
5138

5139
    return pBlock->info.rows == 0 ? NULL : pBlock;
5140 5141 5142
  }
}

dengyihao's avatar
dengyihao 已提交
5143
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5144
  STableIntervalOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5145
  int32_t                     order = TSDB_ORDER_ASC;
5146 5147 5148 5149 5150 5151

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

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5152 5153
    doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5154 5155 5156
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      pOperator->status = OP_EXEC_DONE;
    }
5157
    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5158 5159 5160
  }

  //  STimeWindow win = {0};
5161
  *newgroup = false;
5162 5163 5164 5165 5166 5167
  SOperatorInfo* downstream = pOperator->pDownstream[0];

  SArray* pUpdated = NULL;

  while (1) {
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5168
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
5169 5170 5171 5172 5173 5174
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);

    if (pBlock == NULL) {
      break;
    }

dengyihao's avatar
dengyihao 已提交
5175 5176
    // The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
    // caller. Note that all the time window are not close till now.
5177 5178 5179

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

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

H
Haojun Liao 已提交
5187
  initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
5188
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5189 5190
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5191 5192 5193 5194 5195 5196 5197

  ASSERT(pInfo->binfo.pRes->info.rows > 0);
  pOperator->status = OP_RES_TO_RETURN;

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

dengyihao's avatar
dengyihao 已提交
5198
static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5199 5200 5201 5202
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5203
  STimeSliceOperatorInfo* pSliceInfo = pOperator->info;
5204
  if (pOperator->status == OP_RES_TO_RETURN) {
5205
    //    doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
5206
    if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5207 5208 5209
      doSetOperatorCompleted(pOperator);
    }

5210
    return pSliceInfo->binfo.pRes;
5211 5212
  }

dengyihao's avatar
dengyihao 已提交
5213 5214
  int32_t order = TSDB_ORDER_ASC;
  //  STimeWindow win = pQueryAttr->window;
H
Haojun Liao 已提交
5215
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5216

L
Liu Jicong 已提交
5217
  while (1) {
H
Haojun Liao 已提交
5218
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5219
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5220
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5221 5222 5223 5224
    if (pBlock == NULL) {
      break;
    }

L
Liu Jicong 已提交
5225
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5226
    // the pDataBlock are always the same one, no need to call this again
5227
    setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true);
dengyihao's avatar
dengyihao 已提交
5228
    //    hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
5229 5230 5231 5232
  }

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

5237
//  initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
5238
  //  doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
5239

5240
  if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5241 5242 5243
    pOperator->status = OP_EXEC_DONE;
  }

5244
  return pSliceInfo->binfo.pRes->info.rows == 0 ? NULL : pSliceInfo->binfo.pRes;
5245 5246
}

L
Liu Jicong 已提交
5247
static SSDataBlock* doSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5248 5249 5250 5251
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5252
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
5253

5254
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5255 5256
  if (pOperator->status == OP_RES_TO_RETURN) {
    int64_t st = taosGetTimestampUs();
5257
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5258 5259
      doSetOperatorCompleted(pOperator);
    }
5260 5261

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

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

L
Liu Jicong 已提交
5266
  while (1) {
H
Haojun Liao 已提交
5267
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5268
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5269
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5270 5271 5272 5273 5274 5275

    if (pBlock == NULL) {
      break;
    }

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

5280
    setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window);
dengyihao's avatar
dengyihao 已提交
5281
    //    hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pBlock->info.groupId);
5282 5283
  }

5284 5285 5286
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5287

5288
//  initGroupedResultInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
5289 5290
  OPTR_SET_OPENED(pOperator);

5291
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5292 5293
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5294 5295 5296

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

5299
  return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5300 5301
}

5302
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) {
dengyihao's avatar
dengyihao 已提交
5303
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
5304 5305
  SOptrBasicInfo* pBInfo = &pInfo->binfo;

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

5309 5310 5311 5312 5313 5314 5315 5316
  bool    masterScan = true;
  int32_t numOfOutput = pOperator->numOfOutput;

  int16_t bytes = pStateColInfoData->info.bytes;
  int16_t type = pStateColInfoData->info.type;

  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
  TSKEY*           tsList = (TSKEY*)pColInfoData->pData;
5317

5318 5319
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;
dengyihao's avatar
dengyihao 已提交
5320

5321 5322
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
    if (colDataIsNull(pStateColInfoData, pBlock->info.rows, j, pBlock->pBlockAgg)) {
5323 5324
      continue;
    }
5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337

    char* val = colDataGetData(pStateColInfoData, j);

    if (!pInfo->hasKey) {
      memcpy(pInfo->stateKey.pData, val, bytes);
      pInfo->hasKey = true;

      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
    } else if (memcmp(pInfo->stateKey.pData, val, bytes) == 0) {
      doKeepTuple(pRowSup, tsList[j]);
      if (j == 0 && pRowSup->startRowIndex != 0) {
        pRowSup->startRowIndex = 0;
5338
      }
5339
    } else {  // a new state window started
5340
      SResultRow* pResult = NULL;
5341 5342 5343 5344 5345 5346

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

      pRowSup->win.ekey = pRowSup->win.skey;
      int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &window, masterScan,
dengyihao's avatar
dengyihao 已提交
5347 5348
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
5349
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5350
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5351 5352
      }

5353
      updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
dengyihao's avatar
dengyihao 已提交
5354 5355
      doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                       pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5356 5357 5358 5359

      // here we start a new session window
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
5360 5361 5362 5363
    }
  }

  SResultRow* pResult = NULL;
5364
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
5365 5366 5367
  int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &pRowSup->win, masterScan,
                                           &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                           pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
5368
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5369
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5370 5371
  }

5372
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
dengyihao's avatar
dengyihao 已提交
5373 5374
  doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                   pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5375 5376
}

L
Liu Jicong 已提交
5377
static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5378 5379 5380 5381
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5382
  SStateWindowOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5383 5384
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
  SOptrBasicInfo*           pBInfo = &pInfo->binfo;
5385 5386

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5387 5388
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5389 5390 5391 5392
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
    }
5393 5394 5395 5396

    return pBInfo->pRes;
  }

dengyihao's avatar
dengyihao 已提交
5397 5398
  int32_t     order = TSDB_ORDER_ASC;
  STimeWindow win = pTaskInfo->window;
H
Haojun Liao 已提交
5399

H
Haojun Liao 已提交
5400
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5401
  while (1) {
H
Haojun Liao 已提交
5402
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5403
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5404
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5405 5406 5407 5408

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

5410
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5411
    doStateWindowAggImpl(pOperator, pInfo, pBlock);
5412 5413 5414 5415
  }

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

5419
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5420
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5421 5422
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5423 5424 5425
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
5426

L
Liu Jicong 已提交
5427
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5428 5429
}

L
Liu Jicong 已提交
5430
static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5431 5432 5433 5434
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5435
  SSessionAggOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5436
  SOptrBasicInfo*          pBInfo = &pInfo->binfo;
5437 5438

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5439 5440
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5441 5442 5443
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
5444 5445 5446 5447 5448
    }

    return pBInfo->pRes;
  }

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

L
Liu Jicong 已提交
5452
  while (1) {
H
Haojun Liao 已提交
5453
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5454
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5455
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5456 5457 5458 5459 5460
    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
5461
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5462
    doSessionWindowAggImpl(pOperator, pInfo, pBlock);
5463 5464 5465 5466 5467
  }

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

5471
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5472
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5473 5474
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5475 5476
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5477 5478
  }

L
Liu Jicong 已提交
5479
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5480 5481
}

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

L
Liu Jicong 已提交
5486 5487
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
5488 5489
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

5490
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
5491 5492
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

H
Haojun Liao 已提交
5493
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity, pInfo->p);
5494 5495 5496 5497
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
5498 5499
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
5500 5501
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
H
Haojun Liao 已提交
5502 5503
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity, pInfo->p);
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
5504 5505 5506 5507 5508 5509
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
5510
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5511 5512 5513
  }
}

L
Liu Jicong 已提交
5514 5515 5516
static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
5517

H
Haojun Liao 已提交
5518
  SResultInfo* pResultInfo = &pOperator->resultInfo;
5519 5520 5521
  SSDataBlock* pResBlock = pInfo->pRes;

  blockDataCleanup(pResBlock);
5522 5523 5524 5525
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5526
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5527 5528
  if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
    return pResBlock;
H
Haojun Liao 已提交
5529
  }
5530

H
Haojun Liao 已提交
5531
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
5532
  while (1) {
H
Haojun Liao 已提交
5533 5534 5535
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
    SSDataBlock* pBlock = pDownstream->getNextFn(pDownstream, newgroup);
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546

    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
5547
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5548 5549 5550 5551 5552 5553 5554
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

5555
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5556 5557 5558 5559 5560 5561 5562
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

5563
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity, pInfo->p);
5564 5565

    // current group has no more result to return
5566
    if (pResBlock->info.rows > 0) {
5567 5568
      // 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
5569 5570
      if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
        return pResBlock;
5571 5572
      }

5573
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5574 5575
      if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
        return pResBlock;
5576 5577 5578
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
5579
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5580 5581
      if (pResBlock->info.rows > pResultInfo->threshold) {
        return pResBlock;
5582 5583 5584 5585 5586 5587 5588 5589
      }
    } else {
      return NULL;
    }
  }
}

// todo set the attribute of query scan count
H
Haojun Liao 已提交
5590
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
L
Liu Jicong 已提交
5591
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
    if (functionId == FUNCTION_STDDEV || functionId == FUNCTION_PERCT) {
      return 2;
    }
  }

  return 1;
}

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

H
Haojun Liao 已提交
5606 5607
  if (pOperator->closeFn != NULL) {
    pOperator->closeFn(pOperator->info, pOperator->numOfOutput);
5608 5609
  }

H
Haojun Liao 已提交
5610
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
5611
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
5612
      destroyOperatorInfo(pOperator->pDownstream[i]);
5613 5614
    }

wafwerar's avatar
wafwerar 已提交
5615
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
5616
    pOperator->numOfDownstream = 0;
5617 5618
  }

wafwerar's avatar
wafwerar 已提交
5619 5620
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
5621 5622
}

dengyihao's avatar
dengyihao 已提交
5623 5624
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                         const char* pKey) {
5625 5626
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

dengyihao's avatar
dengyihao 已提交
5627 5628
  pAggSup->resultRowSize = getResultRowSize(pCtx, numOfOutput);
  pAggSup->keyBuf = taosMemoryCalloc(1, keyBufSize + POINTER_BYTES + sizeof(int64_t));
5629
  pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK);
5630 5631
//  pAggSup->pResultRowListSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
//  pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell));
5632

5633
  if (pAggSup->keyBuf == NULL /*|| pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL*/ ||
5634
      pAggSup->pResultRowHashTable == NULL) {
5635 5636 5637
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
5638 5639 5640 5641 5642
  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, 4096, 4096 * 256, pKey, "/tmp/");
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

5643 5644 5645
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
5646
static void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
5647
  taosMemoryFreeClear(pAggSup->keyBuf);
5648
  taosHashCleanup(pAggSup->pResultRowHashTable);
5649 5650
//  taosHashCleanup(pAggSup->pResultRowListSet);
//  taosArrayDestroy(pAggSup->pResultRowArrayList);
H
Haojun Liao 已提交
5651
  destroyDiskbasedBuf(pAggSup->pResultBuf);
5652 5653
}

H
Haojun Liao 已提交
5654
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
5655
                    SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey) {
5656
  pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5657 5658
  pBasicInfo->pRes = pResultBlock;

5659
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, keyBufSize, pkey);
5660 5661 5662 5663 5664

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

5665
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
5666 5667
}

5668 5669 5670 5671 5672 5673 5674 5675 5676
void initResultSizeInfo(SOperatorInfo* pOperator, int32_t numOfRows) {
  pOperator->resultInfo.capacity = numOfRows;
  pOperator->resultInfo.threshold = numOfRows * 0.75;

  if (pOperator->resultInfo.threshold == 0) {
    pOperator->resultInfo.capacity = numOfRows;
  }
}

H
Haojun Liao 已提交
5677
static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5678
  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
H
Haojun Liao 已提交
5679 5680
  if (pTableQueryInfo == NULL) {
    return NULL;
H
Haojun Liao 已提交
5681
  }
H
Haojun Liao 已提交
5682 5683

  int32_t index = 0;
L
Liu Jicong 已提交
5684
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
H
Haojun Liao 已提交
5685
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
L
Liu Jicong 已提交
5686
    for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
H
Haojun Liao 已提交
5687 5688
      STableKeyInfo* pk = taosArrayGet(pa, j);

H
Haojun Liao 已提交
5689
      STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
dengyihao's avatar
dengyihao 已提交
5690
      //      pTQueryInfo->uid = pk->uid;
L
Liu Jicong 已提交
5691
      pTQueryInfo->lastKey = pk->lastKey;
dengyihao's avatar
dengyihao 已提交
5692
      //      pTQueryInfo->groupIndex = i;
H
Haojun Liao 已提交
5693 5694
    }
  }
H
Haojun Liao 已提交
5695 5696

  STimeWindow win = {0, INT64_MAX};
H
Haojun Liao 已提交
5697 5698
  createTableQueryInfo(pTableQueryInfo, false, win);
  return pTableQueryInfo;
H
Haojun Liao 已提交
5699 5700
}

L
Liu Jicong 已提交
5701
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5702
                                           SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
5703
                                           int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5704
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
5705
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5706 5707 5708
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5709

H
Haojun Liao 已提交
5710
  int32_t numOfRows = 1;
dengyihao's avatar
dengyihao 已提交
5711
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5712 5713

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
5714 5715
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResultBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
5716 5717
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) {
H
Haojun Liao 已提交
5718 5719
    goto _error;
  }
H
Haojun Liao 已提交
5720

H
Haojun Liao 已提交
5721 5722 5723 5724 5725 5726 5727
  pOperator->resultInfo.capacity = 4096;
  pOperator->resultInfo.threshold = 4096 * 0.75;

  int32_t numOfGroup = 10;  // todo replaced with true value
  pInfo->groupId = INT32_MIN;
  initResultRowInfo(&pInfo->binfo.resultRowInfo, numOfGroup);

5728 5729
  pInfo->pScalarExprInfo = pScalarExprInfo;
  pInfo->numOfScalarExpr = numOfScalarExpr;
5730 5731 5732
  if (pInfo->pScalarExprInfo != NULL) {
    pInfo->pScalarCtx = createSqlFunctionCtx(pScalarExprInfo, numOfCols, &pInfo->rowCellInfoOffset);
  }
5733

dengyihao's avatar
dengyihao 已提交
5734
  pOperator->name = "TableAggregate";
X
Xiaoyu Wang 已提交
5735
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
5736
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5737 5738 5739 5740 5741 5742 5743 5744
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->_openFn = doOpenAggregateOptr;
  pOperator->getNextFn = getAggregateResult;
  pOperator->closeFn = destroyAggOperatorInfo;
H
Haojun Liao 已提交
5745

wmmhello's avatar
wmmhello 已提交
5746 5747
  pOperator->encodeResultRow = aggEncodeResultRow;
  pOperator->decodeResultRow = aggDecodeResultRow;
H
Haojun Liao 已提交
5748 5749 5750 5751 5752

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

  return pOperator;
L
Liu Jicong 已提交
5755
_error:
H
Haojun Liao 已提交
5756
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5757 5758
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5759 5760
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5761 5762
}

H
Haojun Liao 已提交
5763
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
5764 5765
  assert(pInfo != NULL);

5766
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
5767
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
5768 5769

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
5770
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
5771 5772
}

H
Haojun Liao 已提交
5773
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5774
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
5775 5776
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
5777 5778

void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5779
  SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param;
5780
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
5781
  taosMemoryFreeClear(pInfo->stateKey.pData);
5782
}
H
Haojun Liao 已提交
5783 5784

void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5785
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
5786 5787
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
5788

H
Haojun Liao 已提交
5789
void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5790
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)param;
H
Haojun Liao 已提交
5791 5792 5793 5794 5795
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
  cleanupAggSup(&pInfo->aggSup);
}

void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5796
  SSessionAggOperatorInfo* pInfo = (SSessionAggOperatorInfo*)param;
5797 5798 5799
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5800
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5801
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
5802
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
5803
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
5804
  taosMemoryFreeClear(pInfo->p);
5805 5806
}

H
Haojun Liao 已提交
5807
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5808
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
5809 5810 5811
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5812
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5813
  SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
H
Haojun Liao 已提交
5814 5815
  pInfo->pDataBlock = blockDataDestroy(pInfo->pDataBlock);

H
Haojun Liao 已提交
5816
  taosArrayDestroy(pInfo->pSortInfo);
5817
  taosArrayDestroy(pInfo->inputSlotMap);
5818 5819
}

H
Haojun Liao 已提交
5820
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5821
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
5822 5823 5824 5825 5826 5827 5828 5829 5830
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

H
Haojun Liao 已提交
5831 5832
static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols) {
  SArray* pList = taosArrayInit(4, sizeof(int32_t));
dengyihao's avatar
dengyihao 已提交
5833
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
5834 5835 5836 5837 5838 5839 5840 5841
    if (fmIsPseudoColumnFunc(pCtx[i].functionId)) {
      taosArrayPush(pList, &i);
    }
  }

  return pList;
}

L
Liu Jicong 已提交
5842
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
dengyihao's avatar
dengyihao 已提交
5843 5844
                                         SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit,
                                         SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5845
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
5846
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5847 5848 5849
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
5850

dengyihao's avatar
dengyihao 已提交
5851 5852 5853
  pInfo->limit = *pLimit;
  pInfo->slimit = *pSlimit;
  pInfo->curOffset = pLimit->offset;
H
Haojun Liao 已提交
5854 5855
  pInfo->curSOffset = pSlimit->offset;

H
Haojun Liao 已提交
5856
  pInfo->binfo.pRes = pResBlock;
H
Haojun Liao 已提交
5857 5858 5859

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5860
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5861 5862 5863

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

dengyihao's avatar
dengyihao 已提交
5867
  pOperator->name = "ProjectOperator";
H
Haojun Liao 已提交
5868
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
5869
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
5870 5871 5872 5873 5874 5875 5876
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = num;
  pOperator->_openFn = operatorDummyOpenFn;
  pOperator->getNextFn = doProjectOperation;
  pOperator->closeFn = destroyProjectOperatorInfo;
L
Liu Jicong 已提交
5877 5878

  pOperator->pTaskInfo = pTaskInfo;
5879
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5880
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
5881 5882
    goto _error;
  }
5883 5884

  return pOperator;
H
Haojun Liao 已提交
5885

L
Liu Jicong 已提交
5886
_error:
H
Haojun Liao 已提交
5887 5888
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5889 5890
}

L
Liu Jicong 已提交
5891
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5892
                                          SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
dengyihao's avatar
dengyihao 已提交
5893 5894
                                          STimeWindowAggSupp* pTwAggSupp, const STableGroupInfo* pTableGroupInfo,
                                          SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5895
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
L
Liu Jicong 已提交
5896
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5897 5898 5899
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5900

5901 5902
  pInfo->order          = TSDB_ORDER_ASC;
  pInfo->interval       = *pInterval;
H
Haojun Liao 已提交
5903 5904
//  pInfo->execModel      = OPTR_EXEC_MODEL_STREAM;
  pInfo->execModel      = pTaskInfo->execModel;
5905 5906
  pInfo->win            = pTaskInfo->window;
  pInfo->twAggSup       = *pTwAggSupp;
5907
  pInfo->primaryTsIndex = primaryTsSlotId;
5908

5909
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5910
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5911 5912

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

L
Liu Jicong 已提交
5917 5918
  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
H
Haojun Liao 已提交
5919 5920
    goto _error;
  }
H
Haojun Liao 已提交
5921 5922

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

dengyihao's avatar
dengyihao 已提交
5924
  pOperator->name = "TimeIntervalAggOperator";
H
Haojun Liao 已提交
5925
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
5926
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5927 5928 5929 5930 5931 5932 5933 5934 5935
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->_openFn = doOpenIntervalAgg;
  pOperator->getNextFn = doBuildIntervalResult;
  pOperator->getStreamResFn = doStreamIntervalAgg;
  pOperator->closeFn = destroyIntervalOperatorInfo;
5936 5937
  pOperator->encodeResultRow = aggEncodeResultRow;
  pOperator->decodeResultRow = aggDecodeResultRow;
5938

H
Haojun Liao 已提交
5939
  code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5940 5941 5942 5943
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

5944
  return pOperator;
H
Haojun Liao 已提交
5945

L
Liu Jicong 已提交
5946
_error:
H
Haojun Liao 已提交
5947
  destroyIntervalOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5948 5949
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5950 5951
  pTaskInfo->code = code;
  return NULL;
5952 5953
}

dengyihao's avatar
dengyihao 已提交
5954 5955
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                           SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo) {
5956
  STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
dengyihao's avatar
dengyihao 已提交
5957
  SOperatorInfo*          pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
5958 5959 5960
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }
5961

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

dengyihao's avatar
dengyihao 已提交
5964
  pOperator->name = "TimeSliceOperator";
L
Liu Jicong 已提交
5965
  //  pOperator->operatorType = OP_AllTimeWindow;
5966
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5967 5968 5969 5970 5971 5972 5973
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->getNextFn = doAllIntervalAgg;
  pOperator->closeFn = destroyBasicOperatorInfo;
5974

L
Liu Jicong 已提交
5975
  int32_t code = appendDownstream(pOperator, &downstream, 1);
5976
  return pOperator;
5977

dengyihao's avatar
dengyihao 已提交
5978
_error:
5979 5980 5981 5982
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5983 5984
}

dengyihao's avatar
dengyihao 已提交
5985 5986 5987
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
                                             SSDataBlock* pResBlock, STimeWindowAggSupp* pTwAggSup,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5988
  SStateWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStateWindowOperatorInfo));
dengyihao's avatar
dengyihao 已提交
5989
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
5990 5991 5992
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5993

L
Liu Jicong 已提交
5994
  pInfo->colIndex = -1;
5995
  size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5996 5997 5998

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

6001 6002 6003
  pInfo->twAggSup = *pTwAggSup;
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);

dengyihao's avatar
dengyihao 已提交
6004
  pOperator->name = "StateWindowOperator";
6005
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW;
6006
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6007 6008 6009 6010 6011 6012 6013 6014
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;

  pOperator->pTaskInfo = pTaskInfo;
  pOperator->info = pInfo;
  pOperator->getNextFn = doStateWindowAgg;
  pOperator->closeFn = destroyStateWindowOperatorInfo;
6015 6016
  pOperator->encodeResultRow = aggEncodeResultRow;
  pOperator->decodeResultRow = aggDecodeResultRow;
6017

H
Haojun Liao 已提交
6018
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6019
  return pOperator;
6020

dengyihao's avatar
dengyihao 已提交
6021
_error:
6022 6023
  pTaskInfo->code = TSDB_CODE_SUCCESS;
  return NULL;
6024 6025
}

L
Liu Jicong 已提交
6026
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
dengyihao's avatar
dengyihao 已提交
6027 6028
                                            SSDataBlock* pResBlock, int64_t gap, STimeWindowAggSupp* pTwAggSupp,
                                            SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6029
  SSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSessionAggOperatorInfo));
L
Liu Jicong 已提交
6030
  SOperatorInfo*           pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6031 6032 6033
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6034

H
Haojun Liao 已提交
6035
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
6036
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6037 6038

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
6039 6040
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
6041 6042 6043
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6044

6045
  pInfo->twAggSup = *pTwAggSupp;
H
Haojun Liao 已提交
6046
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6047
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
6048

dengyihao's avatar
dengyihao 已提交
6049 6050 6051 6052 6053
  pInfo->gap = gap;
  pInfo->binfo.pRes = pResBlock;
  pInfo->winSup.prevTs = INT64_MIN;
  pInfo->reptScan = false;
  pOperator->name = "SessionWindowAggOperator";
H
Haojun Liao 已提交
6054
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW;
6055
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6056 6057 6058 6059 6060 6061
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->getNextFn = doSessionWindowAgg;
  pOperator->closeFn = destroySWindowOperatorInfo;
6062 6063
  pOperator->encodeResultRow = aggEncodeResultRow;
  pOperator->decodeResultRow = aggDecodeResultRow;
dengyihao's avatar
dengyihao 已提交
6064
  pOperator->pTaskInfo = pTaskInfo;
6065

H
Haojun Liao 已提交
6066
  code = appendDownstream(pOperator, &downstream, 1);
6067
  return pOperator;
H
Haojun Liao 已提交
6068

L
Liu Jicong 已提交
6069
_error:
H
Haojun Liao 已提交
6070 6071 6072 6073
  if (pInfo != NULL) {
    destroySWindowOperatorInfo(pInfo, numOfCols);
  }

wafwerar's avatar
wafwerar 已提交
6074 6075
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6076 6077
  pTaskInfo->code = code;
  return NULL;
6078 6079
}

H
Haojun Liao 已提交
6080
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, int64_t* fillVal,
L
Liu Jicong 已提交
6081
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
6082
  SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, NULL);
H
Haojun Liao 已提交
6083 6084 6085

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

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

wafwerar's avatar
wafwerar 已提交
6091
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
6092 6093 6094 6095 6096 6097 6098 6099

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

L
Liu Jicong 已提交
6100 6101 6102
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
                                      SInterval* pInterval, SSDataBlock* pResBlock, int32_t fillType, char* fillVal,
                                      bool multigroupResult, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6103
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
6104
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6105

L
Liu Jicong 已提交
6106
  pInfo->pRes = pResBlock;
6107
  pInfo->multigroupResult = multigroupResult;
L
Liu Jicong 已提交
6108
  pInfo->intervalInfo = *pInterval;
6109

6110 6111
  int32_t type = TSDB_FILL_NONE;
  switch (fillType) {
dengyihao's avatar
dengyihao 已提交
6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129
    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;
6130 6131 6132 6133
    default:
      type = TSDB_FILL_NONE;
  }

H
Haojun Liao 已提交
6134
  SResultInfo* pResultInfo = &pOperator->resultInfo;
6135 6136 6137 6138
  initResultSizeInfo(pOperator, 4096);

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

dengyihao's avatar
dengyihao 已提交
6143
  pOperator->name = "FillOperator";
6144
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
6145
  pOperator->status = OP_NOT_OPENED;
L
Liu Jicong 已提交
6146
  //  pOperator->operatorType = OP_Fill;
dengyihao's avatar
dengyihao 已提交
6147 6148 6149 6150 6151 6152
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->_openFn = operatorDummyOpenFn;
  pOperator->getNextFn = doFill;
  pOperator->pTaskInfo = pTaskInfo;
6153

L
Liu Jicong 已提交
6154
  pOperator->closeFn = destroySFillOperatorInfo;
H
Haojun Liao 已提交
6155

6156
  code = appendDownstream(pOperator, &downstream, 1);
6157
  return pOperator;
H
Haojun Liao 已提交
6158

L
Liu Jicong 已提交
6159
_error:
wafwerar's avatar
wafwerar 已提交
6160 6161
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
6162
  return NULL;
6163 6164
}

H
Haojun Liao 已提交
6165

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

H
Haojun Liao 已提交
6169 6170
  if (TSDB_COL_IS_TAG(pExpr->pParam[0].pCol->type)) {
    if (pExpr->pParam[0].pCol->colId == TSDB_TBNAME_COLUMN_INDEX) {
6171 6172 6173
      return TSDB_TBNAME_COLUMN_INDEX;
    }

L
Liu Jicong 已提交
6174
    while (j < pTableInfo->numOfTags) {
H
Haojun Liao 已提交
6175
      if (pExpr->pParam[0].pCol->colId == pTagCols[j].colId) {
6176 6177 6178 6179 6180 6181
        return j;
      }

      j += 1;
    }

6182
  } /*else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {  // user specified column data
6183 6184 6185 6186 6187 6188 6189 6190 6191
    return TSDB_UD_COLUMN_INDEX;
  } else {
    while (j < pTableInfo->numOfCols) {
      if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) {
        return j;
      }

      j += 1;
    }
6192
  }*/
6193 6194 6195 6196

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

L
Liu Jicong 已提交
6197
bool validateExprColumnInfo(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6198 6199 6200 6201
  int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols);
  return j != INT32_MIN;
}

L
Liu Jicong 已提交
6202 6203
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
6204
  SResSchema s = {0};
dengyihao's avatar
dengyihao 已提交
6205 6206 6207 6208
  s.scale = scale;
  s.type = type;
  s.bytes = bytes;
  s.slotId = slotId;
H
Haojun Liao 已提交
6209
  s.precision = precision;
H
Haojun Liao 已提交
6210 6211 6212 6213
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
6214

H
Haojun Liao 已提交
6215 6216 6217 6218 6219 6220 6221
static SColumn* createColumn(int32_t blockId, int32_t slotId, SDataType* pType) {
  SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn));
  if (pCol == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

dengyihao's avatar
dengyihao 已提交
6222 6223 6224 6225 6226
  pCol->slotId = slotId;
  pCol->bytes = pType->bytes;
  pCol->type = pType->type;
  pCol->scale = pType->scale;
  pCol->precision = pType->precision;
H
Haojun Liao 已提交
6227 6228 6229 6230 6231
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
6232
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
6233
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6234 6235 6236 6237
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
6238

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

L
Liu Jicong 已提交
6242
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
6243 6244 6245 6246 6247 6248
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
6249

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

wafwerar's avatar
wafwerar 已提交
6252
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
6253
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
6254
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
6255

6256
    int32_t type = nodeType(pTargetNode->pExpr);
H
Haojun Liao 已提交
6257
    // it is a project query, or group by column
6258
    if (type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
6259
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
6260
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
6261

G
Ganlin Zhao 已提交
6262 6263 6264
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
6265
      SDataType* pType = &pColNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6266 6267
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pColNode->colName);
H
Haojun Liao 已提交
6268 6269
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pType);
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
6270
    } else if (type == QUERY_NODE_VALUE) {
6271 6272 6273 6274 6275 6276 6277
      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 已提交
6278 6279
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pValNode->node.aliasName);
6280 6281
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
      valueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
6282
    } else if (type == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
6283
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
6284 6285 6286
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

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

H
Haojun Liao 已提交
6290
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
6291
      pExp->pExpr->_function.pFunctNode = pFuncNode;
dengyihao's avatar
dengyihao 已提交
6292 6293
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
H
Haojun Liao 已提交
6294 6295

      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
6296 6297 6298 6299

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

H
Haojun Liao 已提交
6300
      for (int32_t j = 0; j < numOfParam; ++j) {
6301
        SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
6302
        if (p1->type == QUERY_NODE_COLUMN) {
dengyihao's avatar
dengyihao 已提交
6303
          SColumnNode* pcn = (SColumnNode*)p1;
G
Ganlin Zhao 已提交
6304 6305

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
H
Haojun Liao 已提交
6306
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, &pcn->node.resType);
G
Ganlin Zhao 已提交
6307 6308 6309
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
6310
          valueNodeToVariant(pvn, &pExp->base.pParam[j].param);
G
Ganlin Zhao 已提交
6311
        }
H
Haojun Liao 已提交
6312
      }
6313
    } else if (type == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
6314
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
6315
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
6316

G
Ganlin Zhao 已提交
6317 6318 6319
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

6320
      SDataType* pType = &pNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6321 6322
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pNode->node.aliasName);
6323 6324 6325
      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6326 6327 6328
    }
  }

H
Haojun Liao 已提交
6329
  return pExprs;
H
Haojun Liao 已提交
6330 6331
}

6332
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model) {
wafwerar's avatar
wafwerar 已提交
6333
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
6334
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
6335

6336
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
6337
  pTaskInfo->id.queryId = queryId;
dengyihao's avatar
dengyihao 已提交
6338
  pTaskInfo->execModel = model;
H
Haojun Liao 已提交
6339

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

6344 6345
  return pTaskInfo;
}
H
Haojun Liao 已提交
6346

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

L
Liu Jicong 已提交
6350 6351
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                                  uint64_t queryId, uint64_t taskId);
6352 6353
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
static SArray* extractScanColumnId(SNodeList* pNodeList);
H
Haojun Liao 已提交
6354
static SArray* extractColumnInfo(SNodeList* pNodeList);
H
Haojun Liao 已提交
6355
static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols);
6356

6357
static SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget);
6358
static SArray* createIndexMap(SNodeList* pNodeList);
6359
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372
static int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode);

static SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode) {
  SInterval interval = {
      .interval     = pTableScanNode->interval,
      .sliding      = pTableScanNode->sliding,
      .intervalUnit = pTableScanNode->intervalUnit,
      .slidingUnit  = pTableScanNode->slidingUnit,
      .offset       = pTableScanNode->offset,
  };

  return interval;
}
H
Haojun Liao 已提交
6373

H
Haojun Liao 已提交
6374
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
6375
                                  uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
6376 6377
  int32_t type = nodeType(pPhyNode);

X
Xiaoyu Wang 已提交
6378
  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
H
Haojun Liao 已提交
6379
    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
dengyihao's avatar
dengyihao 已提交
6380 6381
      SScanPhysiNode*      pScanPhyNode = (SScanPhysiNode*)pPhyNode;
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6382

6383
      int32_t numOfCols = 0;
H
Haojun Liao 已提交
6384
      tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
6385
      if (pDataReader == NULL && terrno != 0) {
6386 6387
        return NULL;
      }
6388

dengyihao's avatar
dengyihao 已提交
6389 6390
      SArray* pColList =
          extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
6391
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6392

6393 6394 6395 6396 6397
      SQueryTableDataCond cond = {0};
      int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }
6398

6399 6400
      SInterval interval = extractIntervalInfo(pTableScanNode);
      return createTableScanOperatorInfo(pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList,
H
Haojun Liao 已提交
6401
                                         pResBlock, pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo);
H
Haojun Liao 已提交
6402
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
H
Haojun Liao 已提交
6403
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
6404
      SSDataBlock*        pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
6405
      return createExchangeOperatorInfo(pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
H
Haojun Liao 已提交
6406
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
H
Haojun Liao 已提交
6407
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
6408

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

6412
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6413 6414

      int32_t numOfCols = 0;
6415 6416
      SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
      SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo);
6417
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
6418
      return pOperator;
H
Haojun Liao 已提交
6419
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
L
Liu Jicong 已提交
6420
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
6421
      SScanPhysiNode* pScanNode = &pSysScanPhyNode->scan;
H
Haojun Liao 已提交
6422

6423 6424
      SSDataBlock* pResBlock = createResDataBlock(pScanNode->node.pOutputDataBlockDesc);
      SArray* colList = extractScanColumnId(pScanNode->pScanCols);
6425

L
Liu Jicong 已提交
6426 6427 6428
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
          pHandle->meta, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
          colList, pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
6429 6430 6431
      return pOperator;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6432 6433 6434
    }
  }

6435 6436
  int32_t num = 0;
  size_t  size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
6437

6438
  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
dengyihao's avatar
dengyihao 已提交
6439
  for (int32_t i = 0; i < size; ++i) {
6440 6441
    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
6442 6443 6444
    if (ops[i] == NULL) {
      return NULL;
    }
6445
  }
H
Haojun Liao 已提交
6446

6447
  SOperatorInfo* pOptr = NULL;
H
Haojun Liao 已提交
6448
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
dengyihao's avatar
dengyihao 已提交
6449 6450
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*)pPhyNode;
    SExprInfo*         pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);
H
Haojun Liao 已提交
6451

6452
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
dengyihao's avatar
dengyihao 已提交
6453 6454
    SLimit       limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
    SLimit       slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
6455
    pOptr = createProjectOperatorInfo(ops[0], pExprInfo, num, pResBlock, &limit, &slimit, pTaskInfo);
H
Haojun Liao 已提交
6456 6457 6458
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == type) {
    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
    SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
6459
    SSDataBlock*   pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
6460

dengyihao's avatar
dengyihao 已提交
6461
    int32_t    numOfScalarExpr = 0;
6462 6463 6464 6465 6466
    SExprInfo* pScalarExprInfo = NULL;
    if (pAggNode->pExprs != NULL) {
      pScalarExprInfo = createExprInfo(pAggNode->pExprs, NULL, &numOfScalarExpr);
    }

H
Haojun Liao 已提交
6467 6468
    if (pAggNode->pGroupKeys != NULL) {
      SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
dengyihao's avatar
dengyihao 已提交
6469 6470
      pOptr = createGroupOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pAggNode->node.pConditions,
                                      pScalarExprInfo, numOfScalarExpr, pTaskInfo, NULL);
H
Haojun Liao 已提交
6471
    } else {
dengyihao's avatar
dengyihao 已提交
6472 6473
      pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr,
                                          pTaskInfo, pTableGroupInfo);
H
Haojun Liao 已提交
6474
    }
H
Haojun Liao 已提交
6475 6476
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type) {
    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6477

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

dengyihao's avatar
dengyihao 已提交
6481 6482 6483 6484 6485 6486
    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 已提交
6487

dengyihao's avatar
dengyihao 已提交
6488 6489
    STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
                             .calTrigger = pIntervalPhyNode->window.triggerType};
6490

dengyihao's avatar
dengyihao 已提交
6491 6492 6493
    int32_t primaryTsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
    pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as,
                                       pTableGroupInfo, pTaskInfo);
6494 6495

    if (pIntervalPhyNode->pFill != NULL) {
dengyihao's avatar
dengyihao 已提交
6496 6497
      pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode, NULL,
                                     false, pTaskInfo);
6498 6499
    }

H
Haojun Liao 已提交
6500
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
H
Haojun Liao 已提交
6501
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6502

6503
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6504
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys, pSortPhyNode->pTargets);
6505
    SArray*      slotMap = createIndexMap(pSortPhyNode->pTargets);
6506
    pOptr = createSortOperatorInfo(ops[0], pResBlock, info, slotMap, pTaskInfo);
H
Haojun Liao 已提交
6507
  } else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
H
Haojun Liao 已提交
6508 6509
    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

dengyihao's avatar
dengyihao 已提交
6510 6511
    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};
6512

H
Haojun Liao 已提交
6513
    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
6514
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6515
    pOptr = createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, &as, pTaskInfo);
H
Haojun Liao 已提交
6516
  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
dengyihao's avatar
dengyihao 已提交
6517 6518 6519
    SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
    SArray*              pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
    SSDataBlock*         pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6520 6521

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

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

dengyihao's avatar
dengyihao 已提交
6528
    SExprInfo*   pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &num);
6529
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6530
    pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, pTaskInfo);
6531
  } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
dengyihao's avatar
dengyihao 已提交
6532 6533
    SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6534 6535

    SExprInfo* pExprInfo = createExprInfo(pJoinNode->pTargets, NULL, &num);
6536
    pOptr = createJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
H
Haojun Liao 已提交
6537 6538
  } else {
    ASSERT(0);
H
Haojun Liao 已提交
6539
  }
6540 6541 6542

  taosMemoryFree(ops);
  return pOptr;
6543
}
H
Haojun Liao 已提交
6544 6545


6546 6547 6548 6549 6550 6551 6552
static  int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode) {
  pCond->loadExternalRows = false;

  pCond->order = pTableScanNode->scanSeq[0] > 0 ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
  pCond->numOfCols = LIST_LENGTH(pTableScanNode->scan.pScanCols);
  pCond->colList = taosMemoryCalloc(pCond->numOfCols, sizeof(SColumnInfo));
  if (pCond->colList == NULL) {
H
Haojun Liao 已提交
6553
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
6554 6555 6556 6557 6558 6559 6560 6561 6562 6563
    return terrno;
  }

  pCond->twindow = pTableScanNode->scanRange;

#if 1
  //todo work around a problem, remove it later
  if ((pCond->order == TSDB_ORDER_ASC && pCond->twindow.skey > pCond->twindow.ekey) ||
      (pCond->order == TSDB_ORDER_DESC && pCond->twindow.skey < pCond->twindow.ekey)) {
    TSWAP(pCond->twindow.skey, pCond->twindow.ekey, int64_t);
H
Haojun Liao 已提交
6564
  }
6565
#endif
H
Haojun Liao 已提交
6566

6567 6568
  pCond->type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
  //  pCond->type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
6569

H
Haojun Liao 已提交
6570
  int32_t j = 0;
6571
  for (int32_t i = 0; i < pCond->numOfCols; ++i) {
H
Haojun Liao 已提交
6572 6573
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6574 6575 6576
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
6577

6578 6579 6580
    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 已提交
6581
    j += 1;
H
Haojun Liao 已提交
6582 6583
  }

6584 6585
  pCond->numOfCols = j;
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
6586
}
H
Haojun Liao 已提交
6587

6588
SArray* extractScanColumnId(SNodeList* pNodeList) {
L
Liu Jicong 已提交
6589
  size_t  numOfCols = LIST_LENGTH(pNodeList);
6590 6591 6592 6593 6594 6595
  SArray* pList = taosArrayInit(numOfCols, sizeof(int16_t));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6596
  for (int32_t i = 0; i < numOfCols; ++i) {
X
Xiaoyu Wang 已提交
6597
    for (int32_t j = 0; j < numOfCols; ++j) {
L
Liu Jicong 已提交
6598
      STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, j);
X
Xiaoyu Wang 已提交
6599
      if (pNode->slotId == i) {
L
Liu Jicong 已提交
6600
        SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
X
Xiaoyu Wang 已提交
6601 6602 6603 6604
        taosArrayPush(pList, &pColNode->colId);
        break;
      }
    }
6605 6606 6607 6608 6609
  }

  return pList;
}

H
Haojun Liao 已提交
6610
SArray* extractColumnInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
6611
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6612 6613 6614 6615 6616 6617
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6618 6619 6620
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6621

H
Haojun Liao 已提交
6622
    // todo extract method
H
Haojun Liao 已提交
6623 6624
    SColumn c = {0};
    c.slotId = pColNode->slotId;
dengyihao's avatar
dengyihao 已提交
6625 6626 6627
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
L
Liu Jicong 已提交
6628 6629
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;
H
Haojun Liao 已提交
6630 6631 6632 6633 6634 6635 6636

    taosArrayPush(pList, &c);
  }

  return pList;
}

6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650
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 已提交
6651 6652 6653
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
6654 6655 6656 6657 6658 6659 6660 6661 6662
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;

    taosArrayPush(pList, &c);
  }

  return pList;
}

6663
SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget) {
L
Liu Jicong 已提交
6664
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6665 6666 6667 6668 6669 6670
  SArray* pList = taosArrayInit(numOfCols, sizeof(SBlockOrderInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

L
Liu Jicong 已提交
6671
  for (int32_t i = 0; i < numOfCols; ++i) {
6672
    SOrderByExprNode* pSortKey = (SOrderByExprNode*)nodesListGetNode(pNodeList, i);
L
Liu Jicong 已提交
6673 6674
    SBlockOrderInfo   bi = {0};
    bi.order = (pSortKey->order == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
H
Haojun Liao 已提交
6675 6676 6677 6678
    bi.nullFirst = (pSortKey->nullOrder == NULL_ORDER_FIRST);

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

6679 6680 6681 6682 6683
    bool found = false;
    for (int32_t j = 0; j < LIST_LENGTH(pNodeListTarget); ++j) {
      STargetNode* pTarget = (STargetNode*)nodesListGetNode(pNodeListTarget, j);

      SColumnNode* pColNodeT = (SColumnNode*)pTarget->pExpr;
dengyihao's avatar
dengyihao 已提交
6684
      if (pColNode->slotId == pColNodeT->slotId) {  // to find slotId in PhysiSort OutputDataBlockDesc
6685 6686 6687 6688 6689 6690
        bi.slotId = pTarget->slotId;
        found = true;
        break;
      }
    }

dengyihao's avatar
dengyihao 已提交
6691
    if (!found) {
6692 6693
      qError("sort slot id does not found");
    }
H
Haojun Liao 已提交
6694 6695 6696 6697 6698 6699
    taosArrayPush(pList, &bi);
  }

  return pList;
}

6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717
SArray* createIndexMap(SNodeList* pNodeList) {
  size_t  numOfCols = LIST_LENGTH(pNodeList);
  SArray* pList = taosArrayInit(numOfCols, sizeof(int32_t));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pTarget = (STargetNode*)nodesListGetNode(pNodeList, i);

    SColumnNode* pColNode = (SColumnNode*)pTarget->pExpr;
    taosArrayPush(pList, &pColNode->slotId);
  }

  return pList;
}

H
Haojun Liao 已提交
6718
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols) {
L
Liu Jicong 已提交
6719
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6720 6721 6722 6723 6724 6725
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6726 6727 6728
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6729 6730

    SColMatchInfo c = {0};
L
Liu Jicong 已提交
6731
    c.colId = pColNode->colId;
H
Haojun Liao 已提交
6732
    c.targetSlotId = pNode->slotId;
L
Liu Jicong 已提交
6733
    c.output = true;
H
Haojun Liao 已提交
6734 6735 6736
    taosArrayPush(pList, &c);
  }

H
Haojun Liao 已提交
6737 6738
  *numOfOutputCols = 0;
  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
6739 6740
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
6741
    // todo: add reserve flag check
dengyihao's avatar
dengyihao 已提交
6742
    if (pNode->slotId >= numOfCols) {  // it is a column reserved for the arithmetic expression calculation
6743 6744 6745 6746
      (*numOfOutputCols) += 1;
      continue;
    }

H
Haojun Liao 已提交
6747
    SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
H
Haojun Liao 已提交
6748 6749 6750 6751 6752
    if (pNode->output) {
      (*numOfOutputCols) += 1;
    } else {
      info->output = false;
    }
H
Haojun Liao 已提交
6753 6754
  }

H
Haojun Liao 已提交
6755 6756 6757
  return pList;
}

dengyihao's avatar
dengyihao 已提交
6758 6759
int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                           uint64_t queryId, uint64_t taskId) {
6760
  int32_t code = 0;
H
Haojun Liao 已提交
6761
  if (tableType == TSDB_SUPER_TABLE) {
H
Haojun Liao 已提交
6762
    code = tsdbQuerySTableByTagCond(metaHandle, tableUid, 0, NULL, 0, 0, NULL, pGroupInfo, NULL, 0, queryId, taskId);
H
Haojun Liao 已提交
6763
  } else {  // Create one table group.
H
Haojun Liao 已提交
6764
    code = tsdbGetOneTableGroup(metaHandle, tableUid, 0, pGroupInfo);
6765 6766 6767 6768
  }

  return code;
}
H
Haojun Liao 已提交
6769

6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787
SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo) {
  SArray* tableIdList = taosArrayInit(4, sizeof(uint64_t));

  if (pTableGroupInfo->numOfTables > 0) {
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, 0);
    ASSERT(taosArrayGetSize(pTableGroupInfo->pGroupList) == 1);

    // Transfer the Array of STableKeyInfo into uid list.
    size_t numOfTables = taosArrayGetSize(pa);
    for (int32_t i = 0; i < numOfTables; ++i) {
      STableKeyInfo* pkeyInfo = taosArrayGet(pa, i);
      taosArrayPush(tableIdList, &pkeyInfo->uid);
    }
  }

  return tableIdList;
}

L
Liu Jicong 已提交
6788 6789
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                               STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId) {
6790
  uint64_t uid = pTableScanNode->scan.uid;
L
Liu Jicong 已提交
6791 6792
  int32_t  code =
      doCreateTableGroup(pHandle->meta, pTableScanNode->scan.tableType, uid, pTableGroupInfo, queryId, taskId);
6793 6794
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
H
Haojun Liao 已提交
6795
  }
H
Haojun Liao 已提交
6796

H
Haojun Liao 已提交
6797
  if (pTableGroupInfo->numOfTables == 0) {
H
Haojun Liao 已提交
6798
    code = 0;
L
Liu Jicong 已提交
6799
    qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
H
Haojun Liao 已提交
6800 6801
    goto _error;
  }
H
Haojun Liao 已提交
6802

6803 6804 6805 6806 6807 6808 6809
  SQueryTableDataCond cond = {0};
  code = initQueryTableDataCond(&cond, pTableScanNode);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

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

L
Liu Jicong 已提交
6811
_error:
H
Haojun Liao 已提交
6812 6813 6814 6815
  terrno = code;
  return NULL;
}

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

H
Haojun Liao 已提交
6820
  int32_t code = TSDB_CODE_SUCCESS;
6821
  *pTaskInfo = createExecTaskInfo(queryId, taskId, model);
H
Haojun Liao 已提交
6822 6823 6824 6825
  if (*pTaskInfo == NULL) {
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    goto _complete;
  }
H
Haojun Liao 已提交
6826

6827
  (*pTaskInfo)->pRoot = createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoGroupInfo);
D
dapan1121 已提交
6828
  if (NULL == (*pTaskInfo)->pRoot) {
L
Liu Jicong 已提交
6829
    code = terrno;
D
dapan1121 已提交
6830 6831
    goto _complete;
  }
H
Haojun Liao 已提交
6832

6833
  if ((*pTaskInfo)->pRoot == NULL) {
H
Haojun Liao 已提交
6834
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
H
Haojun Liao 已提交
6835
    goto _complete;
6836 6837
  }

H
Haojun Liao 已提交
6838 6839
  return code;

H
Haojun Liao 已提交
6840
_complete:
wafwerar's avatar
wafwerar 已提交
6841
  taosMemoryFreeClear(*pTaskInfo);
H
Haojun Liao 已提交
6842 6843 6844

  terrno = code;
  return code;
H
Haojun Liao 已提交
6845 6846
}

L
Liu Jicong 已提交
6847 6848
static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SColumnInfo* pTagCols, SExprInfo* pExprs,
                                             int32_t numOfOutput, int32_t tagLen, bool superTable) {
6849 6850 6851 6852 6853 6854 6855 6856 6857
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int16_t functId = getExprFunctionId(&pExprs[i]);

    if (functId == FUNCTION_TOP || functId == FUNCTION_BOTTOM) {
      int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols);
      if (j < 0 || j >= pTableInfo->numOfCols) {
        return TSDB_CODE_QRY_INVALID_MSG;
      } else {
        SColumnInfo* pCol = &pTableInfo->colList[j];
L
Liu Jicong 已提交
6858 6859 6860 6861
        //        int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i,
        //                                        &pExprs[i].base.resSchema.type, &pExprs[i].base.resSchema.bytes,
        //                                        &pExprs[i].base.interBytes, tagLen, superTable, NULL);
        //        assert(ret == TSDB_CODE_SUCCESS);
6862 6863 6864 6865 6866 6867 6868
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
6869
void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo) {
6870 6871 6872 6873 6874 6875 6876 6877
  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 已提交
6878 6879 6880 6881 6882 6883 6884 6885 6886 6887
  //  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;
  //  }
6888 6889

  pResultInfo->threshold = (int32_t)(pResultInfo->capacity * THRESHOLD_RATIO);
H
Haojun Liao 已提交
6890
  pResultInfo->totalRows = 0;
6891 6892
}

L
Liu Jicong 已提交
6893
// TODO refactor
6894
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
L
Liu Jicong 已提交
6895 6896 6897
  if (pFilter == NULL || numOfFilters == 0) {
    return;
  }
6898

L
Liu Jicong 已提交
6899 6900 6901
  for (int32_t i = 0; i < numOfFilters; i++) {
    if (pFilter[i].filterstr && pFilter[i].pz) {
      taosMemoryFree((void*)(pFilter[i].pz));
6902
    }
L
Liu Jicong 已提交
6903
  }
6904

L
Liu Jicong 已提交
6905
  taosMemoryFree(pFilter);
6906 6907 6908 6909
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
  if (pTableqinfoGroupInfo->pGroupList != NULL) {
L
Liu Jicong 已提交
6910
    int32_t numOfGroups = (int32_t)taosArrayGetSize(pTableqinfoGroupInfo->pGroupList);
6911
    for (int32_t i = 0; i < numOfGroups; ++i) {
L
Liu Jicong 已提交
6912
      SArray* p = taosArrayGetP(pTableqinfoGroupInfo->pGroupList, i);
6913 6914

      size_t num = taosArrayGetSize(p);
L
Liu Jicong 已提交
6915
      for (int32_t j = 0; j < num; ++j) {
6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931
        STableQueryInfo* item = taosArrayGetP(p, j);
        destroyTableQueryInfoImpl(item);
      }

      taosArrayDestroy(p);
    }
  }

  taosArrayDestroy(pTableqinfoGroupInfo->pGroupList);
  taosHashCleanup(pTableqinfoGroupInfo->map);

  pTableqinfoGroupInfo->pGroupList = NULL;
  pTableqinfoGroupInfo->map = NULL;
  pTableqinfoGroupInfo->numOfTables = 0;
}

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

H
Haojun Liao 已提交
6935
  doDestroyTableQueryInfo(&pTaskInfo->tableqinfoGroupInfo);
L
Liu Jicong 已提交
6936 6937
  //  taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
  //  taosHashCleanup(pTaskInfo->summary.operatorProfResults);
6938

wafwerar's avatar
wafwerar 已提交
6939 6940 6941
  taosMemoryFreeClear(pTaskInfo->sql);
  taosMemoryFreeClear(pTaskInfo->id.str);
  taosMemoryFreeClear(pTaskInfo);
6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953
}

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 已提交
6954
      int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966
      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 已提交
6967 6968
  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
  return (int64_t)(s1 * 1.5 * numOfTables);
6969 6970 6971 6972 6973 6974 6975
}

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 已提交
6976
    while (1) {
6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002
      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 已提交
7003

dengyihao's avatar
dengyihao 已提交
7004 7005
int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo** pRes, int32_t* capacity,
                                   int32_t* resNum) {
D
dapan1121 已提交
7006 7007
  if (*resNum >= *capacity) {
    *capacity += 10;
dengyihao's avatar
dengyihao 已提交
7008

D
dapan1121 已提交
7009 7010
    *pRes = taosMemoryRealloc(*pRes, (*capacity) * sizeof(SExplainExecInfo));
    if (NULL == *pRes) {
D
dapan1121 已提交
7011
      qError("malloc %d failed", (*capacity) * (int32_t)sizeof(SExplainExecInfo));
D
dapan1121 已提交
7012 7013 7014 7015
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

D
dapan1121 已提交
7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026
  (*pRes)[*resNum].numOfRows = operatorInfo->resultInfo.totalRows;
  (*pRes)[*resNum].startupCost = operatorInfo->cost.openCost;
  (*pRes)[*resNum].totalCost = operatorInfo->cost.totalCost;

  if (operatorInfo->getExplainFn) {
    int32_t code = (*operatorInfo->getExplainFn)(operatorInfo, &(*pRes)->verboseInfo);
    if (code) {
      qError("operator getExplainFn failed, error:%s", tstrerror(code));
      return code;
    }
  }
dengyihao's avatar
dengyihao 已提交
7027

D
dapan1121 已提交
7028
  ++(*resNum);
dengyihao's avatar
dengyihao 已提交
7029

D
dapan1121 已提交
7030
  int32_t code = 0;
D
dapan1121 已提交
7031 7032
  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pRes, capacity, resNum);
D
dapan1121 已提交
7033 7034 7035 7036 7037 7038 7039
    if (code) {
      taosMemoryFreeClear(*pRes);
      return TSDB_CODE_QRY_OUT_OF_MEMORY;
    }
  }

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
7040 7041
}

7042 7043
static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup) {
  SJoinOperatorInfo* pJoinInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
7044
  //  SOptrBasicInfo* pInfo = &pJoinInfo->binfo;
7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081

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

  int32_t nrows = 0;

  while (1) {
    bool prevVal = *newgroup;

    if (pJoinInfo->pLeft == NULL || pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
      SOperatorInfo* ds1 = pOperator->pDownstream[0];
      publishOperatorProfEvent(ds1, QUERY_PROF_BEFORE_OPERATOR_EXEC);
      pJoinInfo->pLeft = ds1->getNextFn(ds1, newgroup);
      publishOperatorProfEvent(ds1, QUERY_PROF_AFTER_OPERATOR_EXEC);

      pJoinInfo->leftPos = 0;
      if (pJoinInfo->pLeft == NULL) {
        setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
        break;
      }
    }

    if (pJoinInfo->pRight == NULL || pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
      SOperatorInfo* ds2 = pOperator->pDownstream[1];
      publishOperatorProfEvent(ds2, QUERY_PROF_BEFORE_OPERATOR_EXEC);
      pJoinInfo->pRight = ds2->getNextFn(ds2, newgroup);
      publishOperatorProfEvent(ds2, QUERY_PROF_AFTER_OPERATOR_EXEC);

      pJoinInfo->rightPos = 0;
      if (pJoinInfo->pRight == NULL) {
        setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
        break;
      }
    }

    SColumnInfoData* pLeftCol = taosArrayGet(pJoinInfo->pLeft->pDataBlock, pJoinInfo->leftCol.slotId);
dengyihao's avatar
dengyihao 已提交
7082
    char*            pLeftVal = colDataGetData(pLeftCol, pJoinInfo->leftPos);
7083 7084

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

    // only the timestamp match support for ordinary table
dengyihao's avatar
dengyihao 已提交
7088 7089 7090 7091
    ASSERT(pLeftCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
    if (*(int64_t*)pLeftVal == *(int64_t*)pRightVal) {
      for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
        SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, i);
7092

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

dengyihao's avatar
dengyihao 已提交
7095 7096
        int32_t blockId = pExprInfo->base.pParam[0].pCol->dataBlockId;
        int32_t slotId = pExprInfo->base.pParam[0].pCol->slotId;
7097

dengyihao's avatar
dengyihao 已提交
7098 7099 7100 7101 7102 7103
        SColumnInfoData* pSrc = NULL;
        if (pJoinInfo->pLeft->info.blockId == blockId) {
          pSrc = taosArrayGet(pJoinInfo->pLeft->pDataBlock, slotId);
        } else {
          pSrc = taosArrayGet(pJoinInfo->pRight->pDataBlock, slotId);
        }
7104

dengyihao's avatar
dengyihao 已提交
7105 7106 7107 7108 7109
        if (colDataIsNull_s(pSrc, pJoinInfo->leftPos)) {
          colDataAppendNULL(pDst, nrows);
        } else {
          char* p = colDataGetData(pSrc, pJoinInfo->leftPos);
          colDataAppend(pDst, nrows, p, false);
7110
        }
dengyihao's avatar
dengyihao 已提交
7111
      }
7112

dengyihao's avatar
dengyihao 已提交
7113 7114
      pJoinInfo->leftPos += 1;
      pJoinInfo->rightPos += 1;
7115

dengyihao's avatar
dengyihao 已提交
7116 7117 7118
      nrows += 1;
    } else if (*(int64_t*)pLeftVal < *(int64_t*)pRightVal) {
      pJoinInfo->leftPos += 1;
D
dapan1121 已提交
7119

dengyihao's avatar
dengyihao 已提交
7120 7121
      if (pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
        continue;
7122
      }
dengyihao's avatar
dengyihao 已提交
7123 7124 7125 7126
    } else if (*(int64_t*)pLeftVal > *(int64_t*)pRightVal) {
      pJoinInfo->rightPos += 1;
      if (pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
        continue;
7127
      }
dengyihao's avatar
dengyihao 已提交
7128
    }
7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139

    // the pDataBlock are always the same one, no need to call this again
    pRes->info.rows = nrows;
    if (pRes->info.rows >= pOperator->resultInfo.threshold) {
      break;
    }
  }

  return (pRes->info.rows > 0) ? pRes : NULL;
}

dengyihao's avatar
dengyihao 已提交
7140 7141 7142
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                      int32_t numOfCols, SSDataBlock* pResBlock, SNode* pOnCondition,
                                      SExecTaskInfo* pTaskInfo) {
7143
  SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
dengyihao's avatar
dengyihao 已提交
7144
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
7145 7146 7147 7148 7149 7150 7151
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }

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

dengyihao's avatar
dengyihao 已提交
7152 7153 7154
  //  initResultRowInf
  //  o(&pInfo->binfo.resultRowInfo, 8);
  pInfo->pRes = pResBlock;
7155

dengyihao's avatar
dengyihao 已提交
7156
  pOperator->name = "JoinOperator";
7157
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_JOIN;
7158
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
7159 7160 7161 7162 7163 7164 7165
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->getNextFn = doMergeJoin;
  pOperator->closeFn = destroyBasicOperatorInfo;
7166 7167 7168 7169

  int32_t code = appendDownstream(pOperator, pDownstream, numOfDownstream);
  return pOperator;

dengyihao's avatar
dengyihao 已提交
7170
_error:
7171 7172 7173 7174
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
dengyihao's avatar
dengyihao 已提交
7175
}