tsdbRead.c 140.1 KB
Newer Older
H
hjxilinx 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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/>.
 */

H
Hongze Cheng 已提交
16
#include "tsdb.h"
17

dengyihao's avatar
dengyihao 已提交
18 19
#define EXTRA_BYTES                2
#define ASCENDING_TRAVERSE(o)      (o == TSDB_ORDER_ASC)
20
#define QH_GET_NUM_OF_COLS(handle) ((size_t)(taosArrayGetSize((handle)->pColumns)))
H
hjxilinx 已提交
21

H
Haojun Liao 已提交
22 23 24 25
#define GET_FILE_DATA_BLOCK_INFO(_checkInfo, _block)                                   \
  ((SDataBlockInfo){.window = {.skey = (_block)->keyFirst, .ekey = (_block)->keyLast}, \
                    .numOfCols = (_block)->numOfCols,                                  \
                    .rows = (_block)->numOfRows,                                       \
26
                    .uid = (_checkInfo)->tableId})
H
Haojun Liao 已提交
27

H
hjxilinx 已提交
28
enum {
dengyihao's avatar
dengyihao 已提交
29 30
  TSDB_QUERY_TYPE_ALL = 1,
  TSDB_QUERY_TYPE_LAST = 2,
H
hjxilinx 已提交
31 32
};

33
enum {
dengyihao's avatar
dengyihao 已提交
34
  TSDB_CACHED_TYPE_NONE = 0,
35
  TSDB_CACHED_TYPE_LASTROW = 1,
dengyihao's avatar
dengyihao 已提交
36
  TSDB_CACHED_TYPE_LAST = 2,
37 38
};

39
typedef struct SQueryFilePos {
dengyihao's avatar
dengyihao 已提交
40 41 42 43 44 45 46
  int32_t     fid;
  int32_t     slot;
  int32_t     pos;
  int64_t     lastKey;
  int32_t     rows;
  bool        mixBlock;
  bool        blockCompleted;
47
  STimeWindow win;
48
} SQueryFilePos;
H
hjxilinx 已提交
49

50
typedef struct SDataBlockLoadInfo {
dengyihao's avatar
dengyihao 已提交
51 52 53 54
  SDFileSet* fileGroup;
  int32_t    slot;
  uint64_t   uid;
  SArray*    pLoadedCols;
55
} SDataBlockLoadInfo;
H
hjxilinx 已提交
56

57
typedef struct SLoadCompBlockInfo {
H
hjLiao 已提交
58
  int32_t tid; /* table tid */
59 60
  int32_t fileId;
} SLoadCompBlockInfo;
H
hjxilinx 已提交
61

62
enum {
dengyihao's avatar
dengyihao 已提交
63
  CHECKINFO_CHOSEN_MEM = 0,
64
  CHECKINFO_CHOSEN_IMEM = 1,
dengyihao's avatar
dengyihao 已提交
65
  CHECKINFO_CHOSEN_BOTH = 2  // for update=2(merge case)
66 67
};

68
typedef struct STableCheckInfo {
dengyihao's avatar
dengyihao 已提交
69 70 71 72 73 74 75 76 77
  uint64_t           tableId;
  TSKEY              lastKey;
  SBlockInfo*        pCompInfo;
  int32_t            compSize;
  int32_t            numOfBlocks : 29;  // number of qualified data blocks not the original blocks
  uint8_t            chosen : 2;        // indicate which iterator should move forward
  bool               initBuf : 1;       // whether to initialize the in-memory skip list iterator or not
  SSkipListIterator* iter;              // mem buffer skip list iterator
  SSkipListIterator* iiter;             // imem buffer skip list iterator
78
} STableCheckInfo;
79

80
typedef struct STableBlockInfo {
dengyihao's avatar
dengyihao 已提交
81 82
  SBlock*          compBlock;
  STableCheckInfo* pTableCheckInfo;
83
} STableBlockInfo;
84

85
typedef struct SBlockOrderSupporter {
dengyihao's avatar
dengyihao 已提交
86 87 88 89
  int32_t           numOfTables;
  STableBlockInfo** pDataBlockInfo;
  int32_t*          blockIndexArray;
  int32_t*          numOfBlocksPerTable;
90 91
} SBlockOrderSupporter;

H
Haojun Liao 已提交
92 93 94
typedef struct SIOCostSummary {
  int64_t blockLoadTime;
  int64_t statisInfoLoadTime;
H
Haojun Liao 已提交
95
  int64_t checkForNextTime;
96 97
  int64_t headFileLoad;
  int64_t headFileLoadTime;
H
Haojun Liao 已提交
98 99
} SIOCostSummary;

100
typedef struct STsdbReadHandle {
H
Hongze Cheng 已提交
101 102 103 104
  STsdb*          pTsdb;
  SQueryFilePos   cur;  // current position
  int16_t         order;
  STimeWindow     window;  // the primary query time window that applies to all queries
105
  SColumnDataAgg* statis;  // query level statistics, only one table block statistics info exists at any time
H
Hongze Cheng 已提交
106 107 108 109 110 111 112 113 114 115 116 117 118
  int32_t         numOfBlocks;
  SArray*         pColumns;  // column list, SColumnInfoData array list
  bool            locateStart;
  int32_t         outputCapacity;
  int32_t         realNumOfRows;
  SArray*         pTableCheckInfo;  // SArray<STableCheckInfo>
  int32_t         activeIndex;
  bool            checkFiles;               // check file stage
  int8_t          cachelastrow;             // check if last row cached
  bool            loadExternalRow;          // load time window external data rows
  bool            currentLoadExternalRows;  // current load external rows
  int32_t         loadType;                 // block load type
  char*           idStr;                    // query info handle, for debug purpose
dengyihao's avatar
dengyihao 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131
  int32_t type;  // query type: retrieve all data blocks, 2. retrieve only last row, 3. retrieve direct prev|next rows
  SDFileSet*         pFileGroup;
  SFSIter            fileIter;
  SReadH             rhelper;
  STableBlockInfo*   pDataBlockInfo;
  SDataCols*         pDataCols;          // in order to hold current file data block
  int32_t            allocSize;          // allocated data block size
  SArray*            defaultLoadColumn;  // default load column
  SDataBlockLoadInfo dataBlockLoadInfo;  /* record current block load information */
  SLoadCompBlockInfo compBlockLoadInfo;  /* record current compblock information in SQueryAttr */

  SArray*        prev;  // previous row which is before than time window
  SArray*        next;  // next row which is after the query time window
H
Haojun Liao 已提交
132
  SIOCostSummary cost;
133
} STsdbReadHandle;
134

H
Haojun Liao 已提交
135 136 137
typedef struct STableGroupSupporter {
  int32_t    numOfCols;
  SColIndex* pCols;
138
  SSchema*   pTagSchema;
H
Haojun Liao 已提交
139 140
} STableGroupSupporter;

dengyihao's avatar
dengyihao 已提交
141 142 143 144 145
int32_t tsdbQueryTableList(void* pMeta, SArray* pRes, void* filterInfo);

static STimeWindow updateLastrowForEachGroup(STableGroupInfo* groupList);
static int32_t     checkForCachedLastRow(STsdbReadHandle* pTsdbReadHandle, STableGroupInfo* groupList);
static int32_t     checkForCachedLast(STsdbReadHandle* pTsdbReadHandle);
H
Haojun Liao 已提交
146
// static int32_t tsdbGetCachedLastRow(STable* pTable, STSRow** pRes, TSKEY* lastKey);
H
Haojun Liao 已提交
147

H
Haojun Liao 已提交
148
static void    changeQueryHandleForInterpQuery(tsdbReaderT pHandle);
149
static void    doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo, SBlock* pBlock);
150
static int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
dengyihao's avatar
dengyihao 已提交
151 152
static int32_t tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int maxRowsToRead, STimeWindow* win,
                                     STsdbReadHandle* pTsdbReadHandle);
153
static int32_t tsdbCheckInfoCompar(const void* key1, const void* key2);
dengyihao's avatar
dengyihao 已提交
154 155 156 157
// static int32_t doGetExternalRow(STsdbReadHandle* pTsdbReadHandle, int16_t type, void* pMemRef);
// static void*   doFreeColumnInfoData(SArray* pColumnInfoData);
// static void*   destroyTableCheckInfo(SArray* pTableCheckInfo);
static bool tsdbGetExternalRow(tsdbReaderT pHandle);
Y
TD-1733  
yihaoDeng 已提交
158

159
static void tsdbInitDataBlockLoadInfo(SDataBlockLoadInfo* pBlockLoadInfo) {
H
hjxilinx 已提交
160
  pBlockLoadInfo->slot = -1;
dengyihao's avatar
dengyihao 已提交
161
  pBlockLoadInfo->uid = 0;
H
hjxilinx 已提交
162
  pBlockLoadInfo->fileGroup = NULL;
H
hjxilinx 已提交
163 164
}

165
static void tsdbInitCompBlockLoadInfo(SLoadCompBlockInfo* pCompBlockLoadInfo) {
H
hjLiao 已提交
166
  pCompBlockLoadInfo->tid = -1;
167 168
  pCompBlockLoadInfo->fileId = -1;
}
H
hjxilinx 已提交
169

170 171
static SArray* getColumnIdList(STsdbReadHandle* pTsdbReadHandle) {
  size_t numOfCols = QH_GET_NUM_OF_COLS(pTsdbReadHandle);
H
Haojun Liao 已提交
172 173 174 175
  assert(numOfCols <= TSDB_MAX_COLUMNS);

  SArray* pIdList = taosArrayInit(numOfCols, sizeof(int16_t));
  for (int32_t i = 0; i < numOfCols; ++i) {
176
    SColumnInfoData* pCol = taosArrayGet(pTsdbReadHandle->pColumns, i);
H
Haojun Liao 已提交
177 178 179 180 181 182
    taosArrayPush(pIdList, &pCol->info.colId);
  }

  return pIdList;
}

183 184
static SArray* getDefaultLoadColumns(STsdbReadHandle* pTsdbReadHandle, bool loadTS) {
  SArray* pLocalIdList = getColumnIdList(pTsdbReadHandle);
H
Haojun Liao 已提交
185 186 187 188 189

  // check if the primary time stamp column needs to load
  int16_t colId = *(int16_t*)taosArrayGet(pLocalIdList, 0);

  // the primary timestamp column does not be included in the the specified load column list, add it
H
Haojun Liao 已提交
190 191
  if (loadTS && colId != PRIMARYKEY_TIMESTAMP_COL_ID) {
    int16_t columnId = PRIMARYKEY_TIMESTAMP_COL_ID;
H
Haojun Liao 已提交
192 193 194 195 196 197
    taosArrayInsert(pLocalIdList, 0, &columnId);
  }

  return pLocalIdList;
}

H
Haojun Liao 已提交
198
int64_t tsdbGetNumOfRowsInMemTable(tsdbReaderT* pHandle) {
dengyihao's avatar
dengyihao 已提交
199
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)pHandle;
H
Haojun Liao 已提交
200

dengyihao's avatar
dengyihao 已提交
201 202 203 204 205
  int64_t        rows = 0;
  STsdbMemTable* pMemTable = NULL;  // pTsdbReadHandle->pMemTable;
  if (pMemTable == NULL) {
    return rows;
  }
H
Haojun Liao 已提交
206

dengyihao's avatar
dengyihao 已提交
207 208
  //  STableData* pMem  = NULL;
  //  STableData* pIMem = NULL;
H
Haojun Liao 已提交
209

dengyihao's avatar
dengyihao 已提交
210 211
  //  SMemTable* pMemT = pMemRef->snapshot.mem;
  //  SMemTable* pIMemT = pMemRef->snapshot.imem;
H
Haojun Liao 已提交
212 213 214 215 216

  size_t size = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
  for (int32_t i = 0; i < size; ++i) {
    STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);

dengyihao's avatar
dengyihao 已提交
217 218 219 220 221 222 223 224
    //    if (pMemT && pCheckInfo->tableId < pMemT->maxTables) {
    //      pMem = pMemT->tData[pCheckInfo->tableId];
    //      rows += (pMem && pMem->uid == pCheckInfo->tableId) ? pMem->numOfRows : 0;
    //    }
    //    if (pIMemT && pCheckInfo->tableId < pIMemT->maxTables) {
    //      pIMem = pIMemT->tData[pCheckInfo->tableId];
    //      rows += (pIMem && pIMem->uid == pCheckInfo->tableId) ? pIMem->numOfRows : 0;
    //    }
H
Haojun Liao 已提交
225 226 227
  }
  return rows;
}
228

