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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; }

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

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

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

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

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

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

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

  tw->ekey -= 1;
}

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

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

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

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

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

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

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

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

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

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

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

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

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t streamFn,
                                    __optr_fn_t cleanup, __optr_close_fn_t closeFn, __optr_encode_fn_t encode,
                                    __optr_decode_fn_t decode, __optr_get_explain_fn_t explain) {
  SOperatorFpSet fpSet = {
      ._openFn = openFn,
      .getNextFn = nextFn,
      .getStreamResFn = streamFn,
      .cleanupFn = cleanup,
      .closeFn = closeFn,
      .encodeResultRow = encode,
      .decodeResultRow = decode,
      .getExplainFn = explain,
  };

  return fpSet;
}

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

dengyihao's avatar
dengyihao 已提交
248 249 250
static int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
                                  SGroupResInfo* pGroupResInfo, int32_t orderType, int32_t* rowCellOffset,
                                  SqlFunctionCtx* pCtx);
H
Haojun Liao 已提交
251

252
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
H
Haojun Liao 已提交
253
static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo);
dengyihao's avatar
dengyihao 已提交
254 255
static void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId,
                                     SExecTaskInfo* pTaskInfo);
256

H
Haojun Liao 已提交
257
SArray* getOrderCheckColumns(STaskAttr* pQuery);
258 259

typedef struct SRowCompSupporter {
L
Liu Jicong 已提交
260 261 262
  STaskRuntimeEnv* pRuntimeEnv;
  int16_t          dataOffset;
  __compar_fn_t    comFunc;
263 264
} SRowCompSupporter;

L
Liu Jicong 已提交
265 266 267
static int compareRowData(const void* a, const void* b, const void* userData) {
  const SResultRow* pRow1 = (const SResultRow*)a;
  const SResultRow* pRow2 = (const SResultRow*)b;
268

L
Liu Jicong 已提交
269 270
  SRowCompSupporter* supporter = (SRowCompSupporter*)userData;
  STaskRuntimeEnv*   pRuntimeEnv = supporter->pRuntimeEnv;
271

L
Liu Jicong 已提交
272 273
  SFilePage* page1 = getBufPage(pRuntimeEnv->pResultBuf, pRow1->pageId);
  SFilePage* page2 = getBufPage(pRuntimeEnv->pResultBuf, pRow2->pageId);
274 275

  int16_t offset = supporter->dataOffset;
L
Liu Jicong 已提交
276 277
  char*   in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
  char*   in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
278 279 280 281

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

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

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

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

L
Liu Jicong 已提交
292
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
293
    SColumnInfoData idata = {{0}};
L
Liu Jicong 已提交
294
    SSlotDescNode*  pDescNode = nodesListGetNode(pNode->pSlots, i);
H
Haojun Liao 已提交
295 296
    if (!pDescNode->output) {
      continue;
H
Haojun Liao 已提交
297
    }
H
Haojun Liao 已提交
298

dengyihao's avatar
dengyihao 已提交
299
    idata.info.type = pDescNode->dataType.type;
L
Liu Jicong 已提交
300 301
    idata.info.bytes = pDescNode->dataType.bytes;
    idata.info.scale = pDescNode->dataType.scale;
H
Haojun Liao 已提交
302
    idata.info.slotId = pDescNode->slotId;
H
Haojun Liao 已提交
303 304
    idata.info.precision = pDescNode->dataType.precision;

H
Hongze Cheng 已提交
305 306 307 308
    if (IS_VAR_DATA_TYPE(idata.info.type)) {
      pBlock->info.hasVarCol = true;
    }

H
Haojun Liao 已提交
309
    taosArrayPush(pBlock->pDataBlock, &idata);
H
Haojun Liao 已提交
310
  }
H
Haojun Liao 已提交
311

312
  pBlock->info.numOfCols = taosArrayGetSize(pBlock->pDataBlock);
H
Haojun Liao 已提交
313
  return pBlock;
H
Haojun Liao 已提交
314 315
}

L
Liu Jicong 已提交
316
static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
dengyihao's avatar
dengyihao 已提交
317 318
  if (TSDB_COL_IS_TAG(pColumn->flag) || TSDB_COL_IS_UD_COL(pColumn->flag) ||
      pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
319 320 321 322 323 324 325 326 327 328
    return false;
  }

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

  return true;
}

H
Haojun Liao 已提交
329
static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) {
330 331
  int64_t newCapacity = 0;

332 333 334 335 336 337 338 339 340 341 342
  // more than the capacity, reallocate the resources
  if (pResultRowInfo->size < pResultRowInfo->capacity) {
    return;
  }

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

343
  if (newCapacity <= pResultRowInfo->capacity) {
H
Haojun Liao 已提交
344 345 346
    newCapacity += 4;
  }

347 348 349 350 351 352
  char* p = taosMemoryRealloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition));
  if (p == NULL) {
    longjmp(env, TSDB_CODE_OUT_OF_MEMORY);
  }

  pResultRowInfo->pPosition = (SResultRowPosition*)p;
353 354

  int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity;
wmmhello's avatar
wmmhello 已提交
355
  memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition) * inc);
356 357 358
  pResultRowInfo->capacity = (int32_t)newCapacity;
}

L
Liu Jicong 已提交
359 360
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
                                int16_t bytes, bool masterscan, uint64_t uid) {
361 362 363
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);

L
Liu Jicong 已提交
364 365
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
366 367 368 369 370 371 372 373 374 375 376

  // in case of repeat scan/reverse scan, no new time window added.
  if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQueryAttr)) {
    if (!masterscan) {  // the *p1 may be NULL in case of sliding+offset exists.
      return p1 != NULL;
    }

    if (p1 != NULL) {
      if (pResultRowInfo->size == 0) {
        existed = false;
      } else if (pResultRowInfo->size == 1) {
dengyihao's avatar
dengyihao 已提交
377
        //        existed = (pResultRowInfo->pResult[0] == (*p1));
378 379
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid, pResultRowInfo);
L
Liu Jicong 已提交
380 381
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
382 383 384 385 386 387 388 389 390 391 392 393 394 395
        if (index != NULL) {
          existed = true;
        } else {
          existed = false;
        }
      }
    }

    return existed;
  }

  return p1 != NULL;
}

396
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
L
Liu Jicong 已提交
397
  SFilePage* pData = NULL;
398 399 400 401 402 403 404 405 406 407 408 409 410

  // in the first scan, new space needed for results
  int32_t pageId = -1;
  SIDList list = getDataBufPagesIdList(pResultBuf, tableGroupId);

  if (taosArrayGetSize(list) == 0) {
    pData = getNewBufPage(pResultBuf, tableGroupId, &pageId);
    pData->num = sizeof(SFilePage);
  } else {
    SPageInfo* pi = getLastPageInfo(list);
    pData = getBufPage(pResultBuf, getPageId(pi));
    pageId = getPageId(pi);

wmmhello's avatar
wmmhello 已提交
411
    if (pData->num + interBufSize > getBufPageSize(pResultBuf)) {
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
      // release current page first, and prepare the next one
      releaseBufPageInfo(pResultBuf, pi);

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

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

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

wmmhello's avatar
wmmhello 已提交
431
  pData->num += interBufSize;
432 433 434 435

  return pResultRow;
}

436 437 438 439 440 441 442
/**
 * the struct of key in hash table
 * +----------+---------------+
 * | group id |   key data    |
 * | 8 bytes  | actual length |
 * +----------+---------------+
 */
443
static SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, int64_t uid,
444
                                             char* pData, int16_t bytes, bool masterscan, uint64_t groupId,
L
Liu Jicong 已提交
445
                                             SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup) {
446
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
H
Haojun Liao 已提交
447

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

451 452
  SResultRow* pResult = NULL;

H
Haojun Liao 已提交
453 454
  // in case of repeat scan/reverse scan, no new time window added.
  if (isIntervalQuery) {
455 456
    if (masterscan && p1 != NULL) {  // the *p1 may be NULL in case of sliding+offset exists.
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
457 458
    }
  } else {
dengyihao's avatar
dengyihao 已提交
459 460
    // In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
    // pResultRowInfo object.
H
Haojun Liao 已提交
461
    if (p1 != NULL) {
462
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
463 464 465
    }
  }

H
Haojun Liao 已提交
466
    // 1. close current opened time window
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
  if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
                                            pResult->offset != pResultRowInfo->cur.offset))) {
    // todo extract function
    SResultRowPosition pos = pResultRowInfo->cur;
    SFilePage*         pPage = getBufPage(pResultBuf, pos.pageId);
    SResultRow*        pRow = (SResultRow*)((char*)pPage + pos.offset);
    closeResultRow(pRow);
    releaseBufPage(pResultBuf, pPage);
  }

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

483 484 485
    // add a new result set for a new group
    SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
    taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos, sizeof(SResultRowPosition));
H
Haojun Liao 已提交
486 487
  }

488 489 490 491 492
  // 2. set the new time window to be the new active time window
  pResultRowInfo->pPosition[pResultRowInfo->size++] =
      (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
  pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};

H
Haojun Liao 已提交
493 494 495 496 497
  // too many time window in query
  if (pResultRowInfo->size > MAX_INTERVAL_TIME_WINDOW) {
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
  }

H
Haojun Liao 已提交
498
  return pResult;
H
Haojun Liao 已提交
499 500
}

dengyihao's avatar
dengyihao 已提交
501 502
static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, TSKEY ts, STimeWindow* w,
                                      bool ascQuery) {
H
Haojun Liao 已提交
503
  if (ascQuery) {
504
    getAlignQueryTimeWindow(pInterval, precision, ts, w);
505 506
  } else {
    // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
507
    getAlignQueryTimeWindow(pInterval, precision, ts, w);
508 509

    int64_t key = w->skey;
L
Liu Jicong 已提交
510
    while (key < ts) {  // moving towards end
511
      key = taosTimeAdd(key, pInterval->sliding, pInterval->slidingUnit, precision);
512 513 514 515 516 517 518 519 520 521
      if (key >= ts) {
        break;
      }

      w->skey = key;
    }
  }
}

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

526
  if (pResultRowInfo->cur.pageId == -1) {  // the first window, from the previous stored value
527
    getInitialStartTimeWindow(pInterval, precision, ts, &w, true);
528
    w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
529
  } else {
530
    w = getResultRowByPos(pBuf, &pResultRowInfo->cur)->win;
531 532 533
  }

  if (w.skey > ts || w.ekey < ts) {
H
Haojun Liao 已提交
534 535 536
    if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
      w.skey = taosTimeTruncate(ts, pInterval, precision);
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
537 538 539 540
    } else {
      int64_t st = w.skey;

      if (st > ts) {
H
Haojun Liao 已提交
541
        st -= ((st - ts + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
542 543
      }

H
Haojun Liao 已提交
544
      int64_t et = st + pInterval->interval - 1;
545
      if (et < ts) {
H
Haojun Liao 已提交
546
        st += ((ts - et + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
547 548 549
      }

      w.skey = st;
550
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
551 552 553 554 555 556
    }
  }
  return w;
}

// get the correct time window according to the handled timestamp
L
Liu Jicong 已提交
557
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo* pResultRowInfo, int64_t ts, STaskAttr* pQueryAttr) {
558
  STimeWindow w = {0};
H
Haojun Liao 已提交
559
#if 0
L
Liu Jicong 已提交
560 561
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
                                       //    getInitialStartTimeWindow(pQueryAttr, ts, &w);
562 563

    if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') {
L
Liu Jicong 已提交
564 565 566
      w.ekey =
          taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) -
          1;
567 568 569 570
    } else {
      w.ekey = w.skey + pQueryAttr->interval.interval - 1;
    }
  } else {
H
Haojun Liao 已提交
571
    w = pRow->win;
572 573 574 575 576 577 578 579 580
  }

  /*
   * query border check, skey should not be bounded by the query time range, since the value skey will
   * be used as the time window index value. So we only change ekey of time window accordingly.
   */
  if (w.ekey > pQueryAttr->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) {
    w.ekey = pQueryAttr->window.ekey;
  }
H
Haojun Liao 已提交
581
#endif
582 583 584 585 586

  return w;
}

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

L
Liu Jicong 已提交
592
  SFilePage* pData = NULL;
593 594 595 596 597 598

  // in the first scan, new space needed for results
  int32_t pageId = -1;
  SIDList list = getDataBufPagesIdList(pResultBuf, tid);

  if (taosArrayGetSize(list) == 0) {
H
Haojun Liao 已提交
599
    pData = getNewBufPage(pResultBuf, tid, &pageId);
600
    pData->num = sizeof(SFilePage);
601 602
  } else {
    SPageInfo* pi = getLastPageInfo(list);
603
    pData = getBufPage(pResultBuf, getPageId(pi));
604
    pageId = getPageId(pi);
605

606
    if (pData->num + size > getBufPageSize(pResultBuf)) {
607
      // release current page first, and prepare the next one
608
      releaseBufPageInfo(pResultBuf, pi);
609

H
Haojun Liao 已提交
610
      pData = getNewBufPage(pResultBuf, tid, &pageId);
611
      if (pData != NULL) {
612
        pData->num = sizeof(SFilePage);
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
      }
    }
  }

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

  // set the number of rows in current disk page
  if (pWindowRes->pageId == -1) {  // not allocated yet, allocate new buffer
    pWindowRes->pageId = pageId;
    pWindowRes->offset = (int32_t)pData->num;

    pData->num += size;
    assert(pWindowRes->pageId >= 0);
  }

  return 0;
}

L
Liu Jicong 已提交
633 634 635
static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, STimeWindow* win,
                                    bool masterscan, SResultRow** pResult, int64_t groupId, SqlFunctionCtx* pCtx,
                                    int32_t numOfOutput, int32_t* rowCellInfoOffset) {
636
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
637
  return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char*)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
638 639
}

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

L
Liu Jicong 已提交
643 644 645 646
static int32_t setResultOutputBufByKey_rv(SResultRowInfo* pResultRowInfo, int64_t id, STimeWindow* win, bool masterscan,
                                          SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx,
                                          int32_t numOfOutput, int32_t* rowCellInfoOffset, SAggSupporter* pAggSup,
                                          SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
647
  assert(win->skey <= win->ekey);
648
  SResultRow* pResultRow = doSetResultOutBufByKey(pAggSup->pResultBuf, pResultRowInfo, id, (char*)&win->skey,
L
Liu Jicong 已提交
649
                                                     TSDB_KEYSIZE, masterscan, tableGroupId, pTaskInfo, true, pAggSup);
H
Haojun Liao 已提交
650 651 652 653 654 655 656 657 658

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

  // set time window for current result
  pResultRow->win = (*win);
  *pResult = pResultRow;
H
Haojun Liao 已提交
659
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
H
Haojun Liao 已提交
660 661 662
  return TSDB_CODE_SUCCESS;
}

663 664 665 666 667
static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
  assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
  if (type == RESULT_ROW_START_INTERP) {
    pResult->startInterp = true;
  } else {
L
Liu Jicong 已提交
668
    pResult->endInterp = true;
669 670 671 672 673 674 675 676
  }
}

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

L
Liu Jicong 已提交
681 682
static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey,
                                                   int16_t pos, int16_t order, int64_t* pData) {
683 684 685
  int32_t forwardStep = 0;

  if (order == TSDB_ORDER_ASC) {
L
Liu Jicong 已提交
686
    int32_t end = searchFn((char*)&pData[pos], numOfRows - pos, ekey, order);
687 688 689 690 691 692 693 694
    if (end >= 0) {
      forwardStep = end;

      if (pData[end + pos] == ekey) {
        forwardStep += 1;
      }
    }
  } else {
L
Liu Jicong 已提交
695
    int32_t end = searchFn((char*)pData, pos + 1, ekey, order);
696 697 698 699 700 701 702 703 704 705 706 707 708
    if (end >= 0) {
      forwardStep = pos - end;

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

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

dengyihao's avatar
dengyihao 已提交
709 710
static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey, bool ascQuery,
                                   bool timeWindowInterpo) {
711
  int64_t skey = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
712
#if 0
713 714
  int32_t i = 0;
  for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
715
    SResultRow* pResult = pResultRowInfo->pResult[i];
716 717 718 719 720 721
    if (pResult->closed) {
      break;
    }

    // new closed result rows
    if (timeWindowInterpo) {
L
Liu Jicong 已提交
722 723 724
      if (pResult->endInterp &&
          ((pResult->win.skey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery))) {
        if (i > 0) {  // the first time window, the startInterp is false.
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
          assert(pResult->startInterp);
        }

        closeResultRow(pResultRowInfo, i);
      } else {
        skey = pResult->win.skey;
      }
    } else {
      if ((pResult->win.ekey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery)) {
        closeResultRow(pResultRowInfo, i);
      } else {
        skey = pResult->win.skey;
      }
    }
  }

  // all result rows are closed, set the last one to be the skey
  if (skey == TSKEY_INITIAL_VAL) {
    if (pResultRowInfo->size == 0) {
L
Liu Jicong 已提交
744
      //      assert(pResultRowInfo->current == NULL);
745 746 747 748 749 750 751
      assert(pResultRowInfo->curPos == -1);
      pResultRowInfo->curPos = -1;
    } else {
      pResultRowInfo->curPos = pResultRowInfo->size - 1;
    }
  } else {
    for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
752
      SResultRow* pResult = pResultRowInfo->pResult[i];
753 754 755 756 757 758 759 760 761 762 763
      if (pResult->closed) {
        break;
      }
    }

    if (i == pResultRowInfo->size - 1) {
      pResultRowInfo->curPos = i;
    } else {
      pResultRowInfo->curPos = i + 1;  // current not closed result object
    }
  }
H
Haojun Liao 已提交
764
#endif
765
}
766
//
dengyihao's avatar
dengyihao 已提交
767
// static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
768 769 770 771 772 773 774 775 776
//                                           bool ascQuery, bool interp) {
//  if ((lastKey > pWin->ekey && ascQuery) || (lastKey < pWin->ekey && (!ascQuery))) {
//    closeAllResultRows(pResultRowInfo);
//    pResultRowInfo->curPos = pResultRowInfo->size - 1;
//  } else {
//    int32_t step = ascQuery ? 1 : -1;
//    doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, interp);
//  }
//}
777

L
Liu Jicong 已提交
778 779 780
static int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos,
                                        TSKEY ekey, __block_search_fn_t searchFn, STableQueryInfo* item,
                                        int32_t order) {
781 782
  assert(startPos >= 0 && startPos < pDataBlockInfo->rows);

L
Liu Jicong 已提交
783 784
  int32_t num = -1;
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
785

H
Haojun Liao 已提交
786
  if (order == TSDB_ORDER_ASC) {
787 788
    if (ekey < pDataBlockInfo->window.ekey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
789
      if (item != NULL) {
790 791 792 793
        item->lastKey = pPrimaryColumn[startPos + (num - 1)] + step;
      }
    } else {
      num = pDataBlockInfo->rows - startPos;
H
Haojun Liao 已提交
794
      if (item != NULL) {
795 796 797 798 799 800
        item->lastKey = pDataBlockInfo->window.ekey + step;
      }
    }
  } else {  // desc
    if (ekey > pDataBlockInfo->window.skey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
801
      if (item != NULL) {
802 803 804 805
        item->lastKey = pPrimaryColumn[startPos - (num - 1)] + step;
      }
    } else {
      num = startPos + 1;
H
Haojun Liao 已提交
806
      if (item != NULL) {
807 808 809 810 811 812 813 814 815
        item->lastKey = pDataBlockInfo->window.skey + step;
      }
    }
  }

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

816 817 818 819 820
//  query_range_start, query_range_end, window_duration, window_start, window_end
static void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow) {
  pColData->info.type = TSDB_DATA_TYPE_TIMESTAMP;
  pColData->info.bytes = sizeof(int64_t);

821
  colInfoDataEnsureCapacity(pColData, 0, 5);
822 823 824 825 826 827 828 829 830
  colDataAppendInt64(pColData, 0, &pQueryWindow->skey);
  colDataAppendInt64(pColData, 1, &pQueryWindow->ekey);

  int64_t interval = 0;
  colDataAppendInt64(pColData, 2, &interval);  // this value may be variable in case of 'n' and 'y'.
  colDataAppendInt64(pColData, 3, &pQueryWindow->skey);
  colDataAppendInt64(pColData, 4, &pQueryWindow->ekey);
}

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

835
  int64_t duration = pWin->ekey - pWin->skey + delta;
dengyihao's avatar
dengyihao 已提交
836 837 838
  ts[2] = duration;            // set the duration
  ts[3] = pWin->skey;          // window start key
  ts[4] = pWin->ekey + delta;  // window end key
839 840
}

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

H
Haojun Liao 已提交
846
    // keep it temporarily
dengyihao's avatar
dengyihao 已提交
847 848
    bool    hasAgg = pCtx[k].input.colDataAggIsSet;
    int32_t numOfRows = pCtx[k].input.numOfRows;
H
Haojun Liao 已提交
849
    int32_t startOffset = pCtx[k].input.startRowIndex;
850

H
Haojun Liao 已提交
851
    int32_t pos = (order == TSDB_ORDER_ASC) ? offset : offset - (forwardStep - 1);
852 853
    pCtx[k].input.startRowIndex = pos;
    pCtx[k].input.numOfRows = forwardStep;
854 855

    if (tsCol != NULL) {
H
Haojun Liao 已提交
856
      pCtx[k].ptsList = tsCol;
857 858 859 860 861 862 863 864
    }

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

865 866
    if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
      SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
dengyihao's avatar
dengyihao 已提交
867
      char*                p = GET_ROWCELL_INTERBUF(pEntryInfo);
868

869
      SColumnInfoData idata = {0};
dengyihao's avatar
dengyihao 已提交
870
      idata.info.type = TSDB_DATA_TYPE_BIGINT;
871
      idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
dengyihao's avatar
dengyihao 已提交
872
      idata.pData = p;
873 874 875 876

      SScalarParam out = {.columnData = &idata};
      SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
      pCtx[k].sfp.process(&tw, 1, &out);
877 878 879 880
      pEntryInfo->numOfRes = 1;
      continue;
    }

H
Haojun Liao 已提交
881
    if (functionNeedToExecute(&pCtx[k])) {
882
      pCtx[k].fpSet.process(&pCtx[k]);
883 884 885
    }

    // restore it
886 887 888
    pCtx[k].input.colDataAggIsSet = hasAgg;
    pCtx[k].input.startRowIndex = startOffset;
    pCtx[k].input.numOfRows = numOfRows;
889 890 891
  }
}

H
Haojun Liao 已提交
892 893 894
static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo,
                                      TSKEY* primaryKeys, int32_t prevPosition, STableIntervalOperatorInfo* pInfo) {
  int32_t order = pInfo->order;
L
Liu Jicong 已提交
895
  bool    ascQuery = (order == TSDB_ORDER_ASC);
H
Haojun Liao 已提交
896

897
  int32_t precision = pInterval->precision;
H
Haojun Liao 已提交
898
  getNextTimeWindow(pInterval, precision, order, pNext);
899 900

  // next time window is not in current block
H
Haojun Liao 已提交
901 902
  if ((pNext->skey > pDataBlockInfo->window.ekey && order == TSDB_ORDER_ASC) ||
      (pNext->ekey < pDataBlockInfo->window.skey && order == TSDB_ORDER_DESC)) {
903 904 905
    return -1;
  }

L
Liu Jicong 已提交
906
  TSKEY   startKey = ascQuery ? pNext->skey : pNext->ekey;
907 908 909
  int32_t startPos = 0;

  // tumbling time window query, a special case of sliding time window query
H
Haojun Liao 已提交
910 911
  if (pInterval->sliding == pInterval->interval && prevPosition != -1) {
    int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
912 913
    startPos = prevPosition + factor;
  } else {
H
Haojun Liao 已提交
914
    if (startKey <= pDataBlockInfo->window.skey && ascQuery) {
915
      startPos = 0;
H
Haojun Liao 已提交
916
    } else if (startKey >= pDataBlockInfo->window.ekey && !ascQuery) {
917 918
      startPos = pDataBlockInfo->rows - 1;
    } else {
L
Liu Jicong 已提交
919
      startPos = binarySearchForKey((char*)primaryKeys, pDataBlockInfo->rows, startKey, order);
920 921 922 923
    }
  }

  /* interp query with fill should not skip time window */
L
Liu Jicong 已提交
924 925 926
  //  if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
  //    return startPos;
  //  }
927 928 929 930 931 932

  /*
   * This time window does not cover any data, try next time window,
   * this case may happen when the time window is too small
   */
  if (primaryKeys == NULL) {
H
Haojun Liao 已提交
933
    if (ascQuery) {
934 935 936 937 938
      assert(pDataBlockInfo->window.skey <= pNext->ekey);
    } else {
      assert(pDataBlockInfo->window.ekey >= pNext->skey);
    }
  } else {
H
Haojun Liao 已提交
939
    if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
940
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
941 942 943
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
944
      } else {
L
Liu Jicong 已提交
945
        pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
H
Haojun Liao 已提交
946
        pNext->skey = pNext->ekey - pInterval->interval + 1;
947
      }
H
Haojun Liao 已提交
948
    } else if ((!ascQuery) && primaryKeys[startPos] < pNext->skey) {
949
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
950 951 952
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
953
      } else {
H
Haojun Liao 已提交
954 955
        pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
        pNext->ekey = pNext->skey + pInterval->interval - 1;
956 957 958 959 960 961 962
      }
    }
  }

  return startPos;
}

