executorimpl.c 279.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 18 19 20
#include "filter.h"
#include "functionMgt.h"
#include "function.h"
#include "querynodes.h"
#include "tname.h"
21
#include "os.h"
22

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

31 32
#include "executorimpl.h"
#include "function.h"
33
#include "query.h"
34 35
#include "tcompare.h"
#include "tcompression.h"
H
Haojun Liao 已提交
36
#include "thash.h"
37
#include "tsdb.h"
38
#include "ttypes.h"
L
Liu Jicong 已提交
39
#include "vnode.h"
40

H
Haojun Liao 已提交
41
#define IS_MAIN_SCAN(runtime)          ((runtime)->scanFlag == MAIN_SCAN)
42 43
#define IS_REVERSE_SCAN(runtime)       ((runtime)->scanFlag == REVERSE_SCAN)
#define IS_REPEAT_SCAN(runtime)        ((runtime)->scanFlag == REPEAT_SCAN)
L
Liu Jicong 已提交
44
#define SET_MAIN_SCAN_FLAG(runtime)    ((runtime)->scanFlag = MAIN_SCAN)
45 46 47 48
#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 已提交
49 50
#define SDATA_BLOCK_INITIALIZER \
  (SDataBlockInfo) { {0}, 0 }
51 52 53

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

L
Liu Jicong 已提交
54
#define MULTI_KEY_DELIM "-"
55 56

enum {
L
Liu Jicong 已提交
57 58
  TS_JOIN_TS_EQUAL = 0,
  TS_JOIN_TS_NOT_EQUALS = 1,
59 60 61 62 63
  TS_JOIN_TAG_NOT_EQUALS = 2,
};

typedef enum SResultTsInterpType {
  RESULT_ROW_START_INTERP = 1,
L
Liu Jicong 已提交
64
  RESULT_ROW_END_INTERP = 2,
65 66
} SResultTsInterpType;

H
Haojun Liao 已提交
67

68 69
#if 0
static UNUSED_FUNC void *u_malloc (size_t __size) {
wafwerar's avatar
wafwerar 已提交
70
  uint32_t v = taosRand();
71 72 73 74

  if (v % 1000 <= 0) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
75
    return taosMemoryMalloc(__size);
76 77 78 79
  }
}

static UNUSED_FUNC void* u_calloc(size_t num, size_t __size) {
wafwerar's avatar
wafwerar 已提交
80
  uint32_t v = taosRand();
81 82 83
  if (v % 1000 <= 0) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
84
    return taosMemoryCalloc(num, __size);
85 86 87 88
  }
}

static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
wafwerar's avatar
wafwerar 已提交
89
  uint32_t v = taosRand();
90 91 92
  if (v % 5 <= 1) {
    return NULL;
  } else {
wafwerar's avatar
wafwerar 已提交
93
    return taosMemoryRealloc(p, __size);
94 95 96 97 98 99 100 101 102 103 104 105
  }
}

#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 已提交
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 145 146 147 148 149 150
#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) {
151
  assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
152
  return 0;
153 154
}

H
Haojun Liao 已提交
155 156 157 158 159
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;
160 161 162
    return;
  }

H
Haojun Liao 已提交
163
  int64_t key = tw->skey, interval = pInterval->interval;
L
Liu Jicong 已提交
164
  // convert key to second
H
Haojun Liao 已提交
165
  key = convertTimePrecision(key, precision, TSDB_TIME_PRECISION_MILLI) / 1000;
166

H
Haojun Liao 已提交
167
  if (pInterval->intervalUnit == 'y') {
168 169 170 171
    interval *= 12;
  }

  struct tm tm;
L
Liu Jicong 已提交
172
  time_t    t = (time_t)key;
wafwerar's avatar
wafwerar 已提交
173
  taosLocalTime(&t, &tm);
174 175 176 177

  int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
  tm.tm_year = mon / 12;
  tm.tm_mon = mon % 12;
H
Haojun Liao 已提交
178
  tw->skey = convertTimePrecision((int64_t)mktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, precision);
179 180 181 182

  mon = (int)(mon + interval);
  tm.tm_year = mon / 12;
  tm.tm_mon = mon % 12;
H
Haojun Liao 已提交
183
  tw->ekey = convertTimePrecision((int64_t)mktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, precision);
184 185 186 187 188

  tw->ekey -= 1;
}

static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes);
L
Liu Jicong 已提交
189 190 191
void        setResultRowOutputBufInitCtx(STaskRuntimeEnv* pRuntimeEnv, SResultRow* pResult, SqlFunctionCtx* pCtx,
                                         int32_t numOfOutput, int32_t* rowCellInfoOffset);
static bool functionNeedToExecute(SqlFunctionCtx* pCtx);
192

L
Liu Jicong 已提交
193
static void setBlockStatisInfo(SqlFunctionCtx* pCtx, SSDataBlock* pSDataBlock, SColumn* pColumn);
194

L
Liu Jicong 已提交
195 196
static void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo);
static bool hasMainOutput(STaskAttr* pQueryAttr);
197 198 199

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

L
Liu Jicong 已提交
200 201 202 203
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);
// static STsdbQueryCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win);
204 205
static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo);

H
Haojun Liao 已提交
206
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr);
207 208 209 210 211 212 213 214 215

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

H
Haojun Liao 已提交
217
static void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput);
H
Haojun Liao 已提交
218 219 220
static void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput);
static void destroyConditionOperatorInfo(void* param, int32_t numOfOutput);

221
static void destroyOperatorInfo(SOperatorInfo* pOperator);
222
static void destroySysTableScannerOperatorInfo(void* param, int32_t numOfOutput);
223 224 225

static void doSetOperatorCompleted(SOperatorInfo* pOperator) {
  pOperator->status = OP_EXEC_DONE;
H
Haojun Liao 已提交
226
  if (pOperator->pTaskInfo != NULL) {
227
    setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
228 229
  }
}
230 231 232
#define OPTR_IS_OPENED(_optr)  (((_optr)->status & OP_OPENED) == OP_OPENED)
#define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)

H
Haojun Liao 已提交
233
int32_t operatorDummyOpenFn(SOperatorInfo* pOperator) {
234
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
235
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
236 237
}

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

L
Liu Jicong 已提交
240 241
static int32_t doCopyToSDataBlock(SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, int32_t orderType,
                                  SSDataBlock* pBlock, int32_t rowCapacity, int32_t* rowCellOffset);
242

L
Liu Jicong 已提交
243 244 245
static void    initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
static void    getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, int64_t keyFirst,
                                       int64_t keyLast, STimeWindow* win);
H
Haojun Liao 已提交
246

H
Haojun Liao 已提交
247
static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo);
H
Haojun Liao 已提交
248
static void setCtxTagForJoin(STaskRuntimeEnv* pRuntimeEnv, SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable);
L
Liu Jicong 已提交
249 250
static void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, int32_t tableGroupId,
                                     SExecTaskInfo* pTaskInfo);
251

H
Haojun Liao 已提交
252
SArray* getOrderCheckColumns(STaskAttr* pQuery);
253 254

typedef struct SRowCompSupporter {
L
Liu Jicong 已提交
255 256 257
  STaskRuntimeEnv* pRuntimeEnv;
  int16_t          dataOffset;
  __compar_fn_t    comFunc;
258 259
} SRowCompSupporter;

L
Liu Jicong 已提交
260 261 262
static int compareRowData(const void* a, const void* b, const void* userData) {
  const SResultRow* pRow1 = (const SResultRow*)a;
  const SResultRow* pRow2 = (const SResultRow*)b;
263

L
Liu Jicong 已提交
264 265
  SRowCompSupporter* supporter = (SRowCompSupporter*)userData;
  STaskRuntimeEnv*   pRuntimeEnv = supporter->pRuntimeEnv;
266

L
Liu Jicong 已提交
267 268
  SFilePage* page1 = getBufPage(pRuntimeEnv->pResultBuf, pRow1->pageId);
  SFilePage* page2 = getBufPage(pRuntimeEnv->pResultBuf, pRow2->pageId);
269 270

  int16_t offset = supporter->dataOffset;
L
Liu Jicong 已提交
271 272
  char*   in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
  char*   in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
273 274 275 276

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

L
Liu Jicong 已提交
277
// setup the output buffer for each operator
H
Haojun Liao 已提交
278 279
SSDataBlock* createOutputBuf_rv1(SDataBlockDescNode* pNode) {
  int32_t numOfCols = LIST_LENGTH(pNode->pSlots);
H
Haojun Liao 已提交
280

wafwerar's avatar
wafwerar 已提交
281
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
H
Haojun Liao 已提交
282 283 284
  pBlock->info.numOfCols = numOfCols;
  pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));

H
Haojun Liao 已提交
285
  pBlock->info.blockId = pNode->dataBlockId;
X
Xiaoyu Wang 已提交
286
  pBlock->info.rowSize = pNode->totalRowSize;   // todo ??
H
Haojun Liao 已提交
287

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

295
    idata.info.type  = pDescNode->dataType.type;
L
Liu Jicong 已提交
296 297
    idata.info.bytes = pDescNode->dataType.bytes;
    idata.info.scale = pDescNode->dataType.scale;
H
Haojun Liao 已提交
298
    idata.info.slotId = pDescNode->slotId;
H
Haojun Liao 已提交
299 300 301
    idata.info.precision = pDescNode->dataType.precision;

    taosArrayPush(pBlock->pDataBlock, &idata);
H
Haojun Liao 已提交
302
  }
H
Haojun Liao 已提交
303 304

  return pBlock;
H
Haojun Liao 已提交
305 306
}

L
Liu Jicong 已提交
307
static bool isSelectivityWithTagsQuery(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
308
  return true;
L
Liu Jicong 已提交
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
  //  bool    hasTags = false;
  //  int32_t numOfSelectivity = 0;
  //
  //  for (int32_t i = 0; i < numOfOutput; ++i) {
  //    int32_t functId = pCtx[i].functionId;
  //    if (functId == FUNCTION_TAG_DUMMY || functId == FUNCTION_TS_DUMMY) {
  //      hasTags = true;
  //      continue;
  //    }
  //
  //    if ((aAggs[functId].status & FUNCSTATE_SELECTIVITY) != 0) {
  //      numOfSelectivity++;
  //    }
  //  }
  //
  //  return (numOfSelectivity > 0 && hasTags);
}

static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
  if (TSDB_COL_IS_TAG(pColumn->flag) || TSDB_COL_IS_UD_COL(pColumn->flag) ||
      pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
330 331 332 333 334 335 336 337 338 339
    return false;
  }

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

  return true;
}

H
Haojun Liao 已提交
340
static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, jmp_buf env) {
341 342
  int64_t newCapacity = 0;

343 344 345 346 347 348 349 350 351 352 353
  // 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);
  }

H
Haojun Liao 已提交
354 355 356 357
  if (newCapacity == pResultRowInfo->capacity) {
    newCapacity += 4;
  }

wafwerar's avatar
wafwerar 已提交
358
  pResultRowInfo->pPosition = taosMemoryRealloc(pResultRowInfo->pPosition, newCapacity * sizeof(SResultRowPosition));
359 360

  int32_t inc = (int32_t)newCapacity - pResultRowInfo->capacity;
361
  memset(&pResultRowInfo->pPosition[pResultRowInfo->capacity], 0, sizeof(SResultRowPosition));
362 363 364
  pResultRowInfo->capacity = (int32_t)newCapacity;
}

L
Liu Jicong 已提交
365 366
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
                                int16_t bytes, bool masterscan, uint64_t uid) {
367 368 369
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);

L
Liu Jicong 已提交
370 371
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
372 373 374 375 376 377 378 379 380 381 382

  // 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) {
H
Haojun Liao 已提交
383
//        existed = (pResultRowInfo->pResult[0] == (*p1));
384 385
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid, pResultRowInfo);
L
Liu Jicong 已提交
386 387
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
388 389 390 391 392 393 394 395 396 397 398 399 400 401
        if (index != NULL) {
          existed = true;
        } else {
          existed = false;
        }
      }
    }

    return existed;
  }

  return p1 != NULL;
}

H
Haojun Liao 已提交
402
#if 0
H
Haojun Liao 已提交
403
static SResultRow* doSetResultOutBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, int64_t tid,
404 405 406 407
                                          char* pData, int16_t bytes, bool masterscan, uint64_t tableGroupId) {
  bool existed = false;
  SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tableGroupId);

L
Liu Jicong 已提交
408 409
  SResultRow** p1 =
      (SResultRow**)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
410 411 412 413

  // 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.
L
Liu Jicong 已提交
414
      return (p1 != NULL) ? *p1 : NULL;
415 416 417 418 419
    }

    if (p1 != NULL) {
      if (pResultRowInfo->size == 0) {
        existed = false;
H
Haojun Liao 已提交
420
//        assert(pResultRowInfo->curPos == -1);
421
      } else if (pResultRowInfo->size == 1) {
H
Haojun Liao 已提交
422 423
//        existed = (pResultRowInfo->pResult[0] == (*p1));
//        pResultRowInfo->curPos = 0;
424 425
      } else {  // check if current pResultRowInfo contains the existed pResultRow
        SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tid, pResultRowInfo);
L
Liu Jicong 已提交
426 427
        int64_t* index =
            taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
428
        if (index != NULL) {
H
Haojun Liao 已提交
429
//          pResultRowInfo->curPos = (int32_t)*index;
430 431 432 433 434 435 436 437 438 439 440 441 442 443
          existed = true;
        } else {
          existed = false;
        }
      }
    }
  } else {
    // In case of group by column query, the required SResultRow object must be existed in the pResultRowInfo object.
    if (p1 != NULL) {
      return *p1;
    }
  }

  if (!existed) {
L
Liu Jicong 已提交
444
    //    prepareResultListBuffer(pResultRowInfo, pRuntimeEnv);
445

L
Liu Jicong 已提交
446
    SResultRow* pResult = NULL;
447 448 449 450 451 452 453 454
    if (p1 == NULL) {
      pResult = getNewResultRow(pRuntimeEnv->pool);
      int32_t ret = initResultRow(pResult);
      if (ret != TSDB_CODE_SUCCESS) {
        longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
      }

      // add a new result set for a new group
L
Liu Jicong 已提交
455 456
      taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pResult,
                  POINTER_BYTES);
457 458 459 460 461 462 463 464 465 466 467
      SResultRowCell cell = {.groupId = tableGroupId, .pRow = pResult};
      taosArrayPush(pRuntimeEnv->pResultRowArrayList, &cell);
    } else {
      pResult = *p1;
    }

    pResultRowInfo->curPos = pResultRowInfo->size;
    pResultRowInfo->pResult[pResultRowInfo->size++] = pResult;

    int64_t index = pResultRowInfo->curPos;
    SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tid, pResultRowInfo);
L
Liu Jicong 已提交
468 469
    taosHashPut(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes), &index,
                POINTER_BYTES);
470 471 472 473 474 475 476 477 478
  }

  // too many time window in query
  if (pResultRowInfo->size > MAX_INTERVAL_TIME_WINDOW) {
    longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
  }

  return pResultRowInfo->pResult[pResultRowInfo->curPos];
}
H
Haojun Liao 已提交
479
#endif
480

481
SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, int32_t interBufSize) {
L
Liu Jicong 已提交
482
  SFilePage* pData = NULL;
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520

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

    if (pData->num + interBufSize + sizeof(SResultRow) > getBufPageSize(pResultBuf)) {
      // 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;

  pData->num += interBufSize + sizeof(SResultRow);

  return pResultRow;
}

L
Liu Jicong 已提交
521 522 523
static SResultRow* doSetResultOutBufByKey_rv(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, int64_t tid,
                                             char* pData, int16_t bytes, bool masterscan, uint64_t tableGroupId,
                                             SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup) {
H
Haojun Liao 已提交
524
  bool existInCurrentResusltRowInfo = false;
525
  SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, tableGroupId);
H
Haojun Liao 已提交
526

H
Haojun Liao 已提交
527
  SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
H
Haojun Liao 已提交
528 529 530 531

  // in case of repeat scan/reverse scan, no new time window added.
  if (isIntervalQuery) {
    if (!masterscan) {  // the *p1 may be NULL in case of sliding+offset exists.
H
Haojun Liao 已提交
532 533 534 535 536
      if (p1 != NULL) {
        return getResultRowByPos(pResultBuf, p1);
      } else {
        return NULL;
      }
H
Haojun Liao 已提交
537 538 539 540
    }

    if (p1 != NULL) {
      if (pResultRowInfo->size == 0) {
H
Haojun Liao 已提交
541
        existInCurrentResusltRowInfo = false;  // this time window created by other timestamp that does not belongs to current table.
H
Haojun Liao 已提交
542 543
        assert(pResultRowInfo->curPos == -1);
      } else if (pResultRowInfo->size == 1) {
H
Haojun Liao 已提交
544 545 546
        ASSERT(0);
//        existInCurrentResusltRowInfo = (pResultRowInfo->pResult[0] == (*p1));
      } else {  // check if current pResultRowInfo contains the existInCurrentResusltRowInfo pResultRow
547 548
        SET_RES_EXT_WINDOW_KEY(pSup->keyBuf, pData, bytes, tid, pResultRowInfo);
        int64_t* index = taosHashGet(pSup->pResultRowListSet, pSup->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes));
H
Haojun Liao 已提交
549
        if (index != NULL) {
H
Haojun Liao 已提交
550 551 552
          // TODO check the scan order for current opened time window
//          pResultRowInfo->curPos = (int32_t)*index;
          existInCurrentResusltRowInfo = true;
H
Haojun Liao 已提交
553
        } else {
H
Haojun Liao 已提交
554
          existInCurrentResusltRowInfo = false;
H
Haojun Liao 已提交
555 556 557 558
        }
      }
    }
  } else {
H
Haojun Liao 已提交
559
    // In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the pResultRowInfo object.
H
Haojun Liao 已提交
560
    if (p1 != NULL) {
H
Haojun Liao 已提交
561
      return getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
562 563 564
    }
  }

H
Haojun Liao 已提交
565 566 567 568 569 570 571 572 573 574
  SResultRow* pResult = NULL;
  if (!existInCurrentResusltRowInfo) {
    // 1. close current opened time window
    if (pResultRowInfo->curPos != -1) {  // todo extract function
      SResultRowPosition* pos = &pResultRowInfo->pPosition[pResultRowInfo->curPos];
      SFilePage* pPage = getBufPage(pResultBuf, pos->pageId);
      SResultRow* pRow = (SResultRow*)((char*)pPage + pos->offset);
      closeResultRow(pRow);
      releaseBufPage(pResultBuf, pPage);
    }
H
Haojun Liao 已提交
575

H
Haojun Liao 已提交
576
    prepareResultListBuffer(pResultRowInfo, pTaskInfo->env);
H
Haojun Liao 已提交
577
    if (p1 == NULL) {
578
      pResult = getNewResultRow_rv(pResultBuf, tableGroupId, pSup->resultRowSize);
H
Haojun Liao 已提交
579
      initResultRow(pResult);
H
Haojun Liao 已提交
580 581

      // add a new result set for a new group
H
Haojun Liao 已提交
582 583 584
      SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
      taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos, POINTER_BYTES);
      SResultRowCell cell = {.groupId = tableGroupId, .pos = pos};
585
      taosArrayPush(pSup->pResultRowArrayList, &cell);
H
Haojun Liao 已提交
586
    } else {
H
Haojun Liao 已提交
587
      pResult = getResultRowByPos(pResultBuf, p1);
H
Haojun Liao 已提交
588 589
    }

H
Haojun Liao 已提交
590
    // 2. set the new time window to be the new active time window
H
Haojun Liao 已提交
591
    pResultRowInfo->curPos = pResultRowInfo->size;
H
Haojun Liao 已提交
592
    pResultRowInfo->pPosition[pResultRowInfo->size++] = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
H
Haojun Liao 已提交
593 594

    int64_t index = pResultRowInfo->curPos;
595 596
    SET_RES_EXT_WINDOW_KEY(pSup->keyBuf, pData, bytes, tid, pResultRowInfo);
    taosHashPut(pSup->pResultRowListSet, pSup->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes), &index, POINTER_BYTES);
H
Haojun Liao 已提交
597 598 599 600 601 602 603
  }

  // 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 已提交
604
  return pResult;
H
Haojun Liao 已提交
605 606
}

L
Liu Jicong 已提交
607 608
static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, TSKEY ts, STimeWindow* w, TSKEY ekey,
                                      bool ascQuery) {
H
Haojun Liao 已提交
609 610
  if (ascQuery) {
    getAlignQueryTimeWindow(pInterval, precision, ts, ts, ekey, w);
611 612
  } else {
    // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
H
Haojun Liao 已提交
613
    getAlignQueryTimeWindow(pInterval, precision, ts, ekey, ts, w);
614 615

    int64_t key = w->skey;
L
Liu Jicong 已提交
616
    while (key < ts) {  // moving towards end
617
      key = taosTimeAdd(key, pInterval->sliding, pInterval->slidingUnit, precision);
618 619 620 621 622 623 624 625 626 627
      if (key >= ts) {
        break;
      }

      w->skey = key;
    }
  }
}

// get the correct time window according to the handled timestamp
H
Haojun Liao 已提交
628
static STimeWindow getActiveTimeWindow(SDiskbasedBuf * pBuf, SResultRowInfo* pResultRowInfo, int64_t ts, SInterval* pInterval,
L
Liu Jicong 已提交
629
                                       int32_t precision, STimeWindow* win) {
630 631
  STimeWindow w = {0};

L
Liu Jicong 已提交
632
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
H
Haojun Liao 已提交
633
    getInitialStartTimeWindow(pInterval, precision, ts, &w, win->ekey, true);
634
    w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
635
  } else {
H
Haojun Liao 已提交
636
    w = getResultRow(pBuf, pResultRowInfo, pResultRowInfo->curPos)->win;
637 638 639
  }

  if (w.skey > ts || w.ekey < ts) {
H
Haojun Liao 已提交
640 641 642
    if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
      w.skey = taosTimeTruncate(ts, pInterval, precision);
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
643 644 645 646
    } else {
      int64_t st = w.skey;

      if (st > ts) {
H
Haojun Liao 已提交
647
        st -= ((st - ts + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
648 649
      }

H
Haojun Liao 已提交
650
      int64_t et = st + pInterval->interval - 1;
651
      if (et < ts) {
H
Haojun Liao 已提交
652
        st += ((ts - et + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
653 654 655
      }

      w.skey = st;
656
      w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
657 658 659 660 661 662
    }
  }
  return w;
}

// get the correct time window according to the handled timestamp
L
Liu Jicong 已提交
663
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo* pResultRowInfo, int64_t ts, STaskAttr* pQueryAttr) {
664
  STimeWindow w = {0};
H
Haojun Liao 已提交
665
#if 0
L
Liu Jicong 已提交
666 667
  if (pResultRowInfo->curPos == -1) {  // the first window, from the previous stored value
                                       //    getInitialStartTimeWindow(pQueryAttr, ts, &w);
668 669

    if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') {
L
Liu Jicong 已提交
670 671 672
      w.ekey =
          taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) -
          1;
673 674 675 676
    } else {
      w.ekey = w.skey + pQueryAttr->interval.interval - 1;
    }
  } else {
H
Haojun Liao 已提交
677
    w = pRow->win;
678 679 680 681 682 683 684 685 686
  }

  /*
   * 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 已提交
687
#endif
688 689 690 691 692

  return w;
}

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

L
Liu Jicong 已提交
698
  SFilePage* pData = NULL;
699 700 701 702 703 704

  // 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 已提交
705
    pData = getNewBufPage(pResultBuf, tid, &pageId);
706
    pData->num = sizeof(SFilePage);
707 708
  } else {
    SPageInfo* pi = getLastPageInfo(list);
709
    pData = getBufPage(pResultBuf, getPageId(pi));
710
    pageId = getPageId(pi);
711

712
    if (pData->num + size > getBufPageSize(pResultBuf)) {
713
      // release current page first, and prepare the next one
714
      releaseBufPageInfo(pResultBuf, pi);
715

H
Haojun Liao 已提交
716
      pData = getNewBufPage(pResultBuf, tid, &pageId);
717
      if (pData != NULL) {
718
        pData->num = sizeof(SFilePage);
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
      }
    }
  }

  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 已提交
739 740 741
static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, STimeWindow* win,
                                    bool masterscan, SResultRow** pResult, int64_t groupId, SqlFunctionCtx* pCtx,
                                    int32_t numOfOutput, int32_t* rowCellInfoOffset) {
742
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
743
  return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char*)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
744 745
}

L
Liu Jicong 已提交
746 747 748
static int32_t setResultOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, int64_t tid,
                                       STimeWindow* win, bool masterscan, SResultRow** pResult, int64_t tableGroupId,
                                       SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) {
749
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
750
  SDiskbasedBuf* pResultBuf = pRuntimeEnv->pResultBuf;
751

H
Haojun Liao 已提交
752 753
  SResultRow* pResultRow = NULL;//doSetResultOutBufByKey(pRuntimeEnv, pResultRowInfo, tid, (char*)&win->skey, TSDB_KEYSIZE,
//                                                  masterscan, tableGroupId);
754 755 756 757 758 759 760
  if (pResultRow == NULL) {
    *pResult = NULL;
    return TSDB_CODE_SUCCESS;
  }

  // not assign result buffer yet, add new result buffer
  if (pResultRow->pageId == -1) {
L
Liu Jicong 已提交
761 762
    int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, (int32_t)tableGroupId,
                                        pRuntimeEnv->pQueryAttr->intermediateResultRowSize);
763 764 765 766 767 768 769 770 771 772 773 774 775
    if (ret != TSDB_CODE_SUCCESS) {
      return -1;
    }
  }

  // set time window for current result
  pResultRow->win = (*win);
  *pResult = pResultRow;
  setResultRowOutputBufInitCtx(pRuntimeEnv, pResultRow, pCtx, numOfOutput, rowCellInfoOffset);

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
776
static void setResultRowOutputBufInitCtx_rv(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset);
H
Haojun Liao 已提交
777

L
Liu Jicong 已提交
778 779 780 781
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 已提交
782
  assert(win->skey <= win->ekey);
L
Liu Jicong 已提交
783 784
  SResultRow* pResultRow = doSetResultOutBufByKey_rv(pAggSup->pResultBuf, pResultRowInfo, id, (char*)&win->skey,
                                                     TSDB_KEYSIZE, masterscan, tableGroupId, pTaskInfo, true, pAggSup);
H
Haojun Liao 已提交
785 786 787 788 789 790 791 792 793

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

  // set time window for current result
  pResultRow->win = (*win);
  *pResult = pResultRow;
H
Haojun Liao 已提交
794
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
H
Haojun Liao 已提交
795 796 797
  return TSDB_CODE_SUCCESS;
}

798 799 800 801 802
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 已提交
803
    pResult->endInterp = true;
804 805 806 807 808 809 810 811
  }
}

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 已提交
812
    return pResult->endInterp == true;
813 814 815
  }
}

L
Liu Jicong 已提交
816 817
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) {
818 819 820
  int32_t forwardStep = 0;

  if (order == TSDB_ORDER_ASC) {
L
Liu Jicong 已提交
821
    int32_t end = searchFn((char*)&pData[pos], numOfRows - pos, ekey, order);
822 823 824 825 826 827 828 829
    if (end >= 0) {
      forwardStep = end;

      if (pData[end + pos] == ekey) {
        forwardStep += 1;
      }
    }
  } else {
L
Liu Jicong 已提交
830
    int32_t end = searchFn((char*)pData, pos + 1, ekey, order);
831 832 833 834 835 836 837 838 839 840 841 842 843
    if (end >= 0) {
      forwardStep = pos - end;

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

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

H
Haojun Liao 已提交
844
static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey, bool ascQuery, bool timeWindowInterpo) {
845
  int64_t skey = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
846
#if 0
847 848
  int32_t i = 0;
  for (i = pResultRowInfo->size - 1; i >= 0; --i) {
L
Liu Jicong 已提交
849
    SResultRow* pResult = pResultRowInfo->pResult[i];
850 851 852 853 854 855
    if (pResult->closed) {
      break;
    }

    // new closed result rows
    if (timeWindowInterpo) {
L
Liu Jicong 已提交
856 857 858
      if (pResult->endInterp &&
          ((pResult->win.skey <= lastKey && ascQuery) || (pResult->win.skey >= lastKey && !ascQuery))) {
        if (i > 0) {  // the first time window, the startInterp is false.
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
          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 已提交
878
      //      assert(pResultRowInfo->current == NULL);
879 880 881 882 883 884 885
      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 已提交
886
      SResultRow* pResult = pResultRowInfo->pResult[i];
887 888 889 890 891 892 893 894 895 896 897
      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 已提交
898
#endif
899 900
}

L
Liu Jicong 已提交
901 902
static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
                                           bool ascQuery, bool interp) {
H
Haojun Liao 已提交
903
  if ((lastKey > pWin->ekey && ascQuery) || (lastKey < pWin->ekey && (!ascQuery))) {
904 905 906 907
    closeAllResultRows(pResultRowInfo);
    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  } else {
    int32_t step = ascQuery ? 1 : -1;
H
Haojun Liao 已提交
908
    doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, interp);
909 910 911
  }
}

L
Liu Jicong 已提交
912 913 914
static int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos,
                                        TSKEY ekey, __block_search_fn_t searchFn, STableQueryInfo* item,
                                        int32_t order) {
915 916
  assert(startPos >= 0 && startPos < pDataBlockInfo->rows);

L
Liu Jicong 已提交
917 918
  int32_t num = -1;
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
919

H
Haojun Liao 已提交
920
  if (order == TSDB_ORDER_ASC) {
921 922
    if (ekey < pDataBlockInfo->window.ekey && pPrimaryColumn) {
      num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
H
Haojun Liao 已提交
923
      if (item != NULL) {
924 925 926 927
        item->lastKey = pPrimaryColumn[startPos + (num - 1)] + step;
      }
    } else {
      num = pDataBlockInfo->rows - startPos;
H
Haojun Liao 已提交
928
      if (item != NULL) {
929 930 931 932 933 934
        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 已提交
935
      if (item != NULL) {
936 937 938 939
        item->lastKey = pPrimaryColumn[startPos - (num - 1)] + step;
      }
    } else {
      num = startPos + 1;
H
Haojun Liao 已提交
940
      if (item != NULL) {
941 942 943 944 945 946 947 948 949
        item->lastKey = pDataBlockInfo->window.skey + step;
      }
    }
  }

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

950 951 952 953 954
//  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);

H
Haojun Liao 已提交
955
  colInfoDataEnsureCapacity(pColData, 5);
956 957 958 959 960 961 962 963 964
  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);
}

965
static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, bool includeEndpoint) {
966
  int64_t* ts = (int64_t*)pColData->pData;
967
  int32_t delta = includeEndpoint? 1:0;
968

969
  int64_t duration = pWin->ekey - pWin->skey + delta;
970 971
  ts[2] = duration;       // set the duration
  ts[3] = pWin->skey;     // window start key
972
  ts[4] = pWin->ekey + delta; // window end key
973 974
}

H
Haojun Liao 已提交
975
void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset, int32_t forwardStep, TSKEY* tsCol,
976
                             int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
977 978 979 980
  for (int32_t k = 0; k < numOfOutput; ++k) {
    pCtx[k].startTs = pWin->skey;

    // keep it temporarialy
981 982
    bool    hasAgg      = pCtx[k].input.colDataAggIsSet;
    int32_t numOfRows   = pCtx[k].input.numOfRows;
H
Haojun Liao 已提交
983
    int32_t startOffset = pCtx[k].input.startRowIndex;
984

H
Haojun Liao 已提交
985
    int32_t pos = (order == TSDB_ORDER_ASC) ? offset : offset - (forwardStep - 1);
986 987
    pCtx[k].input.startRowIndex = pos;
    pCtx[k].input.numOfRows = forwardStep;
988 989

    if (tsCol != NULL) {
H
Haojun Liao 已提交
990
      pCtx[k].ptsList = tsCol;
991 992 993 994 995 996 997 998
    }

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

999 1000 1001 1002
    if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) {
      SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[k]);
      char* p = GET_ROWCELL_INTERBUF(pEntryInfo);

1003 1004 1005 1006 1007 1008 1009 1010
      SColumnInfoData idata = {0};
      idata.info.type  = TSDB_DATA_TYPE_BIGINT;
      idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
      idata.pData      = p;

      SScalarParam out = {.columnData = &idata};
      SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData};
      pCtx[k].sfp.process(&tw, 1, &out);
1011 1012 1013 1014 1015
      pEntryInfo->numOfRes = 1;
      pEntryInfo->hasResult = ',';
      continue;
    }

H
Haojun Liao 已提交
1016
    if (functionNeedToExecute(&pCtx[k])) {
1017
      pCtx[k].fpSet.process(&pCtx[k]);
1018 1019 1020
    }

    // restore it
1021 1022 1023
    pCtx[k].input.colDataAggIsSet = hasAgg;
    pCtx[k].input.startRowIndex = startOffset;
    pCtx[k].input.numOfRows = numOfRows;
1024 1025 1026
  }
}

H
Haojun Liao 已提交
1027 1028 1029
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 已提交
1030
  bool    ascQuery = (order == TSDB_ORDER_ASC);
H
Haojun Liao 已提交
1031

1032
  int32_t precision = pInterval->precision;
H
Haojun Liao 已提交
1033
  getNextTimeWindow(pInterval, precision, order, pNext);
1034 1035

  // next time window is not in current block
H
Haojun Liao 已提交
1036 1037
  if ((pNext->skey > pDataBlockInfo->window.ekey && order == TSDB_ORDER_ASC) ||
      (pNext->ekey < pDataBlockInfo->window.skey && order == TSDB_ORDER_DESC)) {
1038 1039 1040
    return -1;
  }

L
Liu Jicong 已提交
1041
  TSKEY   startKey = ascQuery ? pNext->skey : pNext->ekey;
1042 1043 1044
  int32_t startPos = 0;

  // tumbling time window query, a special case of sliding time window query
H
Haojun Liao 已提交
1045 1046
  if (pInterval->sliding == pInterval->interval && prevPosition != -1) {
    int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
1047 1048
    startPos = prevPosition + factor;
  } else {
H
Haojun Liao 已提交
1049
    if (startKey <= pDataBlockInfo->window.skey && ascQuery) {
1050
      startPos = 0;
H
Haojun Liao 已提交
1051
    } else if (startKey >= pDataBlockInfo->window.ekey && !ascQuery) {
1052 1053
      startPos = pDataBlockInfo->rows - 1;
    } else {
L
Liu Jicong 已提交
1054
      startPos = binarySearchForKey((char*)primaryKeys, pDataBlockInfo->rows, startKey, order);
1055 1056 1057 1058
    }
  }

  /* interp query with fill should not skip time window */