229 230 231
static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, STableGroupInfo* pGroupList) {
  size_t numOfGroup = taosArrayGetSize(pGroupList->pGroupList);
  assert(numOfGroup >= 1);
H
Haojun Liao 已提交
232 233 234 235 236 237 238 239

  // allocate buffer in order to load data blocks from file
  SArray* pTableCheckInfo = taosArrayInit(pGroupList->numOfTables, sizeof(STableCheckInfo));
  if (pTableCheckInfo == NULL) {
    return NULL;
  }

  // todo apply the lastkey of table check to avoid to load header file
240
  for (int32_t i = 0; i < numOfGroup; ++i) {
dengyihao's avatar
dengyihao 已提交
241
    SArray* group = *(SArray**)taosArrayGet(pGroupList->pGroupList, i);
H
Haojun Liao 已提交
242 243 244 245 246

    size_t gsize = taosArrayGetSize(group);
    assert(gsize > 0);

    for (int32_t j = 0; j < gsize; ++j) {
dengyihao's avatar
dengyihao 已提交
247
      STableKeyInfo* pKeyInfo = (STableKeyInfo*)taosArrayGet(group, j);
H
Haojun Liao 已提交
248

dengyihao's avatar
dengyihao 已提交
249
      STableCheckInfo info = {.lastKey = pKeyInfo->lastKey, .tableId = pKeyInfo->uid};
250 251 252
      if (ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
        if (info.lastKey == INT64_MIN || info.lastKey < pTsdbReadHandle->window.skey) {
          info.lastKey = pTsdbReadHandle->window.skey;
253 254
        }

255
        assert(info.lastKey >= pTsdbReadHandle->window.skey && info.lastKey <= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
256
      } else {
257
        info.lastKey = pTsdbReadHandle->window.skey;
H
Haojun Liao 已提交
258 259 260
      }

      taosArrayPush(pTableCheckInfo, &info);
dengyihao's avatar
dengyihao 已提交
261 262
      tsdbDebug("%p check table uid:%" PRId64 " from lastKey:%" PRId64 " %s", pTsdbReadHandle, info.tableId,
                info.lastKey, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
263 264 265
    }
  }

266
  // TODO  group table according to the tag value.
267
  taosArraySort(pTableCheckInfo, tsdbCheckInfoCompar);
H
Haojun Liao 已提交
268 269 270
  return pTableCheckInfo;
}

271 272
static void resetCheckInfo(STsdbReadHandle* pTsdbReadHandle) {
  size_t numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
H
Haojun Liao 已提交
273 274 275 276
  assert(numOfTables >= 1);

  // todo apply the lastkey of table check to avoid to load header file
  for (int32_t i = 0; i < numOfTables; ++i) {
dengyihao's avatar
dengyihao 已提交
277
    STableCheckInfo* pCheckInfo = (STableCheckInfo*)taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
278
    pCheckInfo->lastKey = pTsdbReadHandle->window.skey;
dengyihao's avatar
dengyihao 已提交
279 280
    pCheckInfo->iter = tSkipListDestroyIter(pCheckInfo->iter);
    pCheckInfo->iiter = tSkipListDestroyIter(pCheckInfo->iiter);
281
    pCheckInfo->initBuf = false;
H
Haojun Liao 已提交
282

283 284
    if (ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
      assert(pCheckInfo->lastKey >= pTsdbReadHandle->window.skey);
285
    } else {
286
      assert(pCheckInfo->lastKey <= pTsdbReadHandle->window.skey);
287
    }
H
Haojun Liao 已提交
288 289 290
  }
}

H
Haojun Liao 已提交
291 292 293
// only one table, not need to sort again
static SArray* createCheckInfoFromCheckInfo(STableCheckInfo* pCheckInfo, TSKEY skey, SArray** psTable) {
  SArray* pNew = taosArrayInit(1, sizeof(STableCheckInfo));
D
fix bug  
dapan1121 已提交
294

dengyihao's avatar
dengyihao 已提交
295
  STableCheckInfo info = {.lastKey = skey};
H
Haojun Liao 已提交
296

H
Haojun Liao 已提交
297 298
  info.tableId = pCheckInfo->tableId;
  taosArrayPush(pNew, &info);
H
Haojun Liao 已提交
299 300 301
  return pNew;
}

302 303
static bool emptyQueryTimewindow(STsdbReadHandle* pTsdbReadHandle) {
  assert(pTsdbReadHandle != NULL);
304

305
  STimeWindow* w = &pTsdbReadHandle->window;
dengyihao's avatar
dengyihao 已提交
306
  bool         asc = ASCENDING_TRAVERSE(pTsdbReadHandle->order);
307 308 309 310

  return ((asc && w->skey > w->ekey) || (!asc && w->ekey > w->skey));
}

311 312
// Update the query time window according to the data time to live(TTL) information, in order to avoid to return
// the expired data to client, even it is queried already.
313
static int64_t getEarliestValidTimestamp(STsdb* pTsdb) {
314 315 316
  STsdbCfg* pCfg = &pTsdb->config;

  int64_t now = taosGetTimestamp(pCfg->precision);
H
Hongze Cheng 已提交
317
  return now - (tsTickPerDay[pCfg->precision] * pCfg->keep2) + 1;  // needs to add one tick
318 319
}

320
static void setQueryTimewindow(STsdbReadHandle* pTsdbReadHandle, SQueryTableDataCond* pCond) {
321
  pTsdbReadHandle->window = pCond->twindow;
322

323
  bool    updateTs = false;
324 325 326 327
  int64_t startTs = getEarliestValidTimestamp(pTsdbReadHandle->pTsdb);
  if (ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
    if (startTs > pTsdbReadHandle->window.skey) {
      pTsdbReadHandle->window.skey = startTs;
328 329
      pCond->twindow.skey = startTs;
      updateTs = true;
330 331
    }
  } else {
332 333
    if (startTs > pTsdbReadHandle->window.ekey) {
      pTsdbReadHandle->window.ekey = startTs;
334 335
      pCond->twindow.ekey = startTs;
      updateTs = true;
336 337 338
    }
  }

339
  if (updateTs) {
H
Haojun Liao 已提交
340 341 342
    tsdbDebug("%p update the query time window, old:%" PRId64 " - %" PRId64 ", new:%" PRId64 " - %" PRId64 ", %s",
              pTsdbReadHandle, pCond->twindow.skey, pCond->twindow.ekey, pTsdbReadHandle->window.skey,
              pTsdbReadHandle->window.ekey, pTsdbReadHandle->idStr);
343
  }
344 345
}

346
static STsdbReadHandle* tsdbQueryTablesImpl(STsdb* tsdb, SQueryTableDataCond* pCond, uint64_t qId, uint64_t taskId) {
wafwerar's avatar
wafwerar 已提交
347
  STsdbReadHandle* pReadHandle = taosMemoryCalloc(1, sizeof(STsdbReadHandle));
348
  if (pReadHandle == NULL) {
349
    goto _end;
350
  }
H
Haojun Liao 已提交
351

dengyihao's avatar
dengyihao 已提交
352 353 354 355 356 357 358 359
  pReadHandle->order = pCond->order;
  pReadHandle->pTsdb = tsdb;
  pReadHandle->type = TSDB_QUERY_TYPE_ALL;
  pReadHandle->cur.fid = INT32_MIN;
  pReadHandle->cur.win = TSWINDOW_INITIALIZER;
  pReadHandle->checkFiles = true;
  pReadHandle->activeIndex = 0;  // current active table index
  pReadHandle->allocSize = 0;
360
  pReadHandle->locateStart = false;
dengyihao's avatar
dengyihao 已提交
361
  pReadHandle->loadType = pCond->type;
362

dengyihao's avatar
dengyihao 已提交
363
  pReadHandle->outputCapacity = 4096;  //((STsdb*)tsdb)->config.maxRowsPerFileBlock;
364 365 366
  pReadHandle->loadExternalRow = pCond->loadExternalRows;
  pReadHandle->currentLoadExternalRows = pCond->loadExternalRows;

H
Haojun Liao 已提交
367
  char buf[128] = {0};
dengyihao's avatar
dengyihao 已提交
368
  snprintf(buf, tListLen(buf), "TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, qId);
H
Haojun Liao 已提交
369 370
  pReadHandle->idStr = strdup(buf);

371
  if (tsdbInitReadH(&pReadHandle->rhelper, (STsdb*)tsdb) != 0) {
372
    goto _end;
B
Bomin Zhang 已提交
373
  }
H
Haojun Liao 已提交
374

375 376
  assert(pCond != NULL);
  setQueryTimewindow(pReadHandle, pCond);
377

378 379
  if (pCond->numOfCols > 0) {
    // allocate buffer in order to load data blocks from file
380
    pReadHandle->statis = taosMemoryCalloc(pCond->numOfCols, sizeof(SColumnDataAgg));
381
    if (pReadHandle->statis == NULL) {
382
      goto _end;
383
    }
H
Haojun Liao 已提交
384

385
    // todo: use list instead of array?
386 387
    pReadHandle->pColumns = taosArrayInit(pCond->numOfCols, sizeof(SColumnInfoData));
    if (pReadHandle->pColumns == NULL) {
388
      goto _end;
389
    }
H
Haojun Liao 已提交
390

391 392 393
    for (int32_t i = 0; i < pCond->numOfCols; ++i) {
      SColumnInfoData colInfo = {{0}, 0};
      colInfo.info = pCond->colList[i];
H
Haojun Liao 已提交
394

395
      int32_t code = colInfoDataEnsureCapacity(&colInfo, 0, pReadHandle->outputCapacity);
396
      if (code != TSDB_CODE_SUCCESS) {
397
        goto _end;
398
      }
399

400 401
      taosArrayPush(pReadHandle->pColumns, &colInfo);
      pReadHandle->statis[i].colId = colInfo.info.colId;
B
Bomin Zhang 已提交
402
    }
H
Haojun Liao 已提交
403

404
    pReadHandle->defaultLoadColumn = getDefaultLoadColumns(pReadHandle, true);
H
Haojun Liao 已提交
405
  }
406

H
refact  
Hongze Cheng 已提交
407
  pReadHandle->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->config.maxRows);
408
  if (pReadHandle->pDataCols == NULL) {
H
Haojun Liao 已提交
409
    tsdbError("%p failed to malloc buf for pDataCols, %s", pReadHandle, pReadHandle->idStr);
H
Haojun Liao 已提交
410
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
411
    goto _end;
H
hjxilinx 已提交
412
  }
413

414 415
  tsdbInitDataBlockLoadInfo(&pReadHandle->dataBlockLoadInfo);
  tsdbInitCompBlockLoadInfo(&pReadHandle->compBlockLoadInfo);
416

H
Haojun Liao 已提交
417
  return (tsdbReaderT)pReadHandle;
418

dengyihao's avatar
dengyihao 已提交
419
_end:
420
  tsdbCleanupReadHandle(pReadHandle);
421
  terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
422
  return NULL;
H
hjxilinx 已提交
423 424
}

425
tsdbReaderT* tsdbQueryTables(STsdb* tsdb, SQueryTableDataCond* pCond, STableGroupInfo* groupList, uint64_t qId,
dengyihao's avatar
dengyihao 已提交
426
                             uint64_t taskId) {
H
Haojun Liao 已提交
427
  STsdbReadHandle* pTsdbReadHandle = tsdbQueryTablesImpl(tsdb, pCond, qId, taskId);
428
  if (pTsdbReadHandle == NULL) {
429 430 431
    return NULL;
  }

432
  if (emptyQueryTimewindow(pTsdbReadHandle)) {
dengyihao's avatar
dengyihao 已提交
433
    return (tsdbReaderT*)pTsdbReadHandle;
434
  }
H
Haojun Liao 已提交
435 436

  // todo apply the lastkey of table check to avoid to load header file
437
  pTsdbReadHandle->pTableCheckInfo = createCheckInfoFromTableGroup(pTsdbReadHandle, groupList);
438
  if (pTsdbReadHandle->pTableCheckInfo == NULL) {
dengyihao's avatar
dengyihao 已提交
439
    //    tsdbCleanupReadHandle(pTsdbReadHandle);
H
Haojun Liao 已提交
440 441 442 443
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    return NULL;
  }

dengyihao's avatar
dengyihao 已提交
444 445 446
  tsdbDebug("%p total numOfTable:%" PRIzu " in this query, group %" PRIzu " %s", pTsdbReadHandle,
            taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo), taosArrayGetSize(groupList->pGroupList),
            pTsdbReadHandle->idStr);
447

dengyihao's avatar
dengyihao 已提交
448
  return (tsdbReaderT)pTsdbReadHandle;
H
Haojun Liao 已提交
449 450
}

451
void tsdbResetReadHandle(tsdbReaderT queryHandle, SQueryTableDataCond* pCond) {
452
  STsdbReadHandle* pTsdbReadHandle = queryHandle;
H
Haojun Liao 已提交
453

454 455 456
  if (emptyQueryTimewindow(pTsdbReadHandle)) {
    if (pCond->order != pTsdbReadHandle->order) {
      pTsdbReadHandle->order = pCond->order;
wafwerar's avatar
wafwerar 已提交
457
      TSWAP(pTsdbReadHandle->window.skey, pTsdbReadHandle->window.ekey);
458 459 460 461 462
    }

    return;
  }

dengyihao's avatar
dengyihao 已提交
463 464 465 466 467 468 469
  pTsdbReadHandle->order = pCond->order;
  pTsdbReadHandle->window = pCond->twindow;
  pTsdbReadHandle->type = TSDB_QUERY_TYPE_ALL;
  pTsdbReadHandle->cur.fid = -1;
  pTsdbReadHandle->cur.win = TSWINDOW_INITIALIZER;
  pTsdbReadHandle->checkFiles = true;
  pTsdbReadHandle->activeIndex = 0;  // current active table index
470 471
  pTsdbReadHandle->locateStart = false;
  pTsdbReadHandle->loadExternalRow = pCond->loadExternalRows;
H
Haojun Liao 已提交
472 473

  if (ASCENDING_TRAVERSE(pCond->order)) {
474
    assert(pTsdbReadHandle->window.skey <= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
475
  } else {
476
    assert(pTsdbReadHandle->window.skey >= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
477 478 479
  }

  // allocate buffer in order to load data blocks from file
480
  memset(pTsdbReadHandle->statis, 0, sizeof(SColumnDataAgg));
H
Haojun Liao 已提交
481

482 483
  tsdbInitDataBlockLoadInfo(&pTsdbReadHandle->dataBlockLoadInfo);
  tsdbInitCompBlockLoadInfo(&pTsdbReadHandle->compBlockLoadInfo);
H
Haojun Liao 已提交
484

485
  resetCheckInfo(pTsdbReadHandle);
H
Haojun Liao 已提交
486 487
}

488
void tsdbResetQueryHandleForNewTable(tsdbReaderT queryHandle, SQueryTableDataCond* pCond, STableGroupInfo* groupList) {
489
  STsdbReadHandle* pTsdbReadHandle = queryHandle;
H
Haojun Liao 已提交
490

dengyihao's avatar
dengyihao 已提交
491 492 493 494 495 496 497
  pTsdbReadHandle->order = pCond->order;
  pTsdbReadHandle->window = pCond->twindow;
  pTsdbReadHandle->type = TSDB_QUERY_TYPE_ALL;
  pTsdbReadHandle->cur.fid = -1;
  pTsdbReadHandle->cur.win = TSWINDOW_INITIALIZER;
  pTsdbReadHandle->checkFiles = true;
  pTsdbReadHandle->activeIndex = 0;  // current active table index
498 499
  pTsdbReadHandle->locateStart = false;
  pTsdbReadHandle->loadExternalRow = pCond->loadExternalRows;
H
Haojun Liao 已提交
500 501

  if (ASCENDING_TRAVERSE(pCond->order)) {
502
    assert(pTsdbReadHandle->window.skey <= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
503
  } else {
504
    assert(pTsdbReadHandle->window.skey >= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
505 506 507
  }

  // allocate buffer in order to load data blocks from file
508
  memset(pTsdbReadHandle->statis, 0, sizeof(SColumnDataAgg));
H
Haojun Liao 已提交
509

510 511
  tsdbInitDataBlockLoadInfo(&pTsdbReadHandle->dataBlockLoadInfo);
  tsdbInitCompBlockLoadInfo(&pTsdbReadHandle->compBlockLoadInfo);
H
Haojun Liao 已提交
512

H
Haojun Liao 已提交
513
  SArray* pTable = NULL;
dengyihao's avatar
dengyihao 已提交
514
  //  STsdbMeta* pMeta = tsdbGetMeta(pTsdbReadHandle->pTsdb);
H
Haojun Liao 已提交
515

dengyihao's avatar
dengyihao 已提交
516
  //  pTsdbReadHandle->pTableCheckInfo = destroyTableCheckInfo(pTsdbReadHandle->pTableCheckInfo);
H
Haojun Liao 已提交
517

dengyihao's avatar
dengyihao 已提交
518 519
  pTsdbReadHandle->pTableCheckInfo = NULL;  // createCheckInfoFromTableGroup(pTsdbReadHandle, groupList, pMeta,
                                            // &pTable);
520
  if (pTsdbReadHandle->pTableCheckInfo == NULL) {
dengyihao's avatar
dengyihao 已提交
521
    //    tsdbCleanupReadHandle(pTsdbReadHandle);
H
Haojun Liao 已提交
522 523
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
  }
H
Haojun Liao 已提交
524

dengyihao's avatar
dengyihao 已提交
525 526
  //  pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbReadHandle->prev);
  //  pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbReadHandle->next);
H
Haojun Liao 已提交
527 528
}

529
tsdbReaderT tsdbQueryLastRow(STsdb* tsdb, SQueryTableDataCond* pCond, STableGroupInfo* groupList, uint64_t qId,
dengyihao's avatar
dengyihao 已提交
530
                             uint64_t taskId) {
531
  pCond->twindow = updateLastrowForEachGroup(groupList);
H
Haojun Liao 已提交
532 533 534 535 536 537

  // no qualified table
  if (groupList->numOfTables == 0) {
    return NULL;
  }

dengyihao's avatar
dengyihao 已提交
538
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)tsdbQueryTables(tsdb, pCond, groupList, qId, taskId);
539
  if (pTsdbReadHandle == NULL) {
540 541 542
    return NULL;
  }

543
  int32_t code = checkForCachedLastRow(pTsdbReadHandle, groupList);
dengyihao's avatar
dengyihao 已提交
544
  if (code != TSDB_CODE_SUCCESS) {  // set the numOfTables to be 0
H
Haojun Liao 已提交
545 546 547
    terrno = code;
    return NULL;
  }
H
Haojun Liao 已提交
548 549

  assert(pCond->order == TSDB_ORDER_ASC && pCond->twindow.skey <= pCond->twindow.ekey);
550 551
  if (pTsdbReadHandle->cachelastrow) {
    pTsdbReadHandle->type = TSDB_QUERY_TYPE_LAST;
D
init  
dapan1121 已提交
552
  }
dengyihao's avatar
dengyihao 已提交
553

554
  return pTsdbReadHandle;
D
init  
dapan1121 已提交
555 556
}

557
#if 0
558
tsdbReaderT tsdbQueryCacheLast(STsdb *tsdb, SQueryTableDataCond *pCond, STableGroupInfo *groupList, uint64_t qId, STsdbMemTable* pMemRef) {
559 560
  STsdbReadHandle *pTsdbReadHandle = (STsdbReadHandle*) tsdbQueryTables(tsdb, pCond, groupList, qId, pMemRef);
  if (pTsdbReadHandle == NULL) {
561 562 563
    return NULL;
  }

564
  int32_t code = checkForCachedLast(pTsdbReadHandle);
D
init  
dapan1121 已提交
565 566 567 568 569
  if (code != TSDB_CODE_SUCCESS) { // set the numOfTables to be 0
    terrno = code;
    return NULL;
  }

570 571
  if (pTsdbReadHandle->cachelastrow) {
    pTsdbReadHandle->type = TSDB_QUERY_TYPE_LAST;
D
fix bug  
dapan1121 已提交
572
  }
D
init  
dapan1121 已提交
573
  
574
  return pTsdbReadHandle;
H
hjxilinx 已提交
575 576
}

577
#endif
dengyihao's avatar
dengyihao 已提交
578
SArray* tsdbGetQueriedTableList(tsdbReaderT* pHandle) {
579
  assert(pHandle != NULL);
H
Haojun Liao 已提交
580

dengyihao's avatar
dengyihao 已提交
581
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)pHandle;
H
Haojun Liao 已提交
582

dengyihao's avatar
dengyihao 已提交
583
  size_t  size = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
584
  SArray* res = taosArrayInit(size, POINTER_BYTES);
585 586 587
  return res;
}

H
Haojun Liao 已提交
588 589 590 591 592
// leave only one table for each group
static STableGroupInfo* trimTableGroup(STimeWindow* window, STableGroupInfo* pGroupList) {
  assert(pGroupList);
  size_t numOfGroup = taosArrayGetSize(pGroupList->pGroupList);

wafwerar's avatar
wafwerar 已提交
593
  STableGroupInfo* pNew = taosMemoryCalloc(1, sizeof(STableGroupInfo));
Y
yihaoDeng 已提交
594
  pNew->pGroupList = taosArrayInit(numOfGroup, POINTER_BYTES);
H
Haojun Liao 已提交
595

dengyihao's avatar
dengyihao 已提交
596
  for (int32_t i = 0; i < numOfGroup; ++i) {
H
Haojun Liao 已提交
597
    SArray* oneGroup = taosArrayGetP(pGroupList->pGroupList, i);
dengyihao's avatar
dengyihao 已提交
598
    size_t  numOfTables = taosArrayGetSize(oneGroup);
H
Haojun Liao 已提交
599 600 601 602

    SArray* px = taosArrayInit(4, sizeof(STableKeyInfo));
    for (int32_t j = 0; j < numOfTables; ++j) {
      STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(oneGroup, j);
dengyihao's avatar
dengyihao 已提交
603 604 605 606 607
      //      if (window->skey <= pInfo->lastKey && ((STable*)pInfo->pTable)->lastKey != TSKEY_INITIAL_VAL) {
      //        taosArrayPush(px, pInfo);
      //        pNew->numOfTables += 1;
      //        break;
      //      }
H
Haojun Liao 已提交
608 609 610 611 612 613 614 615 616 617 618 619 620
    }

    // there are no data in this group
    if (taosArrayGetSize(px) == 0) {
      taosArrayDestroy(px);
    } else {
      taosArrayPush(pNew->pGroupList, &px);
    }
  }

  return pNew;
}

621 622
tsdbReaderT tsdbQueryRowsInExternalWindow(STsdb* tsdb, SQueryTableDataCond* pCond, STableGroupInfo* groupList,
                                          uint64_t qId, uint64_t taskId) {
H
Haojun Liao 已提交
623 624
  STableGroupInfo* pNew = trimTableGroup(&pCond->twindow, groupList);

625 626 627 628 629 630 631 632 633 634 635 636
  if (pNew->numOfTables == 0) {
    tsdbDebug("update query time range to invalidate time window");

    assert(taosArrayGetSize(pNew->pGroupList) == 0);
    bool asc = ASCENDING_TRAVERSE(pCond->order);
    if (asc) {
      pCond->twindow.ekey = pCond->twindow.skey - 1;
    } else {
      pCond->twindow.skey = pCond->twindow.ekey - 1;
    }
  }

dengyihao's avatar
dengyihao 已提交
637
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)tsdbQueryTables(tsdb, pCond, pNew, qId, taskId);
638 639
  pTsdbReadHandle->loadExternalRow = true;
  pTsdbReadHandle->currentLoadExternalRows = true;
640

641
  return pTsdbReadHandle;
642 643
}

644
static bool initTableMemIterator(STsdbReadHandle* pHandle, STableCheckInfo* pCheckInfo) {
645
  if (pCheckInfo->initBuf) {
646 647
    return true;
  }
H
Haojun Liao 已提交
648

649
  pCheckInfo->initBuf = true;
650
  int32_t order = pHandle->order;
H
Haojun Liao 已提交
651

652 653 654
  STbData** pMem = NULL;
  STbData** pIMem = NULL;

655
  TSKEY tLastKey = keyToTkey(pCheckInfo->lastKey);
656 657 658
  if (pHandle->pTsdb->mem != NULL) {
    pMem = taosHashGet(pHandle->pTsdb->mem->pHashIdx, &pCheckInfo->tableId, sizeof(pCheckInfo->tableId));
    if (pMem != NULL) {
H
Haojun Liao 已提交
659
      pCheckInfo->iter =
660
          tSkipListCreateIterFromVal((*pMem)->pData, (const char*)&tLastKey, TSDB_DATA_TYPE_TIMESTAMP, order);
H
Haojun Liao 已提交
661
    }
662
  }
H
Haojun Liao 已提交
663

664 665 666
  if (pHandle->pTsdb->imem != NULL) {
    pIMem = taosHashGet(pHandle->pTsdb->imem->pHashIdx, &pCheckInfo->tableId, sizeof(pCheckInfo->tableId));
    if (pIMem != NULL) {
H
Haojun Liao 已提交
667
      pCheckInfo->iiter =
668
          tSkipListCreateIterFromVal((*pIMem)->pData, (const char*)&tLastKey, TSDB_DATA_TYPE_TIMESTAMP, order);
H
Haojun Liao 已提交
669
    }
670
  }
H
Haojun Liao 已提交
671

672 673 674 675
  // both iterators are NULL, no data in buffer right now
  if (pCheckInfo->iter == NULL && pCheckInfo->iiter == NULL) {
    return false;
  }
H
Haojun Liao 已提交
676

dengyihao's avatar
dengyihao 已提交
677
  bool memEmpty = (pCheckInfo->iter == NULL) || (pCheckInfo->iter != NULL && !tSkipListIterNext(pCheckInfo->iter));
678
  bool imemEmpty = (pCheckInfo->iiter == NULL) || (pCheckInfo->iiter != NULL && !tSkipListIterNext(pCheckInfo->iiter));
dengyihao's avatar
dengyihao 已提交
679
  if (memEmpty && imemEmpty) {  // buffer is empty
680 681
    return false;
  }
H
Haojun Liao 已提交
682

683 684 685
  if (!memEmpty) {
    SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
    assert(node != NULL);
H
Haojun Liao 已提交
686

H
Haojun Liao 已提交
687 688
    STSRow* row = (STSRow*)SL_GET_NODE_DATA(node);
    TSKEY   key = TD_ROW_KEY(row);  // first timestamp in buffer
689
    tsdbDebug("%p uid:%" PRId64 ", check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
dengyihao's avatar
dengyihao 已提交
690 691 692
              "-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%" PRId64 ", %s",
              pHandle, pCheckInfo->tableId, key, order, (*pMem)->keyMin, (*pMem)->keyMax, pCheckInfo->lastKey,
              (*pMem)->nrows, pHandle->idStr);
H
Haojun Liao 已提交
693 694 695 696 697 698 699

    if (ASCENDING_TRAVERSE(order)) {
      assert(pCheckInfo->lastKey <= key);
    } else {
      assert(pCheckInfo->lastKey >= key);
    }

700
  } else {
dengyihao's avatar
dengyihao 已提交
701
    tsdbDebug("%p uid:%" PRId64 ", no data in mem, %s", pHandle, pCheckInfo->tableId, pHandle->idStr);
702
  }
H
Haojun Liao 已提交
703

704 705 706
  if (!imemEmpty) {
    SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
    assert(node != NULL);
H
Haojun Liao 已提交
707

H
Haojun Liao 已提交
708 709
    STSRow* row = (STSRow*)SL_GET_NODE_DATA(node);
    TSKEY   key = TD_ROW_KEY(row);  // first timestamp in buffer
710
    tsdbDebug("%p uid:%" PRId64 ", check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
dengyihao's avatar
dengyihao 已提交
711 712 713
              "-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%" PRId64 ", %s",
              pHandle, pCheckInfo->tableId, key, order, (*pIMem)->keyMin, (*pIMem)->keyMax, pCheckInfo->lastKey,
              (*pIMem)->nrows, pHandle->idStr);
H
Haojun Liao 已提交
714 715 716 717 718 719

    if (ASCENDING_TRAVERSE(order)) {
      assert(pCheckInfo->lastKey <= key);
    } else {
      assert(pCheckInfo->lastKey >= key);
    }
720
  } else {
dengyihao's avatar
dengyihao 已提交
721
    tsdbDebug("%p uid:%" PRId64 ", no data in imem, %s", pHandle, pCheckInfo->tableId, pHandle->idStr);
722
  }
H
Haojun Liao 已提交
723

724 725 726
  return true;
}

H
Haojun Liao 已提交
727 728 729 730 731
static void destroyTableMemIterator(STableCheckInfo* pCheckInfo) {
  tSkipListDestroyIter(pCheckInfo->iter);
  tSkipListDestroyIter(pCheckInfo->iiter);
}

732
static TSKEY extractFirstTraverseKey(STableCheckInfo* pCheckInfo, int32_t order, int32_t update) {
H
Haojun Liao 已提交
733
  STSRow *rmem = NULL, *rimem = NULL;
734 735 736
  if (pCheckInfo->iter) {
    SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
    if (node != NULL) {
H
Haojun Liao 已提交
737
      rmem = (STSRow*)SL_GET_NODE_DATA(node);
738 739 740 741 742 743
    }
  }

  if (pCheckInfo->iiter) {
    SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
    if (node != NULL) {
H
Haojun Liao 已提交
744
      rimem = (STSRow*)SL_GET_NODE_DATA(node);
745 746 747 748 749 750 751 752 753
    }
  }

  if (rmem == NULL && rimem == NULL) {
    return TSKEY_INITIAL_VAL;
  }

  if (rmem != NULL && rimem == NULL) {
    pCheckInfo->chosen = CHECKINFO_CHOSEN_MEM;
H
Haojun Liao 已提交
754
    return TD_ROW_KEY(rmem);
755 756 757 758
  }

  if (rmem == NULL && rimem != NULL) {
    pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
H
Haojun Liao 已提交
759
    return TD_ROW_KEY(rimem);
760 761
  }

H
Haojun Liao 已提交
762 763
  TSKEY r1 = TD_ROW_KEY(rmem);
  TSKEY r2 = TD_ROW_KEY(rimem);
764 765

  if (r1 == r2) {
dengyihao's avatar
dengyihao 已提交
766
    if (update == TD_ROW_DISCARD_UPDATE) {
767 768
      pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
      tSkipListIterNext(pCheckInfo->iter);
dengyihao's avatar
dengyihao 已提交
769
    } else if (update == TD_ROW_OVERWRITE_UPDATE) {
770 771 772 773 774 775 776 777 778
      pCheckInfo->chosen = CHECKINFO_CHOSEN_MEM;
      tSkipListIterNext(pCheckInfo->iiter);
    } else {
      pCheckInfo->chosen = CHECKINFO_CHOSEN_BOTH;
    }
    return r1;
  } else if (r1 < r2 && ASCENDING_TRAVERSE(order)) {
    pCheckInfo->chosen = CHECKINFO_CHOSEN_MEM;
    return r1;
dengyihao's avatar
dengyihao 已提交
779
  } else {
780 781 782 783 784
    pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
    return r2;
  }
}

H
Haojun Liao 已提交
785 786
static STSRow* getSRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order, int32_t update, STSRow** extraRow) {
  STSRow *rmem = NULL, *rimem = NULL;
H
Haojun Liao 已提交
787 788 789
  if (pCheckInfo->iter) {
    SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
    if (node != NULL) {
H
Haojun Liao 已提交
790
      rmem = (STSRow*)SL_GET_NODE_DATA(node);
H
Haojun Liao 已提交
791 792
    }
  }
793

H
Haojun Liao 已提交
794 795 796
  if (pCheckInfo->iiter) {
    SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
    if (node != NULL) {
H
Haojun Liao 已提交
797
      rimem = (STSRow*)SL_GET_NODE_DATA(node);
H
Haojun Liao 已提交
798 799
    }
  }
800

H
Haojun Liao 已提交
801 802
  if (rmem == NULL && rimem == NULL) {
    return NULL;
H
Haojun Liao 已提交
803
  }
804

H
Haojun Liao 已提交
805
  if (rmem != NULL && rimem == NULL) {
H
Haojun Liao 已提交
806 807 808
    pCheckInfo->chosen = 0;
    return rmem;
  }
809

H
Haojun Liao 已提交
810
  if (rmem == NULL && rimem != NULL) {
H
Haojun Liao 已提交
811 812 813
    pCheckInfo->chosen = 1;
    return rimem;
  }
814

H
Haojun Liao 已提交
815 816
  TSKEY r1 = TD_ROW_KEY(rmem);
  TSKEY r2 = TD_ROW_KEY(rimem);
H
Haojun Liao 已提交
817

818 819
  if (r1 == r2) {
    if (update == TD_ROW_DISCARD_UPDATE) {
H
TD-1439  
Hongze Cheng 已提交
820
      tSkipListIterNext(pCheckInfo->iter);
821
      pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
H
TD-1439  
Hongze Cheng 已提交
822
      return rimem;
dengyihao's avatar
dengyihao 已提交
823
    } else if (update == TD_ROW_OVERWRITE_UPDATE) {
H
TD-1439  
Hongze Cheng 已提交
824
      tSkipListIterNext(pCheckInfo->iiter);
825 826 827 828
      pCheckInfo->chosen = CHECKINFO_CHOSEN_MEM;
      return rmem;
    } else {
      pCheckInfo->chosen = CHECKINFO_CHOSEN_BOTH;
H
Haojun Liao 已提交
829
      *extraRow = rimem;
H
TD-1439  
Hongze Cheng 已提交
830 831
      return rmem;
    }
H
Haojun Liao 已提交
832 833 834
  } else {
    if (ASCENDING_TRAVERSE(order)) {
      if (r1 < r2) {
835
        pCheckInfo->chosen = CHECKINFO_CHOSEN_MEM;
H
Haojun Liao 已提交
836 837
        return rmem;
      } else {
838
        pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
H
Haojun Liao 已提交
839 840 841 842
        return rimem;
      }
    } else {
      if (r1 < r2) {
843
        pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
H
Haojun Liao 已提交
844 845
        return rimem;
      } else {
846
        pCheckInfo->chosen = CHECKINFO_CHOSEN_IMEM;
H
Haojun Liao 已提交
847 848 849 850
        return rmem;
      }
    }
  }
H
Haojun Liao 已提交
851 852
}

853
static bool moveToNextRowInMem(STableCheckInfo* pCheckInfo) {
H
Haojun Liao 已提交
854
  bool hasNext = false;
855
  if (pCheckInfo->chosen == CHECKINFO_CHOSEN_MEM) {
H
Haojun Liao 已提交
856 857 858
    if (pCheckInfo->iter != NULL) {
      hasNext = tSkipListIterNext(pCheckInfo->iter);
    }
859

H
Haojun Liao 已提交
860 861 862
    if (hasNext) {
      return hasNext;
    }
863

H
Haojun Liao 已提交
864 865 866
    if (pCheckInfo->iiter != NULL) {
      return tSkipListIterGet(pCheckInfo->iiter) != NULL;
    }
dengyihao's avatar
dengyihao 已提交
867
  } else if (pCheckInfo->chosen == CHECKINFO_CHOSEN_IMEM) {
868 869 870
    if (pCheckInfo->iiter != NULL) {
      hasNext = tSkipListIterNext(pCheckInfo->iiter);
    }
871

872 873 874
    if (hasNext) {
      return hasNext;
    }
875

876 877
    if (pCheckInfo->iter != NULL) {
      return tSkipListIterGet(pCheckInfo->iter) != NULL;
H
Haojun Liao 已提交
878
    }
879 880 881 882 883 884 885
  } else {
    if (pCheckInfo->iter != NULL) {
      hasNext = tSkipListIterNext(pCheckInfo->iter);
    }
    if (pCheckInfo->iiter != NULL) {
      hasNext = tSkipListIterNext(pCheckInfo->iiter) || hasNext;
    }
H
Haojun Liao 已提交
886
  }
887

H
Haojun Liao 已提交
888 889 890
  return hasNext;
}

891
static bool hasMoreDataInCache(STsdbReadHandle* pHandle) {
dengyihao's avatar
dengyihao 已提交
892 893
  STsdbCfg* pCfg = &pHandle->pTsdb->config;
  size_t    size = taosArrayGetSize(pHandle->pTableCheckInfo);
894
  assert(pHandle->activeIndex < size && pHandle->activeIndex >= 0 && size >= 1);
D
dapan1121 已提交
895
  pHandle->cur.fid = INT32_MIN;
H
Haojun Liao 已提交
896

897
  STableCheckInfo* pCheckInfo = taosArrayGet(pHandle->pTableCheckInfo, pHandle->activeIndex);
H
Haojun Liao 已提交
898 899 900 901
  if (!pCheckInfo->initBuf) {
    initTableMemIterator(pHandle, pCheckInfo);
  }

H
Haojun Liao 已提交
902
  STSRow* row = getSRowInTableMem(pCheckInfo, pHandle->order, pCfg->update, NULL);
H
Haojun Liao 已提交
903
  if (row == NULL) {
904 905
    return false;
  }
906

H
Haojun Liao 已提交
907
  pCheckInfo->lastKey = TD_ROW_KEY(row);  // first timestamp in buffer
dengyihao's avatar
dengyihao 已提交
908 909
  tsdbDebug("%p uid:%" PRId64 ", check data in buffer from skey:%" PRId64 ", order:%d, %s", pHandle,
            pCheckInfo->tableId, pCheckInfo->lastKey, pHandle->order, pHandle->idStr);
H
Haojun Liao 已提交
910

911
  // all data in mem are checked already.
912 913
  if ((pCheckInfo->lastKey > pHandle->window.ekey && ASCENDING_TRAVERSE(pHandle->order)) ||
      (pCheckInfo->lastKey < pHandle->window.ekey && !ASCENDING_TRAVERSE(pHandle->order))) {
914 915
    return false;
  }
H
Haojun Liao 已提交
916

dengyihao's avatar
dengyihao 已提交
917
  int32_t      step = ASCENDING_TRAVERSE(pHandle->order) ? 1 : -1;
918
  STimeWindow* win = &pHandle->cur.win;
H
Haojun Liao 已提交
919
  pHandle->cur.rows = tsdbReadRowsFromCache(pCheckInfo, pHandle->window.ekey, pHandle->outputCapacity, win, pHandle);
H
Haojun Liao 已提交
920

921 922 923 924
  // update the last key value
  pCheckInfo->lastKey = win->ekey + step;
  pHandle->cur.lastKey = win->ekey + step;
  pHandle->cur.mixBlock = true;
925

926
  if (!ASCENDING_TRAVERSE(pHandle->order)) {
wafwerar's avatar
wafwerar 已提交
927
    TSWAP(win->skey, win->ekey);
928
  }
H
Haojun Liao 已提交
929

930
  return true;
931
}
H
hjxilinx 已提交
932

933 934
static int32_t getFileIdFromKey(TSKEY key, int32_t daysPerFile, int32_t precision) {
  assert(precision >= TSDB_TIME_PRECISION_MICRO || precision <= TSDB_TIME_PRECISION_NANO);
935 936 937
  if (key == TSKEY_INITIAL_VAL) {
    return INT32_MIN;
  }
H
Haojun Liao 已提交
938

D
dapan1121 已提交
939
  if (key < 0) {
940
    key -= (daysPerFile * tsTickPerDay[precision]);
D
dapan1121 已提交
941
  }
dengyihao's avatar
dengyihao 已提交
942

943
  int64_t fid = (int64_t)(key / (daysPerFile * tsTickPerDay[precision]));  // set the starting fileId
dengyihao's avatar
dengyihao 已提交
944
  if (fid < 0L && llabs(fid) > INT32_MAX) {                                // data value overflow for INT32
945 946
    fid = INT32_MIN;
  }
H
Haojun Liao 已提交
947

948
  if (fid > 0L && fid > INT32_MAX) {
949 950
    fid = INT32_MAX;
  }
H
Haojun Liao 已提交
951

S
TD-1057  
Shengliang Guan 已提交
952
  return (int32_t)fid;
953 954
}

H
refact  
Hongze Cheng 已提交
955
static int32_t binarySearchForBlock(SBlock* pBlock, int32_t numOfBlocks, TSKEY skey, int32_t order) {
956 957
  int32_t firstSlot = 0;
  int32_t lastSlot = numOfBlocks - 1;
H
Haojun Liao 已提交
958

959
  int32_t midSlot = firstSlot;
H
Haojun Liao 已提交
960

961 962 963
  while (1) {
    numOfBlocks = lastSlot - firstSlot + 1;
    midSlot = (firstSlot + (numOfBlocks >> 1));
H
Haojun Liao 已提交
964

965
    if (numOfBlocks == 1) break;
H
Haojun Liao 已提交
966

967 968 969 970 971 972 973 974 975 976 977
    if (skey > pBlock[midSlot].keyLast) {
      if (numOfBlocks == 2) break;
      if ((order == TSDB_ORDER_DESC) && (skey < pBlock[midSlot + 1].keyFirst)) break;
      firstSlot = midSlot + 1;
    } else if (skey < pBlock[midSlot].keyFirst) {
      if ((order == TSDB_ORDER_ASC) && (skey > pBlock[midSlot - 1].keyLast)) break;
      lastSlot = midSlot - 1;
    } else {
      break;  // got the slot
    }
  }
H
Haojun Liao 已提交
978

979 980
  return midSlot;
}
981

dengyihao's avatar
dengyihao 已提交
982
static int32_t loadBlockInfo(STsdbReadHandle* pTsdbReadHandle, int32_t index, int32_t* numOfBlocks) {
H
Haojun Liao 已提交
983
  int32_t code = 0;
H
Haojun Liao 已提交
984

985
  STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, index);
H
Haojun Liao 已提交
986
  pCheckInfo->numOfBlocks = 0;
987

H
Haojun Liao 已提交
988
  STable table = {.uid = pCheckInfo->tableId, .tid = pCheckInfo->tableId};
H
Hongze Cheng 已提交
989
  table.pSchema = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), pCheckInfo->tableId, 0);
H
Haojun Liao 已提交
990 991

  if (tsdbSetReadTable(&pTsdbReadHandle->rhelper, &table) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
992 993 994
    code = terrno;
    return code;
  }
995

996
  SBlockIdx* compIndex = pTsdbReadHandle->rhelper.pBlkIdx;
H
Hongze Cheng 已提交
997

H
Haojun Liao 已提交
998
  // no data block in this file, try next file
999
  if (compIndex == NULL || compIndex->uid != pCheckInfo->tableId) {
H
Haojun Liao 已提交
1000 1001
    return 0;  // no data blocks in the file belongs to pCheckInfo->pTable
  }
1002