L
Liu Jicong 已提交
963
static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* pWindow) {
dengyihao's avatar
dengyihao 已提交
964
  TSKEY   ekey = -1;
965 966
  int32_t order = TSDB_ORDER_ASC;
  if (order == TSDB_ORDER_ASC) {
967 968 969 970 971 972 973 974 975 976 977 978 979 980
    ekey = pWindow->ekey;
    if (ekey > pQueryAttr->window.ekey) {
      ekey = pQueryAttr->window.ekey;
    }
  } else {
    ekey = pWindow->skey;
    if (ekey < pQueryAttr->window.ekey) {
      ekey = pQueryAttr->window.ekey;
    }
  }

  return ekey;
}

H
Haojun Liao 已提交
981
static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t type) {
982 983 984 985 986 987 988 989 990 991 992
  if (type == RESULT_ROW_START_INTERP) {
    for (int32_t k = 0; k < numOfOutput; ++k) {
      pCtx[k].start.key = INT64_MIN;
    }
  } else {
    for (int32_t k = 0; k < numOfOutput; ++k) {
      pCtx[k].end.key = INT64_MIN;
    }
  }
}

H
Haojun Liao 已提交
993
static void saveDataBlockLastRow(char** pRow, SArray* pDataBlock, int32_t rowIndex, int32_t numOfCols) {
994 995 996 997
  if (pDataBlock == NULL) {
    return;
  }

H
Haojun Liao 已提交
998
  for (int32_t k = 0; k < numOfCols; ++k) {
L
Liu Jicong 已提交
999
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, k);
H
Haojun Liao 已提交
1000
    memcpy(pRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes);
1001 1002 1003
  }
}

H
Haojun Liao 已提交
1004
static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols, int32_t rows, bool ascQuery) {
1005 1006
  TSKEY ts = TSKEY_INITIAL_VAL;
  if (tsCols == NULL) {
L
Liu Jicong 已提交
1007
    ts = ascQuery ? win->skey : win->ekey;
1008
  } else {
L
Liu Jicong 已提交
1009
    int32_t offset = ascQuery ? 0 : rows - 1;
1010 1011 1012 1013 1014 1015
    ts = tsCols[offset];
  }

  return ts;
}

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

dengyihao's avatar
dengyihao 已提交
1019 1020
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
                                    int32_t order) {
1021 1022
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
    pCtx[i].order = order;
L
Liu Jicong 已提交
1023
    pCtx[i].size = pBlock->info.rows;
1024
    setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
1025 1026 1027
  }
}

dengyihao's avatar
dengyihao 已提交
1028 1029
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                       bool createDummyCol) {
1030
  if (pBlock->pBlockAgg != NULL) {
H
Haojun Liao 已提交
1031
    doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
1032
  } else {
1033
    doSetInputDataBlock(pOperator, pCtx, pBlock, order, createDummyCol);
H
Haojun Liao 已提交
1034
  }
1035 1036
}

1037
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam,
dengyihao's avatar
dengyihao 已提交
1038
                                             int32_t paramIndex, int32_t numOfRows) {
1039 1040 1041 1042 1043 1044 1045 1046
  SColumnInfoData* pColInfo = NULL;
  if (pInput->pData[paramIndex] == NULL) {
    pColInfo = taosMemoryCalloc(1, sizeof(SColumnInfoData));
    if (pColInfo == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }

    // Set the correct column info (data type and bytes)
1047 1048
    pColInfo->info.type = pFuncParam->param.nType;
    pColInfo->info.bytes = pFuncParam->param.nLen;
1049 1050

    pInput->pData[paramIndex] = pColInfo;
1051 1052
  } else {
    pColInfo = pInput->pData[paramIndex];
1053 1054
  }

1055
  colInfoDataEnsureCapacity(pColInfo, 0, numOfRows);
1056

1057
  int8_t type = pFuncParam->param.nType;
1058 1059
  if (type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_UBIGINT) {
    int64_t v = pFuncParam->param.i;
dengyihao's avatar
dengyihao 已提交
1060
    for (int32_t i = 0; i < numOfRows; ++i) {
1061 1062 1063 1064
      colDataAppendInt64(pColInfo, i, &v);
    }
  } else if (type == TSDB_DATA_TYPE_DOUBLE) {
    double v = pFuncParam->param.d;
dengyihao's avatar
dengyihao 已提交
1065
    for (int32_t i = 0; i < numOfRows; ++i) {
1066 1067
      colDataAppendDouble(pColInfo, i, &v);
    }
1068 1069 1070 1071 1072 1073
  } else if (type == TSDB_DATA_TYPE_VARCHAR) {
    char *tmp = taosMemoryMalloc(pFuncParam->param.nLen + VARSTR_HEADER_SIZE);
    STR_WITH_SIZE_TO_VARSTR(tmp, pFuncParam->param.pz, pFuncParam->param.nLen);
    for(int32_t i = 0; i < numOfRows; ++i) {
      colDataAppend(pColInfo, i, tmp, false);
    }
1074 1075 1076 1077 1078
  }

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
1079 1080
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
                                   bool createDummyCol) {
1081 1082
  int32_t code = TSDB_CODE_SUCCESS;

1083
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
1084 1085 1086
    pCtx[i].order      = order;
    pCtx[i].size       = pBlock->info.rows;
    pCtx[i].pSrcBlock  = pBlock;
H
Haojun Liao 已提交
1087 1088
    pCtx[i].currentStage = MAIN_SCAN;

1089
    SInputColumnInfoData* pInput = &pCtx[i].input;
1090
    pInput->uid = pBlock->info.uid;
C
Cary Xu 已提交
1091
    pInput->colDataAggIsSet = false;
1092

1093 1094
    SExprInfo* pOneExpr = &pOperator->pExpr[i];
    for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
dengyihao's avatar
dengyihao 已提交
1095
      SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
G
Ganlin Zhao 已提交
1096 1097
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
dengyihao's avatar
dengyihao 已提交
1098
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
1099 1100 1101
        pInput->totalRows = pBlock->info.rows;
        pInput->numOfRows = pBlock->info.rows;
        pInput->startRowIndex = 0;
1102

dengyihao's avatar
dengyihao 已提交
1103
        pInput->pPTS = taosArrayGet(pBlock->pDataBlock, 0);  // todo set the correct timestamp column
1104 1105
        ASSERT(pInput->pData[j] != NULL);
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
1106 1107 1108
        // todo avoid case: top(k, 12), 12 is the value parameter.
        // sum(11), 11 is also the value parameter.
        if (createDummyCol && pOneExpr->base.numOfParams == 1) {
1109 1110 1111 1112
          pInput->totalRows = pBlock->info.rows;
          pInput->numOfRows = pBlock->info.rows;
          pInput->startRowIndex = 0;

1113
          code = doCreateConstantValColumnInfo(pInput, pFuncParam, j, pBlock->info.rows);
1114 1115 1116
          if (code != TSDB_CODE_SUCCESS) {
            return code;
          }
1117
        }
G
Ganlin Zhao 已提交
1118 1119
      }
    }
H
Haojun Liao 已提交
1120

H
Haojun Liao 已提交
1121
    //    setBlockStatisInfo(&pCtx[i], pBlock, pOperator->pExpr[i].base.pColumns);
H
Haojun Liao 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
    //      uint32_t flag = pOperator->pExpr[i].base.pParam[0].pCol->flag;
    //      if (TSDB_COL_IS_NORMAL_COL(flag) /*|| (pCtx[i].functionId == FUNCTION_BLKINFO) ||
    //          (TSDB_COL_IS_TAG(flag) && pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)*/) {

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

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

  return code;
H
Haojun Liao 已提交
1162 1163 1164
}

static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
1165
  for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
H
Haojun Liao 已提交
1166
    if (functionNeedToExecute(&pCtx[k])) {
L
Liu Jicong 已提交
1167
      pCtx[k].startTs = startTs;  // this can be set during create the struct
H
Haojun Liao 已提交
1168
      pCtx[k].fpSet.process(&pCtx[k]);
1169 1170 1171 1172
    }
  }
}

H
Haojun Liao 已提交
1173
static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, SArray* pPseudoList) {
dengyihao's avatar
dengyihao 已提交
1174
  size_t num = (pPseudoList != NULL) ? taosArrayGetSize(pPseudoList) : 0;
H
Haojun Liao 已提交
1175 1176 1177 1178 1179
  for (int32_t i = 0; i < num; ++i) {
    pCtx[i].pOutput = taosArrayGet(pResult->pDataBlock, i);
  }
}

dengyihao's avatar
dengyihao 已提交
1180 1181
void projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
                           int32_t numOfOutput, SArray* pPseudoList) {
H
Haojun Liao 已提交
1182
  setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
H
Haojun Liao 已提交
1183
  pResult->info.groupId = pSrcBlock->info.groupId;
H
Haojun Liao 已提交
1184

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

1189 1190
  int32_t numOfRows = 0;

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

L
Liu Jicong 已提交
1195
    if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) {  // it is a project query
1196
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
1197
      if (pResult->info.rows > 0 && !createNewColModel) {
1198 1199 1200 1201
        colDataMergeCol(pColInfoData, pResult->info.rows, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      } else {
        colDataAssign(pColInfoData, pfCtx->input.pData[0], pfCtx->input.numOfRows);
      }
1202

1203
      numOfRows = pfCtx->input.numOfRows;
1204
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_VALUE) {
1205
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, outputSlotId);
1206

dengyihao's avatar
dengyihao 已提交
1207
      int32_t offset = createNewColModel ? 0 : pResult->info.rows;
1208
      for (int32_t i = 0; i < pSrcBlock->info.rows; ++i) {
dengyihao's avatar
dengyihao 已提交
1209 1210 1211
        colDataAppend(pColInfoData, i + offset,
                      taosVariantGet(&pExpr[k].base.pParam[0].param, pExpr[k].base.pParam[0].param.nType),
                      TSDB_DATA_TYPE_NULL == pExpr[k].base.pParam[0].param.nType);
1212
      }
1213 1214

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

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

1222
      SScalarParam dest = {.columnData = &idata};
1223 1224
      scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);

dengyihao's avatar
dengyihao 已提交
1225
      int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
1226
      colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
1227 1228

      numOfRows = dest.numOfRows;
1229 1230
      taosArrayDestroy(pBlockList);
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) {
1231
      ASSERT(!fmIsAggFunc(pfCtx->functionId));
1232

1233
      if (fmIsPseudoColumnFunc(pfCtx->functionId)) {
H
Haojun Liao 已提交
1234
        // do nothing
1235
      } else if (fmIsNonstandardSQLFunc(pfCtx->functionId)) {
H
Haojun Liao 已提交
1236
        // todo set the correct timestamp column
1237
        pfCtx->input.pPTS = taosArrayGet(pSrcBlock->pDataBlock, 1);
1238

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

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

1245
        // set the timestamp(_rowts) output buffer
1246 1247
        if (taosArrayGetSize(pPseudoList) > 0) {
          int32_t* outputColIndex = taosArrayGet(pPseudoList, 0);
1248
          pfCtx->pTsOutput = (SColumnInfoData*)pCtx[*outputColIndex].pOutput;
1249
        }
H
Haojun Liao 已提交
1250

1251
        numOfRows = pfCtx->fpSet.process(pfCtx);
H
Haojun Liao 已提交
1252 1253 1254
      } else {
        SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
        taosArrayPush(pBlockList, &pSrcBlock);
G
Ganlin Zhao 已提交
1255

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

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

dengyihao's avatar
dengyihao 已提交
1262
        int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
1263
        colDataMergeCol(pResColData, startOffset, &idata, dest.numOfRows);
1264 1265

        numOfRows = dest.numOfRows;
H
Haojun Liao 已提交
1266 1267
        taosArrayDestroy(pBlockList);
      }
1268
    } else {
1269
      ASSERT(0);
1270 1271
    }
  }
1272

1273 1274 1275
  if (!createNewColModel) {
    pResult->info.rows += numOfRows;
  }
1276 1277 1278 1279
}

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

H
Haojun Liao 已提交
1282
  SqlFunctionCtx* pCtx = pInfo->pCtx;
1283 1284 1285 1286 1287 1288 1289 1290

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

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

L
Liu Jicong 已提交
1295
    //    assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
1296 1297 1298
    double v1 = 0, v2 = 0, v = 0;

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

L
Liu Jicong 已提交
1304
    GET_TYPED_DATA(v2, double, pColInfo->info.type, (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes);
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315

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

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

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

L
Liu Jicong 已提交
1321
          pCtx[k].end.ptr = (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes;
1322 1323 1324
        }
      }
    } else if (functionId == FUNCTION_TWA) {
L
Liu Jicong 已提交
1325 1326 1327
      SPoint point1 = (SPoint){.key = prevTs, .val = &v1};
      SPoint point2 = (SPoint){.key = curTs, .val = &v2};
      SPoint point = (SPoint){.key = windowKey, .val = &v};
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341

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

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

H
Haojun Liao 已提交
1342
static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t pos,
dengyihao's avatar
dengyihao 已提交
1343 1344
                                              int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols,
                                              STimeWindow* win) {
H
Haojun Liao 已提交
1345
  bool  ascQuery = true;
L
Liu Jicong 已提交
1346
  TSKEY curTs = tsCols[pos];
dengyihao's avatar
dengyihao 已提交
1347
  TSKEY lastTs = 0;  //*(TSKEY*)pRuntimeEnv->prevRow[0];
1348 1349 1350

  // lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
  // start exactly from this point, no need to do interpolation
L
Liu Jicong 已提交
1351
  TSKEY key = ascQuery ? win->skey : win->ekey;
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
  if (key == curTs) {
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
    return true;
  }

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

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

dengyihao's avatar
dengyihao 已提交
1365 1366
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, key,
                            RESULT_ROW_START_INTERP);
1367 1368 1369
  return true;
}