L
Liu Jicong 已提交
1059 1060 1061
  //  if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
  //    return startPos;
  //  }
1062 1063 1064 1065 1066 1067

  /*
   * 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 已提交
1068
    if (ascQuery) {
1069 1070 1071 1072 1073
      assert(pDataBlockInfo->window.skey <= pNext->ekey);
    } else {
      assert(pDataBlockInfo->window.ekey >= pNext->skey);
    }
  } else {
H
Haojun Liao 已提交
1074
    if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
1075
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
1076 1077 1078
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
1079
      } else {
L
Liu Jicong 已提交
1080
        pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
H
Haojun Liao 已提交
1081
        pNext->skey = pNext->ekey - pInterval->interval + 1;
1082
      }
H
Haojun Liao 已提交
1083
    } else if ((!ascQuery) && primaryKeys[startPos] < pNext->skey) {
1084
      TSKEY next = primaryKeys[startPos];
H
Haojun Liao 已提交
1085 1086 1087
      if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
        pNext->skey = taosTimeTruncate(next, pInterval, precision);
        pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
1088
      } else {
H
Haojun Liao 已提交
1089 1090
        pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
        pNext->ekey = pNext->skey + pInterval->interval - 1;
1091 1092 1093 1094 1095 1096 1097
      }
    }
  }

  return startPos;
}

L
Liu Jicong 已提交
1098
static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* pWindow) {
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
  TSKEY ekey = -1;
  if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
    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 已提交
1115
static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t type) {
1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
  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 已提交
1127
static void saveDataBlockLastRow(char** pRow, SArray* pDataBlock, int32_t rowIndex, int32_t numOfCols) {
1128 1129 1130 1131
  if (pDataBlock == NULL) {
    return;
  }

H
Haojun Liao 已提交
1132
  for (int32_t k = 0; k < numOfCols; ++k) {
L
Liu Jicong 已提交
1133
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, k);
H
Haojun Liao 已提交
1134
    memcpy(pRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes);
1135 1136 1137
  }
}

H
Haojun Liao 已提交
1138
static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols, int32_t rows, bool ascQuery) {
1139 1140
  TSKEY ts = TSKEY_INITIAL_VAL;
  if (tsCols == NULL) {
L
Liu Jicong 已提交
1141
    ts = ascQuery ? win->skey : win->ekey;
1142
  } else {
L
Liu Jicong 已提交
1143
    int32_t offset = ascQuery ? 0 : rows - 1;
1144 1145 1146 1147 1148 1149
    ts = tsCols[offset];
  }

  return ts;
}

H
Haojun Liao 已提交
1150
static void doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order);
1151

L
Liu Jicong 已提交
1152 1153
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
                                    int32_t order) {
1154 1155
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
    pCtx[i].order = order;
L
Liu Jicong 已提交
1156
    pCtx[i].size = pBlock->info.rows;
1157 1158
    pCtx[i].currentStage = (uint8_t)pOperator->pRuntimeEnv->scanFlag;

L
Liu Jicong 已提交
1159
    setBlockStatisInfo(&pCtx[i], pBlock, NULL /*&pOperator->pExpr[i].base.colInfo*/);
1160 1161 1162
  }
}

H
Haojun Liao 已提交
1163
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) {
H
Haojun Liao 已提交
1164 1165 1166 1167 1168
  if (pBlock->pDataBlock != NULL) {
    doSetInputDataBlock(pOperator, pCtx, pBlock, order);
  } else {
    doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
  }
1169 1170
}

H
Haojun Liao 已提交
1171
static void doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) {
1172 1173
  for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
    pCtx[i].order = order;
L
Liu Jicong 已提交
1174
    pCtx[i].size = pBlock->info.rows;
H
Haojun Liao 已提交
1175 1176
    pCtx[i].currentStage = MAIN_SCAN;

G
Ganlin Zhao 已提交
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
    SExprInfo expr = pOperator->pExpr[i];
    for (int32_t j = 0; j < expr.base.numOfParams; ++j) {
      SFunctParam *pFuncParam = &expr.base.pParam[j];
      if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
        int32_t slotId = pFuncParam->pCol->slotId;
        pCtx[i].input.pData[j]  = taosArrayGet(pBlock->pDataBlock, slotId);
        pCtx[i].input.totalRows = pBlock->info.rows;
        pCtx[i].input.numOfRows = pBlock->info.rows;
        pCtx[i].input.startRowIndex = 0;
        ASSERT(pCtx[i].input.pData[j] != NULL);
      }
    }
H
Haojun Liao 已提交
1189

H
Haojun Liao 已提交
1190
    //    setBlockStatisInfo(&pCtx[i], pBlock, pOperator->pExpr[i].base.pColumns);
H
Haojun Liao 已提交
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
    //      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;
    //            }
    //          }
    //        }

    // in case of the block distribution query, the inputBytes is not a constant value.
G
Ganlin Zhao 已提交
1207 1208 1209 1210
    //pCtx[i].input.pData[0]  = taosArrayGet(pBlock->pDataBlock, slotId);
    //pCtx[i].input.totalRows = pBlock->info.rows;
    //pCtx[i].input.numOfRows = pBlock->info.rows;
    //pCtx[i].input.startRowIndex = 0;
H
Haojun Liao 已提交
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238


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

static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
1239
  for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
H
Haojun Liao 已提交
1240
    if (functionNeedToExecute(&pCtx[k])) {
L
Liu Jicong 已提交
1241
      pCtx[k].startTs = startTs;  // this can be set during create the struct
H
Haojun Liao 已提交
1242
      pCtx[k].fpSet.process(&pCtx[k]);
1243 1244 1245 1246
    }
  }
}

L
Liu Jicong 已提交
1247 1248
static void projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
                                  int32_t numOfOutput) {
1249
  for (int32_t k = 0; k < numOfOutput; ++k) {
L
Liu Jicong 已提交
1250
    if (pExpr[k].pExpr->nodeType == QUERY_NODE_COLUMN) {  // it is a project query
H
Haojun Liao 已提交
1251
      SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, k);
1252
      colDataAssign(pColInfoData, pCtx[k].input.pData[0], pCtx[k].input.numOfRows);
1253 1254

      pResult->info.rows = pCtx[0].input.numOfRows;
H
Haojun Liao 已提交
1255
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_OPERATOR) {
1256 1257 1258
      SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
      taosArrayPush(pBlockList, &pSrcBlock);

1259 1260 1261 1262 1263 1264 1265 1266
      SScalarParam dest = {0};
      dest.columnData = taosArrayGet(pResult->pDataBlock, k);

      scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);
      pResult->info.rows = dest.numOfRows;

      taosArrayDestroy(pBlockList);
    } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1267
      ASSERT(!fmIsAggFunc(pCtx[k].functionId));
1268

H
Haojun Liao 已提交
1269 1270 1271
      if (fmIsPseudoColumnFunc(pCtx[k].functionId)) {
        // TODO: set the correct _rowts column output buffer, there may be multiple _rowts columns
      } else if (fmIsNonstandardSQLFunc(pCtx[k].functionId)) {
H
Haojun Liao 已提交
1272
        SColumnInfoData* pColInfoData = taosArrayGet(pResult->pDataBlock, k);
1273

H
Haojun Liao 已提交
1274
        pCtx[k].ptsList = 0;
H
Haojun Liao 已提交
1275 1276
        SResultRowEntryInfo *pResInfo = GET_RES_INFO(&pCtx[k]);
        pCtx[k].fpSet.init(&pCtx[k], pResInfo);
1277

H
Haojun Liao 已提交
1278 1279
        pCtx[k].pOutput = (char*)pColInfoData;
//        pCtx[k].pTsOutput =
H
Haojun Liao 已提交
1280
        int32_t numOfRows = pCtx[k].fpSet.process(&pCtx[k]);
H
Haojun Liao 已提交
1281
        pResult->info.rows += numOfRows;
H
Haojun Liao 已提交
1282 1283 1284
      } else {
        SArray* pBlockList = taosArrayInit(4, POINTER_BYTES);
        taosArrayPush(pBlockList, &pSrcBlock);
G
Ganlin Zhao 已提交
1285

H
Haojun Liao 已提交
1286 1287 1288 1289 1290 1291 1292
        SScalarParam dest = {0};
        dest.columnData = taosArrayGet(pResult->pDataBlock, k);

        scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
        pResult->info.rows = dest.numOfRows;
        taosArrayDestroy(pBlockList);
      }
1293
    } else {
1294
      ASSERT(0);
1295 1296 1297 1298 1299 1300
    }
  }
}

void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SArray* pDataBlock, TSKEY prevTs,
                               int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type) {
L
Liu Jicong 已提交
1301 1302
  STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
  SExprInfo*       pExpr = pOperator->pExpr;
1303

H
Haojun Liao 已提交
1304
  SqlFunctionCtx* pCtx = pInfo->pCtx;
1305 1306 1307 1308 1309 1310 1311 1312

  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 已提交
1313
    SColIndex*       pColIndex = NULL /*&pExpr[k].base.colInfo*/;
1314
    int16_t          index = pColIndex->colIndex;
L
Liu Jicong 已提交
1315
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, index);
1316

L
Liu Jicong 已提交
1317
    //    assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
1318 1319 1320
    double v1 = 0, v2 = 0, v = 0;

    if (prevRowIndex == -1) {
L
Liu Jicong 已提交
1321
      GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pRuntimeEnv->prevRow[index]);
1322
    } else {
L
Liu Jicong 已提交
1323
      GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pColInfo->pData + prevRowIndex * pColInfo->info.bytes);
1324 1325
    }

L
Liu Jicong 已提交
1326
    GET_TYPED_DATA(v2, double, pColInfo->info.type, (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes);
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337

    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) {
L
Liu Jicong 已提交
1338
            pCtx[k].start.ptr = (char*)pRuntimeEnv->prevRow[index];
1339
          } else {
L
Liu Jicong 已提交
1340
            pCtx[k].start.ptr = (char*)pColInfo->pData + prevRowIndex * pColInfo->info.bytes;
1341 1342
          }

L
Liu Jicong 已提交
1343
          pCtx[k].end.ptr = (char*)pColInfo->pData + curRowIndex * pColInfo->info.bytes;
1344 1345 1346
        }
      }
    } else if (functionId == FUNCTION_TWA) {
L
Liu Jicong 已提交
1347 1348 1349
      SPoint point1 = (SPoint){.key = prevTs, .val = &v1};
      SPoint point2 = (SPoint){.key = curTs, .val = &v2};
      SPoint point = (SPoint){.key = windowKey, .val = &v};
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363

      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 已提交
1364
static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t pos,
H
Haojun Liao 已提交
1365 1366
                                              int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols, STimeWindow* win) {
  bool  ascQuery = true;
L
Liu Jicong 已提交
1367
  TSKEY curTs = tsCols[pos];
H
Haojun Liao 已提交
1368
  TSKEY lastTs = 0;//*(TSKEY*)pRuntimeEnv->prevRow[0];
1369 1370 1371

  // 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 已提交
1372
  TSKEY key = ascQuery ? win->skey : win->ekey;
1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
  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;
  }

H
Haojun Liao 已提交
1383
  int32_t step = 1;//GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
L
Liu Jicong 已提交
1384
  TSKEY   prevTs = ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery)) ? lastTs : tsCols[pos - step];
1385

H
Haojun Liao 已提交
1386
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, key, RESULT_ROW_START_INTERP);
1387 1388 1389
  return true;
}

L
Liu Jicong 已提交
1390 1391 1392
static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SqlFunctionCtx* pCtx, int32_t endRowIndex,
                                            SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
                                            STimeWindow* win) {
H
Haojun Liao 已提交
1393 1394
  int32_t order = TSDB_ORDER_ASC;
  int32_t numOfOutput = pOperatorInfo->numOfOutput;
1395

L
Liu Jicong 已提交
1396
  TSKEY actualEndKey = tsCols[endRowIndex];
H
Haojun Liao 已提交
1397
  TSKEY key = order ? win->ekey : win->skey;
1398 1399

  // not ended in current data block, do not invoke interpolation
H
Haojun Liao 已提交
1400
  if ((key > blockEkey /*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/) || (key < blockEkey /*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/)) {
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410
    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 已提交
1411
  int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
1412 1413 1414 1415 1416
  int32_t nextRowIndex = endRowIndex + step;
  assert(nextRowIndex >= 0);

  TSKEY nextKey = tsCols[nextRowIndex];
  doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, actualEndKey, endRowIndex, nextKey,
L
Liu Jicong 已提交
1417
                            nextRowIndex, key, RESULT_ROW_END_INTERP);
1418 1419 1420
  return true;
}

H
Haojun Liao 已提交
1421
static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SqlFunctionCtx* pCtx,
L
Liu Jicong 已提交
1422 1423
                                        SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep,
                                        int32_t order, bool timeWindowInterpo) {
H
Haojun Liao 已提交
1424
  if (!timeWindowInterpo) {
1425 1426 1427 1428
    return;
  }

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

L
Liu Jicong 已提交
1431 1432
  if (pBlock->pDataBlock == NULL) {
    //    tscError("pBlock->pDataBlock == NULL");
1433 1434
    return;
  }
H
Haojun Liao 已提交
1435

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

L
Liu Jicong 已提交
1438 1439 1440
  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
1441
    int32_t startRowIndex = startPos;
L
Liu Jicong 已提交
1442 1443
    bool    interp = setTimeWindowInterpolationStartTs(pOperatorInfo, pCtx, startRowIndex, pBlock->info.rows,
                                                       pBlock->pDataBlock, tsCols, win);
1444 1445 1446 1447
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1448
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1449 1450 1451
  }

  // point interpolation does not require the end key time window interpolation.
L
Liu Jicong 已提交
1452 1453 1454
  //  if (pointInterpQuery) {
  //    return;
  //  }
1455 1456 1457 1458 1459 1460

  // 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 已提交
1461 1462 1463
    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);
1464 1465 1466 1467
    if (interp) {
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
    }
  } else {
H
Haojun Liao 已提交
1468
    setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_END_INTERP);
1469 1470 1471
  }
}

1472
static SArray* hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock, int32_t tableGroupId) {
L
Liu Jicong 已提交
1473
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)pOperatorInfo->info;
1474

H
Haojun Liao 已提交
1475
  SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
L
Liu Jicong 已提交
1476
  int32_t        numOfOutput = pOperatorInfo->numOfOutput;
1477

1478 1479 1480 1481 1482
  SArray* pUpdated = NULL;
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
    pUpdated = taosArrayInit(4, sizeof(SResultRowPosition));
  }

H
Haojun Liao 已提交
1483
  int32_t step = 1;
1484
  bool    ascScan = true;
1485 1486 1487 1488 1489 1490

  int32_t prevIndex = pResultRowInfo->curPos;

  TSKEY* tsCols = NULL;
  if (pSDataBlock->pDataBlock != NULL) {
    SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, 0);
L
Liu Jicong 已提交
1491
    tsCols = (int64_t*)pColDataInfo->pData;
H
Haojun Liao 已提交
1492 1493
//    assert(tsCols[0] == pSDataBlock->info.window.skey && tsCols[pSDataBlock->info.rows - 1] ==
//           pSDataBlock->info.window.ekey);
1494 1495
  }

1496 1497
  int32_t startPos = ascScan? 0 : (pSDataBlock->info.rows - 1);
  TSKEY   ts = getStartTsKey(&pSDataBlock->info.window, tsCols, pSDataBlock->info.rows, ascScan);
1498

H
Haojun Liao 已提交
1499
  STimeWindow win = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, pInfo->interval.precision, &pInfo->win);
L
Liu Jicong 已提交
1500
  bool        masterScan = true;
1501 1502

  SResultRow* pResult = NULL;
L
Liu Jicong 已提交
1503 1504 1505
  int32_t     ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult,
                                               tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset,
                                               &pInfo->aggSup, pTaskInfo);
1506
  if (ret != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1507
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1508 1509
  }

1510 1511 1512 1513 1514
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
    SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
    taosArrayPush(pUpdated, &pos);
  }

1515
  int32_t forwardStep = 0;
H
Haojun Liao 已提交
1516
  TSKEY   ekey = win.ekey;
1517
  forwardStep =
H
Haojun Liao 已提交
1518
      getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1519 1520 1521

  // prev time window not interpolation yet.
  int32_t curIndex = pResultRowInfo->curPos;
H
Haojun Liao 已提交
1522 1523

#if 0
H
Haojun Liao 已提交
1524
  if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
1525 1526 1527
    for (int32_t j = prevIndex; j < curIndex; ++j) {  // previous time window may be all closed already.
      SResultRow* pRes = getResultRow(pResultRowInfo, j);
      if (pRes->closed) {
1528
        assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
1529 1530 1531
        continue;
      }

L
Liu Jicong 已提交
1532 1533 1534 1535 1536 1537 1538
      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);
      }
1539

L
Liu Jicong 已提交
1540 1541 1542
      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);
1543

L
Liu Jicong 已提交
1544 1545
      setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
      setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
1546

1547
      doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
L
Liu Jicong 已提交
1548
    }
1549 1550

    // restore current time window
L
Liu Jicong 已提交
1551 1552 1553
    ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
                                     pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
                                     pTaskInfo);
1554
    if (ret != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1555
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1556 1557
    }
  }
H
Haojun Liao 已提交
1558
#endif
1559 1560

  // window start key interpolation
1561 1562 1563
  doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &win, startPos, forwardStep, pInfo->order, false);

  updateTimeWindowInfo(&pInfo->timeWindowData, &win, true);
1564
  doApplyFunctions(pInfo->binfo.pCtx, &win, &pInfo->timeWindowData, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1565 1566 1567 1568

  STimeWindow nextWin = win;
  while (1) {
    int32_t prevEndPos = (forwardStep - 1) * step + startPos;
H
Haojun Liao 已提交
1569
    startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, pInfo);
1570 1571 1572 1573 1574
    if (startPos < 0) {
      break;
    }

    // null data, failed to allocate more memory buffer
L
Liu Jicong 已提交
1575 1576 1577
    int32_t code = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &nextWin, masterScan, &pResult,
                                              tableGroupId, pInfo->binfo.pCtx, numOfOutput,
                                              pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1578
    if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
H
Haojun Liao 已提交
1579
      longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
1580 1581
    }

1582 1583 1584 1585 1586
    if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
      SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
      taosArrayPush(pUpdated, &pos);
    }

L
Liu Jicong 已提交
1587 1588 1589
    ekey = nextWin.ekey;  // reviseWindowEkey(pQueryAttr, &nextWin);
    forwardStep =
        getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
1590 1591

    // window start(end) key interpolation
1592 1593 1594
    doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &nextWin, startPos, forwardStep, pInfo->order, false);

    updateTimeWindowInfo(&pInfo->timeWindowData, &win, true);
1595
    doApplyFunctions(pInfo->binfo.pCtx, &nextWin, &pInfo->timeWindowData, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1596 1597
  }

H
Haojun Liao 已提交
1598
  if (pInfo->timeWindowInterpo) {
1599
    int32_t rowIndex = ascScan ? (pSDataBlock->info.rows - 1) : 0;
H
Haojun Liao 已提交
1600
    saveDataBlockLastRow(pInfo->pRow, pSDataBlock->pDataBlock, rowIndex, pSDataBlock->info.numOfCols);
1601 1602
  }

1603
  return pUpdated;
L
Liu Jicong 已提交
1604
  //  updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
1605 1606
}

L
Liu Jicong 已提交
1607 1608 1609
static void hashAllIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock,
                               int32_t tableGroupId) {
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)pOperatorInfo->info;
1610

H
Haojun Liao 已提交
1611
  STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv;
L
Liu Jicong 已提交
1612
  int32_t          numOfOutput = pOperatorInfo->numOfOutput;
1613

H
Haojun Liao 已提交
1614 1615
  int32_t step = 1;//GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
  bool    ascQuery = true;
1616 1617 1618 1619

  TSKEY* tsCols = NULL;
  if (pSDataBlock->pDataBlock != NULL) {
    SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, 0);
L
Liu Jicong 已提交
1620
    tsCols = (int64_t*)pColDataInfo->pData;
1621 1622 1623 1624
    assert(tsCols[0] == pSDataBlock->info.window.skey &&
           tsCols[pSDataBlock->info.rows - 1] == pSDataBlock->info.window.ekey);
  }

L
Liu Jicong 已提交
1625 1626
  int32_t startPos = ascQuery ? 0 : (pSDataBlock->info.rows - 1);
  TSKEY   ts = getStartTsKey(&pSDataBlock->info.window, tsCols, pSDataBlock->info.rows, ascQuery);
1627

H
Haojun Liao 已提交
1628
  STimeWindow win = {0};//getCurrentActiveTimeWindow(pResultRowInfo, ts, pQueryAttr);
L
Liu Jicong 已提交
1629
  bool        masterScan = IS_MAIN_SCAN(pRuntimeEnv);
1630 1631

  SResultRow* pResult = NULL;
L
Liu Jicong 已提交
1632 1633
  int32_t     forwardStep = 0;
  int32_t     ret = 0;
1634 1635 1636 1637 1638
  STimeWindow preWin = win;

  while (1) {
    // null data, failed to allocate more memory buffer
    ret = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult,
H
Haojun Liao 已提交
1639
                                  tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset);
1640 1641 1642 1643
    if (ret != TSDB_CODE_SUCCESS) {
      longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
    }

H
Haojun Liao 已提交
1644
    TSKEY ekey = 0;//reviseWindowEkey(pQueryAttr, &win);
L
Liu Jicong 已提交
1645 1646
    //    forwardStep = getNumOfRowsInTimeWindow(pRuntimeEnv, &pSDataBlock->info, tsCols, startPos, ekey,
    //    binarySearchForKey, true);
1647 1648

    // window start(end) key interpolation
L
Liu Jicong 已提交
1649 1650 1651
    //    doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &win, startPos,
    //    forwardStep); doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, ascQuery ? &win : &preWin, startPos,
    //    forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput);
1652 1653 1654
    preWin = win;

    int32_t prevEndPos = (forwardStep - 1) * step + startPos;
L
Liu Jicong 已提交
1655 1656
    //    startPos = getNextQualifiedWindow(pQueryAttr, &win, &pSDataBlock->info, tsCols, binarySearchForKey,
    //    prevEndPos);
1657
    if (startPos < 0) {
H
Haojun Liao 已提交
1658 1659 1660 1661 1662 1663 1664 1665 1666
//      if ((ascQuery && win.skey <= pQueryAttr->window.ekey) || ((!ascQuery) && win.ekey >= pQueryAttr->window.ekey)) {
//        int32_t code =
//            setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult,
//                                    tableGroupId, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset);
//        if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
//          longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
//        }
//
//        startPos = pSDataBlock->info.rows - 1;
1667 1668

        // window start(end) key interpolation
L
Liu Jicong 已提交
1669 1670 1671
        //        doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->binfo.pCtx, pResult, &win, startPos,
        //        forwardStep); doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, ascQuery ? &win : &preWin, startPos,
        //        forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput);
H
Haojun Liao 已提交
1672
//      }
1673 1674 1675 1676 1677 1678

      break;
    }
    setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
  }

H
Haojun Liao 已提交
1679 1680
//  if (pQueryAttr->timeWindowInterpo) {
//    int32_t rowIndex = ascQuery ? (pSDataBlock->info.rows - 1) : 0;
L
Liu Jicong 已提交
1681
    //    saveDataBlockLastRow(pRuntimeEnv, &pSDataBlock->info, pSDataBlock->pDataBlock, rowIndex);
H
Haojun Liao 已提交
1682
//  }
1683

L
Liu Jicong 已提交
1684
  //  updateResultRowInfoActiveIndex(pResultRowInfo, pQueryAttr, pRuntimeEnv->current->lastKey);
1685 1686
}

1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
static void doKeepTuple(SSessionAggOperatorInfo* pInfo, int64_t ts) {
  pInfo->curWindow.ekey = ts;
  pInfo->prevTs         = ts;
  pInfo->numOfRows     += 1;
}

static void doKeepSessionStartInfo(SSessionAggOperatorInfo* pInfo, const int64_t* tsList, int32_t rowIndex) {
  pInfo->start          = rowIndex;
  pInfo->numOfRows      = 0;
  pInfo->curWindow.skey = tsList[rowIndex];
}

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

1703
  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
1704

1705 1706 1707
  bool    masterScan = true;
  int32_t numOfOutput = pOperator->numOfOutput;
  int64_t gid = pBlock->info.groupId;
1708

H
Haojun Liao 已提交
1709
  int64_t gap = pInfo->gap;
1710
  pInfo->numOfRows = 0;
1711
  if (!pInfo->reptScan) {
1712
    pInfo->reptScan = true;
1713
    pInfo->prevTs   = INT64_MIN;
1714 1715
  }

1716
  // In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
1717
  TSKEY* tsList = (TSKEY*)pColInfoData->pData;
1718
  for (int32_t j = 0; j < pBlock->info.rows; ++j) {
1719
    if (pInfo->prevTs == INT64_MIN) {
1720 1721
      doKeepSessionStartInfo(pInfo, tsList, j);
      doKeepTuple(pInfo, tsList[j]);
1722
    } else if (tsList[j] - pInfo->prevTs <= gap && (tsList[j] - pInfo->prevTs) >= 0) {
1723 1724
      // The gap is less than the threshold, so it belongs to current session window that has been opened already.
      doKeepTuple(pInfo, tsList[j]);
1725 1726 1727 1728 1729
      if (j == 0 && pInfo->start != 0) {
        pInfo->start = 0;
      }
    } else {  // start a new session window
      SResultRow* pResult = NULL;
1730 1731 1732 1733

      // keep the time window for the closed time window.
      STimeWindow window = pInfo->curWindow;

1734
      pInfo->curWindow.ekey = pInfo->curWindow.skey;
L
Liu Jicong 已提交
1735
      int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &window, masterScan,
1736
                                               &pResult, gid, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1737
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1738
        longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1739 1740
      }

1741
      // pInfo->numOfRows data belong to the current session window
1742 1743
      updateTimeWindowInfo(&pInfo->timeWindowData, &window, false);
      doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->timeWindowData, pInfo->start, pInfo->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1744

1745 1746 1747
      // here we start a new session window
      doKeepSessionStartInfo(pInfo, tsList, j);
      doKeepTuple(pInfo, tsList[j]);
1748 1749 1750 1751
    }
  }

  SResultRow* pResult = NULL;
1752 1753 1754
  pInfo->curWindow.ekey = tsList[pBlock->info.rows - 1];
  int32_t ret = setResultOutputBufByKey_rv(&pInfo->binfo.resultRowInfo, pBlock->info.uid, &pInfo->curWindow, masterScan, &pResult,
                                           gid, pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup, pTaskInfo);
1755
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
1756
    longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
1757 1758
  }

1759 1760
  updateTimeWindowInfo(&pInfo->timeWindowData, &pInfo->curWindow, false);
  doApplyFunctions(pInfo->binfo.pCtx, &pInfo->curWindow, &pInfo->timeWindowData, pInfo->start, pInfo->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
1761 1762 1763 1764 1765
}

static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
  if (IS_VAR_DATA_TYPE(type)) {
    if (pResultRow->key == NULL) {
wafwerar's avatar
wafwerar 已提交
1766
      pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779
      varDataCopy(pResultRow->key, pData);
    } else {
      assert(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
    }
  } else {
    int64_t v = -1;
    GET_TYPED_DATA(v, int64_t, type, pData);

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

H
Haojun Liao 已提交
1780
int32_t setGroupResultOutputBuf_rv(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type,
L
Liu Jicong 已提交
1781 1782 1783 1784
                                          int16_t bytes, int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo,
                                          SAggSupporter* pAggSup) {
  SResultRowInfo* pResultRowInfo = &binfo->resultRowInfo;
  SqlFunctionCtx* pCtx = binfo->pCtx;
1785

L
Liu Jicong 已提交
1786
  SResultRow* pResultRow = doSetResultOutBufByKey_rv(pBuf, pResultRowInfo, groupId, (char*)pData, bytes, true, groupId,
H
Haojun Liao 已提交
1787
                                                     pTaskInfo, false, pAggSup);
L
Liu Jicong 已提交
1788
  assert(pResultRow != NULL);
1789 1790

  setResultRowKey(pResultRow, pData, type);
H
Haojun Liao 已提交
1791
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfCols, binfo->rowCellInfoOffset);
1792 1793 1794
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
1795 1796
static bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
  struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
1797 1798 1799

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

1804
  if (isRowEntryCompleted(pResInfo)) {
1805 1806 1807 1808
    return false;
  }

  if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
L
Liu Jicong 已提交
1809
    //    return QUERY_IS_ASC_QUERY(pQueryAttr);
1810 1811 1812 1813
  }

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

  // in the reverse table scan, only the following functions need to be executed
L
Liu Jicong 已提交
1818 1819 1820 1821
  //  if (IS_REVERSE_SCAN(pRuntimeEnv) ||
  //      (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
  //    return false;
  //  }
1822 1823 1824 1825

  return true;
}

L
Liu Jicong 已提交
1826 1827
void setBlockStatisInfo(SqlFunctionCtx* pCtx, SSDataBlock* pSDataBlock, SColumn* pColumn) {
  SColumnDataAgg* pAgg = NULL;
1828

H
Haojun Liao 已提交
1829 1830
  if (pSDataBlock->pBlockAgg != NULL && TSDB_COL_IS_NORMAL_COL(pColumn->flag)) {
    pAgg = &pSDataBlock->pBlockAgg[pCtx->columnIndex];
1831 1832

    pCtx->agg = *pAgg;
L
Liu Jicong 已提交
1833
    pCtx->isAggSet = true;
1834 1835 1836 1837 1838
    assert(pCtx->agg.numOfNull <= pSDataBlock->info.rows);
  } else {
    pCtx->isAggSet = false;
  }

H
Haojun Liao 已提交
1839
  pCtx->hasNull = hasNull(pColumn, pAgg);
1840 1841

  // set the statistics data for primary time stamp column
H
Haojun Liao 已提交
1842
  if (pCtx->functionId == FUNCTION_SPREAD && pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
L
Liu Jicong 已提交
1843
    pCtx->isAggSet = true;
1844 1845 1846 1847 1848 1849
    pCtx->agg.min = pSDataBlock->info.window.skey;
    pCtx->agg.max = pSDataBlock->info.window.ekey;
  }
}

// set the output buffer for the selectivity + tag query
L
Liu Jicong 已提交
1850
static int32_t setCtxTagColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1851 1852 1853 1854 1855 1856 1857
  if (!isSelectivityWithTagsQuery(pCtx, numOfOutput)) {
    return TSDB_CODE_SUCCESS;
  }

  int32_t num = 0;
  int16_t tagLen = 0;

H
Haojun Liao 已提交
1858
  SqlFunctionCtx*  p = NULL;
wafwerar's avatar
wafwerar 已提交
1859
  SqlFunctionCtx** pTagCtx = taosMemoryCalloc(numOfOutput, POINTER_BYTES);
1860 1861 1862 1863 1864 1865 1866 1867
  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 已提交
1868
      tagLen += pCtx[i].resDataInfo.bytes;
1869
      pTagCtx[num++] = &pCtx[i];
L
Liu Jicong 已提交
1870
    } else if (1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/) {
1871 1872 1873 1874 1875 1876 1877 1878 1879 1880
      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) {
1881 1882 1883
    p->subsidiaryRes.pCtx = pTagCtx;
    p->subsidiaryRes.numOfCols = num;
    p->subsidiaryRes.bufLen = tagLen;
1884
  } else {
wafwerar's avatar
wafwerar 已提交
1885
    taosMemoryFreeClear(pTagCtx);
1886 1887 1888 1889 1890
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
1891
static SqlFunctionCtx* createSqlFunctionCtx_rv(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset) {
L
Liu Jicong 已提交
1892
  SqlFunctionCtx* pFuncCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
H
Haojun Liao 已提交
1893 1894 1895 1896
  if (pFuncCtx == NULL) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
1897
  *rowCellInfoOffset = taosMemoryCalloc(numOfOutput, sizeof(int32_t));
H
Haojun Liao 已提交
1898
  if (*rowCellInfoOffset == 0) {
wafwerar's avatar
wafwerar 已提交
1899
    taosMemoryFreeClear(pFuncCtx);
H
Haojun Liao 已提交
1900 1901 1902 1903
    return NULL;
  }

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

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

1909
    pCtx->functionId = -1;
H
Haojun Liao 已提交
1910
    if (pExpr->pExpr->nodeType == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
1911
      SFuncExecEnv env = {0};
H
Haojun Liao 已提交
1912 1913
      pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;

H
Haojun Liao 已提交
1914
      if (fmIsAggFunc(pCtx->functionId) || fmIsNonstandardSQLFunc(pCtx->functionId)) {
1915 1916 1917 1918
        fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
        pCtx->fpSet.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
      } else {
        fmGetScalarFuncExecFuncs(pCtx->functionId, &pCtx->sfp);
1919 1920 1921
        if (pCtx->sfp.getEnv != NULL) {
          pCtx->sfp.getEnv(pExpr->pExpr->_function.pFunctNode, &env);
        }
1922
      }
H
Haojun Liao 已提交
1923
      pCtx->resDataInfo.interBufSize = env.calcMemSize;
H
Haojun Liao 已提交
1924 1925
    } else if (pExpr->pExpr->nodeType == QUERY_NODE_COLUMN || pExpr->pExpr->nodeType == QUERY_NODE_OPERATOR) {
      pCtx->resDataInfo.interBufSize = pFunct->resSchema.bytes; // for simple column, the intermediate buffer needs to hold one element.
H
Haojun Liao 已提交
1926
    }
H
Haojun Liao 已提交
1927

H
Haojun Liao 已提交
1928
    pCtx->input.numOfInputCols = pFunct->numOfParams;
wafwerar's avatar
wafwerar 已提交
1929 1930
    pCtx->input.pData = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
    pCtx->input.pColumnDataAgg = taosMemoryCalloc(pFunct->numOfParams, POINTER_BYTES);
H
Haojun Liao 已提交
1931

H
Haojun Liao 已提交
1932
    pCtx->pTsOutput         = NULL;
L
Liu Jicong 已提交
1933
    pCtx->resDataInfo.bytes = pFunct->resSchema.bytes;
H
Haojun Liao 已提交
1934 1935
    pCtx->resDataInfo.type  = pFunct->resSchema.type;
    pCtx->order             = TSDB_ORDER_ASC;
L
Liu Jicong 已提交
1936
    pCtx->start.key = INT64_MIN;
H
Haojun Liao 已提交
1937
    pCtx->end.key   = INT64_MIN;
H
Haojun Liao 已提交
1938
#if 0
H
Haojun Liao 已提交
1939
    for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
H
Haojun Liao 已提交
1940 1941
//      int16_t type = pFunct->param[j].nType;
//      int16_t bytes = pFunct->param[j].nLen;
H
Haojun Liao 已提交
1942

H
Haojun Liao 已提交
1943 1944 1945 1946 1947
//      if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
//        taosVariantCreateFromBinary(&pCtx->param[j], pFunct->param[j].pz, bytes, type);
//      } else {
//        taosVariantCreateFromBinary(&pCtx->param[j], (char *)&pFunct->param[j].i, bytes, type);
//      }
H
Haojun Liao 已提交
1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
    }

    // 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_TS_COMP) {
//      pCtx->param[0].i = pQueryAttr->vgId;  //TODO this should be the parameter from client
      pCtx->param[0].nType = TSDB_DATA_TYPE_BIGINT;
    } 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 已提交
1984
#endif
H
Haojun Liao 已提交
1985 1986
  }

L
Liu Jicong 已提交
1987 1988 1989
  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 已提交
1990
  }
H
Haojun Liao 已提交
1991 1992 1993 1994 1995

  setCtxTagColumnInfo(pFuncCtx, numOfOutput);
  return pFuncCtx;
}

1996
static void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
  if (pCtx == NULL) {
    return NULL;
  }

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

    taosVariantDestroy(&pCtx[i].tag);
wafwerar's avatar
wafwerar 已提交
2007
    taosMemoryFreeClear(pCtx[i].subsidiaryRes.pCtx);
2008 2009
  }

wafwerar's avatar
wafwerar 已提交
2010
  taosMemoryFreeClear(pCtx);
2011 2012 2013
  return NULL;
}

H
Haojun Liao 已提交
2014 2015
static void doFreeQueryHandle(STaskRuntimeEnv* pRuntimeEnv) {
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2016

L
Liu Jicong 已提交
2017
  //  tsdbCleanupReadHandle(pRuntimeEnv->pTsdbReadHandle);
2018
  pRuntimeEnv->pTsdbReadHandle = NULL;
2019

L
Liu Jicong 已提交
2020 2021
  //  SMemRef* pMemRef = &pQueryAttr->memRef;
  //  assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL);
2022 2023
}

L
Liu Jicong 已提交
2024 2025 2026
static void destroyTsComp(STaskRuntimeEnv* pRuntimeEnv, STaskAttr* pQueryAttr) {
  if (pQueryAttr->tsCompQuery && pRuntimeEnv->outputBuf && pRuntimeEnv->outputBuf->pDataBlock &&
      taosArrayGetSize(pRuntimeEnv->outputBuf->pDataBlock) > 0) {
2027 2028
    SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0);
    if (pColInfoData) {
L
Liu Jicong 已提交
2029
      TdFilePtr pFile = *(TdFilePtr*)pColInfoData->pData;  // TODO refactor
2030 2031
      if (pFile != NULL) {
        taosCloseFile(&pFile);
L
Liu Jicong 已提交
2032
        *(TdFilePtr*)pColInfoData->pData = NULL;
2033 2034 2035 2036 2037
      }
    }
  }
}

L
Liu Jicong 已提交
2038
bool isTaskKilled(SExecTaskInfo* pTaskInfo) {
2039 2040
  // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
  // abort current query execution.
L
Liu Jicong 已提交
2041 2042
  if (pTaskInfo->owner != 0 &&
      ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec())
2043 2044
      /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) {
    assert(pTaskInfo->cost.start != 0);
L
Liu Jicong 已提交
2045 2046 2047
    //    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;
2048 2049 2050 2051 2052
  }

  return false;
}

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

L
Liu Jicong 已提交
2055
static bool isCachedLastQuery(STaskAttr* pQueryAttr) {
2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084
  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;
  }

  if (pQueryAttr->order.order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) {
    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 已提交
2085 2086 2087
// todo refactor : return window
void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, int64_t keyFirst, int64_t keyLast,
                             STimeWindow* win) {
2088
  ASSERT(key >= keyFirst && key <= keyLast);
H
Haojun Liao 已提交
2089
  win->skey = taosTimeTruncate(key, pInterval, precision);
2090 2091

  /*
H
Haojun Liao 已提交
2092
   * if the realSkey > INT64_MAX - pInterval->interval, the query duration between
2093 2094
   * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
   */
H
Haojun Liao 已提交
2095 2096
  if (keyFirst > (INT64_MAX - pInterval->interval)) {
    assert(keyLast - keyFirst < pInterval->interval);
2097 2098
    win->ekey = INT64_MAX;
  } else {
2099
    win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
2100 2101 2102
  }
}

L
Liu Jicong 已提交
2103
static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126
  bool hasFirstLastFunc = false;
  bool hasOtherFunc = false;

  if (status == BLK_DATA_ALL_NEEDED || status == BLK_DATA_DISCARD) {
    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;
    }
  }

  if (hasFirstLastFunc && status == BLK_DATA_NO_NEEDED) {
L
Liu Jicong 已提交
2127
    if (!hasOtherFunc) {
2128 2129 2130 2131 2132 2133 2134 2135 2136
      return BLK_DATA_DISCARD;
    } else {
      return BLK_DATA_ALL_NEEDED;
    }
  }

  return status;
}