H
Haojun Liao 已提交
1003 1004 1005
  if (pCheckInfo->compSize < (int32_t)compIndex->len) {
    assert(compIndex->len > 0);

wafwerar's avatar
wafwerar 已提交
1006
    char* t = taosMemoryRealloc(pCheckInfo->pCompInfo, compIndex->len);
H
Haojun Liao 已提交
1007 1008 1009 1010
    if (t == NULL) {
      terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
      code = TSDB_CODE_TDB_OUT_OF_MEMORY;
      return code;
1011 1012
    }

H
Haojun Liao 已提交
1013 1014 1015
    pCheckInfo->pCompInfo = (SBlockInfo*)t;
    pCheckInfo->compSize = compIndex->len;
  }
1016

1017
  if (tsdbLoadBlockInfo(&(pTsdbReadHandle->rhelper), (void*)(pCheckInfo->pCompInfo)) < 0) {
H
Hongze Cheng 已提交
1018 1019
    return terrno;
  }
H
Haojun Liao 已提交
1020
  SBlockInfo* pCompInfo = pCheckInfo->pCompInfo;
1021

H
Haojun Liao 已提交
1022
  TSKEY s = TSKEY_INITIAL_VAL, e = TSKEY_INITIAL_VAL;
1023

1024
  if (ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
dengyihao's avatar
dengyihao 已提交
1025 1026
    assert(pCheckInfo->lastKey <= pTsdbReadHandle->window.ekey &&
           pTsdbReadHandle->window.skey <= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
1027
  } else {
dengyihao's avatar
dengyihao 已提交
1028 1029
    assert(pCheckInfo->lastKey >= pTsdbReadHandle->window.ekey &&
           pTsdbReadHandle->window.skey >= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
1030
  }
1031

dengyihao's avatar
dengyihao 已提交
1032 1033
  s = TMIN(pCheckInfo->lastKey, pTsdbReadHandle->window.ekey);
  e = TMAX(pCheckInfo->lastKey, pTsdbReadHandle->window.ekey);
1034

H
Haojun Liao 已提交
1035 1036 1037
  // discard the unqualified data block based on the query time window
  int32_t start = binarySearchForBlock(pCompInfo->blocks, compIndex->numOfBlocks, s, TSDB_ORDER_ASC);
  int32_t end = start;
H
TD-100  
hzcheng 已提交
1038

H
Haojun Liao 已提交
1039 1040 1041
  if (s > pCompInfo->blocks[start].keyLast) {
    return 0;
  }
1042

H
Haojun Liao 已提交
1043 1044 1045 1046
  // todo speedup the procedure of located end block
  while (end < (int32_t)compIndex->numOfBlocks && (pCompInfo->blocks[end].keyFirst <= e)) {
    end += 1;
  }
1047

H
Haojun Liao 已提交
1048
  pCheckInfo->numOfBlocks = (end - start);
1049

H
Haojun Liao 已提交
1050 1051 1052
  if (start > 0) {
    memmove(pCompInfo->blocks, &pCompInfo->blocks[start], pCheckInfo->numOfBlocks * sizeof(SBlock));
  }
1053

H
Haojun Liao 已提交
1054 1055 1056
  (*numOfBlocks) += pCheckInfo->numOfBlocks;
  return 0;
}
1057

1058
static int32_t getFileCompInfo(STsdbReadHandle* pTsdbReadHandle, int32_t* numOfBlocks) {
H
Haojun Liao 已提交
1059 1060 1061 1062
  // load all the comp offset value for all tables in this file
  int32_t code = TSDB_CODE_SUCCESS;
  *numOfBlocks = 0;

1063
  pTsdbReadHandle->cost.headFileLoad += 1;
1064 1065
  int64_t s = taosGetTimestampUs();

H
Haojun Liao 已提交
1066
  size_t numOfTables = 0;
1067 1068 1069 1070
  if (pTsdbReadHandle->loadType == BLOCK_LOAD_TABLE_SEQ_ORDER) {
    code = loadBlockInfo(pTsdbReadHandle, pTsdbReadHandle->activeIndex, numOfBlocks);
  } else if (pTsdbReadHandle->loadType == BLOCK_LOAD_OFFSET_SEQ_ORDER) {
    numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
1071

H
Haojun Liao 已提交
1072
    for (int32_t i = 0; i < numOfTables; ++i) {
1073
      code = loadBlockInfo(pTsdbReadHandle, i, numOfBlocks);
H
Haojun Liao 已提交
1074
      if (code != TSDB_CODE_SUCCESS) {
1075 1076
        int64_t e = taosGetTimestampUs();

1077
        pTsdbReadHandle->cost.headFileLoadTime += (e - s);
H
Haojun Liao 已提交
1078 1079 1080 1081 1082
        return code;
      }
    }
  } else {
    assert(0);
1083
  }
1084

1085
  int64_t e = taosGetTimestampUs();
1086
  pTsdbReadHandle->cost.headFileLoadTime += (e - s);
H
Haojun Liao 已提交
1087
  return code;
1088 1089
}

dengyihao's avatar
dengyihao 已提交
1090 1091
static int32_t doLoadFileDataBlock(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo,
                                   int32_t slotIndex) {
H
Haojun Liao 已提交
1092
  int64_t st = taosGetTimestampUs();
1093

H
Hongze Cheng 已提交
1094
  STSchema* pSchema = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), pCheckInfo->tableId, 0);
1095
  int32_t   code = tdInitDataCols(pTsdbReadHandle->pDataCols, pSchema);
H
Haojun Liao 已提交
1096
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1097
    tsdbError("%p failed to malloc buf for pDataCols, %s", pTsdbReadHandle, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1098 1099 1100 1101
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    goto _error;
  }

1102
  code = tdInitDataCols(pTsdbReadHandle->rhelper.pDCols[0], pSchema);
H
Haojun Liao 已提交
1103
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1104
    tsdbError("%p failed to malloc buf for rhelper.pDataCols[0], %s", pTsdbReadHandle, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1105 1106 1107 1108
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    goto _error;
  }

1109
  code = tdInitDataCols(pTsdbReadHandle->rhelper.pDCols[1], pSchema);
H
Haojun Liao 已提交
1110
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1111
    tsdbError("%p failed to malloc buf for rhelper.pDataCols[1], %s", pTsdbReadHandle, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1112 1113 1114
    terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
    goto _error;
  }
1115

1116
  int16_t* colIds = pTsdbReadHandle->defaultLoadColumn->pData;
H
Haojun Liao 已提交
1117

dengyihao's avatar
dengyihao 已提交
1118 1119
  int32_t ret = tsdbLoadBlockDataCols(&(pTsdbReadHandle->rhelper), pBlock, pCheckInfo->pCompInfo, colIds,
                                      (int)(QH_GET_NUM_OF_COLS(pTsdbReadHandle)), true);
H
Haojun Liao 已提交
1120
  if (ret != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1121 1122 1123
    int32_t c = terrno;
    assert(c != TSDB_CODE_SUCCESS);
    goto _error;
H
Haojun Liao 已提交
1124
  }
1125

1126
  SDataBlockLoadInfo* pBlockLoadInfo = &pTsdbReadHandle->dataBlockLoadInfo;
1127

1128 1129
  pBlockLoadInfo->fileGroup = pTsdbReadHandle->pFileGroup;
  pBlockLoadInfo->slot = pTsdbReadHandle->cur.slot;
H
Haojun Liao 已提交
1130
  pBlockLoadInfo->uid = pCheckInfo->tableId;
1131

1132
  SDataCols* pCols = pTsdbReadHandle->rhelper.pDCols[0];
1133
  assert(pCols->numOfRows != 0 && pCols->numOfRows <= pBlock->numOfRows);
1134

1135
  pBlock->numOfRows = pCols->numOfRows;
H
Haojun Liao 已提交
1136

1137
  // Convert from TKEY to TSKEY for primary timestamp column if current block has timestamp before 1970-01-01T00:00:00Z
dengyihao's avatar
dengyihao 已提交
1138
  if (pBlock->keyFirst < 0 && colIds[0] == PRIMARYKEY_TIMESTAMP_COL_ID) {
1139
    int64_t* src = pCols->cols[0].pData;
dengyihao's avatar
dengyihao 已提交
1140
    for (int32_t i = 0; i < pBlock->numOfRows; ++i) {
1141 1142 1143 1144
      src[i] = tdGetKey(src[i]);
    }
  }

H
Haojun Liao 已提交
1145
  int64_t elapsedTime = (taosGetTimestampUs() - st);
1146
  pTsdbReadHandle->cost.blockLoadTime += elapsedTime;
1147

dengyihao's avatar
dengyihao 已提交
1148 1149 1150 1151
  tsdbDebug("%p load file block into buffer, index:%d, brange:%" PRId64 "-%" PRId64 ", rows:%d, elapsed time:%" PRId64
            " us, %s",
            pTsdbReadHandle, slotIndex, pBlock->keyFirst, pBlock->keyLast, pBlock->numOfRows, elapsedTime,
            pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1152
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
1153 1154 1155 1156

_error:
  pBlock->numOfRows = 0;

dengyihao's avatar
dengyihao 已提交
1157
  tsdbError("%p error occurs in loading file block, index:%d, brange:%" PRId64 "-%" PRId64 ", rows:%d, %s",
H
Haojun Liao 已提交
1158
            pTsdbReadHandle, slotIndex, pBlock->keyFirst, pBlock->keyLast, pBlock->numOfRows, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1159
  return terrno;
H
hjxilinx 已提交
1160 1161
}

1162
static int32_t getEndPosInDataBlock(STsdbReadHandle* pTsdbReadHandle, SDataBlockInfo* pBlockInfo);
dengyihao's avatar
dengyihao 已提交
1163 1164 1165 1166 1167 1168 1169 1170
static int32_t doCopyRowsFromFileBlock(STsdbReadHandle* pTsdbReadHandle, int32_t capacity, int32_t numOfRows,
                                       int32_t start, int32_t end);
static void    moveDataToFront(STsdbReadHandle* pTsdbReadHandle, int32_t numOfRows, int32_t numOfCols);
static void    doCheckGeneratedBlockRange(STsdbReadHandle* pTsdbReadHandle);
static void    copyAllRemainRowsFromFileBlock(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo,
                                              SDataBlockInfo* pBlockInfo, int32_t endPos);

static int32_t handleDataMergeIfNeeded(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo) {
1171 1172
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
  STsdbCfg*      pCfg = &pTsdbReadHandle->pTsdb->config;
H
Haojun Liao 已提交
1173
  SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
1174
  TSKEY          key;
dengyihao's avatar
dengyihao 已提交
1175
  int32_t        code = TSDB_CODE_SUCCESS;
1176

1177
  /*bool hasData = */ initTableMemIterator(pTsdbReadHandle, pCheckInfo);
H
Haojun Liao 已提交
1178 1179
  assert(cur->pos >= 0 && cur->pos <= binfo.rows);

1180
  key = extractFirstTraverseKey(pCheckInfo, pTsdbReadHandle->order, pCfg->update);
1181

H
Haojun Liao 已提交
1182
  if (key != TSKEY_INITIAL_VAL) {
dengyihao's avatar
dengyihao 已提交
1183
    tsdbDebug("%p key in mem:%" PRId64 ", %s", pTsdbReadHandle, key, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1184
  } else {
H
Haojun Liao 已提交
1185
    tsdbDebug("%p no data in mem, %s", pTsdbReadHandle, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1186
  }
H
Haojun Liao 已提交
1187

1188 1189
  bool ascScan = ASCENDING_TRAVERSE(pTsdbReadHandle->order);

1190 1191 1192 1193
  if ((ascScan && (key != TSKEY_INITIAL_VAL && key <= binfo.window.ekey)) ||
      (!ascScan && (key != TSKEY_INITIAL_VAL && key >= binfo.window.skey))) {
    if ((ascScan && (key != TSKEY_INITIAL_VAL && key < binfo.window.skey)) ||
        (!ascScan && (key != TSKEY_INITIAL_VAL && key > binfo.window.ekey))) {
H
Haojun Liao 已提交
1194
      // do not load file block into buffer
1195
      int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
H
Haojun Liao 已提交
1196

dengyihao's avatar
dengyihao 已提交
1197 1198 1199 1200
      TSKEY maxKey =
          ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? (binfo.window.skey - step) : (binfo.window.ekey - step);
      cur->rows =
          tsdbReadRowsFromCache(pCheckInfo, maxKey, pTsdbReadHandle->outputCapacity, &cur->win, pTsdbReadHandle);
1201
      pTsdbReadHandle->realNumOfRows = cur->rows;
H
Haojun Liao 已提交
1202 1203 1204

      // update the last key value
      pCheckInfo->lastKey = cur->win.ekey + step;
1205
      if (!ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
wafwerar's avatar
wafwerar 已提交
1206
        TSWAP(cur->win.skey, cur->win.ekey);
H
Haojun Liao 已提交
1207
      }
H
Haojun Liao 已提交
1208

H
Haojun Liao 已提交
1209 1210
      cur->mixBlock = true;
      cur->blockCompleted = false;
H
Haojun Liao 已提交
1211
      return code;
H
Haojun Liao 已提交
1212
    }
H
Haojun Liao 已提交
1213

1214
    // return error, add test cases
1215
    if ((code = doLoadFileDataBlock(pTsdbReadHandle, pBlock, pCheckInfo, cur->slot)) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1216
      return code;
1217 1218
    }

1219
    doMergeTwoLevelData(pTsdbReadHandle, pCheckInfo, pBlock);
1220
  } else {
1221 1222 1223 1224 1225 1226
    /*
     * no data in cache, only load data from file
     * during the query processing, data in cache will not be checked anymore.
     *
     * Here the buffer is not enough, so only part of file block can be loaded into memory buffer
     */
1227 1228
    assert(pTsdbReadHandle->outputCapacity >= binfo.rows);
    int32_t endPos = getEndPosInDataBlock(pTsdbReadHandle, &binfo);
1229

1230 1231
    if ((cur->pos == 0 && endPos == binfo.rows - 1 && ascScan) ||
        (cur->pos == (binfo.rows - 1) && endPos == 0 && (!ascScan))) {
1232
      pTsdbReadHandle->realNumOfRows = binfo.rows;
1233 1234

      cur->rows = binfo.rows;
dengyihao's avatar
dengyihao 已提交
1235
      cur->win = binfo.window;
1236
      cur->mixBlock = false;
H
Haojun Liao 已提交
1237 1238
      cur->blockCompleted = true;

1239
      if (ascScan) {
H
Haojun Liao 已提交
1240 1241 1242 1243 1244 1245
        cur->lastKey = binfo.window.ekey + 1;
        cur->pos = binfo.rows;
      } else {
        cur->lastKey = binfo.window.skey - 1;
        cur->pos = -1;
      }
dengyihao's avatar
dengyihao 已提交
1246
    } else {  // partially copy to dest buffer
1247
      copyAllRemainRowsFromFileBlock(pTsdbReadHandle, pCheckInfo, &binfo, endPos);
1248 1249
      cur->mixBlock = true;
    }
1250

H
Haojun Liao 已提交
1251
    assert(cur->blockCompleted);
H
Haojun Liao 已提交
1252
    if (cur->rows == binfo.rows) {
dengyihao's avatar
dengyihao 已提交
1253
      tsdbDebug("%p whole file block qualified, brange:%" PRId64 "-%" PRId64 ", rows:%d, lastKey:%" PRId64 ", %s",
H
Haojun Liao 已提交
1254
                pTsdbReadHandle, cur->win.skey, cur->win.ekey, cur->rows, cur->lastKey, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1255
    } else {
dengyihao's avatar
dengyihao 已提交
1256 1257 1258 1259
      tsdbDebug("%p create data block from remain file block, brange:%" PRId64 "-%" PRId64
                ", rows:%d, total:%d, lastKey:%" PRId64 ", %s",
                pTsdbReadHandle, cur->win.skey, cur->win.ekey, cur->rows, binfo.rows, cur->lastKey,
                pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1260
    }
1261
  }
H
Haojun Liao 已提交
1262 1263

  return code;
1264 1265
}

dengyihao's avatar
dengyihao 已提交
1266 1267
static int32_t loadFileDataBlock(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo,
                                 bool* exists) {
1268
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
dengyihao's avatar
dengyihao 已提交
1269 1270
  int32_t        code = TSDB_CODE_SUCCESS;
  bool           asc = ASCENDING_TRAVERSE(pTsdbReadHandle->order);
1271

1272
  if (asc) {
H
Haojun Liao 已提交
1273
    // query ended in/started from current block
1274 1275
    if (pTsdbReadHandle->window.ekey < pBlock->keyLast || pCheckInfo->lastKey > pBlock->keyFirst) {
      if ((code = doLoadFileDataBlock(pTsdbReadHandle, pBlock, pCheckInfo, cur->slot)) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1276 1277
        *exists = false;
        return code;
1278
      }
1279

1280
      SDataCols* pTSCol = pTsdbReadHandle->rhelper.pDCols[0];
H
Haojun Liao 已提交
1281
      assert(pTSCol->cols->type == TSDB_DATA_TYPE_TIMESTAMP && pTSCol->numOfRows == pBlock->numOfRows);
H
Haojun Liao 已提交
1282

1283 1284
      if (pCheckInfo->lastKey > pBlock->keyFirst) {
        cur->pos =
1285
            binarySearchForKey(pTSCol->cols[0].pData, pBlock->numOfRows, pCheckInfo->lastKey, pTsdbReadHandle->order);
1286 1287 1288
      } else {
        cur->pos = 0;
      }
H
Haojun Liao 已提交
1289

H
Haojun Liao 已提交
1290
      assert(pCheckInfo->lastKey <= pBlock->keyLast);
1291
      doMergeTwoLevelData(pTsdbReadHandle, pCheckInfo, pBlock);
1292
    } else {  // the whole block is loaded in to buffer
dengyihao's avatar
dengyihao 已提交
1293
      cur->pos = asc ? 0 : (pBlock->numOfRows - 1);
1294
      code = handleDataMergeIfNeeded(pTsdbReadHandle, pBlock, pCheckInfo);
H
[td-32]  
hjxilinx 已提交
1295
    }
dengyihao's avatar
dengyihao 已提交
1296
  } else {  // desc order, query ended in current block
1297 1298
    if (pTsdbReadHandle->window.ekey > pBlock->keyFirst || pCheckInfo->lastKey < pBlock->keyLast) {
      if ((code = doLoadFileDataBlock(pTsdbReadHandle, pBlock, pCheckInfo, cur->slot)) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
1299 1300
        *exists = false;
        return code;
1301
      }
H
Haojun Liao 已提交
1302

1303
      SDataCols* pTsCol = pTsdbReadHandle->rhelper.pDCols[0];
1304
      if (pCheckInfo->lastKey < pBlock->keyLast) {
dengyihao's avatar
dengyihao 已提交
1305 1306
        cur->pos =
            binarySearchForKey(pTsCol->cols[0].pData, pBlock->numOfRows, pCheckInfo->lastKey, pTsdbReadHandle->order);
1307
      } else {
H
Haojun Liao 已提交
1308
        cur->pos = pBlock->numOfRows - 1;
1309
      }
H
Haojun Liao 已提交
1310

H
Haojun Liao 已提交
1311
      assert(pCheckInfo->lastKey >= pBlock->keyFirst);
1312
      doMergeTwoLevelData(pTsdbReadHandle, pCheckInfo, pBlock);
1313
    } else {
dengyihao's avatar
dengyihao 已提交
1314
      cur->pos = asc ? 0 : (pBlock->numOfRows - 1);
1315
      code = handleDataMergeIfNeeded(pTsdbReadHandle, pBlock, pCheckInfo);
H
[td-32]  
hjxilinx 已提交
1316
    }
1317
  }
1318

1319
  *exists = pTsdbReadHandle->realNumOfRows > 0;
H
Haojun Liao 已提交
1320
  return code;
H
[td-32]  
hjxilinx 已提交
1321 1322
}

1323
static int doBinarySearchKey(char* pValue, int num, TSKEY key, int order) {
1324
  int    firstPos, lastPos, midPos = -1;
H
Haojun Liao 已提交
1325
  int    numOfRows;
1326 1327
  TSKEY* keyList;

1328
  assert(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);
H
Haojun Liao 已提交
1329

1330
  if (num <= 0) return -1;
1331 1332

  keyList = (TSKEY*)pValue;
1333 1334
  firstPos = 0;
  lastPos = num - 1;
1335

1336
  if (order == TSDB_ORDER_DESC) {
1337 1338 1339 1340 1341
    // 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;
1342

H
Haojun Liao 已提交
1343 1344
      numOfRows = lastPos - firstPos + 1;
      midPos = (numOfRows >> 1) + firstPos;
1345

1346 1347 1348 1349 1350 1351 1352 1353
      if (key < keyList[midPos]) {
        lastPos = midPos - 1;
      } else if (key > keyList[midPos]) {
        firstPos = midPos + 1;
      } else {
        break;
      }
    }
1354

1355 1356 1357 1358 1359
  } 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;
1360

1361 1362 1363 1364 1365 1366 1367
      if (key > keyList[lastPos]) {
        lastPos = lastPos + 1;
        if (lastPos >= num)
          return -1;
        else
          return lastPos;
      }
1368

H
Haojun Liao 已提交
1369 1370
      numOfRows = lastPos - firstPos + 1;
      midPos = (numOfRows >> 1) + firstPos;
1371

1372 1373 1374 1375 1376 1377 1378 1379 1380
      if (key < keyList[midPos]) {
        lastPos = midPos - 1;
      } else if (key > keyList[midPos]) {
        firstPos = midPos + 1;
      } else {
        break;
      }
    }
  }
1381

1382 1383 1384
  return midPos;
}

dengyihao's avatar
dengyihao 已提交
1385 1386
static int32_t doCopyRowsFromFileBlock(STsdbReadHandle* pTsdbReadHandle, int32_t capacity, int32_t numOfRows,
                                       int32_t start, int32_t end) {
1387
  SDataCols* pCols = pTsdbReadHandle->rhelper.pDCols[0];
dengyihao's avatar
dengyihao 已提交
1388
  TSKEY*     tsArray = pCols->cols[0].pData;
H
Haojun Liao 已提交
1389

1390
  int32_t num = end - start + 1;
H
Haojun Liao 已提交
1391 1392 1393 1394 1395 1396
  assert(num >= 0);

  if (num == 0) {
    return numOfRows;
  }

1397 1398
  bool    ascScan = ASCENDING_TRAVERSE(pTsdbReadHandle->order);
  int32_t trueStart = ascScan ? start : end;
1399
  int32_t trueEnd = ascScan ? end : start;
1400 1401
  int32_t step = ascScan ? 1 : -1;

1402
  int32_t requiredNumOfCols = (int32_t)taosArrayGetSize(pTsdbReadHandle->pColumns);
H
Haojun Liao 已提交
1403

dengyihao's avatar
dengyihao 已提交
1404
  // data in buffer has greater timestamp, copy data in file block
1405
  int32_t i = 0, j = 0;
dengyihao's avatar
dengyihao 已提交
1406
  while (i < requiredNumOfCols && j < pCols->numOfCols) {
1407
    SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
1408 1409 1410 1411 1412 1413 1414

    SDataCol* src = &pCols->cols[j];
    if (src->colId < pColInfo->info.colId) {
      j++;
      continue;
    }

L
Liu Jicong 已提交
1415
    if (!isAllRowsNull(src) && pColInfo->info.colId == src->colId) {
1416
      if (!IS_VAR_DATA_TYPE(pColInfo->info.type)) {  // todo opt performance
dengyihao's avatar
dengyihao 已提交
1417
        //        memmove(pData, (char*)src->pData + bytes * start, bytes * num);
1418
        int32_t rowIndex = numOfRows;
1419
        for (int32_t k = trueStart; ((ascScan && k <= trueEnd) || (!ascScan && k >= trueEnd)); k += step, ++rowIndex) {
1420
          SCellVal sVal = {0};
C
Cary Xu 已提交
1421
          if (tdGetColDataOfRow(&sVal, src, k, pCols->bitmapMode) < 0) {
1422 1423
            TASSERT(0);
          }
1424

1425
          if (sVal.valType == TD_VTYPE_NULL) {
1426
            colDataAppendNULL(pColInfo, rowIndex);
1427
          } else {
1428
            colDataAppend(pColInfo, rowIndex, sVal.val, false);
1429 1430 1431
          }
        }
      } else {  // handle the var-string
1432 1433
        int32_t rowIndex = numOfRows;

1434
        // todo refactor, only copy one-by-one
1435
        for (int32_t k = trueStart; ((ascScan && k <= trueEnd) || (!ascScan && k >= trueEnd)); k += step, ++rowIndex) {
1436
          SCellVal sVal = {0};
dengyihao's avatar
dengyihao 已提交
1437
          if (tdGetColDataOfRow(&sVal, src, k, pCols->bitmapMode) < 0) {
H
Haojun Liao 已提交
1438 1439
            TASSERT(0);
          }
1440

1441
          if (sVal.valType == TD_VTYPE_NULL) {
1442
            colDataAppendNULL(pColInfo, rowIndex);
1443
          } else {
1444
            colDataAppend(pColInfo, rowIndex, sVal.val, false);
1445
          }
1446 1447
        }
      }
1448 1449 1450

      j++;
      i++;
H
Hongze Cheng 已提交
1451
    } else {  // pColInfo->info.colId < src->colId, it is a NULL data
1452
      colDataAppendNNULL(pColInfo, numOfRows, num);
1453
      i++;
1454 1455
    }
  }
1456

dengyihao's avatar
dengyihao 已提交
1457
  while (i < requiredNumOfCols) {  // the remain columns are all null data
1458
    SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
1459
    colDataAppendNNULL(pColInfo, numOfRows, num);
1460
    i++;
1461
  }
H
Haojun Liao 已提交
1462

1463 1464
  pTsdbReadHandle->cur.win.ekey = tsArray[trueEnd];
  pTsdbReadHandle->cur.lastKey = tsArray[trueEnd] + step;
1465

1466
  return numOfRows + num;
1467 1468
}

H
Haojun Liao 已提交
1469
// TODO fix bug for reverse copy data problem
1470
// Note: row1 always has high priority
H
Haojun Liao 已提交
1471 1472 1473 1474
static void mergeTwoRowFromMem(STsdbReadHandle* pTsdbReadHandle, int32_t capacity, int32_t numOfRows, STSRow* row1,
                               STSRow* row2, int32_t numOfCols, uint64_t uid, STSchema* pSchema1, STSchema* pSchema2,
                               bool forceSetNull) {
#if 1
dengyihao's avatar
dengyihao 已提交
1475 1476 1477 1478 1479 1480 1481 1482 1483
  STSchema* pSchema;
  STSRow*   row;
  int16_t   colId;
  int16_t   offset;

  bool     isRow1DataRow = TD_IS_TP_ROW(row1);
  bool     isRow2DataRow;
  bool     isChosenRowDataRow;
  int32_t  chosen_itr;
H
Haojun Liao 已提交
1484
  SCellVal sVal = {0};
1485

H
Haojun Liao 已提交
1486
  // the schema version info is embeded in STSRow
1487 1488 1489
  int32_t numOfColsOfRow1 = 0;

  if (pSchema1 == NULL) {
H
Hongze Cheng 已提交
1490
    pSchema1 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, TD_ROW_SVER(row1));
1491
  }
1492

dengyihao's avatar
dengyihao 已提交
1493
  if (isRow1DataRow) {
1494
    numOfColsOfRow1 = schemaNCols(pSchema1);
H
Haojun Liao 已提交
1495
  } else {
H
Haojun Liao 已提交
1496
    numOfColsOfRow1 = tdRowGetNCols(row1);
D
fix bug  
dapan1121 已提交
1497
  }
1498

1499
  int32_t numOfColsOfRow2 = 0;
dengyihao's avatar
dengyihao 已提交
1500
  if (row2) {
H
Haojun Liao 已提交
1501
    isRow2DataRow = TD_IS_TP_ROW(row2);
1502
    if (pSchema2 == NULL) {
H
Hongze Cheng 已提交
1503
      pSchema2 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, TD_ROW_SVER(row2));
1504
    }
dengyihao's avatar
dengyihao 已提交
1505
    if (isRow2DataRow) {
1506 1507
      numOfColsOfRow2 = schemaNCols(pSchema2);
    } else {
H
Haojun Liao 已提交
1508
      numOfColsOfRow2 = tdRowGetNCols(row2);
1509 1510
    }
  }
C
Cary Xu 已提交
1511

1512
  int32_t i = 0, j = 0, k = 0;
dengyihao's avatar
dengyihao 已提交
1513
  while (i < numOfCols && (j < numOfColsOfRow1 || k < numOfColsOfRow2)) {
1514
    SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
1515 1516

    int32_t colIdOfRow1;
dengyihao's avatar
dengyihao 已提交
1517
    if (j >= numOfColsOfRow1) {
1518
      colIdOfRow1 = INT32_MAX;
dengyihao's avatar
dengyihao 已提交
1519
    } else if (isRow1DataRow) {
1520 1521
      colIdOfRow1 = pSchema1->columns[j].colId;
    } else {
dengyihao's avatar
dengyihao 已提交
1522
      SKvRowIdx* pColIdx = tdKvRowColIdxAt(row1, j);
1523 1524 1525 1526
      colIdOfRow1 = pColIdx->colId;
    }

    int32_t colIdOfRow2;
dengyihao's avatar
dengyihao 已提交
1527
    if (k >= numOfColsOfRow2) {
1528
      colIdOfRow2 = INT32_MAX;
dengyihao's avatar
dengyihao 已提交
1529
    } else if (isRow2DataRow) {
1530 1531
      colIdOfRow2 = pSchema2->columns[k].colId;
    } else {
dengyihao's avatar
dengyihao 已提交
1532
      SKvRowIdx* pColIdx = tdKvRowColIdxAt(row2, k);
1533 1534 1535
      colIdOfRow2 = pColIdx->colId;
    }

dengyihao's avatar
dengyihao 已提交
1536 1537
    if (colIdOfRow1 == colIdOfRow2) {
      if (colIdOfRow1 < pColInfo->info.colId) {
C
Cary Xu 已提交
1538
        j++;
1539
        k++;
C
Cary Xu 已提交
1540 1541
        continue;
      }
1542 1543 1544 1545
      row = row1;
      pSchema = pSchema1;
      isChosenRowDataRow = isRow1DataRow;
      chosen_itr = j;
dengyihao's avatar
dengyihao 已提交
1546 1547
    } else if (colIdOfRow1 < colIdOfRow2) {
      if (colIdOfRow1 < pColInfo->info.colId) {
1548 1549
        j++;
        continue;
C
Cary Xu 已提交
1550
      }
1551 1552 1553 1554 1555
      row = row1;
      pSchema = pSchema1;
      isChosenRowDataRow = isRow1DataRow;
      chosen_itr = j;
    } else {
dengyihao's avatar
dengyihao 已提交
1556
      if (colIdOfRow2 < pColInfo->info.colId) {
1557 1558 1559 1560 1561 1562 1563 1564
        k++;
        continue;
      }
      row = row2;
      pSchema = pSchema2;
      chosen_itr = k;
      isChosenRowDataRow = isRow2DataRow;
    }
dengyihao's avatar
dengyihao 已提交
1565
    if (isChosenRowDataRow) {
1566 1567
      colId = pSchema->columns[chosen_itr].colId;
      offset = pSchema->columns[chosen_itr].offset;
C
Cary Xu 已提交
1568 1569
      // TODO: use STSRowIter
      tdSTpRowGetVal(row, colId, pSchema->columns[chosen_itr].type, pSchema->flen, offset, chosen_itr - 1, &sVal);
1570
    } else {
C
Cary Xu 已提交
1571 1572 1573 1574 1575 1576 1577 1578 1579 1580
      // TODO: use STSRowIter
      if (chosen_itr == 0) {
        colId = PRIMARYKEY_TIMESTAMP_COL_ID;
        tdSKvRowGetVal(row, PRIMARYKEY_TIMESTAMP_COL_ID, -1, -1, &sVal);
      } else {
        SKvRowIdx* pColIdx = tdKvRowColIdxAt(row, chosen_itr - 1);
        colId = pColIdx->colId;
        offset = pColIdx->offset;
        tdSKvRowGetVal(row, colId, offset, chosen_itr - 1, &sVal);
      }
1581 1582 1583
    }

    if (colId == pColInfo->info.colId) {
H
Haojun Liao 已提交
1584
      if (tdValTypeIsNorm(sVal.valType)) {
H
Haojun Liao 已提交
1585
        colDataAppend(pColInfo, numOfRows, sVal.val, false);
H
Haojun Liao 已提交
1586
      } else if (forceSetNull) {
H
Haojun Liao 已提交
1587
        colDataAppend(pColInfo, numOfRows, NULL, true);
1588
      }
H
Haojun Liao 已提交
1589

1590
      i++;
C
Cary Xu 已提交
1591

dengyihao's avatar
dengyihao 已提交
1592
      if (row == row1) {
C
Cary Xu 已提交
1593
        j++;
1594 1595 1596 1597
      } else {
        k++;
      }
    } else {
dengyihao's avatar
dengyihao 已提交
1598
      if (forceSetNull) {
H
Haojun Liao 已提交
1599
        colDataAppend(pColInfo, numOfRows, NULL, true);
C
Cary Xu 已提交
1600
      }
1601
      i++;
1602
    }
1603
  }
1604

dengyihao's avatar
dengyihao 已提交
1605 1606
  if (forceSetNull) {
    while (i < numOfCols) {  // the remain columns are all null data
1607
      SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
H
Haojun Liao 已提交
1608
      colDataAppend(pColInfo, numOfRows, NULL, true);
1609
      i++;
1610 1611
    }
  }
H
Haojun Liao 已提交
1612
#endif
1613
}
1614