L
Liu Jicong 已提交
1370 1371 1372
static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t endRowIndex,
                                            SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
                                            STimeWindow* win) {
H
Haojun Liao 已提交
1373 1374
  int32_t order = TSDB_ORDER_ASC;
  int32_t numOfOutput = pOperatorInfo->numOfOutput;
1375

L
Liu Jicong 已提交
1376
  TSKEY actualEndKey = tsCols[endRowIndex];
H
Haojun Liao 已提交
1377
  TSKEY key = order ? win->ekey : win->skey;
1378 1379

  // not ended in current data block, do not invoke interpolation
dengyihao's avatar
dengyihao 已提交
1380 1381
  if ((key > blockEkey /*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/) ||
      (key < blockEkey /*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/)) {
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
    setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP);
    return false;
  }

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

H
Haojun Liao 已提交
1392
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
1393 1394 1395 1396 1397
  int32_t nextRowIndex = endRowIndex + step;
  assert(nextRowIndex >= 0);

  TSKEY nextKey = tsCols[nextRowIndex];
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, actualEndKey, endRowIndex, nextKey,
L
Liu Jicong 已提交
1398
                            nextRowIndex, key, RESULT_ROW_END_INTERP);
1399 1400 1401
  return true;
}

H
Haojun Liao 已提交
1402
static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SqlFunctionCtx* pCtx,
L
Liu Jicong 已提交
1403 1404
                                        SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep,
                                        int32_t order, bool timeWindowInterpo) {
H
Haojun Liao 已提交
1405
  if (!timeWindowInterpo) {
1406 1407 1408 1409
    return;
  }

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

L
Liu Jicong 已提交
1412 1413
  if (pBlock->pDataBlock == NULL) {
    //    tscError("pBlock->pDataBlock == NULL");
1414 1415
    return;
  }
H
Haojun Liao 已提交
1416

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

L
Liu Jicong 已提交
1419 1420 1421
  TSKEY* tsCols = (TSKEY*)(pColInfo->pData);
  bool   done = resultRowInterpolated(pResult, RESULT_ROW_START_INTERP);
  if (!done) {  // it is not interpolated, now start to generated the interpolated value
1422
    int32_t startRowIndex = startPos;
L
Liu Jicong 已提交
1423
    bool    interp = setTimeWindowInterpolationStartTs(pOperatorInfo, pCtx, startRowIndex, pBlock->info.rows,
dengyihao's avatar
dengyihao 已提交
1424
                                                    pBlock->pDataBlock, tsCols, win);
1425 1426 1427 1428
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1429
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1430 1431 1432
  }

  // point interpolation does not require the end key time window interpolation.
L
Liu Jicong 已提交
1433 1434 1435
  //  if (pointInterpQuery) {
  //    return;
  //  }
1436 1437 1438 1439 1440 1441

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

L
Liu Jicong 已提交
1442 1443 1444
    TSKEY endKey = (order == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey;
    bool  interp =
        setTimeWindowInterpolationEndTs(pOperatorInfo, pCtx, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
1445 1446 1447 1448
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1449
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_END_INTERP);
1450 1451 1452
  }
}

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

H
Haojun Liao 已提交
1457
  SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
L
Liu Jicong 已提交
1458
  int32_t        numOfOutput = pOperatorInfo->numOfOutput;
1459

1460 1461
  SArray* pUpdated = NULL;
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1462
    pUpdated = taosArrayInit(4, POINTER_BYTES);
1463 1464
  }

H
Haojun Liao 已提交
1465
  int32_t step = 1;
1466
  bool    ascScan = true;
1467

dengyihao's avatar
dengyihao 已提交
1468
  //  int32_t prevIndex = pResultRowInfo->curPos;
1469 1470 1471

  TSKEY* tsCols = NULL;
  if (pSDataBlock->pDataBlock != NULL) {
1472
    SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
L
Liu Jicong 已提交
1473
    tsCols = (int64_t*)pColDataInfo->pData;
1474 1475
  }

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

dengyihao's avatar
dengyihao 已提交
1479 1480
  STimeWindow win = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval,
                                        pInfo->interval.precision, &pInfo->win);
L
Liu Jicong 已提交
1481
  bool        masterScan = true;
1482 1483

  SResultRow* pResult = NULL;
L
Liu Jicong 已提交
1484
  int32_t     ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult,
dengyihao's avatar
dengyihao 已提交
1485 1486
                                           tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset,
                                           &pInfo->aggSup, pTaskInfo);
1487
  if (ret != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1488
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1489 1490
  }

1491
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1492 1493 1494 1495 1496
    SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
    pos->groupId = tableGroupId;
    pos->pos     = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset};
    *(int64_t*) pos->key = pResult->win.skey;

1497 1498 1499
    taosArrayPush(pUpdated, &pos);
  }

1500
  int32_t forwardStep = 0;
H
Haojun Liao 已提交
1501
  TSKEY   ekey = win.ekey;
1502
  forwardStep =
H
Haojun Liao 已提交
1503
      getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1504 1505

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

#if 0
H
Haojun Liao 已提交
1509
  if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
1510 1511 1512
    for (int32_t j = prevIndex; j < curIndex; ++j) {  // previous time window may be all closed already.
      SResultRow* pRes = getResultRow(pResultRowInfo, j);
      if (pRes->closed) {
1513
        assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
1514 1515 1516
        continue;
      }

L
Liu Jicong 已提交
1517 1518 1519 1520 1521 1522 1523
      STimeWindow w = pRes->win;
      ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &w, masterScan, &pResult, tableGroupId,
                                       pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                       pTaskInfo);
      if (ret != TSDB_CODE_SUCCESS) {
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
      }
1524

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

L
Liu Jicong 已提交
1529 1530
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
      setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1531

1532
      doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
L
Liu Jicong 已提交
1533
    }
1534 1535

    // restore current time window
L
Liu Jicong 已提交
1536 1537 1538
    ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
                                     pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                     pTaskInfo);
1539
    if (ret != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1540
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1541 1542
    }
  }
H
Haojun Liao 已提交
1543
#endif
1544 1545

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

1549
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &win, true);
dengyihao's avatar
dengyihao 已提交
1550 1551
  doApplyFunctions(pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
                   pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1552 1553 1554 1555

  STimeWindow nextWin = win;
  while (1) {
    int32_t prevEndPos = (forwardStep - 1) * step + startPos;
H
Haojun Liao 已提交
1556
    startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, pInfo);
1557 1558 1559 1560 1561
    if (startPos < 0) {
      break;
    }

    // null data, failed to allocate more memory buffer
L
Liu Jicong 已提交
1562 1563 1564
    int32_t code = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &nextWin, masterScan, &pResult,
                                              tableGroupId, pInfo->binfo.pCtx, numOfOutput,
                                              pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1565
    if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1566
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1567 1568
    }

1569
    if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
1570 1571 1572 1573 1574
      SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
      pos->groupId = tableGroupId;
      pos->pos     = (SResultRowPosition) {.pageId = pResult->pageId, .offset = pResult->offset};
      *(int64_t*) pos->key = pResult->win.skey;

1575 1576 1577
      taosArrayPush(pUpdated, &pos);
    }

L
Liu Jicong 已提交
1578 1579 1580
    ekey = nextWin.ekey;  // reviseWindowEkey(pQueryAttr, &nextWin);
    forwardStep =
        getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1581 1582

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

1586
    updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
dengyihao's avatar
dengyihao 已提交
1587 1588
    doApplyFunctions(pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
                     pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1589 1590
  }

H
Haojun Liao 已提交
1591
  if (pInfo->timeWindowInterpo) {
1592
    int32_t rowIndex = ascScan ? (pSDataBlock->info.rows - 1) : 0;
H
Haojun Liao 已提交
1593
    saveDataBlockLastRow(pInfo->pRow, pSDataBlock->pDataBlock, rowIndex, pSDataBlock->info.numOfCols);
1594 1595
  }

1596
  return pUpdated;
L
Liu Jicong 已提交
1597
  //  updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
1598 1599
}

1600
static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts) {
dengyihao's avatar
dengyihao 已提交
1601 1602
  pRowSup->win.ekey = ts;
  pRowSup->prevTs = ts;
1603
  pRowSup->numOfRows += 1;
1604 1605
}

1606 1607
static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsList, int32_t rowIndex) {
  pRowSup->startRowIndex = rowIndex;
dengyihao's avatar
dengyihao 已提交
1608 1609
  pRowSup->numOfRows = 0;
  pRowSup->win.skey = tsList[rowIndex];
1610 1611
}

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

1616
  // todo find the correct time stamp column slot
1617
  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
1618

1619 1620 1621
  bool    masterScan = true;
  int32_t numOfOutput = pOperator->numOfOutput;
  int64_t gid = pBlock->info.groupId;
1622

H
Haojun Liao 已提交
1623
  int64_t gap = pInfo->gap;
1624

1625
  if (!pInfo->reptScan) {
1626
    pInfo->reptScan = true;
1627
    pInfo->winSup.prevTs = INT64_MIN;
1628 1629
  }

1630 1631 1632
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;

1633
  // In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
1634
  TSKEY* tsList = (TSKEY*)pColInfoData->pData;
1635
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
1636 1637 1638 1639
    if (pInfo->winSup.prevTs == INT64_MIN) {
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
    } else if (tsList[j] - pRowSup->prevTs <= gap && (tsList[j] - pRowSup->prevTs) >= 0) {
1640
      // The gap is less than the threshold, so it belongs to current session window that has been opened already.
1641 1642 1643
      doKeepTuple(pRowSup, tsList[j]);
      if (j == 0 && pRowSup->startRowIndex != 0) {
        pRowSup->startRowIndex = 0;
1644 1645 1646
      }
    } else {  // start a new session window
      SResultRow* pResult = NULL;
1647 1648

      // keep the time window for the closed time window.
1649
      STimeWindow window = pRowSup->win;
1650

1651
      pRowSup->win.ekey = pRowSup->win.skey;
L
Liu Jicong 已提交
1652
      int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &window, masterScan,
dengyihao's avatar
dengyihao 已提交
1653 1654
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1655
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1656
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1657 1658
      }

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

1664
      // here we start a new session window
1665 1666
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
1667 1668 1669 1670
    }
  }

  SResultRow* pResult = NULL;
1671
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
1672 1673 1674
  int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &pRowSup->win, masterScan,
                                           &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                           pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1675
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1676
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1677 1678
  }

1679
  updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
dengyihao's avatar
dengyihao 已提交
1680 1681
  doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                   pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1682 1683 1684 1685
}

static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
  if (IS_VAR_DATA_TYPE(type)) {
1686
    // todo disable this
dengyihao's avatar
dengyihao 已提交
1687 1688 1689 1690 1691 1692
    //    if (pResultRow->key == NULL) {
    //      pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
    //      varDataCopy(pResultRow->key, pData);
    //    } else {
    //      ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
    //    }
1693 1694 1695 1696 1697 1698 1699 1700 1701
  } else {
    int64_t v = -1;
    GET_TYPED_DATA(v, int64_t, type, pData);

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

1702
int32_t setGroupResultOutputBuf(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type, int16_t bytes,
dengyihao's avatar
dengyihao 已提交
1703 1704
                                int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo,
                                SAggSupporter* pAggSup) {
L
Liu Jicong 已提交
1705 1706
  SResultRowInfo* pResultRowInfo = &binfo->resultRowInfo;
  SqlFunctionCtx* pCtx = binfo->pCtx;
1707

1708
  SResultRow* pResultRow = doSetResultOutBufByKey(pBuf, pResultRowInfo, groupId, (char*)pData, bytes, true, groupId,
H
Haojun Liao 已提交
1709
                                                     pTaskInfo, false, pAggSup);
L
Liu Jicong 已提交
1710
  assert(pResultRow != NULL);
1711 1712

  setResultRowKey(pResultRow, pData, type);
H
Haojun Liao 已提交
1713
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfCols, binfo->rowCellInfoOffset);
1714 1715 1716
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
1717 1718
static bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
  struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
1719 1720 1721

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

1726
  if (isRowEntryCompleted(pResInfo)) {
1727 1728 1729 1730
    return false;
  }

  if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
L
Liu Jicong 已提交
1731
    //    return QUERY_IS_ASC_QUERY(pQueryAttr);
1732 1733 1734 1735
  }

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

  // in the reverse table scan, only the following functions need to be executed
L
Liu Jicong 已提交
1740 1741 1742 1743
  //  if (IS_REVERSE_SCAN(pRuntimeEnv) ||
  //      (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
  //    return false;
  //  }
1744 1745 1746 1747

  return true;
}

dengyihao's avatar
dengyihao 已提交
1748 1749
static int32_t doCreateConstantValColumnAggInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t type,
                                                int32_t paramIndex, int32_t numOfRows) {
1750 1751 1752 1753 1754 1755 1756
  if (pInput->pData[paramIndex] == NULL) {
    pInput->pData[paramIndex] = taosMemoryCalloc(1, sizeof(SColumnInfoData));
    if (pInput->pData[paramIndex] == NULL) {
      return TSDB_CODE_OUT_OF_MEMORY;
    }

    // Set the correct column info (data type and bytes)
dengyihao's avatar
dengyihao 已提交
1757 1758
    pInput->pData[paramIndex]->info.type = type;
    pInput->pData[paramIndex]->info.bytes = tDataTypes[type].bytes;
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
  }

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

  ASSERT(!IS_VAR_DATA_TYPE(type));

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

dengyihao's avatar
dengyihao 已提交
1781 1782 1783
    *(double*)&da->min = v;
    *(double*)&da->max = v;
    *(double*)&da->sum = v * numOfRows;
1784 1785 1786
  } else if (type == TSDB_DATA_TYPE_BOOL) {  // todo validate this data type
    bool v = pFuncParam->param.i;

dengyihao's avatar
dengyihao 已提交
1787 1788 1789 1790
    *da = (SColumnDataAgg){.numOfNull = 0, .maxIndex = 0, .minIndex = 0};
    *(bool*)&da->min = 0;
    *(bool*)&da->max = v;
    *(bool*)&da->sum = v * numOfRows;
1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809
  } else if (type == TSDB_DATA_TYPE_TIMESTAMP) {
    // do nothing
  } else {
    ASSERT(0);
  }

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

1813 1814 1815
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
        pInput->pColumnDataAgg[j] = &pBlock->pBlockAgg[slotId];
1816 1817 1818 1819

        // Here we set the column info data since the data type for each column data is required, but
        // the data in the corresponding SColumnInfoData will not be used.
        pInput->pData[j] = taosArrayGet(pBlock->pDataBlock, slotId);
1820 1821
      } else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
        doCreateConstantValColumnAggInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
1822 1823
      }
    }
1824
  } else {
1825
    pInput->colDataAggIsSet = false;
1826 1827 1828
  }

  // set the statistics data for primary time stamp column
1829 1830 1831 1832 1833
  //  if (pCtx->functionId == FUNCTION_SPREAD && pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
  //    pCtx->isAggSet = true;
  //    pCtx->agg.min = pBlock->info.window.skey;
  //    pCtx->agg.max = pBlock->info.window.ekey;
  //  }
1834 1835 1836
}

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

H
Haojun Liao 已提交
1841
  SqlFunctionCtx*  p = NULL;
wafwerar's avatar
wafwerar 已提交
1842
  SqlFunctionCtx** pTagCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
1843 1844 1845 1846 1847 1848 1849 1850
  if (pTagCtx == NULL) {
    return TSDB_CODE_QRY_OUT_OF_MEMORY;
  }

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

    if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
H
Haojun Liao 已提交
1851
      tagLen += pCtx[i].resDataInfo.bytes;
1852
      pTagCtx[num++] = &pCtx[i];
L
Liu Jicong 已提交
1853
    } else if (1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/) {
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
      p = &pCtx[i];
    } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
      // tag function may be the group by tag column
      // ts may be the required primary timestamp column
      continue;
    } else {
      // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
    }
  }
  if (p != NULL) {
1864 1865
    p->subsidiaries.pCtx = pTagCtx;
    p->subsidiaries.num = num;
1866
  } else {
wafwerar's avatar
wafwerar 已提交
1867
    taosMemoryFreeClear(pTagCtx);
1868 1869 1870 1871 1872
  }

  return TSDB_CODE_SUCCESS;
}

1873
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) {
L
Liu Jicong 已提交
1874
  SqlFunctionCtx* pFuncCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
H
Haojun Liao 已提交
1875 1876 1877 1878
  if (pFuncCtx == NULL) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
1879
  *rowCellInfoOffset = taosMemoryCalloc(numOfOutput, sizeof(int32_t));
H
Haojun Liao 已提交
1880
  if (*rowCellInfoOffset == 0) {
wafwerar's avatar
wafwerar 已提交
1881
    taosMemoryFreeClear(pFuncCtx);
H
Haojun Liao 已提交
1882 1883 1884 1885
    return NULL;
  }

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

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

1891
    pCtx->functionId = -1;
1892 1893 1894
    pCtx->curBufPage = -1;
    pCtx->pExpr      = pExpr;

H
Haojun Liao 已提交
1895
    if (pExpr->pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1896
      SFuncExecEnv env = {0};
H
Haojun Liao 已提交
1897 1898
      pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;

H
Haojun Liao 已提交
1899
      if (fmIsAggFunc(pCtx->functionId) || fmIsNonstandardSQLFunc(pCtx->functionId)) {
1900 1901 1902 1903
        fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
        pCtx->fpSet.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
      } else {
        fmGetScalarFuncExecFuncs(pCtx->functionId, &pCtx->sfp);
1904 1905 1906
        if (pCtx->sfp.getEnv != NULL) {
          pCtx->sfp.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
        }
1907
      }
H
Haojun Liao 已提交
1908
      pCtx->resDataInfo.interBufSize = env.calcMemSize;
1909 1910 1911 1912
    } else if (pExpr->pExpr->nodeType == QUERY_NODE_COLUMN || pExpr->pExpr->nodeType == QUERY_NODE_OPERATOR ||
               pExpr->pExpr->nodeType == QUERY_NODE_VALUE) {
      // for simple column, the intermediate buffer needs to hold one element.
      pCtx->resDataInfo.interBufSize = pFunct->resSchema.bytes;
H
Haojun Liao 已提交
1913
    }
H
Haojun Liao 已提交
1914

H
Haojun Liao 已提交
1915
    pCtx->input.numOfInputCols = pFunct->numOfParams;
wafwerar's avatar
wafwerar 已提交
1916 1917
    pCtx->input.pData = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
    pCtx->input.pColumnDataAgg = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
H
Haojun Liao 已提交
1918

1919
    pCtx->pTsOutput = NULL;
L
Liu Jicong 已提交
1920
    pCtx->resDataInfo.bytes = pFunct->resSchema.bytes;
1921
    pCtx->resDataInfo.type = pFunct->resSchema.type;
1922
    pCtx->order     = TSDB_ORDER_ASC;
1923
    pCtx->start.key = INT64_MIN;
1924
    pCtx->end.key   = INT64_MIN;
1925
    pCtx->numOfParams = pExpr->base.numOfParams;
H
Haojun Liao 已提交
1926

1927
    pCtx->param = pFunct->pParam;
dengyihao's avatar
dengyihao 已提交
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961
    //    for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
    //      // set the order information for top/bottom query
    //      int32_t functionId = pCtx->functionId;
    //      if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF) {
    //        int32_t f = getExprFunctionId(&pExpr[0]);
    //        assert(f == FUNCTION_TS || f == FUNCTION_TS_DUMMY);
    //
    //        //      pCtx->param[2].i = pQueryAttr->order.order;
    //        //      pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
    //        //      pCtx->param[3].i = functionId;
    //        //      pCtx->param[3].nType = TSDB_DATA_TYPE_BIGINT;
    //
    //        //      pCtx->param[1].i = pQueryAttr->order.col.info.colId;
    //      } else if (functionId == FUNCTION_INTERP) {
    //        //      pCtx->param[2].i = (int8_t)pQueryAttr->fillType;
    //        //      if (pQueryAttr->fillVal != NULL) {
    //        //        if (isNull((const char *)&pQueryAttr->fillVal[i], pCtx->inputType)) {
    //        //          pCtx->param[1].nType = TSDB_DATA_TYPE_NULL;
    //        //        } else {  // todo refactor, taosVariantCreateFromBinary should handle the NULL value
    //        //          if (pCtx->inputType != TSDB_DATA_TYPE_BINARY && pCtx->inputType != TSDB_DATA_TYPE_NCHAR) {
    //        //            taosVariantCreateFromBinary(&pCtx->param[1], (char *)&pQueryAttr->fillVal[i],
    //        pCtx->inputBytes, pCtx->inputType);
    //        //          }
    //        //        }
    //        //      }
    //      } else if (functionId == FUNCTION_TWA) {
    //        //      pCtx->param[1].i = pQueryAttr->window.skey;
    //        //      pCtx->param[1].nType = TSDB_DATA_TYPE_BIGINT;
    //        //      pCtx->param[2].i = pQueryAttr->window.ekey;
    //        //      pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
    //      } else if (functionId == FUNCTION_ARITHM) {
    //        //      pCtx->param[1].pz = (char*) getScalarFuncSupport(pRuntimeEnv->scalarSup, i);
    //      }
    //    }
H
Haojun Liao 已提交
1962 1963
  }

L
Liu Jicong 已提交
1964 1965 1966
  for (int32_t i = 1; i < numOfOutput; ++i) {
    (*rowCellInfoOffset)[i] =
        (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowEntryInfo) + pFuncCtx[i - 1].resDataInfo.interBufSize);
H
Haojun Liao 已提交
1967
  }
H
Haojun Liao 已提交
1968 1969 1970 1971 1972

  setCtxTagColumnInfo(pFuncCtx, numOfOutput);
  return pFuncCtx;
}

1973
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1974 1975 1976 1977 1978 1979
  if (pCtx == NULL) {
    return NULL;
  }

  for (int32_t i = 0; i < numOfOutput; ++i) {
    for (int32_t j = 0; j < pCtx[i].numOfParams; ++j) {
1980
      taosVariantDestroy(&pCtx[i].param[j].param);
1981 1982 1983
    }

    taosVariantDestroy(&pCtx[i].tag);
1984
    taosMemoryFreeClear(pCtx[i].subsidiaries.pCtx);
1985 1986
  }

wafwerar's avatar
wafwerar 已提交
1987
  taosMemoryFreeClear(pCtx);
1988 1989 1990
  return NULL;
}

L
Liu Jicong 已提交
1991
bool isTaskKilled(SExecTaskInfo* pTaskInfo) {
1992 1993
  // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
  // abort current query execution.
L
Liu Jicong 已提交
1994 1995
  if (pTaskInfo->owner != 0 &&
      ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec())
1996 1997
      /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) {
    assert(pTaskInfo->cost.start != 0);
L
Liu Jicong 已提交
1998 1999 2000
    //    qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64
    //           ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec());
    //    return true;
2001 2002 2003 2004 2005
  }

  return false;
}

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

L
Liu Jicong 已提交
2008
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
2009 2010 2011 2012 2013 2014 2015 2016 2017
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
    if (functionId == FUNCTION_LAST || functionId == FUNCTION_LAST_DST) {
      continue;
    }

    return false;
  }

2018 2019
  int32_t order = TSDB_ORDER_ASC;
  if (order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) {
2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038
    return false;
  }

  if (pQueryAttr->groupbyColumn) {
    return false;
  }

  if (pQueryAttr->interval.interval > 0) {
    return false;
  }

  if (pQueryAttr->numOfFilterCols > 0 || pQueryAttr->havingNum > 0) {
    return false;
  }

  return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////
L
Liu Jicong 已提交
2039
// todo refactor : return window
2040
void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, STimeWindow* win) {
H
Haojun Liao 已提交
2041
  win->skey = taosTimeTruncate(key, pInterval, precision);
2042 2043

  /*
H
Haojun Liao 已提交
2044
   * if the realSkey > INT64_MAX - pInterval->interval, the query duration between
2045 2046
   * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
   */
2047 2048
  win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
  if (win->ekey < win->skey) {
2049 2050 2051 2052
    win->ekey = INT64_MAX;
  }
}

L
Liu Jicong 已提交
2053
static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
2054 2055 2056
  bool hasFirstLastFunc = false;
  bool hasOtherFunc = false;

2057
  if (status == BLK_DATA_DATA_LOAD || status == BLK_DATA_FILTEROUT) {
2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
    return status;
  }

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

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

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

2076
  if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
L
Liu Jicong 已提交
2077
    if (!hasOtherFunc) {
2078
      return BLK_DATA_FILTEROUT;
2079
    } else {
2080
      return BLK_DATA_DATA_LOAD;
2081 2082 2083 2084 2085 2086
    }
  }

  return status;
}

L
Liu Jicong 已提交
2087 2088
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
//   STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
H
Haojun Liao 已提交
2089
//
L
Liu Jicong 已提交
2090 2091 2092 2093
//   // in case of point-interpolation query, use asc order scan
//   char msg[] = "QInfo:0x%"PRIx64" scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%"
//   PRId64
//                "-%" PRId64 ", new qrange:%" PRId64 "-%" PRId64;
H
Haojun Liao 已提交
2094
//
L
Liu Jicong 已提交
2095 2096 2097 2098 2099
//   // todo handle the case the the order irrelevant query type mixed up with order critical query type
//   // descending order query for last_row query
//   if (isFirstLastRowQuery(pQueryAttr)) {
//     //qDebug("QInfo:0x%"PRIx64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId,
//     pQueryAttr->order.order, TSDB_ORDER_ASC);
H
Haojun Liao 已提交
2100
//
L
Liu Jicong 已提交
2101 2102 2103 2104
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2105
//
L
Liu Jicong 已提交
2106 2107 2108
//     pQueryAttr->needReverseScan = false;
//     return;
//   }
H
Haojun Liao 已提交
2109
//
L
Liu Jicong 已提交
2110 2111 2112 2113 2114
//   if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) {
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2115
//
L
Liu Jicong 已提交
2116 2117 2118 2119
//     pQueryAttr->needReverseScan = false;
//     doUpdateLastKey(pQueryAttr);
//     return;
//   }
H
Haojun Liao 已提交
2120
//
L
Liu Jicong 已提交
2121 2122 2123 2124 2125 2126
//   if (pQueryAttr->pointInterpQuery && pQueryAttr->interval.interval == 0) {
//     if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//       //qDebug(msg, pQInfo->qId, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
//       pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); TSWAP(pQueryAttr->window.skey,
//       pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2127
//
L
Liu Jicong 已提交
2128 2129 2130
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     return;
//   }
H
Haojun Liao 已提交
2131
//
L
Liu Jicong 已提交
2132 2133 2134 2135
//   if (pQueryAttr->interval.interval == 0) {
//     if (onlyFirstQuery(pQueryAttr)) {
//       if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//         //qDebug(msg, pQInfo->qId, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
H
Haojun Liao 已提交
2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//        doUpdateLastKey(pQueryAttr);
//      }
//
//      pQueryAttr->order.order = TSDB_ORDER_ASC;
//      pQueryAttr->needReverseScan = false;
//    } else if (onlyLastQuery(pQueryAttr) && notContainSessionOrStateWindow(pQueryAttr)) {
//      if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//        //qDebug(msg, pQInfo->qId, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
////               pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
//        TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//        doUpdateLastKey(pQueryAttr);
//      }
//
//      pQueryAttr->order.order = TSDB_ORDER_DESC;
//      pQueryAttr->needReverseScan = false;
//    }
//
//  } else {  // interval query
//    if (stableQuery) {
//      if (onlyFirstQuery(pQueryAttr)) {
//        if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
//          //qDebug(msg, pQInfo->qId, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC,
L
Liu Jicong 已提交
2162 2163
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_ASC;
//        pQueryAttr->needReverseScan = false;
//      } else if (onlyLastQuery(pQueryAttr)) {
//        if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//          //qDebug(msg, pQInfo->qId, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC,
L
Liu Jicong 已提交
2174 2175
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_DESC;
//        pQueryAttr->needReverseScan = false;
//      }
//    }
//  }
//}
2187

H
Haojun Liao 已提交
2188 2189
static void getIntermediateBufInfo(STaskRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) {
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
L
Liu Jicong 已提交
2190
  int32_t    MIN_ROWS_PER_PAGE = 4;
2191

L
Liu Jicong 已提交
2192 2193
  *rowsize = (int32_t)(pQueryAttr->resultRowSize *
                       getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
2194 2195 2196 2197
  int32_t overhead = sizeof(SFilePage);

  // one page contains at least two rows
  *ps = DEFAULT_INTERN_BUF_PAGE_SIZE;
L
Liu Jicong 已提交
2198
  while (((*rowsize) * MIN_ROWS_PER_PAGE) > (*ps) - overhead) {
2199 2200 2201 2202 2203 2204
    *ps = ((*ps) << 1u);
  }
}

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

L
Liu Jicong 已提交
2205 2206 2207
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
//   STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2208
//
L
Liu Jicong 已提交
2209 2210 2211
//   if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
//     return true;
//   }
2212
//
L
Liu Jicong 已提交
2213 2214
//   return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
2215

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

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

2222
  if (true) {
L
Liu Jicong 已提交
2223
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
2224 2225 2226 2227 2228 2229
    assert(w.ekey >= pBlockInfo->window.skey);

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

L
Liu Jicong 已提交
2230 2231
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2232 2233 2234 2235 2236 2237 2238 2239 2240 2241
      if (w.skey > pBlockInfo->window.ekey) {
        break;
      }

      assert(w.ekey > pBlockInfo->window.ekey);
      if (w.skey <= pBlockInfo->window.ekey && w.skey > pBlockInfo->window.skey) {
        return true;
      }
    }
  } else {
L
Liu Jicong 已提交
2242
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
2243 2244 2245 2246 2247 2248
    assert(w.skey <= pBlockInfo->window.ekey);

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

L
Liu Jicong 已提交
2249 2250
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
      if (w.ekey < pBlockInfo->window.skey) {
        break;
      }

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

  return false;
}

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

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

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

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

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

    start += len;
    len = 0;
  }

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

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

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

static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
2318
  SqlFunctionCtx* pCtx = pTableScanInfo->pCtx;
2319
  uint32_t        status = BLK_DATA_NOT_LOAD;
2320 2321 2322 2323

  int32_t numOfOutput = pTableScanInfo->numOfOutput;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;
H
Haojun Liao 已提交
2324
    int32_t colId = pTableScanInfo->pExpr[i].base.pParam[0].pCol->colId;
2325 2326 2327

    // group by + first/last should not apply the first/last block filter
    if (functionId < 0) {
2328
      status |= BLK_DATA_DATA_LOAD;
2329 2330
      return status;
    } else {
L
Liu Jicong 已提交
2331
      //      status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
2332
      //      if ((status & BLK_DATA_DATA_LOAD) == BLK_DATA_DATA_LOAD) {
L
Liu Jicong 已提交
2333 2334
      //        return status;
      //      }
2335 2336 2337 2338 2339 2340
    }
  }

  return status;
}

L
Liu Jicong 已提交
2341 2342
int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                              uint32_t* status) {
2343
  *status = BLK_DATA_NOT_LOAD;
2344

H
Haojun Liao 已提交
2345
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
2346
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
2347

L
Liu Jicong 已提交
2348 2349
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2350

H
Haojun Liao 已提交
2351
  STaskCostInfo* pCost = &pTaskInfo->cost;
2352 2353 2354

  pCost->totalBlocks += 1;
  pCost->totalRows += pBlock->info.rows;
H
Haojun Liao 已提交
2355
#if 0
2356 2357 2358
  // Calculate all time windows that are overlapping or contain current data block.
  // If current data block is contained by all possible time window, do not load current data block.
  if (/*pQueryAttr->pFilters || */pQueryAttr->groupbyColumn || pQueryAttr->sw.gap > 0 ||
H
Haojun Liao 已提交
2359
      (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) {
2360
    (*status) = BLK_DATA_DATA_LOAD;
2361 2362 2363
  }

  // check if this data block is required to load
2364
  if ((*status) != BLK_DATA_DATA_LOAD) {
2365 2366 2367 2368 2369 2370 2371
    bool needFilter = true;

    // the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet,
    // the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer
    if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
      SResultRow* pResult = NULL;

H
Haojun Liao 已提交
2372
      bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395
      TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey;

      STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr);
      if (pQueryAttr->pointInterpQuery) {
        needFilter = chkWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId,
                                    pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
                                    pTableScanInfo->rowCellInfoOffset);
      } else {
        if (setResultOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pBlock->info.uid, &win, masterScan, &pResult, groupId,
                                    pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
                                    pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) {
          longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
        }
      }
    } else if (pQueryAttr->stableQuery && (!pQueryAttr->tsCompQuery) && (!pQueryAttr->diffQuery)) { // stable aggregate, not interval aggregate or normal column aggregate
      doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx,
                               pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput,
                               pRuntimeEnv->current->groupIndex);
    }

    if (needFilter) {
      (*status) = doFilterByBlockTimeWindow(pTableScanInfo, pBlock);
    } else {
2396
      (*status) = BLK_DATA_DATA_LOAD;
2397 2398 2399 2400
    }
  }

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

2403
  if ((*status) == BLK_DATA_NOT_LOAD || (*status) == BLK_DATA_FILTEROUT) {
2404 2405
    //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//           pBlockInfo->window.ekey, pBlockInfo->rows);
2406
    pCost->skipBlocks += 1;
2407
  } else if ((*status) == BLK_DATA_SMA_LOAD) {
2408 2409
    // this function never returns error?
    pCost->loadBlockStatis += 1;
2410
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2411 2412

    if (pBlock->pBlockAgg == NULL) {  // data block statistics does not exist, load data block
2413
//      pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2414 2415 2416
      pCost->totalCheckedRows += pBlock->info.rows;
    }
  } else {
2417
    assert((*status) == BLK_DATA_DATA_LOAD);
2418 2419 2420

    // load the data block statistics to perform further filter
    pCost->loadBlockStatis += 1;
2421
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2422 2423 2424 2425 2426 2427

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

H
Haojun Liao 已提交
2428
          bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445
          TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey;

          STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr);
          if (setResultOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pBlock->info.uid, &win, masterScan, &pResult, groupId,
                                      pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
                                      pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) {
            longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
          }
        }
      }
      bool load = false;
      for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
        int32_t functionId = pTableScanInfo->pCtx[i].functionId;
        if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) {
//          load = topbot_datablock_filter(&pTableScanInfo->pCtx[i], (char*)&(pBlock->pBlockAgg[i].min),
//                                         (char*)&(pBlock->pBlockAgg[i].max));
          if (!load) { // current block has been discard due to filter applied
2446
            pCost->skipBlocks += 1;
2447 2448
            //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
//                   pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
2449
            (*status) = BLK_DATA_FILTEROUT;
2450 2451 2452 2453 2454 2455 2456 2457
            return TSDB_CODE_SUCCESS;
          }
        }
      }
    }

    // current block has been discard due to filter applied
//    if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
2458
//      pCost->skipBlocks += 1;
2459 2460
//      qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//             pBlockInfo->window.ekey, pBlockInfo->rows);
2461
//      (*status) = BLK_DATA_FILTEROUT;
2462 2463 2464 2465 2466
//      return TSDB_CODE_SUCCESS;
//    }

    pCost->totalCheckedRows += pBlockInfo->rows;
    pCost->loadBlocks += 1;