H
Haojun Liao 已提交
2137
static void doUpdateLastKey(STaskAttr* pQueryAttr) {
2138 2139 2140
  STimeWindow* win = &pQueryAttr->window;

  size_t num = taosArrayGetSize(pQueryAttr->tableGroupInfo.pGroupList);
L
Liu Jicong 已提交
2141
  for (int32_t i = 0; i < num; ++i) {
2142 2143 2144
    SArray* p1 = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i);

    size_t len = taosArrayGetSize(p1);
L
Liu Jicong 已提交
2145 2146 2147 2148 2149 2150 2151
    for (int32_t j = 0; j < len; ++j) {
      //      STableKeyInfo* pInfo = taosArrayGet(p1, j);
      //
      //      // update the new lastkey if it is equalled to the value of the old skey
      //      if (pInfo->lastKey == win->ekey) {
      //        pInfo->lastKey = win->skey;
      //      }
2152 2153 2154 2155
    }
  }
}

L
Liu Jicong 已提交
2156 2157
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
//   STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
H
Haojun Liao 已提交
2158
//
L
Liu Jicong 已提交
2159 2160 2161 2162
//   // 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 已提交
2163
//
L
Liu Jicong 已提交
2164 2165 2166 2167 2168
//   // 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 已提交
2169
//
L
Liu Jicong 已提交
2170 2171 2172 2173
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
//       TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//     }
H
Haojun Liao 已提交
2174
//
L
Liu Jicong 已提交
2175 2176 2177
//     pQueryAttr->needReverseScan = false;
//     return;
//   }
H
Haojun Liao 已提交
2178
//
L
Liu Jicong 已提交
2179 2180 2181 2182 2183
//   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 已提交
2184
//
L
Liu Jicong 已提交
2185 2186 2187 2188
//     pQueryAttr->needReverseScan = false;
//     doUpdateLastKey(pQueryAttr);
//     return;
//   }
H
Haojun Liao 已提交
2189
//
L
Liu Jicong 已提交
2190 2191 2192 2193 2194 2195
//   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 已提交
2196
//
L
Liu Jicong 已提交
2197 2198 2199
//     pQueryAttr->order.order = TSDB_ORDER_ASC;
//     return;
//   }
H
Haojun Liao 已提交
2200
//
L
Liu Jicong 已提交
2201 2202 2203 2204
//   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 已提交
2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230
////               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 已提交
2231 2232
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
//
//          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 已提交
2243 2244
////                 pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
H
Haojun Liao 已提交
2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255
//
//          TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
//          doUpdateLastKey(pQueryAttr);
//        }
//
//        pQueryAttr->order.order = TSDB_ORDER_DESC;
//        pQueryAttr->needReverseScan = false;
//      }
//    }
//  }
//}
2256

H
Haojun Liao 已提交
2257 2258
static void getIntermediateBufInfo(STaskRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) {
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
L
Liu Jicong 已提交
2259
  int32_t    MIN_ROWS_PER_PAGE = 4;
2260

L
Liu Jicong 已提交
2261 2262
  *rowsize = (int32_t)(pQueryAttr->resultRowSize *
                       getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
2263 2264 2265 2266
  int32_t overhead = sizeof(SFilePage);

  // one page contains at least two rows
  *ps = DEFAULT_INTERN_BUF_PAGE_SIZE;
L
Liu Jicong 已提交
2267
  while (((*rowsize) * MIN_ROWS_PER_PAGE) > (*ps) - overhead) {
2268 2269 2270 2271 2272 2273
    *ps = ((*ps) << 1u);
  }
}

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

L
Liu Jicong 已提交
2274 2275 2276
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
//   STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2277
//
L
Liu Jicong 已提交
2278 2279 2280
//   if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
//     return true;
//   }
2281
//
L
Liu Jicong 已提交
2282 2283
//   return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
2284

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

dengyihao's avatar
dengyihao 已提交
2288 2289
  TSKEY sk = TMIN(pQueryAttr->window.skey, pQueryAttr->window.ekey);
  TSKEY ek = TMAX(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2290 2291

  if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
L
Liu Jicong 已提交
2292
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
2293 2294 2295 2296 2297 2298
    assert(w.ekey >= pBlockInfo->window.skey);

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

L
Liu Jicong 已提交
2299 2300
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
      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 已提交
2311
    //    getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
2312 2313 2314 2315 2316 2317
    assert(w.skey <= pBlockInfo->window.ekey);

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

L
Liu Jicong 已提交
2318 2319
    while (1) {
      //      getNextTimeWindow(pQueryAttr, &w);
2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333
      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;
}

L
Liu Jicong 已提交
2334
static int32_t doTSJoinFilter(STaskRuntimeEnv* pRuntimeEnv, TSKEY key, bool ascQuery) {
2335 2336 2337
  STSElem elem = tsBufGetElem(pRuntimeEnv->pTsBuf);

#if defined(_DEBUG_VIEW)
L
Liu Jicong 已提交
2338 2339
  printf("elem in comp ts file:%" PRId64 ", key:%" PRId64 ", tag:%" PRIu64
         ", query order:%d, ts order:%d, traverse:%d, index:%d\n",
2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372
         elem.ts, key, elem.tag.i, pQueryAttr->order.order, pRuntimeEnv->pTsBuf->tsOrder,
         pRuntimeEnv->pTsBuf->cur.order, pRuntimeEnv->pTsBuf->cur.tsIndex);
#endif

  if (ascQuery) {
    if (key < elem.ts) {
      return TS_JOIN_TS_NOT_EQUALS;
    } else if (key > elem.ts) {
      longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_INCONSISTAN);
    }
  } else {
    if (key > elem.ts) {
      return TS_JOIN_TS_NOT_EQUALS;
    } else if (key < elem.ts) {
      longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_INCONSISTAN);
    }
  }

  return TS_JOIN_TS_EQUAL;
}

bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p) {
  bool all = true;

  for (int32_t i = 0; i < numOfRows; ++i) {
    bool qualified = false;

    for (int32_t k = 0; k < numOfFilterCols; ++k) {
      char* pElem = (char*)pFilterInfo[k].pData + pFilterInfo[k].info.bytes * i;

      qualified = false;
      for (int32_t j = 0; j < pFilterInfo[k].numOfFilters; ++j) {
        SColumnFilterElem* pFilterElem = NULL;
L
Liu Jicong 已提交
2373
        //        SColumnFilterElem* pFilterElem = &pFilterInfo[k].pFilters[j];
2374 2375 2376

        bool isnull = isNull(pElem, pFilterInfo[k].info.type);
        if (isnull) {
L
Liu Jicong 已提交
2377 2378 2379 2380 2381 2382
          //          if (pFilterElem->fp == isNullOperator) {
          //            qualified = true;
          //            break;
          //          } else {
          //            continue;
          //          }
2383
        } else {
L
Liu Jicong 已提交
2384 2385 2386 2387 2388 2389
          //          if (pFilterElem->fp == notNullOperator) {
          //            qualified = true;
          //            break;
          //          } else if (pFilterElem->fp == isNullOperator) {
          //            continue;
          //          }
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460
        }

        if (pFilterElem->fp(pFilterElem, pElem, pElem, pFilterInfo[k].info.type)) {
          qualified = true;
          break;
        }
      }

      if (!qualified) {
        break;
      }
    }

    p[i] = qualified ? 1 : 0;
    if (!qualified) {
      all = false;
    }
  }

  return all;
}

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

H
Haojun Liao 已提交
2461
void filterRowsInDataBlock(STaskRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols,
2462 2463 2464
                           SSDataBlock* pBlock, bool ascQuery) {
  int32_t numOfRows = pBlock->info.rows;

L
Liu Jicong 已提交
2465
  int8_t* p = taosMemoryCalloc(numOfRows, sizeof(int8_t));
2466
  bool    all = true;
H
Haojun Liao 已提交
2467
#if 0
2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494
  if (pRuntimeEnv->pTsBuf != NULL) {
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);

    TSKEY* k = (TSKEY*) pColInfoData->pData;
    for (int32_t i = 0; i < numOfRows; ++i) {
      int32_t offset = ascQuery? i:(numOfRows - i - 1);
      int32_t ret = doTSJoinFilter(pRuntimeEnv, k[offset], ascQuery);
      if (ret == TS_JOIN_TAG_NOT_EQUALS) {
        break;
      } else if (ret == TS_JOIN_TS_NOT_EQUALS) {
        all = false;
        continue;
      } else {
        assert(ret == TS_JOIN_TS_EQUAL);
        p[offset] = true;
      }

      if (!tsBufNextPos(pRuntimeEnv->pTsBuf)) {
        break;
      }
    }

    // save the cursor status
    pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
  } else {
    all = doFilterDataBlock(pFilterInfo, numOfFilterCols, numOfRows, p);
  }
H
Haojun Liao 已提交
2495
#endif
2496 2497 2498 2499 2500

  if (!all) {
    doCompactSDataBlock(pBlock, numOfRows, p);
  }

wafwerar's avatar
wafwerar 已提交
2501
  taosMemoryFreeClear(p);
2502 2503
}

H
Haojun Liao 已提交
2504
void filterColRowsInDataBlock(STaskRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock, bool ascQuery) {
L
Liu Jicong 已提交
2505
  int32_t numOfRows = pBlock->info.rows;
2506

L
Liu Jicong 已提交
2507 2508
  int8_t* p = NULL;
  bool    all = true;
2509

L
Liu Jicong 已提交
2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531
  if (pRuntimeEnv->pTsBuf != NULL) {
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
    p = taosMemoryCalloc(numOfRows, sizeof(int8_t));

    TSKEY* k = (TSKEY*)pColInfoData->pData;
    for (int32_t i = 0; i < numOfRows; ++i) {
      int32_t offset = ascQuery ? i : (numOfRows - i - 1);
      int32_t ret = doTSJoinFilter(pRuntimeEnv, k[offset], ascQuery);
      if (ret == TS_JOIN_TAG_NOT_EQUALS) {
        break;
      } else if (ret == TS_JOIN_TS_NOT_EQUALS) {
        all = false;
        continue;
      } else {
        assert(ret == TS_JOIN_TS_EQUAL);
        p[offset] = true;
      }

      if (!tsBufNextPos(pRuntimeEnv->pTsBuf)) {
        break;
      }
    }
2532

L
Liu Jicong 已提交
2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547
    // save the cursor status
    //   pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
  } else {
    //   all = filterExecute(pRuntimeEnv->pQueryAttr->pFilters, numOfRows, &p, pBlock->pBlockAgg,
    //   pRuntimeEnv->pQueryAttr->numOfCols);
  }

  if (!all) {
    if (p) {
      doCompactSDataBlock(pBlock, numOfRows, p);
    } else {
      pBlock->info.rows = 0;
      pBlock->pBlockAgg = NULL;  // clean the block statistics info
    }
  }
2548

L
Liu Jicong 已提交
2549
  taosMemoryFreeClear(p);
2550 2551 2552
}

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

static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) {
H
Haojun Liao 已提交
2556
  SqlFunctionCtx* pCtx = pTableScanInfo->pCtx;
L
Liu Jicong 已提交
2557
  uint32_t        status = BLK_DATA_NO_NEEDED;
2558 2559 2560 2561

  int32_t numOfOutput = pTableScanInfo->numOfOutput;
  for (int32_t i = 0; i < numOfOutput; ++i) {
    int32_t functionId = pCtx[i].functionId;
H
Haojun Liao 已提交
2562
    int32_t colId = pTableScanInfo->pExpr[i].base.pParam[0].pCol->colId;
2563 2564 2565 2566 2567 2568

    // group by + first/last should not apply the first/last block filter
    if (functionId < 0) {
      status |= BLK_DATA_ALL_NEEDED;
      return status;
    } else {
L
Liu Jicong 已提交
2569 2570 2571 2572
      //      status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
      //      if ((status & BLK_DATA_ALL_NEEDED) == BLK_DATA_ALL_NEEDED) {
      //        return status;
      //      }
2573 2574 2575 2576 2577 2578
    }
  }

  return status;
}

L
Liu Jicong 已提交
2579 2580
int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                              uint32_t* status) {
2581 2582
  *status = BLK_DATA_NO_NEEDED;

H
Haojun Liao 已提交
2583
  pBlock->pDataBlock = NULL;
L
Liu Jicong 已提交
2584
  pBlock->pBlockAgg = NULL;
H
Haojun Liao 已提交
2585

L
Liu Jicong 已提交
2586 2587
  //  int64_t groupId = pRuntimeEnv->current->groupIndex;
  //  bool    ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2588

H
Haojun Liao 已提交
2589
  STaskCostInfo* pCost = &pTaskInfo->cost;
2590 2591 2592

  pCost->totalBlocks += 1;
  pCost->totalRows += pBlock->info.rows;
H
Haojun Liao 已提交
2593
#if 0
2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617
  if (pRuntimeEnv->pTsBuf != NULL) {
    (*status) = BLK_DATA_ALL_NEEDED;

    if (pQueryAttr->stableQuery) {  // todo refactor
      SExprInfo*   pExprInfo = &pTableScanInfo->pExpr[0];
      int16_t      tagId = (int16_t)pExprInfo->base.param[0].i;
      SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagId);

      // compare tag first
      SVariant t = {0};
      doSetTagValueInParam(pRuntimeEnv->current->pTable, tagId, &t, pColInfo->type, pColInfo->bytes);
      setTimestampListJoinInfo(pRuntimeEnv, &t, pRuntimeEnv->current);

      STSElem elem = tsBufGetElem(pRuntimeEnv->pTsBuf);
      if (!tsBufIsValidElem(&elem) || (tsBufIsValidElem(&elem) && (taosVariantCompare(&t, elem.tag) != 0))) {
        (*status) = BLK_DATA_DISCARD;
        return TSDB_CODE_SUCCESS;
      }
    }
  }

  // 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 已提交
2618
      (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pTaskInfo, &pBlock->info))) {
2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630
    (*status) = BLK_DATA_ALL_NEEDED;
  }

  // check if this data block is required to load
  if ((*status) != BLK_DATA_ALL_NEEDED) {
    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 已提交
2631
      bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659
      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 {
      (*status) = BLK_DATA_ALL_NEEDED;
    }
  }

  SDataBlockInfo* pBlockInfo = &pBlock->info;
H
Haojun Liao 已提交
2660
//  *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *status);
2661 2662 2663 2664 2665 2666 2667 2668

  if ((*status) == BLK_DATA_NO_NEEDED || (*status) == BLK_DATA_DISCARD) {
    //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
//           pBlockInfo->window.ekey, pBlockInfo->rows);
    pCost->discardBlocks += 1;
  } else if ((*status) == BLK_DATA_STATIS_NEEDED) {
    // this function never returns error?
    pCost->loadBlockStatis += 1;
2669
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2670 2671

    if (pBlock->pBlockAgg == NULL) {  // data block statistics does not exist, load data block
2672
//      pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2673 2674 2675 2676 2677 2678 2679
      pCost->totalCheckedRows += pBlock->info.rows;
    }
  } else {
    assert((*status) == BLK_DATA_ALL_NEEDED);

    // load the data block statistics to perform further filter
    pCost->loadBlockStatis += 1;
2680
//    tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2681 2682 2683 2684 2685 2686

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

H
Haojun Liao 已提交
2687
          bool  masterScan = IS_MAIN_SCAN(pRuntimeEnv);
2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725
          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
            pCost->discardBlocks += 1;
            //qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
//                   pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
            (*status) = BLK_DATA_DISCARD;
            return TSDB_CODE_SUCCESS;
          }
        }
      }
    }

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

    pCost->totalCheckedRows += pBlockInfo->rows;
    pCost->loadBlocks += 1;
2726
//    pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738
//    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 已提交
2739
#endif
2740 2741 2742
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
2743
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
2744 2745 2746 2747 2748 2749 2750 2751 2752
  int32_t midPos = -1;
  int32_t numOfRows;

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

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

L
Liu Jicong 已提交
2753
  TSKEY*  keyList = (TSKEY*)pValue;
2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806
  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 已提交
2807
 * set tag value in SqlFunctionCtx
2808 2809
 * e.g.,tag information into input buffer
 */
L
Liu Jicong 已提交
2810
static void doSetTagValueInParam(void* pTable, int32_t tagColId, SVariant* tag, int16_t type, int16_t bytes) {
2811 2812 2813
  taosVariantDestroy(tag);

  char* val = NULL;
L
Liu Jicong 已提交
2814 2815 2816 2817 2818 2819
  //  if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
  //    val = tsdbGetTableName(pTable);
  //    assert(val != NULL);
  //  } else {
  //    val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
  //  }
2820 2821 2822 2823 2824 2825 2826 2827

  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 已提交
2828
    int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
2829
    taosVariantCreateFromBinary(tag, varDataVal(val), len, type);
L
Liu Jicong 已提交
2830
    // taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
2831 2832 2833 2834 2835 2836 2837 2838
  } 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 已提交
2839
  for (int32_t i = 0; i < numOfTags; ++i) {
2840 2841 2842 2843 2844 2845 2846 2847
    if (pTagColList[i].colId == colId) {
      return &pTagColList[i];
    }
  }

  return NULL;
}

L
Liu Jicong 已提交
2848
void setTagValue(SOperatorInfo* pOperatorInfo, void* pTable, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
H
Haojun Liao 已提交
2849
  STaskRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv;
2850

L
Liu Jicong 已提交
2851 2852
  SExprInfo* pExpr = pOperatorInfo->pExpr;
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2853 2854

  SExprInfo* pExprInfo = &pExpr[0];
L
Liu Jicong 已提交
2855
  int32_t    functionId = getExprFunctionId(pExprInfo);
2856 2857 2858 2859

  if (pQueryAttr->numOfOutput == 1 && functionId == FUNCTION_TS_COMP && pQueryAttr->stableQuery) {
    assert(pExprInfo->base.numOfParams == 1);

L
Liu Jicong 已提交
2860
    //    int16_t      tagColId = (int16_t)pExprInfo->base.param[0].i;
H
Haojun Liao 已提交
2861
    int16_t      tagColId = -1;
2862 2863 2864
    SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);

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

2866 2867 2868 2869 2870 2871 2872 2873 2874
  } 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 已提交
2875
      if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.pParam[0].pCol->flag)) {
2876 2877 2878 2879
        continue;
      }

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

L
Liu Jicong 已提交
2883 2884 2885
      if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resSchema.type) ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_BOOL ||
          pLocalExprInfo->base.resSchema.type == TSDB_DATA_TYPE_TIMESTAMP) {
2886 2887 2888 2889
        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 已提交
2890
        }
2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902
      }

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

H
Haojun Liao 已提交
2903
void copyToSDataBlock(SSDataBlock* pBlock, int32_t* offset, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pResBuf) {
2904 2905 2906 2907 2908 2909 2910
  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 已提交
2911 2912 2913
      //      if ((code = mergeIntoGroupResult(&pGroupResInfo, pRuntimeEnv, offset)) != TSDB_CODE_SUCCESS) {
      return;
      //      }
2914 2915
    }

L
Liu Jicong 已提交
2916
    //    doCopyToSDataBlock(pResBuf, pGroupResInfo, TSDB_ORDER_ASC, pBlock, );
2917 2918 2919 2920 2921 2922 2923 2924 2925 2926

    // 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 已提交
2927 2928 2929
    //    if (pBlock->info.rows >= threshold) {
    //      break;
    //    }
2930 2931 2932
  }
}

L
Liu Jicong 已提交
2933
static void updateTableQueryInfoForReverseScan(STableQueryInfo* pTableQueryInfo) {
2934 2935 2936 2937
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
2938 2939
  //  TSWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY);
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
2940

L
Liu Jicong 已提交
2941 2942
  //  SWITCH_ORDER(pTableQueryInfo->cur.order);
  //  pTableQueryInfo->cur.vgroupIndex = -1;
2943 2944 2945 2946 2947 2948 2949 2950 2951 2952

  // set the index to be the end slot of result rows array
  SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
  if (pResultRowInfo->size > 0) {
    pResultRowInfo->curPos = pResultRowInfo->size - 1;
  } else {
    pResultRowInfo->curPos = -1;
  }
}

H
Haojun Liao 已提交
2953
void initResultRow(SResultRow* pResultRow) {
2954 2955 2956 2957 2958 2959
  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 已提交
2960 2961 2962
 * +------------+-----------------result column 1------------+------------------result column 2-----------+
 * | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2|
 * +------------+--------------------------------------------+--------------------------------------------+
2963 2964
 *           offset[0]                                  offset[1]                                   offset[2]
 */
2965
// TODO refactor: some function move away
H
Haojun Liao 已提交
2966
void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
2967 2968 2969
  SqlFunctionCtx* pCtx = pInfo->pCtx;
  SSDataBlock*    pDataBlock = pInfo->pRes;
  int32_t*        rowCellInfoOffset = pInfo->rowCellInfoOffset;
H
Haojun Liao 已提交
2970

H
Haojun Liao 已提交
2971
  SResultRowInfo* pResultRowInfo = &pInfo->resultRowInfo;
H
Haojun Liao 已提交
2972
  initResultRowInfo(pResultRowInfo, 16);
H
Haojun Liao 已提交
2973

L
Liu Jicong 已提交
2974 2975 2976 2977
  int64_t     tid = 0;
  int64_t     groupId = 0;
  SResultRow* pRow = doSetResultOutBufByKey_rv(pSup->pResultBuf, pResultRowInfo, tid, (char*)&tid, sizeof(tid), true,
                                               groupId, pTaskInfo, false, pSup);
H
Haojun Liao 已提交
2978 2979 2980 2981 2982

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

L
Liu Jicong 已提交
2983
    pCtx[i].resultInfo = pEntry;
H
Haojun Liao 已提交
2984 2985 2986
    pCtx[i].currentStage = stage;

    // set the timestamp output buffer for top/bottom/diff query
L
Liu Jicong 已提交
2987 2988
    //    int32_t fid = pCtx[i].functionId;
    //    if (fid == FUNCTION_TOP || fid == FUNCTION_BOTTOM || fid == FUNCTION_DIFF || fid == FUNCTION_DERIVATIVE) {
H
Haojun Liao 已提交
2989
    //      if (i > 0) pCtx[i].pTsOutput = pCtx[i-1].pOutput;
L
Liu Jicong 已提交
2990
    //    }
H
Haojun Liao 已提交
2991 2992 2993 2994 2995
  }

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

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

L
Liu Jicong 已提交
2999
  int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5;  // extra output buffer
3000
  if ((*bufCapacity) < newSize) {
L
Liu Jicong 已提交
3001 3002
    for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
      SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
3003

wafwerar's avatar
wafwerar 已提交
3004
      char* p = taosMemoryRealloc(pColInfo->pData, newSize * pColInfo->info.bytes);
3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017
      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 已提交
3018
    SColumnInfoData* pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
3019 3020 3021 3022 3023
    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 已提交
3024 3025
    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF ||
        functionId == FUNCTION_DERIVATIVE) {
H
Haojun Liao 已提交
3026
//      if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
3027 3028 3029 3030
    }
  }
}

H
Haojun Liao 已提交
3031
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
3032 3033
  bool    needCopyTs = false;
  int32_t tsNum = 0;
L
Liu Jicong 已提交
3034
  char*   src = NULL;
3035 3036 3037 3038
  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 已提交
3039 3040
      if (i > 0 && pCtx[i - 1].functionId == FUNCTION_TS_DUMMY) {
        SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1);  // find ts data
3041 3042
        src = pColRes->pData;
      }
L
Liu Jicong 已提交
3043
    } else if (functionId == FUNCTION_TS_DUMMY) {
3044 3045 3046 3047 3048 3049 3050 3051 3052 3053
      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 已提交
3054
    if (functionId == FUNCTION_TS_DUMMY) {
3055 3056 3057 3058 3059 3060
      SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i);
      memcpy(pColRes->pData, src, pColRes->info.bytes * pRes->info.rows);
    }
  }
}

H
Haojun Liao 已提交
3061
void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size) {
3062 3063
  for (int32_t j = 0; j < size; ++j) {
    struct SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
H
Haojun Liao 已提交
3064
    if (isRowEntryInitialized(pResInfo) || fmIsPseudoColumnFunc(pCtx[j].functionId) || pCtx[j].functionId == -1 || fmIsScalarFunc(pCtx[j].functionId)) {
3065 3066 3067
      continue;
    }

H
Haojun Liao 已提交
3068
    pCtx[j].fpSet.init(&pCtx[j], pCtx[j].resultInfo);
3069 3070 3071
  }
}

L
Liu Jicong 已提交
3072
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
3073
  if (status == TASK_NOT_COMPLETED) {
H
Haojun Liao 已提交
3074
    pTaskInfo->status = status;
3075 3076
  } else {
    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
3077
    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
3078
    pTaskInfo->status |= status;
3079 3080 3081
  }
}

3082 3083
void finalizeQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
  for (int32_t j = 0; j < numOfOutput; ++j) {
H
Haojun Liao 已提交
3084 3085 3086 3087
    if (pCtx[j].functionId == -1) {
      continue;
    }

3088 3089 3090 3091
    pCtx[j].fpSet.finalize(&pCtx[j]);
  }
}

L
Liu Jicong 已提交
3092 3093
void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf,
                                   SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) {
3094 3095 3096
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
    SResultRowPosition* pPos = &pResultRowInfo->pPosition[i];

L
Liu Jicong 已提交
3097
    SFilePage*  bufPage = getBufPage(pBuf, pPos->pageId);
3098
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset);
H
Haojun Liao 已提交
3099 3100 3101 3102 3103

    // TODO ignore the close status anyway.
//    if (!isResultRowClosed(pRow)) {
//      continue;
//    }
3104

3105
    for (int32_t j = 0; j < numOfOutput; ++j) {
3106 3107
      pCtx[j].resultInfo = getResultCell(pRow, j, rowCellInfoOffset);

H
Haojun Liao 已提交
3108
      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
3109 3110 3111 3112
      if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
        continue;
      }

H
Haojun Liao 已提交
3113
      if (pCtx[j].fpSet.process) {  // TODO set the dummy function, to avoid the check for null ptr.
H
Haojun Liao 已提交
3114 3115
        pCtx[j].fpSet.finalize(&pCtx[j]);
      }
3116 3117 3118 3119

      if (pRow->numOfRows < pResInfo->numOfRes) {
        pRow->numOfRows = pResInfo->numOfRes;
      }
3120
    }
3121 3122 3123 3124 3125 3126

    releaseBufPage(pBuf, bufPage);
    /*
     * set the number of output results for group by normal columns, the number of output rows usually is 1 except
     * the top and bottom query
     */
L
Liu Jicong 已提交
3127
    //    buf->numOfRows = (uint16_t)getNumOfResult(pCtx, numOfOutput);
3128
  }
3129 3130
}

3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150
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) {
    SResultRowPosition* pPos = taosArrayGet(pUpdateList, i);

    SFilePage*  bufPage = getBufPage(pBuf, pPos->pageId);
    SResultRow* pRow = (SResultRow*)((char*)bufPage + pPos->offset);

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

      struct SResultRowEntryInfo* pResInfo = pCtx[j].resultInfo;
      if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
        continue;
      }

      if (pCtx[j].fpSet.process) {  // TODO set the dummy function.
        pCtx[j].fpSet.finalize(&pCtx[j]);
3151
        pResInfo->initialized = true;
3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167
      }

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

    releaseBufPage(pBuf, bufPage);
    /*
     * set the number of output results for group by normal columns, the number of output rows usually is 1 except
     * the top and bottom query
     */
    //    buf->numOfRows = (uint16_t)getNumOfResult(pCtx, numOfOutput);
  }
}

L
Liu Jicong 已提交
3168
static bool hasMainOutput(STaskAttr* pQueryAttr) {
3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);

    if (functionId != FUNCTION_TS && functionId != FUNCTION_TAG && functionId != FUNCTION_TAGPRJ) {
      return true;
    }
  }

  return false;
}

L
Liu Jicong 已提交
3180 3181
STableQueryInfo* createTableQueryInfo(void* buf, bool groupbyColumn, STimeWindow win) {
  STableQueryInfo* pTableQueryInfo = buf;
3182 3183 3184
  pTableQueryInfo->lastKey = win.skey;

  // set more initial size of interval/groupby query
L
Liu Jicong 已提交
3185 3186 3187 3188 3189 3190 3191 3192
  //  if (/*QUERY_IS_INTERVAL_QUERY(pQueryAttr) || */groupbyColumn) {
  int32_t initialSize = 128;
  int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize);
  if (code != TSDB_CODE_SUCCESS) {
    return NULL;
  }
  //  } else { // in other aggregate query, do not initialize the windowResInfo
  //  }
3193 3194 3195 3196

  return pTableQueryInfo;
}

L
Liu Jicong 已提交
3197
void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
3198 3199 3200 3201
  if (pTableQueryInfo == NULL) {
    return;
  }

L
Liu Jicong 已提交
3202
  //  taosVariantDestroy(&pTableQueryInfo->tag);
3203 3204 3205
  cleanupResultRowInfo(&pTableQueryInfo->resInfo);
}