1615 1616
static void moveDataToFront(STsdbReadHandle* pTsdbReadHandle, int32_t numOfRows, int32_t numOfCols) {
  if (numOfRows == 0 || ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
1617 1618 1619 1620
    return;
  }

  // if the buffer is not full in case of descending order query, move the data in the front of the buffer
1621 1622
  if (numOfRows < pTsdbReadHandle->outputCapacity) {
    int32_t emptySize = pTsdbReadHandle->outputCapacity - numOfRows;
dengyihao's avatar
dengyihao 已提交
1623
    for (int32_t i = 0; i < numOfCols; ++i) {
1624
      SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
dengyihao's avatar
dengyihao 已提交
1625 1626
      memmove((char*)pColInfo->pData, (char*)pColInfo->pData + emptySize * pColInfo->info.bytes,
              numOfRows * pColInfo->info.bytes);
1627 1628 1629 1630
    }
  }
}

dengyihao's avatar
dengyihao 已提交
1631 1632
static void getQualifiedRowsPos(STsdbReadHandle* pTsdbReadHandle, int32_t startPos, int32_t endPos,
                                int32_t numOfExisted, int32_t* start, int32_t* end) {
1633 1634
  *start = -1;

1635
  if (ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
1636
    int32_t remain = endPos - startPos + 1;
1637 1638
    if (remain + numOfExisted > pTsdbReadHandle->outputCapacity) {
      *end = (pTsdbReadHandle->outputCapacity - numOfExisted) + startPos - 1;
H
Haojun Liao 已提交
1639 1640
    } else {
      *end = endPos;
1641 1642 1643 1644 1645
    }

    *start = startPos;
  } else {
    int32_t remain = (startPos - endPos) + 1;
1646 1647
    if (remain + numOfExisted > pTsdbReadHandle->outputCapacity) {
      *end = startPos + 1 - (pTsdbReadHandle->outputCapacity - numOfExisted);
H
Haojun Liao 已提交
1648 1649
    } else {
      *end = endPos;
1650 1651 1652 1653 1654 1655 1656
    }

    *start = *end;
    *end = startPos;
  }
}

dengyihao's avatar
dengyihao 已提交
1657 1658
static void updateInfoAfterMerge(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo, int32_t numOfRows,
                                 int32_t endPos) {
1659
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
1660 1661

  pCheckInfo->lastKey = cur->lastKey;
1662
  pTsdbReadHandle->realNumOfRows = numOfRows;
1663 1664 1665 1666
  cur->rows = numOfRows;
  cur->pos = endPos;
}

1667 1668
static void doCheckGeneratedBlockRange(STsdbReadHandle* pTsdbReadHandle) {
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
H
Haojun Liao 已提交
1669 1670

  if (cur->rows > 0) {
1671 1672
    if (ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
      assert(cur->win.skey >= pTsdbReadHandle->window.skey && cur->win.ekey <= pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
1673
    } else {
1674
      assert(cur->win.skey >= pTsdbReadHandle->window.ekey && cur->win.ekey <= pTsdbReadHandle->window.skey);
H
Haojun Liao 已提交
1675 1676
    }

1677
    SColumnInfoData* pColInfoData = taosArrayGet(pTsdbReadHandle->pColumns, 0);
dengyihao's avatar
dengyihao 已提交
1678 1679
    assert(cur->win.skey == ((TSKEY*)pColInfoData->pData)[0] &&
           cur->win.ekey == ((TSKEY*)pColInfoData->pData)[cur->rows - 1]);
H
Haojun Liao 已提交
1680
  } else {
1681
    cur->win = pTsdbReadHandle->window;
H
Haojun Liao 已提交
1682

dengyihao's avatar
dengyihao 已提交
1683
    int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
1684
    cur->lastKey = pTsdbReadHandle->window.ekey + step;
H
Haojun Liao 已提交
1685 1686 1687
  }
}

dengyihao's avatar
dengyihao 已提交
1688 1689
static void copyAllRemainRowsFromFileBlock(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo,
                                           SDataBlockInfo* pBlockInfo, int32_t endPos) {
1690
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
H
Haojun Liao 已提交
1691

1692
  SDataCols* pCols = pTsdbReadHandle->rhelper.pDCols[0];
dengyihao's avatar
dengyihao 已提交
1693
  TSKEY*     tsArray = pCols->cols[0].pData;
H
Haojun Liao 已提交
1694

dengyihao's avatar
dengyihao 已提交
1695
  int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
1696
  int32_t numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pTsdbReadHandle));
H
Haojun Liao 已提交
1697 1698 1699 1700 1701 1702

  int32_t pos = cur->pos;

  int32_t start = cur->pos;
  int32_t end = endPos;

1703
  if (!ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
wafwerar's avatar
wafwerar 已提交
1704
    TSWAP(start, end);
H
Haojun Liao 已提交
1705 1706
  }

1707 1708
  assert(pTsdbReadHandle->outputCapacity >= (end - start + 1));
  int32_t numOfRows = doCopyRowsFromFileBlock(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, 0, start, end);
H
Haojun Liao 已提交
1709 1710

  // the time window should always be ascending order: skey <= ekey
dengyihao's avatar
dengyihao 已提交
1711
  cur->win = (STimeWindow){.skey = tsArray[start], .ekey = tsArray[end]};
H
Haojun Liao 已提交
1712
  cur->mixBlock = (numOfRows != pBlockInfo->rows);
H
Haojun Liao 已提交
1713
  cur->lastKey = tsArray[endPos] + step;
H
Haojun Liao 已提交
1714
  cur->blockCompleted = true;
H
Haojun Liao 已提交
1715 1716

  // if the buffer is not full in case of descending order query, move the data in the front of the buffer
1717
  moveDataToFront(pTsdbReadHandle, numOfRows, numOfCols);
H
Haojun Liao 已提交
1718 1719 1720

  // The value of pos may be -1 or pBlockInfo->rows, and it is invalid in both cases.
  pos = endPos + step;
1721 1722
  updateInfoAfterMerge(pTsdbReadHandle, pCheckInfo, numOfRows, pos);
  doCheckGeneratedBlockRange(pTsdbReadHandle);
H
Haojun Liao 已提交
1723

dengyihao's avatar
dengyihao 已提交
1724 1725 1726
  tsdbDebug("%p uid:%" PRIu64 ", data block created, mixblock:%d, brange:%" PRIu64 "-%" PRIu64 " rows:%d, %s",
            pTsdbReadHandle, pCheckInfo->tableId, cur->mixBlock, cur->win.skey, cur->win.ekey, cur->rows,
            pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1727 1728
}

1729
int32_t getEndPosInDataBlock(STsdbReadHandle* pTsdbReadHandle, SDataBlockInfo* pBlockInfo) {
H
Haojun Liao 已提交
1730 1731
  // NOTE: reverse the order to find the end position in data block
  int32_t endPos = -1;
dengyihao's avatar
dengyihao 已提交
1732
  int32_t order = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC;
H
Haojun Liao 已提交
1733

1734
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
dengyihao's avatar
dengyihao 已提交
1735
  SDataCols*     pCols = pTsdbReadHandle->rhelper.pDCols[0];
H
Haojun Liao 已提交
1736

1737
  if (ASCENDING_TRAVERSE(pTsdbReadHandle->order) && pTsdbReadHandle->window.ekey >= pBlockInfo->window.ekey) {
H
Haojun Liao 已提交
1738 1739
    endPos = pBlockInfo->rows - 1;
    cur->mixBlock = (cur->pos != 0);
1740
  } else if (!ASCENDING_TRAVERSE(pTsdbReadHandle->order) && pTsdbReadHandle->window.ekey <= pBlockInfo->window.skey) {
H
Haojun Liao 已提交
1741 1742 1743 1744
    endPos = 0;
    cur->mixBlock = (cur->pos != pBlockInfo->rows - 1);
  } else {
    assert(pCols->numOfRows > 0);
1745
    endPos = doBinarySearchKey(pCols->cols[0].pData, pCols->numOfRows, pTsdbReadHandle->window.ekey, order);
H
Haojun Liao 已提交
1746 1747 1748 1749 1750 1751
    cur->mixBlock = true;
  }

  return endPos;
}

H
[td-32]  
hjxilinx 已提交
1752 1753
// only return the qualified data to client in terms of query time window, data rows in the same block but do not
// be included in the query time window will be discarded
1754 1755
static void doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo, SBlock* pBlock) {
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
1756
  SDataBlockInfo blockInfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
1757
  STsdbCfg*      pCfg = &pTsdbReadHandle->pTsdb->config;
H
Haojun Liao 已提交
1758

1759
  initTableMemIterator(pTsdbReadHandle, pCheckInfo);
1760

1761 1762
  SDataCols* pCols = pTsdbReadHandle->rhelper.pDCols[0];
  assert(pCols->cols[0].type == TSDB_DATA_TYPE_TIMESTAMP && pCols->cols[0].colId == PRIMARYKEY_TIMESTAMP_COL_ID &&
dengyihao's avatar
dengyihao 已提交
1763
         cur->pos >= 0 && cur->pos < pBlock->numOfRows);
H
Haojun Liao 已提交
1764

1765
  TSKEY* tsArray = pCols->cols[0].pData;
dengyihao's avatar
dengyihao 已提交
1766 1767
  assert(pCols->numOfRows == pBlock->numOfRows && tsArray[0] == pBlock->keyFirst &&
         tsArray[pBlock->numOfRows - 1] == pBlock->keyLast);
1768 1769

  // for search the endPos, so the order needs to reverse
dengyihao's avatar
dengyihao 已提交
1770
  int32_t order = (pTsdbReadHandle->order == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC;
1771

dengyihao's avatar
dengyihao 已提交
1772
  int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
1773
  int32_t numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pTsdbReadHandle));
1774

H
Haojun Liao 已提交
1775
  STable* pTable = NULL;
1776
  int32_t endPos = getEndPosInDataBlock(pTsdbReadHandle, &blockInfo);
H
Haojun Liao 已提交
1777