2467
//    pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479
//    if (pBlock->pDataBlock == NULL) {
//      return terrno;
//    }

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

L
Liu Jicong 已提交
2484
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
2485 2486 2487 2488 2489 2490 2491 2492 2493
  int32_t midPos = -1;
  int32_t numOfRows;

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

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

L
Liu Jicong 已提交
2494
  TSKEY*  keyList = (TSKEY*)pValue;
2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547
  int32_t firstPos = 0;
  int32_t lastPos = num - 1;

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

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

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

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

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

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

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

  return midPos;
}

/*
H
Haojun Liao 已提交
2548
 * set tag value in SqlFunctionCtx
2549 2550
 * e.g.,tag information into input buffer
 */
L
Liu Jicong 已提交
2551
static void doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes) {
2552 2553 2554
  taosVariantDestroy(tag);

  char* val = NULL;
L
Liu Jicong 已提交
2555 2556 2557 2558 2559 2560
  //  if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
  //    val = tsdbGetTableName(pTable);
  //    assert(val != NULL);
  //  } else {
  //    val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
  //  }
2561 2562 2563 2564 2565 2566 2567 2568

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

  if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
    int32_t maxLen = bytes - VARSTR_HEADER_SIZE;
L
Liu Jicong 已提交
2569
    int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
2570
    taosVariantCreateFromBinary(tag, varDataVal(val), len, type);
L
Liu Jicong 已提交
2571
    // taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
2572 2573 2574 2575 2576 2577 2578 2579
  } else {
    taosVariantCreateFromBinary(tag, val, bytes, type);
  }
}

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

L
Liu Jicong 已提交
2580
  for (int32_t i = 0; i < numOfTags; ++i) {
2581 2582 2583 2584 2585 2586 2587 2588
    if (pTagColList[i].colId == colId) {
      return &pTagColList[i];
    }
  }

  return NULL;
}

L
Liu Jicong 已提交
2589 2590
void setTagValue(SOperatorInfo* pOperatorInfo, void* pTable, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
  SExprInfo* pExpr = pOperatorInfo->pExpr;
2591
  SExprInfo* pExprInfo = &pExpr[0];
L
Liu Jicong 已提交
2592
  int32_t    functionId = getExprFunctionId(pExprInfo);
2593
#if 0
2594 2595 2596
  if (pQueryAttr->numOfOutput == 1 && functionId == FUNCTION_TS_COMP && pQueryAttr->stableQuery) {
    assert(pExprInfo->base.numOfParams == 1);

L
Liu Jicong 已提交
2597
    //    int16_t      tagColId = (int16_t)pExprInfo->base.param[0].i;
H
Haojun Liao 已提交
2598
    int16_t      tagColId = -1;
2599 2600 2601
    SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);

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

2603 2604 2605 2606 2607 2608 2609 2610 2611
  } else {
    // set tag value, by which the results are aggregated.
    int32_t offset = 0;
    memset(pRuntimeEnv->tagVal, 0, pQueryAttr->tagLen);

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

      // ts_comp column required the tag value for join filter
H
Haojun Liao 已提交
2612
      if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.pParam[0].pCol->flag)) {
2613 2614 2615 2616
        continue;
      }

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

L
Liu Jicong 已提交
2620 2621 2622
      if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resSchema.type) ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_BOOL ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_TIMESTAMP) {
2623 2624 2625 2626
        memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i, pLocalExprInfo->base.resSchema.bytes);
      } else {
        if (pCtx[idx].tag.pz != NULL) {
          memcpy(pRuntimeEnv->tagVal + offset, pCtx[idx].tag.pz, pCtx[idx].tag.nLen);
L
Liu Jicong 已提交
2627
        }
2628 2629 2630 2631 2632 2633 2634 2635 2636 2637
      }

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

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

H
Haojun Liao 已提交
2641
void copyToSDataBlock(SSDataBlock* pBlock, int32_t* offset, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pResBuf) {
2642 2643 2644 2645 2646 2647 2648
  pBlock->info.rows = 0;

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

L
Liu Jicong 已提交
2654
    //    doCopyToSDataBlock(pResBuf, pGroupResInfo, TSDB_ORDER_ASC, pBlock, );
2655 2656 2657 2658 2659 2660 2661 2662 2663 2664

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

    // enough results in data buffer, return
L
Liu Jicong 已提交
2665 2666 2667
    //    if (pBlock->info.rows >= threshold) {
    //      break;
    //    }
2668 2669 2670
  }
}

L
Liu Jicong 已提交
2671
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
2672 2673 2674 2675
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2676 2677
  //  TSWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY);
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
2678

L
Liu Jicong 已提交
2679 2680
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
2681 2682

  // set the index to be the end slot of result rows array
dengyihao's avatar
dengyihao 已提交
2683 2684 2685 2686 2687 2688
  //  SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->size > 0) {
  //    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  //  } else {
  //    pResultRowInfo->curPos = -1;
  //  }
2689 2690
}

H
Haojun Liao 已提交
2691
void initResultRow(SResultRow* pResultRow) {
2692 2693 2694 2695 2696 2697
  pResultRow->pEntryInfo = (struct SResultRowEntryInfo*)((char*)pResultRow + sizeof(SResultRow));
}

/*
 * The start of each column SResultRowEntryInfo is denote by RowCellInfoOffset.
 * Note that in case of top/bottom query, the whole multiple rows of result is treated as only one row of results.
H
Haojun Liao 已提交
2698 2699 2700
 * +------------+-----------------result column 1------------+------------------result column 2-----------+
 * | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2|
 * +------------+--------------------------------------------+--------------------------------------------+
2701 2702
 *           offset[0]                                  offset[1]                                   offset[2]
 */
2703
// TODO refactor: some function move away
H
Haojun Liao 已提交
2704
void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
2705 2706 2707
  SqlFunctionCtx* pCtx = pInfo->pCtx;
  SSDataBlock*    pDataBlock = pInfo->pRes;
  int32_t*        rowCellInfoOffset = pInfo->rowCellInfoOffset;
H
Haojun Liao 已提交
2708

H
Haojun Liao 已提交
2709
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
2710
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
2711

L
Liu Jicong 已提交
2712 2713
  int64_t     tid = 0;
  int64_t     groupId = 0;
2714
  SResultRow* pRow = doSetResultOutBufByKey(pSup->pResultBuf, pResultRowInfo, tid, (char*)&tid, sizeof(tid), true,
L
Liu Jicong 已提交
2715
                                               groupId, pTaskInfo, false, pSup);
H
Haojun Liao 已提交
2716 2717 2718 2719 2720

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

L
Liu Jicong 已提交
2721
    pCtx[i].resultInfo = pEntry;
H
Haojun Liao 已提交
2722 2723 2724
    pCtx[i].currentStage = stage;

    // set the timestamp output buffer for top/bottom/diff query
L
Liu Jicong 已提交
2725 2726
    //    int32_t fid = pCtx[i].functionId;
    //    if (fid == FUNCTION_TOP || fid == FUNCTION_BOTTOM || fid == FUNCTION_DIFF || fid == FUNCTION_DERIVATIVE) {
H
Haojun Liao 已提交
2727
    //      if (i > 0) pCtx[i].pTsOutput = pCtx[i-1].pOutput;
L
Liu Jicong 已提交
2728
    //    }
H
Haojun Liao 已提交
2729 2730 2731 2732 2733
  }

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

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

L
Liu Jicong 已提交
2737
  int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5;  // extra output buffer
2738
  if ((*bufCapacity) < newSize) {
L
Liu Jicong 已提交
2739 2740
    for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
2741

wafwerar's avatar
wafwerar 已提交
2742
      char* p = taosMemoryRealloc(pColInfo->pData, newSize * pColInfo->info.bytes);
2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755
      if (p != NULL) {
        pColInfo->pData = p;

        // it starts from the tail of the previously generated results.
        pBInfo->pCtx[i].pOutput = pColInfo->pData;
        (*bufCapacity) = newSize;
      } else {
        // longjmp
      }
    }
  }

  for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
L
Liu Jicong 已提交
2756
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
2757 2758 2759 2760 2761
    pBInfo->pCtx[i].pOutput = pColInfo->pData + pColInfo->info.bytes * pDataBlock->info.rows;

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

L
Liu Jicong 已提交
2762 2763
    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
        functionId == FUNCTION_DERIVATIVE) {
dengyihao's avatar
dengyihao 已提交
2764
      //      if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
2765 2766 2767 2768
    }
  }
}

H
Haojun Liao 已提交
2769
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
2770 2771
  bool    needCopyTs = false;
  int32_t tsNum = 0;
L
Liu Jicong 已提交
2772
  char*   src = NULL;
2773 2774 2775 2776
  for (int32_t i = 0; i < numOfOutput; i++) {
    int32_t functionId = pCtx[i].functionId;
    if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) {
      needCopyTs = true;
L
Liu Jicong 已提交
2777 2778
      if (i > 0 && pCtx[i - 1].functionId == FUNCTION_TS_DUMMY) {
        SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1);  // find ts data
2779 2780
        src = pColRes->pData;
      }
L
Liu Jicong 已提交
2781
    } else if (functionId == FUNCTION_TS_DUMMY) {
2782 2783 2784 2785 2786 2787 2788 2789 2790 2791
      tsNum++;
    }
  }

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

  for (int32_t i = 0; i < numOfOutput; i++) {
    int32_t functionId = pCtx[i].functionId;
L
Liu Jicong 已提交
2792
    if (functionId == FUNCTION_TS_DUMMY) {
2793 2794 2795 2796 2797 2798
      SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i);
      memcpy(pColRes->pData, src, pColRes->info.bytes * pRes->info.rows);
    }
  }
}

H
Haojun Liao 已提交
2799
void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size) {
2800 2801
  for (int32_t j = 0; j < size; ++j) {
    struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
dengyihao's avatar
dengyihao 已提交
2802 2803
    if (isRowEntryInitialized(pResInfo) || fmIsPseudoColumnFunc(pCtx[j].functionId) || pCtx[j].functionId == -1 ||
        fmIsScalarFunc(pCtx[j].functionId)) {
2804 2805 2806
      continue;
    }

H
Haojun Liao 已提交
2807
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
2808 2809 2810
  }
}

L
Liu Jicong 已提交
2811
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
2812
  if (status == TASK_NOT_COMPLETED) {
H
Haojun Liao 已提交
2813
    pTaskInfo->status = status;
2814 2815
  } else {
    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
2816
    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
2817
    pTaskInfo->status |= status;
2818 2819 2820
  }
}

2821
// todo merged with the build group result.
L
Liu Jicong 已提交
2822 2823
void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf,
                                   SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) {
2824 2825 2826
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
    SResultRowPosition* pPos = &pResultRowInfo->pPosition[i];

L
Liu Jicong 已提交
2827
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pageId);
2828
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset);
H
Haojun Liao 已提交
2829 2830

    // TODO ignore the close status anyway.
dengyihao's avatar
dengyihao 已提交
2831 2832 2833
    //    if (!isResultRowClosed(pRow)) {
    //      continue;
    //    }
2834

2835
    for (int32_t j = 0; j < numOfOutput; ++j) {
2836 2837
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);

H
Haojun Liao 已提交
2838
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
H
Haojun Liao 已提交
2839
      if (!isRowEntryInitialized(pResInfo)) {
2840 2841 2842
        continue;
      }

H
Haojun Liao 已提交
2843
      if (pCtx[j].fpSet.process) {  // TODO set the dummy function, to avoid the check for null ptr.
dengyihao's avatar
dengyihao 已提交
2844
                                    //        pCtx[j].fpSet.finalize(&pCtx[j]);
H
Haojun Liao 已提交
2845
      }
2846 2847 2848 2849

      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
2850
    }
2851 2852 2853

    releaseBufPage(pBuf, bufPage);
  }
2854 2855
}

2856
// todo merged with the build group result.
2857 2858 2859 2860 2861
void finalizeUpdatedResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf, SArray* pUpdateList,
                           int32_t* rowCellInfoOffset) {
  size_t num = taosArrayGetSize(pUpdateList);

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

2864 2865 2866
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pos.pageId);
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->pos.offset);
//
2867 2868
    for (int32_t j = 0; j < numOfOutput; ++j) {
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);
2869
//
2870
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
2871 2872 2873 2874 2875 2876 2877 2878 2879
//      if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
//        continue;
//      }
//
//      if (pCtx[j].fpSet.process) {  // TODO set the dummy function.
////        pCtx[j].fpSet.finalize(&pCtx[j]);
//        pResInfo->initialized = true;
//      }
//
2880 2881 2882 2883 2884 2885 2886 2887 2888
      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
    }

    releaseBufPage(pBuf, bufPage);
  }
}

L
Liu Jicong 已提交
2889 2890
STableQueryInfo* createTableQueryInfo(void* buf, bool groupbyColumn, STimeWindow win) {
  STableQueryInfo* pTableQueryInfo = buf;
2891 2892 2893
  pTableQueryInfo->lastKey = win.skey;

  // set more initial size of interval/groupby query
L
Liu Jicong 已提交
2894 2895
  //  if (/*QUERY_IS_INTERVAL_QUERY(pQueryAttr) || */groupbyColumn) {
  int32_t initialSize = 128;
dengyihao's avatar
dengyihao 已提交
2896 2897 2898 2899
  //  int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize);
  //  if (code != TSDB_CODE_SUCCESS) {
  //    return NULL;
  //  }
L
Liu Jicong 已提交
2900 2901
  //  } else { // in other aggregate query, do not initialize the windowResInfo
  //  }
2902 2903 2904 2905

  return pTableQueryInfo;
}

L
Liu Jicong 已提交
2906
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
2907 2908 2909 2910
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2911
  //  taosVariantDestroy(&pTableQueryInfo->tag);
dengyihao's avatar
dengyihao 已提交
2912
  //  cleanupResultRowInfo(&pTableQueryInfo->resInfo);
2913 2914
}

dengyihao's avatar
dengyihao 已提交
2915 2916
void setResultRowOutputBufInitCtx_rv(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput,
                                     int32_t* rowCellInfoOffset) {
2917 2918 2919 2920 2921 2922 2923
  for (int32_t i = 0; i < numOfOutput; ++i) {
    pCtx[i].resultInfo = getResultCell(pResult, i, rowCellInfoOffset);

    struct SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo;
    if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
      continue;
    }
2924 2925 2926 2927 2928

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

2929 2930 2931 2932 2933 2934
    if (!pResInfo->initialized) {
      if (pCtx[i].functionId != -1) {
        pCtx[i].fpSet.init(&pCtx[i], pResInfo);
      } else {
        pResInfo->initialized = true;
      }
2935 2936 2937 2938
    }
  }
}

2939 2940 2941 2942 2943 2944
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
  if (pFilterNode == NULL) {
    return;
  }

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

H
Haojun Liao 已提交
2946
  // todo move to the initialization function
H
Haojun Liao 已提交
2947
  int32_t code = filterInitFromNode((SNode*)pFilterNode, &filter, 0);
2948 2949 2950 2951 2952 2953

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

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

2956
  SSDataBlock* px = createOneDataBlock(pBlock, false);
2957 2958
  blockDataEnsureCapacity(px, pBlock->info.rows);

H
Haojun Liao 已提交
2959
  // todo extract method
2960 2961 2962 2963
  int32_t numOfRow = 0;
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
    SColumnInfoData* pDst = taosArrayGet(px->pDataBlock, i);
    SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, i);
D
dapan1121 已提交
2964 2965 2966 2967 2968 2969 2970 2971 2972
    if (keep) {
      colDataAssign(pDst, pSrc, pBlock->info.rows);
      numOfRow = pBlock->info.rows;
    } else if (NULL != rowRes) {
      numOfRow = 0;
      for (int32_t j = 0; j < pBlock->info.rows; ++j) {
        if (rowRes[j] == 0) {
          continue;
        }
2973

D
dapan1121 已提交
2974 2975 2976 2977 2978 2979
        if (colDataIsNull_s(pSrc, j)) {
          colDataAppendNULL(pDst, numOfRow);
        } else {
          colDataAppend(pDst, numOfRow, colDataGetData(pSrc, j), false);
        }
        numOfRow += 1;
H
Haojun Liao 已提交
2980
      }
D
dapan1121 已提交
2981 2982
    } else {
      numOfRow = 0;
2983 2984 2985 2986 2987 2988
    }

    *pSrc = *pDst;
  }

  pBlock->info.rows = numOfRow;
2989
  blockDataUpdateTsWindow(pBlock);
2990 2991
}

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

2997 2998
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
2999
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
3000

3001
  SResultRow* pResultRow =
3002
      doSetResultOutBufByKey(pAggInfo->aggSup.pResultBuf, pResultRowInfo, uid, (char*)&groupId, sizeof(groupId),
H
Haojun Liao 已提交
3003
                                true, groupId, pTaskInfo, false, &pAggInfo->aggSup);
L
Liu Jicong 已提交
3004
  assert(pResultRow != NULL);
3005 3006 3007 3008 3009 3010

  /*
   * not assign result buffer yet, add new result buffer
   * all group belong to one result set, and each group result has different group id so set the id to be one
   */
  if (pResultRow->pageId == -1) {
dengyihao's avatar
dengyihao 已提交
3011 3012
    int32_t ret =
        addNewWindowResultBuf(pResultRow, pAggInfo->aggSup.pResultBuf, groupId, pAggInfo->binfo.pRes->info.rowSize);
3013 3014 3015 3016 3017
    if (ret != TSDB_CODE_SUCCESS) {
      return;
    }
  }

H
Haojun Liao 已提交
3018
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
3019 3020
}

H
Haojun Liao 已提交
3021 3022
void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* pTaskInfo, SAggOperatorInfo* pAggInfo) {
  if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
3023 3024 3025
    return;
  }

H
Haojun Liao 已提交
3026
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, groupId, pTaskInfo);
3027 3028

  // record the current active group id
H
Haojun Liao 已提交
3029
  pAggInfo->groupId = groupId;
3030 3031 3032 3033 3034
}

/*
 * There are two cases to handle:
 *
L
Liu Jicong 已提交
3035 3036
 * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including
 * pQueryAttr->lastKey, pQueryAttr->window.skey, and pQueryAttr->eKey.
3037 3038 3039 3040
 * 2. Query range is set and query is in progress. There may be another result with the same query ranges to be
 *    merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there
 *    is a previous result generated or not.
 */
3041
void setIntervalQueryRange(STableQueryInfo* pTableQueryInfo, TSKEY key, STimeWindow* pQRange) {
dengyihao's avatar
dengyihao 已提交
3042 3043 3044 3045
  //  SResultRowInfo*  pResultRowInfo = &pTableQueryInfo->resInfo;
  //  if (pResultRowInfo->curPos != -1) {
  //    return;
  //  }
3046

dengyihao's avatar
dengyihao 已提交
3047 3048
  //  pTableQueryInfo->win.skey = key;
  //  STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
3049 3050 3051 3052 3053 3054 3055

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

L
Liu Jicong 已提交
3062 3063 3064 3065 3066 3067 3068
  //  if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
  //    if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
  //      assert(win.ekey == pQueryAttr->window.ekey);
  //    }
  //
  //    pResultRowInfo->prevSKey = w.skey;
  //  }
3069

L
Liu Jicong 已提交
3070
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080
}

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

  int32_t start = 0;
  int32_t step = -1;

L
Liu Jicong 已提交
3089
  // qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100
  assert(orderType == TSDB_ORDER_ASC || orderType == TSDB_ORDER_DESC);

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

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

3104
    SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
3105 3106 3107 3108 3109
    if (pRow->numOfRows == 0) {
      pGroupResInfo->index += 1;
      continue;
    }

3110
    // TODO copy multiple rows?
3111
    int32_t numOfRowsToCopy = pRow->numOfRows;
3112
    if (numOfResult + numOfRowsToCopy >= pBlock->info.capacity) {
3113 3114 3115 3116 3117 3118
      break;
    }

    pGroupResInfo->index += 1;

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

3121 3122
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
      if (pCtx[j].fpSet.process) {
3123
        pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
3124 3125
      } else {
        SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
3126

3127 3128 3129
        char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
        colDataAppend(pColInfoData, pBlock->info.rows, in, pCtx[j].resultInfo->isNullRes);
      }
3130 3131
    }

3132 3133
    releaseBufPage(pBuf, page);

3134 3135
    pBlock->info.rows += pRow->numOfRows;
    if (pBlock->info.rows >= pBlock->info.capacity) {  // output buffer is full
3136 3137 3138 3139
      break;
    }
  }

L
Liu Jicong 已提交
3140
  // qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
3141
  blockDataUpdateTsWindow(pBlock);
3142 3143 3144
  return 0;
}

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

3149
  blockDataCleanup(pBlock);
3150 3151 3152 3153
  if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
    return;
  }

3154
  int32_t orderType = TSDB_ORDER_ASC;
3155
  doCopyToSDataBlock(pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
3156

H
Haojun Liao 已提交
3157 3158
  // add condition (pBlock->info.rows >= 1) just to runtime happy
  blockDataUpdateTsWindow(pBlock);
3159 3160
}

L
Liu Jicong 已提交
3161 3162
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
                                        int32_t* rowCellInfoOffset) {
3163
  // update the number of result for each, only update the number of rows for the corresponding window result.
L
Liu Jicong 已提交
3164 3165 3166
  //  if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
  //    return;
  //  }
H
Haojun Liao 已提交
3167
#if 0
3168
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
L
Liu Jicong 已提交
3169
    SResultRow* pResult = pResultRowInfo->pResult[i];
3170 3171 3172 3173 3174 3175 3176

    for (int32_t j = 0; j < numOfOutput; ++j) {
      int32_t functionId = pCtx[j].functionId;
      if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
        continue;
      }

3177 3178
      SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
      pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
3179 3180
    }
  }
H
Haojun Liao 已提交
3181
#endif
3182 3183
}

L
Liu Jicong 已提交
3184
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
3185 3186
  int32_t colSize = pColRes->info.bytes * numOfRows;
  return (*(tDataTypes[pColRes->info.type].compFunc))(pColRes->pData, colSize, numOfRows, data,
L
Liu Jicong 已提交
3187
                                                      colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
3188 3189
}

L
Liu Jicong 已提交
3190 3191 3192 3193 3194
int32_t doFillTimeIntervalGapsInResults(struct SFillInfo* pFillInfo, SSDataBlock* pOutput, int32_t capacity, void** p) {
  //  for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
  //    SColumnInfoData* pColInfoData = taosArrayGet(pOutput->pDataBlock, i);
  //    p[i] = pColInfoData->pData + (pColInfoData->info.bytes * pOutput->info.rows);
  //  }
3195 3196 3197 3198 3199 3200 3201

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

  return pOutput->info.rows;
}

3202
void publishOperatorProfEvent(SOperatorInfo* pOperator, EQueryProfEventType eventType) {
3203 3204
  SQueryProfEvent event = {0};

L
Liu Jicong 已提交
3205 3206
  event.eventType = eventType;
  event.eventTime = taosGetTimestampUs();
3207
  event.operatorType = pOperator->operatorType;
dengyihao's avatar
dengyihao 已提交
3208 3209 3210
  //    if (pQInfo->summary.queryProfEvents) {
  //      taosArrayPush(pQInfo->summary.queryProfEvents, &event);
  //    }
3211 3212
}

L
Liu Jicong 已提交
3213
void publishQueryAbortEvent(SExecTaskInfo* pTaskInfo, int32_t code) {
3214 3215 3216 3217 3218
  SQueryProfEvent event;
  event.eventType = QUERY_PROF_QUERY_ABORT;
  event.eventTime = taosGetTimestampUs();
  event.abortCode = code;

3219 3220
  if (pTaskInfo->cost.queryProfEvents) {
    taosArrayPush(pTaskInfo->cost.queryProfEvents, &event);
3221 3222 3223
  }
}

L
Liu Jicong 已提交
3224
typedef struct {
3225 3226 3227 3228 3229 3230 3231
  uint8_t operatorType;
  int64_t beginTime;
  int64_t endTime;
  int64_t selfTime;
  int64_t descendantsTime;
} SOperatorStackItem;

L
Liu Jicong 已提交
3232 3233
static void doOperatorExecProfOnce(SOperatorStackItem* item, SQueryProfEvent* event, SArray* opStack,
                                   SHashObj* profResults) {
3234 3235 3236 3237 3238 3239 3240 3241
  item->endTime = event->eventTime;
  item->selfTime = (item->endTime - item->beginTime) - (item->descendantsTime);

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

L
Liu Jicong 已提交
3242
  uint8_t              operatorType = item->operatorType;
3243 3244 3245 3246 3247 3248 3249 3250 3251
  SOperatorProfResult* result = taosHashGet(profResults, &operatorType, sizeof(operatorType));
  if (result != NULL) {
    result->sumRunTimes++;
    result->sumSelfTime += item->selfTime;
  } else {
    SOperatorProfResult opResult;
    opResult.operatorType = operatorType;
    opResult.sumSelfTime = item->selfTime;
    opResult.sumRunTimes = 1;
L
Liu Jicong 已提交
3252
    taosHashPut(profResults, &(operatorType), sizeof(operatorType), &opResult, sizeof(opResult));
3253 3254 3255
  }
}