L
Liu Jicong 已提交
3206 3207
void setResultRowOutputBufInitCtx(STaskRuntimeEnv* pRuntimeEnv, SResultRow* pResult, SqlFunctionCtx* pCtx,
                                  int32_t numOfOutput, int32_t* rowCellInfoOffset) {
3208
  // Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
3209
  SFilePage* bufPage = getBufPage(pRuntimeEnv->pResultBuf, pResult->pageId);
3210 3211 3212 3213 3214 3215 3216

  int32_t offset = 0;
  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)) {
H
Haojun Liao 已提交
3217
      offset += pCtx[i].resDataInfo.bytes;
3218 3219 3220 3221
      continue;
    }

    pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQueryAttr, bufPage, pResult->offset, offset);
H
Haojun Liao 已提交
3222
    offset += pCtx[i].resDataInfo.bytes;
3223 3224 3225 3226 3227 3228 3229

    int32_t functionId = pCtx[i].functionId;
    if (functionId < 0) {
      continue;
    }

    if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF) {
H
Haojun Liao 已提交
3230
//      if (i > 0) pCtx[i].pTsOutput = pCtx[i - 1].pOutput;
3231 3232
    }

L
Liu Jicong 已提交
3233 3234 3235
    //    if (!pResInfo->initialized) {
    //      aAggs[functionId].init(&pCtx[i], pResInfo);
    //    }
3236 3237 3238
  }
}

H
Haojun Liao 已提交
3239
void setResultRowOutputBufInitCtx_rv(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset) {
3240 3241 3242 3243 3244 3245 3246
  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;
    }
3247 3248 3249 3250 3251

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

H
Haojun Liao 已提交
3252
    if (!pResInfo->initialized && pCtx[i].functionId != -1) {
3253
      pCtx[i].fpSet.init(&pCtx[i], pResInfo);
3254 3255 3256 3257
    }
  }
}

H
Haojun Liao 已提交
3258
void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, int32_t tableGroupId, SExecTaskInfo* pTaskInfo) {
3259 3260 3261 3262
  // for simple group by query without interval, all the tables belong to one group result.
  int64_t uid = 0;
  int64_t tid = 0;

3263 3264
  SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
  SqlFunctionCtx* pCtx = pAggInfo->binfo.pCtx;
L
Liu Jicong 已提交
3265
  int32_t*        rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
3266

3267
  SResultRow* pResultRow =
L
Liu Jicong 已提交
3268 3269 3270
      doSetResultOutBufByKey_rv(pAggInfo->pResultBuf, pResultRowInfo, tid, (char*)&tableGroupId, sizeof(tableGroupId),
                                true, uid, pTaskInfo, false, &pAggInfo->aggSup);
  assert(pResultRow != NULL);
3271 3272 3273 3274 3275 3276

  /*
   * 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) {
H
Haojun Liao 已提交
3277
    int32_t ret = addNewWindowResultBuf(pResultRow, pAggInfo->pResultBuf, tableGroupId, pAggInfo->binfo.pRes->info.rowSize);
3278 3279 3280 3281 3282
    if (ret != TSDB_CODE_SUCCESS) {
      return;
    }
  }

H
Haojun Liao 已提交
3283
  setResultRowOutputBufInitCtx_rv(pResultRow, pCtx, numOfOutput, rowCellInfoOffset);
3284 3285
}

L
Liu Jicong 已提交
3286 3287
void setExecutionContext(int32_t numOfOutput, int32_t tableGroupId, TSKEY nextKey, SExecTaskInfo* pTaskInfo,
                         STableQueryInfo* pTableQueryInfo, SAggOperatorInfo* pAggInfo) {
3288 3289
  // lastKey needs to be updated
  pTableQueryInfo->lastKey = nextKey;
3290
  if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == tableGroupId) {
3291 3292 3293
    return;
  }

3294
  doSetTableGroupOutputBuf(pAggInfo, numOfOutput, tableGroupId, pTaskInfo);
3295 3296

  // record the current active group id
3297
  pAggInfo->groupId = tableGroupId;
3298 3299
}

H
Haojun Liao 已提交
3300
void setCtxTagForJoin(STaskRuntimeEnv* pRuntimeEnv, SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable) {
H
Haojun Liao 已提交
3301
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
3302

H
Haojun Liao 已提交
3303
  SExprBasicInfo* pExpr = &pExprInfo->base;
L
Liu Jicong 已提交
3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327
  //  if (pQueryAttr->stableQuery && (pRuntimeEnv->pTsBuf != NULL) &&
  //      (pExpr->functionId == FUNCTION_TS || pExpr->functionId == FUNCTION_PRJ) &&
  //      (pExpr->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_ID)) {
  //    assert(pExpr->numOfParams == 1);
  //
  //    int16_t      tagColId = (int16_t)pExprInfo->base.param[0].i;
  //    SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);
  //
  //    doSetTagValueInParam(pTable, tagColId, &pCtx->tag, pColInfo->type, pColInfo->bytes);
  //
  //    int16_t tagType = pCtx[0].tag.nType;
  //    if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) {
  //      //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s",
  //      GET_TASKID(pRuntimeEnv),
  ////             pExprInfo->base.param[0].i, pCtx[0].tag.pz);
  //    } else {
  //      //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64,
  //      GET_TASKID(pRuntimeEnv),
  ////             pExprInfo->base.param[0].i, pCtx[0].tag.i);
  //    }
  //  }
}

int32_t setTimestampListJoinInfo(STaskRuntimeEnv* pRuntimeEnv, SVariant* pTag, STableQueryInfo* pTableQueryInfo) {
H
Haojun Liao 已提交
3328
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
3329 3330

  assert(pRuntimeEnv->pTsBuf != NULL);
H
Haojun Liao 已提交
3331
#if 0
3332 3333 3334 3335 3336 3337 3338 3339 3340
  // both the master and supplement scan needs to set the correct ts comp start position
  if (pTableQueryInfo->cur.vgroupIndex == -1) {
    taosVariantAssign(&pTableQueryInfo->tag, pTag);

    STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQueryAttr->vgId, &pTableQueryInfo->tag);

    // failed to find data with the specified tag value and vnodeId
    if (!tsBufIsValidElem(&elem)) {
      if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
3341
        //qError("QInfo:0x%"PRIx64" failed to find tag:%s in ts_comp", GET_TASKID(pRuntimeEnv), pTag->pz);
3342
      } else {
3343
        //qError("QInfo:0x%"PRIx64" failed to find tag:%" PRId64 " in ts_comp", GET_TASKID(pRuntimeEnv), pTag->i);
3344 3345 3346 3347 3348 3349 3350 3351
      }

      return -1;
    }

    // Keep the cursor info of current table
    pTableQueryInfo->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf);
    if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
3352
      //qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
3353
    } else {
3354
      //qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
3355 3356 3357 3358 3359
    }

  } else {
    tsBufSetCursor(pRuntimeEnv->pTsBuf, &pTableQueryInfo->cur);
    if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) {
3360
      //qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
3361
    } else {
3362
      //qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
3363 3364
    }
  }
H
Haojun Liao 已提交
3365
#endif
3366 3367 3368 3369 3370 3371
  return 0;
}

/*
 * There are two cases to handle:
 *
L
Liu Jicong 已提交
3372 3373
 * 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.
3374 3375 3376 3377
 * 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.
 */
L
Liu Jicong 已提交
3378 3379 3380 3381
void setIntervalQueryRange(STaskRuntimeEnv* pRuntimeEnv, TSKEY key) {
  STaskAttr*       pQueryAttr = pRuntimeEnv->pQueryAttr;
  STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
  SResultRowInfo*  pResultRowInfo = &pTableQueryInfo->resInfo;
3382 3383 3384 3385 3386

  if (pResultRowInfo->curPos != -1) {
    return;
  }

L
Liu Jicong 已提交
3387
  //  pTableQueryInfo->win.skey = key;
3388 3389 3390 3391 3392 3393 3394 3395 3396 3397
  STimeWindow win = {.skey = key, .ekey = pQueryAttr->window.ekey};

  /**
   * 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.
   */
  STimeWindow w = TSWINDOW_INITIALIZER;

dengyihao's avatar
dengyihao 已提交
3398 3399
  TSKEY sk = TMIN(win.skey, win.ekey);
  TSKEY ek = TMAX(win.skey, win.ekey);
L
Liu Jicong 已提交
3400
  //  getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w);
3401

L
Liu Jicong 已提交
3402 3403 3404 3405 3406 3407 3408
  //  if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
  //    if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
  //      assert(win.ekey == pQueryAttr->window.ekey);
  //    }
  //
  //    pResultRowInfo->prevSKey = w.skey;
  //  }
3409

L
Liu Jicong 已提交
3410
  //  pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421
}

/**
 * copyToOutputBuf support copy data in ascending/descending order
 * 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
 */
L
Liu Jicong 已提交
3422 3423
static int32_t doCopyToSDataBlock(SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, int32_t orderType,
                                  SSDataBlock* pBlock, int32_t rowCapacity, int32_t* rowCellOffset) {
3424
  int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
L
Liu Jicong 已提交
3425
  int32_t numOfResult = pBlock->info.rows;  // there are already exists result rows
3426 3427 3428 3429

  int32_t start = 0;
  int32_t step = -1;

L
Liu Jicong 已提交
3430
  // qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
3431 3432 3433 3434 3435 3436 3437 3438 3439 3440
  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;
  }

3441 3442
  int32_t nrows = pBlock->info.rows;

3443
  for (int32_t i = start; (i < numOfRows) && (i >= 0); i += step) {
3444
    SResultRowPosition* pPos = taosArrayGet(pGroupResInfo->pRows, i);
L
Liu Jicong 已提交
3445
    SFilePage*          page = getBufPage(pBuf, pPos->pageId);
3446 3447

    SResultRow* pRow = (SResultRow*)((char*)page + pPos->offset);
3448 3449 3450 3451 3452
    if (pRow->numOfRows == 0) {
      pGroupResInfo->index += 1;
      continue;
    }

3453
    // TODO copy multiple rows?
3454
    int32_t numOfRowsToCopy = pRow->numOfRows;
L
Liu Jicong 已提交
3455
    if (numOfResult + numOfRowsToCopy >= rowCapacity) {
3456 3457 3458 3459 3460 3461
      break;
    }

    pGroupResInfo->index += 1;

    for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) {
L
Liu Jicong 已提交
3462
      SColumnInfoData*     pColInfoData = taosArrayGet(pBlock->pDataBlock, j);
3463
      SResultRowEntryInfo* pEntryInfo = getResultCell(pRow, j, rowCellOffset);
3464

3465 3466
      char* in = GET_ROWCELL_INTERBUF(pEntryInfo);
      colDataAppend(pColInfoData, nrows, in, pEntryInfo->numOfRes == 0);
3467 3468
    }

3469 3470 3471
    releaseBufPage(pBuf, page);
    nrows += 1;

3472
    numOfResult += numOfRowsToCopy;
H
Haojun Liao 已提交
3473
    if (numOfResult == rowCapacity) {  // output buffer is full
3474 3475 3476 3477
      break;
    }
  }

L
Liu Jicong 已提交
3478
  // qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
3479 3480 3481 3482
  pBlock->info.rows = numOfResult;
  return 0;
}

H
Haojun Liao 已提交
3483
void toSDatablock(SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pBuf, SSDataBlock* pBlock, int32_t rowCapacity,
L
Liu Jicong 已提交
3484
                         int32_t* rowCellOffset) {
3485 3486
  assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup);

3487
  blockDataCleanup(pBlock);
3488 3489 3490 3491
  if (!hasRemainDataInCurrentGroup(pGroupResInfo)) {
    return;
  }

3492
  int32_t orderType = TSDB_ORDER_ASC;
3493
  doCopyToSDataBlock(pBuf, pGroupResInfo, orderType, pBlock, rowCapacity, rowCellOffset);
3494

H
Haojun Liao 已提交
3495 3496
  // add condition (pBlock->info.rows >= 1) just to runtime happy
  blockDataUpdateTsWindow(pBlock);
3497 3498
}

L
Liu Jicong 已提交
3499 3500
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
                                        int32_t* rowCellInfoOffset) {
3501
  // update the number of result for each, only update the number of rows for the corresponding window result.
L
Liu Jicong 已提交
3502 3503 3504
  //  if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
  //    return;
  //  }
H
Haojun Liao 已提交
3505
#if 0
3506
  for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
L
Liu Jicong 已提交
3507
    SResultRow* pResult = pResultRowInfo->pResult[i];
3508 3509 3510 3511 3512 3513 3514

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

3515 3516
      SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
      pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
3517 3518
    }
  }
H
Haojun Liao 已提交
3519 3520
#endif

3521 3522
}

L
Liu Jicong 已提交
3523
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
3524 3525
  int32_t colSize = pColRes->info.bytes * numOfRows;
  return (*(tDataTypes[pColRes->info.type].compFunc))(pColRes->pData, colSize, numOfRows, data,
L
Liu Jicong 已提交
3526
                                                      colSize + COMP_OVERFLOW_BYTES, compressed, NULL, 0);
3527 3528
}

L
Liu Jicong 已提交
3529 3530 3531 3532 3533
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);
  //  }
3534 3535 3536 3537 3538 3539 3540 3541 3542 3543

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

  return pOutput->info.rows;
}

void publishOperatorProfEvent(SOperatorInfo* operatorInfo, EQueryProfEventType eventType) {
  SQueryProfEvent event = {0};

L
Liu Jicong 已提交
3544 3545
  event.eventType = eventType;
  event.eventTime = taosGetTimestampUs();
3546 3547 3548
  event.operatorType = operatorInfo->operatorType;

  if (operatorInfo->pRuntimeEnv) {
L
Liu Jicong 已提交
3549 3550 3551 3552
    //    SQInfo* pQInfo = operatorInfo->pRuntimeEnv->qinfo;
    //    if (pQInfo->summary.queryProfEvents) {
    //      taosArrayPush(pQInfo->summary.queryProfEvents, &event);
    //    }
3553 3554 3555
  }
}

L
Liu Jicong 已提交
3556
void publishQueryAbortEvent(SExecTaskInfo* pTaskInfo, int32_t code) {
3557 3558 3559 3560 3561
  SQueryProfEvent event;
  event.eventType = QUERY_PROF_QUERY_ABORT;
  event.eventTime = taosGetTimestampUs();
  event.abortCode = code;

3562 3563
  if (pTaskInfo->cost.queryProfEvents) {
    taosArrayPush(pTaskInfo->cost.queryProfEvents, &event);
3564 3565 3566
  }
}

L
Liu Jicong 已提交
3567
typedef struct {
3568 3569 3570 3571 3572 3573 3574
  uint8_t operatorType;
  int64_t beginTime;
  int64_t endTime;
  int64_t selfTime;
  int64_t descendantsTime;
} SOperatorStackItem;

L
Liu Jicong 已提交
3575 3576
static void doOperatorExecProfOnce(SOperatorStackItem* item, SQueryProfEvent* event, SArray* opStack,
                                   SHashObj* profResults) {
3577 3578 3579 3580 3581 3582 3583 3584
  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 已提交
3585
  uint8_t              operatorType = item->operatorType;
3586 3587 3588 3589 3590 3591 3592 3593 3594
  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 已提交
3595
    taosHashPut(profResults, &(operatorType), sizeof(operatorType), &opResult, sizeof(opResult));
3596 3597 3598 3599 3600
  }
}

void calculateOperatorProfResults(SQInfo* pQInfo) {
  if (pQInfo->summary.queryProfEvents == NULL) {
L
Liu Jicong 已提交
3601
    // qDebug("QInfo:0x%"PRIx64" query prof events array is null", pQInfo->qId);
3602 3603 3604 3605
    return;
  }

  if (pQInfo->summary.operatorProfResults == NULL) {
L
Liu Jicong 已提交
3606
    // qDebug("QInfo:0x%"PRIx64" operator prof results hash is null", pQInfo->qId);
3607 3608 3609 3610 3611 3612 3613 3614
    return;
  }

  SArray* opStack = taosArrayInit(32, sizeof(SOperatorStackItem));
  if (opStack == NULL) {
    return;
  }

L
Liu Jicong 已提交
3615
  size_t    size = taosArrayGetSize(pQInfo->summary.queryProfEvents);
3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640
  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);
      }
    }
  }

  taosArrayDestroy(opStack);
}

L
Liu Jicong 已提交
3641 3642
void queryCostStatis(SExecTaskInfo* pTaskInfo) {
  STaskCostInfo* pSummary = &pTaskInfo->cost;
3643

L
Liu Jicong 已提交
3644 3645 3646
  //  uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
  //  hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
  //  pSummary->hashSize = hashSize;
3647 3648 3649 3650

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

L
Liu Jicong 已提交
3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670
  //  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);
3671 3672 3673 3674

  if (pSummary->operatorProfResults) {
    SOperatorProfResult* opRes = taosHashIterate(pSummary->operatorProfResults, NULL);
    while (opRes != NULL) {
L
Liu Jicong 已提交
3675 3676
      // qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
      //             pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
3677 3678 3679 3680 3681
      opRes = taosHashIterate(pSummary->operatorProfResults, opRes);
    }
  }
}

L
Liu Jicong 已提交
3682 3683 3684
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
3685
//
L
Liu Jicong 已提交
3686
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3687
//
L
Liu Jicong 已提交
3688 3689 3690 3691
//   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;
//   }
3692
//
L
Liu Jicong 已提交
3693 3694 3695 3696 3697
//   if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
//     pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
//   } else {
//     pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
//   }
3698
//
L
Liu Jicong 已提交
3699
//   assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
3700
//
L
Liu Jicong 已提交
3701 3702
//   SArray *         pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//   SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3703
//
L
Liu Jicong 已提交
3704 3705
//   // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
//   TSKEY *keys = (TSKEY *) pColInfoData->pData;
3706
//
L
Liu Jicong 已提交
3707 3708 3709
//   // update the offset value
//   pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
//   pQueryAttr->limit.offset = 0;
3710
//
L
Liu Jicong 已提交
3711
//   int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
3712
//
L
Liu Jicong 已提交
3713 3714 3715 3716
//   //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);
// }
3717

L
Liu Jicong 已提交
3718 3719
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
//   STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
3720
//
L
Liu Jicong 已提交
3721 3722 3723
//   if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
//     return;
//   }
3724
//
L
Liu Jicong 已提交
3725 3726
//   pQueryAttr->pos = 0;
//   int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
3727
//
L
Liu Jicong 已提交
3728 3729
//   STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//   TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
3730
//
L
Liu Jicong 已提交
3731 3732 3733 3734 3735
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pTsdbReadHandle)) {
//     if (isTaskKilled(pRuntimeEnv->qinfo)) {
//       longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
//     }
3736
//
L
Liu Jicong 已提交
3737
//     tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
3738
//
L
Liu Jicong 已提交
3739 3740 3741 3742
//     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;
3743
//
L
Liu Jicong 已提交
3744 3745 3746 3747 3748 3749 3750
//       //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;
//     }
//   }
3751
//
L
Liu Jicong 已提交
3752 3753 3754 3755 3756 3757 3758 3759 3760
//   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;
3761
//
L
Liu Jicong 已提交
3762 3763 3764
//   assert(pQueryAttr->limit.offset == 0);
//   STimeWindow tw = *win;
//   getNextTimeWindow(pQueryAttr, &tw);
3765
//
L
Liu Jicong 已提交
3766 3767
//   if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
//       (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
3768
//
L
Liu Jicong 已提交
3769 3770 3771 3772
//     // 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);
3773
//
L
Liu Jicong 已提交
3774 3775 3776 3777
//     tw = *win;
//     int32_t startPos =
//         getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
//     assert(startPos >= 0);
3778
//
L
Liu Jicong 已提交
3779 3780
//     // set the abort info
//     pQueryAttr->pos = startPos;
3781
//
L
Liu Jicong 已提交
3782 3783 3784 3785
//     // reset the query start timestamp
//     pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
//     pQueryAttr->window.skey = pTableQueryInfo->win.skey;
//     TSKEY key = pTableQueryInfo->win.skey;
3786
//
L
Liu Jicong 已提交
3787 3788
//     pWindowResInfo->prevSKey = tw.skey;
//     int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
3789
//
L
Liu Jicong 已提交
3790 3791
//     int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//     pRuntimeEnv->resultRowInfo.curIndex = index;  // restore the window index
3792
//
L
Liu Jicong 已提交
3793 3794 3795 3796
//     //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);
3797
//
L
Liu Jicong 已提交
3798 3799 3800 3801 3802
//     return key;
//   } else {  // do nothing
//     pQueryAttr->window.skey      = tw.skey;
//     pWindowResInfo->prevSKey = tw.skey;
//     pTableQueryInfo->lastKey = tw.skey;
3803
//
L
Liu Jicong 已提交
3804 3805
//     return tw.skey;
//   }
3806
//
L
Liu Jicong 已提交
3807 3808 3809 3810 3811 3812 3813 3814 3815 3816
//   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);
//   }
3817
//
L
Liu Jicong 已提交
3818 3819 3820 3821 3822
//   // 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;
//   }
3823
//
L
Liu Jicong 已提交
3824 3825 3826 3827 3828 3829 3830
//   /*
//    * 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);
3831
//
L
Liu Jicong 已提交
3832 3833
//   STimeWindow w = TSWINDOW_INITIALIZER;
//   bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
3834
//
L
Liu Jicong 已提交
3835 3836
//   SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//   STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
3837
//
L
Liu Jicong 已提交
3838 3839 3840
//   SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
//   while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
//     tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
3841
//
L
Liu Jicong 已提交
3842 3843 3844 3845 3846 3847 3848 3849 3850
//     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;
//     }
3851
//
L
Liu Jicong 已提交
3852 3853
//     // the first time window
//     STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
3854
//
L
Liu Jicong 已提交
3855 3856
//     while (pQueryAttr->limit.offset > 0) {
//       STimeWindow tw = win;
3857
//
L
Liu Jicong 已提交
3858 3859 3860
//       if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
//         pQueryAttr->limit.offset -= 1;
//         pWindowResInfo->prevSKey = win.skey;
3861
//
L
Liu Jicong 已提交
3862 3863 3864 3865 3866 3867
//         // 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;
//         }
//       }
3868
//
L
Liu Jicong 已提交
3869 3870 3871 3872
//       if (pQueryAttr->limit.offset == 0) {
//         *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
//         return true;
//       }
3873
//
L
Liu Jicong 已提交
3874 3875
//       // current window does not ended in current data block, try next data block
//       getNextTimeWindow(pQueryAttr, &tw);
3876
//
L
Liu Jicong 已提交
3877 3878 3879 3880 3881 3882 3883 3884 3885
//       /*
//        * 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)) {
3886
//
L
Liu Jicong 已提交
3887 3888
//         SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
//         SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
3889
//
L
Liu Jicong 已提交
3890 3891 3892
//         if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
//           pQueryAttr->limit.offset -= 1;
//         }
3893
//
L
Liu Jicong 已提交
3894 3895 3896 3897 3898 3899 3900 3901
//         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);
3902
//
L
Liu Jicong 已提交
3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913
//           // 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.
//       }
//     }
//   }
3914
//
L
Liu Jicong 已提交
3915 3916 3917 3918
//   // check for error
//   if (terrno != TSDB_CODE_SUCCESS) {
//     longjmp(pRuntimeEnv->env, terrno);
//   }
3919
//
L
Liu Jicong 已提交
3920 3921
//   return true;
// }
3922

3923
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
H
Haojun Liao 已提交
3924
  if (p->pDownstream == NULL) {
H
Haojun Liao 已提交
3925
    assert(p->numOfDownstream == 0);
3926 3927
  }

wafwerar's avatar
wafwerar 已提交
3928
  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
3929 3930 3931 3932 3933 3934 3935
  if (p->pDownstream == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }

  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
  p->numOfDownstream = num;
  return TSDB_CODE_SUCCESS;
3936 3937 3938 3939
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo);

H
Haojun Liao 已提交
3940
static int32_t setupQueryHandle(void* tsdb, STaskRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) {
L
Liu Jicong 已提交
3941
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966
#if 0
  // TODO set the tags scan handle
  if (onlyQueryTags(pQueryAttr)) {
    return TSDB_CODE_SUCCESS;
  }

  STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
  if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery) {
    cond.type = BLOCK_LOAD_TABLE_SEQ_ORDER;
  }

  if (!isSTableQuery
    && (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 1)
    && (cond.order == TSDB_ORDER_ASC)
    && (!QUERY_IS_INTERVAL_QUERY(pQueryAttr))
    && (!pQueryAttr->groupbyColumn)
    && (!pQueryAttr->simpleAgg)
  ) {
    SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0);
    STableQueryInfo* pCheckInfo = taosArrayGetP(pa, 0);
    cond.twindow = pCheckInfo->win;
  }

  terrno = TSDB_CODE_SUCCESS;
  if (isFirstLastRowQuery(pQueryAttr)) {
3967
    pRuntimeEnv->pTsdbReadHandle = tsdbQueryLastRow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987

    // update the query time window
    pQueryAttr->window = cond.twindow;
    if (pQueryAttr->tableGroupInfo.numOfTables == 0) {
      pRuntimeEnv->tableqinfoGroupInfo.numOfTables = 0;
    } else {
      size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pRuntimeEnv);
      for(int32_t i = 0; i < numOfGroups; ++i) {
        SArray *group = GET_TABLEGROUP(pRuntimeEnv, i);

        size_t t = taosArrayGetSize(group);
        for (int32_t j = 0; j < t; ++j) {
          STableQueryInfo *pCheckInfo = taosArrayGetP(group, j);

          pCheckInfo->win = pQueryAttr->window;
          pCheckInfo->lastKey = pCheckInfo->win.skey;
        }
      }
    }
  } else if (isCachedLastQuery(pQueryAttr)) {
3988
    pRuntimeEnv->pTsdbReadHandle = tsdbQueryCacheLast(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
3989
  } else if (pQueryAttr->pointInterpQuery) {
3990
    pRuntimeEnv->pTsdbReadHandle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
3991
  } else {
3992
    pRuntimeEnv->pTsdbReadHandle = tsdbQueryTables(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
3993 3994 3995 3996 3997
  }
#endif
  return terrno;
}

3998
static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQueryInfo* pTableQueryInfo, int32_t order) {
H
Haojun Liao 已提交
3999 4000
#if 0
    if (order == TSDB_ORDER_ASC) {
4001 4002
    assert(
        (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
4003 4004
        (pTableQueryInfo->lastKey >= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey >= pTaskInfo->window.skey && pTableQueryInfo->win.ekey <= pTaskInfo->window.ekey));
4005 4006 4007
  } else {
    assert(
        (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) &&
H
Haojun Liao 已提交
4008 4009
        (pTableQueryInfo->lastKey <= pTaskInfo->window.skey) &&
        (pTableQueryInfo->win.skey <= pTaskInfo->window.skey && pTableQueryInfo->win.ekey >= pTaskInfo->window.ekey));
4010
  }
H
Haojun Liao 已提交
4011
#endif
4012 4013
}

L
Liu Jicong 已提交
4014 4015 4016 4017 4018 4019 4020 4021
// STsdbQueryCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
//   STsdbQueryCond cond = {
//       .colList   = pQueryAttr->tableCols,
//       .order     = pQueryAttr->order.order,
//       .numOfCols = pQueryAttr->numOfCols,
//       .type      = BLOCK_LOAD_OFFSET_SEQ_ORDER,
//       .loadExternalRows = false,
//   };
4022
//
L
Liu Jicong 已提交
4023 4024 4025
//   TIME_WINDOW_COPY(cond.twindow, *win);
//   return cond;
// }
4026 4027 4028

static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo) {
  STableIdInfo tidInfo;
L
Liu Jicong 已提交
4029 4030 4031 4032 4033
  //  STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
  //
  //  tidInfo.uid = id->uid;
  //  tidInfo.tid = id->tid;
  //  tidInfo.key = pTableQueryInfo->lastKey;
4034 4035 4036 4037

  return tidInfo;
}

L
Liu Jicong 已提交
4038 4039 4040 4041
// 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;
4042
//
L
Liu Jicong 已提交
4043 4044 4045
//   if (pTableQueryInfo->pTable == NULL) {
//     return;
//   }
4046
//
L
Liu Jicong 已提交
4047 4048 4049 4050 4051 4052 4053 4054 4055
//   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));
//   }
// }
4056

H
Haojun Liao 已提交
4057
static void doCloseAllTimeWindow(STaskRuntimeEnv* pRuntimeEnv) {
4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069
  size_t numOfGroup = GET_NUM_OF_TABLEGROUP(pRuntimeEnv);
  for (int32_t i = 0; i < numOfGroup; ++i) {
    SArray* group = GET_TABLEGROUP(pRuntimeEnv, i);

    size_t num = taosArrayGetSize(group);
    for (int32_t j = 0; j < num; ++j) {
      STableQueryInfo* item = taosArrayGetP(group, j);
      closeAllResultRows(&item->resInfo);
    }
  }
}

4070
int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) {
L
Liu Jicong 已提交
4071
  SSourceDataInfo* pSourceDataInfo = (SSourceDataInfo*)param;
H
Haojun Liao 已提交
4072 4073
  if (code == TSDB_CODE_SUCCESS) {
    pSourceDataInfo->pRsp = pMsg->pData;
4074

H
Haojun Liao 已提交
4075 4076 4077 4078 4079 4080 4081
    SRetrieveTableRsp* pRsp = pSourceDataInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
    pRsp->compLen   = htonl(pRsp->compLen);
    pRsp->useconds  = htobe64(pRsp->useconds);
  } else {
    pSourceDataInfo->code = code;
  }
H
Haojun Liao 已提交
4082

H
Haojun Liao 已提交
4083
  pSourceDataInfo->status = EX_SOURCE_DATA_READY;
4084
  tsem_post(&pSourceDataInfo->pEx->ready);
H
Haojun Liao 已提交
4085 4086 4087 4088
}

static void destroySendMsgInfo(SMsgSendInfo* pMsgBody) {
  assert(pMsgBody != NULL);
wafwerar's avatar
wafwerar 已提交
4089 4090
  taosMemoryFreeClear(pMsgBody->msgInfo.pData);
  taosMemoryFreeClear(pMsgBody);
H
Haojun Liao 已提交
4091 4092
}

S
Shengliang Guan 已提交
4093
void qProcessFetchRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
L
Liu Jicong 已提交
4094
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->ahandle;
H
Haojun Liao 已提交
4095 4096 4097 4098 4099
  assert(pMsg->ahandle != NULL);

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

  if (pMsg->contLen > 0) {
wafwerar's avatar
wafwerar 已提交
4100
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
H
Haojun Liao 已提交
4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111
    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);
4112 4113
}

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

wafwerar's avatar
wafwerar 已提交
4117
  SResFetchReq* pMsg = taosMemoryCalloc(1, sizeof(SResFetchReq));
4118 4119 4120 4121
  if (NULL == pMsg) {
    pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return pTaskInfo->code;
  }
4122

L
Liu Jicong 已提交
4123 4124
  SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
  SSourceDataInfo*       pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
4125

L
Liu Jicong 已提交
4126 4127
  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);
4128 4129 4130 4131 4132 4133 4134

  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 已提交
4135
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
4136
  if (NULL == pMsgSendInfo) {
wafwerar's avatar
wafwerar 已提交
4137
    taosMemoryFreeClear(pMsg);
4138 4139 4140
    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 已提交
4141 4142
  }

4143 4144 4145 4146 4147
  pMsgSendInfo->param = pDataInfo;
  pMsgSendInfo->msgInfo.pData = pMsg;
  pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq);
  pMsgSendInfo->msgType = TDMT_VND_FETCH;
  pMsgSendInfo->fp = loadRemoteDataCallback;
4148

4149
  int64_t transporterId = 0;
L
Liu Jicong 已提交
4150
  int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
4151 4152 4153
  return TSDB_CODE_SUCCESS;
}

4154
// TODO if only one or two columnss required, how to extract data?
H
Haojun Liao 已提交
4155
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows,
L
Liu Jicong 已提交
4156 4157
                                         char* pData, int32_t compLen, int32_t numOfOutput, int64_t startTs,
                                         uint64_t* total, SArray* pColList) {
H
Haojun Liao 已提交
4158
  blockDataEnsureCapacity(pRes, numOfRows);
4159

H
Haojun Liao 已提交
4160 4161
  if (pColList == NULL) {  // data from other sources
    int32_t* colLen = (int32_t*)pData;
L
Liu Jicong 已提交
4162
    char*    pStart = pData + sizeof(int32_t) * numOfOutput;
H
Haojun Liao 已提交
4163

4164
    for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
4165 4166 4167
      colLen[i] = htonl(colLen[i]);
      ASSERT(colLen[i] > 0);

4168
      SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
H
Haojun Liao 已提交
4169 4170 4171
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
        pColInfoData->varmeta.length = colLen[i];
        pColInfoData->varmeta.allocLen = colLen[i];
4172

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

wafwerar's avatar
wafwerar 已提交
4176
        pColInfoData->pData = taosMemoryMalloc(colLen[i]);
H
Haojun Liao 已提交
4177 4178 4179
      } else {
        memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
        pStart += BitmapLen(numOfRows);
4180
      }
H
Haojun Liao 已提交
4181 4182 4183

      memcpy(pColInfoData->pData, pStart, colLen[i]);
      pStart += colLen[i];
4184
    }
H
Haojun Liao 已提交
4185
  } else {  // extract data according to pColList
4186
    ASSERT(numOfOutput == taosArrayGetSize(pColList));
H
Haojun Liao 已提交
4187 4188

    // data from mnode
L
Liu Jicong 已提交
4189 4190 4191
    for (int32_t i = 0; i < numOfOutput; ++i) {
      for (int32_t j = 0; j < numOfOutput; ++j) {
        int16_t colIndex = *(int16_t*)taosArrayGet(pColList, j);
4192 4193
        if (colIndex - 1 == i) {
          SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, j);
4194

4195 4196 4197 4198 4199 4200 4201
          for (int32_t k = 0; k < numOfRows; ++k) {
            colDataAppend(pColInfoData, k, pData, false);
            pData += pColInfoData->info.bytes;
          }
          break;
        }
      }
4202
    }
4203
  }
4204

H
Haojun Liao 已提交
4205
  pRes->info.rows = numOfRows;
4206

4207
  int64_t el = taosGetTimestampUs() - startTs;
4208

H
Haojun Liao 已提交
4209 4210
  pLoadInfo->totalRows += numOfRows;
  pLoadInfo->totalSize += compLen;
4211

H
Haojun Liao 已提交
4212 4213 4214
  if (total != NULL) {
    *total += numOfRows;
  }
4215

H
Haojun Liao 已提交
4216
  pLoadInfo->totalElapsed += el;
4217 4218
  return TSDB_CODE_SUCCESS;
}
4219