H
Hongze Cheng 已提交
1778 1779
  tsdbDebug("%p uid:%" PRIu64 " start merge data block, file block range:%" PRIu64 "-%" PRIu64
            " rows:%d, start:%d, end:%d, %s",
dengyihao's avatar
dengyihao 已提交
1780 1781
            pTsdbReadHandle, pCheckInfo->tableId, blockInfo.window.skey, blockInfo.window.ekey, blockInfo.rows,
            cur->pos, endPos, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
1782

1783 1784
  // compared with the data from in-memory buffer, to generate the correct timestamp array list
  int32_t numOfRows = 0;
H
Haojun Liao 已提交
1785

dengyihao's avatar
dengyihao 已提交
1786 1787
  int16_t   rv1 = -1;
  int16_t   rv2 = -1;
1788 1789
  STSchema* pSchema1 = NULL;
  STSchema* pSchema2 = NULL;
D
fix bug  
dapan1121 已提交
1790

H
Haojun Liao 已提交
1791 1792
  int32_t pos = cur->pos;
  cur->win = TSWINDOW_INITIALIZER;
1793

1794 1795
  // no data in buffer, load data from file directly
  if (pCheckInfo->iiter == NULL && pCheckInfo->iter == NULL) {
1796
    copyAllRemainRowsFromFileBlock(pTsdbReadHandle, pCheckInfo, &blockInfo, endPos);
1797
    return;
1798
  } else if (pCheckInfo->iter != NULL || pCheckInfo->iiter != NULL) {
1799 1800
    SSkipListNode* node = NULL;
    do {
H
Haojun Liao 已提交
1801 1802
      STSRow* row2 = NULL;
      STSRow* row1 = getSRowInTableMem(pCheckInfo, pTsdbReadHandle->order, pCfg->update, &row2);
1803
      if (row1 == NULL) {
H
[td-32]  
hjxilinx 已提交
1804
        break;
1805
      }
1806

H
Haojun Liao 已提交
1807
      TSKEY key = TD_ROW_KEY(row1);
1808 1809
      if ((key > pTsdbReadHandle->window.ekey && ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
          (key < pTsdbReadHandle->window.ekey && !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
1810 1811 1812
        break;
      }

dengyihao's avatar
dengyihao 已提交
1813 1814 1815 1816
      if (((pos > endPos || tsArray[pos] > pTsdbReadHandle->window.ekey) &&
           ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
          ((pos < endPos || tsArray[pos] < pTsdbReadHandle->window.ekey) &&
           !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
1817 1818 1819
        break;
      }

1820 1821
      if ((key < tsArray[pos] && ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
          (key > tsArray[pos] && !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
H
Haojun Liao 已提交
1822
        if (rv1 != TD_ROW_SVER(row1)) {
dengyihao's avatar
dengyihao 已提交
1823
          //          pSchema1 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row1));
H
Haojun Liao 已提交
1824
          rv1 = TD_ROW_SVER(row1);
C
Cary Xu 已提交
1825
        }
dengyihao's avatar
dengyihao 已提交
1826 1827
        if (row2 && rv2 != TD_ROW_SVER(row2)) {
          //          pSchema2 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row2));
H
Haojun Liao 已提交
1828
          rv2 = TD_ROW_SVER(row2);
1829
        }
dengyihao's avatar
dengyihao 已提交
1830 1831 1832

        mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, row1, row2, numOfCols,
                           pCheckInfo->tableId, pSchema1, pSchema2, true);
1833 1834 1835 1836
        numOfRows += 1;
        if (cur->win.skey == TSKEY_INITIAL_VAL) {
          cur->win.skey = key;
        }
1837

1838
        cur->win.ekey = key;
dengyihao's avatar
dengyihao 已提交
1839
        cur->lastKey = key + step;
1840 1841
        cur->mixBlock = true;

1842
        moveToNextRowInMem(pCheckInfo);
1843
      } else if (key == tsArray[pos]) {  // data in buffer has the same timestamp of data in file block, ignore it
H
TD-1439  
Hongze Cheng 已提交
1844
        if (pCfg->update) {
dengyihao's avatar
dengyihao 已提交
1845
          if (pCfg->update == TD_ROW_PARTIAL_UPDATE) {
1846
            doCopyRowsFromFileBlock(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, pos, pos);
D
fix bug  
dapan1121 已提交
1847
          }
H
Haojun Liao 已提交
1848
          if (rv1 != TD_ROW_SVER(row1)) {
dengyihao's avatar
dengyihao 已提交
1849
            //            pSchema1 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row1));
H
Haojun Liao 已提交
1850
            rv1 = TD_ROW_SVER(row1);
1851
          }
dengyihao's avatar
dengyihao 已提交
1852 1853
          if (row2 && rv2 != TD_ROW_SVER(row2)) {
            //            pSchema2 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row2));
H
Haojun Liao 已提交
1854
            rv2 = TD_ROW_SVER(row2);
1855
          }
dengyihao's avatar
dengyihao 已提交
1856

1857
          bool forceSetNull = pCfg->update != TD_ROW_PARTIAL_UPDATE;
dengyihao's avatar
dengyihao 已提交
1858 1859
          mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, row1, row2, numOfCols,
                             pCheckInfo->tableId, pSchema1, pSchema2, forceSetNull);
H
TD-1439  
Hongze Cheng 已提交
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
          numOfRows += 1;
          if (cur->win.skey == TSKEY_INITIAL_VAL) {
            cur->win.skey = key;
          }

          cur->win.ekey = key;
          cur->lastKey = key + step;
          cur->mixBlock = true;

          moveToNextRowInMem(pCheckInfo);
          pos += step;
        } else {
          moveToNextRowInMem(pCheckInfo);
        }
1874
      } else if ((key > tsArray[pos] && ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
dengyihao's avatar
dengyihao 已提交
1875
                 (key < tsArray[pos] && !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
1876 1877 1878
        if (cur->win.skey == TSKEY_INITIAL_VAL) {
          cur->win.skey = tsArray[pos];
        }
1879

1880
        int32_t end = doBinarySearchKey(pCols->cols[0].pData, pCols->numOfRows, key, order);
1881 1882
        assert(end != -1);

dengyihao's avatar
dengyihao 已提交
1883
        if (tsArray[end] == key) {  // the value of key in cache equals to the end timestamp value, ignore it
1884
          if (pCfg->update == TD_ROW_DISCARD_UPDATE) {
H
Hongze Cheng 已提交
1885 1886 1887 1888
            moveToNextRowInMem(pCheckInfo);
          } else {
            end -= step;
          }
H
Haojun Liao 已提交
1889
        }
1890

1891
        int32_t qstart = 0, qend = 0;
1892
        getQualifiedRowsPos(pTsdbReadHandle, pos, end, numOfRows, &qstart, &qend);
1893

1894
        numOfRows = doCopyRowsFromFileBlock(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, qstart, qend);
1895 1896
        pos += (qend - qstart + 1) * step;

dengyihao's avatar
dengyihao 已提交
1897 1898
        cur->win.ekey = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? tsArray[qend] : tsArray[qstart];
        cur->lastKey = cur->win.ekey + step;
1899
      }
1900
    } while (numOfRows < pTsdbReadHandle->outputCapacity);
H
Haojun Liao 已提交
1901

1902
    if (numOfRows < pTsdbReadHandle->outputCapacity) {
H
Haojun Liao 已提交
1903 1904 1905 1906
      /**
       * if cache is empty, load remain file block data. In contrast, if there are remain data in cache, do NOT
       * copy them all to result buffer, since it may be overlapped with file data block.
       */
1907
      if (node == NULL ||
H
Haojun Liao 已提交
1908
          ((TD_ROW_KEY((STSRow*)SL_GET_NODE_DATA(node)) > pTsdbReadHandle->window.ekey) &&
1909
           ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
H
Haojun Liao 已提交
1910
          ((TD_ROW_KEY((STSRow*)SL_GET_NODE_DATA(node)) < pTsdbReadHandle->window.ekey) &&
1911
           !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
1912 1913 1914 1915 1916
        // no data in cache or data in cache is greater than the ekey of time window, load data from file block
        if (cur->win.skey == TSKEY_INITIAL_VAL) {
          cur->win.skey = tsArray[pos];
        }

1917
        int32_t start = -1, end = -1;
1918
        getQualifiedRowsPos(pTsdbReadHandle, pos, endPos, numOfRows, &start, &end);
1919

1920
        numOfRows = doCopyRowsFromFileBlock(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, numOfRows, start, end);
1921
        pos += (end - start + 1) * step;
1922

dengyihao's avatar
dengyihao 已提交
1923 1924
        cur->win.ekey = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? tsArray[end] : tsArray[start];
        cur->lastKey = cur->win.ekey + step;
H
Haojun Liao 已提交
1925
        cur->mixBlock = true;
1926
      }
1927 1928
    }
  }
H
Haojun Liao 已提交
1929 1930

  cur->blockCompleted =
1931 1932
      (((pos > endPos || cur->lastKey > pTsdbReadHandle->window.ekey) && ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
       ((pos < endPos || cur->lastKey < pTsdbReadHandle->window.ekey) && !ASCENDING_TRAVERSE(pTsdbReadHandle->order)));
1933

1934
  if (!ASCENDING_TRAVERSE(pTsdbReadHandle->order)) {
wafwerar's avatar
wafwerar 已提交
1935
    TSWAP(cur->win.skey, cur->win.ekey);
1936
  }
1937

1938 1939 1940
  moveDataToFront(pTsdbReadHandle, numOfRows, numOfCols);
  updateInfoAfterMerge(pTsdbReadHandle, pCheckInfo, numOfRows, pos);
  doCheckGeneratedBlockRange(pTsdbReadHandle);
H
Haojun Liao 已提交
1941

dengyihao's avatar
dengyihao 已提交
1942 1943 1944
  tsdbDebug("%p uid:%" PRIu64 ", data block created, mixblock:%d, brange:%" PRIu64 "-%" PRIu64 " rows:%d, %s",
            pTsdbReadHandle, pCheckInfo->tableId, cur->mixBlock, cur->win.skey, cur->win.ekey, cur->rows,
            pTsdbReadHandle->idStr);
1945 1946
}

1947
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
H
[td-32]  
hjxilinx 已提交
1948
  int    firstPos, lastPos, midPos = -1;
H
Haojun Liao 已提交
1949
  int    numOfRows;
1950 1951
  TSKEY* keyList;

H
[td-32]  
hjxilinx 已提交
1952
  if (num <= 0) return -1;
1953 1954

  keyList = (TSKEY*)pValue;
H
[td-32]  
hjxilinx 已提交
1955 1956
  firstPos = 0;
  lastPos = num - 1;
1957

1958
  if (order == TSDB_ORDER_DESC) {
H
[td-32]  
hjxilinx 已提交
1959 1960 1961 1962 1963
    // 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;
1964

H
Haojun Liao 已提交
1965 1966
      numOfRows = lastPos - firstPos + 1;
      midPos = (numOfRows >> 1) + firstPos;
1967

H
[td-32]  
hjxilinx 已提交
1968 1969 1970 1971 1972 1973 1974 1975
      if (key < keyList[midPos]) {
        lastPos = midPos - 1;
      } else if (key > keyList[midPos]) {
        firstPos = midPos + 1;
      } else {
        break;
      }
    }
1976

H
[td-32]  
hjxilinx 已提交
1977 1978 1979 1980 1981
  } 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;
1982

H
[td-32]  
hjxilinx 已提交
1983 1984 1985 1986 1987 1988 1989
      if (key > keyList[lastPos]) {
        lastPos = lastPos + 1;
        if (lastPos >= num)
          return -1;
        else
          return lastPos;
      }
1990

H
Haojun Liao 已提交
1991 1992
      numOfRows = lastPos - firstPos + 1;
      midPos = (numOfRows >> 1) + firstPos;
1993

H
[td-32]  
hjxilinx 已提交
1994 1995 1996 1997 1998 1999 2000 2001 2002
      if (key < keyList[midPos]) {
        lastPos = midPos - 1;
      } else if (key > keyList[midPos]) {
        firstPos = midPos + 1;
      } else {
        break;
      }
    }
  }
2003

H
[td-32]  
hjxilinx 已提交
2004 2005 2006
  return midPos;
}

2007
static void cleanBlockOrderSupporter(SBlockOrderSupporter* pSupporter, int32_t numOfTables) {
wafwerar's avatar
wafwerar 已提交
2008 2009
  taosMemoryFreeClear(pSupporter->numOfBlocksPerTable);
  taosMemoryFreeClear(pSupporter->blockIndexArray);
2010 2011

  for (int32_t i = 0; i < numOfTables; ++i) {
H
Haojun Liao 已提交
2012
    STableBlockInfo* pBlockInfo = pSupporter->pDataBlockInfo[i];
wafwerar's avatar
wafwerar 已提交
2013
    taosMemoryFreeClear(pBlockInfo);
2014 2015
  }

wafwerar's avatar
wafwerar 已提交
2016
  taosMemoryFreeClear(pSupporter->pDataBlockInfo);
2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027
}

static int32_t dataBlockOrderCompar(const void* pLeft, const void* pRight, void* param) {
  int32_t leftTableIndex = *(int32_t*)pLeft;
  int32_t rightTableIndex = *(int32_t*)pRight;

  SBlockOrderSupporter* pSupporter = (SBlockOrderSupporter*)param;

  int32_t leftTableBlockIndex = pSupporter->blockIndexArray[leftTableIndex];
  int32_t rightTableBlockIndex = pSupporter->blockIndexArray[rightTableIndex];

2028
  if (leftTableBlockIndex > pSupporter->numOfBlocksPerTable[leftTableIndex]) {
2029 2030
    /* left block is empty */
    return 1;
2031
  } else if (rightTableBlockIndex > pSupporter->numOfBlocksPerTable[rightTableIndex]) {
2032 2033 2034 2035 2036 2037 2038
    /* right block is empty */
    return -1;
  }

  STableBlockInfo* pLeftBlockInfoEx = &pSupporter->pDataBlockInfo[leftTableIndex][leftTableBlockIndex];
  STableBlockInfo* pRightBlockInfoEx = &pSupporter->pDataBlockInfo[rightTableIndex][rightTableBlockIndex];

H
Haojun Liao 已提交
2039
  //    assert(pLeftBlockInfoEx->compBlock->offset != pRightBlockInfoEx->compBlock->offset);
dengyihao's avatar
dengyihao 已提交
2040
#if 0  // TODO: temporarily comment off requested by Dr. Liao
H
Haojun Liao 已提交
2041 2042
  if (pLeftBlockInfoEx->compBlock->offset == pRightBlockInfoEx->compBlock->offset &&
      pLeftBlockInfoEx->compBlock->last == pRightBlockInfoEx->compBlock->last) {
B
Bomin Zhang 已提交
2043
    tsdbError("error in header file, two block with same offset:%" PRId64, (int64_t)pLeftBlockInfoEx->compBlock->offset);
2044
  }
H
Haojun Liao 已提交
2045
#endif
2046

H
Haojun Liao 已提交
2047
  return pLeftBlockInfoEx->compBlock->offset > pRightBlockInfoEx->compBlock->offset ? 1 : -1;
2048 2049
}

2050
static int32_t createDataBlocksInfo(STsdbReadHandle* pTsdbReadHandle, int32_t numOfBlocks, int32_t* numOfAllocBlocks) {
H
Haojun Liao 已提交
2051 2052
  size_t size = sizeof(STableBlockInfo) * numOfBlocks;

2053 2054
  if (pTsdbReadHandle->allocSize < size) {
    pTsdbReadHandle->allocSize = (int32_t)size;
wafwerar's avatar
wafwerar 已提交
2055
    char* tmp = taosMemoryRealloc(pTsdbReadHandle->pDataBlockInfo, pTsdbReadHandle->allocSize);
H
Haojun Liao 已提交
2056 2057 2058 2059
    if (tmp == NULL) {
      return TSDB_CODE_TDB_OUT_OF_MEMORY;
    }

dengyihao's avatar
dengyihao 已提交
2060
    pTsdbReadHandle->pDataBlockInfo = (STableBlockInfo*)tmp;
2061 2062
  }

2063
  memset(pTsdbReadHandle->pDataBlockInfo, 0, size);
2064 2065
  *numOfAllocBlocks = numOfBlocks;

H
Haojun Liao 已提交
2066
  // access data blocks according to the offset of each block in asc/desc order.
2067
  int32_t numOfTables = (int32_t)taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
2068

2069 2070
  SBlockOrderSupporter sup = {0};
  sup.numOfTables = numOfTables;
wafwerar's avatar
wafwerar 已提交
2071 2072 2073
  sup.numOfBlocksPerTable = taosMemoryCalloc(1, sizeof(int32_t) * numOfTables);
  sup.blockIndexArray = taosMemoryCalloc(1, sizeof(int32_t) * numOfTables);
  sup.pDataBlockInfo = taosMemoryCalloc(1, POINTER_BYTES * numOfTables);
2074

2075
  if (sup.numOfBlocksPerTable == NULL || sup.blockIndexArray == NULL || sup.pDataBlockInfo == NULL) {
2076
    cleanBlockOrderSupporter(&sup, 0);
2077
    return TSDB_CODE_TDB_OUT_OF_MEMORY;
2078
  }
H
Haojun Liao 已提交
2079

2080
  int32_t cnt = 0;
2081
  int32_t numOfQualTables = 0;
H
Haojun Liao 已提交
2082

2083
  for (int32_t j = 0; j < numOfTables; ++j) {
2084
    STableCheckInfo* pTableCheck = (STableCheckInfo*)taosArrayGet(pTsdbReadHandle->pTableCheckInfo, j);
2085 2086 2087
    if (pTableCheck->numOfBlocks <= 0) {
      continue;
    }
H
Haojun Liao 已提交
2088

H
refact  
Hongze Cheng 已提交
2089
    SBlock* pBlock = pTableCheck->pCompInfo->blocks;
2090
    sup.numOfBlocksPerTable[numOfQualTables] = pTableCheck->numOfBlocks;
2091

wafwerar's avatar
wafwerar 已提交
2092
    char* buf = taosMemoryMalloc(sizeof(STableBlockInfo) * pTableCheck->numOfBlocks);
2093
    if (buf == NULL) {
2094
      cleanBlockOrderSupporter(&sup, numOfQualTables);
2095
      return TSDB_CODE_TDB_OUT_OF_MEMORY;
2096 2097
    }

2098
    sup.pDataBlockInfo[numOfQualTables] = (STableBlockInfo*)buf;
2099 2100

    for (int32_t k = 0; k < pTableCheck->numOfBlocks; ++k) {
H
Haojun Liao 已提交
2101
      STableBlockInfo* pBlockInfo = &sup.pDataBlockInfo[numOfQualTables][k];
2102

H
Haojun Liao 已提交
2103 2104
      pBlockInfo->compBlock = &pBlock[k];
      pBlockInfo->pTableCheckInfo = pTableCheck;
2105 2106 2107
      cnt++;
    }

2108
    numOfQualTables++;
2109 2110
  }

H
Haojun Liao 已提交
2111
  assert(numOfBlocks == cnt);
2112

H
Haojun Liao 已提交
2113 2114
  // since there is only one table qualified, blocks are not sorted
  if (numOfQualTables == 1) {
2115
    memcpy(pTsdbReadHandle->pDataBlockInfo, sup.pDataBlockInfo[0], sizeof(STableBlockInfo) * numOfBlocks);
H
Haojun Liao 已提交
2116
    cleanBlockOrderSupporter(&sup, numOfQualTables);
2117

H
Haojun Liao 已提交
2118
    tsdbDebug("%p create data blocks info struct completed for 1 table, %d blocks not sorted %s", pTsdbReadHandle, cnt,
dengyihao's avatar
dengyihao 已提交
2119
              pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
2120 2121
    return TSDB_CODE_SUCCESS;
  }
2122

H
Haojun Liao 已提交
2123
  tsdbDebug("%p create data blocks info struct completed, %d blocks in %d tables %s", pTsdbReadHandle, cnt,
dengyihao's avatar
dengyihao 已提交
2124
            numOfQualTables, pTsdbReadHandle->idStr);
2125

2126
  assert(cnt <= numOfBlocks && numOfQualTables <= numOfTables);  // the pTableQueryInfo[j]->numOfBlocks may be 0
2127
  sup.numOfTables = numOfQualTables;
2128

2129
  SMultiwayMergeTreeInfo* pTree = NULL;
dengyihao's avatar
dengyihao 已提交
2130
  uint8_t                 ret = tMergeTreeCreate(&pTree, sup.numOfTables, &sup, dataBlockOrderCompar);
2131 2132
  if (ret != TSDB_CODE_SUCCESS) {
    cleanBlockOrderSupporter(&sup, numOfTables);
2133
    return TSDB_CODE_TDB_OUT_OF_MEMORY;
2134 2135 2136 2137 2138
  }

  int32_t numOfTotal = 0;

  while (numOfTotal < cnt) {
2139
    int32_t pos = tMergeTreeGetChosenIndex(pTree);
2140 2141
    int32_t index = sup.blockIndexArray[pos]++;

H
Haojun Liao 已提交
2142
    STableBlockInfo* pBlocksInfo = sup.pDataBlockInfo[pos];
2143
    pTsdbReadHandle->pDataBlockInfo[numOfTotal++] = pBlocksInfo[index];
2144 2145

    // set data block index overflow, in order to disable the offset comparator
2146 2147
    if (sup.blockIndexArray[pos] >= sup.numOfBlocksPerTable[pos]) {
      sup.blockIndexArray[pos] = sup.numOfBlocksPerTable[pos] + 1;
2148
    }
2149

H
Haojun Liao 已提交
2150
    tMergeTreeAdjust(pTree, tMergeTreeGetAdjustIndex(pTree));
2151 2152 2153 2154 2155
  }

  /*
   * available when no import exists
   * for(int32_t i = 0; i < cnt - 1; ++i) {
H
Haojun Liao 已提交
2156
   *   assert((*pDataBlockInfo)[i].compBlock->offset < (*pDataBlockInfo)[i+1].compBlock->offset);
2157 2158 2159
   * }
   */

H
Haojun Liao 已提交
2160
  tsdbDebug("%p %d data blocks sort completed, %s", pTsdbReadHandle, cnt, pTsdbReadHandle->idStr);
2161
  cleanBlockOrderSupporter(&sup, numOfTables);
wafwerar's avatar
wafwerar 已提交
2162
  taosMemoryFree(pTree);
2163 2164 2165 2166

  return TSDB_CODE_SUCCESS;
}

2167
static int32_t getFirstFileDataBlock(STsdbReadHandle* pTsdbReadHandle, bool* exists);
H
Haojun Liao 已提交
2168

dengyihao's avatar
dengyihao 已提交
2169 2170
static int32_t getDataBlockRv(STsdbReadHandle* pTsdbReadHandle, STableBlockInfo* pNext, bool* exists) {
  int32_t        step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
2171
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
H
Haojun Liao 已提交
2172

dengyihao's avatar
dengyihao 已提交
2173
  while (1) {
2174
    int32_t code = loadFileDataBlock(pTsdbReadHandle, pNext->compBlock, pNext->pTableCheckInfo, exists);
H
Haojun Liao 已提交
2175 2176 2177 2178
    if (code != TSDB_CODE_SUCCESS || *exists) {
      return code;
    }

2179 2180
    if ((cur->slot == pTsdbReadHandle->numOfBlocks - 1 && ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
        (cur->slot == 0 && !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
H
Haojun Liao 已提交
2181
      // all data blocks in current file has been checked already, try next file if exists
2182
      return getFirstFileDataBlock(pTsdbReadHandle, exists);
H
Haojun Liao 已提交
2183 2184 2185 2186
    } else {  // next block of the same file
      cur->slot += step;
      cur->mixBlock = false;
      cur->blockCompleted = false;
2187
      pNext = &pTsdbReadHandle->pDataBlockInfo[cur->slot];
H
Haojun Liao 已提交
2188 2189 2190 2191
    }
  }
}

2192 2193 2194
static int32_t getFirstFileDataBlock(STsdbReadHandle* pTsdbReadHandle, bool* exists) {
  pTsdbReadHandle->numOfBlocks = 0;
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
H
Haojun Liao 已提交
2195 2196 2197

  int32_t code = TSDB_CODE_SUCCESS;

2198
  int32_t numOfBlocks = 0;
2199
  int32_t numOfTables = (int32_t)taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
2200

dengyihao's avatar
dengyihao 已提交
2201
  STsdbCfg*   pCfg = &pTsdbReadHandle->pTsdb->config;
2202 2203
  STimeWindow win = TSWINDOW_INITIALIZER;

H
Hongze Cheng 已提交
2204
  while (true) {
2205
    tsdbRLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Hongze Cheng 已提交
2206

2207 2208
    if ((pTsdbReadHandle->pFileGroup = tsdbFSIterNext(&pTsdbReadHandle->fileIter)) == NULL) {
      tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Hongze Cheng 已提交
2209 2210 2211
      break;
    }

H
refact  
Hongze Cheng 已提交
2212
    tsdbGetFidKeyRange(pCfg->days, pCfg->precision, pTsdbReadHandle->pFileGroup->fid, &win.skey, &win.ekey);
2213 2214

    // current file are not overlapped with query time window, ignore remain files
2215 2216 2217
    if ((ASCENDING_TRAVERSE(pTsdbReadHandle->order) && win.skey > pTsdbReadHandle->window.ekey) ||
        (!ASCENDING_TRAVERSE(pTsdbReadHandle->order) && win.ekey < pTsdbReadHandle->window.ekey)) {
      tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Haojun Liao 已提交
2218 2219
      tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, %s", pTsdbReadHandle,
                pTsdbReadHandle->window.skey, pTsdbReadHandle->window.ekey, pTsdbReadHandle->idStr);
2220 2221
      pTsdbReadHandle->pFileGroup = NULL;
      assert(pTsdbReadHandle->numOfBlocks == 0);
2222 2223 2224
      break;
    }

2225 2226
    if (tsdbSetAndOpenReadFSet(&pTsdbReadHandle->rhelper, pTsdbReadHandle->pFileGroup) < 0) {
      tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Hongze Cheng 已提交
2227 2228 2229 2230
      code = terrno;
      break;
    }

2231
    tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Hongze Cheng 已提交
2232

2233
    if (tsdbLoadBlockIdx(&pTsdbReadHandle->rhelper) < 0) {
H
Hongze Cheng 已提交
2234 2235 2236 2237
      code = terrno;
      break;
    }

2238
    if ((code = getFileCompInfo(pTsdbReadHandle, &numOfBlocks)) != TSDB_CODE_SUCCESS) {
2239 2240
      break;
    }
H
Haojun Liao 已提交
2241

H
Haojun Liao 已提交
2242 2243
    tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %s", pTsdbReadHandle, numOfBlocks, numOfTables,
              pTsdbReadHandle->pFileGroup->fid, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
2244

2245 2246 2247 2248
    assert(numOfBlocks >= 0);
    if (numOfBlocks == 0) {
      continue;
    }
H
Haojun Liao 已提交
2249

2250
    // todo return error code to query engine
dengyihao's avatar
dengyihao 已提交
2251 2252
    if ((code = createDataBlocksInfo(pTsdbReadHandle, numOfBlocks, &pTsdbReadHandle->numOfBlocks)) !=
        TSDB_CODE_SUCCESS) {
2253 2254
      break;
    }
H
Haojun Liao 已提交
2255

2256 2257
    assert(numOfBlocks >= pTsdbReadHandle->numOfBlocks);
    if (pTsdbReadHandle->numOfBlocks > 0) {
2258 2259 2260
      break;
    }
  }
H
Haojun Liao 已提交
2261

2262
  // no data in file anymore
2263
  if (pTsdbReadHandle->numOfBlocks <= 0 || code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
2264
    if (code == TSDB_CODE_SUCCESS) {
2265
      assert(pTsdbReadHandle->pFileGroup == NULL);
H
Haojun Liao 已提交
2266 2267
    }

D
dapan1121 已提交
2268
    cur->fid = INT32_MIN;  // denote that there are no data in file anymore
H
Haojun Liao 已提交
2269 2270
    *exists = false;
    return code;
2271
  }
H
Haojun Liao 已提交
2272

2273
  assert(pTsdbReadHandle->pFileGroup != NULL && pTsdbReadHandle->numOfBlocks > 0);
dengyihao's avatar
dengyihao 已提交
2274
  cur->slot = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 0 : pTsdbReadHandle->numOfBlocks - 1;
2275
  cur->fid = pTsdbReadHandle->pFileGroup->fid;
H
Haojun Liao 已提交
2276

2277 2278
  STableBlockInfo* pBlockInfo = &pTsdbReadHandle->pDataBlockInfo[cur->slot];
  return getDataBlockRv(pTsdbReadHandle, pBlockInfo, exists);
H
Haojun Liao 已提交
2279 2280 2281 2282 2283 2284 2285
}

static bool isEndFileDataBlock(SQueryFilePos* cur, int32_t numOfBlocks, bool ascTrav) {
  assert(cur != NULL && numOfBlocks > 0);
  return (cur->slot == numOfBlocks - 1 && ascTrav) || (cur->slot == 0 && !ascTrav);
}

2286
static void moveToNextDataBlockInCurrentFile(STsdbReadHandle* pTsdbReadHandle) {
dengyihao's avatar
dengyihao 已提交
2287
  int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
H
Haojun Liao 已提交
2288

2289 2290
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
  assert(cur->slot < pTsdbReadHandle->numOfBlocks && cur->slot >= 0);
H
Haojun Liao 已提交
2291 2292

  cur->slot += step;
dengyihao's avatar
dengyihao 已提交
2293
  cur->mixBlock = false;
H
Haojun Liao 已提交
2294
  cur->blockCompleted = false;
2295
}
H
Haojun Liao 已提交
2296 2297

int32_t tsdbGetFileBlocksDistInfo(tsdbReaderT* queryHandle, STableBlockDistInfo* pTableBlockInfo) {
dengyihao's avatar
dengyihao 已提交
2298
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)queryHandle;
H
Haojun Liao 已提交
2299

H
Haojun Liao 已提交
2300
  pTableBlockInfo->totalSize = 0;
2301
  pTableBlockInfo->totalRows = 0;
H
Haojun Liao 已提交
2302

2303
  STsdbFS* pFileHandle = REPO_FS(pTsdbReadHandle->pTsdb);
H
Haojun Liao 已提交
2304 2305

  // find the start data block in file
2306 2307
  pTsdbReadHandle->locateStart = true;
  STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
H
refact  
Hongze Cheng 已提交
2308
  int32_t   fid = getFileIdFromKey(pTsdbReadHandle->window.skey, pCfg->days, pCfg->precision);
H
Haojun Liao 已提交
2309 2310

  tsdbRLockFS(pFileHandle);
2311 2312
  tsdbFSIterInit(&pTsdbReadHandle->fileIter, pFileHandle, pTsdbReadHandle->order);
  tsdbFSIterSeek(&pTsdbReadHandle->fileIter, fid);
H
Haojun Liao 已提交
2313 2314
  tsdbUnLockFS(pFileHandle);

H
Haojun Liao 已提交
2315
  pTableBlockInfo->numOfFiles += 1;
H
Haojun Liao 已提交
2316

H
Haojun Liao 已提交
2317
  int32_t     code = TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
2318
  int32_t     numOfBlocks = 0;
2319
  int32_t     numOfTables = (int32_t)taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
dengyihao's avatar
dengyihao 已提交
2320
  int         defaultRows = 4096;  // TSDB_DEFAULT_BLOCK_ROWS(pCfg->maxRowsPerFileBlock);
H
Haojun Liao 已提交
2321 2322
  STimeWindow win = TSWINDOW_INITIALIZER;

H
Haojun Liao 已提交
2323 2324
  bool ascTraverse = ASCENDING_TRAVERSE(pTsdbReadHandle->order);

H
Haojun Liao 已提交
2325 2326
  while (true) {
    numOfBlocks = 0;
2327
    tsdbRLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Haojun Liao 已提交
2328

2329 2330
    if ((pTsdbReadHandle->pFileGroup = tsdbFSIterNext(&pTsdbReadHandle->fileIter)) == NULL) {
      tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Haojun Liao 已提交
2331 2332 2333
      break;
    }

H
refact  
Hongze Cheng 已提交
2334
    tsdbGetFidKeyRange(pCfg->days, pCfg->precision, pTsdbReadHandle->pFileGroup->fid, &win.skey, &win.ekey);
H
Haojun Liao 已提交
2335 2336

    // current file are not overlapped with query time window, ignore remain files
dengyihao's avatar
dengyihao 已提交
2337 2338
    if ((ascTraverse && win.skey > pTsdbReadHandle->window.ekey) ||
        (!ascTraverse && win.ekey < pTsdbReadHandle->window.ekey)) {
2339
      tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Haojun Liao 已提交
2340 2341
      tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, %s", pTsdbReadHandle,
                pTsdbReadHandle->window.skey, pTsdbReadHandle->window.ekey, pTsdbReadHandle->idStr);
2342
      pTsdbReadHandle->pFileGroup = NULL;
H
Haojun Liao 已提交
2343 2344 2345
      break;
    }

H
Haojun Liao 已提交
2346
    pTableBlockInfo->numOfFiles += 1;
2347 2348
    if (tsdbSetAndOpenReadFSet(&pTsdbReadHandle->rhelper, pTsdbReadHandle->pFileGroup) < 0) {
      tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Haojun Liao 已提交
2349 2350 2351 2352
      code = terrno;
      break;
    }

2353
    tsdbUnLockFS(REPO_FS(pTsdbReadHandle->pTsdb));
H
Haojun Liao 已提交
2354

2355
    if (tsdbLoadBlockIdx(&pTsdbReadHandle->rhelper) < 0) {
H
Haojun Liao 已提交
2356 2357 2358 2359
      code = terrno;
      break;
    }

2360
    if ((code = getFileCompInfo(pTsdbReadHandle, &numOfBlocks)) != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
2361 2362 2363
      break;
    }

H
Haojun Liao 已提交
2364 2365
    tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %s", pTsdbReadHandle, numOfBlocks, numOfTables,
              pTsdbReadHandle->pFileGroup->fid, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
2366 2367 2368 2369 2370 2371

    if (numOfBlocks == 0) {
      continue;
    }

    for (int32_t i = 0; i < numOfTables; ++i) {
2372
      STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
H
Haojun Liao 已提交
2373 2374 2375

      SBlock* pBlock = pCheckInfo->pCompInfo->blocks;
      for (int32_t j = 0; j < pCheckInfo->numOfBlocks; ++j) {
H
Haojun Liao 已提交
2376
        pTableBlockInfo->totalSize += pBlock[j].len;
H
Haojun Liao 已提交
2377

H
Haojun Liao 已提交
2378
        int32_t numOfRows = pBlock[j].numOfRows;
2379
        pTableBlockInfo->totalRows += numOfRows;
H
Haojun Liao 已提交
2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390
        if (numOfRows > pTableBlockInfo->maxRows) {
          pTableBlockInfo->maxRows = numOfRows;
        }

        if (numOfRows < pTableBlockInfo->minRows) {
          pTableBlockInfo->minRows = numOfRows;
        }

        if (numOfRows < defaultRows) {
          pTableBlockInfo->numOfSmallBlocks += 1;
        }
dengyihao's avatar
dengyihao 已提交
2391 2392 2393
        //        int32_t  stepIndex = (numOfRows-1)/TSDB_BLOCK_DIST_STEP_ROWS;
        //        SFileBlockInfo *blockInfo = (SFileBlockInfo*)taosArrayGet(pTableBlockInfo->dataBlockInfos, stepIndex);
        //        blockInfo->numBlocksOfStep++;
H
Haojun Liao 已提交
2394 2395 2396 2397 2398 2399 2400
      }
    }
  }

  return code;
}

2401 2402 2403
static int32_t getDataBlocksInFiles(STsdbReadHandle* pTsdbReadHandle, bool* exists) {
  STsdbFS*       pFileHandle = REPO_FS(pTsdbReadHandle->pTsdb);
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
2404 2405

  // find the start data block in file
2406 2407 2408
  if (!pTsdbReadHandle->locateStart) {
    pTsdbReadHandle->locateStart = true;
    STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
H
refact  
Hongze Cheng 已提交
2409
    int32_t   fid = getFileIdFromKey(pTsdbReadHandle->window.skey, pCfg->days, pCfg->precision);
H
Haojun Liao 已提交
2410

H
Hongze Cheng 已提交
2411
    tsdbRLockFS(pFileHandle);
2412 2413
    tsdbFSIterInit(&pTsdbReadHandle->fileIter, pFileHandle, pTsdbReadHandle->order);
    tsdbFSIterSeek(&pTsdbReadHandle->fileIter, fid);
H
Hongze Cheng 已提交
2414
    tsdbUnLockFS(pFileHandle);
2415

2416
    return getFirstFileDataBlock(pTsdbReadHandle, exists);
2417
  } else {
2418
    // check if current file block is all consumed
2419
    STableBlockInfo* pBlockInfo = &pTsdbReadHandle->pDataBlockInfo[cur->slot];
2420
    STableCheckInfo* pCheckInfo = pBlockInfo->pTableCheckInfo;
H
Haojun Liao 已提交
2421

2422
    // current block is done, try next
H
Haojun Liao 已提交
2423
    if ((!cur->mixBlock) || cur->blockCompleted) {
H
Haojun Liao 已提交
2424
      // all data blocks in current file has been checked already, try next file if exists
2425
    } else {
H
Haojun Liao 已提交
2426 2427
      tsdbDebug("%p continue in current data block, index:%d, pos:%d, %s", pTsdbReadHandle, cur->slot, cur->pos,
                pTsdbReadHandle->idStr);
2428 2429
      int32_t code = handleDataMergeIfNeeded(pTsdbReadHandle, pBlockInfo->compBlock, pCheckInfo);
      *exists = (pTsdbReadHandle->realNumOfRows > 0);
H
Haojun Liao 已提交
2430

H
Haojun Liao 已提交
2431 2432 2433 2434 2435 2436 2437
      if (code != TSDB_CODE_SUCCESS || *exists) {
        return code;
      }
    }

    // current block is empty, try next block in file
    // all data blocks in current file has been checked already, try next file if exists
2438 2439
    if (isEndFileDataBlock(cur, pTsdbReadHandle->numOfBlocks, ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
      return getFirstFileDataBlock(pTsdbReadHandle, exists);
H
Haojun Liao 已提交
2440
    } else {
2441 2442 2443
      moveToNextDataBlockInCurrentFile(pTsdbReadHandle);
      STableBlockInfo* pNext = &pTsdbReadHandle->pDataBlockInfo[cur->slot];
      return getDataBlockRv(pTsdbReadHandle, pNext, exists);
2444 2445
    }
  }
2446 2447
}

2448 2449
static bool doHasDataInBuffer(STsdbReadHandle* pTsdbReadHandle) {
  size_t numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
dengyihao's avatar
dengyihao 已提交
2450

2451 2452
  while (pTsdbReadHandle->activeIndex < numOfTables) {
    if (hasMoreDataInCache(pTsdbReadHandle)) {
2453 2454
      return true;
    }
H
Haojun Liao 已提交
2455

2456
    pTsdbReadHandle->activeIndex += 1;
2457
  }
H
Haojun Liao 已提交
2458

2459 2460 2461
  return false;
}

dengyihao's avatar
dengyihao 已提交
2462
// todo not unref yet, since it is not support multi-group interpolation query
H
Haojun Liao 已提交
2463
static UNUSED_FUNC void changeQueryHandleForInterpQuery(tsdbReaderT pHandle) {
H
Haojun Liao 已提交
2464
  // filter the queried time stamp in the first place
dengyihao's avatar
dengyihao 已提交
2465
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)pHandle;
H
Haojun Liao 已提交
2466 2467

  // starts from the buffer in case of descending timestamp order check data blocks
2468
  size_t numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
H
Haojun Liao 已提交
2469 2470

  int32_t i = 0;
dengyihao's avatar
dengyihao 已提交
2471
  while (i < numOfTables) {
2472
    STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
H
Haojun Liao 已提交
2473 2474

    // the first qualified table for interpolation query
dengyihao's avatar
dengyihao 已提交
2475 2476 2477 2478
    //    if ((pTsdbReadHandle->window.skey <= pCheckInfo->pTableObj->lastKey) &&
    //        (pCheckInfo->pTableObj->lastKey != TSKEY_INITIAL_VAL)) {
    //      break;
    //    }
H
Haojun Liao 已提交
2479 2480 2481 2482 2483 2484 2485 2486 2487

    i++;
  }

  // there are no data in all the tables
  if (i == numOfTables) {
    return;
  }

dengyihao's avatar
dengyihao 已提交
2488
  STableCheckInfo info = *(STableCheckInfo*)taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
2489
  taosArrayClear(pTsdbReadHandle->pTableCheckInfo);
H
Haojun Liao 已提交
2490

2491 2492
  info.lastKey = pTsdbReadHandle->window.skey;
  taosArrayPush(pTsdbReadHandle->pTableCheckInfo, &info);
H
Haojun Liao 已提交
2493 2494 2495
}

static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int maxRowsToRead, STimeWindow* win,
2496
                                 STsdbReadHandle* pTsdbReadHandle) {
dengyihao's avatar
dengyihao 已提交
2497 2498
  int       numOfRows = 0;
  int32_t   numOfCols = (int32_t)taosArrayGetSize(pTsdbReadHandle->pColumns);
2499
  STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
H
Haojun Liao 已提交
2500 2501
  win->skey = TSKEY_INITIAL_VAL;

dengyihao's avatar
dengyihao 已提交
2502 2503
  int64_t   st = taosGetTimestampUs();
  int16_t   rv = -1;
D
fix bug  
dapan1121 已提交
2504
  STSchema* pSchema = NULL;
H
Haojun Liao 已提交
2505 2506

  do {
H
Haojun Liao 已提交
2507
    STSRow* row = getSRowInTableMem(pCheckInfo, pTsdbReadHandle->order, pCfg->update, NULL);
H
Haojun Liao 已提交
2508 2509 2510 2511
    if (row == NULL) {
      break;
    }

H
Haojun Liao 已提交
2512
    TSKEY key = TD_ROW_KEY(row);
dengyihao's avatar
dengyihao 已提交
2513 2514 2515 2516
    if ((key > maxKey && ASCENDING_TRAVERSE(pTsdbReadHandle->order)) ||
        (key < maxKey && !ASCENDING_TRAVERSE(pTsdbReadHandle->order))) {
      tsdbDebug("%p key:%" PRIu64 " beyond qrange:%" PRId64 " - %" PRId64 ", no more data in buffer", pTsdbReadHandle,
                key, pTsdbReadHandle->window.skey, pTsdbReadHandle->window.ekey);
H
Haojun Liao 已提交
2517 2518 2519 2520 2521 2522 2523 2524 2525

      break;
    }

    if (win->skey == INT64_MIN) {
      win->skey = key;
    }

    win->ekey = key;
H
Haojun Liao 已提交
2526
    if (rv != TD_ROW_SVER(row)) {
H
Hongze Cheng 已提交
2527
      pSchema = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), pCheckInfo->tableId, 0);
H
Haojun Liao 已提交
2528
      rv = TD_ROW_SVER(row);
D
fix bug  
dapan1121 已提交
2529
    }
dengyihao's avatar
dengyihao 已提交
2530 2531
    mergeTwoRowFromMem(pTsdbReadHandle, maxRowsToRead, numOfRows, row, NULL, numOfCols, pCheckInfo->tableId, pSchema,
                       NULL, true);
H
Haojun Liao 已提交
2532 2533 2534 2535 2536 2537

    if (++numOfRows >= maxRowsToRead) {
      moveToNextRowInMem(pCheckInfo);
      break;
    }

dengyihao's avatar
dengyihao 已提交
2538
  } while (moveToNextRowInMem(pCheckInfo));
H
Haojun Liao 已提交
2539 2540 2541 2542

  assert(numOfRows <= maxRowsToRead);

  // if the buffer is not full in case of descending order query, move the data in the front of the buffer
2543
  if (!ASCENDING_TRAVERSE(pTsdbReadHandle->order) && numOfRows < maxRowsToRead) {
H
Haojun Liao 已提交
2544 2545
    int32_t emptySize = maxRowsToRead - numOfRows;

dengyihao's avatar
dengyihao 已提交
2546
    for (int32_t i = 0; i < numOfCols; ++i) {
2547
      SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
dengyihao's avatar
dengyihao 已提交
2548 2549
      memmove((char*)pColInfo->pData, (char*)pColInfo->pData + emptySize * pColInfo->info.bytes,
              numOfRows * pColInfo->info.bytes);
H
Haojun Liao 已提交
2550 2551 2552 2553
    }
  }

  int64_t elapsedTime = taosGetTimestampUs() - st;
dengyihao's avatar
dengyihao 已提交
2554 2555
  tsdbDebug("%p build data block from cache completed, elapsed time:%" PRId64 " us, numOfRows:%d, numOfCols:%d, %s",
            pTsdbReadHandle, elapsedTime, numOfRows, numOfCols, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
2556 2557 2558 2559

  return numOfRows;
}

2560 2561
static int32_t getAllTableList(SMeta* pMeta, uint64_t uid, SArray* list) {
  SMCtbCursor* pCur = metaOpenCtbCursor(pMeta, uid);
H
Haojun Liao 已提交
2562

2563 2564 2565 2566 2567
  while (1) {
    tb_uid_t id = metaCtbCursorNext(pCur);
    if (id == 0) {
      break;
    }
H
Haojun Liao 已提交
2568

2569
    STableKeyInfo info = {.lastKey = TSKEY_INITIAL_VAL, uid = id};
H
Haojun Liao 已提交
2570 2571 2572
    taosArrayPush(list, &info);
  }

2573
  metaCloseCtbCurosr(pCur);
H
Haojun Liao 已提交
2574 2575 2576 2577 2578 2579 2580 2581
  return TSDB_CODE_SUCCESS;
}

static void destroyHelper(void* param) {
  if (param == NULL) {
    return;
  }

dengyihao's avatar
dengyihao 已提交
2582 2583 2584 2585 2586 2587
  //  tQueryInfo* pInfo = (tQueryInfo*)param;
  //  if (pInfo->optr != TSDB_RELATION_IN) {
  //    taosMemoryFreeClear(pInfo->q);
  //  } else {
  //    taosHashCleanup((SHashObj *)(pInfo->q));
  //  }
H
Haojun Liao 已提交
2588

wafwerar's avatar
wafwerar 已提交
2589
  taosMemoryFree(param);
H
Haojun Liao 已提交
2590 2591
}

dengyihao's avatar
dengyihao 已提交
2592 2593
#define TSDB_PREV_ROW 0x1
#define TSDB_NEXT_ROW 0x2
2594

dengyihao's avatar
dengyihao 已提交
2595
static bool loadBlockOfActiveTable(STsdbReadHandle* pTsdbReadHandle) {
2596
  if (pTsdbReadHandle->checkFiles) {
H
Haojun Liao 已提交
2597 2598
    // check if the query range overlaps with the file data block
    bool exists = true;
H
Haojun Liao 已提交
2599

2600
    int32_t code = getDataBlocksInFiles(pTsdbReadHandle, &exists);
H
Haojun Liao 已提交
2601
    if (code != TSDB_CODE_SUCCESS) {
2602
      pTsdbReadHandle->checkFiles = false;
H
Haojun Liao 已提交
2603 2604
      return false;
    }
H
Haojun Liao 已提交
2605

H
Haojun Liao 已提交
2606
    if (exists) {
dengyihao's avatar
dengyihao 已提交
2607
      tsdbRetrieveDataBlock((tsdbReaderT*)pTsdbReadHandle, NULL);
2608 2609 2610
      if (pTsdbReadHandle->currentLoadExternalRows && pTsdbReadHandle->window.skey == pTsdbReadHandle->window.ekey) {
        SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, 0);
        assert(*(int64_t*)pColInfo->pData == pTsdbReadHandle->window.skey);
H
Haojun Liao 已提交
2611 2612
      }

dengyihao's avatar
dengyihao 已提交
2613
      pTsdbReadHandle->currentLoadExternalRows = false;  // clear the flag, since the exact matched row is found.
H
Haojun Liao 已提交
2614 2615
      return exists;
    }
H
Haojun Liao 已提交
2616

2617
    pTsdbReadHandle->checkFiles = false;
H
Haojun Liao 已提交
2618
  }
H
Haojun Liao 已提交
2619

2620 2621
  if (hasMoreDataInCache(pTsdbReadHandle)) {
    pTsdbReadHandle->currentLoadExternalRows = false;
H
Haojun Liao 已提交
2622 2623
    return true;
  }
H
Haojun Liao 已提交
2624

H
Haojun Liao 已提交
2625
  // current result is empty
dengyihao's avatar
dengyihao 已提交
2626 2627 2628
  if (pTsdbReadHandle->currentLoadExternalRows && pTsdbReadHandle->window.skey == pTsdbReadHandle->window.ekey &&
      pTsdbReadHandle->cur.rows == 0) {
    //    STsdbMemTable* pMemRef = pTsdbReadHandle->pMemTable;
H
Haojun Liao 已提交
2629

dengyihao's avatar
dengyihao 已提交
2630 2631
    //    doGetExternalRow(pTsdbReadHandle, TSDB_PREV_ROW, pMemRef);
    //    doGetExternalRow(pTsdbReadHandle, TSDB_NEXT_ROW, pMemRef);
H
Haojun Liao 已提交
2632

2633
    bool result = tsdbGetExternalRow(pTsdbReadHandle);
H
Haojun Liao 已提交
2634

dengyihao's avatar
dengyihao 已提交
2635 2636
    //    pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbReadHandle->prev);
    //    pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbReadHandle->next);
2637
    pTsdbReadHandle->currentLoadExternalRows = false;
H
Haojun Liao 已提交
2638 2639

    return result;
2640
  }
H
Haojun Liao 已提交
2641

H
Haojun Liao 已提交
2642 2643
  return false;
}
2644

2645
static bool loadCachedLastRow(STsdbReadHandle* pTsdbReadHandle) {
H
Haojun Liao 已提交
2646
  // the last row is cached in buffer, return it directly.
2647
  // here note that the pTsdbReadHandle->window must be the TS_INITIALIZER
dengyihao's avatar
dengyihao 已提交
2648
  int32_t numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pTsdbReadHandle));
2649
  size_t  numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
H
Haojun Liao 已提交
2650 2651
  assert(numOfTables > 0 && numOfCols > 0);

2652
  SQueryFilePos* cur = &pTsdbReadHandle->cur;
2653

dengyihao's avatar
dengyihao 已提交
2654 2655 2656
  STSRow* pRow = NULL;
  TSKEY   key = TSKEY_INITIAL_VAL;
  int32_t step = ASCENDING_TRAVERSE(pTsdbReadHandle->order) ? 1 : -1;
2657 2658 2659

  if (++pTsdbReadHandle->activeIndex < numOfTables) {
    STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, pTsdbReadHandle->activeIndex);
dengyihao's avatar
dengyihao 已提交
2660 2661 2662 2663 2664 2665
    //    int32_t ret = tsdbGetCachedLastRow(pCheckInfo->pTableObj, &pRow, &key);
    //    if (ret != TSDB_CODE_SUCCESS) {
    //      return false;
    //    }
    mergeTwoRowFromMem(pTsdbReadHandle, pTsdbReadHandle->outputCapacity, 0, pRow, NULL, numOfCols, pCheckInfo->tableId,
                       NULL, NULL, true);
wafwerar's avatar
wafwerar 已提交
2666
    taosMemoryFreeClear(pRow);
H
Haojun Liao 已提交
2667

H
Haojun Liao 已提交
2668 2669 2670
    // update the last key value
    pCheckInfo->lastKey = key + step;

dengyihao's avatar
dengyihao 已提交
2671 2672
    cur->rows = 1;  // only one row
    cur->lastKey = key + step;
H
Haojun Liao 已提交
2673 2674 2675 2676 2677
    cur->mixBlock = true;
    cur->win.skey = key;
    cur->win.ekey = key;

    return true;
2678
  }