3256
void calculateOperatorProfResults(void) {
dengyihao's avatar
dengyihao 已提交
3257 3258 3259 3260 3261 3262 3263 3264 3265
  //  if (pQInfo->summary.queryProfEvents == NULL) {
  //    // qDebug("QInfo:0x%"PRIx64" query prof events array is null", pQInfo->qId);
  //    return;
  //  }
  //
  //  if (pQInfo->summary.operatorProfResults == NULL) {
  //    // qDebug("QInfo:0x%"PRIx64" operator prof results hash is null", pQInfo->qId);
  //    return;
  //  }
3266 3267 3268 3269 3270

  SArray* opStack = taosArrayInit(32, sizeof(SOperatorStackItem));
  if (opStack == NULL) {
    return;
  }
3271
#if 0
L
Liu Jicong 已提交
3272
  size_t    size = taosArrayGetSize(pQInfo->summary.queryProfEvents);
3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
  SHashObj* profResults = pQInfo->summary.operatorProfResults;

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

L
Liu Jicong 已提交
3298 3299
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
3300

L
Liu Jicong 已提交
3301 3302 3303
  //  uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
  //  hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
  //  pSummary->hashSize = hashSize;
3304 3305 3306 3307

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

L
Liu Jicong 已提交
3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327
  //  SResultRowPool* p = pTaskInfo->pool;
  //  if (p != NULL) {
  //    pSummary->winInfoSize = getResultRowPoolMemSize(p);
  //    pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
  //  } else {
  //    pSummary->winInfoSize = 0;
  //    pSummary->numOfTimeWindows = 0;
  //  }
  //
  //  calculateOperatorProfResults(pQInfo);

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

  if (pSummary->operatorProfResults) {
    SOperatorProfResult* opRes = taosHashIterate(pSummary->operatorProfResults, NULL);
    while (opRes != NULL) {
L
Liu Jicong 已提交
3332 3333
      // qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
      //             pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
3334 3335 3336 3337 3338
      opRes = taosHashIterate(pSummary->operatorProfResults, opRes);
    }
  }
}

L
Liu Jicong 已提交
3339 3340 3341
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
3342
//
L
Liu Jicong 已提交
3343
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3344
//
L
Liu Jicong 已提交
3345 3346 3347 3348
//   if (pQueryAttr->limit.offset == pBlockInfo->rows) {  // current block will ignore completed
//     pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQueryAttr) ? pBlockInfo->window.ekey + step :
//     pBlockInfo->window.skey + step; pQueryAttr->limit.offset = 0; return;
//   }
3349
//
L
Liu Jicong 已提交
3350 3351 3352 3353 3354
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
//   } else {
//     pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
//   }
3355
//
L
Liu Jicong 已提交
3356
//   assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
3357
//
L
Liu Jicong 已提交
3358 3359
//   SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//   SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3360
//
L
Liu Jicong 已提交
3361 3362
//   // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
//   TSKEY *keys = (TSKEY *) pColInfoData->pData;
3363
//
L
Liu Jicong 已提交
3364 3365 3366
//   // update the offset value
//   pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
//   pQueryAttr->limit.offset = 0;
3367
//
L
Liu Jicong 已提交
3368
//   int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
3369
//
L
Liu Jicong 已提交
3370 3371 3372 3373
//   //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d,
//   lastKey:%"PRId64, GET_TASKID(pRuntimeEnv),
//          pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey);
// }
3374

L
Liu Jicong 已提交
3375 3376
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
3377
//
L
Liu Jicong 已提交
3378 3379 3380
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
//     return;
//   }
3381
//
L
Liu Jicong 已提交
3382 3383
//   pQueryAttr->pos = 0;
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3384
//
L
Liu Jicong 已提交
3385 3386
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//   TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
3387
//
L
Liu Jicong 已提交
3388 3389 3390 3391 3392
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pTsdbReadHandle)) {
//     if (isTaskKilled(pRuntimeEnv->qinfo)) {
//       longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
//     }
3393
//
L
Liu Jicong 已提交
3394
//     tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
3395
//
L
Liu Jicong 已提交
3396 3397 3398 3399
//     if (pQueryAttr->limit.offset > blockInfo.rows) {
//       pQueryAttr->limit.offset -= blockInfo.rows;
//       pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? blockInfo.window.ekey : blockInfo.window.skey;
//       pTableQueryInfo->lastKey += step;
3400
//
L
Liu Jicong 已提交
3401 3402 3403 3404 3405 3406 3407
//       //qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_TASKID(pRuntimeEnv), blockInfo.rows,
//              pQuery->limit.offset);
//     } else {  // find the appropriated start position in current block
//       updateOffsetVal(pRuntimeEnv, &blockInfo);
//       break;
//     }
//   }
3408
//
L
Liu Jicong 已提交
3409 3410 3411 3412 3413 3414 3415 3416 3417
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
// }

// static TSKEY doSkipIntervalProcess(STaskRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo,
// STableQueryInfo* pTableQueryInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
3418
//
L
Liu Jicong 已提交
3419 3420 3421
//   assert(pQueryAttr->limit.offset == 0);
//   STimeWindow tw = *win;
//   getNextTimeWindow(pQueryAttr, &tw);
3422
//
L
Liu Jicong 已提交
3423 3424
//   if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
//       (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
3425
//
L
Liu Jicong 已提交
3426 3427 3428 3429
//     // load the data block and check data remaining in current data block
//     // TODO optimize performance
//     SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//     SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3430
//
L
Liu Jicong 已提交
3431 3432 3433 3434
//     tw = *win;
//     int32_t startPos =
//         getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
//     assert(startPos >= 0);
3435
//
L
Liu Jicong 已提交
3436 3437
//     // set the abort info
//     pQueryAttr->pos = startPos;
3438
//
L
Liu Jicong 已提交
3439 3440 3441 3442
//     // reset the query start timestamp
//     pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
//     pQueryAttr->window.skey = pTableQueryInfo->win.skey;
//     TSKEY key = pTableQueryInfo->win.skey;
3443
//
L
Liu Jicong 已提交
3444 3445
//     pWindowResInfo->prevSKey = tw.skey;
//     int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
3446
//
L
Liu Jicong 已提交
3447 3448
//     int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//     pRuntimeEnv->resultRowInfo.curIndex = index;  // restore the window index
3449
//
L
Liu Jicong 已提交
3450 3451 3452 3453
//     //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d,
//     lastKey:%" PRId64,
//            GET_TASKID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes,
//            pQueryAttr->current->lastKey);
3454
//
L
Liu Jicong 已提交
3455 3456 3457 3458 3459
//     return key;
//   } else {  // do nothing
//     pQueryAttr->window.skey      = tw.skey;
//     pWindowResInfo->prevSKey = tw.skey;
//     pTableQueryInfo->lastKey = tw.skey;
3460
//
L
Liu Jicong 已提交
3461 3462
//     return tw.skey;
//   }
3463
//
L
Liu Jicong 已提交
3464 3465 3466 3467 3468 3469 3470 3471 3472 3473
//   return true;
// }

// static bool skipTimeInterval(STaskRuntimeEnv *pRuntimeEnv, TSKEY* start) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     assert(*start <= pRuntimeEnv->current->lastKey);
//   } else {
//     assert(*start >= pRuntimeEnv->current->lastKey);
//   }
3474
//
L
Liu Jicong 已提交
3475 3476 3477 3478 3479
//   // if queried with value filter, do NOT forward query start position
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL ||
//   pRuntimeEnv->pFillInfo != NULL) {
//     return true;
//   }
3480
//
L
Liu Jicong 已提交
3481 3482 3483 3484 3485 3486 3487
//   /*
//    * 1. for interval without interpolation query we forward pQueryAttr->interval.interval at a time for
//    *    pQueryAttr->limit.offset times. Since hole exists, pQueryAttr->interval.interval*pQueryAttr->limit.offset
//    value is
//    *    not valid. otherwise, we only forward pQueryAttr->limit.offset number of points
//    */
//   assert(pRuntimeEnv->resultRowInfo.prevSKey == TSKEY_INITIAL_VAL);
3488
//
L
Liu Jicong 已提交
3489 3490
//   STimeWindow w = TSWINDOW_INITIALIZER;
//   bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
3491
//
L
Liu Jicong 已提交
3492 3493
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//   STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
3494
//
L
Liu Jicong 已提交
3495 3496 3497
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
//     tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
3498
//
L
Liu Jicong 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507
//     if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//       if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) {
//         getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.skey, blockInfo.window.skey, pQueryAttr->window.ekey,
//         &w); pWindowResInfo->prevSKey = w.skey;
//       }
//     } else {
//       getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.ekey, pQueryAttr->window.ekey, blockInfo.window.ekey, &w);
//       pWindowResInfo->prevSKey = w.skey;
//     }
3508
//
L
Liu Jicong 已提交
3509 3510
//     // the first time window
//     STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
3511
//
L
Liu Jicong 已提交
3512 3513
//     while (pQueryAttr->limit.offset > 0) {
//       STimeWindow tw = win;
3514
//
L
Liu Jicong 已提交
3515 3516 3517
//       if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
//         pQueryAttr->limit.offset -= 1;
//         pWindowResInfo->prevSKey = win.skey;
3518
//
L
Liu Jicong 已提交
3519 3520 3521 3522 3523 3524
//         // current time window is aligned with blockInfo.window.ekey
//         // restart it from next data block by set prevSKey to be TSKEY_INITIAL_VAL;
//         if ((win.ekey == blockInfo.window.ekey && ascQuery) || (win.ekey == blockInfo.window.skey && !ascQuery)) {
//           pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
//         }
//       }
3525
//
L
Liu Jicong 已提交
3526 3527 3528 3529
//       if (pQueryAttr->limit.offset == 0) {
//         *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//         return true;
//       }
3530
//
L
Liu Jicong 已提交
3531 3532
//       // current window does not ended in current data block, try next data block
//       getNextTimeWindow(pQueryAttr, &tw);
3533
//
L
Liu Jicong 已提交
3534 3535 3536 3537 3538 3539 3540 3541 3542
//       /*
//        * If the next time window still starts from current data block,
//        * load the primary timestamp column first, and then find the start position for the next queried time window.
//        * Note that only the primary timestamp column is required.
//        * TODO: Optimize for this cases. All data blocks are not needed to be loaded, only if the first actually
//        required
//        * time window resides in current data block.
//        */
//       if ((tw.skey <= blockInfo.window.ekey && ascQuery) || (tw.ekey >= blockInfo.window.skey && !ascQuery)) {
3543
//
L
Liu Jicong 已提交
3544 3545
//         SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//         SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3546
//
L
Liu Jicong 已提交
3547 3548 3549
//         if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
//           pQueryAttr->limit.offset -= 1;
//         }
3550
//
L
Liu Jicong 已提交
3551 3552 3553 3554 3555 3556 3557 3558
//         if (pQueryAttr->limit.offset == 0) {
//           *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//           return true;
//         } else {
//           tw = win;
//           int32_t startPos =
//               getNextQualifiedWindow(pQueryAttr, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1);
//           assert(startPos >= 0);
3559
//
L
Liu Jicong 已提交
3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570
//           // set the abort info
//           pQueryAttr->pos = startPos;
//           pTableQueryInfo->lastKey = ((TSKEY *)pColInfoData->pData)[startPos];
//           pWindowResInfo->prevSKey = tw.skey;
//           win = tw;
//         }
//       } else {
//         break;  // offset is not 0, and next time window begins or ends in the next block.
//       }
//     }
//   }
3571
//
L
Liu Jicong 已提交
3572 3573 3574 3575
//   // check for error
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
3576
//
L
Liu Jicong 已提交
3577 3578
//   return true;
// }
3579

3580
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
H
Haojun Liao 已提交
3581
  if (p->pDownstream == NULL) {
H
Haojun Liao 已提交
3582
    assert(p->numOfDownstream == 0);
3583 3584
  }

wafwerar's avatar
wafwerar 已提交
3585
  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
3586 3587 3588 3589 3590 3591 3592
  if (p->pDownstream == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
3593 3594 3595 3596
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);

3597
static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) {
H
Haojun Liao 已提交
3598 3599
#if 0
    if (order == TSDB_ORDER_ASC) {
3600 3601
    assert(
        (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
3602 3603
        (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey));
3604 3605 3606
  } else {
    assert(
        (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
3607 3608
        (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey));
3609
  }
H
Haojun Liao 已提交
3610
#endif
3611 3612
}

3613 3614
// SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
//   SQueryTableDataCond cond = {
L
Liu Jicong 已提交
3615 3616 3617 3618 3619 3620
//       .colList   = pQueryAttr->tableCols,
//       .order     = pQueryAttr->order.order,
//       .numOfCols = pQueryAttr->numOfCols,
//       .type      = BLOCK_LOAD_OFFSET_SEQ_ORDER,
//       .loadExternalRows = false,
//   };
3621
//
L
Liu Jicong 已提交
3622 3623 3624
//   TIME_WINDOW_COPY(cond.twindow, *win);
//   return cond;
// }
3625 3626 3627

static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo) {
  STableIdInfo tidInfo;
L
Liu Jicong 已提交
3628 3629 3630 3631 3632
  //  STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
  //
  //  tidInfo.uid = id->uid;
  //  tidInfo.tid = id->tid;
  //  tidInfo.key = pTableQueryInfo->lastKey;
3633 3634 3635 3636

  return tidInfo;
}

L
Liu Jicong 已提交
3637 3638 3639 3640
// static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBlock, SHashObj* pTableIdInfo, int32_t
// order) {
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
//   pTableQueryInfo->lastKey = ((order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey) + step;
3641
//
L
Liu Jicong 已提交
3642 3643 3644
//   if (pTableQueryInfo->pTable == NULL) {
//     return;
//   }
3645
//
L
Liu Jicong 已提交
3646 3647 3648 3649 3650 3651 3652 3653 3654
//   STableIdInfo tidInfo = createTableIdInfo(pTableQueryInfo);
//   STableIdInfo *idinfo = taosHashGet(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid));
//   if (idinfo != NULL) {
//     assert(idinfo->tid == tidInfo.tid && idinfo->uid == tidInfo.uid);
//     idinfo->key = tidInfo.key;
//   } else {
//     taosHashPut(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid), &tidInfo, sizeof(STableIdInfo));
//   }
// }
3655

3656
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
L
Liu Jicong 已提交
3657
  SSourceDataInfo* pSourceDataInfo = (SSourceDataInfo*)param;
H
Haojun Liao 已提交
3658 3659
  if (code == TSDB_CODE_SUCCESS) {
    pSourceDataInfo->pRsp = pMsg->pData;
3660

H
Haojun Liao 已提交
3661 3662
    SRetrieveTableRsp* pRsp = pSourceDataInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
dengyihao's avatar
dengyihao 已提交
3663 3664
    pRsp->compLen = htonl(pRsp->compLen);
    pRsp->useconds = htobe64(pRsp->useconds);
H
Haojun Liao 已提交
3665 3666 3667
  } else {
    pSourceDataInfo->code = code;
  }
H
Haojun Liao 已提交
3668

H
Haojun Liao 已提交
3669
  pSourceDataInfo->status = EX_SOURCE_DATA_READY;
3670
  tsem_post(&pSourceDataInfo->pEx->ready);
wmmhello's avatar
wmmhello 已提交
3671
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
3672 3673 3674 3675
}

static void destroySendMsgInfo(SMsgSendInfo* pMsgBody) {
  assert(pMsgBody != NULL);
wafwerar's avatar
wafwerar 已提交
3676 3677
  taosMemoryFreeClear(pMsgBody->msgInfo.pData);
  taosMemoryFreeClear(pMsgBody);
H
Haojun Liao 已提交
3678 3679
}

S
Shengliang Guan 已提交
3680
void qProcessFetchRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
L
Liu Jicong 已提交
3681
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->ahandle;
H
Haojun Liao 已提交
3682 3683 3684 3685 3686
  assert(pMsg->ahandle != NULL);

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

  if (pMsg->contLen > 0) {
wafwerar's avatar
wafwerar 已提交
3687
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
H
Haojun Liao 已提交
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698
    if (buf.pData == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      pMsg->code = TSDB_CODE_OUT_OF_MEMORY;
    } else {
      memcpy(buf.pData, pMsg->pCont, pMsg->contLen);
    }
  }

  pSendInfo->fp(pSendInfo->param, &buf, pMsg->code);
  rpcFreeCont(pMsg->pCont);
  destroySendMsgInfo(pSendInfo);
3699 3700
}

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

wafwerar's avatar
wafwerar 已提交
3704
  SResFetchReq* pMsg = taosMemoryCalloc(1, sizeof(SResFetchReq));
3705 3706 3707 3708
  if (NULL == pMsg) {
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
  }
3709

L
Liu Jicong 已提交
3710 3711
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
3712

L
Liu Jicong 已提交
3713 3714
  qDebug("%s build fetch msg and send to vgId:%d, ep:%s, taskId:0x%" PRIx64 ", %d/%" PRIzu, GET_TASKID(pTaskInfo),
         pSource->addr.nodeId, pSource->addr.epSet.eps[0].fqdn, pSource->taskId, sourceIndex, totalSources);
3715 3716 3717 3718 3719 3720 3721

  pMsg->header.vgId = htonl(pSource->addr.nodeId);
  pMsg->sId = htobe64(pSource->schedId);
  pMsg->taskId = htobe64(pSource->taskId);
  pMsg->queryId = htobe64(pTaskInfo->id.queryId);

  // send the fetch remote task result reques
wafwerar's avatar
wafwerar 已提交
3722
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
3723
  if (NULL == pMsgSendInfo) {
wafwerar's avatar
wafwerar 已提交
3724
    taosMemoryFreeClear(pMsg);
3725 3726 3727
    qError("%s prepare message %d failed", GET_TASKID(pTaskInfo), (int32_t)sizeof(SMsgSendInfo));
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
H
Haojun Liao 已提交
3728 3729
  }

3730 3731 3732 3733 3734
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
3735

3736
  int64_t transporterId = 0;
L
Liu Jicong 已提交
3737
  int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
3738 3739 3740
  return TSDB_CODE_SUCCESS;
}

3741 3742
// 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 已提交
3743 3744
                                  int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
                                  SArray* pColList) {
H
Haojun Liao 已提交
3745
  blockDataEnsureCapacity(pRes, numOfRows);
3746

H
Haojun Liao 已提交
3747
  if (pColList == NULL) {  // data from other sources
3748 3749 3750 3751 3752 3753
    int32_t dataLen = *(int32_t*) pData;
    pData += sizeof(int32_t);

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

H
Haojun Liao 已提交
3754 3755
    int32_t* colLen = (int32_t*)pData;

3756
    char* pStart = pData + sizeof(int32_t) * numOfOutput;
3757
    for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
3758 3759 3760
      colLen[i] = htonl(colLen[i]);
      ASSERT(colLen[i] > 0);

3761
      SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
H
Haojun Liao 已提交
3762 3763 3764
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
        pColInfoData->varmeta.length = colLen[i];
        pColInfoData->varmeta.allocLen = colLen[i];
3765

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

wafwerar's avatar
wafwerar 已提交
3769
        pColInfoData->pData = taosMemoryMalloc(colLen[i]);
H
Haojun Liao 已提交
3770 3771 3772
      } else {
        memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
        pStart += BitmapLen(numOfRows);
3773
      }
H
Haojun Liao 已提交
3774 3775

      memcpy(pColInfoData->pData, pStart, colLen[i]);
3776 3777 3778
      //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 已提交
3779
      pStart += colLen[i];
3780
    }
H
Haojun Liao 已提交
3781
  } else {  // extract data according to pColList
3782
    ASSERT(numOfOutput == taosArrayGetSize(pColList));
3783 3784 3785 3786 3787 3788
    char* pStart = pData;

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

    SSysTableSchema* pSchema = (SSysTableSchema*)pStart;
dengyihao's avatar
dengyihao 已提交
3789
    for (int32_t i = 0; i < numOfCols; ++i) {
3790 3791 3792 3793 3794 3795 3796 3797
      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 已提交
3798
    for (int32_t i = 0; i < numOfCols; ++i) {
3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811
      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);

3812 3813 3814 3815 3816
    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);
3817 3818 3819 3820
    pStart += sizeof(int32_t) * numOfCols;

    for (int32_t i = 0; i < numOfCols; ++i) {
      colLen[i] = htonl(colLen[i]);
3821
      ASSERT(colLen[i] >= 0);
3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839

      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 已提交
3840 3841

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

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

3848 3849
        if (colIndex - 1 == i) {
          SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, j);
3850
          colDataAssign(pColInfoData, pSrc, numOfRows);
3851 3852 3853
          break;
        }
      }
3854
    }
3855
  }
3856

H
Haojun Liao 已提交
3857
  pRes->info.rows = numOfRows;
3858
  blockDataUpdateTsWindow(pRes);
3859

3860
  int64_t el = taosGetTimestampUs() - startTs;
3861

H
Haojun Liao 已提交
3862 3863
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
3864

H
Haojun Liao 已提交
3865 3866 3867
  if (total != NULL) {
    *total += numOfRows;
  }
3868

H
Haojun Liao 已提交
3869
  pLoadInfo->totalElapsed += el;
3870 3871
  return TSDB_CODE_SUCCESS;
}
3872

L
Liu Jicong 已提交
3873 3874
static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
3875
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3876

L
Liu Jicong 已提交
3877
  int64_t              el = taosGetTimestampUs() - startTs;
H
Haojun Liao 已提交
3878 3879
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
  pLoadInfo->totalElapsed += el;
H
Haojun Liao 已提交
3880

3881
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
L
Liu Jicong 已提交
3882 3883 3884
  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);
3885 3886 3887 3888 3889

  doSetOperatorCompleted(pOperator);
  return NULL;
}

L
Liu Jicong 已提交
3890 3891
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
                                                   SExecTaskInfo* pTaskInfo) {
3892 3893 3894 3895 3896 3897 3898 3899 3900
  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);

3901
      if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
3902
        completed += 1;
H
Haojun Liao 已提交
3903 3904
        continue;
      }
3905

3906
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
3907 3908 3909
        continue;
      }

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

L
Liu Jicong 已提交
3913
      SSDataBlock*         pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
3914
      SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
3915
      if (pRsp->numOfRows == 0) {
L
Liu Jicong 已提交
3916 3917
        qDebug("%s vgId:%d, taskID:0x%" PRIx64 " index:%d completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
               " try next",
3918
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, i + 1, pDataInfo->totalRows,
H
Haojun Liao 已提交
3919
               pExchangeInfo->loadInfo.totalRows);
3920
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3921 3922 3923
        completed += 1;
        continue;
      }
H
Haojun Liao 已提交
3924

H
Haojun Liao 已提交
3925
      SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
3926 3927 3928
      code =
          setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                    pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
3929
      if (code != 0) {
3930 3931 3932
        goto _error;
      }

3933 3934 3935
      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 已提交
3936 3937
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
               pLoadInfo->totalRows, pLoadInfo->totalSize, i + 1, totalSources);
3938
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
3939
      } else {
dengyihao's avatar
dengyihao 已提交
3940 3941
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64
               ", totalBytes:%" PRIu64,
H
Haojun Liao 已提交
3942 3943
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
               pLoadInfo->totalSize);
3944 3945
      }

3946 3947
      if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED) {
        pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966
        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 已提交
3967 3968 3969
static SSDataBlock* concurrentlyLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
3970

H
Haojun Liao 已提交
3971 3972 3973
  if (pOperator->status == OP_RES_TO_RETURN) {
    return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
  }
3974

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

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

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

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
3991 3992
  pOperator->status = OP_RES_TO_RETURN;
  return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
3993 3994
}

L
Liu Jicong 已提交
3995 3996 3997
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
3998

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

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
4003
  for (int32_t i = 0; i < totalSources; ++i) {
4004 4005
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4006 4007
      pTaskInfo->code = code;
      return code;
4008 4009 4010 4011
    }
  }

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

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

H
Haojun Liao 已提交
4018
  return TSDB_CODE_SUCCESS;
4019 4020
}

L
Liu Jicong 已提交
4021 4022 4023
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4024

L
Liu Jicong 已提交
4025
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4026
  int64_t startTs = taosGetTimestampUs();
4027