L
Liu Jicong 已提交
4220 4221
static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
4222
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
4223

L
Liu Jicong 已提交
4224
  int64_t              el = taosGetTimestampUs() - startTs;
H
Haojun Liao 已提交
4225 4226
  SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
  pLoadInfo->totalElapsed += el;
H
Haojun Liao 已提交
4227

4228
  size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
L
Liu Jicong 已提交
4229 4230 4231
  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);
4232 4233 4234 4235 4236

  doSetOperatorCompleted(pOperator);
  return NULL;
}

L
Liu Jicong 已提交
4237 4238
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
                                                   SExecTaskInfo* pTaskInfo) {
4239 4240 4241 4242 4243 4244 4245 4246 4247
  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);

4248
      if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
4249
        completed += 1;
H
Haojun Liao 已提交
4250 4251
        continue;
      }
4252

4253
      if (pDataInfo->status != EX_SOURCE_DATA_READY) {
4254 4255 4256
        continue;
      }

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

L
Liu Jicong 已提交
4260
      SSDataBlock*         pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
4261
      SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
4262
      if (pRsp->numOfRows == 0) {
L
Liu Jicong 已提交
4263 4264
        qDebug("%s vgId:%d, taskID:0x%" PRIx64 " index:%d completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64
               " try next",
4265
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, i + 1, pDataInfo->totalRows,
H
Haojun Liao 已提交
4266
               pExchangeInfo->loadInfo.totalRows);
4267
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4268 4269 4270
        completed += 1;
        continue;
      }
H
Haojun Liao 已提交
4271

H
Haojun Liao 已提交
4272
      SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
4273 4274 4275
      code =
          setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                    pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
4276
      if (code != 0) {
4277 4278 4279
        goto _error;
      }

4280 4281 4282
      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 已提交
4283 4284
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pDataInfo->totalRows,
               pLoadInfo->totalRows, pLoadInfo->totalSize, i + 1, totalSources);
4285
        pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4286
      } else {
4287
        qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, totalRows:%" PRIu64 ", totalBytes:%" PRIu64,
H
Haojun Liao 已提交
4288 4289
               GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pRes->info.rows, pLoadInfo->totalRows,
               pLoadInfo->totalSize);
4290 4291
      }

4292 4293
      if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED) {
        pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312
        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 已提交
4313 4314 4315
static SSDataBlock* concurrentlyLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
4316

H
Haojun Liao 已提交
4317 4318 4319
  if (pOperator->status == OP_RES_TO_RETURN) {
    return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
  }
4320

L
Liu Jicong 已提交
4321
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4322 4323 4324
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
4325
  for (int32_t i = 0; i < totalSources; ++i) {
4326 4327
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4328
      return NULL;
4329 4330 4331 4332
    }
  }

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

  tsem_wait(&pExchangeInfo->ready);
H
Haojun Liao 已提交
4337 4338
  pOperator->status = OP_RES_TO_RETURN;
  return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
4339 4340
}

L
Liu Jicong 已提交
4341 4342 4343
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4344

L
Liu Jicong 已提交
4345
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4346 4347 4348
  int64_t startTs = taosGetTimestampUs();

  // Asynchronously send all fetch requests to all sources.
L
Liu Jicong 已提交
4349
  for (int32_t i = 0; i < totalSources; ++i) {
4350 4351
    int32_t code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4352 4353
      pTaskInfo->code = code;
      return code;
4354 4355 4356 4357
    }
  }

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

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

H
Haojun Liao 已提交
4364
  return TSDB_CODE_SUCCESS;
4365 4366
}

L
Liu Jicong 已提交
4367 4368 4369
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4370

L
Liu Jicong 已提交
4371
  size_t  totalSources = taosArrayGetSize(pExchangeInfo->pSources);
4372
  int64_t startTs = taosGetTimestampUs();
4373

L
Liu Jicong 已提交
4374
  while (1) {
4375 4376
    if (pExchangeInfo->current >= totalSources) {
      return setAllSourcesCompleted(pOperator, startTs);
4377
    }
4378

4379 4380 4381
    doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
    tsem_wait(&pExchangeInfo->ready);

H
Haojun Liao 已提交
4382
    SSourceDataInfo* pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, pExchangeInfo->current);
X
Xiaoyu Wang 已提交
4383
    SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, pExchangeInfo->current);
4384

H
Haojun Liao 已提交
4385 4386 4387 4388 4389 4390 4391
    if (pDataInfo->code != TSDB_CODE_SUCCESS) {
      qError("%s vgId:%d, taskID:0x%" PRIx64 " error happens, code:%s",
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, tstrerror(pDataInfo->code));
      pOperator->pTaskInfo->code = pDataInfo->code;
      return NULL;
    }

L
Liu Jicong 已提交
4392
    SRetrieveTableRsp*   pRsp = pDataInfo->pRsp;
H
Haojun Liao 已提交
4393
    SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
4394
    if (pRsp->numOfRows == 0) {
H
Haojun Liao 已提交
4395
      qDebug("%s vgId:%d, taskID:0x%" PRIx64 " %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64 " try next",
4396
             GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
H
Haojun Liao 已提交
4397
             pDataInfo->totalRows, pLoadInfo->totalRows);
H
Haojun Liao 已提交
4398

4399
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4400 4401 4402
      pExchangeInfo->current += 1;
      continue;
    }
H
Haojun Liao 已提交
4403

L
Liu Jicong 已提交
4404
    SSDataBlock*       pRes = pExchangeInfo->pResult;
H
Haojun Liao 已提交
4405
    SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
L
Liu Jicong 已提交
4406 4407 4408
    int32_t            code =
        setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
                                  pTableRsp->compLen, pOperator->numOfOutput, startTs, &pDataInfo->totalRows, NULL);
4409 4410

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

4416
      pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
4417 4418
      pExchangeInfo->current += 1;
    } else {
L
Liu Jicong 已提交
4419 4420 4421 4422
      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);
4423 4424 4425 4426
    }

    return pExchangeInfo->pResult;
  }
4427 4428
}

L
Liu Jicong 已提交
4429
static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
4430
  if (OPTR_IS_OPENED(pOperator)) {
H
Haojun Liao 已提交
4431 4432 4433
    return TSDB_CODE_SUCCESS;
  }

L
Liu Jicong 已提交
4434
  SExchangeInfo* pExchangeInfo = pOperator->info;
H
Haojun Liao 已提交
4435 4436 4437 4438 4439 4440 4441 4442 4443
  if (pExchangeInfo->seqLoadData) {
    // do nothing for sequentially load data
  } else {
    int32_t code = prepareConcurrentlyLoad(pOperator);
    if (code != TSDB_CODE_SUCCESS) {
      return code;
    }
  }

4444
  OPTR_SET_OPENED(pOperator);
H
Haojun Liao 已提交
4445 4446 4447
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4448 4449 4450
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
  SExchangeInfo* pExchangeInfo = pOperator->info;
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
4451

4452 4453
  pTaskInfo->code = pOperator->_openFn(pOperator);
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4454 4455
    return NULL;
  }
4456

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

4460
  if (pOperator->status == OP_EXEC_DONE) {
L
Liu Jicong 已提交
4461 4462 4463
    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);
4464 4465 4466 4467
    return NULL;
  }

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

4469 4470 4471
  if (pExchangeInfo->seqLoadData) {
    return seqLoadRemoteData(pOperator);
  } else {
H
Haojun Liao 已提交
4472
    return concurrentlyLoadRemoteData(pOperator);
4473
  }
H
Haojun Liao 已提交
4474

4475
#if 0
H
Haojun Liao 已提交
4476
  _error:
wafwerar's avatar
wafwerar 已提交
4477 4478
  taosMemoryFreeClear(pMsg);
  taosMemoryFreeClear(pMsgSendInfo);
H
Haojun Liao 已提交
4479 4480 4481

  terrno = pTaskInfo->code;
  return NULL;
4482
#endif
H
Haojun Liao 已提交
4483
}
4484

H
Haojun Liao 已提交
4485
static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
4486
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
H
Haojun Liao 已提交
4487 4488
  if (pInfo->pSourceDataInfo == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
4489 4490
  }

L
Liu Jicong 已提交
4491
  for (int32_t i = 0; i < numOfSources; ++i) {
4492
    SSourceDataInfo dataInfo = {0};
H
Haojun Liao 已提交
4493
    dataInfo.status = EX_SOURCE_DATA_NOT_READY;
L
Liu Jicong 已提交
4494 4495
    dataInfo.pEx = pInfo;
    dataInfo.index = i;
4496

H
Haojun Liao 已提交
4497 4498 4499 4500 4501 4502 4503 4504 4505 4506
    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 已提交
4507
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
4508
  SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
wafwerar's avatar
wafwerar 已提交
4509
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
4510 4511

  if (pInfo == NULL || pOperator == NULL) {
wafwerar's avatar
wafwerar 已提交
4512 4513
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4514 4515
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
H
Haojun Liao 已提交
4516 4517
  }

H
Haojun Liao 已提交
4518
  size_t numOfSources = LIST_LENGTH(pSources);
H
Haojun Liao 已提交
4519
  pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
H
Haojun Liao 已提交
4520 4521 4522
  pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
  if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
    goto _error;
H
Haojun Liao 已提交
4523 4524
  }

L
Liu Jicong 已提交
4525 4526
  for (int32_t i = 0; i < numOfSources; ++i) {
    SNodeListNode* pNode = nodesListGetNode((SNodeList*)pSources, i);
H
Haojun Liao 已提交
4527 4528
    taosArrayPush(pInfo->pSources, pNode);
  }
4529

H
Haojun Liao 已提交
4530 4531 4532
  int32_t code = initDataSource(numOfSources, pInfo);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
4533
  }
H
Haojun Liao 已提交
4534

L
Liu Jicong 已提交
4535 4536
  size_t size = pBlock->info.numOfCols;
  pInfo->pResult = pBlock;
4537 4538 4539
  pInfo->seqLoadData = true;

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

L
Liu Jicong 已提交
4541
  pOperator->name = "ExchangeOperator";
X
Xiaoyu Wang 已提交
4542
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
4543
  pOperator->blockingOptr = false;
L
Liu Jicong 已提交
4544 4545 4546 4547 4548 4549 4550
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = size;
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->_openFn = prepareLoadRemoteData;  // assign a dummy function.
  pOperator->getNextFn = doLoadRemoteData;
  pOperator->closeFn = destroyExchangeOperatorInfo;
4551

S
Shengliang Guan 已提交
4552
#if 1
L
Liu Jicong 已提交
4553
  {  // todo refactor
H
Haojun Liao 已提交
4554 4555 4556
    SRpcInit rpcInit;
    memset(&rpcInit, 0, sizeof(rpcInit));
    rpcInit.localPort = 0;
H
Haojun Liao 已提交
4557
    rpcInit.label = "EX";
H
Haojun Liao 已提交
4558
    rpcInit.numOfThreads = 1;
S
Shengliang Guan 已提交
4559
    rpcInit.cfp = qProcessFetchRsp;
S
Shengliang Guan 已提交
4560
    rpcInit.sessions = tsMaxConnections;
H
Haojun Liao 已提交
4561
    rpcInit.connType = TAOS_CONN_CLIENT;
L
Liu Jicong 已提交
4562
    rpcInit.user = (char*)"root";
S
Shengliang Guan 已提交
4563
    rpcInit.idleTime = tsShellActivityTimer * 1000;
H
Haojun Liao 已提交
4564
    rpcInit.ckey = "key";
S
Shengliang Guan 已提交
4565
    rpcInit.spi = 1;
L
Liu Jicong 已提交
4566
    rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
H
Haojun Liao 已提交
4567 4568 4569

    pInfo->pTransporter = rpcOpen(&rpcInit);
    if (pInfo->pTransporter == NULL) {
L
Liu Jicong 已提交
4570
      return NULL;  // todo
H
Haojun Liao 已提交
4571 4572
    }
  }
S
Shengliang 已提交
4573
#endif
4574

4575
  return pOperator;
H
Haojun Liao 已提交
4576

L
Liu Jicong 已提交
4577
_error:
H
Haojun Liao 已提交
4578
  if (pInfo != NULL) {
H
Haojun Liao 已提交
4579
    destroyExchangeOperatorInfo(pInfo, numOfSources);
H
Haojun Liao 已提交
4580 4581
  }

wafwerar's avatar
wafwerar 已提交
4582 4583
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
4584
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
H
Haojun Liao 已提交
4585
  return NULL;
4586 4587
}

H
Haojun Liao 已提交
4588
SSDataBlock* createResultDataBlock(const SArray* pExprInfo) {
wafwerar's avatar
wafwerar 已提交
4589
  SSDataBlock* pResBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
H
Haojun Liao 已提交
4590 4591 4592 4593 4594 4595 4596 4597
  if (pResBlock == NULL) {
    return NULL;
  }

  size_t numOfCols = taosArrayGetSize(pExprInfo);
  pResBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));

  SArray* pResult = pResBlock->pDataBlock;
L
Liu Jicong 已提交
4598
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
4599
    SColumnInfoData colInfoData = {0};
L
Liu Jicong 已提交
4600
    SExprInfo*      p = taosArrayGetP(pExprInfo, i);
H
Haojun Liao 已提交
4601

H
Haojun Liao 已提交
4602
    SResSchema* pSchema = &p->base.resSchema;
L
Liu Jicong 已提交
4603
    colInfoData.info.type = pSchema->type;
H
Haojun Liao 已提交
4604 4605
    colInfoData.info.colId = pSchema->colId;
    colInfoData.info.bytes = pSchema->bytes;
H
Haojun Liao 已提交
4606 4607
    colInfoData.info.scale = pSchema->scale;
    colInfoData.info.precision = pSchema->precision;
H
Haojun Liao 已提交
4608 4609 4610 4611 4612 4613
    taosArrayPush(pResult, &colInfoData);
  }

  return pResBlock;
}

H
Haojun Liao 已提交
4614 4615
static int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, const char* pKey);
static void    cleanupAggSup(SAggSupporter* pAggSup);
4616

4617
static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4618
  SSortedMergeOperatorInfo* pInfo = (SSortedMergeOperatorInfo*)param;
H
Haojun Liao 已提交
4619
  taosArrayDestroy(pInfo->pSortInfo);
4620 4621 4622
  taosArrayDestroy(pInfo->groupInfo);

  if (pInfo->pSortHandle != NULL) {
H
Haojun Liao 已提交
4623
    tsortDestroySortHandle(pInfo->pSortHandle);
4624 4625
  }

H
Haojun Liao 已提交
4626
  blockDataDestroy(pInfo->binfo.pRes);
H
Haojun Liao 已提交
4627
  cleanupAggSup(&pInfo->aggSup);
4628
}
H
Haojun Liao 已提交
4629

4630
static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
4631
  SSLimitOperatorInfo* pInfo = (SSLimitOperatorInfo*)param;
4632
  taosArrayDestroy(pInfo->orderColumnList);
H
Haojun Liao 已提交
4633
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
4634
  taosMemoryFreeClear(pInfo->prevRow);
4635 4636
}

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

X
Xiaoyu Wang 已提交
4640
  *dst = *src;
4641

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

L
Liu Jicong 已提交
4646 4647 4648 4649
  //  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 已提交
4650
}
4651

4652 4653
static SExprInfo* exprArrayDup(SArray* pExprList) {
  size_t numOfOutput = taosArrayGetSize(pExprList);
4654

wafwerar's avatar
wafwerar 已提交
4655
  SExprInfo* p = taosMemoryCalloc(numOfOutput, sizeof(SExprInfo));
4656 4657
  for (int32_t i = 0; i < numOfOutput; ++i) {
    SExprInfo* pExpr = taosArrayGetP(pExprList, i);
H
Haojun Liao 已提交
4658
    assignExprInfo(&p[i], pExpr);
4659 4660
  }

H
Haojun Liao 已提交
4661 4662
  return p;
}
4663

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

H
Haojun Liao 已提交
4669
    bool isNull = tsortIsNullVal(pTupleHandle, i);
H
Haojun Liao 已提交
4670 4671 4672
    if (isNull) {
      colDataAppend(pColInfo, pBlock->info.rows, NULL, true);
    } else {
H
Haojun Liao 已提交
4673
      char* pData = tsortGetValue(pTupleHandle, i);
H
Haojun Liao 已提交
4674 4675
      colDataAppend(pColInfo, pBlock->info.rows, pData, false);
    }
4676 4677
  }

4678 4679
  pBlock->info.rows += 1;
}
4680

L
Liu Jicong 已提交
4681 4682
static SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, bool hasVarCol,
                                       int32_t capacity) {
4683
  blockDataCleanup(pDataBlock);
4684

L
Liu Jicong 已提交
4685
  while (1) {
H
Haojun Liao 已提交
4686
    STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4687 4688 4689
    if (pTupleHandle == NULL) {
      break;
    }
4690

4691 4692 4693
    appendOneRowToDataBlock(pDataBlock, pTupleHandle);
    if (pDataBlock->info.rows >= capacity) {
      return pDataBlock;
H
Haojun Liao 已提交
4694 4695
    }
  }
4696

L
Liu Jicong 已提交
4697
  return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
4698
}
4699

4700
SSDataBlock* loadNextDataBlock(void* param) {
L
Liu Jicong 已提交
4701 4702
  SOperatorInfo* pOperator = (SOperatorInfo*)param;
  bool           newgroup = false;
4703

H
Haojun Liao 已提交
4704
  return pOperator->getNextFn(pOperator, &newgroup);
4705 4706
}

L
Liu Jicong 已提交
4707
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
4708 4709 4710 4711
  size_t size = taosArrayGetSize(groupInfo);
  if (size == 0) {
    return true;
  }
4712

4713 4714
  for (int32_t i = 0; i < size; ++i) {
    int32_t* index = taosArrayGet(groupInfo, i);
4715

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

4719 4720 4721
    if ((isNull && buf[i] != NULL) || (!isNull && buf[i] == NULL)) {
      return false;
    }
4722

4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735
    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;
      }
4736 4737 4738
    }
  }

4739
  return 0;
4740 4741
}

L
Liu Jicong 已提交
4742 4743 4744
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
4745
    pCtx[j].startRow = rowIndex;
4746 4747
  }

4748 4749
  for (int32_t j = 0; j < numOfExpr; ++j) {
    int32_t functionId = pCtx[j].functionId;
L
Liu Jicong 已提交
4750 4751 4752 4753 4754 4755 4756 4757 4758
    //    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]);
    //    }
4759
  }
4760
}
4761

L
Liu Jicong 已提交
4762 4763
static void doFinalizeResultImpl(SqlFunctionCtx* pCtx, int32_t numOfExpr) {
  for (int32_t j = 0; j < numOfExpr; ++j) {
4764 4765 4766 4767
    int32_t functionId = pCtx[j].functionId;
    //    if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
    //      continue;
    //    }
4768

4769 4770 4771 4772
    //    if (functionId < 0) {
    //      SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
    //      doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
    //    } else {
H
Haojun Liao 已提交
4773
    pCtx[j].fpSet.finalize(&pCtx[j]);
4774 4775
  }
}
4776

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

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

4784 4785 4786
    char* data = colDataGetData(pColInfo, rowIndex);
    memcpy(rowColData[i], data, colDataGetLength(pColInfo, rowIndex));
  }
4787

4788 4789
  return true;
}
4790

4791 4792
static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
4793

4794
  SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
L
Liu Jicong 已提交
4795
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
4796 4797
    pCtx[i].size = 1;
  }
4798

L
Liu Jicong 已提交
4799
  for (int32_t i = 0; i < pBlock->info.rows; ++i) {
4800 4801 4802 4803 4804 4805 4806 4807 4808
    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 已提交
4809
        int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4810
        //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4811

4812
        // TODO check for available buffer;
H
Haojun Liao 已提交
4813

4814 4815 4816 4817 4818
        // next group info data
        pInfo->binfo.pRes->info.rows += numOfRows;
        for (int32_t j = 0; j < numOfExpr; ++j) {
          if (pCtx[j].functionId < 0) {
            continue;
4819
          }
4820

H
Haojun Liao 已提交
4821
          pCtx[j].fpSet.process(&pCtx[j]);
4822
        }
4823 4824 4825

        doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
        pInfo->hasGroupVal = saveCurrentTuple(pInfo->groupVal, pInfo->groupInfo, pBlock, i);
H
Haojun Liao 已提交
4826
      }
4827 4828 4829 4830
    }
  }
}

4831 4832
static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
4833
  SSortHandle*              pHandle = pInfo->pSortHandle;
4834

4835 4836 4837
  SSDataBlock* pDataBlock = createOneDataBlock(pInfo->binfo.pRes);
  blockDataEnsureCapacity(pDataBlock, pInfo->binfo.capacity);

L
Liu Jicong 已提交
4838
  while (1) {
4839
    blockDataCleanup(pDataBlock);
4840
    while (1) {
H
Haojun Liao 已提交
4841
      STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4842 4843
      if (pTupleHandle == NULL) {
        break;
4844
      }
4845

4846 4847 4848 4849 4850
      // build datablock for merge for one group
      appendOneRowToDataBlock(pDataBlock, pTupleHandle);
      if (pDataBlock->info.rows >= pInfo->binfo.capacity) {
        break;
      }
4851
    }
4852

4853 4854 4855
    if (pDataBlock->info.rows == 0) {
      break;
    }
4856

4857
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC);
L
Liu Jicong 已提交
4858 4859
    //  updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
    //  pOperator->pRuntimeEnv, true);
4860 4861 4862
    doMergeImpl(pOperator, pOperator->numOfOutput, pDataBlock);
    // flush to tuple store, and after all data have been handled, return to upstream node or sink node
  }
4863

4864
  doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
4865
  int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
4866
  //        setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
4867

4868
  // TODO check for available buffer;
4869

4870 4871
  // next group info data
  pInfo->binfo.pRes->info.rows += numOfRows;
L
Liu Jicong 已提交
4872
  return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
4873
}
4874

L
Liu Jicong 已提交
4875
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator, bool* newgroup) {
4876 4877
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
4878 4879
  }

L
Liu Jicong 已提交
4880
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
4881
  SSortedMergeOperatorInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
4882
  if (pOperator->status == OP_RES_TO_RETURN) {
4883
    return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pInfo->hasVarCol, pInfo->binfo.capacity);
4884 4885
  }

4886
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
L
Liu Jicong 已提交
4887 4888
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage,
                                             pInfo->binfo.pRes, "GET_TASKID(pTaskInfo)");
H
Haojun Liao 已提交
4889

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

L
Liu Jicong 已提交
4892
  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
wafwerar's avatar
wafwerar 已提交
4893
    SGenericSource* ps = taosMemoryCalloc(1, sizeof(SGenericSource));
H
Haojun Liao 已提交
4894
    ps->param = pOperator->pDownstream[i];
H
Haojun Liao 已提交
4895
    tsortAddSource(pInfo->pSortHandle, ps);
4896 4897
  }

H
Haojun Liao 已提交
4898
  int32_t code = tsortOpen(pInfo->pSortHandle);
4899
  if (code != TSDB_CODE_SUCCESS) {
4900
    longjmp(pTaskInfo->env, terrno);
4901 4902
  }

H
Haojun Liao 已提交
4903
  pOperator->status = OP_RES_TO_RETURN;
4904
  return doMerge(pOperator);
4905
}
4906

L
Liu Jicong 已提交
4907 4908
static int32_t initGroupCol(SExprInfo* pExprInfo, int32_t numOfCols, SArray* pGroupInfo,
                            SSortedMergeOperatorInfo* pInfo) {
4909 4910
  if (pGroupInfo == NULL || taosArrayGetSize(pGroupInfo) == 0) {
    return 0;
H
Haojun Liao 已提交
4911 4912
  }

4913 4914 4915 4916 4917 4918 4919 4920
  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 已提交
4921 4922
  size_t numOfGroupCol = taosArrayGetSize(pInfo->groupInfo);
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4923
    SColumn* pCol = taosArrayGet(pGroupInfo, i);
L
Liu Jicong 已提交
4924
    for (int32_t j = 0; j < numOfCols; ++j) {
H
Haojun Liao 已提交
4925
      SExprInfo* pe = &pExprInfo[j];
H
Haojun Liao 已提交
4926
      if (pe->base.resSchema.colId == pCol->colId) {
4927 4928
        taosArrayPush(plist, pCol);
        taosArrayPush(pInfo->groupInfo, &j);
H
Haojun Liao 已提交
4929
        len += pCol->bytes;
4930 4931
        break;
      }
H
Haojun Liao 已提交
4932 4933 4934
    }
  }

4935
  ASSERT(taosArrayGetSize(pGroupInfo) == taosArrayGetSize(plist));
H
Haojun Liao 已提交
4936

wafwerar's avatar
wafwerar 已提交
4937
  pInfo->groupVal = taosMemoryCalloc(1, (POINTER_BYTES * numOfGroupCol + len));
4938 4939 4940 4941
  if (pInfo->groupVal == NULL) {
    taosArrayDestroy(plist);
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
4942

4943
  int32_t offset = 0;
L
Liu Jicong 已提交
4944 4945
  char*   start = (char*)(pInfo->groupVal + (POINTER_BYTES * numOfGroupCol));
  for (int32_t i = 0; i < numOfGroupCol; ++i) {
4946 4947
    pInfo->groupVal[i] = start + offset;
    SColumn* pCol = taosArrayGet(plist, i);
H
Haojun Liao 已提交
4948
    offset += pCol->bytes;
4949
  }
H
Haojun Liao 已提交
4950

4951
  taosArrayDestroy(plist);
H
Haojun Liao 已提交
4952

4953 4954
  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
4955

L
Liu Jicong 已提交
4956 4957 4958
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo,
                                             int32_t num, SArray* pSortInfo, SArray* pGroupInfo,
                                             SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
4959
  SSortedMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortedMergeOperatorInfo));
L
Liu Jicong 已提交
4960
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
4961
  if (pInfo == NULL || pOperator == NULL) {
4962
    goto _error;
4963
  }
H
Haojun Liao 已提交
4964

L
Liu Jicong 已提交
4965
  pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExprInfo, num, &pInfo->binfo.rowCellInfoOffset);
4966
  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
H
Haojun Liao 已提交
4967

4968 4969 4970
  if (pInfo->binfo.pCtx == NULL || pInfo->binfo.pRes == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
4971

H
Haojun Liao 已提交
4972
  int32_t code = doInitAggInfoSup(&pInfo->aggSup, pInfo->binfo.pCtx, num, pTaskInfo->id.str);
4973 4974 4975
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4976

H
Haojun Liao 已提交
4977
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
H
Haojun Liao 已提交
4978
  code = initGroupCol(pExprInfo, num, pGroupInfo, pInfo);
4979 4980 4981
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
4982

L
Liu Jicong 已提交
4983 4984 4985 4986 4987
  //  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 已提交
4988

4989
  pInfo->binfo.capacity = blockDataGetCapacityInRow(pInfo->binfo.pRes, pInfo->bufPageSize);
H
Haojun Liao 已提交
4990

L
Liu Jicong 已提交
4991
  pOperator->name = "SortedMerge";
X
Xiaoyu Wang 已提交
4992
  // pOperator->operatorType = OP_SortedMerge;
4993
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
4994 4995 4996 4997
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->numOfOutput = num;
  pOperator->pExpr = pExprInfo;
H
Haojun Liao 已提交
4998

L
Liu Jicong 已提交
4999 5000 5001
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->getNextFn = doSortedMerge;
  pOperator->closeFn = destroySortedMergeOperatorInfo;
H
Haojun Liao 已提交
5002

5003 5004 5005
  code = appendDownstream(pOperator, downstream, numOfDownstream);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
5006
  }
H
Haojun Liao 已提交
5007

5008
  return pOperator;
H
Haojun Liao 已提交
5009

L
Liu Jicong 已提交
5010
_error:
5011
  if (pInfo != NULL) {
H
Haojun Liao 已提交
5012
    destroySortedMergeOperatorInfo(pInfo, num);
H
Haojun Liao 已提交
5013 5014
  }

wafwerar's avatar
wafwerar 已提交
5015 5016
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
5017 5018
  terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
  return NULL;
H
Haojun Liao 已提交
5019 5020
}

L
Liu Jicong 已提交
5021
static SSDataBlock* doSort(SOperatorInfo* pOperator, bool* newgroup) {
5022 5023 5024 5025
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

L
Liu Jicong 已提交
5026
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
5027
  SSortOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5028
  bool               hasVarCol = pInfo->pDataBlock->info.hasVarCol;
H
Haojun Liao 已提交
5029

H
Haojun Liao 已提交
5030
  if (pOperator->status == OP_RES_TO_RETURN) {
H
Haojun Liao 已提交
5031
    return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, hasVarCol, pInfo->numOfRowsInRes);
H
Haojun Liao 已提交
5032 5033
  }

5034
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
L
Liu Jicong 已提交
5035 5036
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_SINGLESOURCE_SORT, pInfo->bufPageSize, numOfBufPage,
                                             pInfo->pDataBlock, "GET_TASKID(pTaskInfo)");
5037

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

wafwerar's avatar
wafwerar 已提交
5040
  SGenericSource* ps = taosMemoryCalloc(1, sizeof(SGenericSource));
H
Haojun Liao 已提交
5041
  ps->param = pOperator->pDownstream[0];
H
Haojun Liao 已提交
5042
  tsortAddSource(pInfo->pSortHandle, ps);
5043

H
Haojun Liao 已提交
5044
  int32_t code = tsortOpen(pInfo->pSortHandle);
5045
  if (code != TSDB_CODE_SUCCESS) {
5046
    longjmp(pTaskInfo->env, terrno);
5047
  }
5048

H
Haojun Liao 已提交
5049
  pOperator->status = OP_RES_TO_RETURN;
H
Haojun Liao 已提交
5050
  return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, hasVarCol, pInfo->numOfRowsInRes);
5051 5052
}

L
Liu Jicong 已提交
5053 5054
SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo,
                                      SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
5055
  SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo));
L
Liu Jicong 已提交
5056
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
5057
  if (pInfo == NULL || pOperator == NULL) {
wafwerar's avatar
wafwerar 已提交
5058 5059
    taosMemoryFreeClear(pInfo);
    taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
5060 5061 5062
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
  }
5063

L
Liu Jicong 已提交
5064 5065 5066 5067 5068
  pInfo->sortBufSize = 1024 * 16;  // 1MB, TODO dynamic set the available sort buffer
  pInfo->bufPageSize = 1024;
  pInfo->numOfRowsInRes = 1024;
  pInfo->pDataBlock = pResBlock;
  pInfo->pSortInfo = pSortInfo;
H
Haojun Liao 已提交
5069

L
Liu Jicong 已提交
5070 5071 5072 5073 5074
  pOperator->name = "Sort";
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
  pOperator->blockingOptr = true;
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
5075

L
Liu Jicong 已提交
5076 5077 5078
  pOperator->pTaskInfo = pTaskInfo;
  pOperator->getNextFn = doSort;
  pOperator->closeFn = destroyOrderOperatorInfo;
5079

5080
  int32_t code = appendDownstream(pOperator, &downstream, 1);
5081 5082 5083
  return pOperator;
}

L
Liu Jicong 已提交
5084
static int32_t getTableScanOrder(STableScanInfo* pTableScanInfo) { return pTableScanInfo->order; }
5085 5086

// this is a blocking operator
L
Liu Jicong 已提交
5087
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
5088 5089
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
5090 5091 5092
  }

  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
5093
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;
5094

H
Haojun Liao 已提交
5095
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
5096
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5097

H
Haojun Liao 已提交
5098 5099
  bool newgroup = true;
  while (1) {
H
Haojun Liao 已提交
5100
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5101
    SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
5102
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5103 5104 5105 5106

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
5107 5108 5109
    //    if (pAggInfo->current != NULL) {
    //      setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5110 5111 5112

    // the pDataBlock are always the same one, no need to call this again
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order);
H
Haojun Liao 已提交
5113
    doAggregateImpl(pOperator, 0, pInfo->pCtx);
5114 5115
  }

5116
  finalizeQueryResult(pInfo->pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
5117 5118 5119 5120 5121

  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
5122 5123
static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup) {
  SAggOperatorInfo* pAggInfo = pOperator->info;
H
Haojun Liao 已提交
5124 5125 5126 5127 5128 5129
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;

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

L
Liu Jicong 已提交
5130
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
H
Haojun Liao 已提交
5131 5132 5133 5134 5135
  pTaskInfo->code = pOperator->_openFn(pOperator);
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
    return NULL;
  }

H
Haojun Liao 已提交
5136
  getNumOfResult(pInfo->pCtx, pOperator->numOfOutput, pInfo->pRes);
H
Haojun Liao 已提交
5137
  doSetOperatorCompleted(pOperator);
5138

L
Liu Jicong 已提交
5139
  return (blockDataGetNumOfRows(pInfo->pRes) != 0) ? pInfo->pRes : NULL;
5140 5141
}