H
Haojun Liao 已提交
2679

H
Haojun Liao 已提交
2680 2681 2682
  return false;
}

dengyihao's avatar
dengyihao 已提交
2683
// static bool loadCachedLast(STsdbReadHandle* pTsdbReadHandle) {
2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702
//  // the last row is cached in buffer, return it directly.
//  // here note that the pTsdbReadHandle->window must be the TS_INITIALIZER
//  int32_t tgNumOfCols = (int32_t)QH_GET_NUM_OF_COLS(pTsdbReadHandle);
//  size_t  numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
//  int32_t numOfRows = 0;
//  assert(numOfTables > 0 && tgNumOfCols > 0);
//  SQueryFilePos* cur = &pTsdbReadHandle->cur;
//  TSKEY priKey = TSKEY_INITIAL_VAL;
//  int32_t priIdx = -1;
//  SColumnInfoData* pColInfo = NULL;
//
//  while (++pTsdbReadHandle->activeIndex < numOfTables) {
//    STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, pTsdbReadHandle->activeIndex);
//    STable* pTable = pCheckInfo->pTableObj;
//    char* pData = NULL;
//
//    int32_t numOfCols = pTable->maxColNum;
//
//    if (pTable->lastCols == NULL || pTable->maxColNum <= 0) {
dengyihao's avatar
dengyihao 已提交
2703 2704
//      tsdbWarn("no last cached for table %s, uid:%" PRIu64 ",tid:%d", pTable->name->data, pTable->uid,
//      pTable->tableId); continue;
2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 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 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834
//    }
//
//    int32_t i = 0, j = 0;
//    while(i < tgNumOfCols && j < numOfCols) {
//      pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
//      if (pTable->lastCols[j].colId < pColInfo->info.colId) {
//        j++;
//        continue;
//      } else if (pTable->lastCols[j].colId > pColInfo->info.colId) {
//        i++;
//        continue;
//      }
//
//      pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;
//
//      if (pTable->lastCols[j].bytes > 0) {
//        void* value = pTable->lastCols[j].pData;
//        switch (pColInfo->info.type) {
//          case TSDB_DATA_TYPE_BINARY:
//          case TSDB_DATA_TYPE_NCHAR:
//            memcpy(pData, value, varDataTLen(value));
//            break;
//          case TSDB_DATA_TYPE_NULL:
//          case TSDB_DATA_TYPE_BOOL:
//          case TSDB_DATA_TYPE_TINYINT:
//          case TSDB_DATA_TYPE_UTINYINT:
//            *(uint8_t *)pData = *(uint8_t *)value;
//            break;
//          case TSDB_DATA_TYPE_SMALLINT:
//          case TSDB_DATA_TYPE_USMALLINT:
//            *(uint16_t *)pData = *(uint16_t *)value;
//            break;
//          case TSDB_DATA_TYPE_INT:
//          case TSDB_DATA_TYPE_UINT:
//            *(uint32_t *)pData = *(uint32_t *)value;
//            break;
//          case TSDB_DATA_TYPE_BIGINT:
//          case TSDB_DATA_TYPE_UBIGINT:
//            *(uint64_t *)pData = *(uint64_t *)value;
//            break;
//          case TSDB_DATA_TYPE_FLOAT:
//            SET_FLOAT_PTR(pData, value);
//            break;
//          case TSDB_DATA_TYPE_DOUBLE:
//            SET_DOUBLE_PTR(pData, value);
//            break;
//          case TSDB_DATA_TYPE_TIMESTAMP:
//            if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
//              priKey = tdGetKey(*(TKEY *)value);
//              priIdx = i;
//
//              i++;
//              j++;
//              continue;
//            } else {
//              *(TSKEY *)pData = *(TSKEY *)value;
//            }
//            break;
//          default:
//            memcpy(pData, value, pColInfo->info.bytes);
//        }
//
//        for (int32_t n = 0; n < tgNumOfCols; ++n) {
//          if (n == i) {
//            continue;
//          }
//
//          pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, n);
//          pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;;
//
//          if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
////            *(TSKEY *)pData = pTable->lastCols[j].ts;
//            continue;
//          }
//
//          if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) {
//            setVardataNull(pData, pColInfo->info.type);
//          } else {
//            setNull(pData, pColInfo->info.type, pColInfo->info.bytes);
//          }
//        }
//
//        numOfRows++;
//        assert(numOfRows < pTsdbReadHandle->outputCapacity);
//      }
//
//      i++;
//      j++;
//    }
//
//    // leave the real ts column as the last row, because last function only (not stable) use the last row as res
//    if (priKey != TSKEY_INITIAL_VAL) {
//      pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, priIdx);
//      pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;
//
//      *(TSKEY *)pData = priKey;
//
//      for (int32_t n = 0; n < tgNumOfCols; ++n) {
//        if (n == priIdx) {
//          continue;
//        }
//
//        pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, n);
//        pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;;
//
//        assert (pColInfo->info.colId != PRIMARYKEY_TIMESTAMP_COL_ID);
//
//        if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) {
//          setVardataNull(pData, pColInfo->info.type);
//        } else {
//          setNull(pData, pColInfo->info.type, pColInfo->info.bytes);
//        }
//      }
//
//      numOfRows++;
//    }
//
//    if (numOfRows > 0) {
//      cur->rows     = numOfRows;
//      cur->mixBlock = true;
//
//      return true;
//    }
//  }
//
//  return false;
//}

static bool loadDataBlockFromTableSeq(STsdbReadHandle* pTsdbReadHandle) {
  size_t numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
H
Haojun Liao 已提交
2835 2836 2837
  assert(numOfTables > 0);

  int64_t stime = taosGetTimestampUs();
H
Haojun Liao 已提交
2838

dengyihao's avatar
dengyihao 已提交
2839
  while (pTsdbReadHandle->activeIndex < numOfTables) {
2840
    if (loadBlockOfActiveTable(pTsdbReadHandle)) {
H
Haojun Liao 已提交
2841 2842 2843
      return true;
    }

2844
    STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, pTsdbReadHandle->activeIndex);
H
Haojun Liao 已提交
2845 2846
    pCheckInfo->numOfBlocks = 0;

2847 2848
    pTsdbReadHandle->activeIndex += 1;
    pTsdbReadHandle->locateStart = false;
dengyihao's avatar
dengyihao 已提交
2849 2850
    pTsdbReadHandle->checkFiles = true;
    pTsdbReadHandle->cur.rows = 0;
2851
    pTsdbReadHandle->currentLoadExternalRows = pTsdbReadHandle->loadExternalRow;
H
Haojun Liao 已提交
2852 2853 2854 2855

    terrno = TSDB_CODE_SUCCESS;

    int64_t elapsedTime = taosGetTimestampUs() - stime;
2856
    pTsdbReadHandle->cost.checkForNextTime += elapsedTime;
H
Haojun Liao 已提交
2857 2858 2859
  }

  return false;
2860 2861
}

H
Haojun Liao 已提交
2862
// handle data in cache situation
H
Haojun Liao 已提交
2863
bool tsdbNextDataBlock(tsdbReaderT pHandle) {
dengyihao's avatar
dengyihao 已提交
2864
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)pHandle;
Y
yihaoDeng 已提交
2865

dengyihao's avatar
dengyihao 已提交
2866
  for (int32_t i = 0; i < taosArrayGetSize(pTsdbReadHandle->pColumns); ++i) {
2867 2868 2869 2870
    SColumnInfoData* pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
    colInfoDataCleanup(pColInfo, pTsdbReadHandle->outputCapacity);
  }

2871
  if (emptyQueryTimewindow(pTsdbReadHandle)) {
dengyihao's avatar
dengyihao 已提交
2872 2873
    tsdbDebug("%p query window not overlaps with the data set, no result returned, %s", pTsdbReadHandle,
              pTsdbReadHandle->idStr);
2874 2875 2876
    return false;
  }

Y
yihaoDeng 已提交
2877 2878 2879
  int64_t stime = taosGetTimestampUs();
  int64_t elapsedTime = stime;

2880
  // TODO refactor: remove "type"
2881 2882
  if (pTsdbReadHandle->type == TSDB_QUERY_TYPE_LAST) {
    if (pTsdbReadHandle->cachelastrow == TSDB_CACHED_TYPE_LASTROW) {
dengyihao's avatar
dengyihao 已提交
2883
      //      return loadCachedLastRow(pTsdbReadHandle);
2884
    } else if (pTsdbReadHandle->cachelastrow == TSDB_CACHED_TYPE_LAST) {
dengyihao's avatar
dengyihao 已提交
2885
      //      return loadCachedLast(pTsdbReadHandle);
D
init  
dapan1121 已提交
2886
    }
H
Haojun Liao 已提交
2887
  }
Y
yihaoDeng 已提交
2888

2889 2890
  if (pTsdbReadHandle->loadType == BLOCK_LOAD_TABLE_SEQ_ORDER) {
    return loadDataBlockFromTableSeq(pTsdbReadHandle);
dengyihao's avatar
dengyihao 已提交
2891
  } else {  // loadType == RR and Offset Order
2892
    if (pTsdbReadHandle->checkFiles) {
H
Haojun Liao 已提交
2893 2894 2895
      // check if the query range overlaps with the file data block
      bool exists = true;

2896
      int32_t code = getDataBlocksInFiles(pTsdbReadHandle, &exists);
H
Haojun Liao 已提交
2897
      if (code != TSDB_CODE_SUCCESS) {
2898 2899
        pTsdbReadHandle->activeIndex = 0;
        pTsdbReadHandle->checkFiles = false;
H
Haojun Liao 已提交
2900 2901 2902 2903 2904

        return false;
      }

      if (exists) {
2905
        pTsdbReadHandle->cost.checkForNextTime += (taosGetTimestampUs() - stime);
H
Haojun Liao 已提交
2906 2907
        return exists;
      }
Y
yihaoDeng 已提交
2908

2909 2910
      pTsdbReadHandle->activeIndex = 0;
      pTsdbReadHandle->checkFiles = false;
Y
yihaoDeng 已提交
2911 2912
    }

H
Haojun Liao 已提交
2913
    // TODO: opt by consider the scan order
2914
    bool ret = doHasDataInBuffer(pTsdbReadHandle);
H
Haojun Liao 已提交
2915
    terrno = TSDB_CODE_SUCCESS;
Y
yihaoDeng 已提交
2916

H
Haojun Liao 已提交
2917
    elapsedTime = taosGetTimestampUs() - stime;
2918
    pTsdbReadHandle->cost.checkForNextTime += elapsedTime;
H
Haojun Liao 已提交
2919
    return ret;
Y
yihaoDeng 已提交
2920 2921
  }
}
2922

dengyihao's avatar
dengyihao 已提交
2923
// static int32_t doGetExternalRow(STsdbReadHandle* pTsdbReadHandle, int16_t type, STsdbMemTable* pMemRef) {
2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957
//  STsdbReadHandle* pSecQueryHandle = NULL;
//
//  if (type == TSDB_PREV_ROW && pTsdbReadHandle->prev) {
//    return TSDB_CODE_SUCCESS;
//  }
//
//  if (type == TSDB_NEXT_ROW && pTsdbReadHandle->next) {
//    return TSDB_CODE_SUCCESS;
//  }
//
//  // prepare the structure
//  int32_t numOfCols = (int32_t) QH_GET_NUM_OF_COLS(pTsdbReadHandle);
//
//  if (type == TSDB_PREV_ROW) {
//    pTsdbReadHandle->prev = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
//    if (pTsdbReadHandle->prev == NULL) {
//      terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//      goto out_of_memory;
//    }
//  } else {
//    pTsdbReadHandle->next = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
//    if (pTsdbReadHandle->next == NULL) {
//      terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//      goto out_of_memory;
//    }
//  }
//
//  SArray* row = (type == TSDB_PREV_ROW)? pTsdbReadHandle->prev : pTsdbReadHandle->next;
//
//  for (int32_t i = 0; i < numOfCols; ++i) {
//    SColumnInfoData* pCol = taosArrayGet(pTsdbReadHandle->pColumns, i);
//
//    SColumnInfoData colInfo = {{0}, 0};
//    colInfo.info = pCol->info;
wafwerar's avatar
wafwerar 已提交
2958
//    colInfo.pData = taosMemoryCalloc(1, pCol->info.bytes);
2959 2960 2961 2962 2963 2964 2965 2966 2967
//    if (colInfo.pData == NULL) {
//      terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//      goto out_of_memory;
//    }
//
//    taosArrayPush(row, &colInfo);
//  }
//
//  // load the previous row
2968
//  SQueryTableDataCond cond = {.numOfCols = numOfCols, .loadExternalRows = false, .type = BLOCK_LOAD_OFFSET_SEQ_ORDER};
2969 2970 2971 2972 2973 2974 2975 2976
//  if (type == TSDB_PREV_ROW) {
//    cond.order = TSDB_ORDER_DESC;
//    cond.twindow = (STimeWindow){pTsdbReadHandle->window.skey, INT64_MIN};
//  } else {
//    cond.order = TSDB_ORDER_ASC;
//    cond.twindow = (STimeWindow){pTsdbReadHandle->window.skey, INT64_MAX};
//  }
//
wafwerar's avatar
wafwerar 已提交
2977
//  cond.colList = taosMemoryCalloc(cond.numOfCols, sizeof(SColumnInfo));
2978 2979 2980 2981 2982 2983 2984 2985 2986 2987
//  if (cond.colList == NULL) {
//    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//    goto out_of_memory;
//  }
//
//  for (int32_t i = 0; i < cond.numOfCols; ++i) {
//    SColumnInfoData* pColInfoData = taosArrayGet(pTsdbReadHandle->pColumns, i);
//    memcpy(&cond.colList[i], &pColInfoData->info, sizeof(SColumnInfo));
//  }
//
H
Haojun Liao 已提交
2988
//  pSecQueryHandle = tsdbQueryTablesImpl(pTsdbReadHandle->pTsdb, &cond, pTsdbReadHandle->idStr, pMemRef);
wafwerar's avatar
wafwerar 已提交
2989
//  taosMemoryFreeClear(cond.colList);
2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027
//
//  // current table, only one table
//  STableCheckInfo* pCurrent = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, pTsdbReadHandle->activeIndex);
//
//  SArray* psTable = NULL;
//  pSecQueryHandle->pTableCheckInfo = createCheckInfoFromCheckInfo(pCurrent, pSecQueryHandle->window.skey, &psTable);
//  if (pSecQueryHandle->pTableCheckInfo == NULL) {
//    taosArrayDestroy(psTable);
//    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//    goto out_of_memory;
//  }
//
//
//  tsdbMayTakeMemSnapshot(pSecQueryHandle, psTable);
//  if (!tsdbNextDataBlock((void*)pSecQueryHandle)) {
//    // no result in current query, free the corresponding result rows structure
//    if (type == TSDB_PREV_ROW) {
//      pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbReadHandle->prev);
//    } else {
//      pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbReadHandle->next);
//    }
//
//    goto out_of_memory;
//  }
//
//  SDataBlockInfo blockInfo = {{0}, 0};
//  tsdbRetrieveDataBlockInfo((void*)pSecQueryHandle, &blockInfo);
//  tsdbRetrieveDataBlock((void*)pSecQueryHandle, pSecQueryHandle->defaultLoadColumn);
//
//  row = (type == TSDB_PREV_ROW)? pTsdbReadHandle->prev:pTsdbReadHandle->next;
//  int32_t pos = (type == TSDB_PREV_ROW)?pSecQueryHandle->cur.rows - 1:0;
//
//  for (int32_t i = 0; i < numOfCols; ++i) {
//    SColumnInfoData* pCol = taosArrayGet(row, i);
//    SColumnInfoData* s = taosArrayGet(pSecQueryHandle->pColumns, i);
//    memcpy((char*)pCol->pData, (char*)s->pData + s->info.bytes * pos, pCol->info.bytes);
//  }
//
dengyihao's avatar
dengyihao 已提交
3028
// out_of_memory:
3029
//  tsdbCleanupReadHandle(pSecQueryHandle);
3030 3031 3032
//  return terrno;
//}