L
Liu Jicong 已提交
4028
  while (1) {
4029 4030
    if (pExchangeInfo->current >= totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
4031
    }
4032

4033 4034 4035
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

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

H
Haojun Liao 已提交
4039
    if (pDataInfo->code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
dengyihao 已提交
4040 4041
      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 已提交
4042 4043 4044 4045
      pOperator->pTaskInfo->code = pDataInfo->code;
      return NULL;
    }

L
Liu Jicong 已提交
4046
    SRetrieveTableRsp*   pRsp = pDataInfo->pRsp;
H
Haojun Liao 已提交
4047
    SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
4048
    if (pRsp->numOfRows == 0) {
dengyihao's avatar
dengyihao 已提交
4049 4050
      qDebug("%s vgId:%d, taskID:0x%" PRIx64 " %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
             " try next",
4051
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
H
Haojun Liao 已提交
4052
             pDataInfo->totalRows, pLoadInfo->totalRows);
H
Haojun Liao 已提交
4053

4054
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4055 4056 4057
      pExchangeInfo->current += 1;
      continue;
    }
H
Haojun Liao 已提交
4058

L
Liu Jicong 已提交
4059
    SSDataBlock*       pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
4060
    SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
4061 4062 4063
    int32_t            code =
        setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                  pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
4064 4065

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

4071
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4072 4073
      pExchangeInfo->current += 1;
    } else {
L
Liu Jicong 已提交
4074 4075 4076 4077
      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);
4078 4079 4080 4081
    }

    return pExchangeInfo->pResult;
  }
4082 4083
}

L
Liu Jicong 已提交
4084
static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
4085
  if (OPTR_IS_OPENED(pOperator)) {
H
Haojun Liao 已提交
4086 4087 4088
    return TSDB_CODE_SUCCESS;
  }

L
Liu Jicong 已提交
4089
  SExchangeInfo* pExchangeInfo = pOperator->info;
H
Haojun Liao 已提交
4090 4091 4092 4093 4094 4095 4096 4097 4098
  if (pExchangeInfo->seqLoadData) {
    // do nothing for sequentially load data
  } else {
    int32_t code = prepareConcurrentlyLoad(pOperator);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

4099
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
4100 4101 4102
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4103 4104 4105
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4106

4107
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
4108
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4109 4110
    return NULL;
  }
4111

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

4115
  if (pOperator->status == OP_EXEC_DONE) {
L
Liu Jicong 已提交
4116 4117 4118
    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);
4119 4120 4121 4122
    return NULL;
  }

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

4124 4125 4126
  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
4127
    return concurrentlyLoadRemoteData(pOperator);
4128
  }
H
Haojun Liao 已提交
4129

4130
#if 0
H
Haojun Liao 已提交
4131
  _error:
wafwerar's avatar
wafwerar 已提交
4132 4133
  taosMemoryFreeClear(pMsg);
  taosMemoryFreeClear(pMsgSendInfo);
H
Haojun Liao 已提交
4134 4135 4136

  terrno = pTaskInfo->code;
  return NULL;
4137
#endif
H
Haojun Liao 已提交
4138
}
4139

H
Haojun Liao 已提交
4140
static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
4141
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
H
Haojun Liao 已提交
4142 4143
  if (pInfo->pSourceDataInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
4144 4145
  }

L
Liu Jicong 已提交
4146
  for (int32_t i = 0; i < numOfSources; ++i) {
4147
    SSourceDataInfo dataInfo = {0};
H
Haojun Liao 已提交
4148
    dataInfo.status = EX_SOURCE_DATA_NOT_READY;
L
Liu Jicong 已提交
4149 4150
    dataInfo.pEx = pInfo;
    dataInfo.index = i;
4151

H
Haojun Liao 已提交
4152 4153 4154 4155 4156 4157 4158 4159 4160 4161
    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 已提交
4162
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
4163
  SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
wafwerar's avatar
wafwerar 已提交
4164
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4165 4166

  if (pInfo == NULL || pOperator == NULL) {
wafwerar's avatar
wafwerar 已提交
4167 4168
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4169 4170
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
H
Haojun Liao 已提交
4171 4172
  }

H
Haojun Liao 已提交
4173
  size_t numOfSources = LIST_LENGTH(pSources);
H
Haojun Liao 已提交
4174
  pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
H
Haojun Liao 已提交
4175 4176 4177
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
  if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
    goto _error;
H
Haojun Liao 已提交
4178 4179
  }

L
Liu Jicong 已提交
4180 4181
  for (int32_t i = 0; i < numOfSources; ++i) {
    SNodeListNode* pNode = nodesListGetNode((SNodeList*)pSources, i);
H
Haojun Liao 已提交
4182 4183
    taosArrayPush(pInfo->pSources, pNode);
  }
4184

H
Haojun Liao 已提交
4185 4186 4187
  int32_t code = initDataSource(numOfSources, pInfo);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4188
  }
H
Haojun Liao 已提交
4189

dengyihao's avatar
dengyihao 已提交
4190
  pInfo->pResult = pBlock;
4191 4192 4193
  pInfo->seqLoadData = true;

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

dengyihao's avatar
dengyihao 已提交
4195
  pOperator->name = "ExchangeOperator";
X
Xiaoyu Wang 已提交
4196
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
4197
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
4198 4199 4200 4201
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = pBlock->info.numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
4202 4203 4204

  pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL, destroyExchangeOperatorInfo,
                                         NULL, NULL, NULL);
4205

S
Shengliang Guan 已提交
4206
#if 1
L
Liu Jicong 已提交
4207
  {  // todo refactor
H
Haojun Liao 已提交
4208 4209 4210
    SRpcInit rpcInit;
    memset(&rpcInit, 0, sizeof(rpcInit));
    rpcInit.localPort = 0;
H
Haojun Liao 已提交
4211
    rpcInit.label = "EX";
H
Haojun Liao 已提交
4212
    rpcInit.numOfThreads = 1;
S
Shengliang Guan 已提交
4213
    rpcInit.cfp = qProcessFetchRsp;
S
Shengliang Guan 已提交
4214
    rpcInit.sessions = tsMaxConnections;
H
Haojun Liao 已提交
4215
    rpcInit.connType = TAOS_CONN_CLIENT;
L
Liu Jicong 已提交
4216
    rpcInit.user = (char*)"root";
S
Shengliang Guan 已提交
4217
    rpcInit.idleTime = tsShellActivityTimer * 1000;
H
Haojun Liao 已提交
4218
    rpcInit.ckey = "key";
S
Shengliang Guan 已提交
4219
    rpcInit.spi = 1;
L
Liu Jicong 已提交
4220
    rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
H
Haojun Liao 已提交
4221 4222 4223

    pInfo->pTransporter = rpcOpen(&rpcInit);
    if (pInfo->pTransporter == NULL) {
L
Liu Jicong 已提交
4224
      return NULL;  // todo
H
Haojun Liao 已提交
4225 4226
    }
  }
S
Shengliang 已提交
4227
#endif
4228

4229
  return pOperator;
H
Haojun Liao 已提交
4230

L
Liu Jicong 已提交
4231
_error:
H
Haojun Liao 已提交
4232
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4233
    destroyExchangeOperatorInfo(pInfo, numOfSources);
H
Haojun Liao 已提交
4234 4235
  }

wafwerar's avatar
wafwerar 已提交
4236 4237
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4238
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
4239
  return NULL;
4240 4241
}

dengyihao's avatar
dengyihao 已提交
4242 4243
static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                                const char* pKey);
H
Haojun Liao 已提交
4244
static void    cleanupAggSup(SAggSupporter* pAggSup);
4245

4246
static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4247
  SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*)param;
H
Haojun Liao 已提交
4248
  taosArrayDestroy(pInfo->pSortInfo);
4249 4250 4251
  taosArrayDestroy(pInfo->groupInfo);

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
4252
    tsortDestroySortHandle(pInfo->pSortHandle);
4253 4254
  }

H
Haojun Liao 已提交
4255
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
4256
  cleanupAggSup(&pInfo->aggSup);
4257
}
H
Haojun Liao 已提交
4258

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

X
Xiaoyu Wang 已提交
4262
  *dst = *src;
4263

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

L
Liu Jicong 已提交
4268 4269 4270 4271
  //  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 已提交
4272
}
4273

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

H
Haojun Liao 已提交
4279
    bool isNull = tsortIsNullVal(pTupleHandle, i);
H
Haojun Liao 已提交
4280 4281 4282
    if (isNull) {
      colDataAppend(pColInfo, pBlock->info.rows, NULL, true);
    } else {
H
Haojun Liao 已提交
4283
      char* pData = tsortGetValue(pTupleHandle, i);
H
Haojun Liao 已提交
4284 4285
      colDataAppend(pColInfo, pBlock->info.rows, pData, false);
    }
4286 4287
  }

4288 4289
  pBlock->info.rows += 1;
}
4290

H
Haojun Liao 已提交
4291
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity) {
4292
  blockDataCleanup(pDataBlock);
D
dapan1121 已提交
4293
  blockDataEnsureCapacity(pDataBlock, capacity);
4294

wmmhello's avatar
wmmhello 已提交
4295 4296
  blockDataEnsureCapacity(pDataBlock, capacity);

L
Liu Jicong 已提交
4297
  while (1) {
H
Haojun Liao 已提交
4298
    STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4299 4300 4301
    if (pTupleHandle == NULL) {
      break;
    }
4302

4303 4304 4305
    appendOneRowToDataBlock(pDataBlock, pTupleHandle);
    if (pDataBlock->info.rows >= capacity) {
      return pDataBlock;
H
Haojun Liao 已提交
4306 4307
    }
  }
4308

L
Liu Jicong 已提交
4309
  return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
4310
}
4311

4312
SSDataBlock* loadNextDataBlock(void* param) {
L
Liu Jicong 已提交
4313 4314
  SOperatorInfo* pOperator = (SOperatorInfo*)param;
  bool           newgroup = false;
4315
  return pOperator->fpSet.getNextFn(pOperator, &newgroup);
4316 4317
}

L
Liu Jicong 已提交
4318
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
4319 4320 4321 4322
  size_t size = taosArrayGetSize(groupInfo);
  if (size == 0) {
    return true;
  }
4323

4324 4325
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
4326

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

4330 4331 4332
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
4333

4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346
    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;
      }
4347 4348 4349
    }
  }

4350
  return 0;
4351 4352
}

L
Liu Jicong 已提交
4353 4354 4355
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
4356
    pCtx[j].startRow = rowIndex;
4357 4358
  }

4359 4360
  for (int32_t j = 0; j < numOfExpr; ++j) {
    int32_t functionId = pCtx[j].functionId;
L
Liu Jicong 已提交
4361 4362 4363 4364 4365 4366 4367 4368 4369
    //    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]);
    //    }
4370
  }
4371
}
4372

L
Liu Jicong 已提交
4373 4374
static void doFinalizeResultImpl(SqlFunctionCtx* pCtx, int32_t numOfExpr) {
  for (int32_t j = 0; j < numOfExpr; ++j) {
4375 4376 4377 4378
    int32_t functionId = pCtx[j].functionId;
    //    if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
    //      continue;
    //    }
4379

4380 4381 4382 4383
    //    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 已提交
4384
    //    pCtx[j].fpSet.finalize(&pCtx[j]);
4385 4386
  }
}
4387

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

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

4395 4396 4397
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
4398

4399 4400
  return true;
}
4401

4402 4403
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
4404

4405
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
L
Liu Jicong 已提交
4406
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
4407 4408
    pCtx[i].size = 1;
  }
4409

L
Liu Jicong 已提交
4410
  for (int32_t i = 0; i < pBlock->info.rows; ++i) {
4411 4412 4413 4414 4415 4416 4417 4418 4419
    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 已提交
4420
        int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4421
        //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4422

4423
        // TODO check for available buffer;
H
Haojun Liao 已提交
4424

4425 4426 4427 4428 4429
        // next group info data
        pInfo->binfo.pRes->info.rows += numOfRows;
        for (int32_t j = 0; j < numOfExpr; ++j) {
          if (pCtx[j].functionId < 0) {
            continue;
4430
          }
4431

H
Haojun Liao 已提交
4432
          pCtx[j].fpSet.process(&pCtx[j]);
4433
        }
4434 4435 4436

        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
        pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
H
Haojun Liao 已提交
4437
      }
4438 4439 4440 4441
    }
  }
}

4442 4443
static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
4444
  SSortHandle*              pHandle = pInfo->pSortHandle;
4445

4446
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes, false);
4447
  blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
4448

L
Liu Jicong 已提交
4449
  while (1) {
4450
    blockDataCleanup(pDataBlock);
4451
    while (1) {
H
Haojun Liao 已提交
4452
      STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4453 4454
      if (pTupleHandle == NULL) {
        break;
4455
      }
4456

4457 4458
      // build datablock for merge for one group
      appendOneRowToDataBlock(pDataBlock, pTupleHandle);
4459
      if (pDataBlock->info.rows >= pOperator->resultInfo.capacity) {
4460 4461
        break;
      }
4462
    }
4463

4464 4465 4466
    if (pDataBlock->info.rows == 0) {
      break;
    }
4467

4468
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, true);
L
Liu Jicong 已提交
4469 4470
    //  updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
    //  pOperator->pRuntimeEnv, true);
4471 4472 4473
    doMergeImpl(pOperator, pOperator->numOfOutput, pDataBlock);
    // flush to tuple store, and after all data have been handled, return to upstream node or sink node
  }
4474

4475
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
4476
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4477
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4478

4479
  // TODO check for available buffer;
4480

4481 4482
  // next group info data
  pInfo->binfo.pRes->info.rows += numOfRows;
L
Liu Jicong 已提交
4483
  return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
4484
}
4485

L
Liu Jicong 已提交
4486
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator, bool* newgroup) {
4487 4488
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
4489 4490
  }

L
Liu Jicong 已提交
4491
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
4492
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
4493
  if (pOperator->status == OP_RES_TO_RETURN) {
4494
    return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity);
4495 4496
  }

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

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

L
Liu Jicong 已提交
4503
  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
wmmhello's avatar
wmmhello 已提交
4504
    SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
H
Haojun Liao 已提交
4505
    ps->param = pOperator->pDownstream[i];
H
Haojun Liao 已提交
4506
    tsortAddSource(pInfo->pSortHandle, ps);
4507 4508
  }

H
Haojun Liao 已提交
4509
  int32_t code = tsortOpen(pInfo->pSortHandle);
4510
  if (code != TSDB_CODE_SUCCESS) {
4511
    longjmp(pTaskInfo->env, terrno);
4512 4513
  }

H
Haojun Liao 已提交
4514
  pOperator->status = OP_RES_TO_RETURN;
4515
  return doMerge(pOperator);
4516
}
4517

L
Liu Jicong 已提交
4518 4519
static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo,
                            SSortedMergeOperatorInfo* pInfo) {
4520 4521
  if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) {
    return 0;
H
Haojun Liao 已提交
4522 4523
  }

4524 4525 4526 4527 4528 4529 4530 4531
  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 已提交
4532 4533
  size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo);
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4534
    SColumn* pCol = taosArrayGet(pGroupInfo, i);
L
Liu Jicong 已提交
4535
    for (int32_t j = 0; j < numOfCols; ++j) {
H
Haojun Liao 已提交
4536
      SExprInfo* pe = &pExprInfo[j];
4537
      if (pe->base.resSchema.slotId == pCol->colId) {
4538 4539
        taosArrayPush(plist, pCol);
        taosArrayPush(pInfo->groupInfo, &j);
H
Haojun Liao 已提交
4540
        len += pCol->bytes;
4541 4542
        break;
      }
H
Haojun Liao 已提交
4543 4544 4545
    }
  }

4546
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
4547

wafwerar's avatar
wafwerar 已提交
4548
  pInfo->groupVal = taosMemoryCalloc(1, (POINTER_BYTES * numOfGroupCol + len));
4549 4550 4551 4552
  if (pInfo->groupVal == NULL) {
    taosArrayDestroy(plist);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
4553

4554
  int32_t offset = 0;
L
Liu Jicong 已提交
4555 4556
  char*   start = (char*)(pInfo->groupVal + (POINTER_BYTES * numOfGroupCol));
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4557 4558
    pInfo->groupVal[i] = start + offset;
    SColumn* pCol = taosArrayGet(plist, i);
H
Haojun Liao 已提交
4559
    offset += pCol->bytes;
4560
  }
H
Haojun Liao 已提交
4561

4562
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
4563

4564 4565
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
4566

L
Liu Jicong 已提交
4567 4568 4569
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                             int32_t num, SArray* pSortInfo, SArray* pGroupInfo,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4570
  SSortedMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortedMergeOperatorInfo));
L
Liu Jicong 已提交
4571
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
4572
  if (pInfo == NULL || pOperator == NULL) {
4573
    goto _error;
4574
  }
H
Haojun Liao 已提交
4575

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

4579 4580 4581
  if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
4582

dengyihao's avatar
dengyihao 已提交
4583
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
4584
  int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, keyBufSize, pTaskInfo->id.str);
4585 4586 4587
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4588

H
Haojun Liao 已提交
4589
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
H
Haojun Liao 已提交
4590
  code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo);
4591 4592 4593
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4594

L
Liu Jicong 已提交
4595 4596 4597 4598 4599
  //  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 已提交
4600

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

L
Liu Jicong 已提交
4603
  pOperator->name = "SortedMerge";
X
Xiaoyu Wang 已提交
4604
  // pOperator->operatorType = OP_SortedMerge;
4605
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
4606 4607 4608 4609
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = num;
  pOperator->pExpr = pExprInfo;
H
Haojun Liao 已提交
4610

L
Liu Jicong 已提交
4611
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
4612

4613 4614
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSortedMerge, NULL, NULL, destroySortedMergeOperatorInfo,
                                         NULL, NULL, NULL);
4615 4616 4617
  code = appendDownstream(pOperator, downstream, numOfDownstream);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4618
  }
H
Haojun Liao 已提交
4619

4620
  return pOperator;
H
Haojun Liao 已提交
4621

L
Liu Jicong 已提交
4622
_error:
4623
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4624
    destroySortedMergeOperatorInfo(pInfo, num);
H
Haojun Liao 已提交
4625 4626
  }

wafwerar's avatar
wafwerar 已提交
4627 4628
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
4629 4630
  terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
  return NULL;
H
Haojun Liao 已提交
4631 4632
}

L
Liu Jicong 已提交
4633
static SSDataBlock* doSort(SOperatorInfo* pOperator, bool* newgroup) {
4634 4635 4636 4637
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

L
Liu Jicong 已提交
4638
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
4639 4640
  SSortOperatorInfo* pInfo = pOperator->info;

H
Haojun Liao 已提交
4641
  if (pOperator->status == OP_RES_TO_RETURN) {
H
Haojun Liao 已提交
4642
    return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
H
Haojun Liao 已提交
4643 4644
  }

4645
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
dengyihao's avatar
dengyihao 已提交
4646 4647
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, pInfo->inputSlotMap, SORT_SINGLESOURCE_SORT,
                                             pInfo->bufPageSize, numOfBufPage, pInfo->pDataBlock, pTaskInfo->id.str);
4648

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

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

H
Haojun Liao 已提交
4655
  int32_t code = tsortOpen(pInfo->pSortHandle);
4656
  taosMemoryFreeClear(ps);
4657
  if (code != TSDB_CODE_SUCCESS) {
4658
    longjmp(pTaskInfo->env, terrno);
4659
  }
4660

H
Haojun Liao 已提交
4661
  pOperator->status = OP_RES_TO_RETURN;
H
Haojun Liao 已提交
4662
  return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
4663 4664
}

dengyihao's avatar
dengyihao 已提交
4665 4666
SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo,
                                      SArray* pIndexMap, SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
4667
  SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo));
L
Liu Jicong 已提交
4668
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
dengyihao's avatar
dengyihao 已提交
4669
  int32_t            rowSize = pResBlock->info.rowSize;
4670 4671

  if (pInfo == NULL || pOperator == NULL || rowSize > 100 * 1024 * 1024) {
wafwerar's avatar
wafwerar 已提交
4672 4673
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4674 4675 4676
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
  }
4677

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

wmmhello's avatar
wmmhello 已提交
4680
  pInfo->sortBufSize = pInfo->bufPageSize * 16;  // TODO dynamic set the available sort buffer
L
Liu Jicong 已提交
4681 4682 4683
  pInfo->numOfRowsInRes = 1024;
  pInfo->pDataBlock = pResBlock;
  pInfo->pSortInfo = pSortInfo;
4684
  pInfo->inputSlotMap = pIndexMap;
H
Haojun Liao 已提交
4685

dengyihao's avatar
dengyihao 已提交
4686
  pOperator->name = "SortOperator";
L
Liu Jicong 已提交
4687 4688
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
4689 4690
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
4691

dengyihao's avatar
dengyihao 已提交
4692
  pOperator->pTaskInfo = pTaskInfo;
4693 4694
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSort, NULL, NULL, destroyOrderOperatorInfo,
                                         NULL, NULL, NULL);
4695

4696
  int32_t code = appendDownstream(pOperator, &downstream, 1);
4697
  return pOperator;
H
Haojun Liao 已提交
4698

dengyihao's avatar
dengyihao 已提交
4699
_error:
H
Haojun Liao 已提交
4700 4701 4702 4703
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  return NULL;
4704 4705
}

4706 4707
int32_t getTableScanOrder(SOperatorInfo* pOperator) {
  if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
H
Haojun Liao 已提交
4708
    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
4709
      return TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4710 4711
    } else {
      return getTableScanOrder(pOperator->pDownstream[0]);
4712 4713 4714 4715 4716 4717
    }
  }

  STableScanInfo* pTableScanInfo = pOperator->info;
  return pTableScanInfo->cond.order;
}
4718 4719

// this is a blocking operator
L
Liu Jicong 已提交
4720
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
4721 4722
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
4723 4724
  }

H
Haojun Liao 已提交
4725
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
4726
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
4727

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

H
Haojun Liao 已提交
4730
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
4731
  SOperatorInfo* downstream = pOperator->pDownstream[0];
4732

H
Haojun Liao 已提交
4733 4734
  bool newgroup = true;
  while (1) {
H
Haojun Liao 已提交
4735
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
4736
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
4737
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
4738 4739 4740 4741

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
4742 4743 4744
    //    if (pAggInfo->current != NULL) {
    //      setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
4745

4746 4747
    // there is an scalar expression that needs to be calculated before apply the group aggregation.
    if (pAggInfo->pScalarExprInfo != NULL) {
dengyihao's avatar
dengyihao 已提交
4748 4749
      projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, pAggInfo->numOfScalarExpr,
                            NULL);
4750 4751
    }

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

dengyihao's avatar
dengyihao 已提交
4757
#if 0  // test for encode/decode result info
4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768
    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);
      }
4769
    }
4770
#endif
4771 4772
  }

H
Haojun Liao 已提交
4773 4774 4775
  closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pAggInfo->binfo.pCtx, pOperator->numOfOutput, pAggInfo->aggSup.pResultBuf,
                                &pAggInfo->binfo.resultRowInfo, pAggInfo->binfo.rowCellInfoOffset);
H
Haojun Liao 已提交
4776

4777
  initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, false);
H
Haojun Liao 已提交
4778 4779 4780 4781
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4782 4783
static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup) {
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
4784 4785 4786 4787 4788 4789
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;

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

L
Liu Jicong 已提交
4790
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4791
  pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
H
Haojun Liao 已提交
4792 4793 4794 4795
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
    return NULL;
  }

H
Haojun Liao 已提交
4796
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
4797 4798
  doBuildResultDatablock(pInfo->pRes, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf,
                         pInfo->rowCellInfoOffset, pInfo->pCtx);
H
Haojun Liao 已提交
4799 4800 4801
  if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
4802

H
Haojun Liao 已提交
4803
  doSetOperatorCompleted(pOperator);
L
Liu Jicong 已提交
4804
  return (blockDataGetNumOfRows(pInfo->pRes) != 0) ? pInfo->pRes : NULL;
4805 4806
}