L
Liu Jicong 已提交
5142 5143 5144
static void aggEncodeResultRow(SOperatorInfo* pOperator, char** result, int32_t* length) {
  SAggOperatorInfo* pAggInfo = pOperator->info;
  SAggSupporter*    pSup = &pAggInfo->aggSup;
wmmhello's avatar
wmmhello 已提交
5145 5146

  int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
L
Liu Jicong 已提交
5147
  size_t  keyLen = POINTER_BYTES;  // estimate the key length
wmmhello's avatar
wmmhello 已提交
5148
  int32_t totalSize = sizeof(int32_t) + size * (sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize);
wafwerar's avatar
wafwerar 已提交
5149
  *result = taosMemoryCalloc(1, totalSize);
L
Liu Jicong 已提交
5150
  if (*result == NULL) {
wmmhello's avatar
wmmhello 已提交
5151 5152 5153 5154 5155
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return;
  }
  *(int32_t*)(*result) = size;
  int32_t offset = sizeof(int32_t);
L
Liu Jicong 已提交
5156
  void*   pIter = taosHashIterate(pSup->pResultRowHashTable, NULL);
wmmhello's avatar
wmmhello 已提交
5157
  while (pIter) {
L
Liu Jicong 已提交
5158 5159
    void*        key = taosHashGetKey(pIter, &keyLen);
    SResultRow** p1 = (SResultRow**)pIter;
wmmhello's avatar
wmmhello 已提交
5160 5161 5162

    // recalculate the result size
    int32_t realTotalSize = offset + sizeof(int32_t) + keyLen + sizeof(int32_t) + pSup->resultRowSize;
L
Liu Jicong 已提交
5163 5164 5165
    if (realTotalSize > totalSize) {
      char* tmp = taosMemoryRealloc(*result, realTotalSize);
      if (tmp == NULL) {
wmmhello's avatar
wmmhello 已提交
5166
        terrno = TSDB_CODE_OUT_OF_MEMORY;
wafwerar's avatar
wafwerar 已提交
5167
        taosMemoryFree(*result);
wmmhello's avatar
wmmhello 已提交
5168 5169
        *result = NULL;
        return;
L
Liu Jicong 已提交
5170
      } else {
wmmhello's avatar
wmmhello 已提交
5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188
        *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);
    memcpy(*result + offset, *p1, pSup->resultRowSize);
    offset += pSup->resultRowSize;

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

L
Liu Jicong 已提交
5189
  if (length) {
wmmhello's avatar
wmmhello 已提交
5190 5191 5192 5193 5194
    *length = offset;
  }
  return;
}

L
Liu Jicong 已提交
5195 5196
static bool aggDecodeResultRow(SOperatorInfo* pOperator, char* result, int32_t length) {
  if (!result || length <= 0) {
wmmhello's avatar
wmmhello 已提交
5197 5198 5199
    return false;
  }

L
Liu Jicong 已提交
5200 5201 5202
  SAggOperatorInfo* pAggInfo = pOperator->info;
  SAggSupporter*    pSup = &pAggInfo->aggSup;
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;
wmmhello's avatar
wmmhello 已提交
5203 5204 5205 5206 5207

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

  int32_t offset = sizeof(int32_t);
L
Liu Jicong 已提交
5208
  while (count-- > 0 && length > offset) {
wmmhello's avatar
wmmhello 已提交
5209 5210 5211
    int32_t keyLen = *(int32_t*)(result + offset);
    offset += sizeof(int32_t);

L
Liu Jicong 已提交
5212 5213 5214
    uint64_t    tableGroupId = *(uint64_t*)(result + offset);
    SResultRow* resultRow = getNewResultRow_rv(pSup->pResultBuf, tableGroupId, pSup->resultRowSize);
    if (!resultRow) {
wmmhello's avatar
wmmhello 已提交
5215 5216 5217 5218 5219 5220 5221 5222
      terrno = TSDB_CODE_TSC_INVALID_INPUT;
      return false;
    }
    // add a new result set for a new group
    taosHashPut(pSup->pResultRowHashTable, result + offset, keyLen, &resultRow, POINTER_BYTES);

    offset += keyLen;
    int32_t valueLen = *(int32_t*)(result + offset);
L
Liu Jicong 已提交
5223
    if (valueLen != pSup->resultRowSize) {
wmmhello's avatar
wmmhello 已提交
5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235
      terrno = TSDB_CODE_TSC_INVALID_INPUT;
      return false;
    }
    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);
L
Liu Jicong 已提交
5236 5237
    pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
        (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
wmmhello's avatar
wmmhello 已提交
5238 5239
  }

L
Liu Jicong 已提交
5240
  if (offset != length) {
wmmhello's avatar
wmmhello 已提交
5241 5242 5243 5244 5245 5246
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
    return false;
  }
  return true;
}

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

  SAggOperatorInfo* pAggInfo = pOperator->info;
L
Liu Jicong 已提交
5253 5254
  SOptrBasicInfo*   pInfo = &pAggInfo->binfo;
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
5255 5256

  if (pOperator->status == OP_RES_TO_RETURN) {
L
Liu Jicong 已提交
5257 5258
    toSDatablock(&pAggInfo->groupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity,
                 pAggInfo->binfo.rowCellInfoOffset);
5259

H
Haojun Liao 已提交
5260
    if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
5261 5262 5263 5264 5265 5266
      pOperator->status = OP_EXEC_DONE;
    }

    return pInfo->pRes;
  }

5267
  // table scan order
L
Liu Jicong 已提交
5268
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
5269
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5270

L
Liu Jicong 已提交
5271
  while (1) {
H
Haojun Liao 已提交
5272
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5273
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5274
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5275 5276 5277 5278 5279

    if (pBlock == NULL) {
      break;
    }

L
Liu Jicong 已提交
5280 5281 5282 5283 5284
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    if (downstream->operatorType == OP_TableScan) {
    //      STableScanInfo* pScanInfo = downstream->info;
    //      order = getTableScanOrder(pScanInfo);
    //    }
5285 5286 5287 5288 5289

    // the pDataBlock are always the same one, no need to call this again
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order);

    TSKEY key = 0;
5290
    if (order == TSDB_ORDER_ASC) {
5291 5292 5293 5294 5295 5296
      key = pBlock->info.window.ekey;
      TSKEY_MAX_ADD(key, 1);
    } else {
      key = pBlock->info.window.skey;
      TSKEY_MIN_SUB(key, -1);
    }
L
Liu Jicong 已提交
5297 5298 5299

    setExecutionContext(pOperator->numOfOutput, pAggInfo->current->groupIndex, key, pTaskInfo, pAggInfo->current,
                        pAggInfo);
H
Haojun Liao 已提交
5300
    doAggregateImpl(pOperator, 0, pInfo->pCtx);
5301 5302 5303 5304
  }

  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pInfo->resultRowInfo);
5305
  updateNumOfRowsInResultRows(pInfo->pCtx, pOperator->numOfOutput, &pInfo->resultRowInfo, pInfo->rowCellInfoOffset);
5306

H
Haojun Liao 已提交
5307
  initGroupResInfo(&pAggInfo->groupResInfo, &pInfo->resultRowInfo);
L
Liu Jicong 已提交
5308 5309
  toSDatablock(&pAggInfo->groupResInfo, pAggInfo->pResultBuf, pInfo->pRes, pAggInfo->binfo.capacity,
               pAggInfo->binfo.rowCellInfoOffset);
5310

H
Haojun Liao 已提交
5311
  if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
5312 5313 5314 5315 5316 5317
    doSetOperatorCompleted(pOperator);
  }

  return pInfo->pRes;
}

L
Liu Jicong 已提交
5318
static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup) {
5319
  SProjectOperatorInfo* pProjectInfo = pOperator->info;
L
Liu Jicong 已提交
5320
  SOptrBasicInfo*       pInfo = &pProjectInfo->binfo;
5321 5322

  SSDataBlock* pRes = pInfo->pRes;
5323
  blockDataCleanup(pRes);
H
Haojun Liao 已提交
5324
#if 0
5325 5326 5327 5328 5329 5330
  if (pProjectInfo->existDataBlock) {  // TODO refactor
    SSDataBlock* pBlock = pProjectInfo->existDataBlock;
    pProjectInfo->existDataBlock = NULL;
    *newgroup = true;

    // todo dynamic set tags
L
Liu Jicong 已提交
5331 5332 5333
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5334 5335

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

H
Haojun Liao 已提交
5338
    blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
5339
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
L
Liu Jicong 已提交
5340
    if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
5341 5342 5343 5344 5345
      copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
      resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
      return pRes;
    }
  }
H
Haojun Liao 已提交
5346
#endif
5347

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

L
Liu Jicong 已提交
5350
  while (1) {
5351 5352
    bool prevVal = *newgroup;

H
Haojun Liao 已提交
5353
    // The downstream exec may change the value of the newgroup, so use a local variable instead.
H
Haojun Liao 已提交
5354 5355 5356
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5357 5358 5359 5360

    if (pBlock == NULL) {
      assert(*newgroup == false);
      *newgroup = prevVal;
5361
      setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5362 5363 5364 5365 5366 5367 5368 5369
      break;
    }

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

    // todo dynamic set tags
H
Haojun Liao 已提交
5376 5377 5378 5379
    //    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
    //    if (pTableQueryInfo != NULL) {
    //      setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
    //    }
5380 5381

    // the pDataBlock are always the same one, no need to call this again
H
Haojun Liao 已提交
5382
    setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC);
5383 5384
    blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);

5385
    projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396

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

5397
    if (pRes->info.rows >= pOperator->resultInfo.threshold) {
5398 5399 5400
      break;
    }
  }
H
Haojun Liao 已提交
5401
  
H
Haojun Liao 已提交
5402
  if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pInfo->pRes->info.rows >= pProjectInfo->limit.limit) {
H
Haojun Liao 已提交
5403 5404 5405 5406
    pInfo->pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput);
  }

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

L
Liu Jicong 已提交
5408 5409
  //  copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
  return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
5410 5411
}

L
Liu Jicong 已提交
5412
static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
5413 5414
  if (OPTR_IS_OPENED(pOperator)) {
    return TSDB_CODE_SUCCESS;
5415 5416
  }

H
Haojun Liao 已提交
5417
  STableIntervalOperatorInfo* pInfo = pOperator->info;
5418

5419
  int32_t order = TSDB_ORDER_ASC;
5420 5421
  //  STimeWindow win = {0};
  bool newgroup = false;
H
Haojun Liao 已提交
5422
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5423

5424
  while (1) {
H
Haojun Liao 已提交
5425
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5426
    SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup);
H
Haojun Liao 已提交
5427
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5428 5429 5430 5431 5432

    if (pBlock == NULL) {
      break;
    }

5433
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
5434
    // the pDataBlock are always the same one, no need to call this again
5435
    setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order);
H
Haojun Liao 已提交
5436
    hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0);
5437 5438
  }

H
Haojun Liao 已提交
5439
  closeAllResultRows(&pInfo->binfo.resultRowInfo);
L
Liu Jicong 已提交
5440 5441
  finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
                                &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
5442

H
Haojun Liao 已提交
5443
  initGroupResInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
5444 5445 5446 5447
  OPTR_SET_OPENED(pOperator);
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
5448
static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator, bool* newgroup) {
5449
  STableIntervalOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5450
  SExecTaskInfo*              pTaskInfo = pOperator->pTaskInfo;
5451 5452 5453 5454 5455

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

5456 5457 5458 5459
  if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
    return pOperator->getStreamResFn(pOperator, newgroup);
  }

5460 5461 5462 5463 5464 5465
  pTaskInfo->code = pOperator->_openFn(pOperator);
  if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
    return NULL;
  }

  blockDataEnsureCapacity(pInfo->binfo.pRes, pInfo->binfo.capacity);
L
Liu Jicong 已提交
5466 5467
  toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pInfo->binfo.pRes, pInfo->binfo.capacity,
               pInfo->binfo.rowCellInfoOffset);
5468

H
Haojun Liao 已提交
5469
  if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
5470 5471 5472
    doSetOperatorCompleted(pOperator);
  }

L
Liu Jicong 已提交
5473
  return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5474 5475
}

5476
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo *pOperator, bool* newgroup) {
5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489
  STableIntervalOperatorInfo* pInfo = pOperator->info;
  int32_t order = TSDB_ORDER_ASC;

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

  if (pOperator->status == OP_RES_TO_RETURN) {
    toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pInfo->binfo.pRes, pInfo->binfo.capacity,
                 pInfo->binfo.rowCellInfoOffset);
    if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      pOperator->status = OP_EXEC_DONE;
    }
5490
    return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes;
5491 5492 5493
  }

  //  STimeWindow win = {0};
5494
  *newgroup = false;
5495 5496 5497 5498 5499 5500
  SOperatorInfo* downstream = pOperator->pDownstream[0];

  SArray* pUpdated = NULL;

  while (1) {
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
5501
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);

    if (pBlock == NULL) {
      break;
    }

    // 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.

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

  finalizeUpdatedResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, pUpdated, pInfo->binfo.rowCellInfoOffset);

H
Haojun Liao 已提交
5519
  initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530
  blockDataEnsureCapacity(pInfo->binfo.pRes, pInfo->binfo.capacity);
  toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pInfo->binfo.pRes, pInfo->binfo.capacity,
               pInfo->binfo.rowCellInfoOffset);

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

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

static SSDataBlock* doAllIntervalAgg(SOperatorInfo *pOperator, bool* newgroup) {
5531 5532 5533 5534 5535 5536
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  STableIntervalOperatorInfo* pIntervalInfo = pOperator->info;

H
Haojun Liao 已提交
5537
  STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
5538
  if (pOperator->status == OP_RES_TO_RETURN) {
L
Liu Jicong 已提交
5539
    //    toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
5540

H
Haojun Liao 已提交
5541
    if (pIntervalInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
5542 5543 5544
      doSetOperatorCompleted(pOperator);
    }

H
Haojun Liao 已提交
5545
    return pIntervalInfo->binfo.pRes;
5546 5547
  }

L
Liu Jicong 已提交
5548 5549
  STaskAttr*  pQueryAttr = pRuntimeEnv->pQueryAttr;
  int32_t     order = pQueryAttr->order.order;
5550 5551
  STimeWindow win = pQueryAttr->window;

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

L
Liu Jicong 已提交
5554
  while (1) {
H
Haojun Liao 已提交
5555
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5556
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5557
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5558 5559 5560 5561 5562

    if (pBlock == NULL) {
      break;
    }

L
Liu Jicong 已提交
5563
    //    setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
5564 5565

    // the pDataBlock are always the same one, no need to call this again
H
Haojun Liao 已提交
5566 5567
    setInputDataBlock(pOperator, pIntervalInfo->binfo.pCtx, pBlock, pQueryAttr->order.order);
    hashAllIntervalAgg(pOperator, &pIntervalInfo->binfo.resultRowInfo, pBlock, 0);
5568 5569 5570 5571 5572 5573 5574
  }

  // restore the value
  pQueryAttr->order.order = order;
  pQueryAttr->window = win;

  pOperator->status = OP_RES_TO_RETURN;
H
Haojun Liao 已提交
5575
  closeAllResultRows(&pIntervalInfo->binfo.resultRowInfo);
5576
  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5577
  finalizeQueryResult(pIntervalInfo->binfo.pCtx, pOperator->numOfOutput);
5578

H
Haojun Liao 已提交
5579
  initGroupResInfo(&pRuntimeEnv->groupResInfo, &pIntervalInfo->binfo.resultRowInfo);
L
Liu Jicong 已提交
5580
  //  toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
5581

H
Haojun Liao 已提交
5582
  if (pIntervalInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
5583 5584 5585
    pOperator->status = OP_EXEC_DONE;
  }

L
Liu Jicong 已提交
5586
  return pIntervalInfo->binfo.pRes->info.rows == 0 ? NULL : pIntervalInfo->binfo.pRes;
5587 5588
}

L
Liu Jicong 已提交
5589
static SSDataBlock* doSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5590 5591 5592 5593 5594
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  STableIntervalOperatorInfo* pIntervalInfo = pOperator->info;
L
Liu Jicong 已提交
5595
  STaskRuntimeEnv*            pRuntimeEnv = pOperator->pRuntimeEnv;
5596 5597 5598 5599

  if (pOperator->status == OP_RES_TO_RETURN) {
    int64_t st = taosGetTimestampUs();

L
Liu Jicong 已提交
5600
    //    copyToSDataBlock(NULL, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5601
    if (pIntervalInfo->binfo.pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) {
5602 5603
      doSetOperatorCompleted(pOperator);
    }
H
Haojun Liao 已提交
5604
    return pIntervalInfo->binfo.pRes;
5605 5606
  }

H
Haojun Liao 已提交
5607
  STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
L
Liu Jicong 已提交
5608
  int32_t    order = pQueryAttr->order.order;
5609

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

L
Liu Jicong 已提交
5612
  while (1) {
H
Haojun Liao 已提交
5613
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5614
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5615
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5616 5617 5618 5619 5620 5621 5622 5623

    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;

L
Liu Jicong 已提交
5624
    //    setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
5625
    setInputDataBlock(pOperator, pIntervalInfo->binfo.pCtx, pBlock, pQueryAttr->order.order);
5626 5627 5628 5629 5630 5631
    setIntervalQueryRange(pRuntimeEnv, pBlock->info.window.skey);

    hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pTableQueryInfo->groupIndex);
  }

  pOperator->status = OP_RES_TO_RETURN;
L
Liu Jicong 已提交
5632
  pQueryAttr->order.order = order;  // TODO : restore the order
5633
  doCloseAllTimeWindow(pRuntimeEnv);
5634
  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5635

L
Liu Jicong 已提交
5636
  //  copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5637
  if (pIntervalInfo->binfo.pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) {
5638 5639 5640
    pOperator->status = OP_EXEC_DONE;
  }

H
Haojun Liao 已提交
5641
  return pIntervalInfo->binfo.pRes;
5642 5643
}

L
Liu Jicong 已提交
5644
static SSDataBlock* doAllSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
5645 5646 5647 5648 5649
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  STableIntervalOperatorInfo* pIntervalInfo = pOperator->info;
L
Liu Jicong 已提交
5650
  STaskRuntimeEnv*            pRuntimeEnv = pOperator->pRuntimeEnv;
5651 5652

  if (pOperator->status == OP_RES_TO_RETURN) {
L
Liu Jicong 已提交
5653
    //    copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5654
    if (pIntervalInfo->binfo.pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) {
5655 5656 5657
      pOperator->status = OP_EXEC_DONE;
    }

H
Haojun Liao 已提交
5658
    return pIntervalInfo->binfo.pRes;
5659 5660
  }

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

L
Liu Jicong 已提交
5663
  while (1) {
H
Haojun Liao 已提交
5664
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5665
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5666
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5667 5668 5669 5670 5671 5672 5673 5674

    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
    STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;

L
Liu Jicong 已提交
5675
    //    setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
H
Haojun Liao 已提交
5676
//    setInputDataBlock(pOperator, pIntervalInfo->binfo.pCtx, pBlock, pQueryAttr->order.order);
5677 5678 5679 5680 5681 5682
    setIntervalQueryRange(pRuntimeEnv, pBlock->info.window.skey);

    hashAllIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pTableQueryInfo->groupIndex);
  }

  pOperator->status = OP_RES_TO_RETURN;
H
Haojun Liao 已提交
5683
//  pQueryAttr->order.order = order;  // TODO : restore the order
5684
  doCloseAllTimeWindow(pRuntimeEnv);
5685
  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5686 5687

  int64_t st = taosGetTimestampUs();
L
Liu Jicong 已提交
5688
  //  copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset);
H
Haojun Liao 已提交
5689
  if (pIntervalInfo->binfo.pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) {
5690 5691 5692
    pOperator->status = OP_EXEC_DONE;
  }

L
Liu Jicong 已提交
5693 5694
  //  SQInfo* pQInfo = pRuntimeEnv->qinfo;
  //  pQInfo->summary.firstStageMergeTime += (taosGetTimestampUs() - st);
5695

H
Haojun Liao 已提交
5696
  return pIntervalInfo->binfo.pRes;
5697 5698
}

L
Liu Jicong 已提交
5699
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pSDataBlock) {
H
Haojun Liao 已提交
5700
  STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
L
Liu Jicong 已提交
5701
  STableQueryInfo* item = pRuntimeEnv->current;
5702 5703 5704 5705
  SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex);

  SOptrBasicInfo* pBInfo = &pInfo->binfo;

H
Haojun Liao 已提交
5706
  bool    masterScan = IS_MAIN_SCAN(pRuntimeEnv);
L
Liu Jicong 已提交
5707 5708
  int16_t bytes = pColInfoData->info.bytes;
  int16_t type = pColInfoData->info.type;
5709 5710

  SColumnInfoData* pTsColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0);
L
Liu Jicong 已提交
5711
  TSKEY*           tsList = (TSKEY*)pTsColInfoData->pData;
5712 5713
  if (IS_REPEAT_SCAN(pRuntimeEnv) && !pInfo->reptScan) {
    pInfo->reptScan = true;
wafwerar's avatar
wafwerar 已提交
5714
    taosMemoryFreeClear(pInfo->prevData);
5715 5716 5717 5718 5719 5720 5721 5722 5723
  }

  pInfo->numOfRows = 0;
  for (int32_t j = 0; j < pSDataBlock->info.rows; ++j) {
    char* val = ((char*)pColInfoData->pData) + bytes * j;
    if (isNull(val, type)) {
      continue;
    }
    if (pInfo->prevData == NULL) {
wafwerar's avatar
wafwerar 已提交
5724
      pInfo->prevData = taosMemoryMalloc(bytes);
5725 5726 5727 5728 5729 5730 5731 5732 5733
      memcpy(pInfo->prevData, val, bytes);
      pInfo->numOfRows = 1;
      pInfo->curWindow.skey = tsList[j];
      pInfo->curWindow.ekey = tsList[j];
      pInfo->start = j;

    } else if (memcmp(pInfo->prevData, val, bytes) == 0) {
      pInfo->curWindow.ekey = tsList[j];
      pInfo->numOfRows += 1;
L
Liu Jicong 已提交
5734
      // pInfo->start = j;
5735 5736 5737 5738 5739 5740 5741
      if (j == 0 && pInfo->start != 0) {
        pInfo->numOfRows = 1;
        pInfo->start = 0;
      }
    } else {
      SResultRow* pResult = NULL;
      pInfo->curWindow.ekey = pInfo->curWindow.skey;
L
Liu Jicong 已提交
5742 5743 5744
      int32_t ret = setResultOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, pSDataBlock->info.uid,
                                            &pInfo->curWindow, masterScan, &pResult, item->groupIndex, pBInfo->pCtx,
                                            pOperator->numOfOutput, pBInfo->rowCellInfoOffset);
5745 5746 5747
      if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
        longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
      }
L
Liu Jicong 已提交
5748 5749
      //      doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList,
      //                       pSDataBlock->info.rows, pOperator->numOfOutput);
5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761

      pInfo->curWindow.skey = tsList[j];
      pInfo->curWindow.ekey = tsList[j];
      memcpy(pInfo->prevData, val, bytes);
      pInfo->numOfRows = 1;
      pInfo->start = j;
    }
  }

  SResultRow* pResult = NULL;

  pInfo->curWindow.ekey = pInfo->curWindow.skey;
L
Liu Jicong 已提交
5762 5763
  int32_t ret = setResultOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, pSDataBlock->info.uid, &pInfo->curWindow,
                                        masterScan, &pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
5764 5765 5766 5767 5768
                                        pBInfo->rowCellInfoOffset);
  if (ret != TSDB_CODE_SUCCESS) {  // null data, too many state code
    longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
  }

L
Liu Jicong 已提交
5769 5770
  //  doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList,
  //                   pSDataBlock->info.rows, pOperator->numOfOutput);
5771 5772
}

L
Liu Jicong 已提交
5773
static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5774 5775 5776 5777 5778
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  SStateWindowOperatorInfo* pWindowInfo = pOperator->info;
H
Haojun Liao 已提交
5779 5780
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
  SOptrBasicInfo* pBInfo    = &pWindowInfo->binfo;
5781 5782

  if (pOperator->status == OP_RES_TO_RETURN) {
L
Liu Jicong 已提交
5783
    //    toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes);
5784

H
Haojun Liao 已提交
5785 5786 5787
//    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
//      pOperator->status = OP_EXEC_DONE;
//    }
5788 5789 5790 5791

    return pBInfo->pRes;
  }

H
Haojun Liao 已提交
5792 5793 5794
  int32_t        order = TSDB_ORDER_ASC;
  STimeWindow    win = pTaskInfo->window;

H
Haojun Liao 已提交
5795
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5796
  while (1) {
H
Haojun Liao 已提交
5797
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5798
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5799
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5800 5801 5802 5803

    if (pBlock == NULL) {
      break;
    }
H
Haojun Liao 已提交
5804 5805 5806 5807 5808

//    setInputDataBlock(pOperator, pBInfo->pCtx, pDataBlock, TSDB_ORDER_ASC);
//    if (pWindowInfo->colIndex == -1) {
//      pWindowInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQueryAttr->pGroupbyExpr, pBlock);
//    }
L
Liu Jicong 已提交
5809
    doStateWindowAggImpl(pOperator, pWindowInfo, pBlock);
5810 5811 5812
  }

  // restore the value
H
Haojun Liao 已提交
5813 5814
//  pQueryAttr->order.order = order;
//  pQueryAttr->window = win;
5815 5816 5817

  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pBInfo->resultRowInfo);
5818
  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
5819
  finalizeQueryResult(pBInfo->pCtx, pOperator->numOfOutput);
5820

H
Haojun Liao 已提交
5821
//  initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo);
L
Liu Jicong 已提交
5822
  //  toSDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes);
5823

H
Haojun Liao 已提交
5824 5825 5826
//  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
//    pOperator->status = OP_EXEC_DONE;
//  }
5827

L
Liu Jicong 已提交
5828
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5829 5830
}

L
Liu Jicong 已提交
5831
static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
5832 5833 5834 5835
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5836
  SSessionAggOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
5837
  SOptrBasicInfo*          pBInfo = &pInfo->binfo;
5838 5839

  if (pOperator->status == OP_RES_TO_RETURN) {
5840
    toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pBInfo->pRes, pBInfo->capacity, pBInfo->rowCellInfoOffset);
5841 5842 5843
    if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
      doSetOperatorCompleted(pOperator);
      return NULL;
5844 5845 5846 5847 5848
    }

    return pBInfo->pRes;
  }

L
Liu Jicong 已提交
5849
  int32_t        order = TSDB_ORDER_ASC;
H
Haojun Liao 已提交
5850
  SOperatorInfo* downstream = pOperator->pDownstream[0];
5851

L
Liu Jicong 已提交
5852
  while (1) {
H
Haojun Liao 已提交
5853
    publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
H
Haojun Liao 已提交
5854
    SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
H
Haojun Liao 已提交
5855
    publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5856 5857 5858 5859 5860
    if (pBlock == NULL) {
      break;
    }

    // the pDataBlock are always the same one, no need to call this again
H
Haojun Liao 已提交
5861
    setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order);
5862
    doSessionWindowAggImpl(pOperator, pInfo, pBlock);
5863 5864 5865 5866 5867
  }

  // restore the value
  pOperator->status = OP_RES_TO_RETURN;
  closeAllResultRows(&pBInfo->resultRowInfo);
5868
  finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset);
5869

5870 5871
  initGroupResInfo(&pInfo->groupResInfo, &pBInfo->resultRowInfo);
  blockDataEnsureCapacity(pBInfo->pRes, pBInfo->capacity);
5872
  toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pBInfo->pRes, pBInfo->capacity, pBInfo->rowCellInfoOffset);
5873 5874
  if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
    doSetOperatorCompleted(pOperator);
5875 5876
  }

L
Liu Jicong 已提交
5877
  return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
5878 5879 5880
}


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

L
Liu Jicong 已提交
5885 5886
  int64_t ekey = Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pTaskInfo->window.ekey
                                                                   : pInfo->existNewGroupBlock->info.window.ekey;
5887 5888
  taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));

5889
  taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey);
5890 5891
  taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);

H
Haojun Liao 已提交
5892
  doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity, pInfo->p);
5893 5894 5895 5896
  pInfo->existNewGroupBlock = NULL;
  *newgroup = true;
}

L
Liu Jicong 已提交
5897 5898
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup,
                                            SExecTaskInfo* pTaskInfo) {
5899 5900
  if (taosFillHasMoreResults(pInfo->pFillInfo)) {
    *newgroup = false;
H
Haojun Liao 已提交
5901 5902
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity, pInfo->p);
    if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) {
5903 5904 5905 5906 5907 5908
      return;
    }
  }

  // handle the cached new group data block
  if (pInfo->existNewGroupBlock) {
5909
    doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
5910 5911 5912
  }
}

L
Liu Jicong 已提交
5913 5914 5915
static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
  SFillOperatorInfo* pInfo = pOperator->info;
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
5916

H
Haojun Liao 已提交
5917 5918
  SResultInfo* pResultInfo = &pOperator->resultInfo;
  blockDataCleanup(pInfo->pRes);
5919 5920 5921 5922
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

5923
  doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
H
Haojun Liao 已提交
5924 5925 5926
  if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pInfo->pRes->info.rows > 0)) {
    return pInfo->pRes;
  }
5927

H
Haojun Liao 已提交
5928
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
5929
  while (1) {
H
Haojun Liao 已提交
5930 5931 5932
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
    SSDataBlock* pBlock = pDownstream->getNextFn(pDownstream, newgroup);
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943

    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
5944
      taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5945 5946 5947 5948 5949 5950 5951
    } else {
      if (pBlock == NULL) {
        if (pInfo->totalInputRows == 0) {
          pOperator->status = OP_EXEC_DONE;
          return NULL;
        }

5952
        taosFillSetStartInfo(pInfo->pFillInfo, 0, pTaskInfo->window.ekey);
5953 5954 5955 5956 5957 5958 5959
      } else {
        pInfo->totalInputRows += pBlock->info.rows;
        taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey);
        taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock);
      }
    }

H
Haojun Liao 已提交
5960
    doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pInfo->capacity, pInfo->p);
5961 5962 5963 5964 5965

    // current group has no more result to return
    if (pInfo->pRes->info.rows > 0) {
      // 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
H
Haojun Liao 已提交
5966
      if (pInfo->pRes->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) {
5967 5968 5969
        return pInfo->pRes;
      }

5970
      doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo);
H
Haojun Liao 已提交
5971
      if (pInfo->pRes->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) {
5972 5973 5974 5975
        return pInfo->pRes;
      }
    } else if (pInfo->existNewGroupBlock) {  // try next group
      assert(pBlock != NULL);
5976
      doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo);
H
Haojun Liao 已提交
5977
      if (pInfo->pRes->info.rows > pResultInfo->threshold) {
5978 5979 5980 5981 5982 5983 5984 5985 5986
        return pInfo->pRes;
      }
    } else {
      return NULL;
    }
  }
}

// todo set the attribute of query scan count
H
Haojun Liao 已提交
5987
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) {
L
Liu Jicong 已提交
5988
  for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002
    int32_t functionId = getExprFunctionId(&pQueryAttr->pExpr1[i]);
    if (functionId == FUNCTION_STDDEV || functionId == FUNCTION_PERCT) {
      return 2;
    }
  }

  return 1;
}

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

H
Haojun Liao 已提交
6003 6004
  if (pOperator->closeFn != NULL) {
    pOperator->closeFn(pOperator->info, pOperator->numOfOutput);
6005 6006
  }

H
Haojun Liao 已提交
6007
  if (pOperator->pDownstream != NULL) {
L
Liu Jicong 已提交
6008
    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
H
Haojun Liao 已提交
6009
      destroyOperatorInfo(pOperator->pDownstream[i]);
6010 6011
    }

wafwerar's avatar
wafwerar 已提交
6012
    taosMemoryFreeClear(pOperator->pDownstream);
H
Haojun Liao 已提交
6013
    pOperator->numOfDownstream = 0;
6014 6015
  }

wafwerar's avatar
wafwerar 已提交
6016 6017
  taosMemoryFreeClear(pOperator->info);
  taosMemoryFreeClear(pOperator);
6018 6019
}

L
Liu Jicong 已提交
6020
int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, const char* pKey) {
6021 6022
  _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);

H
Haojun Liao 已提交
6023 6024
  pAggSup->resultRowSize       = getResultRowSize(pCtx, numOfOutput);
  pAggSup->keyBuf              = taosMemoryCalloc(1, sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES);
6025
  pAggSup->pResultRowHashTable = taosHashInit(10, hashFn, true, HASH_NO_LOCK);
H
Haojun Liao 已提交
6026
  pAggSup->pResultRowListSet   = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
6027 6028 6029
  pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell));

  if (pAggSup->keyBuf == NULL || pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL ||
6030
      pAggSup->pResultRowHashTable == NULL) {
6031 6032 6033
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Haojun Liao 已提交
6034 6035 6036 6037 6038
  int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, 4096, 4096 * 256, pKey, "/tmp/");
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

6039 6040 6041
  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
6042
static void cleanupAggSup(SAggSupporter* pAggSup) {
wafwerar's avatar
wafwerar 已提交
6043
  taosMemoryFreeClear(pAggSup->keyBuf);
6044 6045 6046
  taosHashCleanup(pAggSup->pResultRowHashTable);
  taosHashCleanup(pAggSup->pResultRowListSet);
  taosArrayDestroy(pAggSup->pResultRowArrayList);
H
Haojun Liao 已提交
6047
  destroyDiskbasedBuf(pAggSup->pResultBuf);
6048 6049
}

H
Haojun Liao 已提交
6050
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
H
Haojun Liao 已提交
6051
                           int32_t numOfRows, SSDataBlock* pResultBlock, const char* pkey) {
H
Haojun Liao 已提交
6052 6053 6054 6055
  pBasicInfo->pCtx = createSqlFunctionCtx_rv(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
  pBasicInfo->pRes = pResultBlock;
  pBasicInfo->capacity = numOfRows;

H
Haojun Liao 已提交
6056
  doInitAggInfoSup(pAggSup, pBasicInfo->pCtx, numOfCols, pkey);
H
Haojun Liao 已提交
6057 6058 6059
}

static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
6060
  STableQueryInfo* pTableQueryInfo = taosMemoryCalloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
H
Haojun Liao 已提交
6061 6062
  if (pTableQueryInfo == NULL) {
    return NULL;
H
Haojun Liao 已提交
6063
  }
H
Haojun Liao 已提交
6064 6065

  int32_t index = 0;
L
Liu Jicong 已提交
6066
  for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
H
Haojun Liao 已提交
6067
    SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
L
Liu Jicong 已提交
6068
    for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
H
Haojun Liao 已提交
6069 6070
      STableKeyInfo* pk = taosArrayGet(pa, j);

H
Haojun Liao 已提交
6071
      STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
L
Liu Jicong 已提交
6072 6073
      pTQueryInfo->uid = pk->uid;
      pTQueryInfo->lastKey = pk->lastKey;
H
Haojun Liao 已提交
6074 6075 6076
      pTQueryInfo->groupIndex = i;
    }
  }
H
Haojun Liao 已提交
6077 6078

  STimeWindow win = {0, INT64_MAX};
H
Haojun Liao 已提交
6079 6080
  createTableQueryInfo(pTableQueryInfo, false, win);
  return pTableQueryInfo;
H
Haojun Liao 已提交
6081 6082
}

L
Liu Jicong 已提交
6083 6084 6085
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                           SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo,
                                           const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
6086
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
L
Liu Jicong 已提交
6087
  SOperatorInfo*    pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6088 6089 6090
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6091 6092

  //(int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
H
Haojun Liao 已提交
6093
  int32_t numOfRows = 1;
H
Haojun Liao 已提交
6094
  int32_t code = initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResultBlock, pTaskInfo->id.str);
H
Haojun Liao 已提交
6095 6096
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) {
H
Haojun Liao 已提交
6097 6098
    goto _error;
  }
H
Haojun Liao 已提交
6099

H
Haojun Liao 已提交
6100
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
6101

H
Haojun Liao 已提交
6102
  pOperator->name         = "TableAggregate";