H
Haojun Liao 已提交
3033
bool tsdbGetExternalRow(tsdbReaderT pHandle) {
dengyihao's avatar
dengyihao 已提交
3034 3035
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)pHandle;
  SQueryFilePos*   cur = &pTsdbReadHandle->cur;
H
Haojun Liao 已提交
3036

H
Haojun Liao 已提交
3037 3038
  cur->fid = INT32_MIN;
  cur->mixBlock = true;
3039
  if (pTsdbReadHandle->prev == NULL || pTsdbReadHandle->next == NULL) {
H
Haojun Liao 已提交
3040 3041
    cur->rows = 0;
    return false;
H
Haojun Liao 已提交
3042 3043
  }

dengyihao's avatar
dengyihao 已提交
3044
  int32_t numOfCols = (int32_t)QH_GET_NUM_OF_COLS(pTsdbReadHandle);
H
Haojun Liao 已提交
3045
  for (int32_t i = 0; i < numOfCols; ++i) {
3046 3047
    SColumnInfoData* pColInfoData = taosArrayGet(pTsdbReadHandle->pColumns, i);
    SColumnInfoData* first = taosArrayGet(pTsdbReadHandle->prev, i);
H
Haojun Liao 已提交
3048 3049 3050

    memcpy(pColInfoData->pData, first->pData, pColInfoData->info.bytes);

3051
    SColumnInfoData* sec = taosArrayGet(pTsdbReadHandle->next, i);
sangshuduo's avatar
sangshuduo 已提交
3052
    memcpy(((char*)pColInfoData->pData) + pColInfoData->info.bytes, sec->pData, pColInfoData->info.bytes);
H
Haojun Liao 已提交
3053 3054

    if (i == 0 && pColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
H
Haojun Liao 已提交
3055
      cur->win.skey = *(TSKEY*)pColInfoData->pData;
sangshuduo's avatar
sangshuduo 已提交
3056
      cur->win.ekey = *(TSKEY*)(((char*)pColInfoData->pData) + TSDB_KEYSIZE);
H
Haojun Liao 已提交
3057 3058 3059
    }
  }

H
Haojun Liao 已提交
3060 3061
  cur->rows = 2;
  return true;
3062 3063
}

3064
/*
3065
 * if lastRow == NULL, return TSDB_CODE_TDB_NO_CACHE_LAST_ROW
3066
 * else set pRes and return TSDB_CODE_SUCCESS and save lastKey
3067
 */
H
Haojun Liao 已提交
3068
// int32_t tsdbGetCachedLastRow(STable* pTable, STSRow** pRes, TSKEY* lastKey) {
3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084
//  int32_t code = TSDB_CODE_SUCCESS;
//
//  TSDB_RLOCK_TABLE(pTable);
//
//  if (!pTable->lastRow) {
//    code = TSDB_CODE_TDB_NO_CACHE_LAST_ROW;
//    goto out;
//  }
//
//  if (pRes) {
//    *pRes = tdMemRowDup(pTable->lastRow);
//    if (*pRes == NULL) {
//      code = TSDB_CODE_TDB_OUT_OF_MEMORY;
//    }
//  }
//
H
Haojun Liao 已提交
3085
// out:
3086 3087 3088 3089
//  TSDB_RUNLOCK_TABLE(pTable);
//  return code;
//}

3090
bool isTsdbCacheLastRow(tsdbReaderT* pReader) {
dengyihao's avatar
dengyihao 已提交
3091
  return ((STsdbReadHandle*)pReader)->cachelastrow > TSDB_CACHED_TYPE_NONE;
D
fix bug  
dapan1121 已提交
3092 3093
}

dengyihao's avatar
dengyihao 已提交
3094
int32_t checkForCachedLastRow(STsdbReadHandle* pTsdbReadHandle, STableGroupInfo* groupList) {
3095 3096
  assert(pTsdbReadHandle != NULL && groupList != NULL);

dengyihao's avatar
dengyihao 已提交
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120
  //  TSKEY    key = TSKEY_INITIAL_VAL;
  //
  //  SArray* group = taosArrayGetP(groupList->pGroupList, 0);
  //  assert(group != NULL);
  //
  //  STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(group, 0);
  //
  //  int32_t code = 0;
  //
  //  if (((STable*)pInfo->pTable)->lastRow) {
  //    code = tsdbGetCachedLastRow(pInfo->pTable, NULL, &key);
  //    if (code != TSDB_CODE_SUCCESS) {
  //      pTsdbReadHandle->cachelastrow = TSDB_CACHED_TYPE_NONE;
  //    } else {
  //      pTsdbReadHandle->cachelastrow = TSDB_CACHED_TYPE_LASTROW;
  //    }
  //  }
  //
  //  // update the tsdb query time range
  //  if (pTsdbReadHandle->cachelastrow != TSDB_CACHED_TYPE_NONE) {
  //    pTsdbReadHandle->window      = TSWINDOW_INITIALIZER;
  //    pTsdbReadHandle->checkFiles  = false;
  //    pTsdbReadHandle->activeIndex = -1;  // start from -1
  //  }
H
Haojun Liao 已提交
3121

3122
  return TSDB_CODE_SUCCESS;
3123 3124
}

3125 3126
int32_t checkForCachedLast(STsdbReadHandle* pTsdbReadHandle) {
  assert(pTsdbReadHandle != NULL);
D
update  
dapan1121 已提交
3127 3128

  int32_t code = 0;
dengyihao's avatar
dengyihao 已提交
3129 3130 3131
  //  if (pTsdbReadHandle->pTsdb && atomic_load_8(&pTsdbReadHandle->pTsdb->hasCachedLastColumn)){
  //    pTsdbReadHandle->cachelastrow = TSDB_CACHED_TYPE_LAST;
  //  }
D
update  
dapan1121 已提交
3132 3133

  // update the tsdb query time range
3134
  if (pTsdbReadHandle->cachelastrow) {
dengyihao's avatar
dengyihao 已提交
3135
    pTsdbReadHandle->checkFiles = false;
3136
    pTsdbReadHandle->activeIndex = -1;  // start from -1
D
update  
dapan1121 已提交
3137 3138 3139 3140 3141
  }

  return code;
}

dengyihao's avatar
dengyihao 已提交
3142
STimeWindow updateLastrowForEachGroup(STableGroupInfo* groupList) {
H
Haojun Liao 已提交
3143
  STimeWindow window = {INT64_MAX, INT64_MIN};
H
Haojun Liao 已提交
3144

H
Haojun Liao 已提交
3145
  int32_t totalNumOfTable = 0;
3146
  SArray* emptyGroup = taosArrayInit(16, sizeof(int32_t));
H
Haojun Liao 已提交
3147

H
Haojun Liao 已提交
3148 3149
  // NOTE: starts from the buffer in case of descending timestamp order check data blocks
  size_t numOfGroups = taosArrayGetSize(groupList->pGroupList);
dengyihao's avatar
dengyihao 已提交
3150
  for (int32_t j = 0; j < numOfGroups; ++j) {
H
Haojun Liao 已提交
3151 3152
    SArray* pGroup = taosArrayGetP(groupList->pGroupList, j);
    TSKEY   key = TSKEY_INITIAL_VAL;
H
Haojun Liao 已提交
3153

H
Haojun Liao 已提交
3154
    STableKeyInfo keyInfo = {0};
H
Haojun Liao 已提交
3155

H
Haojun Liao 已提交
3156
    size_t numOfTables = taosArrayGetSize(pGroup);
dengyihao's avatar
dengyihao 已提交
3157 3158
    for (int32_t i = 0; i < numOfTables; ++i) {
      STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(pGroup, i);
H
Haojun Liao 已提交
3159

H
Haojun Liao 已提交
3160
      // if the lastKey equals to INT64_MIN, there is no data in this table
dengyihao's avatar
dengyihao 已提交
3161
      TSKEY lastKey = 0;  //((STable*)(pInfo->pTable))->lastKey;
H
Haojun Liao 已提交
3162 3163
      if (key < lastKey) {
        key = lastKey;
H
Haojun Liao 已提交
3164

dengyihao's avatar
dengyihao 已提交
3165
        //        keyInfo.pTable  = pInfo->pTable;
H
Haojun Liao 已提交
3166
        keyInfo.lastKey = key;
dengyihao's avatar
dengyihao 已提交
3167
        pInfo->lastKey = key;
H
Haojun Liao 已提交
3168

H
Haojun Liao 已提交
3169 3170 3171
        if (key < window.skey) {
          window.skey = key;
        }
3172

H
Haojun Liao 已提交
3173 3174 3175 3176
        if (key > window.ekey) {
          window.ekey = key;
        }
      }
3177
    }
H
Haojun Liao 已提交
3178

H
Haojun Liao 已提交
3179
    // more than one table in each group, only one table left for each group
dengyihao's avatar
dengyihao 已提交
3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191
    //    if (keyInfo.pTable != NULL) {
    //      totalNumOfTable++;
    //      if (taosArrayGetSize(pGroup) == 1) {
    //        // do nothing
    //      } else {
    //        taosArrayClear(pGroup);
    //        taosArrayPush(pGroup, &keyInfo);
    //      }
    //    } else {  // mark all the empty groups, and remove it later
    //      taosArrayDestroy(pGroup);
    //      taosArrayPush(emptyGroup, &j);
    //    }
3192
  }
H
Haojun Liao 已提交
3193

H
Haojun Liao 已提交
3194 3195 3196
  // window does not being updated, so set the original
  if (window.skey == INT64_MAX && window.ekey == INT64_MIN) {
    window = TSWINDOW_INITIALIZER;
H
Haojun Liao 已提交
3197
    assert(totalNumOfTable == 0 && taosArrayGetSize(groupList->pGroupList) == numOfGroups);
H
Haojun Liao 已提交
3198 3199
  }

dengyihao's avatar
dengyihao 已提交
3200
  taosArrayRemoveBatch(groupList->pGroupList, TARRAY_GET_START(emptyGroup), (int32_t)taosArrayGetSize(emptyGroup));
3201 3202
  taosArrayDestroy(emptyGroup);

H
Haojun Liao 已提交
3203
  groupList->numOfTables = totalNumOfTable;
H
Haojun Liao 已提交
3204
  return window;
H
hjxilinx 已提交
3205 3206
}

H
Haojun Liao 已提交
3207
void tsdbRetrieveDataBlockInfo(tsdbReaderT* pTsdbReadHandle, SDataBlockInfo* pDataBlockInfo) {
3208
  STsdbReadHandle* pHandle = (STsdbReadHandle*)pTsdbReadHandle;
dengyihao's avatar
dengyihao 已提交
3209
  SQueryFilePos*   cur = &pHandle->cur;
3210 3211

  uint64_t uid = 0;
H
Haojun Liao 已提交
3212

3213
  // there are data in file
D
dapan1121 已提交
3214
  if (pHandle->cur.fid != INT32_MIN) {
3215
    STableBlockInfo* pBlockInfo = &pHandle->pDataBlockInfo[cur->slot];
3216
    uid = pBlockInfo->pTableCheckInfo->tableId;
H
[td-32]  
hjxilinx 已提交
3217
  } else {
3218
    STableCheckInfo* pCheckInfo = taosArrayGet(pHandle->pTableCheckInfo, pHandle->activeIndex);
3219
    uid = pCheckInfo->tableId;
3220
  }
3221

dengyihao's avatar
dengyihao 已提交
3222 3223
  tsdbDebug("data block generated, uid:%" PRIu64 " numOfRows:%d, tsrange:%" PRId64 " - %" PRId64 " %s", uid, cur->rows,
            cur->win.skey, cur->win.ekey, pHandle->idStr);
3224

3225
  pDataBlockInfo->uid = uid;
3226 3227 3228 3229 3230 3231

#if 0
  // for multi-group data query processing test purpose
  pDataBlockInfo->groupId = uid;
#endif

dengyihao's avatar
dengyihao 已提交
3232
  pDataBlockInfo->rows = cur->rows;
H
Haojun Liao 已提交
3233
  pDataBlockInfo->window = cur->win;
S
TD-1057  
Shengliang Guan 已提交
3234
  pDataBlockInfo->numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pHandle));
3235
}
H
hjxilinx 已提交
3236

H
Haojun Liao 已提交
3237 3238 3239
/*
 * return null for mixed data block, if not a complete file data block, the statistics value will always return NULL
 */
3240
int32_t tsdbRetrieveDataBlockStatisInfo(tsdbReaderT* pTsdbReadHandle, SColumnDataAgg** pBlockStatis) {
dengyihao's avatar
dengyihao 已提交
3241
  STsdbReadHandle* pHandle = (STsdbReadHandle*)pTsdbReadHandle;
H
Haojun Liao 已提交
3242

H
Haojun Liao 已提交
3243 3244
  SQueryFilePos* c = &pHandle->cur;
  if (c->mixBlock) {
H
Haojun Liao 已提交
3245 3246 3247
    *pBlockStatis = NULL;
    return TSDB_CODE_SUCCESS;
  }
H
Haojun Liao 已提交
3248

H
Haojun Liao 已提交
3249 3250 3251 3252
  STableBlockInfo* pBlockInfo = &pHandle->pDataBlockInfo[c->slot];
  assert((c->slot >= 0 && c->slot < pHandle->numOfBlocks) || ((c->slot == pHandle->numOfBlocks) && (c->slot == 0)));

  // file block with sub-blocks has no statistics data
H
Haojun Liao 已提交
3253 3254 3255 3256
  if (pBlockInfo->compBlock->numOfSubBlocks > 1) {
    *pBlockStatis = NULL;
    return TSDB_CODE_SUCCESS;
  }
H
Haojun Liao 已提交
3257 3258

  int64_t stime = taosGetTimestampUs();
3259 3260
  int     statisStatus = tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock);
  if (statisStatus < TSDB_STATIS_OK) {
H
Hongze Cheng 已提交
3261
    return terrno;
3262 3263 3264
  } else if (statisStatus > TSDB_STATIS_OK) {
    *pBlockStatis = NULL;
    return TSDB_CODE_SUCCESS;
H
Hongze Cheng 已提交
3265
  }
H
Haojun Liao 已提交
3266

C
Cary Xu 已提交
3267 3268 3269
  tsdbDebug("vgId:%d succeed to load block statis part for uid %" PRIu64, REPO_ID(pHandle->pTsdb),
            TSDB_READ_TABLE_UID(&pHandle->rhelper));

H
Haojun Liao 已提交
3270 3271
  int16_t* colIds = pHandle->defaultLoadColumn->pData;

H
Haojun Liao 已提交
3272
  size_t numOfCols = QH_GET_NUM_OF_COLS(pHandle);
3273
  memset(pHandle->statis, 0, numOfCols * sizeof(SColumnDataAgg));
dengyihao's avatar
dengyihao 已提交
3274
  for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
3275
    pHandle->statis[i].colId = colIds[i];
3276
  }
H
Haojun Liao 已提交
3277

3278
  tsdbGetBlockStatis(&pHandle->rhelper, pHandle->statis, (int)numOfCols, pBlockInfo->compBlock);
H
Haojun Liao 已提交
3279 3280

  // always load the first primary timestamp column data
3281
  SColumnDataAgg* pPrimaryColStatis = &pHandle->statis[0];
3282
  assert(pPrimaryColStatis->colId == PRIMARYKEY_TIMESTAMP_COL_ID);
H
Haojun Liao 已提交
3283 3284 3285 3286 3287

  pPrimaryColStatis->numOfNull = 0;
  pPrimaryColStatis->min = pBlockInfo->compBlock->keyFirst;
  pPrimaryColStatis->max = pBlockInfo->compBlock->keyLast;

dengyihao's avatar
dengyihao 已提交
3288 3289 3290
  // update the number of NULL data rows
  for (int32_t i = 1; i < numOfCols; ++i) {
    if (pHandle->statis[i].numOfNull == -1) {  // set the column data are all NULL
H
Haojun Liao 已提交
3291 3292 3293
      pHandle->statis[i].numOfNull = pBlockInfo->compBlock->numOfRows;
    }
  }
H
Haojun Liao 已提交
3294 3295 3296 3297

  int64_t elapsed = taosGetTimestampUs() - stime;
  pHandle->cost.statisInfoLoadTime += elapsed;

H
Haojun Liao 已提交
3298
  *pBlockStatis = pHandle->statis;
3299
  return TSDB_CODE_SUCCESS;
H
hjxilinx 已提交
3300 3301
}

H
Haojun Liao 已提交
3302
SArray* tsdbRetrieveDataBlock(tsdbReaderT* pTsdbReadHandle, SArray* pIdList) {
H
[td-32]  
hjxilinx 已提交
3303
  /**
H
hjxilinx 已提交
3304
   * In the following two cases, the data has been loaded to SColumnInfoData.
H
[td-32]  
hjxilinx 已提交
3305 3306
   * 1. data is from cache, 2. data block is not completed qualified to query time range
   */
3307
  STsdbReadHandle* pHandle = (STsdbReadHandle*)pTsdbReadHandle;
D
dapan1121 已提交
3308
  if (pHandle->cur.fid == INT32_MIN) {
H
[td-32]  
hjxilinx 已提交
3309 3310
    return pHandle->pColumns;
  } else {
H
Haojun Liao 已提交
3311 3312
    STableBlockInfo* pBlockInfo = &pHandle->pDataBlockInfo[pHandle->cur.slot];
    STableCheckInfo* pCheckInfo = pBlockInfo->pTableCheckInfo;
3313

3314
    if (pHandle->cur.mixBlock) {
H
[td-32]  
hjxilinx 已提交
3315 3316
      return pHandle->pColumns;
    } else {
H
Haojun Liao 已提交
3317
      SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlockInfo->compBlock);
3318
      assert(pHandle->realNumOfRows <= binfo.rows);
H
Haojun Liao 已提交
3319

H
hjxilinx 已提交
3320 3321
      // data block has been loaded, todo extract method
      SDataBlockLoadInfo* pBlockLoadInfo = &pHandle->dataBlockLoadInfo;
H
Haojun Liao 已提交
3322

H
Hongze Cheng 已提交
3323
      if (pBlockLoadInfo->slot == pHandle->cur.slot && pBlockLoadInfo->fileGroup->fid == pHandle->cur.fid &&
H
Haojun Liao 已提交
3324
          pBlockLoadInfo->uid == pCheckInfo->tableId) {
H
hjxilinx 已提交
3325
        return pHandle->pColumns;
H
Haojun Liao 已提交
3326
      } else {  // only load the file block
H
refact  
Hongze Cheng 已提交
3327
        SBlock* pBlock = pBlockInfo->compBlock;
H
Haojun Liao 已提交
3328
        if (doLoadFileDataBlock(pHandle, pBlock, pCheckInfo, pHandle->cur.slot) != TSDB_CODE_SUCCESS) {
3329 3330
          return NULL;
        }
H
Haojun Liao 已提交
3331

H
Haojun Liao 已提交
3332
        int32_t numOfRows = doCopyRowsFromFileBlock(pHandle, pHandle->outputCapacity, 0, 0, pBlock->numOfRows - 1);
H
hjxilinx 已提交
3333 3334
        return pHandle->pColumns;
      }
H
[td-32]  
hjxilinx 已提交
3335 3336
    }
  }
H
hjxilinx 已提交
3337
}
3338
#if 0
3339
void filterPrepare(void* expr, void* param) {
3340
  tExprNode* pExpr = (tExprNode*)expr;
H
[td-32]  
hjxilinx 已提交
3341
  if (pExpr->_node.info != NULL) {
3342 3343
    return;
  }
3344

wafwerar's avatar
wafwerar 已提交
3345
  pExpr->_node.info = taosMemoryCalloc(1, sizeof(tQueryInfo));
H
Haojun Liao 已提交
3346

3347
  STSchema*   pTSSchema = (STSchema*) param;
H
hjxilinx 已提交
3348 3349 3350
  tQueryInfo* pInfo = pExpr->_node.info;
  tVariant*   pCond = pExpr->_node.pRight->pVal;
  SSchema*    pSchema = pExpr->_node.pLeft->pSchema;
3351

3352 3353
  pInfo->sch      = *pSchema;
  pInfo->optr     = pExpr->_node.optr;
Y
yihaoDeng 已提交
3354
  pInfo->compare  = getComparFunc(pInfo->sch.type, pInfo->optr);
H
Haojun Liao 已提交
3355
  pInfo->indexed  = pTSSchema->columns->colId == pInfo->sch.colId;
H
Haojun Liao 已提交
3356

H
hjxilinx 已提交
3357
  if (pInfo->optr == TSDB_RELATION_IN) {
Y
yihaoDeng 已提交
3358
     int dummy = -1;
3359
     SHashObj *pObj = NULL;
Y
yihaoDeng 已提交
3360 3361 3362 3363
     if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
        pObj = taosHashInit(256, taosGetDefaultHashFunction(pInfo->sch.type), true, false);
        SArray *arr = (SArray *)(pCond->arr);
        for (size_t i = 0; i < taosArrayGetSize(arr); i++) {
Y
yihaoDeng 已提交
3364
          char* p = taosArrayGetP(arr, i);
3365 3366
          strntolower_s(varDataVal(p), varDataVal(p), varDataLen(p));
          taosHashPut(pObj, varDataVal(p), varDataLen(p), &dummy, sizeof(dummy));
Y
yihaoDeng 已提交
3367 3368 3369 3370
        }
     } else {
       buildFilterSetFromBinary((void **)&pObj, pCond->pz, pCond->nLen);
     }
3371
     pInfo->q = (char *)pObj;
H
Haojun Liao 已提交
3372
  } else if (pCond != NULL) {
3373 3374 3375 3376
    uint32_t size = pCond->nLen * TSDB_NCHAR_SIZE;
    if (size < (uint32_t)pSchema->bytes) {
      size = pSchema->bytes;
    }
wafwerar's avatar
wafwerar 已提交
3377
    // to make sure tonchar does not cause invalid write, since the '\0' needs at least sizeof(TdUcs4) space.
wafwerar's avatar
wafwerar 已提交
3378
    pInfo->q = taosMemoryCalloc(1, size + TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
3379
    tVariantDump(pCond, pInfo->q, pSchema->type, true);
weixin_48148422's avatar
weixin_48148422 已提交
3380
  }
3381 3382
}

3383
#endif
3384

dengyihao's avatar
dengyihao 已提交
3385
static int32_t tableGroupComparFn(const void* p1, const void* p2, const void* param) {
3386
#if 0
3387
  STableGroupSupporter* pTableGroupSupp = (STableGroupSupporter*) param;
3388 3389
  STable* pTable1 = ((STableKeyInfo*) p1)->uid;
  STable* pTable2 = ((STableKeyInfo*) p2)->uid;
H
Haojun Liao 已提交
3390

3391 3392 3393
  for (int32_t i = 0; i < pTableGroupSupp->numOfCols; ++i) {
    SColIndex* pColIndex = &pTableGroupSupp->pCols[i];
    int32_t colIndex = pColIndex->colIndex;
H
Haojun Liao 已提交
3394

H
Haojun Liao 已提交
3395
    assert(colIndex >= TSDB_TBNAME_COLUMN_INDEX);
H
Haojun Liao 已提交
3396

3397 3398 3399 3400
    char *  f1 = NULL;
    char *  f2 = NULL;
    int32_t type = 0;
    int32_t bytes = 0;
H
Haojun Liao 已提交
3401

H
Haojun Liao 已提交
3402 3403 3404
    if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
      f1 = (char*) TABLE_NAME(pTable1);
      f2 = (char*) TABLE_NAME(pTable2);
3405
      type = TSDB_DATA_TYPE_BINARY;
3406
      bytes = tGetTbnameColumnSchema()->bytes;
3407
    } else {
Y
yihaoDeng 已提交
3408 3409 3410 3411 3412 3413 3414
      if (pTableGroupSupp->pTagSchema && colIndex < pTableGroupSupp->pTagSchema->numOfCols) {
        STColumn* pCol = schemaColAt(pTableGroupSupp->pTagSchema, colIndex);
        bytes = pCol->bytes;
        type = pCol->type;
        f1 = tdGetKVRowValOfCol(pTable1->tagVal, pCol->colId);
        f2 = tdGetKVRowValOfCol(pTable2->tagVal, pCol->colId);
      } 
3415
    }
H
Haojun Liao 已提交
3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429

    // this tags value may be NULL
    if (f1 == NULL && f2 == NULL) {
      continue;
    }

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

    if (f2 == NULL) {
      return 1;
    }

3430 3431 3432 3433 3434 3435 3436
    int32_t ret = doCompare(f1, f2, type, bytes);
    if (ret == 0) {
      continue;
    } else {
      return ret;
    }
  }
3437
#endif
3438 3439 3440
  return 0;
}

H
Haojun Liao 已提交
3441
static int tsdbCheckInfoCompar(const void* key1, const void* key2) {
3442
  if (((STableCheckInfo*)key1)->tableId < ((STableCheckInfo*)key2)->tableId) {
H
Haojun Liao 已提交
3443
    return -1;
3444
  } else if (((STableCheckInfo*)key1)->tableId > ((STableCheckInfo*)key2)->tableId) {
H
Haojun Liao 已提交
3445 3446 3447 3448 3449 3450 3451 3452 3453
    return 1;
  } else {
    ASSERT(false);
    return 0;
  }
}

void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTables, TSKEY skey,
                          STableGroupSupporter* pSupp, __ext_compar_fn_t compareFn) {
3454
  STable* pTable = taosArrayGetP(pTableList, 0);
H
Haojun Liao 已提交
3455 3456
  SArray* g = taosArrayInit(16, sizeof(STableKeyInfo));

3457
  STableKeyInfo info = {.lastKey = skey};
H
Haojun Liao 已提交
3458
  taosArrayPush(g, &info);
3459

3460
  for (int32_t i = 1; i < numOfTables; ++i) {
3461 3462
    STable** prev = taosArrayGet(pTableList, i - 1);
    STable** p = taosArrayGet(pTableList, i);
H
Haojun Liao 已提交
3463

H
hjxilinx 已提交
3464
    int32_t ret = compareFn(prev, p, pSupp);
3465
    assert(ret == 0 || ret == -1);
H
Haojun Liao 已提交
3466

3467
    if (ret == 0) {
3468
      STableKeyInfo info1 = {.lastKey = skey};
H
Haojun Liao 已提交
3469
      taosArrayPush(g, &info1);
3470 3471
    } else {
      taosArrayPush(pGroups, &g);  // current group is ended, start a new group
H
Haojun Liao 已提交
3472 3473
      g = taosArrayInit(16, sizeof(STableKeyInfo));

3474
      STableKeyInfo info1 = {.lastKey = skey};
H
Haojun Liao 已提交
3475
      taosArrayPush(g, &info1);
3476 3477
    }
  }
H
Haojun Liao 已提交
3478

3479
  taosArrayPush(pGroups, &g);
3480 3481
}