dengyihao's avatar
dengyihao 已提交
4807 4808
void aggEncodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char** result,
                        int32_t* length) {
wmmhello's avatar
wmmhello 已提交
4809
  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
4810
  size_t  keyLen = sizeof(uint64_t) * 2;  // estimate the key length
wmmhello's avatar
wmmhello 已提交
4811
  int32_t totalSize = sizeof(int32_t) + size * (sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize);
wafwerar's avatar
wafwerar 已提交
4812
  *result = taosMemoryCalloc(1, totalSize);
L
Liu Jicong 已提交
4813
  if (*result == NULL) {
4814
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
wmmhello's avatar
wmmhello 已提交
4815 4816 4817
  }
  *(int32_t*)(*result) = size;
  int32_t offset = sizeof(int32_t);
4818 4819

  // prepare memory
4820
  SResultRowPosition* pos = &pInfo->resultRowInfo.cur;
dengyihao's avatar
dengyihao 已提交
4821 4822
  void*               pPage = getBufPage(pSup->pResultBuf, pos->pageId);
  SResultRow*         pRow = (SResultRow*)((char*)pPage + pos->offset);
4823 4824 4825
  setBufPageDirty(pPage, true);
  releaseBufPage(pSup->pResultBuf, pPage);

dengyihao's avatar
dengyihao 已提交
4826
  void* pIter = taosHashIterate(pSup->pResultRowHashTable, NULL);
wmmhello's avatar
wmmhello 已提交
4827
  while (pIter) {
dengyihao's avatar
dengyihao 已提交
4828
    void*               key = taosHashGetKey(pIter, &keyLen);
4829
    SResultRowPosition* p1 = (SResultRowPosition*)pIter;
4830

dengyihao's avatar
dengyihao 已提交
4831
    pPage = (SFilePage*)getBufPage(pSup->pResultBuf, p1->pageId);
4832
    pRow = (SResultRow*)((char*)pPage + p1->offset);
4833 4834
    setBufPageDirty(pPage, true);
    releaseBufPage(pSup->pResultBuf, pPage);
wmmhello's avatar
wmmhello 已提交
4835 4836 4837

    // recalculate the result size
    int32_t realTotalSize = offset + sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize;
L
Liu Jicong 已提交
4838 4839 4840
    if (realTotalSize > totalSize) {
      char* tmp = taosMemoryRealloc(*result, realTotalSize);
      if (tmp == NULL) {
wmmhello's avatar
wmmhello 已提交
4841
        terrno = TSDB_CODE_OUT_OF_MEMORY;
wafwerar's avatar
wafwerar 已提交
4842
        taosMemoryFree(*result);
wmmhello's avatar
wmmhello 已提交
4843
        *result = NULL;
4844
        longjmp(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
L
Liu Jicong 已提交
4845
      } else {
wmmhello's avatar
wmmhello 已提交
4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857
        *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);
4858
    memcpy(*result + offset, pRow, pSup->resultRowSize);
wmmhello's avatar
wmmhello 已提交
4859 4860 4861 4862 4863
    offset += pSup->resultRowSize;

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

L
Liu Jicong 已提交
4864
  if (length) {
wmmhello's avatar
wmmhello 已提交
4865 4866 4867 4868 4869
    *length = offset;
  }
  return;
}

dengyihao's avatar
dengyihao 已提交
4870 4871
bool aggDecodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char* result,
                        int32_t length) {
L
Liu Jicong 已提交
4872
  if (!result || length <= 0) {
wmmhello's avatar
wmmhello 已提交
4873 4874 4875 4876 4877 4878 4879
    return false;
  }

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

  int32_t offset = sizeof(int32_t);
L
Liu Jicong 已提交
4880
  while (count-- > 0 && length > offset) {
wmmhello's avatar
wmmhello 已提交
4881 4882 4883
    int32_t keyLen = *(int32_t*)(result + offset);
    offset += sizeof(int32_t);

L
Liu Jicong 已提交
4884 4885 4886
    uint64_t    tableGroupId = *(uint64_t*)(result + offset);
    SResultRow* resultRow = getNewResultRow_rv(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
    if (!resultRow) {
4887
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4888
    }
4889

wmmhello's avatar
wmmhello 已提交
4890
    // add a new result set for a new group
4891 4892
    SResultRowPosition pos = {.pageId = resultRow->pageId, .offset = resultRow->offset};
    taosHashPut(pSup->pResultRowHashTable, result + offset, keyLen, &pos, sizeof(SResultRowPosition));
wmmhello's avatar
wmmhello 已提交
4893 4894 4895

    offset += keyLen;
    int32_t valueLen = *(int32_t*)(result + offset);
L
Liu Jicong 已提交
4896
    if (valueLen != pSup->resultRowSize) {
4897
      longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4898 4899 4900 4901 4902 4903 4904 4905 4906 4907
    }
    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);
4908
    prepareResultListBuffer(&pInfo->resultRowInfo, pOperator->pTaskInfo->env);
dengyihao's avatar
dengyihao 已提交
4909
    //    pInfo->resultRowInfo.cur = pInfo->resultRowInfo.size;
4910 4911
//    pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
//        (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
dengyihao's avatar
dengyihao 已提交
4912
    pInfo->resultRowInfo.cur = (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
wmmhello's avatar
wmmhello 已提交
4913 4914
  }

L
Liu Jicong 已提交
4915
  if (offset != length) {
4916
    longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_INVALID_INPUT);
wmmhello's avatar
wmmhello 已提交
4917 4918 4919 4920
  }
  return true;
}

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 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990
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 已提交
4991
static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup) {
4992
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
L
Liu Jicong 已提交
4993
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
4994 4995

  SSDataBlock* pRes = pInfo->pRes;
4996
  blockDataCleanup(pRes);
4997 4998 4999 5000

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

H
Haojun Liao 已提交
5002
#if 0
5003 5004 5005 5006 5007 5008
  if (pProjectInfo->existDataBlock) {  // TODO refactor
    SSDataBlock* pBlock = pProjectInfo->existDataBlock;
    pProjectInfo->existDataBlock = NULL;
    *newgroup = true;

    // todo dynamic set tags
L
Liu Jicong 已提交
5009 5010 5011
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5012 5013

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

H
Haojun Liao 已提交
5016
    blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
5017
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
L
Liu Jicong 已提交
5018
    if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
5019 5020 5021 5022 5023
      copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
      resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
      return pRes;
    }
  }
H
Haojun Liao 已提交
5024
#endif
5025

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

L
Liu Jicong 已提交
5028
  while (1) {
5029 5030
    bool prevVal = *newgroup;

H
Haojun Liao 已提交
5031
    // The downstream exec may change the value of the newgroup, so use a local variable instead.
H
Haojun Liao 已提交
5032
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5033
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5034
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5035 5036 5037

    if (pBlock == NULL) {
      *newgroup = prevVal;
5038
      setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5039 5040 5041 5042 5043 5044 5045 5046
      break;
    }

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

    // todo dynamic set tags
H
Haojun Liao 已提交
5053 5054 5055 5056
    //    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5057 5058

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

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

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

5067 5068
    int32_t status = handleLimitOffset(pOperator, pBlock);
    if (status == PROJECT_RETRIEVE_CONTINUE) {
H
Haojun Liao 已提交
5069
      continue;
5070
    } else if (status == PROJECT_RETRIEVE_DONE)  {
5071 5072 5073
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
5074

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

L
Liu Jicong 已提交
5077 5078
  //  copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
  return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
5079 5080
}

L
Liu Jicong 已提交
5081
static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
5082 5083
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
5084 5085
  }

dengyihao's avatar
dengyihao 已提交
5086
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
5087
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5088

5089
  int32_t order = TSDB_ORDER_ASC;
5090
  //  STimeWindow win = {0};
dengyihao's avatar
dengyihao 已提交
5091
  bool           newgroup = false;
H
Haojun Liao 已提交
5092
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5093

5094
  while (1) {
H
Haojun Liao 已提交
5095
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5096
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
5097
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5098 5099 5100 5101 5102

    if (pBlock == NULL) {
      break;
    }

5103
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
5104
    // the pDataBlock are always the same one, no need to call this again
5105
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
5106 5107 5108
    STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;

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

dengyihao's avatar
dengyihao 已提交
5111
#if 0  // test for encode/decode result info
5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122
    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);
      }
5123
    }
5124
#endif
5125 5126
  }

H
Haojun Liao 已提交
5127
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
L
Liu Jicong 已提交
5128 5129
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5130

5131
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5132 5133 5134 5135
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
5136
static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator, bool* newgroup) {
5137
  STableIntervalOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5138
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
5139 5140 5141 5142 5143

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

5144 5145
  SSDataBlock* pBlock = pInfo->binfo.pRes;

5146
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
5147
    return pOperator->fpSet.getStreamResFn(pOperator, newgroup);
5148
  } else {
5149
    pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
5150 5151 5152
    if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
      return NULL;
    }
5153

5154
    blockDataEnsureCapacity(pBlock, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5155 5156
    doBuildResultDatablock(pBlock, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5157

5158
    if (pBlock->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5159 5160
      doSetOperatorCompleted(pOperator);
    }
5161

5162
    return pBlock->info.rows == 0 ? NULL : pBlock;
5163 5164 5165
  }
}

dengyihao's avatar
dengyihao 已提交
5166
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5167
  STableIntervalOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5168
  int32_t                     order = TSDB_ORDER_ASC;
5169 5170 5171 5172 5173 5174

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

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5175 5176
    doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5177 5178 5179
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      pOperator->status = OP_EXEC_DONE;
    }
5180
    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5181 5182 5183
  }

  //  STimeWindow win = {0};
5184
  *newgroup = false;
5185 5186 5187 5188 5189 5190
  SOperatorInfo* downstream = pOperator->pDownstream[0];

  SArray* pUpdated = NULL;

  while (1) {
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5191
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
5192 5193 5194 5195 5196 5197
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);

    if (pBlock == NULL) {
      break;
    }

dengyihao's avatar
dengyihao 已提交
5198 5199
    // 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.
5200 5201 5202

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

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

H
Haojun Liao 已提交
5210
  initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
5211
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5212 5213
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5214 5215 5216 5217 5218 5219 5220

  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 已提交
5221
static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5222 5223 5224 5225
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5226
  STimeSliceOperatorInfo* pSliceInfo = pOperator->info;
5227
  if (pOperator->status == OP_RES_TO_RETURN) {
5228
    //    doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
5229
    if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5230 5231 5232
      doSetOperatorCompleted(pOperator);
    }

5233
    return pSliceInfo->binfo.pRes;
5234 5235
  }

dengyihao's avatar
dengyihao 已提交
5236 5237
  int32_t order = TSDB_ORDER_ASC;
  //  STimeWindow win = pQueryAttr->window;
H
Haojun Liao 已提交
5238
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5239

L
Liu Jicong 已提交
5240
  while (1) {
H
Haojun Liao 已提交
5241
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5242
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5243
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5244 5245 5246 5247
    if (pBlock == NULL) {
      break;
    }

L
Liu Jicong 已提交
5248
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5249
    // the pDataBlock are always the same one, no need to call this again
5250
    setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true);
dengyihao's avatar
dengyihao 已提交
5251
    //    hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
5252 5253 5254 5255
  }

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

5260
//  initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
5261
  //  doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
5262

5263
  if (pSliceInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pSliceInfo->groupResInfo)) {
5264 5265 5266
    pOperator->status = OP_EXEC_DONE;
  }

5267
  return pSliceInfo->binfo.pRes->info.rows == 0 ? NULL : pSliceInfo->binfo.pRes;
5268 5269
}

L
Liu Jicong 已提交
5270
static SSDataBlock* doSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5271 5272 5273 5274
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5275
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
5276

5277
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5278 5279
  if (pOperator->status == OP_RES_TO_RETURN) {
    int64_t st = taosGetTimestampUs();
5280
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5281 5282
      doSetOperatorCompleted(pOperator);
    }
5283 5284

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

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

L
Liu Jicong 已提交
5289
  while (1) {
H
Haojun Liao 已提交
5290
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5291
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5292
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5293 5294 5295 5296 5297 5298

    if (pBlock == NULL) {
      break;
    }

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

5303
    setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window);
dengyihao's avatar
dengyihao 已提交
5304
    //    hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pBlock->info.groupId);
5305 5306
  }

5307 5308 5309
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5310

5311
//  initGroupedResultInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
5312 5313
  OPTR_SET_OPENED(pOperator);

5314
  blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5315 5316
  doBuildResultDatablock(pInfo->binfo.pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pInfo->binfo.rowCellInfoOffset, pInfo->binfo.pCtx);
5317 5318 5319

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

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

5325
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) {
dengyihao's avatar
dengyihao 已提交
5326
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
5327 5328
  SOptrBasicInfo* pBInfo = &pInfo->binfo;

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

5332 5333 5334 5335 5336 5337 5338 5339
  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;
5340

5341 5342
  SWindowRowsSup* pRowSup = &pInfo->winSup;
  pRowSup->numOfRows = 0;
dengyihao's avatar
dengyihao 已提交
5343

5344 5345
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
    if (colDataIsNull(pStateColInfoData, pBlock->info.rows, j, pBlock->pBlockAgg)) {
5346 5347
      continue;
    }
5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360

    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;
5361
      }
5362
    } else {  // a new state window started
5363
      SResultRow* pResult = NULL;
5364 5365 5366 5367 5368 5369

      // 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 已提交
5370 5371
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput,
                                               pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
5372
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5373
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5374 5375
      }

5376
      updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
dengyihao's avatar
dengyihao 已提交
5377 5378
      doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
                       pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
5379 5380 5381 5382

      // here we start a new session window
      doKeepNewWindowStartInfo(pRowSup, tsList, j);
      doKeepTuple(pRowSup, tsList[j]);
5383 5384 5385 5386
    }
  }

  SResultRow* pResult = NULL;
5387
  pRowSup->win.ekey = tsList[pBlock->info.rows - 1];
dengyihao's avatar
dengyihao 已提交
5388 5389 5390
  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);
5391
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
5392
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
5393 5394
  }

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

L
Liu Jicong 已提交
5400
static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5401 5402 5403 5404
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5405
  SStateWindowOperatorInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
5406 5407
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
  SOptrBasicInfo*           pBInfo = &pInfo->binfo;
5408 5409

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5410 5411
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5412 5413 5414 5415
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
    }
5416 5417 5418 5419

    return pBInfo->pRes;
  }

dengyihao's avatar
dengyihao 已提交
5420 5421
  int32_t     order = TSDB_ORDER_ASC;
  STimeWindow win = pTaskInfo->window;
H
Haojun Liao 已提交
5422

H
Haojun Liao 已提交
5423
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5424
  while (1) {
H
Haojun Liao 已提交
5425
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5426
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5427
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5428 5429 5430 5431

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

5433
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5434
    doStateWindowAggImpl(pOperator, pInfo, pBlock);
5435 5436 5437 5438
  }

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

5442
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5443
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5444 5445
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5446 5447 5448
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
  }
5449

L
Liu Jicong 已提交
5450
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5451 5452
}

L
Liu Jicong 已提交
5453
static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5454 5455 5456 5457
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5458
  SSessionAggOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5459
  SOptrBasicInfo*          pBInfo = &pInfo->binfo;
5460 5461

  if (pOperator->status == OP_RES_TO_RETURN) {
dengyihao's avatar
dengyihao 已提交
5462 5463
    doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                           pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5464 5465 5466
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
5467 5468 5469 5470 5471
    }

    return pBInfo->pRes;
  }

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

L
Liu Jicong 已提交
5475
  while (1) {
H
Haojun Liao 已提交
5476
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5477
    SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5478
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5479 5480 5481 5482 5483
    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
5484
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true);
5485
    doSessionWindowAggImpl(pOperator, pInfo, pBlock);
5486 5487 5488 5489 5490
  }

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

5494
  initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
5495
  blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
dengyihao's avatar
dengyihao 已提交
5496 5497
  doBuildResultDatablock(pBInfo->pRes, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf,
                         pBInfo->rowCellInfoOffset, pInfo->binfo.pCtx);
5498 5499
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5500 5501
  }

L
Liu Jicong 已提交
5502
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5503 5504
}

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

L
Liu Jicong 已提交
5509 5510
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
5511 5512
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

5513
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
5514 5515
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

H
Haojun Liao 已提交
5516
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity, pInfo->p);
5517 5518 5519 5520
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
5521 5522
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
5523 5524
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
H
Haojun Liao 已提交
5525 5526
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity, pInfo->p);
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
5527 5528 5529 5530 5531 5532
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
5533
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5534 5535 5536
  }
}

L
Liu Jicong 已提交
5537 5538 5539
static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
5540

H
Haojun Liao 已提交
5541
  SResultInfo* pResultInfo = &pOperator->resultInfo;
5542 5543 5544
  SSDataBlock* pResBlock = pInfo->pRes;

  blockDataCleanup(pResBlock);
5545 5546 5547 5548
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5549
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5550 5551
  if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) {
    return pResBlock;
H
Haojun Liao 已提交
5552
  }
5553

H
Haojun Liao 已提交
5554
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
5555
  while (1) {
H
Haojun Liao 已提交
5556
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5557
    SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream, newgroup);
H
Haojun Liao 已提交
5558
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569

    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
5570
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5571 5572 5573 5574 5575 5576 5577
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

5578
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5579 5580 5581 5582 5583 5584 5585
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

5586
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity, pInfo->p);
5587 5588

    // current group has no more result to return
5589
    if (pResBlock->info.rows > 0) {
5590 5591
      // 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
5592 5593
      if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
        return pResBlock;
5594 5595
      }

5596
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
5597 5598
      if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
        return pResBlock;
5599 5600 5601
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
5602
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5603 5604
      if (pResBlock->info.rows > pResultInfo->threshold) {
        return pResBlock;
5605 5606 5607 5608 5609 5610 5611 5612
      }
    } else {
      return NULL;
    }
  }
}

// todo set the attribute of query scan count
H
Haojun Liao 已提交
5613
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
L
Liu Jicong 已提交
5614
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628
    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;
  }

5629 5630
  if (pOperator->fpSet.closeFn != NULL) {
    pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfOutput);
5631 5632
  }

H
Haojun Liao 已提交
5633
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
5634
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
5635
      destroyOperatorInfo(pOperator->pDownstream[i]);
5636 5637
    }

wafwerar's avatar
wafwerar 已提交
5638
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
5639
    pOperator->numOfDownstream = 0;
5640 5641
  }

wafwerar's avatar
wafwerar 已提交
5642 5643
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
5644 5645
}

dengyihao's avatar
dengyihao 已提交
5646 5647
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, size_t keyBufSize,
                         const char* pKey) {
5648 5649
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

dengyihao's avatar
dengyihao 已提交
5650 5651
  pAggSup->resultRowSize = getResultRowSize(pCtx, numOfOutput);
  pAggSup->keyBuf = taosMemoryCalloc(1, keyBufSize + POINTER_BYTES + sizeof(int64_t));
5652
  pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK);
5653 5654
//  pAggSup->pResultRowListSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
//  pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell));
5655

5656
  if (pAggSup->keyBuf == NULL /*|| pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL*/ ||
5657
      pAggSup->pResultRowHashTable == NULL) {
5658 5659 5660
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
5661 5662 5663 5664 5665
  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, 4096, 4096 * 256, pKey, "/tmp/");
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

5666 5667 5668
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
5669
static void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
5670
  taosMemoryFreeClear(pAggSup->keyBuf);
5671
  taosHashCleanup(pAggSup->pResultRowHashTable);
5672 5673
//  taosHashCleanup(pAggSup->pResultRowListSet);
//  taosArrayDestroy(pAggSup->pResultRowArrayList);
H
Haojun Liao 已提交
5674
  destroyDiskbasedBuf(pAggSup->pResultBuf);
5675 5676
}

H
Haojun Liao 已提交
5677
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
5678
                    SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey) {
5679
  pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5680 5681
  pBasicInfo->pRes = pResultBlock;

5682
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, keyBufSize, pkey);
5683 5684 5685 5686 5687

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

5688
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
5689 5690
}

5691 5692 5693 5694 5695 5696 5697 5698 5699
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 已提交
5700
static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5701
  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
H
Haojun Liao 已提交
5702 5703
  if (pTableQueryInfo == NULL) {
    return NULL;
H
Haojun Liao 已提交
5704
  }
H
Haojun Liao 已提交
5705 5706

  int32_t index = 0;
L
Liu Jicong 已提交
5707
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
H
Haojun Liao 已提交
5708
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
L
Liu Jicong 已提交
5709
    for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
H
Haojun Liao 已提交
5710 5711
      STableKeyInfo* pk = taosArrayGet(pa, j);

H
Haojun Liao 已提交
5712
      STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
dengyihao's avatar
dengyihao 已提交
5713
      //      pTQueryInfo->uid = pk->uid;
L
Liu Jicong 已提交
5714
      pTQueryInfo->lastKey = pk->lastKey;
dengyihao's avatar
dengyihao 已提交
5715
      //      pTQueryInfo->groupIndex = i;
H
Haojun Liao 已提交
5716 5717
    }
  }
H
Haojun Liao 已提交
5718 5719

  STimeWindow win = {0, INT64_MAX};
H
Haojun Liao 已提交
5720 5721
  createTableQueryInfo(pTableQueryInfo, false, win);
  return pTableQueryInfo;
H
Haojun Liao 已提交
5722 5723
}

L
Liu Jicong 已提交
5724
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5725
                                           SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
5726
                                           int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
5727
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
5728
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5729 5730 5731
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5732

H
Haojun Liao 已提交
5733
  int32_t numOfRows = 1;
dengyihao's avatar
dengyihao 已提交
5734
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5735 5736

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
5737 5738
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResultBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
5739 5740
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) {
H
Haojun Liao 已提交
5741 5742
    goto _error;
  }
H
Haojun Liao 已提交
5743

H
Haojun Liao 已提交
5744 5745 5746 5747 5748 5749 5750
  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);

5751 5752
  pInfo->pScalarExprInfo = pScalarExprInfo;
  pInfo->numOfScalarExpr = numOfScalarExpr;
5753 5754 5755
  if (pInfo->pScalarExprInfo != NULL) {
    pInfo->pScalarCtx = createSqlFunctionCtx(pScalarExprInfo, numOfCols, &pInfo->rowCellInfoOffset);
  }
5756

dengyihao's avatar
dengyihao 已提交
5757
  pOperator->name = "TableAggregate";
X
Xiaoyu Wang 已提交
5758
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
5759
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5760 5761 5762 5763 5764
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
H
Haojun Liao 已提交
5765

5766 5767
  pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
                                         aggEncodeResultRow, aggDecodeResultRow, NULL);
H
Haojun Liao 已提交
5768 5769 5770 5771 5772

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

  return pOperator;
L
Liu Jicong 已提交
5775
_error:
H
Haojun Liao 已提交
5776
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5777 5778
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5779 5780
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5781 5782
}

H
Haojun Liao 已提交
5783
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
5784 5785
  assert(pInfo != NULL);

5786
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
5787
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
5788 5789

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
5790
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
5791 5792
}

H
Haojun Liao 已提交
5793
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5794
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
5795 5796
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
5797 5798

void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5799
  SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param;
5800
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
5801
  taosMemoryFreeClear(pInfo->stateKey.pData);
5802
}
H
Haojun Liao 已提交
5803 5804

void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5805
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
5806 5807
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
5808

H
Haojun Liao 已提交
5809
void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5810
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)param;
H
Haojun Liao 已提交
5811 5812 5813 5814 5815
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
  cleanupAggSup(&pInfo->aggSup);
}

void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5816
  SSessionAggOperatorInfo* pInfo = (SSessionAggOperatorInfo*)param;
5817 5818 5819
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5820
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5821
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
5822
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
5823
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
5824
  taosMemoryFreeClear(pInfo->p);
5825 5826
}

H
Haojun Liao 已提交
5827
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5828
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
5829 5830 5831
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
5832
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5833
  SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
H
Haojun Liao 已提交
5834 5835
  pInfo->pDataBlock = blockDataDestroy(pInfo->pDataBlock);

H
Haojun Liao 已提交
5836
  taosArrayDestroy(pInfo->pSortInfo);
5837
  taosArrayDestroy(pInfo->inputSlotMap);
5838 5839
}

H
Haojun Liao 已提交
5840
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
5841
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
5842 5843 5844 5845 5846 5847 5848 5849 5850
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

H
Haojun Liao 已提交
5851 5852
static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols) {
  SArray* pList = taosArrayInit(4, sizeof(int32_t));
dengyihao's avatar
dengyihao 已提交
5853
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
5854 5855 5856 5857 5858 5859 5860 5861
    if (fmIsPseudoColumnFunc(pCtx[i].functionId)) {
      taosArrayPush(pList, &i);
    }
  }

  return pList;
}

L
Liu Jicong 已提交
5862
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
dengyihao's avatar
dengyihao 已提交
5863 5864
                                         SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit,
                                         SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5865
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
5866
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5867 5868 5869
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
5870

dengyihao's avatar
dengyihao 已提交
5871 5872 5873
  pInfo->limit = *pLimit;
  pInfo->slimit = *pSlimit;
  pInfo->curOffset = pLimit->offset;
H
Haojun Liao 已提交
5874 5875
  pInfo->curSOffset = pSlimit->offset;

H
Haojun Liao 已提交
5876
  pInfo->binfo.pRes = pResBlock;
H
Haojun Liao 已提交
5877 5878 5879

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5880
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5881 5882 5883

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

dengyihao's avatar
dengyihao 已提交
5887
  pOperator->name = "ProjectOperator";
H
Haojun Liao 已提交
5888
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
5889
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
5890 5891 5892 5893
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = num;
5894 5895 5896

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

  pOperator->pTaskInfo = pTaskInfo;
5899
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5900
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
5901 5902
    goto _error;
  }