X
Xiaoyu Wang 已提交
6103
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG;
6104
  pOperator->blockingOptr = true;
H
Haojun Liao 已提交
6105 6106 6107 6108 6109 6110 6111 6112 6113
  pOperator->status       = OP_NOT_OPENED;
  pOperator->info         = pInfo;
  pOperator->pExpr        = pExprInfo;
  pOperator->numOfOutput  = numOfCols;

  pOperator->pTaskInfo    = pTaskInfo;
  pOperator->_openFn      = doOpenAggregateOptr;
  pOperator->getNextFn    = getAggregateResult;
  pOperator->closeFn      = destroyAggOperatorInfo;
wmmhello's avatar
wmmhello 已提交
6114 6115
  pOperator->encodeResultRow = aggEncodeResultRow;
  pOperator->decodeResultRow = aggDecodeResultRow;
H
Haojun Liao 已提交
6116 6117 6118 6119 6120

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

  return pOperator;
L
Liu Jicong 已提交
6123
_error:
H
Haojun Liao 已提交
6124
  destroyAggOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
6125 6126
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6127 6128
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
6129 6130
}

H
Haojun Liao 已提交
6131
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput) {
6132 6133
  assert(pInfo != NULL);

6134
  destroySqlFunctionCtx(pInfo->pCtx, numOfOutput);
wafwerar's avatar
wafwerar 已提交
6135
  taosMemoryFreeClear(pInfo->rowCellInfoOffset);
6136 6137

  cleanupResultRowInfo(&pInfo->resultRowInfo);
H
Haojun Liao 已提交
6138
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
6139 6140
}

H
Haojun Liao 已提交
6141
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6142
  SOptrBasicInfo* pInfo = (SOptrBasicInfo*)param;
6143 6144
  doDestroyBasicInfo(pInfo, numOfOutput);
}
H
Haojun Liao 已提交
6145 6146

void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6147
  SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param;
6148
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
wafwerar's avatar
wafwerar 已提交
6149
  taosMemoryFreeClear(pInfo->prevData);
6150
}
H
Haojun Liao 已提交
6151 6152

void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6153
  SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param;
6154 6155
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}
6156

H
Haojun Liao 已提交
6157
void destroyIntervalOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6158
  STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)param;
H
Haojun Liao 已提交
6159 6160 6161 6162 6163
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
  cleanupAggSup(&pInfo->aggSup);
}

void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6164
  SSessionAggOperatorInfo* pInfo = (SSessionAggOperatorInfo*)param;
6165 6166 6167
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
6168
void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6169
  SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
6170
  pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
H
Haojun Liao 已提交
6171
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
wafwerar's avatar
wafwerar 已提交
6172
  taosMemoryFreeClear(pInfo->p);
6173 6174
}

H
Haojun Liao 已提交
6175
static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6176
  SProjectOperatorInfo* pInfo = (SProjectOperatorInfo*)param;
6177 6178 6179
  doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
}

H
Haojun Liao 已提交
6180
static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6181
  STagScanInfo* pInfo = (STagScanInfo*)param;
H
Haojun Liao 已提交
6182
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
6183 6184
}

H
Haojun Liao 已提交
6185
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6186
  SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
H
Haojun Liao 已提交
6187 6188
  pInfo->pDataBlock = blockDataDestroy(pInfo->pDataBlock);

H
Haojun Liao 已提交
6189
  taosArrayDestroy(pInfo->pSortInfo);
6190 6191 6192
}

static void destroyDistinctOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6193
  SDistinctOperatorInfo* pInfo = (SDistinctOperatorInfo*)param;
6194
  taosHashCleanup(pInfo->pSet);
wafwerar's avatar
wafwerar 已提交
6195
  taosMemoryFreeClear(pInfo->buf);
6196
  taosArrayDestroy(pInfo->pDistinctDataInfo);
H
Haojun Liao 已提交
6197
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
6198 6199
}

H
Haojun Liao 已提交
6200
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
L
Liu Jicong 已提交
6201
  SExchangeInfo* pExInfo = (SExchangeInfo*)param;
H
Haojun Liao 已提交
6202 6203 6204 6205 6206 6207 6208 6209 6210
  taosArrayDestroy(pExInfo->pSources);
  taosArrayDestroy(pExInfo->pSourceDataInfo);
  if (pExInfo->pResult != NULL) {
    blockDataDestroy(pExInfo->pResult);
  }

  tsem_destroy(&pExInfo->ready);
}

L
Liu Jicong 已提交
6211 6212 6213
SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                               SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo,
                                               const STableGroupInfo* pTableGroupInfo) {
wafwerar's avatar
wafwerar 已提交
6214
  SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
6215

H
Haojun Liao 已提交
6216
  int32_t numOfRows = 1;
L
Liu Jicong 已提交
6217 6218
  int32_t code =
      initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResBlock, pTaskInfo->id.str);
H
Haojun Liao 已提交
6219 6220 6221 6222
  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS || pInfo->pTableQueryInfo == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6223

L
Liu Jicong 已提交
6224
  size_t tableGroup = taosArrayGetSize(pTableGroupInfo->pGroupList);
6225
  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)tableGroup);
6226

wafwerar's avatar
wafwerar 已提交
6227
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
L
Liu Jicong 已提交
6228
  pOperator->name = "MultiTableAggregate";
X
Xiaoyu Wang 已提交
6229
  // pOperator->operatorType = OP_MultiTableAggregate;
6230
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
6231 6232 6233 6234 6235
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
  pOperator->pExpr = pExprInfo;
  pOperator->numOfOutput = numOfCols;
  pOperator->pTaskInfo = pTaskInfo;
6236

H
Haojun Liao 已提交
6237
  pOperator->getNextFn = doMultiTableAggregate;
H
Haojun Liao 已提交
6238
  pOperator->closeFn = destroyAggOperatorInfo;
H
Haojun Liao 已提交
6239 6240 6241 6242
  code = appendDownstream(pOperator, &downstream, 1);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6243 6244

  return pOperator;
H
Haojun Liao 已提交
6245 6246 6247

_error:
  return NULL;
6248 6249
}

L
Liu Jicong 已提交
6250
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num,
H
Haojun Liao 已提交
6251
                                         SSDataBlock* pResBlock, SLimit* pLimit, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6252
  SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
L
Liu Jicong 已提交
6253
  SOperatorInfo*        pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6254 6255 6256
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
6257

H
Haojun Liao 已提交
6258 6259
  pInfo->limit      = *pLimit;
  pInfo->curOffset  = pLimit->offset;
H
Haojun Liao 已提交
6260
  pInfo->binfo.pRes = pResBlock;
H
Haojun Liao 已提交
6261 6262 6263 6264 6265

  int32_t numOfCols = num;
  int32_t numOfRows = 4096;
  initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResBlock, pTaskInfo->id.str);
  setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, pTaskInfo);
6266

H
Haojun Liao 已提交
6267
  pOperator->name         = "ProjectOperator";
H
Haojun Liao 已提交
6268
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
6269
  pOperator->blockingOptr = false;
H
Haojun Liao 已提交
6270 6271 6272 6273 6274 6275 6276
  pOperator->status       = OP_NOT_OPENED;
  pOperator->info         = pInfo;
  pOperator->pExpr        = pExprInfo;
  pOperator->numOfOutput  = num;
  pOperator->_openFn      = operatorDummyOpenFn;
  pOperator->getNextFn    = doProjectOperation;
  pOperator->closeFn      = destroyProjectOperatorInfo;
L
Liu Jicong 已提交
6277 6278

  pOperator->pTaskInfo = pTaskInfo;
6279
  int32_t code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
6280
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
6281 6282
    goto _error;
  }
6283 6284

  return pOperator;
H
Haojun Liao 已提交
6285

L
Liu Jicong 已提交
6286
_error:
H
Haojun Liao 已提交
6287 6288
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
6289 6290
}

L
Liu Jicong 已提交
6291 6292
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                          SSDataBlock* pResBlock, SInterval* pInterval,
6293
                                          const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6294
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
L
Liu Jicong 已提交
6295
  SOperatorInfo*              pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6296 6297 6298
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6299

H
Haojun Liao 已提交
6300 6301
  pInfo->order     = TSDB_ORDER_ASC;
  pInfo->interval  = *pInterval;
6302 6303 6304
  pInfo->execModel = pTaskInfo->execModel;

  pInfo->win       = pTaskInfo->window;
6305 6306
  pInfo->win.skey  = 0;
  pInfo->win.ekey  = INT64_MAX;
6307 6308

  int32_t numOfRows = 4096;
H
Haojun Liao 已提交
6309
  int32_t code = initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResBlock, pTaskInfo->id.str);
6310 6311
  initExecTimeWindowInfo(&pInfo->timeWindowData, &pInfo->win);

L
Liu Jicong 已提交
6312 6313
  //  pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
  if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
H
Haojun Liao 已提交
6314 6315
    goto _error;
  }
H
Haojun Liao 已提交
6316 6317

  initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
6318

6319
  pOperator->name         = "TimeIntervalAggOperator";
H
Haojun Liao 已提交
6320
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
6321
  pOperator->blockingOptr = true;
H
Haojun Liao 已提交
6322 6323 6324 6325 6326 6327 6328
  pOperator->status       = OP_NOT_OPENED;
  pOperator->pExpr        = pExprInfo;
  pOperator->pTaskInfo    = pTaskInfo;
  pOperator->numOfOutput  = numOfCols;
  pOperator->info         = pInfo;
  pOperator->_openFn      = doOpenIntervalAgg;
  pOperator->getNextFn    = doBuildIntervalResult;
6329
  pOperator->getStreamResFn= doStreamIntervalAgg;
H
Haojun Liao 已提交
6330
  pOperator->closeFn      = destroyIntervalOperatorInfo;
6331

H
Haojun Liao 已提交
6332
  code = appendDownstream(pOperator, &downstream, 1);
H
Haojun Liao 已提交
6333 6334 6335 6336
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

6337
  return pOperator;
H
Haojun Liao 已提交
6338

L
Liu Jicong 已提交
6339
_error:
H
Haojun Liao 已提交
6340
  destroyIntervalOperatorInfo(pInfo, numOfCols);
wafwerar's avatar
wafwerar 已提交
6341 6342
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6343 6344
  pTaskInfo->code = code;
  return NULL;
6345 6346
}

L
Liu Jicong 已提交
6347 6348
SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream,
                                                 SExprInfo* pExpr, int32_t numOfOutput) {
wafwerar's avatar
wafwerar 已提交
6349
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
6350

L
Liu Jicong 已提交
6351 6352
  //  pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
  //  pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pResultInfo->capacity);
H
Haojun Liao 已提交
6353
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6354

wafwerar's avatar
wafwerar 已提交
6355
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
6356

L
Liu Jicong 已提交
6357 6358
  pOperator->name = "AllTimeIntervalAggOperator";
  //  pOperator->operatorType = OP_AllTimeWindow;
6359
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
6360 6361 6362 6363 6364
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfOutput;
  pOperator->info = pInfo;
  pOperator->pRuntimeEnv = pRuntimeEnv;
H
Haojun Liao 已提交
6365
  pOperator->getNextFn = doAllIntervalAgg;
H
Haojun Liao 已提交
6366
  pOperator->closeFn = destroyBasicOperatorInfo;
6367

L
Liu Jicong 已提交
6368
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6369 6370 6371
  return pOperator;
}

H
Haojun Liao 已提交
6372
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6373
  SStateWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStateWindowOperatorInfo));
H
Haojun Liao 已提交
6374

L
Liu Jicong 已提交
6375 6376 6377 6378
  pInfo->colIndex = -1;
  pInfo->reptScan = false;
  //  pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
  //  pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pResultInfo->capacity);
6379
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6380

wafwerar's avatar
wafwerar 已提交
6381
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
L
Liu Jicong 已提交
6382 6383
  pOperator->name = "StateWindowOperator";
  //  pOperator->operatorType = OP_StateWindow;
6384
  pOperator->blockingOptr = true;
H
Haojun Liao 已提交
6385 6386 6387 6388 6389 6390 6391 6392
  pOperator->status       = OP_NOT_OPENED;
  pOperator->pExpr        = pExpr;
  pOperator->numOfOutput  = numOfCols;

  pOperator->pTaskInfo    = pTaskInfo;
  pOperator->info         = pInfo;
  pOperator->getNextFn    = doStateWindowAgg;
  pOperator->closeFn      = destroyStateWindowOperatorInfo;
6393

H
Haojun Liao 已提交
6394
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6395 6396 6397
  return pOperator;
}

L
Liu Jicong 已提交
6398 6399
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
                                            SSDataBlock* pResBlock, int64_t gap, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6400
  SSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSessionAggOperatorInfo));
L
Liu Jicong 已提交
6401
  SOperatorInfo*           pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6402 6403 6404
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
H
Haojun Liao 已提交
6405

H
Haojun Liao 已提交
6406
  int32_t numOfRows = 4096;
6407
  int32_t code = initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, numOfRows, pResBlock, pTaskInfo->id.str);
H
Haojun Liao 已提交
6408 6409 6410
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6411

H
Haojun Liao 已提交
6412
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6413
  initExecTimeWindowInfo(&pInfo->timeWindowData, &pTaskInfo->window);
6414

6415 6416 6417 6418 6419
  pInfo->gap              = gap;
  pInfo->binfo.pRes       = pResBlock;
  pInfo->prevTs           = INT64_MIN;
  pInfo->reptScan         = false;
  pOperator->name         = "SessionWindowAggOperator";
H
Haojun Liao 已提交
6420
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW;
6421
  pOperator->blockingOptr = true;
6422 6423 6424 6425 6426 6427 6428
  pOperator->status       = OP_NOT_OPENED;
  pOperator->pExpr        = pExprInfo;
  pOperator->numOfOutput  = numOfCols;
  pOperator->info         = pInfo;
  pOperator->getNextFn    = doSessionWindowAgg;
  pOperator->closeFn      = destroySWindowOperatorInfo;
  pOperator->pTaskInfo    = pTaskInfo;
6429

H
Haojun Liao 已提交
6430
  code = appendDownstream(pOperator, &downstream, 1);
6431
  return pOperator;
H
Haojun Liao 已提交
6432

L
Liu Jicong 已提交
6433
_error:
H
Haojun Liao 已提交
6434 6435 6436 6437
  if (pInfo != NULL) {
    destroySWindowOperatorInfo(pInfo, numOfCols);
  }

wafwerar's avatar
wafwerar 已提交
6438 6439
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
H
Haojun Liao 已提交
6440 6441
  pTaskInfo->code = code;
  return NULL;
6442 6443
}

L
Liu Jicong 已提交
6444 6445
SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream,
                                                        SExprInfo* pExpr, int32_t numOfOutput) {
wafwerar's avatar
wafwerar 已提交
6446
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
6447

L
Liu Jicong 已提交
6448 6449
  //  pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
  //  pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pResultInfo->capacity);
H
Haojun Liao 已提交
6450
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6451

wafwerar's avatar
wafwerar 已提交
6452
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
L
Liu Jicong 已提交
6453 6454
  pOperator->name = "MultiTableTimeIntervalOperator";
  //  pOperator->operatorType = OP_MultiTableTimeInterval;
6455
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
6456 6457 6458 6459 6460
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfOutput;
  pOperator->info = pInfo;
  pOperator->pRuntimeEnv = pRuntimeEnv;
6461

H
Haojun Liao 已提交
6462
  pOperator->getNextFn = doSTableIntervalAgg;
H
Haojun Liao 已提交
6463
  pOperator->closeFn = destroyBasicOperatorInfo;
6464

L
Liu Jicong 已提交
6465
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6466 6467 6468
  return pOperator;
}

L
Liu Jicong 已提交
6469 6470
SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream,
                                                           SExprInfo* pExpr, int32_t numOfOutput) {
wafwerar's avatar
wafwerar 已提交
6471
  STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
6472

L
Liu Jicong 已提交
6473 6474
  //  pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
  //  pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pResultInfo->capacity);
H
Haojun Liao 已提交
6475
  initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
6476

wafwerar's avatar
wafwerar 已提交
6477
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
L
Liu Jicong 已提交
6478 6479
  pOperator->name = "AllMultiTableTimeIntervalOperator";
  //  pOperator->operatorType = OP_AllMultiTableTimeInterval;
6480
  pOperator->blockingOptr = true;
L
Liu Jicong 已提交
6481 6482 6483 6484 6485
  pOperator->status = OP_NOT_OPENED;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfOutput;
  pOperator->info = pInfo;
  pOperator->pRuntimeEnv = pRuntimeEnv;
6486

H
Haojun Liao 已提交
6487
  pOperator->getNextFn = doAllSTableIntervalAgg;
H
Haojun Liao 已提交
6488
  pOperator->closeFn = destroyBasicOperatorInfo;
6489

L
Liu Jicong 已提交
6490
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6491 6492 6493 6494

  return pOperator;
}

H
Haojun Liao 已提交
6495
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, int64_t* fillVal,
L
Liu Jicong 已提交
6496
                            STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) {
H
Haojun Liao 已提交
6497 6498 6499 6500 6501 6502 6503 6504 6505 6506
  struct SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, (int64_t*)fillVal);

  TSKEY sk = TMIN(win.skey, win.ekey);
  TSKEY ek = TMAX(win.skey, win.ekey);

  // TODO set correct time precision
  STimeWindow w = TSWINDOW_INITIALIZER;
  getAlignQueryTimeWindow(pInterval, TSDB_TIME_PRECISION_MILLI, win.skey, sk, ek, &w);

  int32_t order = TSDB_ORDER_ASC;
L
Liu Jicong 已提交
6507 6508
  pInfo->pFillInfo = taosCreateFillInfo(order, w.skey, 0, capacity, numOfCols, pInterval->sliding,
                                        pInterval->slidingUnit, (int8_t)pInterval->precision, fillType, pColInfo, id);
H
Haojun Liao 已提交
6509

wafwerar's avatar
wafwerar 已提交
6510
  pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
H
Haojun Liao 已提交
6511 6512 6513 6514 6515 6516 6517 6518

  if (pInfo->pFillInfo == NULL || pInfo->p == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  } else {
    return TSDB_CODE_SUCCESS;
  }
}

L
Liu Jicong 已提交
6519 6520 6521
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 已提交
6522
  SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo));
L
Liu Jicong 已提交
6523
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
6524

L
Liu Jicong 已提交
6525
  pInfo->pRes = pResBlock;
6526
  pInfo->multigroupResult = multigroupResult;
L
Liu Jicong 已提交
6527
  pInfo->intervalInfo = *pInterval;
6528

H
Haojun Liao 已提交
6529
  SResultInfo* pResultInfo = &pOperator->resultInfo;
L
Liu Jicong 已提交
6530 6531
  int32_t      code = initFillInfo(pInfo, pExpr, numOfCols, (int64_t*)fillVal, pTaskInfo->window, pResultInfo->capacity,
                                   pTaskInfo->id.str, pInterval, fillType);
6532 6533 6534
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
6535

L
Liu Jicong 已提交
6536
  pOperator->name = "FillOperator";
6537
  pOperator->blockingOptr = false;
L
Liu Jicong 已提交
6538 6539 6540 6541 6542 6543 6544 6545
  pOperator->status = OP_NOT_OPENED;
  //  pOperator->operatorType = OP_Fill;
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfCols;
  pOperator->info = pInfo;
  pOperator->_openFn = operatorDummyOpenFn;
  pOperator->getNextFn = doFill;
  pOperator->pTaskInfo = pTaskInfo;
6546

L
Liu Jicong 已提交
6547
  pOperator->closeFn = destroySFillOperatorInfo;
H
Haojun Liao 已提交
6548

6549
  code = appendDownstream(pOperator, &downstream, 1);
6550
  return pOperator;
H
Haojun Liao 已提交
6551

L
Liu Jicong 已提交
6552
_error:
wafwerar's avatar
wafwerar 已提交
6553 6554
  taosMemoryFreeClear(pOperator);
  taosMemoryFreeClear(pInfo);
H
Haojun Liao 已提交
6555
  return NULL;
6556 6557
}

L
Liu Jicong 已提交
6558 6559
SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr,
                                        int32_t numOfOutput, void* pMerger, bool multigroupResult) {
wafwerar's avatar
wafwerar 已提交
6560
  SSLimitOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSLimitOperatorInfo));
L
Liu Jicong 已提交
6561 6562 6563 6564 6565 6566 6567 6568 6569 6570
  SOperatorInfo*       pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));

  //  pInfo->orderColumnList = getResultGroupCheckColumns(pQueryAttr);
  //  pInfo->slimit          = pQueryAttr->slimit;
  //  pInfo->limit           = pQueryAttr->limit;
  //  pInfo->capacity        = pResultInfo->capacity;
  //  pInfo->threshold       = (int64_t)(pInfo->capacity * 0.8);
  //  pInfo->currentOffset   = pQueryAttr->limit.offset;
  //  pInfo->currentGroupOffset = pQueryAttr->slimit.offset;
  pInfo->multigroupResult = multigroupResult;
6571 6572 6573

  // TODO refactor
  int32_t len = 0;
L
Liu Jicong 已提交
6574
  for (int32_t i = 0; i < numOfOutput; ++i) {
6575 6576 6577
    len += pExpr[i].base.resSchema.bytes;
  }

L
Liu Jicong 已提交
6578
  int32_t numOfCols = (pInfo->orderColumnList != NULL) ? (int32_t)taosArrayGetSize(pInfo->orderColumnList) : 0;
wafwerar's avatar
wafwerar 已提交
6579
  pInfo->prevRow = taosMemoryCalloc(1, (POINTER_BYTES * numOfCols + len));
6580 6581

  int32_t offset = POINTER_BYTES * numOfCols;
L
Liu Jicong 已提交
6582
  for (int32_t i = 0; i < numOfCols; ++i) {
6583 6584 6585 6586 6587 6588
    pInfo->prevRow[i] = (char*)pInfo->prevRow + offset;

    SColIndex* index = taosArrayGet(pInfo->orderColumnList, i);
    offset += pExpr[index->colIndex].base.resSchema.bytes;
  }

L
Liu Jicong 已提交
6589
  //  pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pOperator->resultInfo.capacity);
6590

L
Liu Jicong 已提交
6591
  pOperator->name = "SLimitOperator";
X
Xiaoyu Wang 已提交
6592
  // pOperator->operatorType = OP_SLimit;
6593
  pOperator->blockingOptr = false;
L
Liu Jicong 已提交
6594 6595 6596 6597
  pOperator->status = OP_NOT_OPENED;
  //  pOperator->exec         = doSLimit;
  pOperator->info = pInfo;
  pOperator->pRuntimeEnv = pRuntimeEnv;
H
Haojun Liao 已提交
6598
  pOperator->closeFn = destroySlimitOperatorInfo;
6599

L
Liu Jicong 已提交
6600
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6601 6602 6603
  return pOperator;
}

L
Liu Jicong 已提交
6604
static SSDataBlock* doTagScan(SOperatorInfo* pOperator, bool* newgroup) {
6605 6606 6607 6608 6609 6610
#if 0
  SOperatorInfo* pOperator = (SOperatorInfo*) param;
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

H
Haojun Liao 已提交
6611
  STaskRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
H
Haojun Liao 已提交
6612
  int32_t maxNumOfTables = (int32_t)pResultInfo->capacity;
6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633

  STagScanInfo *pInfo = pOperator->info;
  SSDataBlock  *pRes = pInfo->pRes;
  *newgroup = false;

  int32_t count = 0;
  SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0);

  int32_t functionId = getExprFunctionId(&pOperator->pExpr[0]);
  if (functionId == FUNCTION_TID_TAG) { // return the tags & table Id
    assert(pQueryAttr->numOfOutput == 1);

    SExprInfo* pExprInfo = &pOperator->pExpr[0];
    int32_t rsize = pExprInfo->base.resSchema.bytes;

    count = 0;

    int16_t bytes = pExprInfo->base.resSchema.bytes;
    int16_t type  = pExprInfo->base.resSchema.type;

    for(int32_t i = 0; i < pQueryAttr->numOfTags; ++i) {
6634
      if (pQueryAttr->tagColList[i].colId == pExprInfo->base.pColumns->info.colId) {
6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665
        bytes = pQueryAttr->tagColList[i].bytes;
        type = pQueryAttr->tagColList[i].type;
        break;
      }
    }

    SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, 0);

    while(pInfo->curPos < pInfo->totalTables && count < maxNumOfTables) {
      int32_t i = pInfo->curPos++;
      STableQueryInfo *item = taosArrayGetP(pa, i);

      char *output = pColInfo->pData + count * rsize;
      varDataSetLen(output, rsize - VARSTR_HEADER_SIZE);

      output = varDataVal(output);
      STableId* id = TSDB_TABLEID(item->pTable);

      *(int16_t *)output = 0;
      output += sizeof(int16_t);

      *(int64_t *)output = id->uid;  // memory align problem, todo serialize
      output += sizeof(id->uid);

      *(int32_t *)output = id->tid;
      output += sizeof(id->tid);

      *(int32_t *)output = pQueryAttr->vgId;
      output += sizeof(pQueryAttr->vgId);

      char* data = NULL;
6666
      if (pExprInfo->base.pColumns->info.colId == TSDB_TBNAME_COLUMN_INDEX) {
6667 6668
        data = tsdbGetTableName(item->pTable);
      } else {
6669
        data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.pColumns->info.colId, type, bytes);
6670 6671 6672 6673 6674 6675
      }

      doSetTagValueToResultBuf(output, data, type, bytes);
      count += 1;
    }

6676
    //qDebug("QInfo:0x%"PRIx64" create (tableId, tag) info completed, rows:%d", GET_TASKID(pRuntimeEnv), count);
6677 6678 6679 6680 6681 6682
  } else if (functionId == FUNCTION_COUNT) {// handle the "count(tbname)" query
    SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, 0);
    *(int64_t*)pColInfo->pData = pInfo->totalTables;
    count = 1;

    pOperator->status = OP_EXEC_DONE;
6683
    //qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_TASKID(pRuntimeEnv), count);
6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696
  } else {  // return only the tags|table name etc.
    SExprInfo* pExprInfo = &pOperator->pExpr[0];  // todo use the column list instead of exprinfo

    count = 0;
    while(pInfo->curPos < pInfo->totalTables && count < maxNumOfTables) {
      int32_t i = pInfo->curPos++;

      STableQueryInfo* item = taosArrayGetP(pa, i);

      char *data = NULL, *dst = NULL;
      int16_t type = 0, bytes = 0;
      for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
        // not assign value in case of user defined constant output column
6697
        if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.pColumns->flag)) {
6698 6699 6700 6701 6702 6703 6704
          continue;
        }

        SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, j);
        type  = pExprInfo[j].base.resSchema.type;
        bytes = pExprInfo[j].base.resSchema.bytes;

6705
        if (pExprInfo[j].base.pColumns->info.colId == TSDB_TBNAME_COLUMN_INDEX) {
6706 6707
          data = tsdbGetTableName(item->pTable);
        } else {
6708
          data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.pColumns->info.colId, type, bytes);
6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721
        }

        dst  = pColInfo->pData + count * pExprInfo[j].base.resSchema.bytes;
        doSetTagValueToResultBuf(dst, data, type, bytes);
      }

      count += 1;
    }

    if (pInfo->curPos >= pInfo->totalTables) {
      pOperator->status = OP_EXEC_DONE;
    }

6722
    //qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_TASKID(pRuntimeEnv), count);
6723 6724 6725
  }

  if (pOperator->status == OP_EXEC_DONE) {
6726
    setTaskStatus(pOperator->pRuntimeEnv, TASK_COMPLETED);
6727 6728 6729 6730 6731 6732 6733 6734
  }

  pRes->info.rows = count;
  return (pRes->info.rows == 0)? NULL:pInfo->pRes;

#endif
}

H
Haojun Liao 已提交
6735
SOperatorInfo* createTagScanOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput) {
wafwerar's avatar
wafwerar 已提交
6736
  STagScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STagScanInfo));
L
Liu Jicong 已提交
6737
  //  pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pResultInfo->capacity);
6738 6739 6740 6741 6742 6743 6744

  size_t numOfGroup = GET_NUM_OF_TABLEGROUP(pRuntimeEnv);
  assert(numOfGroup == 0 || numOfGroup == 1);

  pInfo->totalTables = pRuntimeEnv->tableqinfoGroupInfo.numOfTables;
  pInfo->curPos = 0;

wafwerar's avatar
wafwerar 已提交
6745
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
L
Liu Jicong 已提交
6746
  pOperator->name = "SeqTableTagScan";
X
Xiaoyu Wang 已提交
6747
  pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN;
6748
  pOperator->blockingOptr = false;
L
Liu Jicong 已提交
6749 6750
  pOperator->status = OP_NOT_OPENED;
  pOperator->info = pInfo;
H
Haojun Liao 已提交
6751
  pOperator->getNextFn = doTagScan;
L
Liu Jicong 已提交
6752 6753 6754
  pOperator->pExpr = pExpr;
  pOperator->numOfOutput = numOfOutput;
  pOperator->pRuntimeEnv = pRuntimeEnv;
H
Haojun Liao 已提交
6755
  pOperator->closeFn = destroyTagScanOperatorInfo;
6756 6757 6758

  return pOperator;
}
L
Liu Jicong 已提交
6759
static bool initMultiDistinctInfo(SDistinctOperatorInfo* pInfo, SOperatorInfo* pOperator, SSDataBlock* pBlock) {
6760
  if (taosArrayGetSize(pInfo->pDistinctDataInfo) == pOperator->numOfOutput) {
L
Liu Jicong 已提交
6761
    // distinct info already inited
6762 6763 6764
    return true;
  }
  for (int i = 0; i < pOperator->numOfOutput; i++) {
L
Liu Jicong 已提交
6765
    //    pInfo->totalBytes += pOperator->pExpr[i].base.colBytes;
6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778
  }
  for (int i = 0; i < pOperator->numOfOutput; i++) {
    int numOfBlock = (int)(taosArrayGetSize(pBlock->pDataBlock));
    assert(i < numOfBlock);
    for (int j = 0; j < numOfBlock; j++) {
      SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, j);
      if (pColDataInfo->info.colId == pOperator->pExpr[i].base.resSchema.colId) {
        SDistinctDataInfo item = {.index = j, .type = pColDataInfo->info.type, .bytes = pColDataInfo->info.bytes};
        taosArrayInsert(pInfo->pDistinctDataInfo, i, &item);
      }
    }
  }
  pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * (pOperator->numOfOutput);
L
Liu Jicong 已提交
6779 6780
  pInfo->buf = taosMemoryCalloc(1, pInfo->totalBytes);
  return taosArrayGetSize(pInfo->pDistinctDataInfo) == pOperator->numOfOutput ? true : false;
6781 6782
}

L
Liu Jicong 已提交
6783 6784 6785
static void buildMultiDistinctKey(SDistinctOperatorInfo* pInfo, SSDataBlock* pBlock, int32_t rowId) {
  char* p = pInfo->buf;
  memset(p, 0, pInfo->totalBytes);
6786 6787

  for (int i = 0; i < taosArrayGetSize(pInfo->pDistinctDataInfo); i++) {
L
Liu Jicong 已提交
6788
    SDistinctDataInfo* pDistDataInfo = (SDistinctDataInfo*)taosArrayGet(pInfo->pDistinctDataInfo, i);
6789
    SColumnInfoData*   pColDataInfo = taosArrayGet(pBlock->pDataBlock, pDistDataInfo->index);
L
Liu Jicong 已提交
6790 6791 6792
    char*              val = ((char*)pColDataInfo->pData) + pColDataInfo->info.bytes * rowId;
    if (isNull(val, pDistDataInfo->type)) {
      p += pDistDataInfo->bytes;
6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806
      continue;
    }
    if (IS_VAR_DATA_TYPE(pDistDataInfo->type)) {
      memcpy(p, varDataVal(val), varDataLen(val));
      p += varDataLen(val);
    } else {
      memcpy(p, val, pDistDataInfo->bytes);
      p += pDistDataInfo->bytes;
    }
    memcpy(p, MULTI_KEY_DELIM, strlen(MULTI_KEY_DELIM));
    p += strlen(MULTI_KEY_DELIM);
  }
}

L
Liu Jicong 已提交
6807
static SSDataBlock* hashDistinct(SOperatorInfo* pOperator, bool* newgroup) {
6808 6809 6810 6811 6812
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  SDistinctOperatorInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
6813
  SSDataBlock*           pRes = pInfo->pRes;
6814 6815 6816

  pRes->info.rows = 0;
  SSDataBlock* pBlock = NULL;
L
Liu Jicong 已提交
6817

H
Haojun Liao 已提交
6818
  SOperatorInfo* pDownstream = pOperator->pDownstream[0];
L
Liu Jicong 已提交
6819
  while (1) {
H
Haojun Liao 已提交
6820 6821 6822
    publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
    pBlock = pDownstream->getNextFn(pDownstream, newgroup);
    publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
6823 6824 6825 6826 6827 6828 6829 6830 6831

    if (pBlock == NULL) {
      doSetOperatorCompleted(pOperator);
      break;
    }
    if (!initMultiDistinctInfo(pInfo, pOperator, pBlock)) {
      doSetOperatorCompleted(pOperator);
      break;
    }
H
Haojun Liao 已提交
6832

L
Liu Jicong 已提交
6833
    // ensure result output buf
6834 6835 6836 6837
    if (pRes->info.rows + pBlock->info.rows > pInfo->outputCapacity) {
      int32_t newSize = pRes->info.rows + pBlock->info.rows;
      for (int i = 0; i < taosArrayGetSize(pRes->pDataBlock); i++) {
        SColumnInfoData*   pResultColInfoData = taosArrayGet(pRes->pDataBlock, i);
L
Liu Jicong 已提交
6838 6839
        SDistinctDataInfo* pDistDataInfo = taosArrayGet(pInfo->pDistinctDataInfo, i);
        char*              tmp = taosMemoryRealloc(pResultColInfoData->pData, newSize * pDistDataInfo->bytes);
6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855
        if (tmp == NULL) {
          return NULL;
        } else {
          pResultColInfoData->pData = tmp;
        }
      }
      pInfo->outputCapacity = newSize;
    }

    for (int32_t i = 0; i < pBlock->info.rows; i++) {
      buildMultiDistinctKey(pInfo, pBlock, i);
      if (taosHashGet(pInfo->pSet, pInfo->buf, pInfo->totalBytes) == NULL) {
        int32_t dummy;
        taosHashPut(pInfo->pSet, pInfo->buf, pInfo->totalBytes, &dummy, sizeof(dummy));
        for (int j = 0; j < taosArrayGetSize(pRes->pDataBlock); j++) {
          SDistinctDataInfo* pDistDataInfo = taosArrayGet(pInfo->pDistinctDataInfo, j);  // distinct meta info
L
Liu Jicong 已提交
6856 6857
          SColumnInfoData*   pColInfoData = taosArrayGet(pBlock->pDataBlock, pDistDataInfo->index);  // src
          SColumnInfoData*   pResultColInfoData = taosArrayGet(pRes->pDataBlock, j);                 // dist
6858 6859

          char* val = ((char*)pColInfoData->pData) + pDistDataInfo->bytes * i;
L
Liu Jicong 已提交
6860
          char* start = pResultColInfoData->pData + pDistDataInfo->bytes * pInfo->pRes->info.rows;
6861 6862 6863
          memcpy(start, val, pDistDataInfo->bytes);
        }
        pRes->info.rows += 1;
L
Liu Jicong 已提交
6864
      }
6865 6866 6867 6868 6869 6870
    }

    if (pRes->info.rows >= pInfo->threshold) {
      break;
    }
  }
L
Liu Jicong 已提交
6871
  return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
6872 6873
}