dengyihao's avatar
dengyihao 已提交
3482 3483
SArray* createTableGroup(SArray* pTableList, SSchemaWrapper* pTagSchema, SColIndex* pCols, int32_t numOfOrderCols,
                         TSKEY skey) {
3484
  assert(pTableList != NULL);
3485
  SArray* pTableGroup = taosArrayInit(1, POINTER_BYTES);
H
Haojun Liao 已提交
3486

3487 3488
  size_t size = taosArrayGetSize(pTableList);
  if (size == 0) {
S
Shengliang Guan 已提交
3489
    tsdbDebug("no qualified tables");
3490 3491
    return pTableGroup;
  }
H
Haojun Liao 已提交
3492

dengyihao's avatar
dengyihao 已提交
3493
  if (numOfOrderCols == 0 || size == 1) {  // no group by tags clause or only one table
3494
    SArray* sa = taosArrayDup(pTableList);
H
Haojun Liao 已提交
3495 3496 3497 3498
    if (sa == NULL) {
      taosArrayDestroy(pTableGroup);
      return NULL;
    }
H
Haojun Liao 已提交
3499

3500
    taosArrayPush(pTableGroup, &sa);
S
TD-1057  
Shengliang Guan 已提交
3501
    tsdbDebug("all %" PRIzu " tables belong to one group", size);
3502
  } else {
H
Haojun Liao 已提交
3503 3504
    STableGroupSupporter sup = {0};
    sup.numOfCols = numOfOrderCols;
3505
    sup.pTagSchema = pTagSchema->pSchema;
H
Haojun Liao 已提交
3506 3507
    sup.pCols = pCols;

3508 3509
    taosqsort(pTableList->pData, size, sizeof(STableKeyInfo), &sup, tableGroupComparFn);
    createTableGroupImpl(pTableGroup, pTableList, size, skey, &sup, tableGroupComparFn);
3510
  }
H
Haojun Liao 已提交
3511

3512 3513 3514
  return pTableGroup;
}

dengyihao's avatar
dengyihao 已提交
3515
// static bool tableFilterFp(const void* pNode, void* param) {
3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598
//  tQueryInfo* pInfo = (tQueryInfo*) param;
//
//  STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
//
//  char* val = NULL;
//  if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
//    val = (char*) TABLE_NAME(pTable);
//  } else {
//    val = tdGetKVRowValOfCol(pTable->tagVal, pInfo->sch.colId);
//  }
//
//  if (pInfo->optr == TSDB_RELATION_ISNULL || pInfo->optr == TSDB_RELATION_NOTNULL) {
//    if (pInfo->optr == TSDB_RELATION_ISNULL) {
//      return (val == NULL) || isNull(val, pInfo->sch.type);
//    } else if (pInfo->optr == TSDB_RELATION_NOTNULL) {
//      return (val != NULL) && (!isNull(val, pInfo->sch.type));
//    }
//  } else if (pInfo->optr == TSDB_RELATION_IN) {
//     int type = pInfo->sch.type;
//     if (type == TSDB_DATA_TYPE_BOOL || IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_TIMESTAMP) {
//       int64_t v;
//       GET_TYPED_DATA(v, int64_t, pInfo->sch.type, val);
//       return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
//     } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
//       uint64_t v;
//       GET_TYPED_DATA(v, uint64_t, pInfo->sch.type, val);
//       return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
//     }
//     else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_FLOAT) {
//       double v;
//       GET_TYPED_DATA(v, double, pInfo->sch.type, val);
//       return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
//     } else if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR){
//       return NULL != taosHashGet((SHashObj *)pInfo->q, varDataVal(val), varDataLen(val));
//     }
//
//  }
//
//  int32_t ret = 0;
//  if (val == NULL) { //the val is possible to be null, so check it out carefully
//    ret = -1; // val is missing in table tags value pairs
//  } else {
//    ret = pInfo->compare(val, pInfo->q);
//  }
//
//  switch (pInfo->optr) {
//    case TSDB_RELATION_EQUAL: {
//      return ret == 0;
//    }
//    case TSDB_RELATION_NOT_EQUAL: {
//      return ret != 0;
//    }
//    case TSDB_RELATION_GREATER_EQUAL: {
//      return ret >= 0;
//    }
//    case TSDB_RELATION_GREATER: {
//      return ret > 0;
//    }
//    case TSDB_RELATION_LESS_EQUAL: {
//      return ret <= 0;
//    }
//    case TSDB_RELATION_LESS: {
//      return ret < 0;
//    }
//    case TSDB_RELATION_LIKE: {
//      return ret == 0;
//    }
//    case TSDB_RELATION_MATCH: {
//      return ret == 0;
//    }
//    case TSDB_RELATION_NMATCH: {
//      return ret == 0;
//    }
//    case TSDB_RELATION_IN: {
//      return ret == 1;
//    }
//
//    default:
//      assert(false);
//  }
//
//  return true;
//}
H
Haojun Liao 已提交
3599

dengyihao's avatar
dengyihao 已提交
3600 3601
// static void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp
// *param);
3602

dengyihao's avatar
dengyihao 已提交
3603 3604
// static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
//  //  // query according to the expression tree
3605
//  SExprTraverseSupp supp = {
dengyihao's avatar
dengyihao 已提交
3606
//      .nodeFilterFn = (__result_filter_fn_t)tableFilterFp,
3607 3608
//      .setupInfoFn = filterPrepare,
//      .pExtInfo = pSTable->tagSchema,
dengyihao's avatar
dengyihao 已提交
3609
//  };
3610 3611 3612 3613 3614
//
//  getTableListfromSkipList(pExpr, pSTable->pIndex, pRes, &supp);
//  tExprTreeDestroy(pExpr, destroyHelper);
//  return TSDB_CODE_SUCCESS;
//}
3615

H
Haojun Liao 已提交
3616
int32_t tsdbQuerySTableByTagCond(void* pMeta, uint64_t uid, TSKEY skey, const char* pTagCond, size_t len,
3617
                                 int16_t tagNameRelType, const char* tbnameCond, STableGroupInfo* pGroupInfo,
3618
                                 SColIndex* pColIndex, int32_t numOfCols, uint64_t reqId, uint64_t taskId) {
H
Hongze Cheng 已提交
3619 3620
  SMetaReader mr = {0};

H
Hongze Cheng 已提交
3621
  metaReaderInit(&mr, (SMeta*)pMeta, 0);
H
Hongze Cheng 已提交
3622 3623

  if (metaGetTableEntryByUid(&mr, uid) < 0) {
dengyihao's avatar
dengyihao 已提交
3624
    tsdbError("%p failed to get stable, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId, reqId);
3625 3626
    terrno = TSDB_CODE_TDB_INVALID_TABLE_ID;
    goto _error;
C
Cary Xu 已提交
3627 3628
  } else {
    tsdbDebug("%p succeed to get stable, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId, reqId);
3629
  }
H
Haojun Liao 已提交
3630

H
Hongze Cheng 已提交
3631
  if (mr.me.type != TSDB_SUPER_TABLE) {
dengyihao's avatar
dengyihao 已提交
3632 3633 3634
    tsdbError("%p query normal tag not allowed, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId,
              reqId);
    terrno = TSDB_CODE_OPS_NOT_SUPPORT;  // basically, this error is caused by invalid sql issued by client
3635
    goto _error;
H
hjxilinx 已提交
3636
  }
3637

H
Hongze Cheng 已提交
3638 3639
  metaReaderClear(&mr);

dengyihao's avatar
dengyihao 已提交
3640 3641
  // NOTE: not add ref count for super table
  SArray*         res = taosArrayInit(8, sizeof(STableKeyInfo));
H
Haojun Liao 已提交
3642
  SSchemaWrapper* pTagSchema = metaGetTableSchema(pMeta, uid, 0, true);
H
Haojun Liao 已提交
3643

weixin_48148422's avatar
weixin_48148422 已提交
3644 3645
  // no tags and tbname condition, all child tables of this stable are involved
  if (tbnameCond == NULL && (pTagCond == NULL || len == 0)) {
H
Haojun Liao 已提交
3646
    int32_t ret = getAllTableList(pMeta, uid, res);
3647 3648
    if (ret != TSDB_CODE_SUCCESS) {
      goto _error;
3649
    }
3650

dengyihao's avatar
dengyihao 已提交
3651 3652
    pGroupInfo->numOfTables = (uint32_t)taosArrayGetSize(res);
    pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey);
H
Haojun Liao 已提交
3653

dengyihao's avatar
dengyihao 已提交
3654 3655 3656
    tsdbDebug("%p no table name/tag condition, all tables qualified, numOfTables:%u, group:%zu, TID:0x%" PRIx64
              " QID:0x%" PRIx64,
              pMeta, pGroupInfo->numOfTables, taosArrayGetSize(pGroupInfo->pGroupList), taskId, reqId);
3657

3658
    taosArrayDestroy(res);
3659 3660
    return ret;
  }
3661

H
hjxilinx 已提交
3662
  int32_t ret = TSDB_CODE_SUCCESS;
3663

dengyihao's avatar
dengyihao 已提交
3664 3665
  SFilterInfo* filterInfo = NULL;
  ret = filterInitFromNode((SNode*)pTagCond, &filterInfo, 0);
dengyihao's avatar
dengyihao 已提交
3666 3667 3668 3669 3670 3671 3672 3673
  if (ret != TSDB_CODE_SUCCESS) {
    terrno = ret;
    return ret;
  }
  ret = tsdbQueryTableList(pMeta, res, filterInfo);
  pGroupInfo->numOfTables = (uint32_t)taosArrayGetSize(res);
  pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey);

dengyihao's avatar
dengyihao 已提交
3674 3675
  // tsdbDebug("%p stable tid:%d, uid:%" PRIu64 " query, numOfTables:%u, belong to %" PRIzu " groups", tsdb,
  //          pTable->tableId, pTable->uid, pGroupInfo->numOfTables, taosArrayGetSize(pGroupInfo->pGroupList));
dengyihao's avatar
dengyihao 已提交
3676 3677 3678 3679 3680

  taosArrayDestroy(res);
  return ret;

_error:
3681
  return terrno;
3682
}
3683

dengyihao's avatar
dengyihao 已提交
3684 3685 3686 3687 3688
int32_t tsdbQueryTableList(void* pMeta, SArray* pRes, void* filterInfo) {
  // impl later

  return TSDB_CODE_SUCCESS;
}
H
Haojun Liao 已提交
3689
int32_t tsdbGetOneTableGroup(void* pMeta, uint64_t uid, TSKEY startKey, STableGroupInfo* pGroupInfo) {
H
Hongze Cheng 已提交
3690 3691
  SMetaReader mr = {0};

H
Hongze Cheng 已提交
3692
  metaReaderInit(&mr, (SMeta*)pMeta, 0);
H
Hongze Cheng 已提交
3693 3694

  if (metaGetTableEntryByUid(&mr, uid) < 0) {
3695 3696
    terrno = TSDB_CODE_TDB_INVALID_TABLE_ID;
    goto _error;
3697
  }
3698

H
Hongze Cheng 已提交
3699 3700
  metaReaderClear(&mr);

3701 3702
  pGroupInfo->numOfTables = 1;
  pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES);
H
Haojun Liao 已提交
3703

H
Haojun Liao 已提交
3704 3705
  SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));

3706
  STableKeyInfo info = {.lastKey = startKey, .uid = uid};
H
Haojun Liao 已提交
3707
  taosArrayPush(group, &info);
H
Haojun Liao 已提交
3708

3709
  taosArrayPush(pGroupInfo->pGroupList, &group);
3710
  return TSDB_CODE_SUCCESS;
3711

dengyihao's avatar
dengyihao 已提交
3712
_error:
H
Hongze Cheng 已提交
3713
  metaReaderClear(&mr);
3714
  return terrno;
3715
}
3716

3717
#if 0
3718
int32_t tsdbGetTableGroupFromIdList(STsdb* tsdb, SArray* pTableIdList, STableGroupInfo* pGroupInfo) {
B
Bomin Zhang 已提交
3719 3720 3721
  if (tsdbRLockRepoMeta(tsdb) < 0) {
    return terrno;
  }
3722 3723 3724 3725

  assert(pTableIdList != NULL);
  size_t size = taosArrayGetSize(pTableIdList);
  pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES);
H
Haojun Liao 已提交
3726
  SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));
3727

B
Bomin Zhang 已提交
3728
  for(int32_t i = 0; i < size; ++i) {
3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739
    STableIdInfo *id = taosArrayGet(pTableIdList, i);

    STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), id->uid);
    if (pTable == NULL) {
      tsdbWarn("table uid:%"PRIu64", tid:%d has been drop already", id->uid, id->tid);
      continue;
    }

    if (pTable->type == TSDB_SUPER_TABLE) {
      tsdbError("direct query on super tale is not allowed, table uid:%"PRIu64", tid:%d", id->uid, id->tid);
      terrno = TSDB_CODE_QRY_INVALID_MSG;
D
fix bug  
dapan1121 已提交
3740 3741 3742
      tsdbUnlockRepoMeta(tsdb);
      taosArrayDestroy(group);
      return terrno;
3743 3744
    }

H
Haojun Liao 已提交
3745 3746
    STableKeyInfo info = {.pTable = pTable, .lastKey = id->key};
    taosArrayPush(group, &info);
3747 3748
  }

B
Bomin Zhang 已提交
3749 3750 3751 3752
  if (tsdbUnlockRepoMeta(tsdb) < 0) {
    taosArrayDestroy(group);
    return terrno;
  }
3753

sangshuduo's avatar
sangshuduo 已提交
3754
  pGroupInfo->numOfTables = (uint32_t) taosArrayGetSize(group);
B
Bomin Zhang 已提交
3755 3756 3757 3758 3759
  if (pGroupInfo->numOfTables > 0) {
    taosArrayPush(pGroupInfo->pGroupList, &group);
  } else {
    taosArrayDestroy(group);
  }
3760 3761 3762

  return TSDB_CODE_SUCCESS;
}
3763
#endif
3764 3765 3766 3767 3768 3769 3770 3771
static void* doFreeColumnInfoData(SArray* pColumnInfoData) {
  if (pColumnInfoData == NULL) {
    return NULL;
  }

  size_t cols = taosArrayGetSize(pColumnInfoData);
  for (int32_t i = 0; i < cols; ++i) {
    SColumnInfoData* pColInfo = taosArrayGet(pColumnInfoData, i);
wafwerar's avatar
wafwerar 已提交
3772
    taosMemoryFreeClear(pColInfo->pData);
3773 3774 3775 3776 3777 3778
  }

  taosArrayDestroy(pColumnInfoData);
  return NULL;
}

H
Haojun Liao 已提交
3779 3780 3781 3782 3783 3784
static void* destroyTableCheckInfo(SArray* pTableCheckInfo) {
  size_t size = taosArrayGetSize(pTableCheckInfo);
  for (int32_t i = 0; i < size; ++i) {
    STableCheckInfo* p = taosArrayGet(pTableCheckInfo, i);
    destroyTableMemIterator(p);

wafwerar's avatar
wafwerar 已提交
3785
    taosMemoryFreeClear(p->pCompInfo);
H
Haojun Liao 已提交
3786 3787 3788 3789 3790 3791
  }

  taosArrayDestroy(pTableCheckInfo);
  return NULL;
}

H
Haojun Liao 已提交
3792
void tsdbCleanupReadHandle(tsdbReaderT queryHandle) {
3793 3794
  STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)queryHandle;
  if (pTsdbReadHandle == NULL) {
3795 3796
    return;
  }
3797

3798
  pTsdbReadHandle->pColumns = doFreeColumnInfoData(pTsdbReadHandle->pColumns);
3799

3800
  taosArrayDestroy(pTsdbReadHandle->defaultLoadColumn);
wafwerar's avatar
wafwerar 已提交
3801 3802
  taosMemoryFreeClear(pTsdbReadHandle->pDataBlockInfo);
  taosMemoryFreeClear(pTsdbReadHandle->statis);
3803

3804
  if (!emptyQueryTimewindow(pTsdbReadHandle)) {
dengyihao's avatar
dengyihao 已提交
3805
    //    tsdbMayUnTakeMemSnapshot(pTsdbReadHandle);
3806
  } else {
3807
    assert(pTsdbReadHandle->pTableCheckInfo == NULL);
3808 3809
  }

3810 3811
  if (pTsdbReadHandle->pTableCheckInfo != NULL) {
    pTsdbReadHandle->pTableCheckInfo = destroyTableCheckInfo(pTsdbReadHandle->pTableCheckInfo);
3812
  }
3813

3814
  tsdbDestroyReadH(&pTsdbReadHandle->rhelper);
H
Haojun Liao 已提交
3815

3816 3817
  tdFreeDataCols(pTsdbReadHandle->pDataCols);
  pTsdbReadHandle->pDataCols = NULL;
H
Haojun Liao 已提交
3818

3819 3820
  pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbReadHandle->prev);
  pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbReadHandle->next);
3821

3822
  SIOCostSummary* pCost = &pTsdbReadHandle->cost;
3823

dengyihao's avatar
dengyihao 已提交
3824 3825 3826 3827
  tsdbDebug("%p :io-cost summary: head-file read cnt:%" PRIu64 ", head-file time:%" PRIu64 " us, statis-info:%" PRId64
            " us, datablock:%" PRId64 " us, check data:%" PRId64 " us, %s",
            pTsdbReadHandle, pCost->headFileLoad, pCost->headFileLoadTime, pCost->statisInfoLoadTime,
            pCost->blockLoadTime, pCost->checkForNextTime, pTsdbReadHandle->idStr);
H
Haojun Liao 已提交
3828

wafwerar's avatar
wafwerar 已提交
3829
  taosMemoryFreeClear(pTsdbReadHandle);
3830
}
3831

3832
#if 0
H
Haojun Liao 已提交
3833
void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) {
3834 3835 3836 3837 3838 3839 3840 3841 3842 3843
  assert(pGroupList != NULL);

  size_t numOfGroup = taosArrayGetSize(pGroupList->pGroupList);

  for(int32_t i = 0; i < numOfGroup; ++i) {
    SArray* p = taosArrayGetP(pGroupList->pGroupList, i);

    size_t numOfTables = taosArrayGetSize(p);
    for(int32_t j = 0; j < numOfTables; ++j) {
      STable* pTable = taosArrayGetP(p, j);
3844 3845 3846 3847
      if (pTable != NULL) { // in case of handling retrieve data from tsdb
        tsdbUnRefTable(pTable);
      }
      //assert(pTable != NULL);
3848 3849 3850 3851 3852
    }

    taosArrayDestroy(p);
  }

3853
  taosHashCleanup(pGroupList->map);
3854
  taosArrayDestroy(pGroupList->pGroupList);
H
Haojun Liao 已提交
3855
  pGroupList->numOfTables = 0;
3856
}
H
Haojun Liao 已提交
3857 3858 3859 3860 3861 3862 3863

static void applyFilterToSkipListNode(SSkipList *pSkipList, tExprNode *pExpr, SArray *pResult, SExprTraverseSupp *param) {
  SSkipListIterator* iter = tSkipListCreateIter(pSkipList);

  // Scan each node in the skiplist by using iterator
  while (tSkipListIterNext(iter)) {
    SSkipListNode *pNode = tSkipListIterGet(iter);
H
Haojun Liao 已提交
3864
    if (exprTreeApplyFilter(pExpr, pNode, param)) {
H
Haojun Liao 已提交
3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887
      taosArrayPush(pResult, &(SL_GET_NODE_DATA(pNode)));
    }
  }

  tSkipListDestroyIter(iter);
}

typedef struct {
  char*    v;
  int32_t  optr;
} SEndPoint;

typedef struct {
  SEndPoint* start;
  SEndPoint* end;
} SQueryCond;

// todo check for malloc failure
static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
  int32_t optr = queryColInfo->optr;

  if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
      optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
wafwerar's avatar
wafwerar 已提交
3888
    pCond->start       = taosMemoryCalloc(1, sizeof(SEndPoint));
H
Haojun Liao 已提交
3889
    pCond->start->optr = queryColInfo->optr;
Y
yihaoDeng 已提交
3890
    pCond->start->v    = queryColInfo->q;
H
Haojun Liao 已提交
3891
  } else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
wafwerar's avatar
wafwerar 已提交
3892
    pCond->end       = taosMemoryCalloc(1, sizeof(SEndPoint));
H
Haojun Liao 已提交
3893
    pCond->end->optr = queryColInfo->optr;
Y
yihaoDeng 已提交
3894 3895
    pCond->end->v    = queryColInfo->q;
  } else if (optr == TSDB_RELATION_IN) {
wafwerar's avatar
wafwerar 已提交
3896
    pCond->start       = taosMemoryCalloc(1, sizeof(SEndPoint));
Y
yihaoDeng 已提交
3897 3898 3899
    pCond->start->optr = queryColInfo->optr;
    pCond->start->v    = queryColInfo->q; 
  } else if (optr == TSDB_RELATION_LIKE) {
H
Haojun Liao 已提交
3900
    assert(0);
3901 3902
  } else if (optr == TSDB_RELATION_MATCH) {
    assert(0);
3903 3904
  } else if (optr == TSDB_RELATION_NMATCH) {
    assert(0);
H
Haojun Liao 已提交
3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987
  }

  return TSDB_CODE_SUCCESS;
}

static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
  SSkipListIterator* iter = NULL;

  SQueryCond cond = {0};
  if (setQueryCond(pQueryInfo, &cond) != TSDB_CODE_SUCCESS) {
    //todo handle error
  }

  if (cond.start != NULL) {
    iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_ASC);
  } else {
    iter = tSkipListCreateIterFromVal(pSkipList, (char*)(cond.end ? cond.end->v: NULL), pSkipList->type, TSDB_ORDER_DESC);
  }

  if (cond.start != NULL) {
    int32_t optr = cond.start->optr;

    if (optr == TSDB_RELATION_EQUAL) {   // equals
      while(tSkipListIterNext(iter)) {
        SSkipListNode* pNode = tSkipListIterGet(iter);

        int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
        if (ret != 0) {
          break;
        }

        STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
        taosArrayPush(result, &info);
      }
    } else if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL) { // greater equal
      bool comp = true;
      int32_t ret = 0;

      while(tSkipListIterNext(iter)) {
        SSkipListNode* pNode = tSkipListIterGet(iter);

        if (comp) {
          ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
          assert(ret >= 0);
        }

        if (ret == 0 && optr == TSDB_RELATION_GREATER) {
          continue;
        } else {
          STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
          taosArrayPush(result, &info);
          comp = false;
        }
      }
    } else if (optr == TSDB_RELATION_NOT_EQUAL) {   // not equal
      bool comp = true;

      while(tSkipListIterNext(iter)) {
        SSkipListNode* pNode = tSkipListIterGet(iter);
        comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
        if (comp) {
          continue;
        }

        STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
        taosArrayPush(result, &info);
      }

      tSkipListDestroyIter(iter);

      comp = true;
      iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_DESC);
      while(tSkipListIterNext(iter)) {
        SSkipListNode* pNode = tSkipListIterGet(iter);
        comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
        if (comp) {
          continue;
        }

        STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
        taosArrayPush(result, &info);
      }

Y
yihaoDeng 已提交
3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000
    } else if (optr == TSDB_RELATION_IN) {
      while(tSkipListIterNext(iter)) {
        SSkipListNode* pNode = tSkipListIterGet(iter);

        int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
        if (ret != 0) {
          break;
        }

        STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
        taosArrayPush(result, &info);
      }
      
H
Haojun Liao 已提交
4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041
    } else {
      assert(0);
    }
  } else {
    int32_t optr = cond.end ? cond.end->optr : TSDB_RELATION_INVALID;
    if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
      bool    comp = true;
      int32_t ret = 0;

      while (tSkipListIterNext(iter)) {
        SSkipListNode *pNode = tSkipListIterGet(iter);

        if (comp) {
          ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.end->v);
          assert(ret <= 0);
        }

        if (ret == 0 && optr == TSDB_RELATION_LESS) {
          continue;
        } else {
          STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
          taosArrayPush(result, &info);
          comp = false;  // no need to compare anymore
        }
      }
    } else {
      assert(pQueryInfo->optr == TSDB_RELATION_ISNULL || pQueryInfo->optr == TSDB_RELATION_NOTNULL);

      while (tSkipListIterNext(iter)) {
        SSkipListNode *pNode = tSkipListIterGet(iter);

        bool isnull = isNull(SL_GET_NODE_KEY(pSkipList, pNode), pQueryInfo->sch.type);
        if ((pQueryInfo->optr == TSDB_RELATION_ISNULL && isnull) ||
            (pQueryInfo->optr == TSDB_RELATION_NOTNULL && (!isnull))) {
          STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
          taosArrayPush(result, &info);
        }
      }
    }
  }

wafwerar's avatar
wafwerar 已提交
4042 4043
  taosMemoryFree(cond.start);
  taosMemoryFree(cond.end);
H
Haojun Liao 已提交
4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061
  tSkipListDestroyIter(iter);
}

static void queryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* res, __result_filter_fn_t filterFp) {
  SSkipListIterator* iter = tSkipListCreateIter(pSkipList);

  while (tSkipListIterNext(iter)) {
    bool addToResult = false;

    SSkipListNode *pNode = tSkipListIterGet(iter);

    char *pData = SL_GET_NODE_DATA(pNode);
    tstr *name = (tstr*) tsdbGetTableName((void*) pData);

    // todo speed up by using hash
    if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
      if (pQueryInfo->optr == TSDB_RELATION_IN) {
        addToResult = pQueryInfo->compare(name, pQueryInfo->q);
4062 4063 4064
      } else if (pQueryInfo->optr == TSDB_RELATION_LIKE ||
                 pQueryInfo->optr == TSDB_RELATION_MATCH ||
                 pQueryInfo->optr == TSDB_RELATION_NMATCH) {
H
Haojun Liao 已提交
4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080
        addToResult = !pQueryInfo->compare(name, pQueryInfo->q);
      }
    } else {
      addToResult = filterFp(pNode, pQueryInfo);
    }

    if (addToResult) {
      STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
      taosArrayPush(res, &info);
    }
  }

  tSkipListDestroyIter(iter);
}

// Apply the filter expression to each node in the skiplist to acquire the qualified nodes in skip list
dengyihao's avatar
dengyihao 已提交
4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113
//void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param) {
//  if (pExpr == NULL) {
//    return;
//  }
//
//  tExprNode *pLeft  = pExpr->_node.pLeft;
//  tExprNode *pRight = pExpr->_node.pRight;
//
//  // column project
//  if (pLeft->nodeType != TSQL_NODE_EXPR && pRight->nodeType != TSQL_NODE_EXPR) {
//    assert(pLeft->nodeType == TSQL_NODE_COL && (pRight->nodeType == TSQL_NODE_VALUE || pRight->nodeType == TSQL_NODE_DUMMY));
//
//    param->setupInfoFn(pExpr, param->pExtInfo);
//
//    tQueryInfo *pQueryInfo = pExpr->_node.info;
//    if (pQueryInfo->indexed && (pQueryInfo->optr != TSDB_RELATION_LIKE
//                                && pQueryInfo->optr != TSDB_RELATION_MATCH && pQueryInfo->optr != TSDB_RELATION_NMATCH
//                                && pQueryInfo->optr != TSDB_RELATION_IN)) {
//      queryIndexedColumn(pSkipList, pQueryInfo, result);
//    } else {
//      queryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
//    }
//
//    return;
//  }
//
//  // The value of hasPK is always 0.
//  uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK;
//  assert(weight == 0 && pSkipList != NULL && taosArrayGetSize(result) == 0);
//
//  //apply the hierarchical filter expression to every node in skiplist to find the qualified nodes
//  applyFilterToSkipListNode(pSkipList, pExpr, result, param);
//}
L
Liu Jicong 已提交
4114
#endif