5903 5904

  return pOperator;
H
Haojun Liao 已提交
5905

L
Liu Jicong 已提交
5906
_error:
H
Haojun Liao 已提交
5907 5908
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
5909 5910
}

L
Liu Jicong 已提交
5911
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
5912
                                          SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
dengyihao's avatar
dengyihao 已提交
5913 5914
                                          STimeWindowAggSupp* pTwAggSupp, const STableGroupInfo* pTableGroupInfo,
                                          SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
5915
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
L
Liu Jicong 已提交
5916
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5917 5918 5919
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
5920

5921 5922
  pInfo->order          = TSDB_ORDER_ASC;
  pInfo->interval       = *pInterval;
H
Haojun Liao 已提交
5923 5924
//  pInfo->execModel      = OPTR_EXEC_MODEL_STREAM;
  pInfo->execModel      = pTaskInfo->execModel;
5925 5926
  pInfo->win            = pTaskInfo->window;
  pInfo->twAggSup       = *pTwAggSupp;
5927
  pInfo->primaryTsIndex = primaryTsSlotId;
5928

5929
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
5930
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
5931 5932

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

L
Liu Jicong 已提交
5937 5938
  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
H
Haojun Liao 已提交
5939 5940
    goto _error;
  }
H
Haojun Liao 已提交
5941 5942

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

dengyihao's avatar
dengyihao 已提交
5944
  pOperator->name = "TimeIntervalAggOperator";
H
Haojun Liao 已提交
5945
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
5946
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
5947 5948 5949 5950 5951
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
5952 5953 5954

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

H
Haojun Liao 已提交
5956
  code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
5957 5958 5959 5960
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

5961
  return pOperator;
H
Haojun Liao 已提交
5962

L
Liu Jicong 已提交
5963
_error:
H
Haojun Liao 已提交
5964
  destroyIntervalOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
5965 5966
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5967 5968
  pTaskInfo->code = code;
  return NULL;
5969 5970
}

5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029
SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                                SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
                                                STimeWindowAggSupp *pTwAggSupp, const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo) {
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }

  pInfo->order          = TSDB_ORDER_ASC;
  pInfo->interval       = *pInterval;
  pInfo->execModel      = OPTR_EXEC_MODEL_STREAM;
  pInfo->win            = pTaskInfo->window;
  pInfo->twAggSup       = *pTwAggSupp;
  pInfo->primaryTsIndex = primaryTsSlotId;

  int32_t numOfRows = 4096;
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;

  initResultSizeInfo(pOperator, numOfRows);
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);

  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
    goto _error;
  }

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

  pOperator->name = "StreamTimeIntervalAggOperator";
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
  pOperator->blockingOptr = true;
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;

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

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

  return pOperator;

  _error:
  destroyIntervalOperatorInfo(pInfo, numOfCols);
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
  pTaskInfo->code = code;
  return NULL;

}

dengyihao's avatar
dengyihao 已提交
6030 6031
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                           SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo) {
6032
  STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
dengyihao's avatar
dengyihao 已提交
6033
  SOperatorInfo*          pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6034 6035 6036
  if (pOperator == NULL || pInfo == NULL) {
    goto _error;
  }
6037

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

dengyihao's avatar
dengyihao 已提交
6040
  pOperator->name = "TimeSliceOperator";
L
Liu Jicong 已提交
6041
  //  pOperator->operatorType = OP_AllTimeWindow;
6042
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6043 6044 6045 6046 6047
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->pTaskInfo = pTaskInfo;
6048 6049 6050

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

L
Liu Jicong 已提交
6052
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6053
  return pOperator;
6054

dengyihao's avatar
dengyihao 已提交
6055
_error:
6056 6057 6058 6059
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
6060 6061
}

dengyihao's avatar
dengyihao 已提交
6062 6063 6064
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
                                             SSDataBlock* pResBlock, STimeWindowAggSupp* pTwAggSup,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6065
  SStateWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStateWindowOperatorInfo));
dengyihao's avatar
dengyihao 已提交
6066
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6067 6068 6069
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6070

L
Liu Jicong 已提交
6071
  pInfo->colIndex = -1;
6072
  size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6073 6074 6075

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

6078 6079 6080
  pInfo->twAggSup = *pTwAggSup;
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);

dengyihao's avatar
dengyihao 已提交
6081
  pOperator->name = "StateWindowOperator";
6082
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW;
6083
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6084 6085 6086 6087 6088 6089
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;

  pOperator->pTaskInfo = pTaskInfo;
  pOperator->info = pInfo;
6090 6091 6092

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

H
Haojun Liao 已提交
6094
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6095
  return pOperator;
6096

dengyihao's avatar
dengyihao 已提交
6097
_error:
6098 6099
  pTaskInfo->code = TSDB_CODE_SUCCESS;
  return NULL;
6100 6101
}

L
Liu Jicong 已提交
6102
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
dengyihao's avatar
dengyihao 已提交
6103 6104
                                            SSDataBlock* pResBlock, int64_t gap, STimeWindowAggSupp* pTwAggSupp,
                                            SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6105
  SSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSessionAggOperatorInfo));
L
Liu Jicong 已提交
6106
  SOperatorInfo*           pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6107 6108 6109
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6110

H
Haojun Liao 已提交
6111
  int32_t numOfRows = 4096;
dengyihao's avatar
dengyihao 已提交
6112
  size_t  keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
6113 6114

  initResultSizeInfo(pOperator, numOfRows);
dengyihao's avatar
dengyihao 已提交
6115 6116
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
H
Haojun Liao 已提交
6117 6118 6119
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6120

6121
  pInfo->twAggSup = *pTwAggSupp;
H
Haojun Liao 已提交
6122
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6123
  initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
6124

dengyihao's avatar
dengyihao 已提交
6125 6126 6127 6128 6129
  pInfo->gap = gap;
  pInfo->binfo.pRes = pResBlock;
  pInfo->winSup.prevTs = INT64_MIN;
  pInfo->reptScan = false;
  pOperator->name = "SessionWindowAggOperator";
H
Haojun Liao 已提交
6130
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW;
6131
  pOperator->blockingOptr = true;
dengyihao's avatar
dengyihao 已提交
6132 6133 6134 6135
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
6136 6137 6138

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

H
Haojun Liao 已提交
6141
  code = appendDownstream(pOperator, &downstream, 1);
6142
  return pOperator;
H
Haojun Liao 已提交
6143

L
Liu Jicong 已提交
6144
_error:
H
Haojun Liao 已提交
6145 6146 6147 6148
  if (pInfo != NULL) {
    destroySWindowOperatorInfo(pInfo, numOfCols);
  }

wafwerar's avatar
wafwerar 已提交
6149 6150
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6151 6152
  pTaskInfo->code = code;
  return NULL;
6153 6154
}

H
Haojun Liao 已提交
6155
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, int64_t* fillVal,
L
Liu Jicong 已提交
6156
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
6157
  SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, NULL);
H
Haojun Liao 已提交
6158 6159 6160

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

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

wafwerar's avatar
wafwerar 已提交
6166
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
6167 6168 6169 6170 6171 6172 6173 6174

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

L
Liu Jicong 已提交
6175 6176 6177
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 已提交
6178
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
6179
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6180

L
Liu Jicong 已提交
6181
  pInfo->pRes = pResBlock;
6182
  pInfo->multigroupResult = multigroupResult;
L
Liu Jicong 已提交
6183
  pInfo->intervalInfo = *pInterval;
6184

6185 6186
  int32_t type = TSDB_FILL_NONE;
  switch (fillType) {
dengyihao's avatar
dengyihao 已提交
6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204
    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;
6205 6206 6207 6208
    default:
      type = TSDB_FILL_NONE;
  }

H
Haojun Liao 已提交
6209
  SResultInfo* pResultInfo = &pOperator->resultInfo;
6210 6211 6212 6213
  initResultSizeInfo(pOperator, 4096);

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

dengyihao's avatar
dengyihao 已提交
6218
  pOperator->name = "FillOperator";
6219
  pOperator->blockingOptr = false;
dengyihao's avatar
dengyihao 已提交
6220
  pOperator->status = OP_NOT_OPENED;
L
Liu Jicong 已提交
6221
  //  pOperator->operatorType = OP_Fill;
dengyihao's avatar
dengyihao 已提交
6222 6223 6224
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
H
Haojun Liao 已提交
6225

6226 6227 6228
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo,
                                         NULL, NULL, NULL);
  pOperator->pTaskInfo = pTaskInfo;
6229
  code = appendDownstream(pOperator, &downstream, 1);
6230
  return pOperator;
H
Haojun Liao 已提交
6231

L
Liu Jicong 已提交
6232
_error:
wafwerar's avatar
wafwerar 已提交
6233 6234
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
6235
  return NULL;
6236 6237
}

H
Haojun Liao 已提交
6238

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

H
Haojun Liao 已提交
6242 6243
  if (TSDB_COL_IS_TAG(pExpr->pParam[0].pCol->type)) {
    if (pExpr->pParam[0].pCol->colId == TSDB_TBNAME_COLUMN_INDEX) {
6244 6245 6246
      return TSDB_TBNAME_COLUMN_INDEX;
    }

L
Liu Jicong 已提交
6247
    while (j < pTableInfo->numOfTags) {
H
Haojun Liao 已提交
6248
      if (pExpr->pParam[0].pCol->colId == pTagCols[j].colId) {
6249 6250 6251 6252 6253 6254
        return j;
      }

      j += 1;
    }

6255
  } /*else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {  // user specified column data
6256 6257 6258 6259 6260 6261 6262 6263 6264
    return TSDB_UD_COLUMN_INDEX;
  } else {
    while (j < pTableInfo->numOfCols) {
      if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) {
        return j;
      }

      j += 1;
    }
6265
  }*/
6266 6267 6268 6269

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

L
Liu Jicong 已提交
6270
bool validateExprColumnInfo(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6271 6272 6273 6274
  int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols);
  return j != INT32_MIN;
}

L
Liu Jicong 已提交
6275 6276
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
6277
  SResSchema s = {0};
dengyihao's avatar
dengyihao 已提交
6278 6279 6280 6281
  s.scale = scale;
  s.type = type;
  s.bytes = bytes;
  s.slotId = slotId;
H
Haojun Liao 已提交
6282
  s.precision = precision;
H
Haojun Liao 已提交
6283 6284 6285 6286
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
6287

H
Haojun Liao 已提交
6288 6289 6290 6291 6292 6293 6294
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 已提交
6295 6296 6297 6298 6299
  pCol->slotId = slotId;
  pCol->bytes = pType->bytes;
  pCol->type = pType->type;
  pCol->scale = pType->scale;
  pCol->precision = pType->precision;
H
Haojun Liao 已提交
6300 6301 6302 6303 6304
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
6305
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
6306
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
6307 6308 6309 6310
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
6311

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

L
Liu Jicong 已提交
6315
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
6316 6317 6318 6319 6320 6321
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
6322

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

wafwerar's avatar
wafwerar 已提交
6325
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
6326
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
6327
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
6328

6329
    int32_t type = nodeType(pTargetNode->pExpr);
H
Haojun Liao 已提交
6330
    // it is a project query, or group by column
6331
    if (type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
6332
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
6333
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
6334

G
Ganlin Zhao 已提交
6335 6336 6337
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
6338
      SDataType* pType = &pColNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6339 6340
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pColNode->colName);
H
Haojun Liao 已提交
6341 6342
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pType);
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
6343
    } else if (type == QUERY_NODE_VALUE) {
6344 6345 6346 6347 6348 6349 6350
      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 已提交
6351 6352
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pValNode->node.aliasName);
6353 6354
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
      valueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
6355
    } else if (type == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
6356
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
6357 6358 6359
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

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

H
Haojun Liao 已提交
6363
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
6364
      pExp->pExpr->_function.pFunctNode = pFuncNode;
dengyihao's avatar
dengyihao 已提交
6365 6366
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName,
              tListLen(pExp->pExpr->_function.functionName));
H
Haojun Liao 已提交
6367 6368

      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
6369 6370 6371 6372

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

H
Haojun Liao 已提交
6373
      for (int32_t j = 0; j < numOfParam; ++j) {
6374
        SNode* p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
6375
        if (p1->type == QUERY_NODE_COLUMN) {
dengyihao's avatar
dengyihao 已提交
6376
          SColumnNode* pcn = (SColumnNode*)p1;
G
Ganlin Zhao 已提交
6377 6378

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
H
Haojun Liao 已提交
6379
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, &pcn->node.resType);
G
Ganlin Zhao 已提交
6380 6381 6382
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
6383
          valueNodeToVariant(pvn, &pExp->base.pParam[j].param);
G
Ganlin Zhao 已提交
6384
        }
H
Haojun Liao 已提交
6385
      }
6386
    } else if (type == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
6387
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
6388
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
6389

G
Ganlin Zhao 已提交
6390 6391 6392
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

6393
      SDataType* pType = &pNode->node.resType;
dengyihao's avatar
dengyihao 已提交
6394 6395
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pNode->node.aliasName);
6396 6397 6398
      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6399 6400 6401
    }
  }

H
Haojun Liao 已提交
6402
  return pExprs;
H
Haojun Liao 已提交
6403 6404
}

6405
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model) {
wafwerar's avatar
wafwerar 已提交
6406
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
6407
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
6408

6409
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
6410
  pTaskInfo->id.queryId = queryId;
dengyihao's avatar
dengyihao 已提交
6411
  pTaskInfo->execModel = model;
H
Haojun Liao 已提交
6412

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

6417 6418
  return pTaskInfo;
}
H
Haojun Liao 已提交
6419

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

L
Liu Jicong 已提交
6423 6424
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                                  uint64_t queryId, uint64_t taskId);
6425 6426
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
static SArray* extractScanColumnId(SNodeList* pNodeList);
H
Haojun Liao 已提交
6427
static SArray* extractColumnInfo(SNodeList* pNodeList);
H
Haojun Liao 已提交
6428
static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols);
6429

6430
static SArray* createSortInfo(SNodeList* pNodeList, SNodeList* pNodeListTarget);
6431
static SArray* createIndexMap(SNodeList* pNodeList);
6432
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445
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 已提交
6446

H
Haojun Liao 已提交
6447
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
6448
                                  uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
6449 6450
  int32_t type = nodeType(pPhyNode);

X
Xiaoyu Wang 已提交
6451
  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
H
Haojun Liao 已提交
6452
    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
dengyihao's avatar
dengyihao 已提交
6453 6454
      SScanPhysiNode*      pScanPhyNode = (SScanPhysiNode*)pPhyNode;
      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6455

6456
      int32_t numOfCols = 0;
H
Haojun Liao 已提交
6457
      tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
6458
      if (pDataReader == NULL && terrno != 0) {
6459 6460
        return NULL;
      }
6461

dengyihao's avatar
dengyihao 已提交
6462 6463
      SArray* pColList =
          extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
6464
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6465

6466 6467 6468 6469 6470
      SQueryTableDataCond cond = {0};
      int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
      if (code != TSDB_CODE_SUCCESS) {
        return NULL;
      }
6471

6472 6473
      SInterval interval = extractIntervalInfo(pTableScanNode);
      return createTableScanOperatorInfo(pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList,
H
Haojun Liao 已提交
6474
                                         pResBlock, pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo);
H
Haojun Liao 已提交
6475
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
H
Haojun Liao 已提交
6476
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
6477
      SSDataBlock*        pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
6478
      return createExchangeOperatorInfo(pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
H
Haojun Liao 已提交
6479
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
H
Haojun Liao 已提交
6480
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
6481

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

6485
      SSDataBlock* pResBlock = createResDataBlock(pScanPhyNode->node.pOutputDataBlockDesc);
6486 6487

      int32_t numOfCols = 0;
6488 6489
      SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
      SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo);
6490
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
6491
      return pOperator;
H
Haojun Liao 已提交
6492
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
L
Liu Jicong 已提交
6493
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
6494
      SScanPhysiNode* pScanNode = &pSysScanPhyNode->scan;
H
Haojun Liao 已提交
6495

6496 6497
      SSDataBlock* pResBlock = createResDataBlock(pScanNode->node.pOutputDataBlockDesc);
      SArray* colList = extractScanColumnId(pScanNode->pScanCols);
6498

L
Liu Jicong 已提交
6499
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
6500
          pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
L
Liu Jicong 已提交
6501
          colList, pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
6502 6503 6504
      return pOperator;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
6505 6506 6507
    }
  }

6508 6509
  int32_t num = 0;
  size_t  size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
6510

6511
  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
dengyihao's avatar
dengyihao 已提交
6512
  for (int32_t i = 0; i < size; ++i) {
6513 6514
    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
6515 6516 6517
    if (ops[i] == NULL) {
      return NULL;
    }
6518
  }
H
Haojun Liao 已提交
6519

6520
  SOperatorInfo* pOptr = NULL;
H
Haojun Liao 已提交
6521
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
dengyihao's avatar
dengyihao 已提交
6522 6523
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*)pPhyNode;
    SExprInfo*         pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);
H
Haojun Liao 已提交
6524

6525
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
dengyihao's avatar
dengyihao 已提交
6526 6527
    SLimit       limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
    SLimit       slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
6528
    pOptr = createProjectOperatorInfo(ops[0], pExprInfo, num, pResBlock, &limit, &slimit, pTaskInfo);
H
Haojun Liao 已提交
6529 6530 6531
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == type) {
    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
    SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
6532
    SSDataBlock*   pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
6533

dengyihao's avatar
dengyihao 已提交
6534
    int32_t    numOfScalarExpr = 0;
6535 6536 6537 6538 6539
    SExprInfo* pScalarExprInfo = NULL;
    if (pAggNode->pExprs != NULL) {
      pScalarExprInfo = createExprInfo(pAggNode->pExprs, NULL, &numOfScalarExpr);
    }

H
Haojun Liao 已提交
6540 6541
    if (pAggNode->pGroupKeys != NULL) {
      SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
dengyihao's avatar
dengyihao 已提交
6542 6543
      pOptr = createGroupOperatorInfo(ops[0], pExprInfo, num, pResBlock, pColList, pAggNode->node.pConditions,
                                      pScalarExprInfo, numOfScalarExpr, pTaskInfo, NULL);
H
Haojun Liao 已提交
6544
    } else {
dengyihao's avatar
dengyihao 已提交
6545 6546
      pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pScalarExprInfo, numOfScalarExpr,
                                          pTaskInfo, pTableGroupInfo);
H
Haojun Liao 已提交
6547
    }
H
Haojun Liao 已提交
6548 6549
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == type) {
    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6550

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

dengyihao's avatar
dengyihao 已提交
6554 6555 6556 6557 6558 6559
    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 已提交
6560

dengyihao's avatar
dengyihao 已提交
6561 6562
    STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
                             .calTrigger = pIntervalPhyNode->window.triggerType};
6563

dengyihao's avatar
dengyihao 已提交
6564 6565 6566
    int32_t primaryTsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
    pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as,
                                       pTableGroupInfo, pTaskInfo);
6567 6568

    if (pIntervalPhyNode->pFill != NULL) {
dengyihao's avatar
dengyihao 已提交
6569 6570
      pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode, NULL,
                                     false, pTaskInfo);
6571 6572
    }

H
Haojun Liao 已提交
6573
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
H
Haojun Liao 已提交
6574
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
6575

6576
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6577
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys, pSortPhyNode->pTargets);
6578
    SArray*      slotMap = createIndexMap(pSortPhyNode->pTargets);
6579
    pOptr = createSortOperatorInfo(ops[0], pResBlock, info, slotMap, pTaskInfo);
H
Haojun Liao 已提交
6580
  } else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
H
Haojun Liao 已提交
6581 6582
    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

dengyihao's avatar
dengyihao 已提交
6583 6584
    STimeWindowAggSupp as = {.waterMark = pSessionNode->window.watermark,
                             .calTrigger = pSessionNode->window.triggerType};
6585

H
Haojun Liao 已提交
6586
    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
6587
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6588
    pOptr = createSessionAggOperatorInfo(ops[0], pExprInfo, num, pResBlock, pSessionNode->gap, &as, pTaskInfo);
H
Haojun Liao 已提交
6589
  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
dengyihao's avatar
dengyihao 已提交
6590 6591 6592
    SPartitionPhysiNode* pPartNode = (SPartitionPhysiNode*)pPhyNode;
    SArray*              pColList = extractPartitionColInfo(pPartNode->pPartitionKeys);
    SSDataBlock*         pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6593 6594

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

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

dengyihao's avatar
dengyihao 已提交
6601
    SExprInfo*   pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &num);
6602
    SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6603
    pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, pTaskInfo);
6604
  } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
dengyihao's avatar
dengyihao 已提交
6605 6606
    SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
    SSDataBlock*    pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
6607 6608

    SExprInfo* pExprInfo = createExprInfo(pJoinNode->pTargets, NULL, &num);
6609
    pOptr = createJoinOperatorInfo(ops, size, pExprInfo, num, pResBlock, pJoinNode->pOnConditions, pTaskInfo);
H
Haojun Liao 已提交
6610 6611
  } else {
    ASSERT(0);
H
Haojun Liao 已提交
6612
  }
6613 6614 6615

  taosMemoryFree(ops);
  return pOptr;
6616
}
H
Haojun Liao 已提交
6617 6618


6619 6620 6621 6622 6623 6624 6625
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 已提交
6626
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
6627 6628 6629 6630 6631 6632 6633 6634 6635 6636
    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 已提交
6637
  }
6638
#endif
H
Haojun Liao 已提交
6639

6640 6641
  pCond->type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
  //  pCond->type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
6642

H
Haojun Liao 已提交
6643
  int32_t j = 0;
6644
  for (int32_t i = 0; i < pCond->numOfCols; ++i) {
H
Haojun Liao 已提交
6645 6646
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
6647 6648 6649
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
6650

6651 6652 6653
    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 已提交
6654
    j += 1;
H
Haojun Liao 已提交
6655 6656
  }

6657 6658
  pCond->numOfCols = j;
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
6659
}
H
Haojun Liao 已提交
6660

6661
SArray* extractScanColumnId(SNodeList* pNodeList) {
L
Liu Jicong 已提交
6662
  size_t  numOfCols = LIST_LENGTH(pNodeList);
6663 6664 6665 6666 6667 6668
  SArray* pList = taosArrayInit(numOfCols, sizeof(int16_t));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
6669
  for (int32_t i = 0; i < numOfCols; ++i) {
X
Xiaoyu Wang 已提交
6670
    for (int32_t j = 0; j < numOfCols; ++j) {
L
Liu Jicong 已提交
6671
      STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, j);
X
Xiaoyu Wang 已提交
6672
      if (pNode->slotId == i) {
L
Liu Jicong 已提交
6673
        SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
X
Xiaoyu Wang 已提交
6674 6675 6676 6677
        taosArrayPush(pList, &pColNode->colId);
        break;
      }
    }
6678 6679 6680 6681 6682
  }

  return pList;
}

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

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

6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718
    if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN) {
      SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;

      // todo extract method
      SColumn c = {0};
      c.slotId  = pColNode->slotId;
      c.colId   = pColNode->colId;
      c.type    = pColNode->node.resType.type;
      c.bytes   = pColNode->node.resType.bytes;
      c.scale   = pColNode->node.resType.scale;
      c.precision = pColNode->node.resType.precision;

      taosArrayPush(pList, &c);
    } else if (nodeType(pNode->pExpr) == QUERY_NODE_VALUE) {
      SValueNode* pValNode = (SValueNode*) pNode->pExpr;
      SColumn c = {0};
      c.slotId = pNode->slotId;
      c.colId  = pNode->slotId;
      c.type   = pValNode->node.type;
      c.bytes  = pValNode->node.resType.bytes;
      c.scale  = pValNode->node.resType.scale;
      c.precision = pValNode->node.resType.precision;

      taosArrayPush(pList, &c);
    }
H
Haojun Liao 已提交
6719 6720 6721 6722 6723
  }

  return pList;
}

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

    taosArrayPush(pList, &c);
  }

  return pList;
}

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

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

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

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

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

  return pList;
}

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

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

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

H
Haojun Liao 已提交
6824 6825
  *numOfOutputCols = 0;
  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
6826 6827
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
6828
    // todo: add reserve flag check
dengyihao's avatar
dengyihao 已提交
6829
    if (pNode->slotId >= numOfCols) {  // it is a column reserved for the arithmetic expression calculation
6830 6831 6832 6833
      (*numOfOutputCols) += 1;
      continue;
    }

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

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

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

  return code;
}
H
Haojun Liao 已提交
6856

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

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

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

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

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

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

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

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

H
Haojun Liao 已提交
6925 6926
  return code;

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

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

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

  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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 已提交
7063
    while (1) {
7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089
      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 已提交
7090

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

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

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

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

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

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

  return TSDB_CODE_SUCCESS;
D
dapan1121 已提交
7127 7128
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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