H
Haojun Liao 已提交
6874
SOperatorInfo* createDistinctOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo) {
wafwerar's avatar
wafwerar 已提交
6875
  SDistinctOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SDistinctOperatorInfo));
H
Haojun Liao 已提交
6876 6877 6878 6879 6880 6881 6882 6883
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));

  pOperator->resultInfo.capacity = 4096;  // todo extract function.

  pInfo->totalBytes        = 0;
  pInfo->buf               = NULL;

  pInfo->pDistinctDataInfo = taosArrayInit(numOfCols, sizeof(SDistinctDataInfo));
6884 6885
  pInfo->pSet = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);

H
Haojun Liao 已提交
6886 6887 6888 6889 6890 6891 6892 6893 6894
  pOperator->name         = "DistinctOperator";
  pOperator->blockingOptr = true;
  pOperator->status       = OP_NOT_OPENED;
//  pOperator->operatorType = DISTINCT;
  pOperator->pExpr        = pExpr;
  pOperator->numOfOutput  = numOfCols;
  pOperator->info         = pInfo;
  pOperator->getNextFn    = hashDistinct;
  pOperator->closeFn      = destroyDistinctOperatorInfo;
6895

L
Liu Jicong 已提交
6896
  int32_t code = appendDownstream(pOperator, &downstream, 1);
6897 6898 6899
  return pOperator;
}

L
Liu Jicong 已提交
6900
static int32_t getColumnIndexInSource(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6901 6902
  int32_t j = 0;

H
Haojun Liao 已提交
6903 6904
  if (TSDB_COL_IS_TAG(pExpr->pParam[0].pCol->type)) {
    if (pExpr->pParam[0].pCol->colId == TSDB_TBNAME_COLUMN_INDEX) {
6905 6906 6907
      return TSDB_TBNAME_COLUMN_INDEX;
    }

L
Liu Jicong 已提交
6908
    while (j < pTableInfo->numOfTags) {
H
Haojun Liao 已提交
6909
      if (pExpr->pParam[0].pCol->colId == pTagCols[j].colId) {
6910 6911 6912 6913 6914 6915
        return j;
      }

      j += 1;
    }

6916
  } /*else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {  // user specified column data
6917 6918 6919 6920 6921 6922 6923 6924 6925
    return TSDB_UD_COLUMN_INDEX;
  } else {
    while (j < pTableInfo->numOfCols) {
      if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) {
        return j;
      }

      j += 1;
    }
6926
  }*/
6927 6928 6929 6930

  return INT32_MIN;  // return a less than TSDB_TBNAME_COLUMN_INDEX value
}

L
Liu Jicong 已提交
6931
bool validateExprColumnInfo(SQueriedTableInfo* pTableInfo, SExprBasicInfo* pExpr, SColumnInfo* pTagCols) {
6932 6933 6934 6935 6936 6937
  int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols);
  return j != INT32_MIN;
}

static int32_t deserializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t numOfFilters, char** pMsg) {
  for (int32_t f = 0; f < numOfFilters; ++f) {
L
Liu Jicong 已提交
6938
    SColumnFilterInfo* pFilterMsg = (SColumnFilterInfo*)(*pMsg);
6939

L
Liu Jicong 已提交
6940
    SColumnFilterInfo* pColFilter = &pColFilters[f];
6941 6942 6943 6944 6945 6946 6947
    pColFilter->filterstr = htons(pFilterMsg->filterstr);

    (*pMsg) += sizeof(SColumnFilterInfo);

    if (pColFilter->filterstr) {
      pColFilter->len = htobe64(pFilterMsg->len);

L
Liu Jicong 已提交
6948 6949
      pColFilter->pz =
          (int64_t)taosMemoryCalloc(1, (size_t)(pColFilter->len + 1 * TSDB_NCHAR_SIZE));  // note: null-terminator
6950 6951 6952 6953
      if (pColFilter->pz == 0) {
        return TSDB_CODE_QRY_OUT_OF_MEMORY;
      }

L
Liu Jicong 已提交
6954
      memcpy((void*)pColFilter->pz, (*pMsg), (size_t)pColFilter->len);
6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967
      (*pMsg) += (pColFilter->len + 1);
    } else {
      pColFilter->lowerBndi = htobe64(pFilterMsg->lowerBndi);
      pColFilter->upperBndi = htobe64(pFilterMsg->upperBndi);
    }

    pColFilter->lowerRelOptr = htons(pFilterMsg->lowerRelOptr);
    pColFilter->upperRelOptr = htons(pFilterMsg->upperRelOptr);
  }

  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
6968 6969
static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, int32_t scale, int32_t precision,
                                  const char* name) {
H
Haojun Liao 已提交
6970 6971
  SResSchema s = {0};
  s.scale = scale;
L
Liu Jicong 已提交
6972
  s.type = type;
H
Haojun Liao 已提交
6973 6974
  s.bytes = bytes;
  s.colId = slotId;
H
Haojun Liao 已提交
6975
  s.precision = precision;
H
Haojun Liao 已提交
6976 6977 6978 6979
  strncpy(s.name, name, tListLen(s.name));

  return s;
}
H
Haojun Liao 已提交
6980

H
Haojun Liao 已提交
6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997
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;
  }

  pCol->slotId      = slotId;
  pCol->bytes       = pType->bytes;
  pCol->type        = pType->type;
  pCol->scale       = pType->scale;
  pCol->precision   = pType->precision;
  pCol->dataBlockId = blockId;

  return pCol;
}

H
Haojun Liao 已提交
6998
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs) {
H
Haojun Liao 已提交
6999
  int32_t numOfFuncs = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
7000 7001 7002 7003
  int32_t numOfGroupKeys = 0;
  if (pGroupKeys != NULL) {
    numOfGroupKeys = LIST_LENGTH(pGroupKeys);
  }
H
Haojun Liao 已提交
7004

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

L
Liu Jicong 已提交
7008
  for (int32_t i = 0; i < (*numOfExprs); ++i) {
H
Haojun Liao 已提交
7009 7010 7011 7012 7013 7014
    STargetNode* pTargetNode = NULL;
    if (i < numOfFuncs) {
      pTargetNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    } else {
      pTargetNode = (STargetNode*)nodesListGetNode(pGroupKeys, i - numOfFuncs);
    }
H
Haojun Liao 已提交
7015

H
Haojun Liao 已提交
7016
    SExprInfo* pExp = &pExprs[pTargetNode->slotId];
H
Haojun Liao 已提交
7017

wafwerar's avatar
wafwerar 已提交
7018
    pExp->pExpr = taosMemoryCalloc(1, sizeof(tExprNode));
H
Haojun Liao 已提交
7019
    pExp->pExpr->_function.num = 1;
H
Haojun Liao 已提交
7020
    pExp->pExpr->_function.functionId = -1;
H
Haojun Liao 已提交
7021

H
Haojun Liao 已提交
7022
    // it is a project query, or group by column
H
Haojun Liao 已提交
7023
    if (nodeType(pTargetNode->pExpr) == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
7024
      pExp->pExpr->nodeType = QUERY_NODE_COLUMN;
L
Liu Jicong 已提交
7025
      SColumnNode* pColNode = (SColumnNode*)pTargetNode->pExpr;
H
Haojun Liao 已提交
7026

G
Ganlin Zhao 已提交
7027 7028 7029
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

H
Haojun Liao 已提交
7030 7031
      SDataType* pType = &pColNode->node.resType;
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale, pType->precision, pColNode->colName);
H
Haojun Liao 已提交
7032 7033
      pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pType);
      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
7034
    } else if (nodeType(pTargetNode->pExpr) == QUERY_NODE_FUNCTION) {
H
Haojun Liao 已提交
7035
      pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
H
Haojun Liao 已提交
7036 7037 7038
      SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;

      SDataType* pType = &pFuncNode->node.resType;
L
Liu Jicong 已提交
7039 7040
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
                                             pType->precision, pFuncNode->node.aliasName);
H
Haojun Liao 已提交
7041

H
Haojun Liao 已提交
7042
      pExp->pExpr->_function.functionId = pFuncNode->funcId;
H
Haojun Liao 已提交
7043
      pExp->pExpr->_function.pFunctNode = pFuncNode;
H
Haojun Liao 已提交
7044
      strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName, tListLen(pExp->pExpr->_function.functionName));
H
Haojun Liao 已提交
7045 7046 7047

      // TODO: value parameter needs to be handled
      int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList);
G
Ganlin Zhao 已提交
7048 7049 7050 7051

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

H
Haojun Liao 已提交
7052 7053
      for (int32_t j = 0; j < numOfParam; ++j) {
        SNode*       p1 = nodesListGetNode(pFuncNode->pParameterList, j);
G
Ganlin Zhao 已提交
7054
        if (p1->type == QUERY_NODE_COLUMN) {
H
Haojun Liao 已提交
7055
          SColumnNode* pcn = (SColumnNode*) p1;
G
Ganlin Zhao 已提交
7056 7057

          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
H
Haojun Liao 已提交
7058
          pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, &pcn->node.resType);
G
Ganlin Zhao 已提交
7059 7060 7061 7062
        } else if (p1->type == QUERY_NODE_VALUE) {
          SValueNode* pvn = (SValueNode*)p1;
          pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
        }
H
Haojun Liao 已提交
7063
      }
7064
    } else if (nodeType(pTargetNode->pExpr) == QUERY_NODE_OPERATOR) {
H
Haojun Liao 已提交
7065
      pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
L
Liu Jicong 已提交
7066
      SOperatorNode* pNode = (SOperatorNode*)pTargetNode->pExpr;
7067

G
Ganlin Zhao 已提交
7068 7069 7070
      pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
      pExp->base.numOfParams = 1;

7071
      SDataType* pType = &pNode->node.resType;
H
Haojun Liao 已提交
7072
      pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale, pType->precision, pNode->node.aliasName);
7073 7074 7075

      pExp->pExpr->_optrRoot.pRootNode = pTargetNode->pExpr;

H
Haojun Liao 已提交
7076 7077
//      pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
//      pExp->base.pParam[0].pCol = createColumn(pTargetNode->dataBlockId, pTargetNode->slotId, pType);
7078 7079
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
7080 7081 7082
    }
  }

H
Haojun Liao 已提交
7083
  return pExprs;
H
Haojun Liao 已提交
7084 7085
}

7086
static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPTR_EXEC_MODEL model) {
wafwerar's avatar
wafwerar 已提交
7087
  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
7088
  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
H
Haojun Liao 已提交
7089

7090
  pTaskInfo->cost.created = taosGetTimestampMs();
H
Haojun Liao 已提交
7091
  pTaskInfo->id.queryId = queryId;
7092
  pTaskInfo->execModel  = model;
H
Haojun Liao 已提交
7093

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

7098 7099
  return pTaskInfo;
}
H
Haojun Liao 已提交
7100

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

L
Liu Jicong 已提交
7104 7105
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
                                  uint64_t queryId, uint64_t taskId);
7106 7107
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
static SArray* extractScanColumnId(SNodeList* pNodeList);
H
Haojun Liao 已提交
7108
static SArray* extractColumnInfo(SNodeList* pNodeList);
H
Haojun Liao 已提交
7109
static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols);
H
Haojun Liao 已提交
7110
static SArray* createSortInfo(SNodeList* pNodeList);
H
Haojun Liao 已提交
7111

H
Haojun Liao 已提交
7112
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
L
Liu Jicong 已提交
7113
                                        uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) {
X
Xiaoyu Wang 已提交
7114 7115 7116
  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == nodeType(pPhyNode)) {
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
7117

H
Haojun Liao 已提交
7118
      int32_t     numOfCols = 0;
H
Haojun Liao 已提交
7119 7120
      tsdbReaderT pDataReader = doCreateDataReader((STableScanPhysiNode*)pPhyNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
      SArray* pColList = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
H
Haojun Liao 已提交
7121

L
Liu Jicong 已提交
7122
      return createTableScanOperatorInfo(pDataReader, pScanPhyNode->order, numOfCols, pScanPhyNode->count,
H
Haojun Liao 已提交
7123
                                         pScanPhyNode->reverse, pColList, pScanPhyNode->node.pConditions, pTaskInfo);
X
Xiaoyu Wang 已提交
7124
    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == nodeType(pPhyNode)) {
H
Haojun Liao 已提交
7125
      SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode;
L
Liu Jicong 已提交
7126
      SSDataBlock*        pResBlock = createOutputBuf_rv1(pExchange->node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
7127
      return createExchangeOperatorInfo(pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
X
Xiaoyu Wang 已提交
7128
    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == nodeType(pPhyNode)) {
H
Haojun Liao 已提交
7129
      SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode;  // simple child table.
7130

L
Liu Jicong 已提交
7131 7132
      int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo,
                                        queryId, taskId);
H
Haojun Liao 已提交
7133
      SArray* tableIdList = extractTableIdList(pTableGroupInfo);
H
Haojun Liao 已提交
7134

7135
      SSDataBlock* pResBlock = createOutputBuf_rv1(pScanPhyNode->node.pOutputDataBlockDesc);
7136 7137 7138 7139

      int32_t numOfCols = 0;
      SArray* pColList = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
      SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pColList, tableIdList, pTaskInfo);
7140
      taosArrayDestroy(tableIdList);
H
Haojun Liao 已提交
7141
      return pOperator;
H
Haojun Liao 已提交
7142
    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == nodeType(pPhyNode)) {
L
Liu Jicong 已提交
7143 7144
      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
      SSDataBlock*               pResBlock = createOutputBuf_rv1(pSysScanPhyNode->scan.node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
7145

7146
      struct SScanPhysiNode* pScanNode = &pSysScanPhyNode->scan;
L
Liu Jicong 已提交
7147
      SArray*                colList = extractScanColumnId(pScanNode->pScanCols);
7148

L
Liu Jicong 已提交
7149 7150 7151
      SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
          pHandle->meta, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
          colList, pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
H
Haojun Liao 已提交
7152 7153 7154
      return pOperator;
    } else {
      ASSERT(0);
H
Haojun Liao 已提交
7155 7156 7157
    }
  }

H
Haojun Liao 已提交
7158 7159 7160 7161
  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == nodeType(pPhyNode)) {
    size_t size = LIST_LENGTH(pPhyNode->pChildren);
    assert(size == 1);

H
Haojun Liao 已提交
7162
    SPhysiNode*    pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, 0);
H
Haojun Liao 已提交
7163
    SOperatorInfo* op = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
H
Haojun Liao 已提交
7164

L
Liu Jicong 已提交
7165
    int32_t      num = 0;
H
Haojun Liao 已提交
7166 7167 7168
    SProjectPhysiNode* pProjPhyNode = (SProjectPhysiNode*) pPhyNode;
    SExprInfo*   pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &num);

H
Haojun Liao 已提交
7169
    SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
7170 7171 7172
    SLimit limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};

    return createProjectOperatorInfo(op, pExprInfo, num, pResBlock, &limit, pTaskInfo);
H
Haojun Liao 已提交
7173
  } else if (QUERY_NODE_PHYSICAL_PLAN_AGG == nodeType(pPhyNode)) {
X
Xiaoyu Wang 已提交
7174
    size_t size = LIST_LENGTH(pPhyNode->pChildren);
H
Haojun Liao 已提交
7175 7176
    assert(size == 1);

H
Haojun Liao 已提交
7177
    for (int32_t i = 0; i < size; ++i) {
H
Haojun Liao 已提交
7178
      SPhysiNode*    pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
H
Haojun Liao 已提交
7179
      SOperatorInfo* op = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
H
Haojun Liao 已提交
7180

H
Haojun Liao 已提交
7181
      int32_t num = 0;
H
Haojun Liao 已提交
7182 7183

      SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
L
Liu Jicong 已提交
7184 7185
      SExprInfo*     pExprInfo = createExprInfo(pAggNode->pAggFuncs, pAggNode->pGroupKeys, &num);
      SSDataBlock*   pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc);
H
Haojun Liao 已提交
7186 7187 7188 7189 7190 7191 7192

      if (pAggNode->pGroupKeys != NULL) {
        SArray* pColList = extractColumnInfo(pAggNode->pGroupKeys);
        return createGroupOperatorInfo(op, pExprInfo, num, pResBlock, pColList, pTaskInfo, NULL);
      } else {
        return createAggregateOperatorInfo(op, pExprInfo, num, pResBlock, pTaskInfo, pTableGroupInfo);
      }
H
Haojun Liao 已提交
7193
    }
H
Haojun Liao 已提交
7194 7195 7196 7197 7198 7199
  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERVAL == nodeType(pPhyNode)) {
    size_t size = LIST_LENGTH(pPhyNode->pChildren);
    assert(size == 1);

    for (int32_t i = 0; i < size; ++i) {
      SPhysiNode*    pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
H
Haojun Liao 已提交
7200
      SOperatorInfo* op = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
H
Haojun Liao 已提交
7201

7202 7203
      SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;

L
Liu Jicong 已提交
7204 7205 7206
      // todo: set the correct primary timestamp key column
      int32_t      num = 0;
      SExprInfo*   pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
H
Haojun Liao 已提交
7207
      SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc);
7208

H
Haojun Liao 已提交
7209 7210
      SInterval interval = {.interval     = pIntervalPhyNode->interval,
                            .sliding      = pIntervalPhyNode->sliding,
H
Haojun Liao 已提交
7211
                            .intervalUnit = pIntervalPhyNode->intervalUnit,
H
Haojun Liao 已提交
7212 7213
                            .slidingUnit  = pIntervalPhyNode->slidingUnit,
                            .offset       = pIntervalPhyNode->offset,
7214
                            .precision    = TSDB_TIME_PRECISION_MILLI};
7215
      return createIntervalOperatorInfo(op, pExprInfo, num, pResBlock, &interval, pTableGroupInfo, pTaskInfo);
H
Haojun Liao 已提交
7216
    }
H
Haojun Liao 已提交
7217 7218 7219 7220
  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == nodeType(pPhyNode)) {
    size_t size = LIST_LENGTH(pPhyNode->pChildren);
    assert(size == 1);

H
Haojun Liao 已提交
7221
    SPhysiNode*    pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, 0);
H
Haojun Liao 已提交
7222
    SOperatorInfo* op = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
H
Haojun Liao 已提交
7223

H
Haojun Liao 已提交
7224
    SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
H
Haojun Liao 已提交
7225

H
Haojun Liao 已提交
7226 7227
    SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc);
    SArray*      info = createSortInfo(pSortPhyNode->pSortKeys);
H
Haojun Liao 已提交
7228
    return createSortOperatorInfo(op, pResBlock, info, pTaskInfo);
H
Haojun Liao 已提交
7229 7230 7231 7232 7233
  } else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == nodeType(pPhyNode)) {
    size_t size = LIST_LENGTH(pPhyNode->pChildren);
    assert(size == 1);

    SPhysiNode*    pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, 0);
H
Haojun Liao 已提交
7234
    SOperatorInfo* op = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
H
Haojun Liao 已提交
7235 7236 7237 7238 7239 7240 7241

    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;

    int32_t      num = 0;
    SExprInfo*   pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &num);
    SSDataBlock* pResBlock = createOutputBuf_rv1(pPhyNode->pOutputDataBlockDesc);
    return createSessionAggOperatorInfo(op, pExprInfo, num, pResBlock, pSessionNode->gap, pTaskInfo);
H
Haojun Liao 已提交
7242 7243
  } else {
    ASSERT(0);
L
Liu Jicong 已提交
7244 7245 7246 7247 7248 7249
  } /*else if (pPhyNode->info.type == OP_MultiTableAggregate) {
     size_t size = taosArrayGetSize(pPhyNode->pChildren);
     assert(size == 1);

     for (int32_t i = 0; i < size; ++i) {
       SPhysiNode*      pChildNode = taosArrayGetP(pPhyNode->pChildren, i);
H
Haojun Liao 已提交
7250
       SOperatorInfo* op = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableGroupInfo);
L
Liu Jicong 已提交
7251 7252 7253
       return createMultiTableAggOperatorInfo(op, pPhyNode->pTargets, pTaskInfo, pTableGroupInfo);
     }
   }*/
7254
}
H
Haojun Liao 已提交
7255

L
Liu Jicong 已提交
7256 7257
static tsdbReaderT createDataReaderImpl(STableScanPhysiNode* pTableScanNode, STableGroupInfo* pGroupInfo,
                                        void* readHandle, uint64_t queryId, uint64_t taskId) {
H
Haojun Liao 已提交
7258
  STsdbQueryCond cond = {.loadExternalRows = false};
H
Haojun Liao 已提交
7259

L
Liu Jicong 已提交
7260
  cond.order = pTableScanNode->scan.order;
X
Xiaoyu Wang 已提交
7261
  cond.numOfCols = LIST_LENGTH(pTableScanNode->scan.pScanCols);
L
Liu Jicong 已提交
7262
  cond.colList = taosMemoryCalloc(cond.numOfCols, sizeof(SColumnInfo));
H
Haojun Liao 已提交
7263 7264 7265 7266 7267
  if (cond.colList == NULL) {
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return NULL;
  }

X
Xiaoyu Wang 已提交
7268
  cond.twindow = pTableScanNode->scanRange;
H
Haojun Liao 已提交
7269
  cond.type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
L
Liu Jicong 已提交
7270
  //  cond.type = pTableScanNode->scanFlag;
H
Haojun Liao 已提交
7271

H
Haojun Liao 已提交
7272
  int32_t j = 0;
H
Haojun Liao 已提交
7273
  for (int32_t i = 0; i < cond.numOfCols; ++i) {
H
Haojun Liao 已提交
7274 7275
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pTableScanNode->scan.pScanCols, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
7276 7277 7278
    if (pColNode->colType == COLUMN_TYPE_TAG) {
      continue;
    }
H
Haojun Liao 已提交
7279

L
Liu Jicong 已提交
7280
    cond.colList[j].type = pColNode->node.resType.type;
H
Haojun Liao 已提交
7281 7282 7283
    cond.colList[j].bytes = pColNode->node.resType.bytes;
    cond.colList[j].colId = pColNode->colId;
    j += 1;
H
Haojun Liao 已提交
7284 7285
  }

H
Haojun Liao 已提交
7286
  cond.numOfCols = j;
H
Haojun Liao 已提交
7287
  return tsdbQueryTables(readHandle, &cond, pGroupInfo, queryId, taskId);
H
Haojun Liao 已提交
7288
}
H
Haojun Liao 已提交
7289

7290
SArray* extractScanColumnId(SNodeList* pNodeList) {
L
Liu Jicong 已提交
7291
  size_t  numOfCols = LIST_LENGTH(pNodeList);
7292 7293 7294 7295 7296 7297
  SArray* pList = taosArrayInit(numOfCols, sizeof(int16_t));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
7298
  for (int32_t i = 0; i < numOfCols; ++i) {
X
Xiaoyu Wang 已提交
7299
    for (int32_t j = 0; j < numOfCols; ++j) {
L
Liu Jicong 已提交
7300
      STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, j);
X
Xiaoyu Wang 已提交
7301
      if (pNode->slotId == i) {
L
Liu Jicong 已提交
7302
        SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
X
Xiaoyu Wang 已提交
7303 7304 7305 7306
        taosArrayPush(pList, &pColNode->colId);
        break;
      }
    }
7307 7308 7309 7310 7311
  }

  return pList;
}

H
Haojun Liao 已提交
7312
SArray* extractColumnInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
7313
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
7314 7315 7316 7317 7318 7319
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
7320 7321 7322
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
7323 7324 7325

    SColumn c = {0};
    c.slotId = pColNode->slotId;
L
Liu Jicong 已提交
7326 7327 7328 7329 7330
    c.colId = pColNode->colId;
    c.type = pColNode->node.resType.type;
    c.bytes = pColNode->node.resType.bytes;
    c.precision = pColNode->node.resType.precision;
    c.scale = pColNode->node.resType.scale;
H
Haojun Liao 已提交
7331 7332 7333 7334 7335 7336 7337

    taosArrayPush(pList, &c);
  }

  return pList;
}

H
Haojun Liao 已提交
7338
SArray* createSortInfo(SNodeList* pNodeList) {
L
Liu Jicong 已提交
7339
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
7340 7341 7342 7343 7344 7345
  SArray* pList = taosArrayInit(numOfCols, sizeof(SBlockOrderInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return pList;
  }

L
Liu Jicong 已提交
7346 7347 7348 7349 7350
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode*      pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SOrderByExprNode* pSortKey = (SOrderByExprNode*)pNode->pExpr;
    SBlockOrderInfo   bi = {0};
    bi.order = (pSortKey->order == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
H
Haojun Liao 已提交
7351 7352 7353 7354
    bi.nullFirst = (pSortKey->nullOrder == NULL_ORDER_FIRST);

    SColumnNode* pColNode = (SColumnNode*)pSortKey->pExpr;
    bi.slotId = pColNode->slotId;
L
Liu Jicong 已提交
7355 7356 7357 7358 7359 7360 7361 7362
    //    pColNode->order;
    //    SColumn c = {0};
    //    c.slotId = pColNode->slotId;
    //    c.colId  = pColNode->colId;
    //    c.type   = pColNode->node.resType.type;
    //    c.bytes  = pColNode->node.resType.bytes;
    //    c.precision  = pColNode->node.resType.precision;
    //    c.scale  = pColNode->node.resType.scale;
H
Haojun Liao 已提交
7363 7364 7365 7366 7367 7368 7369

    taosArrayPush(pList, &bi);
  }

  return pList;
}

H
Haojun Liao 已提交
7370
SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols) {
L
Liu Jicong 已提交
7371
  size_t  numOfCols = LIST_LENGTH(pNodeList);
H
Haojun Liao 已提交
7372 7373 7374 7375 7376 7377
  SArray* pList = taosArrayInit(numOfCols, sizeof(SColMatchInfo));
  if (pList == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

L
Liu Jicong 已提交
7378 7379 7380
  for (int32_t i = 0; i < numOfCols; ++i) {
    STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
H
Haojun Liao 已提交
7381 7382

    SColMatchInfo c = {0};
L
Liu Jicong 已提交
7383
    c.colId = pColNode->colId;
H
Haojun Liao 已提交
7384
    c.targetSlotId = pNode->slotId;
L
Liu Jicong 已提交
7385
    c.output = true;
H
Haojun Liao 已提交
7386 7387 7388
    taosArrayPush(pList, &c);
  }

H
Haojun Liao 已提交
7389 7390 7391
  *numOfOutputCols = 0;

  int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
L
Liu Jicong 已提交
7392 7393
  for (int32_t i = 0; i < num; ++i) {
    SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
H
Haojun Liao 已提交
7394
    SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
H
Haojun Liao 已提交
7395 7396 7397 7398 7399
    if (pNode->output) {
      (*numOfOutputCols) += 1;
    } else {
      info->output = false;
    }
H
Haojun Liao 已提交
7400 7401
  }

H
Haojun Liao 已提交
7402 7403 7404
  return pList;
}

H
Haojun Liao 已提交
7405
int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo, uint64_t queryId, uint64_t taskId) {
7406
  int32_t code = 0;
H
Haojun Liao 已提交
7407
  if (tableType == TSDB_SUPER_TABLE) {
H
Haojun Liao 已提交
7408
    code = tsdbQuerySTableByTagCond(metaHandle, tableUid, 0, NULL, 0, 0, NULL, pGroupInfo, NULL, 0, queryId, taskId);
H
Haojun Liao 已提交
7409
  } else {  // Create one table group.
H
Haojun Liao 已提交
7410
    code = tsdbGetOneTableGroup(metaHandle, tableUid, 0, pGroupInfo);
7411 7412 7413 7414
  }

  return code;
}
H
Haojun Liao 已提交
7415

7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433
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 已提交
7434 7435
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
                               STableGroupInfo* pTableGroupInfo, uint64_t queryId, uint64_t taskId) {
7436
  uint64_t uid = pTableScanNode->scan.uid;
L
Liu Jicong 已提交
7437 7438
  int32_t  code =
      doCreateTableGroup(pHandle->meta, pTableScanNode->scan.tableType, uid, pTableGroupInfo, queryId, taskId);
7439 7440
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
H
Haojun Liao 已提交
7441
  }
H
Haojun Liao 已提交
7442

H
Haojun Liao 已提交
7443
  if (pTableGroupInfo->numOfTables == 0) {
H
Haojun Liao 已提交
7444
    code = 0;
L
Liu Jicong 已提交
7445
    qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
H
Haojun Liao 已提交
7446 7447
    goto _error;
  }
H
Haojun Liao 已提交
7448

H
Haojun Liao 已提交
7449
  return createDataReaderImpl(pTableScanNode, pTableGroupInfo, pHandle->reader, queryId, taskId);
H
Haojun Liao 已提交
7450

L
Liu Jicong 已提交
7451
_error:
H
Haojun Liao 已提交
7452 7453 7454 7455
  terrno = code;
  return NULL;
}

7456
int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId, EOPTR_EXEC_MODEL model) {
H
Haojun Liao 已提交
7457 7458
  uint64_t queryId = pPlan->id.queryId;

H
Haojun Liao 已提交
7459
  int32_t code = TSDB_CODE_SUCCESS;
7460
  *pTaskInfo = createExecTaskInfo(queryId, taskId, model);
H
Haojun Liao 已提交
7461 7462 7463 7464
  if (*pTaskInfo == NULL) {
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
    goto _complete;
  }
H
Haojun Liao 已提交
7465

H
Haojun Liao 已提交
7466
  STableGroupInfo group = {0};
H
Haojun Liao 已提交
7467
  (*pTaskInfo)->pRoot = createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &group);
D
dapan1121 已提交
7468
  if (NULL == (*pTaskInfo)->pRoot) {
L
Liu Jicong 已提交
7469
    code = terrno;
D
dapan1121 已提交
7470 7471
    goto _complete;
  }
H
Haojun Liao 已提交
7472

7473
  if ((*pTaskInfo)->pRoot == NULL) {
H
Haojun Liao 已提交
7474
    code = TSDB_CODE_QRY_OUT_OF_MEMORY;
H
Haojun Liao 已提交
7475
    goto _complete;
7476 7477
  }

H
Haojun Liao 已提交
7478 7479
  return code;

H
Haojun Liao 已提交
7480
_complete:
wafwerar's avatar
wafwerar 已提交
7481
  taosMemoryFreeClear(*pTaskInfo);
H
Haojun Liao 已提交
7482 7483 7484

  terrno = code;
  return code;
H
Haojun Liao 已提交
7485 7486
}

L
Liu Jicong 已提交
7487 7488
static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SColumnInfo* pTagCols, SExprInfo* pExprs,
                                             int32_t numOfOutput, int32_t tagLen, bool superTable) {
7489 7490 7491 7492 7493 7494 7495 7496 7497
  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 已提交
7498 7499 7500 7501
        //        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);
7502 7503 7504 7505 7506 7507 7508
      }
    }
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
7509
void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo) {
7510 7511 7512 7513 7514 7515 7516 7517
  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;

H
Haojun Liao 已提交
7518 7519 7520 7521 7522 7523 7524 7525 7526 7527
//  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;
//  }
7528 7529

  pResultInfo->threshold = (int32_t)(pResultInfo->capacity * THRESHOLD_RATIO);
H
Haojun Liao 已提交
7530
  pResultInfo->totalRows = 0;
7531 7532
}

L
Liu Jicong 已提交
7533
// TODO refactor
7534
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
L
Liu Jicong 已提交
7535 7536 7537
  if (pFilter == NULL || numOfFilters == 0) {
    return;
  }
7538

L
Liu Jicong 已提交
7539 7540 7541
  for (int32_t i = 0; i < numOfFilters; i++) {
    if (pFilter[i].filterstr && pFilter[i].pz) {
      taosMemoryFree((void*)(pFilter[i].pz));
7542
    }
L
Liu Jicong 已提交
7543
  }
7544

L
Liu Jicong 已提交
7545
  taosMemoryFree(pFilter);
7546 7547 7548 7549
}

static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) {
  if (pTableqinfoGroupInfo->pGroupList != NULL) {
L
Liu Jicong 已提交
7550
    int32_t numOfGroups = (int32_t)taosArrayGetSize(pTableqinfoGroupInfo->pGroupList);
7551
    for (int32_t i = 0; i < numOfGroups; ++i) {
L
Liu Jicong 已提交
7552
      SArray* p = taosArrayGetP(pTableqinfoGroupInfo->pGroupList, i);
7553 7554

      size_t num = taosArrayGetSize(p);
L
Liu Jicong 已提交
7555
      for (int32_t j = 0; j < num; ++j) {
7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571
        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 已提交
7572
void doDestroyTask(SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
7573 7574
  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));

H
Haojun Liao 已提交
7575
  doDestroyTableQueryInfo(&pTaskInfo->tableqinfoGroupInfo);
L
Liu Jicong 已提交
7576 7577
  //  taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
  //  taosHashCleanup(pTaskInfo->summary.operatorProfResults);
7578

wafwerar's avatar
wafwerar 已提交
7579 7580 7581
  taosMemoryFreeClear(pTaskInfo->sql);
  taosMemoryFreeClear(pTaskInfo->id.str);
  taosMemoryFreeClear(pTaskInfo);
7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593
}

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 已提交
7594
      int32_t len = (varDataLen(val) > maxLen) ? maxLen : varDataLen(val);
7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606
      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 已提交
7607 7608
  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
  return (int64_t)(s1 * 1.5 * numOfTables);
7609 7610 7611 7612 7613 7614 7615
}

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 已提交
7616
    while (1) {
7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642
      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);
}