scanoperator.c 173.2 KB
Newer Older
H
Haojun Liao 已提交
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/>.
 */

16
#include <vnode.h>
17
#include "executorimpl.h"
H
Haojun Liao 已提交
18
#include "filter.h"
19
#include "function.h"
20
#include "functionMgt.h"
L
Liu Jicong 已提交
21
#include "os.h"
H
Haojun Liao 已提交
22
#include "querynodes.h"
23
#include "systable.h"
H
Haojun Liao 已提交
24
#include "tname.h"
25
#include "ttime.h"
H
Haojun Liao 已提交
26 27 28 29 30 31 32 33

#include "tdatablock.h"
#include "tmsg.h"

#include "query.h"
#include "tcompare.h"
#include "thash.h"
#include "ttypes.h"
34
#include "vnode.h"
H
Haojun Liao 已提交
35 36

#define SET_REVERSE_SCAN_FLAG(_info) ((_info)->scanFlag = REVERSE_SCAN)
37
#define SWITCH_ORDER(n)              (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC))
38

39
static int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity);
40 41
static int32_t buildDbTableInfoBlock(bool sysInfo, const SSDataBlock* p, const SSysTableMeta* pSysDbTableMeta,
                                     size_t size, const char* dbName);
42

dengyihao's avatar
dengyihao 已提交
43 44 45
static char* SYSTABLE_IDX_COLUMN[] = {"table_name", "db_name",     "create_time",      "columns",
                                      "ttl",        "stable_name", "vgroup_id', 'uid", "type"};

dengyihao's avatar
opt mem  
dengyihao 已提交
46
static char* SYSTABLE_SPECIAL_COL[] = {"db_name", "vgroup_id"};
dengyihao's avatar
dengyihao 已提交
47

dengyihao's avatar
dengyihao 已提交
48 49 50
typedef int32_t (*__sys_filte)(void* pMeta, SNode* cond, SArray* result);
typedef int32_t (*__sys_check)(SNode* cond);

dengyihao's avatar
dengyihao 已提交
51
typedef struct {
dengyihao's avatar
dengyihao 已提交
52 53 54
  const char* name;
  __sys_check chkFunc;
  __sys_filte fltFunc;
dengyihao's avatar
dengyihao 已提交
55 56
} SSTabFltFuncDef;

dengyihao's avatar
dengyihao 已提交
57 58
typedef struct {
  void* pMeta;
dengyihao's avatar
dengyihao 已提交
59
  void* pVnode;
dengyihao's avatar
dengyihao 已提交
60 61
} SSTabFltArg;

H
Haojun Liao 已提交
62 63 64 65 66 67 68 69 70 71 72 73
typedef struct STableMergeScanExecInfo {
  SFileBlockLoadRecorder blockRecorder;
  SSortExecInfo          sortExecInfo;
} STableMergeScanExecInfo;

typedef struct STableMergeScanSortSourceParam {
  SOperatorInfo* pOperator;
  int32_t        readerIdx;
  uint64_t       uid;
  SSDataBlock*   inputBlock;
} STableMergeScanSortSourceParam;

dengyihao's avatar
dengyihao 已提交
74
static int32_t sysChkFilter__Comm(SNode* pNode);
dengyihao's avatar
dengyihao 已提交
75 76 77 78 79 80 81 82 83 84
static int32_t sysChkFilter__DBName(SNode* pNode);
static int32_t sysChkFilter__VgroupId(SNode* pNode);
static int32_t sysChkFilter__TableName(SNode* pNode);
static int32_t sysChkFilter__CreateTime(SNode* pNode);
static int32_t sysChkFilter__Ncolumn(SNode* pNode);
static int32_t sysChkFilter__Ttl(SNode* pNode);
static int32_t sysChkFilter__STableName(SNode* pNode);
static int32_t sysChkFilter__Uid(SNode* pNode);
static int32_t sysChkFilter__Type(SNode* pNode);

H
Haojun Liao 已提交
85 86 87 88 89 90 91 92 93
static int32_t sysFilte__DbName(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__VgroupId(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__TableName(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__CreateTime(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__Ncolumn(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__Ttl(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__STableName(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__Uid(void* arg, SNode* pNode, SArray* result);
static int32_t sysFilte__Type(void* arg, SNode* pNode, SArray* result);
dengyihao's avatar
dengyihao 已提交
94 95 96 97 98 99 100 101 102 103 104

const SSTabFltFuncDef filterDict[] = {
    {.name = "table_name", .chkFunc = sysChkFilter__TableName, .fltFunc = sysFilte__TableName},
    {.name = "db_name", .chkFunc = sysChkFilter__DBName, .fltFunc = sysFilte__DbName},
    {.name = "create_time", .chkFunc = sysChkFilter__CreateTime, .fltFunc = sysFilte__CreateTime},
    {.name = "columns", .chkFunc = sysChkFilter__Ncolumn, .fltFunc = sysFilte__Ncolumn},
    {.name = "ttl", .chkFunc = sysChkFilter__Ttl, .fltFunc = sysFilte__Ttl},
    {.name = "stable_name", .chkFunc = sysChkFilter__STableName, .fltFunc = sysFilte__STableName},
    {.name = "vgroup_id", .chkFunc = sysChkFilter__VgroupId, .fltFunc = sysFilte__VgroupId},
    {.name = "uid", .chkFunc = sysChkFilter__Uid, .fltFunc = sysFilte__Uid},
    {.name = "type", .chkFunc = sysChkFilter__Type, .fltFunc = sysFilte__Type}};
dengyihao's avatar
dengyihao 已提交
105

dengyihao's avatar
dengyihao 已提交
106
#define SYSTAB_FILTER_DICT_SIZE (sizeof(filterDict) / sizeof(filterDict[0]))
dengyihao's avatar
dengyihao 已提交
107

dengyihao's avatar
dengyihao 已提交
108
static int32_t optSysTabFilte(void* arg, SNode* cond, SArray* result);
dengyihao's avatar
dengyihao 已提交
109
static int32_t optSysTabFilteImpl(void* arg, SNode* cond, SArray* result);
dengyihao's avatar
dengyihao 已提交
110
static int32_t optSysCheckOper(SNode* pOpear);
H
Haojun Liao 已提交
111
static int32_t optSysMergeRslt(SArray* mRslt, SArray* rslt);
dengyihao's avatar
dengyihao 已提交
112

L
Liu Jicong 已提交
113
static bool processBlockWithProbability(const SSampleExecInfo* pInfo);
114

115 116 117
static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo, SMetaReader* smrSuperTable,
                                                SMetaReader* smrChildTable, const char* dbname, const char* tableName,
                                                int32_t* pNumOfRows, const SSDataBlock* dataBlock);
118

H
Haojun Liao 已提交
119 120 121 122
static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
                                               SFilterInfo* pFilterInfo);

bool processBlockWithProbability(const SSampleExecInfo* pInfo) {
123 124 125 126 127 128 129 130 131 132 133 134
#if 0
  if (pInfo->sampleRatio == 1) {
    return true;
  }

  uint32_t val = taosRandR((uint32_t*) &pInfo->seed);
  return (val % ((uint32_t)(1/pInfo->sampleRatio))) == 0;
#else
  return true;
#endif
}

135
static void switchCtxOrder(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
H
Haojun Liao 已提交
136 137 138 139 140
  for (int32_t i = 0; i < numOfOutput; ++i) {
    SWITCH_ORDER(pCtx[i].order);
  }
}

141 142 143 144 145 146 147 148 149
static void getNextTimeWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) {
  int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
  if (pInterval->intervalUnit != 'n' && pInterval->intervalUnit != 'y') {
    tw->skey += pInterval->sliding * factor;
    tw->ekey = tw->skey + pInterval->interval - 1;
    return;
  }

  int64_t key = tw->skey, interval = pInterval->interval;
150
  // convert key to second
151 152 153 154 155 156 157
  key = convertTimePrecision(key, pInterval->precision, TSDB_TIME_PRECISION_MILLI) / 1000;

  if (pInterval->intervalUnit == 'y') {
    interval *= 12;
  }

  struct tm tm;
158
  time_t    t = (time_t)key;
159 160 161 162 163
  taosLocalTime(&t, &tm);

  int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
  tm.tm_year = mon / 12;
  tm.tm_mon = mon % 12;
wafwerar's avatar
wafwerar 已提交
164
  tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
165 166 167 168

  mon = (int)(mon + interval);
  tm.tm_year = mon / 12;
  tm.tm_mon = mon % 12;
wafwerar's avatar
wafwerar 已提交
169
  tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
170 171 172 173

  tw->ekey -= 1;
}

174
static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockInfo, int32_t order) {
175 176 177 178 179 180 181
  STimeWindow w = {0};

  // 0 by default, which means it is not a interval operator of the upstream operator.
  if (pInterval->interval == 0) {
    return false;
  }

182
  if (order == TSDB_ORDER_ASC) {
183
    w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.skey);
184 185
    assert(w.ekey >= pBlockInfo->window.skey);

S
slzhou 已提交
186
    if (TMAX(w.skey, pBlockInfo->window.skey) <= TMIN(w.ekey, pBlockInfo->window.ekey)) {
187 188 189
      return true;
    }

190 191
    while (1) {
      getNextTimeWindow(pInterval, &w, order);
192 193 194 195 196
      if (w.skey > pBlockInfo->window.ekey) {
        break;
      }

      assert(w.ekey > pBlockInfo->window.ekey);
197
      if (TMAX(w.skey, pBlockInfo->window.skey) <= pBlockInfo->window.ekey) {
198 199 200 201
        return true;
      }
    }
  } else {
202
    w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.ekey);
203 204
    assert(w.skey <= pBlockInfo->window.ekey);

205
    if (TMAX(w.skey, pBlockInfo->window.skey) <= TMIN(w.ekey, pBlockInfo->window.ekey)) {
206 207 208
      return true;
    }

209
    while (1) {
210 211 212 213 214 215
      getNextTimeWindow(pInterval, &w, order);
      if (w.ekey < pBlockInfo->window.skey) {
        break;
      }

      assert(w.skey < pBlockInfo->window.skey);
216
      if (pBlockInfo->window.skey <= TMIN(w.ekey, pBlockInfo->window.ekey)) {
217 218 219
        return true;
      }
    }
220 221 222 223 224
  }

  return false;
}

225 226 227 228 229 230 231 232 233 234 235
// this function is for table scanner to extract temporary results of upstream aggregate results.
static SResultRow* getTableGroupOutputBuf(SOperatorInfo* pOperator, uint64_t groupId, SFilePage** pPage) {
  if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
    return NULL;
  }

  int64_t buf[2] = {0};
  SET_RES_WINDOW_KEY((char*)buf, &groupId, sizeof(groupId), groupId);

  STableScanInfo* pTableScanInfo = pOperator->info;

236 237
  SResultRowPosition* p1 = (SResultRowPosition*)tSimpleHashGet(pTableScanInfo->pdInfo.pAggSup->pResultRowHashTable, buf,
                                                               GET_RES_WINDOW_KEY_LEN(sizeof(groupId)));
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285

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

  *pPage = getBufPage(pTableScanInfo->pdInfo.pAggSup->pResultBuf, p1->pageId);
  return (SResultRow*)((char*)(*pPage) + p1->offset);
}

static int32_t doDynamicPruneDataBlock(SOperatorInfo* pOperator, SDataBlockInfo* pBlockInfo, uint32_t* status) {
  STableScanInfo* pTableScanInfo = pOperator->info;

  if (pTableScanInfo->pdInfo.pExprSup == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  SExprSupp* pSup1 = pTableScanInfo->pdInfo.pExprSup;

  SFilePage*  pPage = NULL;
  SResultRow* pRow = getTableGroupOutputBuf(pOperator, pBlockInfo->groupId, &pPage);

  if (pRow == NULL) {
    return TSDB_CODE_SUCCESS;
  }

  bool notLoadBlock = true;
  for (int32_t i = 0; i < pSup1->numOfExprs; ++i) {
    int32_t functionId = pSup1->pCtx[i].functionId;

    SResultRowEntryInfo* pEntry = getResultEntryInfo(pRow, i, pTableScanInfo->pdInfo.pExprSup->rowEntryInfoOffset);

    int32_t reqStatus = fmFuncDynDataRequired(functionId, pEntry, &pBlockInfo->window);
    if (reqStatus != FUNC_DATA_REQUIRED_NOT_LOAD) {
      notLoadBlock = false;
      break;
    }
  }

  // release buffer pages
  releaseBufPage(pTableScanInfo->pdInfo.pAggSup->pResultBuf, pPage);

  if (notLoadBlock) {
    *status = FUNC_DATA_REQUIRED_NOT_LOAD;
  }

  return TSDB_CODE_SUCCESS;
}

H
Haojun Liao 已提交
286
static bool doFilterByBlockSMA(SFilterInfo* pFilterInfo, SColumnDataAgg** pColsAgg, int32_t numOfCols,
287
                               int32_t numOfRows) {
H
Haojun Liao 已提交
288
  if (pColsAgg == NULL || pFilterInfo == NULL) {
H
Haojun Liao 已提交
289 290 291
    return true;
  }

H
Haojun Liao 已提交
292
  bool keep = filterRangeExecute(pFilterInfo, pColsAgg, numOfCols, numOfRows);
H
Haojun Liao 已提交
293 294 295 296 297 298 299 300 301
  return keep;
}

static bool doLoadBlockSMA(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
  bool             allColumnsHaveAgg = true;
  SColumnDataAgg** pColAgg = NULL;

  int32_t code = tsdbRetrieveDatablockSMA(pTableScanInfo->dataReader, &pColAgg, &allColumnsHaveAgg);
  if (code != TSDB_CODE_SUCCESS) {
302
    T_LONG_JMP(pTaskInfo->env, code);
H
Haojun Liao 已提交
303 304 305 306 307 308 309 310 311 312 313 314 315
  }

  if (!allColumnsHaveAgg) {
    return false;
  }

  //  if (allColumnsHaveAgg == true) {
  int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);

  // todo create this buffer during creating operator
  if (pBlock->pBlockAgg == NULL) {
    pBlock->pBlockAgg = taosMemoryCalloc(numOfCols, POINTER_BYTES);
    if (pBlock->pBlockAgg == NULL) {
316
      T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
H
Haojun Liao 已提交
317 318 319
    }
  }

320 321
  size_t num = taosArrayGetSize(pTableScanInfo->matchInfo.pList);
  for (int32_t i = 0; i < num; ++i) {
H
Haojun Liao 已提交
322 323
    SColMatchItem* pColMatchInfo = taosArrayGet(pTableScanInfo->matchInfo.pList, i);
    if (!pColMatchInfo->needOutput) {
H
Haojun Liao 已提交
324 325
      continue;
    }
H
Haojun Liao 已提交
326 327

    pBlock->pBlockAgg[pColMatchInfo->dstSlotId] = pColAgg[i];
H
Haojun Liao 已提交
328 329 330 331 332
  }

  return true;
}

333 334
static void doSetTagColumnData(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo,
                               int32_t rows) {
H
Haojun Liao 已提交
335 336 337
  if (pTableScanInfo->pseudoSup.numOfExprs > 0) {
    SExprSupp* pSup = &pTableScanInfo->pseudoSup;

338
    int32_t code = addTagPseudoColumnData(&pTableScanInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pBlock, rows,
339
                                          GET_TASKID(pTaskInfo), &pTableScanInfo->metaCache);
H
Haojun Liao 已提交
340
    // ignore the table not exists error, since this table may have been dropped during the scan procedure.
H
Haojun Liao 已提交
341
    if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_PAR_TABLE_NOT_EXIST) {
H
Haojun Liao 已提交
342 343
      T_LONG_JMP(pTaskInfo->env, code);
    }
H
Haojun Liao 已提交
344 345 346

    // reset the error code.
    terrno = 0;
H
Haojun Liao 已提交
347 348 349
  }
}

350 351
// todo handle the slimit info
void applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator) {
352
  SLimit*     pLimit = &pLimitInfo->limit;
H
Haojun Liao 已提交
353
  const char* id = GET_TASKID(pTaskInfo);
354 355 356 357 358

  if (pLimit->offset > 0 && pLimitInfo->remainOffset > 0) {
    if (pLimitInfo->remainOffset >= pBlock->info.rows) {
      pLimitInfo->remainOffset -= pBlock->info.rows;
      pBlock->info.rows = 0;
H
Haojun Liao 已提交
359
      qDebug("current block ignore due to offset, current:%" PRId64 ", %s", pLimitInfo->remainOffset, id);
360 361 362 363 364 365 366 367 368 369 370 371
    } else {
      blockDataTrimFirstNRows(pBlock, pLimitInfo->remainOffset);
      pLimitInfo->remainOffset = 0;
    }
  }

  if (pLimit->limit != -1 && pLimit->limit <= (pLimitInfo->numOfOutputRows + pBlock->info.rows)) {
    // limit the output rows
    int32_t overflowRows = pLimitInfo->numOfOutputRows + pBlock->info.rows - pLimit->limit;
    int32_t keep = pBlock->info.rows - overflowRows;

    blockDataKeepFirstNRows(pBlock, keep);
H
Haojun Liao 已提交
372
    qDebug("output limit %" PRId64 " has reached, %s", pLimit->limit, id);
373 374 375 376
    pOperator->status = OP_EXEC_DONE;
  }
}

L
Liu Jicong 已提交
377 378
static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
                             uint32_t* status) {
379
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
380 381
  STableScanInfo* pInfo = pOperator->info;

382
  SFileBlockLoadRecorder* pCost = &pTableScanInfo->readRecorder;
H
Haojun Liao 已提交
383 384

  pCost->totalBlocks += 1;
385
  pCost->totalRows += pBlock->info.rows;
386

H
Haojun Liao 已提交
387
  bool loadSMA = false;
H
Haojun Liao 已提交
388

389
  *status = pInfo->dataBlockLoadFlag;
H
Haojun Liao 已提交
390
  if (pOperator->exprSupp.pFilterInfo != NULL ||
391
      overlapWithTimeWindow(&pTableScanInfo->pdInfo.interval, &pBlock->info, pTableScanInfo->cond.order)) {
392 393 394 395
    (*status) = FUNC_DATA_REQUIRED_DATA_LOAD;
  }

  SDataBlockInfo* pBlockInfo = &pBlock->info;
396
  taosMemoryFreeClear(pBlock->pBlockAgg);
397 398

  if (*status == FUNC_DATA_REQUIRED_FILTEROUT) {
399 400
    qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
           pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
401
    pCost->filterOutBlocks += 1;
402
    pCost->totalRows += pBlock->info.rows;
403 404
    return TSDB_CODE_SUCCESS;
  } else if (*status == FUNC_DATA_REQUIRED_NOT_LOAD) {
405 406
    qDebug("%s data block skipped, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
           pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
407
    doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, 1);
408 409
    pCost->skipBlocks += 1;
    return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
410
  } else if (*status == FUNC_DATA_REQUIRED_SMA_LOAD) {
411
    pCost->loadBlockStatis += 1;
L
Liu Jicong 已提交
412
    loadSMA = true;  // mark the operation of load sma;
H
Haojun Liao 已提交
413
    bool success = doLoadBlockSMA(pTableScanInfo, pBlock, pTaskInfo);
L
Liu Jicong 已提交
414
    if (success) {  // failed to load the block sma data, data block statistics does not exist, load data block instead
415 416
      qDebug("%s data block SMA loaded, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
             pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
417
      doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, 1);
418 419
      return TSDB_CODE_SUCCESS;
    } else {
420
      qDebug("%s failed to load SMA, since not all columns have SMA", GET_TASKID(pTaskInfo));
H
Haojun Liao 已提交
421
      *status = FUNC_DATA_REQUIRED_DATA_LOAD;
422
    }
H
Haojun Liao 已提交
423
  }
424

H
Haojun Liao 已提交
425
  ASSERT(*status == FUNC_DATA_REQUIRED_DATA_LOAD);
426

H
Haojun Liao 已提交
427
  // try to filter data block according to sma info
H
Haojun Liao 已提交
428
  if (pOperator->exprSupp.pFilterInfo != NULL && (!loadSMA)) {
429 430 431
    bool success = doLoadBlockSMA(pTableScanInfo, pBlock, pTaskInfo);
    if (success) {
      size_t size = taosArrayGetSize(pBlock->pDataBlock);
H
Haojun Liao 已提交
432
      bool   keep = doFilterByBlockSMA(pOperator->exprSupp.pFilterInfo, pBlock->pBlockAgg, size, pBlockInfo->rows);
433 434 435 436 437 438 439 440
      if (!keep) {
        qDebug("%s data block filter out by block SMA, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
               pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
        pCost->filterOutBlocks += 1;
        (*status) = FUNC_DATA_REQUIRED_FILTEROUT;

        return TSDB_CODE_SUCCESS;
      }
441
    }
H
Haojun Liao 已提交
442
  }
443

444 445 446
  // free the sma info, since it should not be involved in later computing process.
  taosMemoryFreeClear(pBlock->pBlockAgg);

447
  // try to filter data block according to current results
448 449
  doDynamicPruneDataBlock(pOperator, pBlockInfo, status);
  if (*status == FUNC_DATA_REQUIRED_NOT_LOAD) {
450
    qDebug("%s data block skipped due to dynamic prune, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
451 452 453
           pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
    pCost->skipBlocks += 1;

454
    *status = FUNC_DATA_REQUIRED_FILTEROUT;
455 456 457
    return TSDB_CODE_SUCCESS;
  }

H
Haojun Liao 已提交
458 459
  pCost->totalCheckedRows += pBlock->info.rows;
  pCost->loadBlocks += 1;
460

H
Haojun Liao 已提交
461 462 463
  SArray* pCols = tsdbRetrieveDataBlock(pTableScanInfo->dataReader, NULL);
  if (pCols == NULL) {
    return terrno;
H
Haojun Liao 已提交
464 465
  }

H
Haojun Liao 已提交
466
  relocateColumnData(pBlock, pTableScanInfo->matchInfo.pList, pCols, true);
467
  doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, pBlock->info.rows);
468

H
Haojun Liao 已提交
469 470
  // restore the previous value
  pCost->totalRows -= pBlock->info.rows;
471

H
Haojun Liao 已提交
472
  if (pOperator->exprSupp.pFilterInfo != NULL) {
473
    int64_t st = taosGetTimestampUs();
H
Haojun Liao 已提交
474
    doFilter(pBlock, pOperator->exprSupp.pFilterInfo, &pTableScanInfo->matchInfo);
475

476 477
    double el = (taosGetTimestampUs() - st) / 1000.0;
    pTableScanInfo->readRecorder.filterTime += el;
478

479 480 481 482 483 484 485
    if (pBlock->info.rows == 0) {
      pCost->filterOutBlocks += 1;
      qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d, elapsed time:%.2f ms",
             GET_TASKID(pTaskInfo), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, el);
    } else {
      qDebug("%s data block filter applied, elapsed time:%.2f ms", GET_TASKID(pTaskInfo), el);
    }
486 487
  }

488
  applyLimitOffset(&pInfo->limitInfo, pBlock, pTaskInfo, pOperator);
489

H
Haojun Liao 已提交
490 491
  pCost->totalRows += pBlock->info.rows;
  pInfo->limitInfo.numOfOutputRows = pCost->totalRows;
H
Haojun Liao 已提交
492 493 494
  return TSDB_CODE_SUCCESS;
}

495
static void prepareForDescendingScan(STableScanInfo* pTableScanInfo, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
H
Haojun Liao 已提交
496 497 498
  SET_REVERSE_SCAN_FLAG(pTableScanInfo);

  switchCtxOrder(pCtx, numOfOutput);
499
  pTableScanInfo->cond.order = TSDB_ORDER_DESC;
H
Haojun Liao 已提交
500 501
  STimeWindow* pTWindow = &pTableScanInfo->cond.twindows;
  TSWAP(pTWindow->skey, pTWindow->ekey);
H
Haojun Liao 已提交
502 503
}

504 505
typedef struct STableCachedVal {
  const char* pName;
506
  STag*       pTags;
507 508
} STableCachedVal;

509 510 511 512 513 514 515 516 517 518 519
static void freeTableCachedVal(void* param) {
  if (param == NULL) {
    return;
  }

  STableCachedVal* pVal = param;
  taosMemoryFree((void*)pVal->pName);
  taosMemoryFree(pVal->pTags);
  taosMemoryFree(pVal);
}

H
Haojun Liao 已提交
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
static STableCachedVal* createTableCacheVal(const SMetaReader* pMetaReader) {
  STableCachedVal* pVal = taosMemoryMalloc(sizeof(STableCachedVal));
  pVal->pName = strdup(pMetaReader->me.name);
  pVal->pTags = NULL;

  // only child table has tag value
  if (pMetaReader->me.type == TSDB_CHILD_TABLE) {
    STag* pTag = (STag*) pMetaReader->me.ctbEntry.pTags;
    pVal->pTags = taosMemoryMalloc(pTag->len);
    memcpy(pVal->pTags, pTag, pTag->len);
  }

  return pVal;
}

535 536
// const void *key, size_t keyLen, void *value
static void freeCachedMetaItem(const void* key, size_t keyLen, void* value) { freeTableCachedVal(value); }
537

538 539
int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int32_t numOfExpr, SSDataBlock* pBlock,
                               int32_t rows, const char* idStr, STableMetaCacheInfo* pCache) {
540
  // currently only the tbname pseudo column
541
  if (numOfExpr <= 0) {
H
Haojun Liao 已提交
542
    return TSDB_CODE_SUCCESS;
543 544
  }

545 546
  int32_t code = 0;

547 548 549 550
  // backup the rows
  int32_t backupRows = pBlock->info.rows;
  pBlock->info.rows = rows;

551
  bool            freeReader = false;
552
  STableCachedVal val = {0};
553 554

  SMetaReader mr = {0};
555
  LRUHandle*  h = NULL;
556

557
  // 1. check if it is existed in meta cache
558
  if (pCache == NULL) {
559 560 561
    metaReaderInit(&mr, pHandle->meta, 0);
    code = metaGetTableEntryByUid(&mr, pBlock->info.uid);
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
562
      if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
H
Haojun Liao 已提交
563 564 565 566
        qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.uid, tstrerror(terrno), idStr);
      } else {
        qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.uid, tstrerror(terrno), idStr);
      }
567 568 569 570 571
      metaReaderClear(&mr);
      return terrno;
    }

    metaReaderReleaseLock(&mr);
572

573 574
    val.pName = mr.me.name;
    val.pTags = (STag*)mr.me.ctbEntry.pTags;
575 576

    freeReader = true;
577
  } else {
578 579
    pCache->metaFetch += 1;

H
Haojun Liao 已提交
580
    h = taosLRUCacheLookup(pCache->pTableMetaEntryCache, &pBlock->info.uid, sizeof(pBlock->info.uid));
581 582 583 584
    if (h == NULL) {
      metaReaderInit(&mr, pHandle->meta, 0);
      code = metaGetTableEntryByUid(&mr, pBlock->info.uid);
      if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
585
        if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
H
Haojun Liao 已提交
586 587 588 589
          qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.uid, tstrerror(terrno), idStr);
        } else {
          qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.uid, tstrerror(terrno), idStr);
        }
590 591 592 593 594 595
        metaReaderClear(&mr);
        return terrno;
      }

      metaReaderReleaseLock(&mr);

H
Haojun Liao 已提交
596
      STableCachedVal* pVal = createTableCacheVal(&mr);
597

H
Haojun Liao 已提交
598
      val = *pVal;
599
      freeReader = true;
H
Haojun Liao 已提交
600

601 602
      int32_t ret = taosLRUCacheInsert(pCache->pTableMetaEntryCache, &pBlock->info.uid, sizeof(uint64_t), pVal,
                                       sizeof(STableCachedVal), freeCachedMetaItem, NULL, TAOS_LRU_PRIORITY_LOW);
603 604 605 606 607 608 609 610
      if (ret != TAOS_LRU_STATUS_OK) {
        qError("failed to put meta into lru cache, code:%d, %s", ret, idStr);
        freeTableCachedVal(pVal);
      }
    } else {
      pCache->cacheHit += 1;
      STableCachedVal* pVal = taosLRUCacheValue(pCache->pTableMetaEntryCache, h);
      val = *pVal;
H
Haojun Liao 已提交
611

H
Haojun Liao 已提交
612
      taosLRUCacheRelease(pCache->pTableMetaEntryCache, h, false);
613
    }
H
Haojun Liao 已提交
614

615 616
    qDebug("retrieve table meta from cache:%" PRIu64 ", hit:%" PRIu64 " miss:%" PRIu64 ", %s", pCache->metaFetch,
           pCache->cacheHit, (pCache->metaFetch - pCache->cacheHit), idStr);
H
Haojun Liao 已提交
617
  }
618

619 620
  for (int32_t j = 0; j < numOfExpr; ++j) {
    const SExprInfo* pExpr1 = &pExpr[j];
621
    int32_t          dstSlotId = pExpr1->base.resSchema.slotId;
622 623

    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotId);
D
dapan1121 已提交
624
    colInfoDataCleanup(pColInfoData, pBlock->info.rows);
625

626
    int32_t functionId = pExpr1->pExpr->_function.functionId;
627 628 629

    // this is to handle the tbname
    if (fmIsScanPseudoColumnFunc(functionId)) {
630
      setTbNameColData(pBlock, pColInfoData, functionId, val.pName);
631
    } else {  // these are tags
wmmhello's avatar
wmmhello 已提交
632
      STagVal tagVal = {0};
633 634
      tagVal.cid = pExpr1->base.pParam[0].pCol->colId;
      const char* p = metaGetTableTagVal(val.pTags, pColInfoData->info.type, &tagVal);
wmmhello's avatar
wmmhello 已提交
635

636 637 638 639
      char* data = NULL;
      if (pColInfoData->info.type != TSDB_DATA_TYPE_JSON && p != NULL) {
        data = tTagValToData((const STagVal*)p, false);
      } else {
wmmhello's avatar
wmmhello 已提交
640
        data = (char*)p;
wmmhello's avatar
wmmhello 已提交
641
      }
642

H
Haojun Liao 已提交
643 644 645
      bool isNullVal = (data == NULL) || (pColInfoData->info.type == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(data));
      if (isNullVal) {
        colDataAppendNNULL(pColInfoData, 0, pBlock->info.rows);
H
Haojun Liao 已提交
646
      } else if (pColInfoData->info.type != TSDB_DATA_TYPE_JSON) {
H
Haojun Liao 已提交
647
        colDataAppendNItems(pColInfoData, 0, data, pBlock->info.rows);
H
Haojun Liao 已提交
648 649 650
        if (IS_VAR_DATA_TYPE(((const STagVal*)p)->type)) {
          taosMemoryFree(data);
        }
L
Liu Jicong 已提交
651
      } else {  // todo opt for json tag
H
Haojun Liao 已提交
652
        for (int32_t i = 0; i < pBlock->info.rows; ++i) {
H
Haojun Liao 已提交
653
          colDataAppend(pColInfoData, i, data, false);
H
Haojun Liao 已提交
654
        }
655 656 657 658
      }
    }
  }

659 660
  // restore the rows
  pBlock->info.rows = backupRows;
661 662 663 664
  if (freeReader) {
    metaReaderClear(&mr);
  }

H
Haojun Liao 已提交
665
  return TSDB_CODE_SUCCESS;
666 667
}

H
Haojun Liao 已提交
668
void setTbNameColData(const SSDataBlock* pBlock, SColumnInfoData* pColInfoData, int32_t functionId, const char* name) {
669 670 671
  struct SScalarFuncExecFuncs fpSet = {0};
  fmGetScalarFuncExecFuncs(functionId, &fpSet);

H
Haojun Liao 已提交
672
  size_t len = TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE;
673
  char   buf[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
H
Haojun Liao 已提交
674 675 676
  STR_TO_VARSTR(buf, name)

  SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, len, 1);
677

H
Haojun Liao 已提交
678 679
  colInfoDataEnsureCapacity(&infoData, 1, false);
  colDataAppend(&infoData, 0, buf, false);
680

H
Haojun Liao 已提交
681
  SScalarParam srcParam = {.numOfRows = pBlock->info.rows, .columnData = &infoData};
682
  SScalarParam param = {.columnData = pColInfoData};
H
Haojun Liao 已提交
683 684 685 686 687 688 689

  if (fpSet.process != NULL) {
    fpSet.process(&srcParam, 1, &param);
  } else {
    qError("failed to get the corresponding callback function, functionId:%d", functionId);
  }

D
dapan1121 已提交
690
  colDataDestroy(&infoData);
691 692
}

693
static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
694
  STableScanInfo* pTableScanInfo = pOperator->info;
695
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
L
Liu Jicong 已提交
696
  SSDataBlock*    pBlock = pTableScanInfo->pResBlock;
H
Haojun Liao 已提交
697

698 699
  int64_t st = taosGetTimestampUs();

700
  while (tsdbNextDataBlock(pTableScanInfo->dataReader)) {
701
    if (isTaskKilled(pTaskInfo)) {
702
      T_LONG_JMP(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED);
703
    }
H
Haojun Liao 已提交
704

705 706 707 708 709 710
    // process this data block based on the probabilities
    bool processThisBlock = processBlockWithProbability(&pTableScanInfo->sample);
    if (!processThisBlock) {
      continue;
    }

711
    blockDataCleanup(pBlock);
H
Haojun Liao 已提交
712
    SDataBlockInfo* pBInfo = &pBlock->info;
H
Haojun Liao 已提交
713 714 715 716

    int32_t rows = 0;
    tsdbRetrieveDataBlockInfo(pTableScanInfo->dataReader, &rows, &pBInfo->uid, &pBInfo->window);

717
    blockDataEnsureCapacity(pBlock, rows);  // todo remove it latter
H
Haojun Liao 已提交
718
    pBInfo->rows = rows;
719

H
Haojun Liao 已提交
720
    ASSERT(pBInfo->uid != 0);
H
Haojun Liao 已提交
721
    pBlock->info.groupId = getTableGroupId(pTaskInfo->pTableInfoList, pBlock->info.uid);
722

723 724 725 726
    uint32_t status = 0;
    int32_t  code = loadDataBlock(pOperator, pTableScanInfo, pBlock, &status);
    //    int32_t  code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status);
    if (code != TSDB_CODE_SUCCESS) {
727
      T_LONG_JMP(pOperator->pTaskInfo->env, code);
728
    }
729

730 731 732
    // current block is filter out according to filter condition, continue load the next block
    if (status == FUNC_DATA_REQUIRED_FILTEROUT || pBlock->info.rows == 0) {
      continue;
733
    }
734 735 736 737 738

    pOperator->resultInfo.totalRows = pTableScanInfo->readRecorder.totalRows;
    pTableScanInfo->readRecorder.elapsedTime += (taosGetTimestampUs() - st) / 1000.0;

    pOperator->cost.totalCost = pTableScanInfo->readRecorder.elapsedTime;
739 740

    // todo refactor
L
Liu Jicong 已提交
741 742 743 744 745
    /*pTableScanInfo->lastStatus.uid = pBlock->info.uid;*/
    /*pTableScanInfo->lastStatus.ts = pBlock->info.window.ekey;*/
    pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__SNAPSHOT_DATA;
    pTaskInfo->streamInfo.lastStatus.uid = pBlock->info.uid;
    pTaskInfo->streamInfo.lastStatus.ts = pBlock->info.window.ekey;
746

L
Liu Jicong 已提交
747
    ASSERT(pBlock->info.uid != 0);
748
    return pBlock;
H
Haojun Liao 已提交
749 750 751 752
  }
  return NULL;
}

H
Haojun Liao 已提交
753
static SSDataBlock* doGroupedTableScan(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
754 755 756 757
  STableScanInfo* pTableScanInfo = pOperator->info;
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;

  // The read handle is not initialized yet, since no qualified tables exists
758
  if (pTableScanInfo->dataReader == NULL || pOperator->status == OP_EXEC_DONE) {
H
Haojun Liao 已提交
759 760 761
    return NULL;
  }

762 763
  // do the ascending order traverse in the first place.
  while (pTableScanInfo->scanTimes < pTableScanInfo->scanInfo.numOfAsc) {
H
Haojun Liao 已提交
764 765 766
    SSDataBlock* p = doTableScanImpl(pOperator);
    if (p != NULL) {
      return p;
H
Haojun Liao 已提交
767 768
    }

769
    pTableScanInfo->scanTimes += 1;
770

771
    if (pTableScanInfo->scanTimes < pTableScanInfo->scanInfo.numOfAsc) {
772 773
      setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
      pTableScanInfo->scanFlag = REPEAT_SCAN;
774
      qDebug("start to repeat ascending order scan data blocks due to query func required, %s", GET_TASKID(pTaskInfo));
H
Haojun Liao 已提交
775

776
      // do prepare for the next round table scan operation
H
Haojun Liao 已提交
777
      tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond);
H
Haojun Liao 已提交
778
    }
779
  }
H
Haojun Liao 已提交
780

781
  int32_t total = pTableScanInfo->scanInfo.numOfAsc + pTableScanInfo->scanInfo.numOfDesc;
782
  if (pTableScanInfo->scanTimes < total) {
783
    if (pTableScanInfo->cond.order == TSDB_ORDER_ASC) {
H
Haojun Liao 已提交
784 785
      prepareForDescendingScan(pTableScanInfo, pOperator->exprSupp.pCtx, 0);
      tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond);
786
      qDebug("%s start to descending order scan data blocks due to query func required", GET_TASKID(pTaskInfo));
787
    }
H
Haojun Liao 已提交
788

789
    while (pTableScanInfo->scanTimes < total) {
H
Haojun Liao 已提交
790 791 792
      SSDataBlock* p = doTableScanImpl(pOperator);
      if (p != NULL) {
        return p;
793
      }
H
Haojun Liao 已提交
794

795
      pTableScanInfo->scanTimes += 1;
H
Haojun Liao 已提交
796

797
      if (pTableScanInfo->scanTimes < total) {
798 799
        setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
        pTableScanInfo->scanFlag = REPEAT_SCAN;
H
Haojun Liao 已提交
800

801
        qDebug("%s start to repeat descending order scan data blocks", GET_TASKID(pTaskInfo));
H
Haojun Liao 已提交
802
        tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond);
803
      }
H
Haojun Liao 已提交
804 805 806
    }
  }

wmmhello's avatar
wmmhello 已提交
807 808 809 810 811 812 813
  return NULL;
}

static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
  STableScanInfo* pInfo = pOperator->info;
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;

814
  // scan table one by one sequentially
L
Liu Jicong 已提交
815
  if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) {
H
Haojun Liao 已提交
816
    int32_t numOfTables = tableListGetSize(pTaskInfo->pTableInfoList);
H
Haojun Liao 已提交
817

L
Liu Jicong 已提交
818
    while (1) {
H
Haojun Liao 已提交
819
      SSDataBlock* result = doGroupedTableScan(pOperator);
L
Liu Jicong 已提交
820 821 822
      if (result) {
        return result;
      }
H
Haojun Liao 已提交
823

L
Liu Jicong 已提交
824 825
      // if no data, switch to next table and continue scan
      pInfo->currentTable++;
H
Haojun Liao 已提交
826
      if (pInfo->currentTable >= numOfTables) {
L
Liu Jicong 已提交
827 828
        return NULL;
      }
H
Haojun Liao 已提交
829

H
Haojun Liao 已提交
830
      STableKeyInfo* pTableInfo = tableListGetInfo(pTaskInfo->pTableInfoList, pInfo->currentTable);
831
      tsdbSetTableList(pInfo->dataReader, pTableInfo, 1);
L
Liu Jicong 已提交
832 833
      qDebug("set uid:%" PRIu64 " into scanner, total tables:%d, index:%d %s", pTableInfo->uid, numOfTables,
             pInfo->currentTable, pTaskInfo->id.str);
H
Haojun Liao 已提交
834

H
Haojun Liao 已提交
835
      tsdbReaderReset(pInfo->dataReader, &pInfo->cond);
L
Liu Jicong 已提交
836 837
      pInfo->scanTimes = 0;
    }
838 839
  } else {  // scan table group by group sequentially
    if (pInfo->currentGroupId == -1) {
H
Haojun Liao 已提交
840
      if ((++pInfo->currentGroupId) >= tableListGetOutputGroups(pTaskInfo->pTableInfoList)) {
H
Haojun Liao 已提交
841
        setOperatorCompleted(pOperator);
842 843
        return NULL;
      }
844

5
54liuyao 已提交
845
      int32_t        num = 0;
846
      STableKeyInfo* pList = NULL;
H
Haojun Liao 已提交
847
      tableListGetGroupList(pTaskInfo->pTableInfoList, pInfo->currentGroupId, &pList, &num);
848 849
      ASSERT(pInfo->dataReader == NULL);

5
54liuyao 已提交
850 851
      int32_t code = tsdbReaderOpen(pInfo->readHandle.vnode, &pInfo->cond, pList, num,
                                    (STsdbReader**)&pInfo->dataReader, GET_TASKID(pTaskInfo));
852 853 854
      if (code != TSDB_CODE_SUCCESS) {
        T_LONG_JMP(pTaskInfo->env, code);
      }
wmmhello's avatar
wmmhello 已提交
855
    }
H
Haojun Liao 已提交
856

H
Haojun Liao 已提交
857
    SSDataBlock* result = doGroupedTableScan(pOperator);
858
    if (result != NULL) {
H
Haojun Liao 已提交
859
      ASSERT(result->info.uid != 0);
860 861
      return result;
    }
H
Haojun Liao 已提交
862

H
Haojun Liao 已提交
863
    if ((++pInfo->currentGroupId) >= tableListGetOutputGroups(pTaskInfo->pTableInfoList)) {
H
Haojun Liao 已提交
864
      setOperatorCompleted(pOperator);
865 866
      return NULL;
    }
wmmhello's avatar
wmmhello 已提交
867

868 869 870 871
    // reset value for the next group data output
    pOperator->status = OP_OPENED;
    pInfo->limitInfo.numOfOutputRows = 0;
    pInfo->limitInfo.remainOffset = pInfo->limitInfo.limit.offset;
wmmhello's avatar
wmmhello 已提交
872

5
54liuyao 已提交
873
    int32_t        num = 0;
874
    STableKeyInfo* pList = NULL;
H
Haojun Liao 已提交
875
    tableListGetGroupList(pTaskInfo->pTableInfoList, pInfo->currentGroupId, &pList, &num);
wmmhello's avatar
wmmhello 已提交
876

877 878 879
    tsdbSetTableList(pInfo->dataReader, pList, num);
    tsdbReaderReset(pInfo->dataReader, &pInfo->cond);
    pInfo->scanTimes = 0;
wmmhello's avatar
wmmhello 已提交
880

H
Haojun Liao 已提交
881
    result = doGroupedTableScan(pOperator);
882 883 884
    if (result != NULL) {
      return result;
    }
885

H
Haojun Liao 已提交
886
    setOperatorCompleted(pOperator);
887 888
    return NULL;
  }
H
Haojun Liao 已提交
889 890
}

891 892
static int32_t getTableScannerExecInfo(struct SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
  SFileBlockLoadRecorder* pRecorder = taosMemoryCalloc(1, sizeof(SFileBlockLoadRecorder));
893
  STableScanInfo*         pTableScanInfo = pOptr->info;
894 895 896 897 898 899
  *pRecorder = pTableScanInfo->readRecorder;
  *pOptrExplain = pRecorder;
  *len = sizeof(SFileBlockLoadRecorder);
  return 0;
}

900
static void destroyTableScanOperatorInfo(void* param) {
901
  STableScanInfo* pTableScanInfo = (STableScanInfo*)param;
H
Haojun Liao 已提交
902
  blockDataDestroy(pTableScanInfo->pResBlock);
903
  cleanupQueryTableDataCond(&pTableScanInfo->cond);
H
Haojun Liao 已提交
904

H
refact  
Hongze Cheng 已提交
905
  tsdbReaderClose(pTableScanInfo->dataReader);
906
  pTableScanInfo->dataReader = NULL;
907

H
Haojun Liao 已提交
908 909
  if (pTableScanInfo->matchInfo.pList != NULL) {
    taosArrayDestroy(pTableScanInfo->matchInfo.pList);
910
  }
L
Liu Jicong 已提交
911

912
  taosLRUCacheCleanup(pTableScanInfo->metaCache.pTableMetaEntryCache);
913
  cleanupExprSupp(&pTableScanInfo->pseudoSup);
D
dapan1121 已提交
914
  taosMemoryFreeClear(param);
915 916
}

917
SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* readHandle,
918
                                           SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
919 920 921
  STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo));
  SOperatorInfo*  pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
  if (pInfo == NULL || pOperator == NULL) {
922
    goto _error;
H
Haojun Liao 已提交
923 924
  }

925
  SScanPhysiNode*     pScanNode = &pTableScanNode->scan;
H
Haojun Liao 已提交
926
  SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;
927 928

  int32_t numOfCols = 0;
929 930
  int32_t code =
      extractColMatchInfo(pScanNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
931 932 933 934
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

H
Haojun Liao 已提交
935
  initLimitInfo(pScanNode->node.pLimit, pScanNode->node.pSlimit, &pInfo->limitInfo);
H
Haojun Liao 已提交
936
  code = initQueryTableDataCond(&pInfo->cond, pTableScanNode);
937
  if (code != TSDB_CODE_SUCCESS) {
938
    goto _error;
939 940
  }

H
Haojun Liao 已提交
941
  if (pScanNode->pScanPseudoCols != NULL) {
942
    SExprSupp* pSup = &pInfo->pseudoSup;
H
Haojun Liao 已提交
943
    pSup->pExprInfo = createExprInfo(pScanNode->pScanPseudoCols, NULL, &pSup->numOfExprs);
944
    pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset);
945 946
  }

947
  pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]};
948
  pInfo->pdInfo.interval = extractIntervalInfo(pTableScanNode);
949 950 951
  pInfo->readHandle = *readHandle;
  pInfo->sample.sampleRatio = pTableScanNode->ratio;
  pInfo->sample.seed = taosGetTimestampSec();
952

953
  pInfo->dataBlockLoadFlag = pTableScanNode->dataRequired;
H
Haojun Liao 已提交
954 955

  initResultSizeInfo(&pOperator->resultInfo, 4096);
956
  pInfo->pResBlock = createResDataBlock(pDescNode);
H
Haojun Liao 已提交
957
  blockDataEnsureCapacity(pInfo->pResBlock, pOperator->resultInfo.capacity);
H
Haojun Liao 已提交
958

H
Haojun Liao 已提交
959 960 961
  code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
H
Haojun Liao 已提交
962 963
  }

964
  pInfo->scanFlag = MAIN_SCAN;
wmmhello's avatar
wmmhello 已提交
965
  pInfo->currentGroupId = -1;
966
  pInfo->assignBlockUid = pTableScanNode->assignBlockUid;
967

L
Liu Jicong 已提交
968 969
  setOperatorInfo(pOperator, "TableScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN, false, OP_NOT_OPENED, pInfo,
                  pTaskInfo);
970
  pOperator->exprSupp.numOfExprs = numOfCols;
971

972
  pInfo->metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);
973 974 975 976
  if (pInfo->metaCache.pTableMetaEntryCache == NULL) {
    code = terrno;
    goto _error;
  }
977

978
  taosLRUCacheSetStrictCapacity(pInfo->metaCache.pTableMetaEntryCache, false);
H
Haojun Liao 已提交
979
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScan, NULL, destroyTableScanOperatorInfo,
980
                                         getTableScannerExecInfo);
981 982 983

  // for non-blocking operator, the open cost is always 0
  pOperator->cost.openCost = 0;
H
Haojun Liao 已提交
984
  return pOperator;
985

986
_error:
987 988 989
  if (pInfo != NULL) {
    destroyTableScanOperatorInfo(pInfo);
  }
990

991 992
  taosMemoryFreeClear(pOperator);
  pTaskInfo->code = code;
993
  return NULL;
H
Haojun Liao 已提交
994 995
}

996
SOperatorInfo* createTableSeqScanOperatorInfo(void* pReadHandle, SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
997
  STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo));
L
Liu Jicong 已提交
998
  SOperatorInfo*  pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
999

L
Liu Jicong 已提交
1000 1001
  pInfo->dataReader = pReadHandle;
  //  pInfo->prevGroupId       = -1;
H
Haojun Liao 已提交
1002

L
Liu Jicong 已提交
1003 1004
  setOperatorInfo(pOperator, "TableSeqScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN, false, OP_NOT_OPENED,
                  pInfo, pTaskInfo);
H
Haojun Liao 已提交
1005
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScanImpl, NULL, NULL, NULL);
H
Haojun Liao 已提交
1006 1007 1008
  return pOperator;
}

H
Haojun Liao 已提交
1009 1010
static int32_t doGetTableRowSize(void* pMeta, uint64_t uid, int32_t* rowLen, const char* idstr) {
  *rowLen = 0;
H
Haojun Liao 已提交
1011

1012
  SMetaReader mr = {0};
1013
  metaReaderInit(&mr, pMeta, 0);
H
Haojun Liao 已提交
1014 1015
  int32_t code = metaGetTableEntryByUid(&mr, uid);
  if (code != TSDB_CODE_SUCCESS) {
L
Liu Jicong 已提交
1016
    qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", uid, tstrerror(terrno), idstr);
H
Haojun Liao 已提交
1017 1018 1019 1020
    metaReaderClear(&mr);
    return terrno;
  }

1021 1022
  if (mr.me.type == TSDB_SUPER_TABLE) {
    int32_t numOfCols = mr.me.stbEntry.schemaRow.nCols;
1023
    for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
1024
      (*rowLen) += mr.me.stbEntry.schemaRow.pSchema[i].bytes;
1025 1026 1027
    }
  } else if (mr.me.type == TSDB_CHILD_TABLE) {
    uint64_t suid = mr.me.ctbEntry.suid;
1028
    tDecoderClear(&mr.coder);
H
Haojun Liao 已提交
1029 1030
    code = metaGetTableEntryByUid(&mr, suid);
    if (code != TSDB_CODE_SUCCESS) {
L
Liu Jicong 已提交
1031
      qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", suid, tstrerror(terrno), idstr);
H
Haojun Liao 已提交
1032 1033 1034 1035
      metaReaderClear(&mr);
      return terrno;
    }

1036 1037
    int32_t numOfCols = mr.me.stbEntry.schemaRow.nCols;

1038
    for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
1039
      (*rowLen) += mr.me.stbEntry.schemaRow.pSchema[i].bytes;
1040 1041 1042
    }
  } else if (mr.me.type == TSDB_NORMAL_TABLE) {
    int32_t numOfCols = mr.me.ntbEntry.schemaRow.nCols;
1043
    for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
1044
      (*rowLen) += mr.me.ntbEntry.schemaRow.pSchema[i].bytes;
1045 1046 1047 1048
    }
  }

  metaReaderClear(&mr);
H
Haojun Liao 已提交
1049
  return TSDB_CODE_SUCCESS;
1050 1051 1052 1053 1054 1055 1056 1057
}

static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  SBlockDistInfo* pBlockScanInfo = pOperator->info;
L
Liu Jicong 已提交
1058
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
1059 1060

  STableBlockDistInfo blockDistInfo = {.minRows = INT_MAX, .maxRows = INT_MIN};
1061 1062
  int32_t             code = doGetTableRowSize(pBlockScanInfo->readHandle.meta, pBlockScanInfo->uid,
                                               (int32_t*)&blockDistInfo.rowSize, GET_TASKID(pTaskInfo));
H
Haojun Liao 已提交
1063
  if (code != TSDB_CODE_SUCCESS) {
1064
    T_LONG_JMP(pTaskInfo->env, code);
H
Haojun Liao 已提交
1065
  }
1066 1067 1068

  tsdbGetFileBlocksDistInfo(pBlockScanInfo->pHandle, &blockDistInfo);
  blockDistInfo.numOfInmemRows = (int32_t)tsdbGetNumOfRowsInMemTable(pBlockScanInfo->pHandle);
H
Haojun Liao 已提交
1069

1070
  SSDataBlock* pBlock = pBlockScanInfo->pResBlock;
H
Haojun Liao 已提交
1071

1072
  int32_t          slotId = pOperator->exprSupp.pExprInfo->base.resSchema.slotId;
1073
  SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, slotId);
H
Haojun Liao 已提交
1074

1075
  int32_t len = tSerializeBlockDistInfo(NULL, 0, &blockDistInfo);
1076
  char*   p = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
1077 1078 1079 1080 1081
  tSerializeBlockDistInfo(varDataVal(p), len, &blockDistInfo);
  varDataSetLen(p, len);

  colDataAppend(pColInfo, 0, p, false);
  taosMemoryFree(p);
H
Haojun Liao 已提交
1082

1083
  pBlock->info.rows = 1;
H
Haojun Liao 已提交
1084 1085 1086 1087
  pOperator->status = OP_EXEC_DONE;
  return pBlock;
}

1088
static void destroyBlockDistScanOperatorInfo(void* param) {
1089
  SBlockDistInfo* pDistInfo = (SBlockDistInfo*)param;
1090
  blockDataDestroy(pDistInfo->pResBlock);
H
Hongze Cheng 已提交
1091
  tsdbReaderClose(pDistInfo->pHandle);
D
dapan1121 已提交
1092
  taosMemoryFreeClear(param);
1093 1094
}

1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
static int32_t initTableblockDistQueryCond(uint64_t uid, SQueryTableDataCond* pCond) {
  memset(pCond, 0, sizeof(SQueryTableDataCond));

  pCond->order = TSDB_ORDER_ASC;
  pCond->numOfCols = 1;
  pCond->colList = taosMemoryCalloc(1, sizeof(SColumnInfo));
  if (pCond->colList == NULL) {
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
    return terrno;
  }

  pCond->colList->colId = 1;
  pCond->colList->type = TSDB_DATA_TYPE_TIMESTAMP;
  pCond->colList->bytes = sizeof(TSKEY);

  pCond->twindows = (STimeWindow){.skey = INT64_MIN, .ekey = INT64_MAX};
  pCond->suid = uid;
  pCond->type = TIMEWINDOW_RANGE_CONTAINED;
  pCond->startVersion = -1;
  pCond->endVersion = -1;

  return TSDB_CODE_SUCCESS;
}

5
54liuyao 已提交
1119 1120
SOperatorInfo* createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDistScanPhysiNode* pBlockScanNode,
                                               SExecTaskInfo* pTaskInfo) {
1121
  SBlockDistInfo* pInfo = taosMemoryCalloc(1, sizeof(SBlockDistInfo));
1122
  SOperatorInfo*  pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
H
Haojun Liao 已提交
1123 1124 1125 1126 1127
  if (pInfo == NULL || pOperator == NULL) {
    pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
    goto _error;
  }

1128 1129 1130 1131 1132
  {
    SQueryTableDataCond cond = {0};

    int32_t code = initTableblockDistQueryCond(pBlockScanNode->suid, &cond);
    if (code != TSDB_CODE_SUCCESS) {
dengyihao's avatar
merge  
dengyihao 已提交
1133
      goto _error;
1134 1135 1136
    }

    STableListInfo* pTableListInfo = pTaskInfo->pTableInfoList;
5
54liuyao 已提交
1137 1138
    size_t          num = tableListGetSize(pTableListInfo);
    void*           pList = tableListGetInfo(pTableListInfo, 0);
1139

dengyihao's avatar
dengyihao 已提交
1140
    code = tsdbReaderOpen(readHandle->vnode, &cond, pList, num, &pInfo->pHandle, pTaskInfo->id.str);
1141
    cleanupQueryTableDataCond(&cond);
dengyihao's avatar
dengyihao 已提交
1142 1143 1144
    if (code != 0) {
      goto _error;
    }
1145 1146
  }

1147
  pInfo->readHandle = *readHandle;
1148
  pInfo->uid = pBlockScanNode->suid;
H
Haojun Liao 已提交
1149

1150
  pInfo->pResBlock = createResDataBlock(pBlockScanNode->node.pOutputDataBlockDesc);
H
Haojun Liao 已提交
1151
  blockDataEnsureCapacity(pInfo->pResBlock, 1);
1152

1153
  int32_t    numOfCols = 0;
1154
  SExprInfo* pExprInfo = createExprInfo(pBlockScanNode->pScanPseudoCols, NULL, &numOfCols);
1155
  int32_t    code = initExprSupp(&pOperator->exprSupp, pExprInfo, numOfCols);
1156 1157 1158
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
H
Haojun Liao 已提交
1159

L
Liu Jicong 已提交
1160 1161 1162 1163
  setOperatorInfo(pOperator, "DataBlockDistScanOperator", QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN, false,
                  OP_NOT_OPENED, pInfo, pTaskInfo);
  pOperator->fpSet =
      createOperatorFpSet(operatorDummyOpenFn, doBlockInfoScan, NULL, destroyBlockDistScanOperatorInfo, NULL);
H
Haojun Liao 已提交
1164 1165
  return pOperator;

1166
_error:
H
Haojun Liao 已提交
1167 1168 1169 1170 1171
  taosMemoryFreeClear(pInfo);
  taosMemoryFreeClear(pOperator);
  return NULL;
}

1172
static FORCE_INLINE void doClearBufferedBlocks(SStreamScanInfo* pInfo) {
L
Liu Jicong 已提交
1173 1174
  taosArrayClear(pInfo->pBlockLists);
  pInfo->validBlockIndex = 0;
H
Haojun Liao 已提交
1175 1176
}

1177
static bool isSessionWindow(SStreamScanInfo* pInfo) {
H
Haojun Liao 已提交
1178
  return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION;
5
54liuyao 已提交
1179 1180
}

1181
static bool isStateWindow(SStreamScanInfo* pInfo) {
1182
  return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE;
5
54liuyao 已提交
1183
}
5
54liuyao 已提交
1184

L
Liu Jicong 已提交
1185
static bool isIntervalWindow(SStreamScanInfo* pInfo) {
1186 1187 1188
  return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL ||
         pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL ||
         pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL;
5
54liuyao 已提交
1189 1190 1191
}

static bool isSignleIntervalWindow(SStreamScanInfo* pInfo) {
1192
  return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL;
L
Liu Jicong 已提交
1193 1194
}

1195 1196 1197 1198
static bool isSlidingWindow(SStreamScanInfo* pInfo) {
  return isIntervalWindow(pInfo) && pInfo->interval.interval != pInfo->interval.sliding;
}

1199
static void setGroupId(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_t groupColIndex, int32_t rowIndex) {
1200 1201
  SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, groupColIndex);
  uint64_t*        groupCol = (uint64_t*)pColInfo->pData;
1202
  ASSERT(rowIndex < pBlock->info.rows);
1203
  pInfo->groupId = groupCol[rowIndex];
1204 1205
}

L
Liu Jicong 已提交
1206
void resetTableScanInfo(STableScanInfo* pTableScanInfo, STimeWindow* pWin) {
H
Haojun Liao 已提交
1207
  pTableScanInfo->cond.twindows = *pWin;
L
Liu Jicong 已提交
1208 1209
  pTableScanInfo->scanTimes = 0;
  pTableScanInfo->currentGroupId = -1;
1210 1211
  tsdbReaderClose(pTableScanInfo->dataReader);
  pTableScanInfo->dataReader = NULL;
1212 1213
}

L
Liu Jicong 已提交
1214 1215
static SSDataBlock* readPreVersionData(SOperatorInfo* pTableScanOp, uint64_t tbUid, TSKEY startTs, TSKEY endTs,
                                       int64_t maxVersion) {
1216
  STableKeyInfo tblInfo = {.uid = tbUid, .groupId = 0};
1217

1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
  STableScanInfo*     pTableScanInfo = pTableScanOp->info;
  SQueryTableDataCond cond = pTableScanInfo->cond;

  cond.startVersion = -1;
  cond.endVersion = maxVersion;
  cond.twindows = (STimeWindow){.skey = startTs, .ekey = endTs};

  SExecTaskInfo* pTaskInfo = pTableScanOp->pTaskInfo;

  SSDataBlock* pBlock = pTableScanInfo->pResBlock;
  blockDataCleanup(pBlock);

  STsdbReader* pReader = NULL;
5
54liuyao 已提交
1231 1232
  int32_t      code = tsdbReaderOpen(pTableScanInfo->readHandle.vnode, &cond, &tblInfo, 1, (STsdbReader**)&pReader,
                                     GET_TASKID(pTaskInfo));
1233 1234
  if (code != TSDB_CODE_SUCCESS) {
    terrno = code;
dengyihao's avatar
dengyihao 已提交
1235
    T_LONG_JMP(pTaskInfo->env, code);
1236 1237 1238 1239 1240
    return NULL;
  }

  bool hasBlock = tsdbNextDataBlock(pReader);
  if (hasBlock) {
H
Haojun Liao 已提交
1241
    SDataBlockInfo* pBInfo = &pBlock->info;
1242

H
Haojun Liao 已提交
1243 1244
    int32_t rows = 0;
    tsdbRetrieveDataBlockInfo(pReader, &rows, &pBInfo->uid, &pBInfo->window);
1245

H
Haojun Liao 已提交
1246
    SArray* pCols = tsdbRetrieveDataBlock(pReader, NULL);
H
Haojun Liao 已提交
1247 1248
    blockDataEnsureCapacity(pBlock, rows);
    pBlock->info.rows = rows;
1249 1250

    relocateColumnData(pBlock, pTableScanInfo->matchInfo.pList, pCols, true);
1251
    doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, rows);
H
Haojun Liao 已提交
1252

H
Haojun Liao 已提交
1253
    pBlock->info.groupId = getTableGroupId(pTaskInfo->pTableInfoList, pBInfo->uid);
1254 1255 1256 1257
  }

  tsdbReaderClose(pReader);
  qDebug("retrieve prev rows:%d, skey:%" PRId64 ", ekey:%" PRId64 " uid:%" PRIu64 ", max ver:%" PRId64
5
54liuyao 已提交
1258 1259
         ", suid:%" PRIu64,
         pBlock->info.rows, startTs, endTs, tbUid, maxVersion, cond.suid);
1260 1261

  return pBlock->info.rows > 0 ? pBlock : NULL;
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272
}

static uint64_t getGroupIdByCol(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, int64_t maxVersion) {
  SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, uid, ts, ts, maxVersion);
  if (!pPreRes || pPreRes->info.rows == 0) {
    return 0;
  }
  ASSERT(pPreRes->info.rows == 1);
  return calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pPreRes, 0);
}

5
54liuyao 已提交
1273
static uint64_t getGroupIdByUid(SStreamScanInfo* pInfo, uint64_t uid) {
H
Haojun Liao 已提交
1274
  return getTableGroupId(pInfo->pTableScanOp->pTaskInfo->pTableInfoList, uid);
1275 1276
}

5
54liuyao 已提交
1277 1278 1279 1280 1281 1282 1283 1284
static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, int64_t maxVersion) {
  if (pInfo->partitionSup.needCalc) {
    return getGroupIdByCol(pInfo, uid, ts, maxVersion);
  }

  return getGroupIdByUid(pInfo, uid);
}

L
Liu Jicong 已提交
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_t* pRowIndex) {
  if ((*pRowIndex) == pBlock->info.rows) {
    return false;
  }

  ASSERT(taosArrayGetSize(pBlock->pDataBlock) >= 3);
  SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
  TSKEY*           startData = (TSKEY*)pStartTsCol->pData;
  SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
  TSKEY*           endData = (TSKEY*)pEndTsCol->pData;
  STimeWindow      win = {.skey = startData[*pRowIndex], .ekey = endData[*pRowIndex]};
1296 1297 1298
  SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
  uint64_t*        gpData = (uint64_t*)pGpCol->pData;
  uint64_t         groupId = gpData[*pRowIndex];
1299 1300 1301 1302 1303 1304

  SColumnInfoData* pCalStartTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
  TSKEY*           calStartData = (TSKEY*)pCalStartTsCol->pData;
  SColumnInfoData* pCalEndTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
  TSKEY*           calEndData = (TSKEY*)pCalEndTsCol->pData;

L
Liu Jicong 已提交
1305
  setGroupId(pInfo, pBlock, GROUPID_COLUMN_INDEX, *pRowIndex);
1306 1307 1308 1309
  if (isSlidingWindow(pInfo)) {
    pInfo->updateWin.skey = calStartData[*pRowIndex];
    pInfo->updateWin.ekey = calEndData[*pRowIndex];
  }
L
Liu Jicong 已提交
1310 1311 1312
  (*pRowIndex)++;

  for (; *pRowIndex < pBlock->info.rows; (*pRowIndex)++) {
1313
    if (win.skey == startData[*pRowIndex] && groupId == gpData[*pRowIndex]) {
L
Liu Jicong 已提交
1314 1315 1316
      win.ekey = TMAX(win.ekey, endData[*pRowIndex]);
      continue;
    }
1317
    if (win.skey == endData[*pRowIndex] && groupId == gpData[*pRowIndex]) {
L
Liu Jicong 已提交
1318 1319 1320
      win.skey = TMIN(win.skey, startData[*pRowIndex]);
      continue;
    }
1321 1322
    ASSERT(!(win.skey > startData[*pRowIndex] && win.ekey < endData[*pRowIndex]) ||
           !(isInTimeWindow(&win, startData[*pRowIndex], 0) || isInTimeWindow(&win, endData[*pRowIndex], 0)));
L
Liu Jicong 已提交
1323 1324 1325 1326
    break;
  }

  resetTableScanInfo(pInfo->pTableScanOp->info, &win);
1327
  pInfo->pTableScanOp->status = OP_OPENED;
L
Liu Jicong 已提交
1328 1329 1330
  return true;
}

5
54liuyao 已提交
1331
static STimeWindow getSlidingWindow(TSKEY* startTsCol, TSKEY* endTsCol, uint64_t* gpIdCol, SInterval* pInterval,
1332
                                    SDataBlockInfo* pDataBlockInfo, int32_t* pRowIndex, bool hasGroup) {
H
Haojun Liao 已提交
1333
  SResultRowInfo dumyInfo = {0};
5
54liuyao 已提交
1334
  dumyInfo.cur.pageId = -1;
1335
  STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, startTsCol[*pRowIndex], pInterval, TSDB_ORDER_ASC);
5
54liuyao 已提交
1336 1337
  STimeWindow endWin = win;
  STimeWindow preWin = win;
5
54liuyao 已提交
1338
  uint64_t    groupId = gpIdCol[*pRowIndex];
H
Haojun Liao 已提交
1339

5
54liuyao 已提交
1340
  while (1) {
1341 1342 1343
    if (hasGroup) {
      (*pRowIndex) += 1;
    } else {
5
54liuyao 已提交
1344 1345 1346 1347 1348 1349
      while ((groupId == gpIdCol[(*pRowIndex)] && startTsCol[*pRowIndex] < endWin.ekey)) {
        (*pRowIndex) += 1;
        if ((*pRowIndex) == pDataBlockInfo->rows) {
          break;
        }
      }
1350
    }
5
54liuyao 已提交
1351

5
54liuyao 已提交
1352 1353 1354
    do {
      preWin = endWin;
      getNextTimeWindow(pInterval, &endWin, TSDB_ORDER_ASC);
1355
    } while (endTsCol[(*pRowIndex) - 1] >= endWin.skey);
5
54liuyao 已提交
1356
    endWin = preWin;
5
54liuyao 已提交
1357
    if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows || groupId != gpIdCol[*pRowIndex]) {
5
54liuyao 已提交
1358 1359 1360 1361 1362 1363
      win.ekey = endWin.ekey;
      return win;
    }
    win.ekey = endWin.ekey;
  }
}
5
54liuyao 已提交
1364

L
Liu Jicong 已提交
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375
static SSDataBlock* doRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pSDB, int32_t tsColIndex, int32_t* pRowIndex) {
  while (1) {
    SSDataBlock* pResult = NULL;
    pResult = doTableScan(pInfo->pTableScanOp);
    if (!pResult && prepareRangeScan(pInfo, pSDB, pRowIndex)) {
      // scan next window data
      pResult = doTableScan(pInfo->pTableScanOp);
    }
    if (!pResult) {
      blockDataCleanup(pSDB);
      *pRowIndex = 0;
5
54liuyao 已提交
1376
      pInfo->updateWin = (STimeWindow){.skey = INT64_MIN, .ekey = INT64_MAX};
H
Hongze Cheng 已提交
1377 1378 1379
      STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info;
      tsdbReaderClose(pTableScanInfo->dataReader);
      pTableScanInfo->dataReader = NULL;
1380 1381
      return NULL;
    }
L
Liu Jicong 已提交
1382

H
Haojun Liao 已提交
1383
    doFilter(pResult, pInfo->pTableScanOp->exprSupp.pFilterInfo, NULL);
1384 1385 1386 1387
    if (pResult->info.rows == 0) {
      continue;
    }

1388 1389 1390 1391 1392 1393 1394 1395
    if (pInfo->partitionSup.needCalc) {
      SSDataBlock* tmpBlock = createOneDataBlock(pResult, true);
      blockDataCleanup(pResult);
      for (int32_t i = 0; i < tmpBlock->info.rows; i++) {
        if (calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, tmpBlock, i) == pInfo->groupId) {
          for (int32_t j = 0; j < pInfo->pTableScanOp->exprSupp.numOfExprs; j++) {
            SColumnInfoData* pSrcCol = taosArrayGet(tmpBlock->pDataBlock, j);
            SColumnInfoData* pDestCol = taosArrayGet(pResult->pDataBlock, j);
L
Liu Jicong 已提交
1396 1397
            bool             isNull = colDataIsNull(pSrcCol, tmpBlock->info.rows, i, NULL);
            char*            pSrcData = colDataGetData(pSrcCol, i);
1398 1399 1400 1401 1402
            colDataAppend(pDestCol, pResult->info.rows, pSrcData, isNull);
          }
          pResult->info.rows++;
        }
      }
H
Haojun Liao 已提交
1403 1404 1405

      blockDataDestroy(tmpBlock);

1406 1407 1408 1409 1410
      if (pResult->info.rows > 0) {
        pResult->info.calWin = pInfo->updateWin;
        return pResult;
      }
    } else if (pResult->info.groupId == pInfo->groupId) {
5
54liuyao 已提交
1411
      pResult->info.calWin = pInfo->updateWin;
1412
      return pResult;
5
54liuyao 已提交
1413 1414
    }
  }
1415
}
1416

1417 1418 1419
static int32_t generateSessionScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock) {
  if (pSrcBlock->info.rows == 0) {
    return TSDB_CODE_SUCCESS;
1420
  }
1421 1422
  blockDataCleanup(pDestBlock);
  int32_t code = blockDataEnsureCapacity(pDestBlock, pSrcBlock->info.rows);
1423
  if (code != TSDB_CODE_SUCCESS) {
1424
    return code;
L
Liu Jicong 已提交
1425
  }
1426 1427
  ASSERT(taosArrayGetSize(pSrcBlock->pDataBlock) >= 3);
  SColumnInfoData* pStartTsCol = taosArrayGet(pSrcBlock->pDataBlock, START_TS_COLUMN_INDEX);
L
Liu Jicong 已提交
1428
  TSKEY*           startData = (TSKEY*)pStartTsCol->pData;
1429
  SColumnInfoData* pEndTsCol = taosArrayGet(pSrcBlock->pDataBlock, END_TS_COLUMN_INDEX);
L
Liu Jicong 已提交
1430
  TSKEY*           endData = (TSKEY*)pEndTsCol->pData;
1431 1432
  SColumnInfoData* pUidCol = taosArrayGet(pSrcBlock->pDataBlock, UID_COLUMN_INDEX);
  uint64_t*        uidCol = (uint64_t*)pUidCol->pData;
L
Liu Jicong 已提交
1433

1434 1435
  SColumnInfoData* pDestStartCol = taosArrayGet(pDestBlock->pDataBlock, START_TS_COLUMN_INDEX);
  SColumnInfoData* pDestEndCol = taosArrayGet(pDestBlock->pDataBlock, END_TS_COLUMN_INDEX);
5
54liuyao 已提交
1436
  SColumnInfoData* pDestUidCol = taosArrayGet(pDestBlock->pDataBlock, UID_COLUMN_INDEX);
1437
  SColumnInfoData* pDestGpCol = taosArrayGet(pDestBlock->pDataBlock, GROUPID_COLUMN_INDEX);
5
54liuyao 已提交
1438 1439
  SColumnInfoData* pDestCalStartTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
  SColumnInfoData* pDestCalEndTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
L
Liu Jicong 已提交
1440
  int64_t          version = pSrcBlock->info.version - 1;
1441
  for (int32_t i = 0; i < pSrcBlock->info.rows; i++) {
1442
    uint64_t groupId = getGroupIdByData(pInfo, uidCol[i], startData[i], version);
L
Liu Jicong 已提交
1443
    // gap must be 0.
5
54liuyao 已提交
1444
    SSessionKey startWin = {0};
1445
    getCurSessionWindow(pInfo->windowSup.pStreamAggSup, startData[i], startData[i], groupId, &startWin);
5
54liuyao 已提交
1446
    if (IS_INVALID_SESSION_WIN_KEY(startWin)) {
L
Liu Jicong 已提交
1447 1448 1449
      // window has been closed.
      continue;
    }
5
54liuyao 已提交
1450 1451 1452 1453 1454 1455
    SSessionKey endWin = {0};
    getCurSessionWindow(pInfo->windowSup.pStreamAggSup, endData[i], endData[i], groupId, &endWin);
    ASSERT(!IS_INVALID_SESSION_WIN_KEY(endWin));
    colDataAppend(pDestStartCol, i, (const char*)&startWin.win.skey, false);
    colDataAppend(pDestEndCol, i, (const char*)&endWin.win.ekey, false);

5
54liuyao 已提交
1456
    colDataAppendNULL(pDestUidCol, i);
L
Liu Jicong 已提交
1457
    colDataAppend(pDestGpCol, i, (const char*)&groupId, false);
5
54liuyao 已提交
1458 1459
    colDataAppendNULL(pDestCalStartTsCol, i);
    colDataAppendNULL(pDestCalEndTsCol, i);
1460
    pDestBlock->info.rows++;
L
Liu Jicong 已提交
1461
  }
1462
  return TSDB_CODE_SUCCESS;
L
Liu Jicong 已提交
1463
}
1464 1465 1466 1467 1468 1469

static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock) {
  blockDataCleanup(pDestBlock);
  int32_t rows = pSrcBlock->info.rows;
  if (rows == 0) {
    return TSDB_CODE_SUCCESS;
1470
  }
5
54liuyao 已提交
1471
  int32_t code = blockDataEnsureCapacity(pDestBlock, rows);
1472 1473 1474 1475
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

1476 1477
  SColumnInfoData* pSrcStartTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, START_TS_COLUMN_INDEX);
  SColumnInfoData* pSrcEndTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, END_TS_COLUMN_INDEX);
1478 1479 1480 1481
  SColumnInfoData* pSrcUidCol = taosArrayGet(pSrcBlock->pDataBlock, UID_COLUMN_INDEX);
  uint64_t*        srcUidData = (uint64_t*)pSrcUidCol->pData;
  SColumnInfoData* pSrcGpCol = taosArrayGet(pSrcBlock->pDataBlock, GROUPID_COLUMN_INDEX);
  uint64_t*        srcGp = (uint64_t*)pSrcGpCol->pData;
1482 1483 1484
  ASSERT(pSrcStartTsCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
  TSKEY*           srcStartTsCol = (TSKEY*)pSrcStartTsCol->pData;
  TSKEY*           srcEndTsCol = (TSKEY*)pSrcEndTsCol->pData;
1485 1486
  SColumnInfoData* pStartTsCol = taosArrayGet(pDestBlock->pDataBlock, START_TS_COLUMN_INDEX);
  SColumnInfoData* pEndTsCol = taosArrayGet(pDestBlock->pDataBlock, END_TS_COLUMN_INDEX);
1487
  SColumnInfoData* pDeUidCol = taosArrayGet(pDestBlock->pDataBlock, UID_COLUMN_INDEX);
1488 1489 1490
  SColumnInfoData* pGpCol = taosArrayGet(pDestBlock->pDataBlock, GROUPID_COLUMN_INDEX);
  SColumnInfoData* pCalStartTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
  SColumnInfoData* pCalEndTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
L
Liu Jicong 已提交
1491
  int64_t          version = pSrcBlock->info.version - 1;
1492
  for (int32_t i = 0; i < rows;) {
1493
    uint64_t srcUid = srcUidData[i];
5
54liuyao 已提交
1494 1495 1496 1497 1498
    uint64_t groupId = srcGp[i];
    if (groupId == 0) {
      groupId = getGroupIdByData(pInfo, srcUid, srcStartTsCol[i], version);
    }
    TSKEY calStartTs = srcStartTsCol[i];
1499
    colDataAppend(pCalStartTsCol, pDestBlock->info.rows, (const char*)(&calStartTs), false);
5
54liuyao 已提交
1500
    STimeWindow win = getSlidingWindow(srcStartTsCol, srcEndTsCol, srcGp, &pInfo->interval, &pSrcBlock->info, &i,
1501 1502
                                       pInfo->partitionSup.needCalc);
    TSKEY       calEndTs = srcStartTsCol[i - 1];
1503 1504
    colDataAppend(pCalEndTsCol, pDestBlock->info.rows, (const char*)(&calEndTs), false);
    colDataAppend(pDeUidCol, pDestBlock->info.rows, (const char*)(&srcUid), false);
1505 1506 1507 1508
    colDataAppend(pStartTsCol, pDestBlock->info.rows, (const char*)(&win.skey), false);
    colDataAppend(pEndTsCol, pDestBlock->info.rows, (const char*)(&win.ekey), false);
    colDataAppend(pGpCol, pDestBlock->info.rows, (const char*)(&groupId), false);
    pDestBlock->info.rows++;
5
54liuyao 已提交
1509
  }
1510 1511
  return TSDB_CODE_SUCCESS;
}
1512

1513
static int32_t generateDeleteResultBlock(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock) {
5
54liuyao 已提交
1514 1515 1516
  blockDataCleanup(pDestBlock);
  int32_t rows = pSrcBlock->info.rows;
  if (rows == 0) {
1517 1518
    return TSDB_CODE_SUCCESS;
  }
5
54liuyao 已提交
1519
  int32_t code = blockDataEnsureCapacity(pDestBlock, rows);
1520 1521 1522 1523
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }

5
54liuyao 已提交
1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
  SColumnInfoData* pSrcStartTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, START_TS_COLUMN_INDEX);
  SColumnInfoData* pSrcEndTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, END_TS_COLUMN_INDEX);
  SColumnInfoData* pSrcUidCol = taosArrayGet(pSrcBlock->pDataBlock, UID_COLUMN_INDEX);
  uint64_t*        srcUidData = (uint64_t*)pSrcUidCol->pData;
  SColumnInfoData* pSrcGpCol = taosArrayGet(pSrcBlock->pDataBlock, GROUPID_COLUMN_INDEX);
  uint64_t*        srcGp = (uint64_t*)pSrcGpCol->pData;
  ASSERT(pSrcStartTsCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
  TSKEY*  srcStartTsCol = (TSKEY*)pSrcStartTsCol->pData;
  TSKEY*  srcEndTsCol = (TSKEY*)pSrcEndTsCol->pData;
  int64_t version = pSrcBlock->info.version - 1;
1534
  for (int32_t i = 0; i < pSrcBlock->info.rows; i++) {
5
54liuyao 已提交
1535 1536
    uint64_t srcUid = srcUidData[i];
    uint64_t groupId = srcGp[i];
L
Liu Jicong 已提交
1537
    char*    tbname[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN] = {0};
5
54liuyao 已提交
1538 1539 1540
    if (groupId == 0) {
      groupId = getGroupIdByData(pInfo, srcUid, srcStartTsCol[i], version);
    }
L
Liu Jicong 已提交
1541 1542 1543 1544 1545 1546 1547
    if (pInfo->tbnameCalSup.pExprInfo) {
      char* parTbname = taosHashGet(pInfo->pGroupIdTbNameMap, &groupId, sizeof(int64_t));
      memcpy(varDataVal(tbname), parTbname, TSDB_TABLE_NAME_LEN);
      varDataSetLen(tbname, strlen(varDataVal(tbname)));
    }
    appendOneRowToStreamSpecialBlock(pDestBlock, srcStartTsCol + i, srcEndTsCol + i, srcUidData + i, &groupId,
                                     tbname[0] == 0 ? NULL : tbname);
1548 1549 1550 1551
  }
  return TSDB_CODE_SUCCESS;
}

1552 1553 1554 1555
static int32_t generateScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock) {
  int32_t code = TSDB_CODE_SUCCESS;
  if (isIntervalWindow(pInfo)) {
    code = generateIntervalScanRange(pInfo, pSrcBlock, pDestBlock);
1556
  } else if (isSessionWindow(pInfo) || isStateWindow(pInfo)) {
1557
    code = generateSessionScanRange(pInfo, pSrcBlock, pDestBlock);
5
54liuyao 已提交
1558 1559
  } else {
    code = generateDeleteResultBlock(pInfo, pSrcBlock, pDestBlock);
1560
  }
1561
  pDestBlock->info.type = STREAM_CLEAR;
1562
  pDestBlock->info.version = pSrcBlock->info.version;
1563 1564 1565 1566
  blockDataUpdateTsWindow(pDestBlock, 0);
  return code;
}

L
Liu Jicong 已提交
1567 1568 1569 1570 1571 1572 1573 1574 1575
static void calBlockTag(SExprSupp* pTagCalSup, SSDataBlock* pBlock, SSDataBlock* pResBlock) {
  if (pTagCalSup == NULL || pTagCalSup->numOfExprs == 0) return;
  if (pBlock == NULL || pBlock->info.rows == 0) return;

  SSDataBlock* pSrcBlock = blockCopyOneRow(pBlock, 0);
  ASSERT(pSrcBlock->info.rows == 1);

  blockDataEnsureCapacity(pResBlock, 1);

H
Haojun Liao 已提交
1576
  projectApplyFunctions(pTagCalSup->pExprInfo, pResBlock, pSrcBlock, pTagCalSup->pCtx, 1, NULL);
L
Liu Jicong 已提交
1577 1578 1579
  ASSERT(pResBlock->info.rows == 1);

  // build tagArray
1580 1581 1582 1583 1584
  /*SArray* tagArray = taosArrayInit(0, sizeof(void*));*/
  /*STagVal tagVal = {*/
  /*.cid = 0,*/
  /*.type = 0,*/
  /*};*/
L
Liu Jicong 已提交
1585 1586 1587 1588 1589 1590
  // build STag
  // set STag

  blockDataDestroy(pSrcBlock);
}

L
Liu Jicong 已提交
1591 1592
void calBlockTbName(SStreamScanInfo* pInfo, SSDataBlock* pBlock) {
  SExprSupp* pTbNameCalSup = &pInfo->tbnameCalSup;
L
Liu Jicong 已提交
1593 1594
  if (pTbNameCalSup == NULL || pTbNameCalSup->numOfExprs == 0) return;
  if (pBlock == NULL || pBlock->info.rows == 0) return;
L
Liu Jicong 已提交
1595 1596 1597 1598 1599 1600
  if (pBlock->info.groupId) {
    char* tbname = taosHashGet(pInfo->pGroupIdTbNameMap, &pBlock->info.groupId, sizeof(int64_t));
    if (tbname != NULL) {
      memcpy(pBlock->info.parTbName, tbname, TSDB_TABLE_NAME_LEN);
    }
  }
L
Liu Jicong 已提交
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619

  SSDataBlock* pSrcBlock = blockCopyOneRow(pBlock, 0);
  ASSERT(pSrcBlock->info.rows == 1);

  SSDataBlock* pResBlock = createDataBlock();
  pResBlock->info.rowSize = VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN;
  SColumnInfoData data = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, TSDB_TABLE_NAME_LEN, 0);
  taosArrayPush(pResBlock->pDataBlock, &data);
  blockDataEnsureCapacity(pResBlock, 1);

  projectApplyFunctions(pTbNameCalSup->pExprInfo, pResBlock, pSrcBlock, pTbNameCalSup->pCtx, 1, NULL);
  ASSERT(pResBlock->info.rows == 1);
  ASSERT(taosArrayGetSize(pResBlock->pDataBlock) == 1);
  SColumnInfoData* pCol = taosArrayGet(pResBlock->pDataBlock, 0);
  ASSERT(pCol->info.type == TSDB_DATA_TYPE_VARCHAR);

  void* pData = colDataGetData(pCol, 0);
  // TODO check tbname validation
  if (pData != (void*)-1 && pData != NULL) {
1620
    memset(pBlock->info.parTbName, 0, TSDB_TABLE_NAME_LEN);
L
Liu Jicong 已提交
1621
    int32_t len = TMIN(varDataLen(pData), TSDB_TABLE_NAME_LEN - 1);
1622 1623
    memcpy(pBlock->info.parTbName, varDataVal(pData), len);
    /*pBlock->info.parTbName[len + 1] = 0;*/
L
Liu Jicong 已提交
1624 1625 1626 1627
  } else {
    pBlock->info.parTbName[0] = 0;
  }

L
Liu Jicong 已提交
1628 1629 1630 1631 1632
  if (pBlock->info.groupId) {
    taosHashPut(pInfo->pGroupIdTbNameMap, &pBlock->info.groupId, sizeof(int64_t), pBlock->info.parTbName,
                TSDB_TABLE_NAME_LEN);
  }

L
Liu Jicong 已提交
1633 1634 1635 1636
  blockDataDestroy(pSrcBlock);
  blockDataDestroy(pResBlock);
}

1637 1638
void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
                                      uint64_t* pGp, void* pTbName) {
1639 1640
  SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
  SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
1641 1642
  SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX);
  SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
1643 1644
  SColumnInfoData* pCalStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
  SColumnInfoData* pCalEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
1645
  SColumnInfoData* pTableCol = taosArrayGet(pBlock->pDataBlock, TABLE_NAME_COLUMN_INDEX);
1646 1647
  colDataAppend(pStartTsCol, pBlock->info.rows, (const char*)pStartTs, false);
  colDataAppend(pEndTsCol, pBlock->info.rows, (const char*)pEndTs, false);
1648 1649
  colDataAppend(pUidCol, pBlock->info.rows, (const char*)pUid, false);
  colDataAppend(pGpCol, pBlock->info.rows, (const char*)pGp, false);
1650 1651
  colDataAppend(pCalStartCol, pBlock->info.rows, (const char*)pStartTs, false);
  colDataAppend(pCalEndCol, pBlock->info.rows, (const char*)pEndTs, false);
1652
  colDataAppend(pTableCol, pBlock->info.rows, (const char*)pTbName, pTbName == NULL);
1653
  pBlock->info.rows++;
5
54liuyao 已提交
1654 1655
}

1656
static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock* pBlock, bool out) {
1657 1658
  if (out) {
    blockDataCleanup(pInfo->pUpdateDataRes);
5
54liuyao 已提交
1659
    blockDataEnsureCapacity(pInfo->pUpdateDataRes, pBlock->info.rows * 2);
1660
  }
1661 1662
  SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex);
  ASSERT(pColDataInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP);
5
54liuyao 已提交
1663
  TSKEY* tsCol = (TSKEY*)pColDataInfo->pData;
L
Liu Jicong 已提交
1664
  bool   tableInserted = updateInfoIsTableInserted(pInfo->pUpdateInfo, pBlock->info.uid);
1665
  for (int32_t rowId = 0; rowId < pBlock->info.rows; rowId++) {
5
54liuyao 已提交
1666 1667
    SResultRowInfo dumyInfo;
    dumyInfo.cur.pageId = -1;
L
Liu Jicong 已提交
1668
    bool        isClosed = false;
5
54liuyao 已提交
1669
    STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
L
Liu Jicong 已提交
1670
    if (tableInserted && isOverdue(tsCol[rowId], &pInfo->twAggSup)) {
5
54liuyao 已提交
1671 1672 1673
      win = getActiveTimeWindow(NULL, &dumyInfo, tsCol[rowId], &pInfo->interval, TSDB_ORDER_ASC);
      isClosed = isCloseWindow(&win, &pInfo->twAggSup);
    }
5
54liuyao 已提交
1674 1675
    // must check update info first.
    bool update = updateInfoIsUpdated(pInfo->pUpdateInfo, pBlock->info.uid, tsCol[rowId]);
L
Liu Jicong 已提交
1676
    bool closedWin = isClosed && isSignleIntervalWindow(pInfo) &&
1677 1678
                     isDeletedStreamWindow(&win, pBlock->info.groupId,
                                           pInfo->pTableScanOp->pTaskInfo->streamInfo.pState, &pInfo->twAggSup);
L
Liu Jicong 已提交
1679
    if ((update || closedWin) && out) {
L
Liu Jicong 已提交
1680
      qDebug("stream update check not pass, update %d, closedWin %d", update, closedWin);
5
54liuyao 已提交
1681
      uint64_t gpId = 0;
1682 1683
      appendOneRowToStreamSpecialBlock(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid, &gpId,
                                       NULL);
5
54liuyao 已提交
1684 1685
      if (closedWin && pInfo->partitionSup.needCalc) {
        gpId = calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pBlock, rowId);
1686 1687
        appendOneRowToStreamSpecialBlock(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid, &gpId,
                                         NULL);
5
54liuyao 已提交
1688
      }
1689 1690
    }
  }
1691 1692
  if (out && pInfo->pUpdateDataRes->info.rows > 0) {
    pInfo->pUpdateDataRes->info.version = pBlock->info.version;
1693
    blockDataUpdateTsWindow(pInfo->pUpdateDataRes, 0);
1694
    pInfo->pUpdateDataRes->info.type = pInfo->partitionSup.needCalc ? STREAM_DELETE_DATA : STREAM_CLEAR;
5
54liuyao 已提交
1695 1696
  }
}
L
Liu Jicong 已提交
1697

1698
static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock, bool filter) {
L
Liu Jicong 已提交
1699 1700
  SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;
  SOperatorInfo*  pOperator = pInfo->pStreamScanOp;
L
Liu Jicong 已提交
1701
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
L
Liu Jicong 已提交
1702

1703 1704
  blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);

L
Liu Jicong 已提交
1705 1706 1707
  pInfo->pRes->info.rows = pBlock->info.rows;
  pInfo->pRes->info.uid = pBlock->info.uid;
  pInfo->pRes->info.type = STREAM_NORMAL;
1708
  pInfo->pRes->info.version = pBlock->info.version;
L
Liu Jicong 已提交
1709

H
Haojun Liao 已提交
1710
  pInfo->pRes->info.groupId = getTableGroupId(pTaskInfo->pTableInfoList, pBlock->info.uid);
L
Liu Jicong 已提交
1711 1712

  // todo extract method
H
Haojun Liao 已提交
1713 1714 1715
  for (int32_t i = 0; i < taosArrayGetSize(pInfo->matchInfo.pList); ++i) {
    SColMatchItem* pColMatchInfo = taosArrayGet(pInfo->matchInfo.pList, i);
    if (!pColMatchInfo->needOutput) {
L
Liu Jicong 已提交
1716 1717 1718 1719 1720 1721 1722
      continue;
    }

    bool colExists = false;
    for (int32_t j = 0; j < blockDataGetNumOfCols(pBlock); ++j) {
      SColumnInfoData* pResCol = bdGetColumnInfoData(pBlock, j);
      if (pResCol->info.colId == pColMatchInfo->colId) {
H
Haojun Liao 已提交
1723
        SColumnInfoData* pDst = taosArrayGet(pInfo->pRes->pDataBlock, pColMatchInfo->dstSlotId);
1724
        colDataAssign(pDst, pResCol, pBlock->info.rows, &pInfo->pRes->info);
L
Liu Jicong 已提交
1725 1726 1727 1728 1729 1730 1731
        colExists = true;
        break;
      }
    }

    // the required column does not exists in submit block, let's set it to be all null value
    if (!colExists) {
H
Haojun Liao 已提交
1732
      SColumnInfoData* pDst = taosArrayGet(pInfo->pRes->pDataBlock, pColMatchInfo->dstSlotId);
L
Liu Jicong 已提交
1733 1734 1735 1736 1737 1738
      colDataAppendNNULL(pDst, 0, pBlockInfo->rows);
    }
  }

  // currently only the tbname pseudo column
  if (pInfo->numOfPseudoExpr > 0) {
L
Liu Jicong 已提交
1739
    int32_t code = addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes,
1740
                                          pInfo->pRes->info.rows, GET_TASKID(pTaskInfo), NULL);
H
Haojun Liao 已提交
1741
    if (code != TSDB_CODE_SUCCESS) {
L
Liu Jicong 已提交
1742
      blockDataFreeRes((SSDataBlock*)pBlock);
1743
      T_LONG_JMP(pTaskInfo->env, code);
H
Haojun Liao 已提交
1744
    }
L
Liu Jicong 已提交
1745 1746
  }

1747
  if (filter) {
H
Haojun Liao 已提交
1748
    doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL);
1749
  }
1750

L
Liu Jicong 已提交
1751
  blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
L
Liu Jicong 已提交
1752
  blockDataFreeRes((SSDataBlock*)pBlock);
L
Liu Jicong 已提交
1753

L
Liu Jicong 已提交
1754
  calBlockTbName(pInfo, pInfo->pRes);
L
Liu Jicong 已提交
1755 1756
  return 0;
}
5
54liuyao 已提交
1757

L
Liu Jicong 已提交
1758
static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
1759 1760
  SExecTaskInfo*   pTaskInfo = pOperator->pTaskInfo;
  SStreamScanInfo* pInfo = pOperator->info;
H
Haojun Liao 已提交
1761

L
Liu Jicong 已提交
1762
  qDebug("queue scan called");
L
Liu Jicong 已提交
1763 1764 1765 1766 1767 1768 1769 1770

  if (pTaskInfo->streamInfo.pReq != NULL) {
    if (pInfo->tqReader->pMsg == NULL) {
      pInfo->tqReader->pMsg = pTaskInfo->streamInfo.pReq;
      const SSubmitReq* pSubmit = pInfo->tqReader->pMsg;
      if (tqReaderSetDataMsg(pInfo->tqReader, pSubmit, 0) < 0) {
        qError("submit msg messed up when initing stream submit block %p", pSubmit);
        pInfo->tqReader->pMsg = NULL;
L
Liu Jicong 已提交
1771
        pTaskInfo->streamInfo.pReq = NULL;
L
Liu Jicong 已提交
1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787
        ASSERT(0);
      }
    }

    blockDataCleanup(pInfo->pRes);
    SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;

    while (tqNextDataBlock(pInfo->tqReader)) {
      SSDataBlock block = {0};

      int32_t code = tqRetrieveDataBlock(&block, pInfo->tqReader);

      if (code != TSDB_CODE_SUCCESS || block.info.rows == 0) {
        continue;
      }

1788
      setBlockIntoRes(pInfo, &block, true);
L
Liu Jicong 已提交
1789 1790 1791 1792 1793 1794 1795 1796

      if (pBlockInfo->rows > 0) {
        return pInfo->pRes;
      }
    }

    pInfo->tqReader->pMsg = NULL;
    pTaskInfo->streamInfo.pReq = NULL;
L
Liu Jicong 已提交
1797
    return NULL;
L
Liu Jicong 已提交
1798 1799
  }

L
Liu Jicong 已提交
1800 1801 1802
  if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__SNAPSHOT_DATA) {
    SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp);
    if (pResult && pResult->info.rows > 0) {
L
Liu Jicong 已提交
1803
      qDebug("queue scan tsdb return %d rows", pResult->info.rows);
1804
      pTaskInfo->streamInfo.returned = 1;
L
Liu Jicong 已提交
1805 1806
      return pResult;
    } else {
1807 1808 1809 1810 1811
      if (!pTaskInfo->streamInfo.returned) {
        STableScanInfo* pTSInfo = pInfo->pTableScanOp->info;
        tsdbReaderClose(pTSInfo->dataReader);
        pTSInfo->dataReader = NULL;
        tqOffsetResetToLog(&pTaskInfo->streamInfo.prepareStatus, pTaskInfo->streamInfo.snapshotVer);
1812
        qDebug("queue scan tsdb over, switch to wal ver %" PRId64 "", pTaskInfo->streamInfo.snapshotVer + 1);
1813
        if (tqSeekVer(pInfo->tqReader, pTaskInfo->streamInfo.snapshotVer + 1) < 0) {
1814
          tqOffsetResetToLog(&pTaskInfo->streamInfo.lastStatus, pTaskInfo->streamInfo.snapshotVer);
1815 1816 1817 1818
          return NULL;
        }
        ASSERT(pInfo->tqReader->pWalReader->curVersion == pTaskInfo->streamInfo.snapshotVer + 1);
      } else {
L
Liu Jicong 已提交
1819 1820
        return NULL;
      }
1821 1822 1823
    }
  }

L
Liu Jicong 已提交
1824 1825 1826 1827 1828 1829
  if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__LOG) {
    while (1) {
      SFetchRet ret = {0};
      tqNextBlock(pInfo->tqReader, &ret);
      if (ret.fetchType == FETCH_TYPE__DATA) {
        blockDataCleanup(pInfo->pRes);
1830
        if (setBlockIntoRes(pInfo, &ret.data, true) < 0) {
L
Liu Jicong 已提交
1831 1832 1833
          ASSERT(0);
        }
        if (pInfo->pRes->info.rows > 0) {
L
Liu Jicong 已提交
1834
          pOperator->status = OP_EXEC_RECV;
L
Liu Jicong 已提交
1835
          qDebug("queue scan log return %d rows", pInfo->pRes->info.rows);
L
Liu Jicong 已提交
1836 1837 1838 1839
          return pInfo->pRes;
        }
      } else if (ret.fetchType == FETCH_TYPE__META) {
        ASSERT(0);
L
Liu Jicong 已提交
1840 1841 1842
        //        pTaskInfo->streamInfo.lastStatus = ret.offset;
        //        pTaskInfo->streamInfo.metaBlk = ret.meta;
        //        return NULL;
L
Liu Jicong 已提交
1843 1844
      } else if (ret.fetchType == FETCH_TYPE__NONE ||
                 (ret.fetchType == FETCH_TYPE__SEP && pOperator->status == OP_EXEC_RECV)) {
L
Liu Jicong 已提交
1845
        pTaskInfo->streamInfo.lastStatus = ret.offset;
1846 1847 1848 1849
        ASSERT(pTaskInfo->streamInfo.lastStatus.version >= pTaskInfo->streamInfo.prepareStatus.version);
        ASSERT(pTaskInfo->streamInfo.lastStatus.version + 1 == pInfo->tqReader->pWalReader->curVersion);
        char formatBuf[80];
        tFormatOffset(formatBuf, 80, &ret.offset);
L
Liu Jicong 已提交
1850
        qDebug("queue scan log return null, offset %s", formatBuf);
L
Liu Jicong 已提交
1851
        pOperator->status = OP_OPENED;
L
Liu Jicong 已提交
1852 1853 1854
        return NULL;
      }
    }
L
Liu Jicong 已提交
1855
#if 0
1856
    } else if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__SNAPSHOT_DATA) {
L
Liu Jicong 已提交
1857
    SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp);
L
Liu Jicong 已提交
1858 1859 1860 1861 1862 1863
    if (pResult && pResult->info.rows > 0) {
      qDebug("stream scan tsdb return %d rows", pResult->info.rows);
      return pResult;
    }
    qDebug("stream scan tsdb return null");
    return NULL;
L
Liu Jicong 已提交
1864
#endif
L
Liu Jicong 已提交
1865 1866 1867
  } else {
    ASSERT(0);
    return NULL;
H
Haojun Liao 已提交
1868
  }
L
Liu Jicong 已提交
1869 1870
}

L
Liu Jicong 已提交
1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898
static int32_t filterDelBlockByUid(SSDataBlock* pDst, const SSDataBlock* pSrc, SStreamScanInfo* pInfo) {
  STqReader* pReader = pInfo->tqReader;
  int32_t    rows = pSrc->info.rows;
  blockDataEnsureCapacity(pDst, rows);

  SColumnInfoData* pSrcStartCol = taosArrayGet(pSrc->pDataBlock, START_TS_COLUMN_INDEX);
  uint64_t*        startCol = (uint64_t*)pSrcStartCol->pData;
  SColumnInfoData* pSrcEndCol = taosArrayGet(pSrc->pDataBlock, END_TS_COLUMN_INDEX);
  uint64_t*        endCol = (uint64_t*)pSrcEndCol->pData;
  SColumnInfoData* pSrcUidCol = taosArrayGet(pSrc->pDataBlock, UID_COLUMN_INDEX);
  uint64_t*        uidCol = (uint64_t*)pSrcUidCol->pData;

  SColumnInfoData* pDstStartCol = taosArrayGet(pDst->pDataBlock, START_TS_COLUMN_INDEX);
  SColumnInfoData* pDstEndCol = taosArrayGet(pDst->pDataBlock, END_TS_COLUMN_INDEX);
  SColumnInfoData* pDstUidCol = taosArrayGet(pDst->pDataBlock, UID_COLUMN_INDEX);
  int32_t          j = 0;
  for (int32_t i = 0; i < rows; i++) {
    if (taosHashGet(pReader->tbIdHash, &uidCol[i], sizeof(uint64_t))) {
      colDataAppend(pDstStartCol, j, (const char*)&startCol[i], false);
      colDataAppend(pDstEndCol, j, (const char*)&endCol[i], false);
      colDataAppend(pDstUidCol, j, (const char*)&uidCol[i], false);

      colDataAppendNULL(taosArrayGet(pDst->pDataBlock, GROUPID_COLUMN_INDEX), j);
      colDataAppendNULL(taosArrayGet(pDst->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX), j);
      colDataAppendNULL(taosArrayGet(pDst->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX), j);
      j++;
    }
  }
L
Liu Jicong 已提交
1899
  uint32_t cap = pDst->info.capacity;
L
Liu Jicong 已提交
1900 1901
  pDst->info = pSrc->info;
  pDst->info.rows = j;
L
Liu Jicong 已提交
1902
  pDst->info.capacity = cap;
L
Liu Jicong 已提交
1903 1904 1905 1906

  return 0;
}

5
54liuyao 已提交
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930
// for partition by tag
static void setBlockGroupIdByUid(SStreamScanInfo* pInfo, SSDataBlock* pBlock) {
  SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
  TSKEY*           startTsCol = (TSKEY*)pStartTsCol->pData;
  SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
  uint64_t*        gpCol = (uint64_t*)pGpCol->pData;
  SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX);
  uint64_t*        uidCol = (uint64_t*)pUidCol->pData;
  int32_t          rows = pBlock->info.rows;
  if (!pInfo->partitionSup.needCalc) {
    for (int32_t i = 0; i < rows; i++) {
      uint64_t groupId = getGroupIdByUid(pInfo, uidCol[i]);
      colDataAppend(pGpCol, i, (const char*)&groupId, false);
    }
  } else {
    // SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, uidCol[i], startTsCol, ts, maxVersion);
    // if (!pPreRes || pPreRes->info.rows == 0) {
    //   return 0;
    // }
    // ASSERT(pPreRes->info.rows == 1);
    // return calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pPreRes, 0);
  }
}

L
Liu Jicong 已提交
1931 1932 1933 1934 1935
static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
  // NOTE: this operator does never check if current status is done or not
  SExecTaskInfo*   pTaskInfo = pOperator->pTaskInfo;
  SStreamScanInfo* pInfo = pOperator->info;

L
Liu Jicong 已提交
1936
  qDebug("stream scan called");
L
Liu Jicong 已提交
1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
#if 0
  SStreamState* pState = pTaskInfo->streamInfo.pState;
  if (pState) {
    printf(">>>>>>>> stream write backend\n");
    SWinKey key = {
        .ts = 1,
        .groupId = 2,
    };
    char tmp[100] = "abcdefg1";
    if (streamStatePut(pState, &key, &tmp, strlen(tmp) + 1) < 0) {
      ASSERT(0);
    }

    key.ts = 2;
    char tmp2[100] = "abcdefg2";
    if (streamStatePut(pState, &key, &tmp2, strlen(tmp2) + 1) < 0) {
      ASSERT(0);
    }

    key.groupId = 5;
    key.ts = 1;
    char tmp3[100] = "abcdefg3";
    if (streamStatePut(pState, &key, &tmp3, strlen(tmp3) + 1) < 0) {
      ASSERT(0);
    }

    char*   val2 = NULL;
    int32_t sz;
    if (streamStateGet(pState, &key, (void**)&val2, &sz) < 0) {
      ASSERT(0);
    }
    printf("stream read %s %d\n", val2, sz);
    streamFreeVal(val2);
H
Haojun Liao 已提交
1970
  }
L
Liu Jicong 已提交
1971
#endif
H
Haojun Liao 已提交
1972

1973 1974
  if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__PREPARE1 ||
      pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__PREPARE2) {
L
Liu Jicong 已提交
1975 1976
    STableScanInfo* pTSInfo = pInfo->pTableScanOp->info;
    memcpy(&pTSInfo->cond, &pTaskInfo->streamInfo.tableCond, sizeof(SQueryTableDataCond));
1977
    if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__PREPARE1) {
1978
      pTSInfo->cond.startVersion = 0;
1979
      pTSInfo->cond.endVersion = pTaskInfo->streamInfo.fillHistoryVer1;
1980 1981
      qDebug("stream recover step 1, from %" PRId64 " to %" PRId64, pTSInfo->cond.startVersion,
             pTSInfo->cond.endVersion);
1982 1983 1984
    } else {
      pTSInfo->cond.startVersion = pTaskInfo->streamInfo.fillHistoryVer1 + 1;
      pTSInfo->cond.endVersion = pTaskInfo->streamInfo.fillHistoryVer2;
1985 1986
      qDebug("stream recover step 2, from %" PRId64 " to %" PRId64, pTSInfo->cond.startVersion,
             pTSInfo->cond.endVersion);
1987
    }
L
Liu Jicong 已提交
1988 1989 1990 1991 1992

    /*resetTableScanInfo(pTSInfo, pWin);*/
    tsdbReaderClose(pTSInfo->dataReader);
    pTSInfo->dataReader = NULL;

L
Liu Jicong 已提交
1993 1994 1995 1996 1997 1998 1999 2000
    pTSInfo->scanTimes = 0;
    pTSInfo->currentGroupId = -1;
    pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__SCAN;
  }

  if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__SCAN) {
    SSDataBlock* pBlock = doTableScan(pInfo->pTableScanOp);
    if (pBlock != NULL) {
L
Liu Jicong 已提交
2001
      calBlockTbName(pInfo, pBlock);
2002
      if (pInfo->pUpdateInfo) {
L
Liu Jicong 已提交
2003 2004
        TSKEY maxTs = updateInfoFillBlockData(pInfo->pUpdateInfo, pBlock, pInfo->primaryTsIndex);
        pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs);
2005
      }
2006
      qDebug("stream recover scan get block, rows %d", pBlock->info.rows);
L
Liu Jicong 已提交
2007
      printDataBlock(pBlock, "scan recover");
L
Liu Jicong 已提交
2008 2009 2010
      return pBlock;
    }
    pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__NONE;
L
Liu Jicong 已提交
2011
    STableScanInfo* pTSInfo = pInfo->pTableScanOp->info;
2012 2013 2014 2015
    tsdbReaderClose(pTSInfo->dataReader);
    pTSInfo->dataReader = NULL;

    pTSInfo->cond.startVersion = -1;
L
Liu Jicong 已提交
2016 2017
    pTSInfo->cond.endVersion = -1;

L
Liu Jicong 已提交
2018 2019 2020
    return NULL;
  }

5
54liuyao 已提交
2021
  size_t total = taosArrayGetSize(pInfo->pBlockLists);
5
54liuyao 已提交
2022
// TODO: refactor
L
Liu Jicong 已提交
2023
FETCH_NEXT_BLOCK:
L
Liu Jicong 已提交
2024
  if (pInfo->blockType == STREAM_INPUT__DATA_BLOCK) {
H
Haojun Liao 已提交
2025
    if (pInfo->validBlockIndex >= total) {
L
Liu Jicong 已提交
2026
      doClearBufferedBlocks(pInfo);
L
Liu Jicong 已提交
2027
      /*pOperator->status = OP_EXEC_DONE;*/
H
Haojun Liao 已提交
2028 2029 2030
      return NULL;
    }

2031
    int32_t      current = pInfo->validBlockIndex++;
2032
    SSDataBlock* pBlock = taosArrayGetP(pInfo->pBlockLists, current);
2033
    // TODO move into scan
5
54liuyao 已提交
2034 2035
    pBlock->info.calWin.skey = INT64_MIN;
    pBlock->info.calWin.ekey = INT64_MAX;
2036
    blockDataUpdateTsWindow(pBlock, 0);
2037
    switch (pBlock->info.type) {
L
Liu Jicong 已提交
2038 2039 2040
      case STREAM_NORMAL:
      case STREAM_GET_ALL:
        return pBlock;
2041 2042 2043
      case STREAM_RETRIEVE: {
        pInfo->blockType = STREAM_INPUT__DATA_SUBMIT;
        pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RETRIEVE;
2044 2045
        copyDataBlock(pInfo->pUpdateRes, pBlock);
        prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
2046 2047 2048
        updateInfoAddCloseWindowSBF(pInfo->pUpdateInfo);
      } break;
      case STREAM_DELETE_DATA: {
2049
        printDataBlock(pBlock, "stream scan delete recv");
L
Liu Jicong 已提交
2050
        SSDataBlock* pDelBlock = NULL;
L
Liu Jicong 已提交
2051
        if (pInfo->tqReader) {
L
Liu Jicong 已提交
2052
          pDelBlock = createSpecialDataBlock(STREAM_DELETE_DATA);
L
Liu Jicong 已提交
2053
          filterDelBlockByUid(pDelBlock, pBlock, pInfo);
L
Liu Jicong 已提交
2054 2055
        } else {
          pDelBlock = pBlock;
L
Liu Jicong 已提交
2056
        }
5
54liuyao 已提交
2057 2058
        setBlockGroupIdByUid(pInfo, pDelBlock);
        printDataBlock(pDelBlock, "stream scan delete recv filtered");
2059
        if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) {
L
Liu Jicong 已提交
2060
          generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes);
2061
          pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT;
L
Liu Jicong 已提交
2062
          printDataBlock(pDelBlock, "stream scan delete result");
H
Haojun Liao 已提交
2063 2064
          blockDataDestroy(pDelBlock);

L
Liu Jicong 已提交
2065 2066 2067 2068 2069
          if (pInfo->pDeleteDataRes->info.rows > 0) {
            return pInfo->pDeleteDataRes;
          } else {
            goto FETCH_NEXT_BLOCK;
          }
2070 2071 2072
        } else {
          pInfo->blockType = STREAM_INPUT__DATA_SUBMIT;
          pInfo->updateResIndex = 0;
L
Liu Jicong 已提交
2073
          generateScanRange(pInfo, pDelBlock, pInfo->pUpdateRes);
2074 2075 2076 2077
          prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
          copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes);
          pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA;
          pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
L
Liu Jicong 已提交
2078 2079 2080 2081
          printDataBlock(pDelBlock, "stream scan delete data");
          if (pInfo->tqReader) {
            blockDataDestroy(pDelBlock);
          }
L
Liu Jicong 已提交
2082 2083 2084 2085 2086
          if (pInfo->pDeleteDataRes->info.rows > 0) {
            return pInfo->pDeleteDataRes;
          } else {
            goto FETCH_NEXT_BLOCK;
          }
2087
        }
2088 2089 2090
      } break;
      default:
        break;
5
54liuyao 已提交
2091
    }
2092
    // printDataBlock(pBlock, "stream scan recv");
2093
    return pBlock;
L
Liu Jicong 已提交
2094
  } else if (pInfo->blockType == STREAM_INPUT__DATA_SUBMIT) {
L
Liu Jicong 已提交
2095
    qDebug("scan mode %d", pInfo->scanMode);
5
54liuyao 已提交
2096 2097 2098 2099 2100 2101
    switch (pInfo->scanMode) {
      case STREAM_SCAN_FROM_RES: {
        blockDataDestroy(pInfo->pUpdateRes);
        pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
        return pInfo->pRes;
      } break;
2102
      case STREAM_SCAN_FROM_DELETE_DATA: {
2103 2104 2105 2106 2107 2108 2109
        generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes);
        prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
        pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
        copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes);
        pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA;
        return pInfo->pDeleteDataRes;
      } break;
5
54liuyao 已提交
2110 2111 2112 2113 2114 2115 2116 2117 2118 2119
      case STREAM_SCAN_FROM_UPDATERES: {
        generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes);
        prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
        pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
        return pInfo->pUpdateRes;
      } break;
      case STREAM_SCAN_FROM_DATAREADER_RANGE:
      case STREAM_SCAN_FROM_DATAREADER_RETRIEVE: {
        SSDataBlock* pSDB = doRangeScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
        if (pSDB) {
2120
          STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info;
L
Liu Jicong 已提交
2121 2122
          uint64_t        version = getReaderMaxVersion(pTableScanInfo->dataReader);
          updateInfoSetScanRange(pInfo->pUpdateInfo, &pTableScanInfo->cond.twindows, pInfo->groupId, version);
5
54liuyao 已提交
2123 2124
          pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA;
          checkUpdateData(pInfo, true, pSDB, false);
2125
          // printDataBlock(pSDB, "stream scan update");
L
Liu Jicong 已提交
2126
          calBlockTbName(pInfo, pSDB);
5
54liuyao 已提交
2127 2128
          return pSDB;
        }
2129
        blockDataCleanup(pInfo->pUpdateDataRes);
5
54liuyao 已提交
2130 2131 2132 2133
        pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
      } break;
      default:
        break;
2134
    }
2135

2136
    SStreamAggSupporter* pSup = pInfo->windowSup.pStreamAggSup;
5
54liuyao 已提交
2137
    if (isStateWindow(pInfo) && pSup->pScanBlock->info.rows > 0) {
2138 2139
      pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
      pInfo->updateResIndex = 0;
5
54liuyao 已提交
2140 2141
      copyDataBlock(pInfo->pUpdateRes, pSup->pScanBlock);
      blockDataCleanup(pSup->pScanBlock);
2142 2143
      prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
      return pInfo->pUpdateRes;
5
54liuyao 已提交
2144
    }
5
54liuyao 已提交
2145

H
Haojun Liao 已提交
2146 2147
    SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;

2148
    int32_t totBlockNum = taosArrayGetSize(pInfo->pBlockLists);
2149

L
Liu Jicong 已提交
2150
  NEXT_SUBMIT_BLK:
2151 2152 2153
    while (1) {
      if (pInfo->tqReader->pMsg == NULL) {
        if (pInfo->validBlockIndex >= totBlockNum) {
5
54liuyao 已提交
2154
          updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
L
Liu Jicong 已提交
2155
          doClearBufferedBlocks(pInfo);
2156 2157
          return NULL;
        }
2158

2159 2160 2161 2162 2163 2164 2165 2166
        int32_t     current = pInfo->validBlockIndex++;
        SSubmitReq* pSubmit = taosArrayGetP(pInfo->pBlockLists, current);
        if (tqReaderSetDataMsg(pInfo->tqReader, pSubmit, 0) < 0) {
          qError("submit msg messed up when initing stream submit block %p, current %d, total %d", pSubmit, current,
                 totBlockNum);
          pInfo->tqReader->pMsg = NULL;
          continue;
        }
H
Haojun Liao 已提交
2167 2168
      }

2169 2170 2171 2172
      blockDataCleanup(pInfo->pRes);

      while (tqNextDataBlock(pInfo->tqReader)) {
        SSDataBlock block = {0};
2173

2174 2175 2176 2177 2178 2179
        int32_t code = tqRetrieveDataBlock(&block, pInfo->tqReader);

        if (code != TSDB_CODE_SUCCESS || block.info.rows == 0) {
          continue;
        }

2180
        setBlockIntoRes(pInfo, &block, false);
2181

L
Liu Jicong 已提交
2182 2183
        if (updateInfoIgnore(pInfo->pUpdateInfo, &pInfo->pRes->info.window, pInfo->pRes->info.groupId,
                             pInfo->pRes->info.version)) {
2184 2185 2186 2187 2188
          printDataBlock(pInfo->pRes, "stream scan ignore");
          blockDataCleanup(pInfo->pRes);
          continue;
        }

2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204
        if (pInfo->pUpdateInfo) {
          checkUpdateData(pInfo, true, pInfo->pRes, true);
          pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlockInfo->window.ekey);
          if (pInfo->pUpdateDataRes->info.rows > 0) {
            pInfo->updateResIndex = 0;
            if (pInfo->pUpdateDataRes->info.type == STREAM_CLEAR) {
              pInfo->scanMode = STREAM_SCAN_FROM_UPDATERES;
            } else if (pInfo->pUpdateDataRes->info.type == STREAM_INVERT) {
              pInfo->scanMode = STREAM_SCAN_FROM_RES;
              return pInfo->pUpdateDataRes;
            } else if (pInfo->pUpdateDataRes->info.type == STREAM_DELETE_DATA) {
              pInfo->scanMode = STREAM_SCAN_FROM_DELETE_DATA;
            }
          }
        }

H
Haojun Liao 已提交
2205
        doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL);
2206 2207 2208
        blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);

        if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) {
2209 2210 2211
          break;
        }
      }
2212
      if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) {
5
54liuyao 已提交
2213
        break;
J
jiacy-jcy 已提交
2214 2215
      } else {
        pInfo->tqReader->pMsg = NULL;
2216
        continue;
5
54liuyao 已提交
2217
      }
2218
      /*blockDataCleanup(pInfo->pRes);*/
H
Haojun Liao 已提交
2219 2220 2221 2222
    }

    // record the scan action.
    pInfo->numOfExec++;
2223
    pOperator->resultInfo.totalRows += pBlockInfo->rows;
2224
    // printDataBlock(pInfo->pRes, "stream scan");
H
Haojun Liao 已提交
2225

L
Liu Jicong 已提交
2226
    qDebug("scan rows: %d", pBlockInfo->rows);
L
Liu Jicong 已提交
2227 2228 2229
    if (pBlockInfo->rows > 0) {
      return pInfo->pRes;
    }
2230 2231 2232 2233 2234 2235

    if (pInfo->pUpdateDataRes->info.rows > 0) {
      goto FETCH_NEXT_BLOCK;
    }

    goto NEXT_SUBMIT_BLK;
L
Liu Jicong 已提交
2236 2237 2238
  } else {
    ASSERT(0);
    return NULL;
H
Haojun Liao 已提交
2239 2240 2241
  }
}

H
Haojun Liao 已提交
2242
static SArray* extractTableIdList(const STableListInfo* pTableListInfo) {
2243 2244 2245
  SArray* tableIdList = taosArrayInit(4, sizeof(uint64_t));

  // Transfer the Array of STableKeyInfo into uid list.
H
Haojun Liao 已提交
2246 2247 2248
  size_t size = tableListGetSize(pTableListInfo);
  for (int32_t i = 0; i < size; ++i) {
    STableKeyInfo* pkeyInfo = tableListGetInfo(pTableListInfo, i);
2249 2250 2251 2252 2253 2254
    taosArrayPush(tableIdList, &pkeyInfo->uid);
  }

  return tableIdList;
}

2255
static SSDataBlock* doRawScan(SOperatorInfo* pOperator) {
L
Liu Jicong 已提交
2256 2257
  // NOTE: this operator does never check if current status is done or not
  SExecTaskInfo*      pTaskInfo = pOperator->pTaskInfo;
2258
  SStreamRawScanInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
2259
  pTaskInfo->streamInfo.metaRsp.metaRspLen = 0;  // use metaRspLen !=0 to judge if data is meta
wmmhello's avatar
wmmhello 已提交
2260
  pTaskInfo->streamInfo.metaRsp.metaRsp = NULL;
2261

wmmhello's avatar
wmmhello 已提交
2262
  qDebug("tmqsnap doRawScan called");
L
Liu Jicong 已提交
2263
  if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__SNAPSHOT_DATA) {
wmmhello's avatar
wmmhello 已提交
2264
    SSDataBlock* pBlock = &pInfo->pRes;
2265

2266
    if (pInfo->dataReader && tsdbNextDataBlock(pInfo->dataReader)) {
wmmhello's avatar
wmmhello 已提交
2267 2268 2269
      if (isTaskKilled(pTaskInfo)) {
        longjmp(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED);
      }
2270

H
Haojun Liao 已提交
2271 2272 2273
      int32_t rows = 0;
      tsdbRetrieveDataBlockInfo(pInfo->dataReader, &rows, &pBlock->info.uid, &pBlock->info.window);
      pBlock->info.rows = rows;
2274

wmmhello's avatar
wmmhello 已提交
2275 2276 2277
      SArray* pCols = tsdbRetrieveDataBlock(pInfo->dataReader, NULL);
      pBlock->pDataBlock = pCols;
      if (pCols == NULL) {
wmmhello's avatar
wmmhello 已提交
2278
        longjmp(pTaskInfo->env, terrno);
wmmhello's avatar
wmmhello 已提交
2279 2280
      }

2281
      qDebug("tmqsnap doRawScan get data uid:%" PRId64 "", pBlock->info.uid);
wmmhello's avatar
wmmhello 已提交
2282 2283 2284 2285 2286
      pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__SNAPSHOT_DATA;
      pTaskInfo->streamInfo.lastStatus.uid = pBlock->info.uid;
      pTaskInfo->streamInfo.lastStatus.ts = pBlock->info.window.ekey;
      return pBlock;
    }
wmmhello's avatar
wmmhello 已提交
2287 2288

    SMetaTableInfo mtInfo = getUidfromSnapShot(pInfo->sContext);
L
Liu Jicong 已提交
2289
    if (mtInfo.uid == 0) {  // read snapshot done, change to get data from wal
wmmhello's avatar
wmmhello 已提交
2290 2291
      qDebug("tmqsnap read snapshot done, change to get data from wal");
      pTaskInfo->streamInfo.prepareStatus.uid = mtInfo.uid;
wmmhello's avatar
wmmhello 已提交
2292 2293
      pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__LOG;
      pTaskInfo->streamInfo.lastStatus.version = pInfo->sContext->snapVersion;
L
Liu Jicong 已提交
2294
    } else {
wmmhello's avatar
wmmhello 已提交
2295 2296
      pTaskInfo->streamInfo.prepareStatus.uid = mtInfo.uid;
      pTaskInfo->streamInfo.prepareStatus.ts = INT64_MIN;
2297
      qDebug("tmqsnap change get data uid:%" PRId64 "", mtInfo.uid);
wmmhello's avatar
wmmhello 已提交
2298 2299
      qStreamPrepareScan(pTaskInfo, &pTaskInfo->streamInfo.prepareStatus, pInfo->sContext->subType);
    }
2300
    tDeleteSSchemaWrapper(mtInfo.schema);
wmmhello's avatar
wmmhello 已提交
2301
    qDebug("tmqsnap stream scan tsdb return null");
wmmhello's avatar
wmmhello 已提交
2302
    return NULL;
L
Liu Jicong 已提交
2303 2304 2305 2306 2307 2308 2309
  } else if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__SNAPSHOT_META) {
    SSnapContext* sContext = pInfo->sContext;
    void*         data = NULL;
    int32_t       dataLen = 0;
    int16_t       type = 0;
    int64_t       uid = 0;
    if (getMetafromSnapShot(sContext, &data, &dataLen, &type, &uid) < 0) {
wmmhello's avatar
wmmhello 已提交
2310
      qError("tmqsnap getMetafromSnapShot error");
wmmhello's avatar
wmmhello 已提交
2311
      taosMemoryFreeClear(data);
2312 2313 2314
      return NULL;
    }

L
Liu Jicong 已提交
2315
    if (!sContext->queryMetaOrData) {  // change to get data next poll request
wmmhello's avatar
wmmhello 已提交
2316 2317 2318 2319
      pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__SNAPSHOT_META;
      pTaskInfo->streamInfo.lastStatus.uid = uid;
      pTaskInfo->streamInfo.metaRsp.rspOffset.type = TMQ_OFFSET__SNAPSHOT_DATA;
      pTaskInfo->streamInfo.metaRsp.rspOffset.uid = 0;
wmmhello's avatar
wmmhello 已提交
2320
      pTaskInfo->streamInfo.metaRsp.rspOffset.ts = INT64_MIN;
L
Liu Jicong 已提交
2321
    } else {
wmmhello's avatar
wmmhello 已提交
2322 2323 2324 2325 2326 2327 2328
      pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__SNAPSHOT_META;
      pTaskInfo->streamInfo.lastStatus.uid = uid;
      pTaskInfo->streamInfo.metaRsp.rspOffset = pTaskInfo->streamInfo.lastStatus;
      pTaskInfo->streamInfo.metaRsp.resMsgType = type;
      pTaskInfo->streamInfo.metaRsp.metaRspLen = dataLen;
      pTaskInfo->streamInfo.metaRsp.metaRsp = data;
    }
2329

wmmhello's avatar
wmmhello 已提交
2330
    return NULL;
2331
  }
L
Liu Jicong 已提交
2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369
  //  else if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__LOG) {
  //    int64_t fetchVer = pTaskInfo->streamInfo.prepareStatus.version + 1;
  //
  //    while(1){
  //      if (tqFetchLog(pInfo->tqReader->pWalReader, pInfo->sContext->withMeta, &fetchVer, &pInfo->pCkHead) < 0) {
  //        qDebug("tmqsnap tmq poll: consumer log end. offset %" PRId64, fetchVer);
  //        pTaskInfo->streamInfo.lastStatus.version = fetchVer;
  //        pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__LOG;
  //        return NULL;
  //      }
  //      SWalCont* pHead = &pInfo->pCkHead->head;
  //      qDebug("tmqsnap tmq poll: consumer log offset %" PRId64 " msgType %d", fetchVer, pHead->msgType);
  //
  //      if (pHead->msgType == TDMT_VND_SUBMIT) {
  //        SSubmitReq* pCont = (SSubmitReq*)&pHead->body;
  //        tqReaderSetDataMsg(pInfo->tqReader, pCont, 0);
  //        SSDataBlock* block = tqLogScanExec(pInfo->sContext->subType, pInfo->tqReader, pInfo->pFilterOutTbUid,
  //        &pInfo->pRes); if(block){
  //          pTaskInfo->streamInfo.lastStatus.type = TMQ_OFFSET__LOG;
  //          pTaskInfo->streamInfo.lastStatus.version = fetchVer;
  //          qDebug("tmqsnap fetch data msg, ver:%" PRId64 ", type:%d", pHead->version, pHead->msgType);
  //          return block;
  //        }else{
  //          fetchVer++;
  //        }
  //      } else{
  //        ASSERT(pInfo->sContext->withMeta);
  //        ASSERT(IS_META_MSG(pHead->msgType));
  //        qDebug("tmqsnap fetch meta msg, ver:%" PRId64 ", type:%d", pHead->version, pHead->msgType);
  //        pTaskInfo->streamInfo.metaRsp.rspOffset.version = fetchVer;
  //        pTaskInfo->streamInfo.metaRsp.rspOffset.type = TMQ_OFFSET__LOG;
  //        pTaskInfo->streamInfo.metaRsp.resMsgType = pHead->msgType;
  //        pTaskInfo->streamInfo.metaRsp.metaRspLen = pHead->bodyLen;
  //        pTaskInfo->streamInfo.metaRsp.metaRsp = taosMemoryMalloc(pHead->bodyLen);
  //        memcpy(pTaskInfo->streamInfo.metaRsp.metaRsp, pHead->body, pHead->bodyLen);
  //        return NULL;
  //      }
  //    }
2370 2371 2372
  return NULL;
}

wmmhello's avatar
wmmhello 已提交
2373
static void destroyRawScanOperatorInfo(void* param) {
wmmhello's avatar
wmmhello 已提交
2374 2375 2376 2377 2378 2379
  SStreamRawScanInfo* pRawScan = (SStreamRawScanInfo*)param;
  tsdbReaderClose(pRawScan->dataReader);
  destroySnapContext(pRawScan->sContext);
  taosMemoryFree(pRawScan);
}

L
Liu Jicong 已提交
2380 2381 2382
// for subscribing db or stb (not including column),
// if this scan is used, meta data can be return
// and schemas are decided when scanning
2383
SOperatorInfo* createRawScanOperatorInfo(SReadHandle* pHandle, SExecTaskInfo* pTaskInfo) {
L
Liu Jicong 已提交
2384 2385 2386 2387 2388
  // create operator
  // create tb reader
  // create meta reader
  // create tq reader

H
Haojun Liao 已提交
2389 2390
  int32_t code = TSDB_CODE_SUCCESS;

2391
  SStreamRawScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamRawScanInfo));
L
Liu Jicong 已提交
2392
  SOperatorInfo*      pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
2393
  if (pInfo == NULL || pOperator == NULL) {
H
Haojun Liao 已提交
2394 2395
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _end;
2396 2397
  }

wmmhello's avatar
wmmhello 已提交
2398 2399
  pInfo->vnode = pHandle->vnode;

2400
  pInfo->sContext = pHandle->sContext;
L
Liu Jicong 已提交
2401 2402
  setOperatorInfo(pOperator, "RawScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN, false, OP_NOT_OPENED, pInfo,
                  pTaskInfo);
2403

H
Haojun Liao 已提交
2404
  pOperator->fpSet = createOperatorFpSet(NULL, doRawScan, NULL, destroyRawScanOperatorInfo, NULL);
2405
  return pOperator;
H
Haojun Liao 已提交
2406

L
Liu Jicong 已提交
2407
_end:
H
Haojun Liao 已提交
2408 2409 2410 2411
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  pTaskInfo->code = code;
  return NULL;
L
Liu Jicong 已提交
2412 2413
}

2414
static void destroyStreamScanOperatorInfo(void* param) {
2415 2416
  SStreamScanInfo* pStreamScan = (SStreamScanInfo*)param;
  if (pStreamScan->pTableScanOp && pStreamScan->pTableScanOp->info) {
5
54liuyao 已提交
2417
    destroyOperatorInfo(pStreamScan->pTableScanOp);
2418 2419 2420 2421
  }
  if (pStreamScan->tqReader) {
    tqCloseReader(pStreamScan->tqReader);
  }
H
Haojun Liao 已提交
2422 2423
  if (pStreamScan->matchInfo.pList) {
    taosArrayDestroy(pStreamScan->matchInfo.pList);
2424
  }
C
Cary Xu 已提交
2425 2426
  if (pStreamScan->pPseudoExpr) {
    destroyExprInfo(pStreamScan->pPseudoExpr, pStreamScan->numOfPseudoExpr);
L
Liu Jicong 已提交
2427
    taosMemoryFree(pStreamScan->pPseudoExpr);
C
Cary Xu 已提交
2428
  }
C
Cary Xu 已提交
2429

L
Liu Jicong 已提交
2430
  cleanupExprSupp(&pStreamScan->tbnameCalSup);
L
Liu Jicong 已提交
2431
  taosHashCleanup(pStreamScan->pGroupIdTbNameMap);
L
Liu Jicong 已提交
2432

L
Liu Jicong 已提交
2433
  updateInfoDestroy(pStreamScan->pUpdateInfo);
2434 2435 2436 2437
  blockDataDestroy(pStreamScan->pRes);
  blockDataDestroy(pStreamScan->pUpdateRes);
  blockDataDestroy(pStreamScan->pPullDataRes);
  blockDataDestroy(pStreamScan->pDeleteDataRes);
5
54liuyao 已提交
2438
  blockDataDestroy(pStreamScan->pUpdateDataRes);
2439 2440 2441 2442
  taosArrayDestroy(pStreamScan->pBlockLists);
  taosMemoryFree(pStreamScan);
}

2443
SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNode* pTableScanNode, SNode* pTagCond,
2444
                                            SExecTaskInfo* pTaskInfo) {
2445 2446
  SStreamScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamScanInfo));
  SOperatorInfo*   pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
2447

H
Haojun Liao 已提交
2448 2449
  if (pInfo == NULL || pOperator == NULL) {
    terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
2450
    goto _error;
H
Haojun Liao 已提交
2451 2452
  }

2453
  SScanPhysiNode*     pScanPhyNode = &pTableScanNode->scan;
2454
  SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;
H
Haojun Liao 已提交
2455

2456
  pInfo->pTagCond = pTagCond;
2457
  pInfo->pGroupTags = pTableScanNode->pGroupTags;
2458

2459
  int32_t numOfCols = 0;
2460 2461
  int32_t code =
      extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
H
Haojun Liao 已提交
2462 2463 2464
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
2465

H
Haojun Liao 已提交
2466
  int32_t numOfOutput = taosArrayGetSize(pInfo->matchInfo.pList);
2467
  SArray* pColIds = taosArrayInit(numOfOutput, sizeof(int16_t));
2468
  for (int32_t i = 0; i < numOfOutput; ++i) {
H
Haojun Liao 已提交
2469
    SColMatchItem* id = taosArrayGet(pInfo->matchInfo.pList, i);
2470 2471

    int16_t colId = id->colId;
2472
    taosArrayPush(pColIds, &colId);
2473
    if (id->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
H
Haojun Liao 已提交
2474
      pInfo->primaryTsIndex = id->dstSlotId;
5
54liuyao 已提交
2475
    }
H
Haojun Liao 已提交
2476 2477
  }

L
Liu Jicong 已提交
2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488
  if (pTableScanNode->pSubtable != NULL) {
    SExprInfo* pSubTableExpr = taosMemoryCalloc(1, sizeof(SExprInfo));
    if (pSubTableExpr == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _error;
    }
    pInfo->tbnameCalSup.pExprInfo = pSubTableExpr;
    createExprFromOneNode(pSubTableExpr, pTableScanNode->pSubtable, 0);
    if (initExprSupp(&pInfo->tbnameCalSup, pSubTableExpr, 1) != 0) {
      goto _error;
    }
L
Liu Jicong 已提交
2489 2490
    pInfo->pGroupIdTbNameMap =
        taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK);
L
Liu Jicong 已提交
2491 2492
  }

2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505
  if (pTableScanNode->pTags != NULL) {
    int32_t    numOfTags;
    SExprInfo* pTagExpr = createExprInfo(pTableScanNode->pTags, NULL, &numOfTags);
    if (pTagExpr == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _error;
    }
    if (initExprSupp(&pInfo->tagCalSup, pTagExpr, numOfTags) != 0) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _error;
    }
  }

H
Haojun Liao 已提交
2506 2507
  pInfo->pBlockLists = taosArrayInit(4, POINTER_BYTES);
  if (pInfo->pBlockLists == NULL) {
2508 2509
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _error;
H
Haojun Liao 已提交
2510 2511
  }

5
54liuyao 已提交
2512
  if (pHandle->vnode) {
L
Liu Jicong 已提交
2513
    SOperatorInfo*  pTableScanOp = createTableScanOperatorInfo(pTableScanNode, pHandle, pTaskInfo);
L
Liu Jicong 已提交
2514
    STableScanInfo* pTSInfo = (STableScanInfo*)pTableScanOp->info;
2515
    if (pHandle->version > 0) {
L
Liu Jicong 已提交
2516
      pTSInfo->cond.endVersion = pHandle->version;
2517
    }
L
Liu Jicong 已提交
2518

2519
    STableKeyInfo* pList = NULL;
5
54liuyao 已提交
2520
    int32_t        num = 0;
H
Haojun Liao 已提交
2521
    tableListGetGroupList(pTaskInfo->pTableInfoList, 0, &pList, &num);
2522

2523
    if (pHandle->initTableReader) {
L
Liu Jicong 已提交
2524 2525
      pTSInfo->scanMode = TABLE_SCAN__TABLE_ORDER;
      pTSInfo->dataReader = NULL;
H
Haojun Liao 已提交
2526
      code = tsdbReaderOpen(pHandle->vnode, &pTSInfo->cond, pList, num, &pTSInfo->dataReader, NULL);
dengyihao's avatar
dengyihao 已提交
2527 2528
      if (code != 0) {
        terrno = code;
H
Haojun Liao 已提交
2529
        destroyTableScanOperatorInfo(pTableScanOp);
2530
        goto _error;
L
Liu Jicong 已提交
2531
      }
L
Liu Jicong 已提交
2532 2533
    }

L
Liu Jicong 已提交
2534 2535 2536 2537
    if (pHandle->initTqReader) {
      ASSERT(pHandle->tqReader == NULL);
      pInfo->tqReader = tqOpenReader(pHandle->vnode);
      ASSERT(pInfo->tqReader);
2538
    } else {
L
Liu Jicong 已提交
2539 2540
      ASSERT(pHandle->tqReader);
      pInfo->tqReader = pHandle->tqReader;
2541 2542
    }

2543
    pInfo->pUpdateInfo = NULL;
2544
    pInfo->pTableScanOp = pTableScanOp;
2545 2546 2547
    if (pInfo->pTableScanOp->pTaskInfo->streamInfo.pState) {
      streamStateSetNumber(pInfo->pTableScanOp->pTaskInfo->streamInfo.pState, -1);
    }
L
Liu Jicong 已提交
2548

L
Liu Jicong 已提交
2549 2550
    pInfo->readHandle = *pHandle;
    pInfo->tableUid = pScanPhyNode->uid;
L
Liu Jicong 已提交
2551
    pTaskInfo->streamInfo.snapshotVer = pHandle->version;
L
Liu Jicong 已提交
2552

L
Liu Jicong 已提交
2553
    // set the extract column id to streamHandle
L
Liu Jicong 已提交
2554
    tqReaderSetColIdList(pInfo->tqReader, pColIds);
H
Haojun Liao 已提交
2555
    SArray* tableIdList = extractTableIdList(pTaskInfo->pTableInfoList);
2556
    code = tqReaderSetTbUidList(pInfo->tqReader, tableIdList);
L
Liu Jicong 已提交
2557 2558 2559 2560 2561
    if (code != 0) {
      taosArrayDestroy(tableIdList);
      goto _error;
    }
    taosArrayDestroy(tableIdList);
L
Liu Jicong 已提交
2562
    memcpy(&pTaskInfo->streamInfo.tableCond, &pTSInfo->cond, sizeof(SQueryTableDataCond));
L
Liu Jicong 已提交
2563 2564
  } else {
    taosArrayDestroy(pColIds);
5
54liuyao 已提交
2565 2566
  }

2567 2568 2569 2570 2571
  // create the pseduo columns info
  if (pTableScanNode->scan.pScanPseudoCols != NULL) {
    pInfo->pPseudoExpr = createExprInfo(pTableScanNode->scan.pScanPseudoCols, NULL, &pInfo->numOfPseudoExpr);
  }

H
Haojun Liao 已提交
2572 2573 2574 2575 2576
  code = filterInitFromNode((SNode*)pScanPhyNode->node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

2577
  pInfo->pRes = createResDataBlock(pDescNode);
2578
  pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR);
2579
  pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
L
Liu Jicong 已提交
2580
  pInfo->windowSup = (SWindowSupporter){.pStreamAggSup = NULL, .gap = -1, .parentType = QUERY_NODE_PHYSICAL_PLAN};
2581
  pInfo->groupId = 0;
2582
  pInfo->pPullDataRes = createSpecialDataBlock(STREAM_RETRIEVE);
2583
  pInfo->pStreamScanOp = pOperator;
2584
  pInfo->deleteDataIndex = 0;
2585
  pInfo->pDeleteDataRes = createSpecialDataBlock(STREAM_DELETE_DATA);
5
54liuyao 已提交
2586
  pInfo->updateWin = (STimeWindow){.skey = INT64_MAX, .ekey = INT64_MAX};
2587
  pInfo->pUpdateDataRes = createSpecialDataBlock(STREAM_CLEAR);
X
Xiaoyu Wang 已提交
2588
  pInfo->assignBlockUid = pTableScanNode->assignBlockUid;
2589
  pInfo->partitionSup.needCalc = false;
L
Liu Jicong 已提交
2590

L
Liu Jicong 已提交
2591 2592
  setOperatorInfo(pOperator, "StreamScanOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN, false, OP_NOT_OPENED, pInfo,
                  pTaskInfo);
2593
  pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pRes->pDataBlock);
H
Haojun Liao 已提交
2594

L
Liu Jicong 已提交
2595
  __optr_fn_t nextFn = pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM ? doStreamScan : doQueueScan;
H
Haojun Liao 已提交
2596
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, nextFn, NULL, destroyStreamScanOperatorInfo, NULL);
2597

H
Haojun Liao 已提交
2598
  return pOperator;
2599

L
Liu Jicong 已提交
2600
_error:
H
Haojun Liao 已提交
2601 2602 2603 2604 2605 2606 2607 2608
  if (pColIds != NULL) {
    taosArrayDestroy(pColIds);
  }

  if (pInfo != NULL) {
    destroyStreamScanOperatorInfo(pInfo);
  }

2609 2610
  taosMemoryFreeClear(pOperator);
  return NULL;
H
Haojun Liao 已提交
2611 2612
}

2613
static void destroySysScanOperator(void* param) {
H
Haojun Liao 已提交
2614 2615 2616 2617
  SSysTableScanInfo* pInfo = (SSysTableScanInfo*)param;
  tsem_destroy(&pInfo->ready);
  blockDataDestroy(pInfo->pRes);

2618
  const char* name = tNameGetTableName(&pInfo->name);
D
dapan1121 已提交
2619 2620
  if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
      strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 || pInfo->pCur != NULL) {
H
Haojun Liao 已提交
2621
    metaCloseTbCursor(pInfo->pCur);
2622
    pInfo->pCur = NULL;
H
Haojun Liao 已提交
2623
  }
dengyihao's avatar
dengyihao 已提交
2624 2625 2626 2627 2628
  if (pInfo->pIdx) {
    taosArrayDestroy(pInfo->pIdx->uids);
    taosMemoryFree(pInfo->pIdx);
    pInfo->pIdx = NULL;
  }
H
Haojun Liao 已提交
2629

H
Haojun Liao 已提交
2630
  taosArrayDestroy(pInfo->matchInfo.pList);
2631
  taosMemoryFreeClear(pInfo->pUser);
D
dapan1121 已提交
2632 2633

  taosMemoryFreeClear(param);
H
Haojun Liao 已提交
2634 2635
}

X
Xiaoyu Wang 已提交
2636
static int32_t getSysTableDbNameColId(const char* pTable) {
D
dapan1121 已提交
2637
  // if (0 == strcmp(TSDB_INS_TABLE_INDEXES, pTable)) {
X
Xiaoyu Wang 已提交
2638 2639
  //   return 1;
  // }
X
Xiaoyu Wang 已提交
2640 2641 2642
  return TSDB_INS_USER_STABLES_DBNAME_COLID;
}

H
Haojun Liao 已提交
2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
EDealRes getDBNameFromConditionWalker(SNode* pNode, void* pContext) {
  int32_t   code = TSDB_CODE_SUCCESS;
  ENodeType nType = nodeType(pNode);

  switch (nType) {
    case QUERY_NODE_OPERATOR: {
      SOperatorNode* node = (SOperatorNode*)pNode;
      if (OP_TYPE_EQUAL == node->opType) {
        *(int32_t*)pContext = 1;
        return DEAL_RES_CONTINUE;
      }

      *(int32_t*)pContext = 0;
      return DEAL_RES_IGNORE_CHILD;
    }
    case QUERY_NODE_COLUMN: {
      if (1 != *(int32_t*)pContext) {
        return DEAL_RES_CONTINUE;
      }

      SColumnNode* node = (SColumnNode*)pNode;
X
Xiaoyu Wang 已提交
2664
      if (getSysTableDbNameColId(node->tableName) == node->colId) {
H
Haojun Liao 已提交
2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680
        *(int32_t*)pContext = 2;
        return DEAL_RES_CONTINUE;
      }

      *(int32_t*)pContext = 0;
      return DEAL_RES_CONTINUE;
    }
    case QUERY_NODE_VALUE: {
      if (2 != *(int32_t*)pContext) {
        return DEAL_RES_CONTINUE;
      }

      SValueNode* node = (SValueNode*)pNode;
      char*       dbName = nodesGetValueFromNode(node);
      strncpy(pContext, varDataVal(dbName), varDataLen(dbName));
      *((char*)pContext + varDataLen(dbName)) = 0;
2681
      return DEAL_RES_END;  // stop walk
H
Haojun Liao 已提交
2682 2683 2684 2685 2686 2687 2688
    }
    default:
      break;
  }
  return DEAL_RES_CONTINUE;
}

2689
static void getDBNameFromCondition(SNode* pCondition, const char* dbName) {
H
Haojun Liao 已提交
2690 2691 2692
  if (NULL == pCondition) {
    return;
  }
L
Liu Jicong 已提交
2693
  nodesWalkExpr(pCondition, getDBNameFromConditionWalker, (char*)dbName);
H
Haojun Liao 已提交
2694 2695
}

D
dapan1121 已提交
2696
static int32_t loadSysTableCallback(void* param, SDataBuf* pMsg, int32_t code) {
H
Haojun Liao 已提交
2697 2698 2699 2700 2701 2702 2703
  SOperatorInfo*     operator=(SOperatorInfo*) param;
  SSysTableScanInfo* pScanResInfo = (SSysTableScanInfo*)operator->info;
  if (TSDB_CODE_SUCCESS == code) {
    pScanResInfo->pRsp = pMsg->pData;

    SRetrieveMetaTableRsp* pRsp = pScanResInfo->pRsp;
    pRsp->numOfRows = htonl(pRsp->numOfRows);
2704 2705 2706
    pRsp->useconds = htobe64(pRsp->useconds);
    pRsp->handle = htobe64(pRsp->handle);
    pRsp->compLen = htonl(pRsp->compLen);
H
Haojun Liao 已提交
2707 2708 2709 2710 2711
  } else {
    operator->pTaskInfo->code = code;
  }

  tsem_post(&pScanResInfo->ready);
wmmhello's avatar
wmmhello 已提交
2712
  return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
2713 2714
}

H
Haojun Liao 已提交
2715 2716 2717
static SSDataBlock* doFilterResult(SSDataBlock* pDataBlock, SFilterInfo* pFilterInfo) {
  if (pFilterInfo == NULL) {
    return pDataBlock->info.rows == 0 ? NULL : pDataBlock;
H
Haojun Liao 已提交
2718 2719
  }

H
Haojun Liao 已提交
2720 2721
  doFilter(pDataBlock, pFilterInfo, NULL);
  return pDataBlock->info.rows == 0 ? NULL : pDataBlock;
H
Haojun Liao 已提交
2722 2723
}

2724
static SSDataBlock* buildInfoSchemaTableMetaBlock(char* tableName) {
L
Liu Jicong 已提交
2725 2726
  size_t               size = 0;
  const SSysTableMeta* pMeta = NULL;
2727 2728 2729
  getInfosDbMeta(&pMeta, &size);

  int32_t index = 0;
L
Liu Jicong 已提交
2730
  for (int32_t i = 0; i < size; ++i) {
2731
    if (strcmp(pMeta[i].name, tableName) == 0) {
2732 2733 2734 2735
      index = i;
      break;
    }
  }
2736

2737
  SSDataBlock* pBlock = createDataBlock();
L
Liu Jicong 已提交
2738
  for (int32_t i = 0; i < pMeta[index].colNum; ++i) {
L
Liu Jicong 已提交
2739 2740
    SColumnInfoData colInfoData =
        createColumnInfoData(pMeta[index].schema[i].type, pMeta[index].schema[i].bytes, i + 1);
2741
    blockDataAppendColInfo(pBlock, &colInfoData);
2742 2743
  }

2744 2745 2746
  return pBlock;
}

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
int32_t convertTagDataToStr(char* str, int type, void* buf, int32_t bufSize, int32_t* len) {
  int32_t n = 0;

  switch (type) {
    case TSDB_DATA_TYPE_NULL:
      n = sprintf(str, "null");
      break;

    case TSDB_DATA_TYPE_BOOL:
      n = sprintf(str, (*(int8_t*)buf) ? "true" : "false");
      break;

    case TSDB_DATA_TYPE_TINYINT:
      n = sprintf(str, "%d", *(int8_t*)buf);
      break;

    case TSDB_DATA_TYPE_SMALLINT:
      n = sprintf(str, "%d", *(int16_t*)buf);
      break;

    case TSDB_DATA_TYPE_INT:
      n = sprintf(str, "%d", *(int32_t*)buf);
      break;

    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_TIMESTAMP:
      n = sprintf(str, "%" PRId64, *(int64_t*)buf);
      break;

    case TSDB_DATA_TYPE_FLOAT:
      n = sprintf(str, "%.5f", GET_FLOAT_VAL(buf));
      break;

    case TSDB_DATA_TYPE_DOUBLE:
      n = sprintf(str, "%.9f", GET_DOUBLE_VAL(buf));
      break;

    case TSDB_DATA_TYPE_BINARY:
      if (bufSize < 0) {
        return TSDB_CODE_TSC_INVALID_VALUE;
      }

      memcpy(str, buf, bufSize);
      n = bufSize;
      break;
    case TSDB_DATA_TYPE_NCHAR:
      if (bufSize < 0) {
        return TSDB_CODE_TSC_INVALID_VALUE;
      }

      int32_t length = taosUcs4ToMbs((TdUcs4*)buf, bufSize, str);
      if (length <= 0) {
        return TSDB_CODE_TSC_INVALID_VALUE;
      }
      n = length;
      break;
    case TSDB_DATA_TYPE_UTINYINT:
      n = sprintf(str, "%u", *(uint8_t*)buf);
      break;

    case TSDB_DATA_TYPE_USMALLINT:
      n = sprintf(str, "%u", *(uint16_t*)buf);
      break;

    case TSDB_DATA_TYPE_UINT:
      n = sprintf(str, "%u", *(uint32_t*)buf);
      break;

    case TSDB_DATA_TYPE_UBIGINT:
      n = sprintf(str, "%" PRIu64, *(uint64_t*)buf);
      break;

    default:
      return TSDB_CODE_TSC_INVALID_VALUE;
  }

  if (len) *len = n;

  return TSDB_CODE_SUCCESS;
}

2828 2829 2830 2831 2832 2833 2834
static bool sysTableIsOperatorCondOnOneTable(SNode* pCond, char* condTable) {
  SOperatorNode* node = (SOperatorNode*)pCond;
  if (node->opType == OP_TYPE_EQUAL) {
    if (nodeType(node->pLeft) == QUERY_NODE_COLUMN &&
        strcasecmp(nodesGetNameFromColumnNode(node->pLeft), "table_name") == 0 &&
        nodeType(node->pRight) == QUERY_NODE_VALUE) {
      SValueNode* pValue = (SValueNode*)node->pRight;
2835 2836 2837 2838
      if (pValue->node.resType.type == TSDB_DATA_TYPE_NCHAR || pValue->node.resType.type == TSDB_DATA_TYPE_VARCHAR ||
          pValue->node.resType.type == TSDB_DATA_TYPE_BINARY) {
        char* value = nodesGetValueFromNode(pValue);
        strncpy(condTable, varDataVal(value), TSDB_TABLE_NAME_LEN);
2839 2840 2841 2842 2843 2844 2845 2846
        return true;
      }
    }
  }
  return false;
}

static bool sysTableIsCondOnOneTable(SNode* pCond, char* condTable) {
S
slzhou 已提交
2847 2848 2849
  if (pCond == NULL) {
    return false;
  }
2850 2851 2852
  if (nodeType(pCond) == QUERY_NODE_LOGIC_CONDITION) {
    SLogicConditionNode* node = (SLogicConditionNode*)pCond;
    if (LOGIC_COND_TYPE_AND == node->condType) {
S
slzhou 已提交
2853 2854 2855 2856
      SNode* pChild = NULL;
      FOREACH(pChild, node->pParameterList) {
        if (QUERY_NODE_OPERATOR == nodeType(pChild) && sysTableIsOperatorCondOnOneTable(pChild, condTable)) {
          return true;
2857 2858 2859 2860
        }
      }
    }
  }
S
slzhou 已提交
2861

2862 2863 2864
  if (QUERY_NODE_OPERATOR == nodeType(pCond)) {
    return sysTableIsOperatorCondOnOneTable(pCond, condTable);
  }
S
slzhou 已提交
2865

2866 2867 2868
  return false;
}

S
shenglian zhou 已提交
2869 2870 2871 2872 2873 2874 2875 2876 2877 2878
static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
  SSysTableScanInfo* pInfo = pOperator->info;
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  blockDataCleanup(pInfo->pRes);
  int32_t numOfRows = 0;

2879 2880 2881
  SSDataBlock* dataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TAGS);
  blockDataEnsureCapacity(dataBlock, pOperator->resultInfo.capacity);

S
shenglian zhou 已提交
2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892
  const char* db = NULL;
  int32_t     vgId = 0;
  vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId);

  SName sn = {0};
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
  tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);

  tNameGetDbName(&sn, varDataVal(dbname));
  varDataSetLen(dbname, strlen(varDataVal(dbname)));

2893
  char condTableName[TSDB_TABLE_NAME_LEN] = {0};
S
slzhou 已提交
2894 2895
  // optimize when sql like where table_name='tablename' and xxx.
  if (pInfo->pCondition && sysTableIsCondOnOneTable(pInfo->pCondition, condTableName)) {
2896 2897 2898
    char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    STR_TO_VARSTR(tableName, condTableName);

2899 2900
    SMetaReader smrChildTable = {0};
    metaReaderInit(&smrChildTable, pInfo->readHandle.meta, 0);
H
Haojun Liao 已提交
2901 2902 2903 2904 2905 2906
    int32_t code = metaGetTableEntryByName(&smrChildTable, condTableName);
    if (code != TSDB_CODE_SUCCESS) {
      // terrno has been set by metaGetTableEntryByName, therefore, return directly
      return NULL;
    }

2907 2908 2909 2910 2911 2912
    if (smrChildTable.me.type != TSDB_CHILD_TABLE) {
      metaReaderClear(&smrChildTable);
      blockDataDestroy(dataBlock);
      pInfo->loadInfo.totalRows = 0;
      return NULL;
    }
H
Haojun Liao 已提交
2913

2914
    SMetaReader smrSuperTable = {0};
2915
    metaReaderInit(&smrSuperTable, pInfo->readHandle.meta, META_READER_NOLOCK);
H
Haojun Liao 已提交
2916 2917 2918 2919 2920 2921
    code = metaGetTableEntryByUid(&smrSuperTable, smrChildTable.me.ctbEntry.suid);
    if (code != TSDB_CODE_SUCCESS) {
      // terrno has been set by metaGetTableEntryByUid
      return NULL;
    }

2922 2923 2924
    sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &smrChildTable, dbname, tableName, &numOfRows, dataBlock);
    metaReaderClear(&smrSuperTable);
    metaReaderClear(&smrChildTable);
2925
    if (numOfRows > 0) {
H
Haojun Liao 已提交
2926
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
2927 2928 2929 2930
      numOfRows = 0;
    }
    blockDataDestroy(dataBlock);
    pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
H
Haojun Liao 已提交
2931
    setOperatorCompleted(pOperator);
2932 2933
    return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
  }
S
shenglian zhou 已提交
2934 2935

  int32_t ret = 0;
2936 2937 2938 2939
  if (pInfo->pCur == NULL) {
    pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
  }

S
shenglian zhou 已提交
2940
  while ((ret = metaTbCursorNext(pInfo->pCur)) == 0) {
2941 2942 2943
    if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE) {
      continue;
    }
S
shenglian zhou 已提交
2944

2945 2946
    char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
S
shenglian zhou 已提交
2947

2948 2949
    SMetaReader smrSuperTable = {0};
    metaReaderInit(&smrSuperTable, pInfo->readHandle.meta, 0);
2950
    uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
2951
    int32_t  code = metaGetTableEntryByUid(&smrSuperTable, suid);
2952 2953 2954
    if (code != TSDB_CODE_SUCCESS) {
      qError("failed to get super table meta, uid:0x%" PRIx64 ", code:%s, %s", suid, tstrerror(terrno),
             GET_TASKID(pTaskInfo));
2955
      metaReaderClear(&smrSuperTable);
2956 2957
      metaCloseTbCursor(pInfo->pCur);
      pInfo->pCur = NULL;
2958
      T_LONG_JMP(pTaskInfo->env, terrno);
2959
    }
S
shenglian zhou 已提交
2960

2961
    sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &pInfo->pCur->mr, dbname, tableName, &numOfRows, dataBlock);
2962

2963
    metaReaderClear(&smrSuperTable);
S
shenglian zhou 已提交
2964

2965
    if (numOfRows >= pOperator->resultInfo.capacity) {
H
Haojun Liao 已提交
2966
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
2967 2968 2969 2970 2971
      numOfRows = 0;

      if (pInfo->pRes->info.rows > 0) {
        break;
      }
S
shenglian zhou 已提交
2972 2973 2974
    }
  }

2975
  if (numOfRows > 0) {
H
Haojun Liao 已提交
2976
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
2977 2978 2979
    numOfRows = 0;
  }

2980
  blockDataDestroy(dataBlock);
S
shenglian zhou 已提交
2981 2982 2983
  if (ret != 0) {
    metaCloseTbCursor(pInfo->pCur);
    pInfo->pCur = NULL;
H
Haojun Liao 已提交
2984
    setOperatorCompleted(pOperator);
S
shenglian zhou 已提交
2985 2986 2987 2988 2989 2990
  }

  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
}

H
Haojun Liao 已提交
2991 2992
void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
                                        SFilterInfo* pFilterInfo) {
2993 2994 2995
  dataBlock->info.rows = numOfRows;
  pInfo->pRes->info.rows = numOfRows;

H
Haojun Liao 已提交
2996
  relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, dataBlock->pDataBlock, false);
H
Haojun Liao 已提交
2997
  doFilterResult(pInfo->pRes, pFilterInfo);
2998 2999 3000
  blockDataCleanup(dataBlock);
}

3001 3002 3003
static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo, SMetaReader* smrSuperTable,
                                                SMetaReader* smrChildTable, const char* dbname, const char* tableName,
                                                int32_t* pNumOfRows, const SSDataBlock* dataBlock) {
3004
  char stableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3005
  STR_TO_VARSTR(stableName, (*smrSuperTable).me.name);
3006 3007 3008

  int32_t numOfRows = *pNumOfRows;

3009
  int32_t numOfTags = (*smrSuperTable).me.stbEntry.schemaTag.nCols;
3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026
  for (int32_t i = 0; i < numOfTags; ++i) {
    SColumnInfoData* pColInfoData = NULL;

    // table name
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
    colDataAppend(pColInfoData, numOfRows, tableName, false);

    // database name
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
    colDataAppend(pColInfoData, numOfRows, dbname, false);

    // super table name
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
    colDataAppend(pColInfoData, numOfRows, stableName, false);

    // tag name
    char tagName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3027
    STR_TO_VARSTR(tagName, (*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].name);
3028 3029 3030 3031
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
    colDataAppend(pColInfoData, numOfRows, tagName, false);

    // tag type
3032
    int8_t tagType = (*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].type;
3033 3034 3035 3036 3037
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
    char tagTypeStr[VARSTR_HEADER_SIZE + 32];
    int  tagTypeLen = sprintf(varDataVal(tagTypeStr), "%s", tDataTypes[tagType].name);
    if (tagType == TSDB_DATA_TYPE_VARCHAR) {
      tagTypeLen += sprintf(varDataVal(tagTypeStr) + tagTypeLen, "(%d)",
3038
                            (int32_t)((*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].bytes - VARSTR_HEADER_SIZE));
3039
    } else if (tagType == TSDB_DATA_TYPE_NCHAR) {
3040 3041 3042
      tagTypeLen += sprintf(
          varDataVal(tagTypeStr) + tagTypeLen, "(%d)",
          (int32_t)(((*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
3043 3044 3045 3046 3047
    }
    varDataSetLen(tagTypeStr, tagTypeLen);
    colDataAppend(pColInfoData, numOfRows, (char*)tagTypeStr, false);

    STagVal tagVal = {0};
3048
    tagVal.cid = (*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].colId;
3049 3050 3051 3052
    char*    tagData = NULL;
    uint32_t tagLen = 0;

    if (tagType == TSDB_DATA_TYPE_JSON) {
3053
      tagData = (char*)smrChildTable->me.ctbEntry.pTags;
3054
    } else {
3055
      bool exist = tTagGet((STag*)smrChildTable->me.ctbEntry.pTags, &tagVal);
3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095
      if (exist) {
        if (IS_VAR_DATA_TYPE(tagType)) {
          tagData = (char*)tagVal.pData;
          tagLen = tagVal.nData;
        } else {
          tagData = (char*)&tagVal.i64;
          tagLen = tDataTypes[tagType].bytes;
        }
      }
    }

    char* tagVarChar = NULL;
    if (tagData != NULL) {
      if (tagType == TSDB_DATA_TYPE_JSON) {
        char* tagJson = parseTagDatatoJson(tagData);
        tagVarChar = taosMemoryMalloc(strlen(tagJson) + VARSTR_HEADER_SIZE);
        memcpy(varDataVal(tagVarChar), tagJson, strlen(tagJson));
        varDataSetLen(tagVarChar, strlen(tagJson));
        taosMemoryFree(tagJson);
      } else {
        int32_t bufSize = IS_VAR_DATA_TYPE(tagType) ? (tagLen + VARSTR_HEADER_SIZE)
                                                    : (3 + DBL_MANT_DIG - DBL_MIN_EXP + VARSTR_HEADER_SIZE);
        tagVarChar = taosMemoryMalloc(bufSize);
        int32_t len = -1;
        convertTagDataToStr(varDataVal(tagVarChar), tagType, tagData, tagLen, &len);
        varDataSetLen(tagVarChar, len);
      }
    }
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
    colDataAppend(pColInfoData, numOfRows, tagVarChar,
                  (tagData == NULL) || (tagType == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(tagData)));
    taosMemoryFree(tagVarChar);
    ++numOfRows;
  }

  *pNumOfRows = numOfRows;

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121
typedef int (*__optSysFilter)(void* a, void* b, int16_t dtype);

int optSysDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) {
  int32_t cmp = func(a, b);
  switch (comparType) {
    case OP_TYPE_LOWER_THAN:
      if (cmp < 0) return 0;
      break;
    case OP_TYPE_LOWER_EQUAL: {
      if (cmp <= 0) return 0;
      break;
    }
    case OP_TYPE_GREATER_THAN: {
      if (cmp > 0) return 0;
      break;
    }
    case OP_TYPE_GREATER_EQUAL: {
      if (cmp >= 0) return 0;
      break;
    }
    case OP_TYPE_EQUAL: {
      if (cmp == 0) return 0;
      break;
    }
    default:
      return -1;
3122
  }
dengyihao's avatar
dengyihao 已提交
3123
  return cmp;
dengyihao's avatar
dengyihao 已提交
3124
}
H
Haojun Liao 已提交
3125

dengyihao's avatar
dengyihao 已提交
3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145
static int optSysFilterFuncImpl__LowerThan(void* a, void* b, int16_t dtype) {
  __compar_fn_t func = getComparFunc(dtype, 0);
  return optSysDoCompare(func, OP_TYPE_LOWER_THAN, a, b);
}
static int optSysFilterFuncImpl__LowerEqual(void* a, void* b, int16_t dtype) {
  __compar_fn_t func = getComparFunc(dtype, 0);
  return optSysDoCompare(func, OP_TYPE_LOWER_EQUAL, a, b);
}
static int optSysFilterFuncImpl__GreaterThan(void* a, void* b, int16_t dtype) {
  __compar_fn_t func = getComparFunc(dtype, 0);
  return optSysDoCompare(func, OP_TYPE_GREATER_THAN, a, b);
}
static int optSysFilterFuncImpl__GreaterEqual(void* a, void* b, int16_t dtype) {
  __compar_fn_t func = getComparFunc(dtype, 0);
  return optSysDoCompare(func, OP_TYPE_GREATER_EQUAL, a, b);
}
static int optSysFilterFuncImpl__Equal(void* a, void* b, int16_t dtype) {
  __compar_fn_t func = getComparFunc(dtype, 0);
  return optSysDoCompare(func, OP_TYPE_EQUAL, a, b);
}
3146

dengyihao's avatar
dengyihao 已提交
3147 3148 3149 3150
static int optSysFilterFuncImpl__NoEqual(void* a, void* b, int16_t dtype) {
  __compar_fn_t func = getComparFunc(dtype, 0);
  return optSysDoCompare(func, OP_TYPE_NOT_EQUAL, a, b);
}
dengyihao's avatar
dengyihao 已提交
3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164
static __optSysFilter optSysGetFilterFunc(int32_t ctype, bool* reverse) {
  if (ctype == OP_TYPE_LOWER_EQUAL || ctype == OP_TYPE_LOWER_THAN) {
    *reverse = true;
  }
  if (ctype == OP_TYPE_LOWER_THAN)
    return optSysFilterFuncImpl__LowerThan;
  else if (ctype == OP_TYPE_LOWER_EQUAL)
    return optSysFilterFuncImpl__LowerEqual;
  else if (ctype == OP_TYPE_GREATER_THAN)
    return optSysFilterFuncImpl__GreaterThan;
  else if (ctype == OP_TYPE_GREATER_EQUAL)
    return optSysFilterFuncImpl__GreaterEqual;
  else if (ctype == OP_TYPE_EQUAL)
    return optSysFilterFuncImpl__Equal;
dengyihao's avatar
dengyihao 已提交
3165 3166
  else if (ctype == OP_TYPE_NOT_EQUAL)
    return optSysFilterFuncImpl__NoEqual;
dengyihao's avatar
dengyihao 已提交
3167 3168
  return NULL;
}
dengyihao's avatar
dengyihao 已提交
3169 3170
static int32_t sysFilte__DbName(void* arg, SNode* pNode, SArray* result) {
  void* pVnode = ((SSTabFltArg*)arg)->pVnode;
3171

dengyihao's avatar
dengyihao 已提交
3172 3173
  const char* db = NULL;
  vnodeGetInfo(pVnode, &db, NULL);
dengyihao's avatar
dengyihao 已提交
3174

dengyihao's avatar
dengyihao 已提交
3175 3176 3177 3178 3179 3180
  SName sn = {0};
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
  tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);

  tNameGetDbName(&sn, varDataVal(dbname));
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
dengyihao's avatar
dengyihao 已提交
3181

dengyihao's avatar
dengyihao 已提交
3182
  SOperatorNode* pOper = (SOperatorNode*)pNode;
dengyihao's avatar
dengyihao 已提交
3183
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3184

dengyihao's avatar
dengyihao 已提交
3185 3186
  bool           reverse = false;
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3187 3188 3189 3190 3191
  if (func == NULL) return -1;

  int ret = func(dbname, pVal->datum.p, TSDB_DATA_TYPE_VARCHAR);
  if (ret == 0) return 0;

dengyihao's avatar
dengyihao 已提交
3192
  return -2;
dengyihao's avatar
dengyihao 已提交
3193
}
dengyihao's avatar
dengyihao 已提交
3194 3195
static int32_t sysFilte__VgroupId(void* arg, SNode* pNode, SArray* result) {
  void* pVnode = ((SSTabFltArg*)arg)->pVnode;
dengyihao's avatar
dengyihao 已提交
3196

dengyihao's avatar
dengyihao 已提交
3197 3198
  int64_t vgId = 0;
  vnodeGetInfo(pVnode, NULL, (int32_t*)&vgId);
dengyihao's avatar
dengyihao 已提交
3199

dengyihao's avatar
dengyihao 已提交
3200
  SOperatorNode* pOper = (SOperatorNode*)pNode;
dengyihao's avatar
dengyihao 已提交
3201 3202
  SValueNode*    pVal = (SValueNode*)pOper->pRight;

dengyihao's avatar
dengyihao 已提交
3203 3204 3205
  bool reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3206 3207 3208 3209
  if (func == NULL) return -1;

  int ret = func(&vgId, &pVal->datum.i, TSDB_DATA_TYPE_BIGINT);
  if (ret == 0) return 0;
dengyihao's avatar
dengyihao 已提交
3210

dengyihao's avatar
dengyihao 已提交
3211
  return -1;
dengyihao's avatar
dengyihao 已提交
3212
}
dengyihao's avatar
dengyihao 已提交
3213 3214
static int32_t sysFilte__TableName(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
  if (func == NULL) return -1;

  SMetaFltParam param = {.suid = 0,
                         .cid = 0,
                         .type = TSDB_DATA_TYPE_VARCHAR,
                         .val = pVal->datum.p,
                         .reverse = reverse,
                         .filterFunc = func};
dengyihao's avatar
dengyihao 已提交
3229
  return -1;
dengyihao's avatar
dengyihao 已提交
3230 3231
}

dengyihao's avatar
dengyihao 已提交
3232 3233
static int32_t sysFilte__CreateTime(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3234 3235 3236 3237 3238 3239 3240

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
  if (func == NULL) return -1;
dengyihao's avatar
dengyihao 已提交
3241 3242 3243 3244 3245 3246 3247 3248 3249 3250

  SMetaFltParam param = {.suid = 0,
                         .cid = 0,
                         .type = TSDB_DATA_TYPE_BIGINT,
                         .val = &pVal->datum.i,
                         .reverse = reverse,
                         .filterFunc = func};

  int32_t ret = metaFilterCreateTime(pMeta, &param, result);
  return ret;
dengyihao's avatar
dengyihao 已提交
3251
}
dengyihao's avatar
dengyihao 已提交
3252 3253
static int32_t sysFilte__Ncolumn(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3254 3255 3256 3257 3258 3259

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3260 3261
  if (func == NULL) return -1;
  return -1;
dengyihao's avatar
dengyihao 已提交
3262 3263
}

dengyihao's avatar
dengyihao 已提交
3264 3265
static int32_t sysFilte__Ttl(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3266 3267 3268 3269 3270 3271

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3272 3273
  if (func == NULL) return -1;
  return -1;
dengyihao's avatar
dengyihao 已提交
3274
}
dengyihao's avatar
dengyihao 已提交
3275 3276
static int32_t sysFilte__STableName(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3277 3278 3279 3280 3281 3282

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3283 3284
  if (func == NULL) return -1;
  return -1;
dengyihao's avatar
dengyihao 已提交
3285
}
dengyihao's avatar
dengyihao 已提交
3286 3287
static int32_t sysFilte__Uid(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3288 3289 3290 3291 3292 3293

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3294 3295
  if (func == NULL) return -1;
  return -1;
dengyihao's avatar
dengyihao 已提交
3296
}
dengyihao's avatar
dengyihao 已提交
3297 3298
static int32_t sysFilte__Type(void* arg, SNode* pNode, SArray* result) {
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
dengyihao's avatar
dengyihao 已提交
3299 3300 3301 3302 3303 3304

  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
  bool           reverse = false;

  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse);
dengyihao's avatar
dengyihao 已提交
3305
  if (func == NULL) return -1;
dengyihao's avatar
dengyihao 已提交
3306
  return -1;
dengyihao's avatar
dengyihao 已提交
3307
}
dengyihao's avatar
dengyihao 已提交
3308 3309 3310 3311 3312
static int32_t sysChkFilter__Comm(SNode* pNode) {
  // impl
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  EOperatorType  opType = pOper->opType;
  if (opType != OP_TYPE_EQUAL && opType != OP_TYPE_LOWER_EQUAL && opType != OP_TYPE_LOWER_THAN &&
dengyihao's avatar
dengyihao 已提交
3313
      opType != OP_TYPE_GREATER_EQUAL && opType != OP_TYPE_GREATER_THAN) {
dengyihao's avatar
dengyihao 已提交
3314
    return -1;
dengyihao's avatar
dengyihao 已提交
3315 3316 3317 3318
  }
  return 0;
}

dengyihao's avatar
dengyihao 已提交
3319 3320
static int32_t sysChkFilter__DBName(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
dengyihao's avatar
dengyihao 已提交
3321 3322 3323 3324 3325 3326

  if (pOper->opType != OP_TYPE_EQUAL && pOper->opType != OP_TYPE_NOT_EQUAL) {
    return -1;
  }

  SValueNode* pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3327
  if (!IS_STR_DATA_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3328 3329
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3330

dengyihao's avatar
dengyihao 已提交
3331 3332 3333 3334 3335
  return 0;
}
static int32_t sysChkFilter__VgroupId(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3336
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3337 3338
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3339
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3340 3341 3342 3343
}
static int32_t sysChkFilter__TableName(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3344
  if (!IS_STR_DATA_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3345 3346
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3347
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3348 3349 3350 3351 3352
}
static int32_t sysChkFilter__CreateTime(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;

dengyihao's avatar
dengyihao 已提交
3353
  if (!IS_TIMESTAMP_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3354 3355
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3356
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3357 3358 3359 3360 3361 3362
}

static int32_t sysChkFilter__Ncolumn(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;

dengyihao's avatar
dengyihao 已提交
3363
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3364 3365
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3366
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3367 3368 3369 3370 3371
}
static int32_t sysChkFilter__Ttl(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;

dengyihao's avatar
dengyihao 已提交
3372
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3373 3374
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3375
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3376 3377 3378 3379
}
static int32_t sysChkFilter__STableName(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3380
  if (!IS_STR_DATA_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3381 3382
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3383
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3384 3385 3386 3387
}
static int32_t sysChkFilter__Uid(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3388
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3389 3390
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3391
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3392 3393 3394 3395
}
static int32_t sysChkFilter__Type(SNode* pNode) {
  SOperatorNode* pOper = (SOperatorNode*)pNode;
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
dengyihao's avatar
dengyihao 已提交
3396
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
dengyihao's avatar
dengyihao 已提交
3397 3398
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
3399
  return sysChkFilter__Comm(pNode);
dengyihao's avatar
dengyihao 已提交
3400
}
dengyihao's avatar
dengyihao 已提交
3401
static int32_t optSysTabFilteImpl(void* arg, SNode* cond, SArray* result) {
dengyihao's avatar
dengyihao 已提交
3402
  if (optSysCheckOper(cond) != 0) return -1;
dengyihao's avatar
dengyihao 已提交
3403 3404 3405

  SOperatorNode* pNode = (SOperatorNode*)cond;

dengyihao's avatar
dengyihao 已提交
3406 3407
  int8_t i = 0;
  for (; i < SYSTAB_FILTER_DICT_SIZE; i++) {
dengyihao's avatar
dengyihao 已提交
3408 3409
    if (strcmp(filterDict[i].name, ((SColumnNode*)(pNode->pLeft))->colName) == 0) {
      break;
3410
    }
dengyihao's avatar
dengyihao 已提交
3411 3412
  }
  if (i >= SYSTAB_FILTER_DICT_SIZE) return -1;
3413

dengyihao's avatar
dengyihao 已提交
3414
  if (filterDict[i].chkFunc(cond) != 0) return -1;
3415

dengyihao's avatar
dengyihao 已提交
3416 3417
  return filterDict[i].fltFunc(arg, cond, result);
}
3418

dengyihao's avatar
dengyihao 已提交
3419 3420
static int32_t optSysCheckOper(SNode* pOpear) {
  if (nodeType(pOpear) != QUERY_NODE_OPERATOR) return -1;
3421

dengyihao's avatar
dengyihao 已提交
3422
  SOperatorNode* pOper = (SOperatorNode*)pOpear;
dengyihao's avatar
dengyihao 已提交
3423 3424 3425
  if (pOper->opType < OP_TYPE_GREATER_THAN || pOper->opType > OP_TYPE_NOT_EQUAL) {
    return -1;
  }
3426

dengyihao's avatar
dengyihao 已提交
3427 3428 3429 3430
  if (nodeType(pOper->pLeft) != QUERY_NODE_COLUMN || nodeType(pOper->pRight) != QUERY_NODE_VALUE) {
    return -1;
  }
  return 0;
dengyihao's avatar
dengyihao 已提交
3431
}
3432

dengyihao's avatar
dengyihao 已提交
3433 3434 3435 3436 3437 3438 3439 3440
static int tableUidCompare(const void* a, const void* b) {
  int64_t u1 = *(int64_t*)a;
  int64_t u2 = *(int64_t*)b;
  if (u1 == u2) {
    return 0;
  }
  return u1 < u2 ? -1 : 1;
}
dengyihao's avatar
opt mem  
dengyihao 已提交
3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495

typedef struct MergeIndex {
  int idx;
  int len;
} MergeIndex;

static FORCE_INLINE int optSysBinarySearch(SArray* arr, int s, int e, uint64_t k) {
  uint64_t v;
  int32_t  m;
  while (s <= e) {
    m = s + (e - s) / 2;
    v = *(uint64_t*)taosArrayGet(arr, m);
    if (v >= k) {
      e = m - 1;
    } else {
      s = m + 1;
    }
  }
  return s;
}

void optSysIntersection(SArray* in, SArray* out) {
  int32_t sz = (int32_t)taosArrayGetSize(in);
  if (sz <= 0) {
    return;
  }
  MergeIndex* mi = taosMemoryCalloc(sz, sizeof(MergeIndex));
  for (int i = 0; i < sz; i++) {
    SArray* t = taosArrayGetP(in, i);
    mi[i].len = (int32_t)taosArrayGetSize(t);
    mi[i].idx = 0;
  }

  SArray* base = taosArrayGetP(in, 0);
  for (int i = 0; i < taosArrayGetSize(base); i++) {
    uint64_t tgt = *(uint64_t*)taosArrayGet(base, i);
    bool     has = true;
    for (int j = 1; j < taosArrayGetSize(in); j++) {
      SArray* oth = taosArrayGetP(in, j);
      int     mid = optSysBinarySearch(oth, mi[j].idx, mi[j].len - 1, tgt);
      if (mid >= 0 && mid < mi[j].len) {
        uint64_t val = *(uint64_t*)taosArrayGet(oth, mid);
        has = (val == tgt ? true : false);
        mi[j].idx = mid;
      } else {
        has = false;
      }
    }
    if (has == true) {
      taosArrayPush(out, &tgt);
    }
  }
  taosMemoryFreeClear(mi);
}

dengyihao's avatar
dengyihao 已提交
3496 3497 3498
static int32_t optSysMergeRslt(SArray* mRslt, SArray* rslt) {
  // TODO, find comm mem from mRslt
  for (int i = 0; i < taosArrayGetSize(mRslt); i++) {
dengyihao's avatar
opt mem  
dengyihao 已提交
3499 3500 3501 3502 3503 3504
    SArray* arslt = taosArrayGetP(mRslt, i);
    taosArraySort(arslt, tableUidCompare);
  }
  optSysIntersection(mRslt, rslt);
  return 0;
}
3505

dengyihao's avatar
opt mem  
dengyihao 已提交
3506 3507 3508 3509 3510 3511 3512
static int32_t optSysSpecialColumn(SNode* cond) {
  SOperatorNode* pOper = (SOperatorNode*)cond;
  SColumnNode*   pCol = (SColumnNode*)pOper->pLeft;
  for (int i = 0; i < sizeof(SYSTABLE_SPECIAL_COL) / sizeof(SYSTABLE_SPECIAL_COL[0]); i++) {
    if (0 == strcmp(pCol->colName, SYSTABLE_SPECIAL_COL[i])) {
      return 1;
    }
dengyihao's avatar
dengyihao 已提交
3513 3514 3515
  }
  return 0;
}
3516

dengyihao's avatar
dengyihao 已提交
3517 3518 3519 3520
static int32_t optSysTabFilte(void* arg, SNode* cond, SArray* result) {
  int ret = -1;
  if (nodeType(cond) == QUERY_NODE_OPERATOR) {
    ret = optSysTabFilteImpl(arg, cond, result);
dengyihao's avatar
dengyihao 已提交
3521 3522 3523
    if (ret == 0) {
      SOperatorNode* pOper = (SOperatorNode*)cond;
      SColumnNode*   pCol = (SColumnNode*)pOper->pLeft;
dengyihao's avatar
dengyihao 已提交
3524
      if (0 == strcmp(pCol->colName, "create_time")) {
dengyihao's avatar
dengyihao 已提交
3525 3526 3527 3528
        return 0;
      }
      return -1;
    }
dengyihao's avatar
dengyihao 已提交
3529 3530
    return ret;
  }
3531

dengyihao's avatar
dengyihao 已提交
3532 3533 3534
  if (nodeType(cond) != QUERY_NODE_LOGIC_CONDITION || ((SLogicConditionNode*)cond)->condType != LOGIC_COND_TYPE_AND) {
    return ret;
  }
3535

dengyihao's avatar
dengyihao 已提交
3536 3537
  SLogicConditionNode* pNode = (SLogicConditionNode*)cond;
  SNodeList*           pList = (SNodeList*)pNode->pParameterList;
3538

dengyihao's avatar
dengyihao 已提交
3539
  int32_t len = LIST_LENGTH(pList);
3540

dengyihao's avatar
dengyihao 已提交
3541
  bool    hasIdx = false;
dengyihao's avatar
dengyihao 已提交
3542
  bool    hasRslt = true;
dengyihao's avatar
dengyihao 已提交
3543
  SArray* mRslt = taosArrayInit(len, POINTER_BYTES);
3544

dengyihao's avatar
dengyihao 已提交
3545 3546 3547
  SListCell* cell = pList->pHead;
  for (int i = 0; i < len; i++) {
    if (cell == NULL) break;
3548

dengyihao's avatar
dengyihao 已提交
3549
    SArray* aRslt = taosArrayInit(16, sizeof(int64_t));
3550

dengyihao's avatar
dengyihao 已提交
3551 3552
    ret = optSysTabFilteImpl(arg, cell->pNode, aRslt);
    if (ret == 0) {
dengyihao's avatar
dengyihao 已提交
3553
      // has index
dengyihao's avatar
dengyihao 已提交
3554
      hasIdx = true;
dengyihao's avatar
opt mem  
dengyihao 已提交
3555 3556 3557 3558 3559 3560
      if (optSysSpecialColumn(cell->pNode) == 0) {
        taosArrayPush(mRslt, &aRslt);
      } else {
        // db_name/vgroup not result
        taosArrayDestroy(aRslt);
      }
dengyihao's avatar
dengyihao 已提交
3561
    } else if (ret == -2) {
dengyihao's avatar
dengyihao 已提交
3562
      // current vg
dengyihao's avatar
dengyihao 已提交
3563 3564 3565 3566 3567 3568
      hasIdx = true;
      hasRslt = false;
      taosArrayDestroy(aRslt);
      break;
    } else {
      taosArrayDestroy(aRslt);
dengyihao's avatar
dengyihao 已提交
3569 3570 3571
    }
    cell = cell->pNext;
  }
dengyihao's avatar
dengyihao 已提交
3572 3573 3574
  if (hasRslt && hasIdx) {
    optSysMergeRslt(mRslt, result);
  }
3575

dengyihao's avatar
dengyihao 已提交
3576 3577 3578
  for (int i = 0; i < taosArrayGetSize(mRslt); i++) {
    SArray* aRslt = taosArrayGetP(mRslt, i);
    taosArrayDestroy(aRslt);
dengyihao's avatar
dengyihao 已提交
3579
  }
dengyihao's avatar
dengyihao 已提交
3580
  taosArrayDestroy(mRslt);
dengyihao's avatar
dengyihao 已提交
3581 3582 3583 3584
  if (hasRslt == false) {
    return -2;
  }
  if (hasRslt && hasIdx) {
dengyihao's avatar
dengyihao 已提交
3585 3586 3587 3588 3589
    cell = pList->pHead;
    for (int i = 0; i < len; i++) {
      if (cell == NULL) break;
      SOperatorNode* pOper = (SOperatorNode*)cell->pNode;
      SColumnNode*   pCol = (SColumnNode*)pOper->pLeft;
dengyihao's avatar
dengyihao 已提交
3590
      if (0 == strcmp(pCol->colName, "create_time")) {
dengyihao's avatar
dengyihao 已提交
3591 3592 3593 3594 3595
        return 0;
      }
      cell = cell->pNext;
    }
    return -1;
dengyihao's avatar
dengyihao 已提交
3596 3597
  }
  return -1;
dengyihao's avatar
dengyihao 已提交
3598
}
3599

dengyihao's avatar
dengyihao 已提交
3600
static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
dengyihao's avatar
dengyihao 已提交
3601 3602
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
  SSysTableScanInfo* pInfo = pOperator->info;
3603

dengyihao's avatar
dengyihao 已提交
3604
  SSysTableIndex* pIdx = pInfo->pIdx;
dengyihao's avatar
dengyihao 已提交
3605 3606
  blockDataCleanup(pInfo->pRes);
  int32_t numOfRows = 0;
3607

dengyihao's avatar
dengyihao 已提交
3608
  int ret = 0;
3609

dengyihao's avatar
dengyihao 已提交
3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623
  const char* db = NULL;
  int32_t     vgId = 0;
  vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId);

  SName sn = {0};
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
  tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);

  tNameGetDbName(&sn, varDataVal(dbname));
  varDataSetLen(dbname, strlen(varDataVal(dbname)));

  SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
  blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);

dengyihao's avatar
dengyihao 已提交
3624 3625 3626 3627
  char    n[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
  int32_t i = pIdx->lastIdx;
  for (; i < taosArrayGetSize(pIdx->uids); i++) {
    tb_uid_t* uid = taosArrayGet(pIdx->uids, i);
3628

dengyihao's avatar
dengyihao 已提交
3629
    SMetaReader mr = {0};
dengyihao's avatar
dengyihao 已提交
3630
    metaReaderInit(&mr, pInfo->readHandle.meta, 0);
H
Haojun Liao 已提交
3631
    ret = metaGetTableEntryByUid(&mr, *uid);
dengyihao's avatar
dengyihao 已提交
3632 3633 3634 3635 3636 3637 3638 3639 3640
    if (ret < 0) {
      metaReaderClear(&mr);
      continue;
    }
    STR_TO_VARSTR(n, mr.me.name);

    // table name
    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
    colDataAppend(pColInfoData, numOfRows, n, false);
3641

dengyihao's avatar
dengyihao 已提交
3642 3643 3644
    // database name
    pColInfoData = taosArrayGet(p->pDataBlock, 1);
    colDataAppend(pColInfoData, numOfRows, dbname, false);
3645

dengyihao's avatar
dengyihao 已提交
3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659
    // vgId
    pColInfoData = taosArrayGet(p->pDataBlock, 6);
    colDataAppend(pColInfoData, numOfRows, (char*)&vgId, false);

    int32_t tableType = mr.me.type;
    if (tableType == TSDB_CHILD_TABLE) {
      // create time
      int64_t ts = mr.me.ctbEntry.ctime;
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
      colDataAppend(pColInfoData, numOfRows, (char*)&ts, false);

      SMetaReader mr1 = {0};
      metaReaderInit(&mr1, pInfo->readHandle.meta, META_READER_NOLOCK);

dengyihao's avatar
dengyihao 已提交
3660 3661
      int64_t suid = mr.me.ctbEntry.suid;
      int32_t code = metaGetTableEntryByUid(&mr1, suid);
dengyihao's avatar
dengyihao 已提交
3662 3663 3664 3665
      if (code != TSDB_CODE_SUCCESS) {
        qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pInfo->pCur->mr.me.name,
               suid, tstrerror(terrno), GET_TASKID(pTaskInfo));
        metaReaderClear(&mr1);
dengyihao's avatar
dengyihao 已提交
3666
        metaReaderClear(&mr);
dengyihao's avatar
dengyihao 已提交
3667
        T_LONG_JMP(pTaskInfo->env, terrno);
H
Haojun Liao 已提交
3668
      }
dengyihao's avatar
dengyihao 已提交
3669
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
dengyihao's avatar
dengyihao 已提交
3670
      colDataAppend(pColInfoData, numOfRows, (char*)&mr1.me.stbEntry.schemaRow.nCols, false);
H
Haojun Liao 已提交
3671

dengyihao's avatar
dengyihao 已提交
3672 3673 3674
      // super table name
      STR_TO_VARSTR(n, mr1.me.name);
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
3675
      colDataAppend(pColInfoData, numOfRows, n, false);
dengyihao's avatar
dengyihao 已提交
3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690
      metaReaderClear(&mr1);

      // table comment
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
      if (mr.me.ctbEntry.commentLen > 0) {
        char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, mr.me.ctbEntry.comment);
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else if (mr.me.ctbEntry.commentLen == 0) {
        char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, "");
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else {
        colDataAppendNULL(pColInfoData, numOfRows);
      }
3691

dengyihao's avatar
dengyihao 已提交
3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716
      // uid
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
      colDataAppend(pColInfoData, numOfRows, (char*)&mr.me.uid, false);

      // ttl
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
      colDataAppend(pColInfoData, numOfRows, (char*)&mr.me.ctbEntry.ttlDays, false);

      STR_TO_VARSTR(n, "CHILD_TABLE");

    } else if (tableType == TSDB_NORMAL_TABLE) {
      // create time
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.ctime, false);

      // number of columns
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.schemaRow.nCols, false);

      // super table name
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
      colDataAppendNULL(pColInfoData, numOfRows);

      // table comment
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
dengyihao's avatar
dengyihao 已提交
3717
      if (mr.me.ntbEntry.commentLen > 0) {
dengyihao's avatar
dengyihao 已提交
3718
        char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
dengyihao's avatar
dengyihao 已提交
3719
        STR_TO_VARSTR(comment, mr.me.ntbEntry.comment);
dengyihao's avatar
dengyihao 已提交
3720
        colDataAppend(pColInfoData, numOfRows, comment, false);
dengyihao's avatar
dengyihao 已提交
3721
      } else if (mr.me.ntbEntry.commentLen == 0) {
dengyihao's avatar
dengyihao 已提交
3722 3723 3724 3725 3726 3727
        char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, "");
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else {
        colDataAppendNULL(pColInfoData, numOfRows);
      }
3728

dengyihao's avatar
dengyihao 已提交
3729 3730
      // uid
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
dengyihao's avatar
dengyihao 已提交
3731
      colDataAppend(pColInfoData, numOfRows, (char*)&mr.me.uid, false);
3732

dengyihao's avatar
dengyihao 已提交
3733 3734
      // ttl
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
dengyihao's avatar
dengyihao 已提交
3735
      colDataAppend(pColInfoData, numOfRows, (char*)&mr.me.ntbEntry.ttlDays, false);
3736

dengyihao's avatar
dengyihao 已提交
3737 3738
      STR_TO_VARSTR(n, "NORMAL_TABLE");
      // impl later
3739
    }
3740

dengyihao's avatar
dengyihao 已提交
3741 3742
    metaReaderClear(&mr);

dengyihao's avatar
dengyihao 已提交
3743 3744 3745 3746
    pColInfoData = taosArrayGet(p->pDataBlock, 9);
    colDataAppend(pColInfoData, numOfRows, n, false);

    if (++numOfRows >= pOperator->resultInfo.capacity) {
3747 3748 3749
      p->info.rows = numOfRows;
      pInfo->pRes->info.rows = numOfRows;

H
Haojun Liao 已提交
3750
      relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
H
Haojun Liao 已提交
3751
      doFilterResult(pInfo->pRes, pOperator->exprSupp.pFilterInfo);
3752 3753 3754

      blockDataCleanup(p);
      numOfRows = 0;
dengyihao's avatar
dengyihao 已提交
3755 3756 3757 3758

      if (pInfo->pRes->info.rows > 0) {
        break;
      }
3759
    }
dengyihao's avatar
dengyihao 已提交
3760
  }
3761

dengyihao's avatar
dengyihao 已提交
3762 3763 3764
  if (numOfRows > 0) {
    p->info.rows = numOfRows;
    pInfo->pRes->info.rows = numOfRows;
3765

H
Haojun Liao 已提交
3766
    relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
H
Haojun Liao 已提交
3767
    doFilterResult(pInfo->pRes, pOperator->exprSupp.pFilterInfo);
dengyihao's avatar
dengyihao 已提交
3768 3769 3770 3771 3772

    blockDataCleanup(p);
    numOfRows = 0;
  }

dengyihao's avatar
dengyihao 已提交
3773
  if (i >= taosArrayGetSize(pIdx->uids)) {
H
Haojun Liao 已提交
3774
    setOperatorCompleted(pOperator);
dengyihao's avatar
dengyihao 已提交
3775
  } else {
dengyihao's avatar
dengyihao 已提交
3776
    pIdx->lastIdx = i + 1;
dengyihao's avatar
dengyihao 已提交
3777
  }
dengyihao's avatar
dengyihao 已提交
3778

dengyihao's avatar
dengyihao 已提交
3779
  blockDataDestroy(p);
dengyihao's avatar
dengyihao 已提交
3780 3781 3782 3783

  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
}
3784

dengyihao's avatar
dengyihao 已提交
3785
static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
dengyihao's avatar
dengyihao 已提交
3786 3787
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;

H
Haojun Liao 已提交
3788
  SSysTableScanInfo* pInfo = pOperator->info;
dengyihao's avatar
dengyihao 已提交
3789 3790
  if (pInfo->pCur == NULL) {
    pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
3791
  }
H
Haojun Liao 已提交
3792

dengyihao's avatar
dengyihao 已提交
3793 3794
  blockDataCleanup(pInfo->pRes);
  int32_t numOfRows = 0;
3795

dengyihao's avatar
dengyihao 已提交
3796 3797 3798
  const char* db = NULL;
  int32_t     vgId = 0;
  vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId);
3799

dengyihao's avatar
dengyihao 已提交
3800 3801 3802
  SName sn = {0};
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
  tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
3803

dengyihao's avatar
dengyihao 已提交
3804 3805
  tNameGetDbName(&sn, varDataVal(dbname));
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
3806

dengyihao's avatar
dengyihao 已提交
3807 3808
  SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
  blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
3809

dengyihao's avatar
dengyihao 已提交
3810
  char n[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3811

dengyihao's avatar
dengyihao 已提交
3812 3813 3814
  int32_t ret = 0;
  while ((ret = metaTbCursorNext(pInfo->pCur)) == 0) {
    STR_TO_VARSTR(n, pInfo->pCur->mr.me.name);
3815

dengyihao's avatar
dengyihao 已提交
3816 3817 3818
    // table name
    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
    colDataAppend(pColInfoData, numOfRows, n, false);
3819

dengyihao's avatar
dengyihao 已提交
3820 3821 3822
    // database name
    pColInfoData = taosArrayGet(p->pDataBlock, 1);
    colDataAppend(pColInfoData, numOfRows, dbname, false);
3823

dengyihao's avatar
dengyihao 已提交
3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842
    // vgId
    pColInfoData = taosArrayGet(p->pDataBlock, 6);
    colDataAppend(pColInfoData, numOfRows, (char*)&vgId, false);

    int32_t tableType = pInfo->pCur->mr.me.type;
    if (tableType == TSDB_CHILD_TABLE) {
      // create time
      int64_t ts = pInfo->pCur->mr.me.ctbEntry.ctime;
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
      colDataAppend(pColInfoData, numOfRows, (char*)&ts, false);

      SMetaReader mr = {0};
      metaReaderInit(&mr, pInfo->readHandle.meta, META_READER_NOLOCK);

      uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
      int32_t  code = metaGetTableEntryByUid(&mr, suid);
      if (code != TSDB_CODE_SUCCESS) {
        qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pInfo->pCur->mr.me.name,
               suid, tstrerror(terrno), GET_TASKID(pTaskInfo));
3843
        metaReaderClear(&mr);
dengyihao's avatar
dengyihao 已提交
3844 3845 3846 3847
        metaCloseTbCursor(pInfo->pCur);
        pInfo->pCur = NULL;
        T_LONG_JMP(pTaskInfo->env, terrno);
      }
3848

dengyihao's avatar
dengyihao 已提交
3849 3850 3851
      // number of columns
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
      colDataAppend(pColInfoData, numOfRows, (char*)&mr.me.stbEntry.schemaRow.nCols, false);
3852

dengyihao's avatar
dengyihao 已提交
3853 3854 3855 3856 3857
      // super table name
      STR_TO_VARSTR(n, mr.me.name);
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
      colDataAppend(pColInfoData, numOfRows, n, false);
      metaReaderClear(&mr);
3858

dengyihao's avatar
dengyihao 已提交
3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869
      // table comment
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
      if (pInfo->pCur->mr.me.ctbEntry.commentLen > 0) {
        char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, pInfo->pCur->mr.me.ctbEntry.comment);
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else if (pInfo->pCur->mr.me.ctbEntry.commentLen == 0) {
        char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, "");
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else {
3870
        colDataAppendNULL(pColInfoData, numOfRows);
H
Haojun Liao 已提交
3871 3872
      }

dengyihao's avatar
dengyihao 已提交
3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907
      // uid
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);

      // ttl
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ctbEntry.ttlDays, false);

      STR_TO_VARSTR(n, "CHILD_TABLE");
    } else if (tableType == TSDB_NORMAL_TABLE) {
      // create time
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.ctime, false);

      // number of columns
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.schemaRow.nCols, false);

      // super table name
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
      colDataAppendNULL(pColInfoData, numOfRows);

      // table comment
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
      if (pInfo->pCur->mr.me.ntbEntry.commentLen > 0) {
        char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, pInfo->pCur->mr.me.ntbEntry.comment);
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else if (pInfo->pCur->mr.me.ntbEntry.commentLen == 0) {
        char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
        STR_TO_VARSTR(comment, "");
        colDataAppend(pColInfoData, numOfRows, comment, false);
      } else {
        colDataAppendNULL(pColInfoData, numOfRows);
      }
3908

dengyihao's avatar
dengyihao 已提交
3909 3910 3911
      // uid
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
3912

dengyihao's avatar
dengyihao 已提交
3913 3914 3915
      // ttl
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
      colDataAppend(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.ttlDays, false);
3916

dengyihao's avatar
dengyihao 已提交
3917
      STR_TO_VARSTR(n, "NORMAL_TABLE");
3918
    }
H
Haojun Liao 已提交
3919

dengyihao's avatar
dengyihao 已提交
3920 3921 3922 3923
    pColInfoData = taosArrayGet(p->pDataBlock, 9);
    colDataAppend(pColInfoData, numOfRows, n, false);

    if (++numOfRows >= pOperator->resultInfo.capacity) {
3924 3925 3926
      p->info.rows = numOfRows;
      pInfo->pRes->info.rows = numOfRows;

H
Haojun Liao 已提交
3927
      relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
H
Haojun Liao 已提交
3928
      doFilterResult(pInfo->pRes, pOperator->exprSupp.pFilterInfo);
3929 3930 3931

      blockDataCleanup(p);
      numOfRows = 0;
dengyihao's avatar
dengyihao 已提交
3932 3933 3934 3935

      if (pInfo->pRes->info.rows > 0) {
        break;
      }
3936
    }
dengyihao's avatar
dengyihao 已提交
3937
  }
3938

dengyihao's avatar
dengyihao 已提交
3939 3940 3941
  if (numOfRows > 0) {
    p->info.rows = numOfRows;
    pInfo->pRes->info.rows = numOfRows;
3942

H
Haojun Liao 已提交
3943
    relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
H
Haojun Liao 已提交
3944
    doFilterResult(pInfo->pRes, pOperator->exprSupp.pFilterInfo);
H
Haojun Liao 已提交
3945

dengyihao's avatar
dengyihao 已提交
3946 3947 3948 3949 3950 3951 3952 3953 3954 3955
    blockDataCleanup(p);
    numOfRows = 0;
  }

  blockDataDestroy(p);

  // todo temporarily free the cursor here, the true reason why the free is not valid needs to be found
  if (ret != 0) {
    metaCloseTbCursor(pInfo->pCur);
    pInfo->pCur = NULL;
H
Haojun Liao 已提交
3956
    setOperatorCompleted(pOperator);
dengyihao's avatar
dengyihao 已提交
3957 3958 3959 3960 3961
  }

  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
}
dengyihao's avatar
dengyihao 已提交
3962

dengyihao's avatar
dengyihao 已提交
3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974
static SSDataBlock* sysTableScanUserTables(SOperatorInfo* pOperator) {
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
  SSysTableScanInfo* pInfo = pOperator->info;

  SNode* pCondition = pInfo->pCondition;
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  // the retrieve is executed on the mnode, so return tables that belongs to the information schema database.
  if (pInfo->readHandle.mnd != NULL) {
    buildSysDbTableInfo(pInfo, pOperator->resultInfo.capacity);
H
Haojun Liao 已提交
3975
    doFilterResult(pInfo->pRes, pOperator->exprSupp.pFilterInfo);
3976
    pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
dengyihao's avatar
dengyihao 已提交
3977

H
Haojun Liao 已提交
3978
    setOperatorCompleted(pOperator);
3979
    return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
dengyihao's avatar
dengyihao 已提交
3980
  } else {
dengyihao's avatar
dengyihao 已提交
3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004
    if (pInfo->showRewrite == false) {
      if (pCondition != NULL && pInfo->pIdx == NULL) {
        SSTabFltArg arg = {.pMeta = pInfo->readHandle.meta, .pVnode = pInfo->readHandle.vnode};

        SSysTableIndex* idx = taosMemoryMalloc(sizeof(SSysTableIndex));
        idx->init = 0;
        idx->uids = taosArrayInit(128, sizeof(int64_t));
        idx->lastIdx = 0;

        pInfo->pIdx = idx;  // set idx arg

        int flt = optSysTabFilte(&arg, pCondition, idx->uids);
        if (flt == 0) {
          pInfo->pIdx->init = 1;
          SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
          return blk;
        } else if (flt == -2) {
          qDebug("%s failed to get sys table info by idx, empty result", GET_TASKID(pTaskInfo));
          return NULL;
        } else if (flt == -1) {
          // not idx
          qDebug("%s failed to get sys table info by idx, scan sys table one by one", GET_TASKID(pTaskInfo));
        }
      } else if (pCondition != NULL && (pInfo->pIdx != NULL && pInfo->pIdx->init == 1)) {
dengyihao's avatar
dengyihao 已提交
4005
        SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
dengyihao's avatar
dengyihao 已提交
4006 4007
        return blk;
      }
dengyihao's avatar
dengyihao 已提交
4008
    }
dengyihao's avatar
dengyihao 已提交
4009

dengyihao's avatar
dengyihao 已提交
4010
    return sysTableBuildUserTables(pOperator);
4011
  }
dengyihao's avatar
dengyihao 已提交
4012
  return NULL;
4013 4014
}

4015 4016 4017 4018 4019 4020 4021 4022
static SSDataBlock* sysTableScanUserSTables(SOperatorInfo* pOperator) {
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
  SSysTableScanInfo* pInfo = pOperator->info;
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  pInfo->pRes->info.rows = 0;
D
dapan1121 已提交
4023
  pOperator->status = OP_EXEC_DONE;
4024 4025 4026 4027 4028

  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
}

4029 4030 4031 4032
static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
  // build message and send to mnode to fetch the content of system tables.
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
  SSysTableScanInfo* pInfo = pOperator->info;
L
Liu Jicong 已提交
4033
  char               dbName[TSDB_DB_NAME_LEN] = {0};
4034 4035

  const char* name = tNameGetTableName(&pInfo->name);
D
dapan1121 已提交
4036 4037 4038 4039
  if (pInfo->showRewrite) {
    getDBNameFromCondition(pInfo->pCondition, dbName);
    sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
  }
H
Hongze Cheng 已提交
4040

D
dapan1121 已提交
4041
  if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0) {
4042
    return sysTableScanUserTables(pOperator);
D
dapan1121 已提交
4043
  } else if (strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0) {
4044
    return sysTableScanUserTags(pOperator);
L
Liu Jicong 已提交
4045 4046
  } else if (strncasecmp(name, TSDB_INS_TABLE_STABLES, TSDB_TABLE_FNAME_LEN) == 0 && pInfo->showRewrite &&
             IS_SYS_DBNAME(dbName)) {
4047
    return sysTableScanUserSTables(pOperator);
H
Haojun Liao 已提交
4048 4049 4050 4051 4052
  } else {  // load the meta from mnode of the given epset
    if (pOperator->status == OP_EXEC_DONE) {
      return NULL;
    }

4053 4054
    while (1) {
      int64_t startTs = taosGetTimestampUs();
H
Haojun Liao 已提交
4055
      tstrncpy(pInfo->req.tb, tNameGetTableName(&pInfo->name), tListLen(pInfo->req.tb));
H
Haojun Liao 已提交
4056
      tstrncpy(pInfo->req.user, pInfo->pUser, tListLen(pInfo->req.user));
H
Haojun Liao 已提交
4057

4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068
      int32_t contLen = tSerializeSRetrieveTableReq(NULL, 0, &pInfo->req);
      char*   buf1 = taosMemoryCalloc(1, contLen);
      tSerializeSRetrieveTableReq(buf1, contLen, &pInfo->req);

      // send the fetch remote task result reques
      SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
      if (NULL == pMsgSendInfo) {
        qError("%s prepare message %d failed", GET_TASKID(pTaskInfo), (int32_t)sizeof(SMsgSendInfo));
        pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
        return NULL;
      }
H
Haojun Liao 已提交
4069

L
Liu Jicong 已提交
4070 4071
      int32_t msgType = (strcasecmp(name, TSDB_INS_TABLE_DNODE_VARIABLES) == 0) ? TDMT_DND_SYSTABLE_RETRIEVE
                                                                                : TDMT_MND_SYSTABLE_RETRIEVE;
D
dapan1121 已提交
4072

4073 4074 4075
      pMsgSendInfo->param = pOperator;
      pMsgSendInfo->msgInfo.pData = buf1;
      pMsgSendInfo->msgInfo.len = contLen;
D
dapan1121 已提交
4076
      pMsgSendInfo->msgType = msgType;
4077
      pMsgSendInfo->fp = loadSysTableCallback;
D
dapan1121 已提交
4078
      pMsgSendInfo->requestId = pTaskInfo->id.queryId;
H
Haojun Liao 已提交
4079

4080
      int64_t transporterId = 0;
4081 4082
      int32_t code =
          asyncSendMsgToServer(pInfo->readHandle.pMsgCb->clientRpc, &pInfo->epSet, &transporterId, pMsgSendInfo);
4083
      tsem_wait(&pInfo->ready);
H
Haojun Liao 已提交
4084

4085 4086 4087 4088 4089
      if (pTaskInfo->code) {
        qDebug("%s load meta data from mnode failed, totalRows:%" PRIu64 ", code:%s", GET_TASKID(pTaskInfo),
               pInfo->loadInfo.totalRows, tstrerror(pTaskInfo->code));
        return NULL;
      }
H
Haojun Liao 已提交
4090

4091 4092
      SRetrieveMetaTableRsp* pRsp = pInfo->pRsp;
      pInfo->req.showId = pRsp->handle;
H
Haojun Liao 已提交
4093

4094 4095
      if (pRsp->numOfRows == 0 || pRsp->completed) {
        pOperator->status = OP_EXEC_DONE;
4096
        qDebug("%s load meta data from mnode completed, rowsOfSource:%d, totalRows:%" PRIu64, GET_TASKID(pTaskInfo),
4097
               pRsp->numOfRows, pInfo->loadInfo.totalRows);
H
Haojun Liao 已提交
4098

4099
        if (pRsp->numOfRows == 0) {
H
Haojun Liao 已提交
4100
          taosMemoryFree(pRsp);
4101 4102 4103
          return NULL;
        }
      }
H
Haojun Liao 已提交
4104

4105
      char* pStart = pRsp->data;
H
Haojun Liao 已提交
4106
      extractDataBlockFromFetchRsp(pInfo->pRes, pRsp->data, pInfo->matchInfo.pList, &pStart);
4107
      updateLoadRemoteInfo(&pInfo->loadInfo, pRsp->numOfRows, pRsp->compLen, startTs, pOperator);
H
Haojun Liao 已提交
4108

4109
      // todo log the filter info
H
Haojun Liao 已提交
4110
      doFilterResult(pInfo->pRes, pOperator->exprSupp.pFilterInfo);
H
Haojun Liao 已提交
4111
      taosMemoryFree(pRsp);
4112 4113
      if (pInfo->pRes->info.rows > 0) {
        return pInfo->pRes;
D
dapan1121 已提交
4114 4115
      } else if (pOperator->status == OP_EXEC_DONE) {
        return NULL;
4116
      }
4117
    }
H
Haojun Liao 已提交
4118 4119 4120
  }
}

4121
int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity) {
D
dapan1121 已提交
4122
  SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
4123
  blockDataEnsureCapacity(p, capacity);
4124

L
Liu Jicong 已提交
4125
  size_t               size = 0;
4126 4127 4128
  const SSysTableMeta* pSysDbTableMeta = NULL;

  getInfosDbMeta(&pSysDbTableMeta, &size);
4129
  p->info.rows = buildDbTableInfoBlock(pInfo->sysInfo, p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB);
4130 4131

  getPerfDbMeta(&pSysDbTableMeta, &size);
4132
  p->info.rows = buildDbTableInfoBlock(pInfo->sysInfo, p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB);
4133 4134

  pInfo->pRes->info.rows = p->info.rows;
H
Haojun Liao 已提交
4135
  relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
4136 4137 4138
  blockDataDestroy(p);

  return pInfo->pRes->info.rows;
4139 4140
}

4141
int32_t buildDbTableInfoBlock(bool sysInfo, const SSDataBlock* p, const SSysTableMeta* pSysDbTableMeta, size_t size,
L
Liu Jicong 已提交
4142 4143
                              const char* dbName) {
  char    n[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
4144 4145
  int32_t numOfRows = p->info.rows;

L
Liu Jicong 已提交
4146
  for (int32_t i = 0; i < size; ++i) {
4147
    const SSysTableMeta* pm = &pSysDbTableMeta[i];
4148 4149 4150
    if (!sysInfo && pm->sysInfo) {
      continue;
    }
4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169

    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);

    STR_TO_VARSTR(n, pm->name);
    colDataAppend(pColInfoData, numOfRows, n, false);

    // database name
    STR_TO_VARSTR(n, dbName);
    pColInfoData = taosArrayGet(p->pDataBlock, 1);
    colDataAppend(pColInfoData, numOfRows, n, false);

    // create time
    pColInfoData = taosArrayGet(p->pDataBlock, 2);
    colDataAppendNULL(pColInfoData, numOfRows);

    // number of columns
    pColInfoData = taosArrayGet(p->pDataBlock, 3);
    colDataAppend(pColInfoData, numOfRows, (char*)&pm->colNum, false);

L
Liu Jicong 已提交
4170
    for (int32_t j = 4; j <= 8; ++j) {
4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185
      pColInfoData = taosArrayGet(p->pDataBlock, j);
      colDataAppendNULL(pColInfoData, numOfRows);
    }

    STR_TO_VARSTR(n, "SYSTEM_TABLE");

    pColInfoData = taosArrayGet(p->pDataBlock, 9);
    colDataAppend(pColInfoData, numOfRows, n, false);

    numOfRows += 1;
  }

  return numOfRows;
}

4186
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode,
4187
                                              const char* pUser, SExecTaskInfo* pTaskInfo) {
H
Haojun Liao 已提交
4188 4189 4190
  SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
  if (pInfo == NULL || pOperator == NULL) {
4191
    goto _error;
H
Haojun Liao 已提交
4192 4193
  }

H
Haojun Liao 已提交
4194
  SScanPhysiNode*     pScanNode = &pScanPhyNode->scan;
4195 4196 4197
  SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;

  int32_t num = 0;
H
Haojun Liao 已提交
4198
  int32_t code = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &num, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
H
Haojun Liao 已提交
4199 4200 4201
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4202

4203 4204
  pInfo->accountId = pScanPhyNode->accountId;
  pInfo->pUser = taosMemoryStrDup((void*)pUser);
4205
  pInfo->sysInfo = pScanPhyNode->sysInfo;
4206
  pInfo->showRewrite = pScanPhyNode->showRewrite;
H
Haojun Liao 已提交
4207
  pInfo->pRes = createResDataBlock(pDescNode);
4208

4209
  pInfo->pCondition = pScanNode->node.pConditions;
4210 4211 4212 4213
  code = filterInitFromNode(pScanNode->node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4214

4215
  initResultSizeInfo(&pOperator->resultInfo, 4096);
4216
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
H
Haojun Liao 已提交
4217

4218
  tNameAssign(&pInfo->name, &pScanNode->tableName);
4219
  const char* name = tNameGetTableName(&pInfo->name);
4220

D
dapan1121 已提交
4221 4222
  if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
      strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0) {
L
Liu Jicong 已提交
4223
    pInfo->readHandle = *(SReadHandle*)readHandle;
H
Haojun Liao 已提交
4224 4225
  } else {
    tsem_init(&pInfo->ready, 0, 0);
4226
    pInfo->epSet = pScanPhyNode->mgmtEpSet;
4227
    pInfo->readHandle = *(SReadHandle*)readHandle;
H
Haojun Liao 已提交
4228 4229
  }

L
Liu Jicong 已提交
4230 4231
  setOperatorInfo(pOperator, "SysTableScanOperator", QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN, false, OP_NOT_OPENED,
                  pInfo, pTaskInfo);
H
Haojun Liao 已提交
4232
  pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pRes->pDataBlock);
H
Haojun Liao 已提交
4233
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSysTableScan, NULL, destroySysScanOperator, NULL);
H
Haojun Liao 已提交
4234
  return pOperator;
4235

4236
_error:
H
Haojun Liao 已提交
4237 4238 4239
  if (pInfo != NULL) {
    destroySysScanOperator(pInfo);
  }
4240
  taosMemoryFreeClear(pOperator);
4241
  pTaskInfo->code = code;
4242
  return NULL;
H
Haojun Liao 已提交
4243
}
H
Haojun Liao 已提交
4244

4245
static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
H
Haojun Liao 已提交
4246 4247 4248 4249
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

4250 4251 4252
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;

  STagScanInfo* pInfo = pOperator->info;
4253
  SExprInfo*    pExprInfo = &pOperator->exprSupp.pExprInfo[0];
4254
  SSDataBlock*  pRes = pInfo->pRes;
4255
  blockDataCleanup(pRes);
H
Haojun Liao 已提交
4256

H
Haojun Liao 已提交
4257
  int32_t size = tableListGetSize(pTaskInfo->pTableInfoList);
wmmhello's avatar
wmmhello 已提交
4258
  if (size == 0) {
H
Haojun Liao 已提交
4259 4260 4261 4262
    setTaskStatus(pTaskInfo, TASK_COMPLETED);
    return NULL;
  }

4263 4264 4265
  char        str[512] = {0};
  int32_t     count = 0;
  SMetaReader mr = {0};
4266
  metaReaderInit(&mr, pInfo->readHandle.meta, 0);
H
Haojun Liao 已提交
4267

wmmhello's avatar
wmmhello 已提交
4268
  while (pInfo->curPos < size && count < pOperator->resultInfo.capacity) {
H
Haojun Liao 已提交
4269
    STableKeyInfo* item = tableListGetInfo(pInfo->pTableList, pInfo->curPos);
L
Liu Jicong 已提交
4270
    int32_t        code = metaGetTableEntryByUid(&mr, item->uid);
4271
    tDecoderClear(&mr.coder);
H
Haojun Liao 已提交
4272
    if (code != TSDB_CODE_SUCCESS) {
L
Liu Jicong 已提交
4273 4274
      qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", item->uid, tstrerror(terrno),
             GET_TASKID(pTaskInfo));
H
Haojun Liao 已提交
4275
      metaReaderClear(&mr);
4276
      T_LONG_JMP(pTaskInfo->env, terrno);
H
Haojun Liao 已提交
4277
    }
H
Haojun Liao 已提交
4278

4279
    for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) {
4280 4281 4282 4283 4284 4285
      SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId);

      // refactor later
      if (fmIsScanPseudoColumnFunc(pExprInfo[j].pExpr->_function.functionId)) {
        STR_TO_VARSTR(str, mr.me.name);
        colDataAppend(pDst, count, str, false);
4286
      } else {  // it is a tag value
wmmhello's avatar
wmmhello 已提交
4287 4288
        STagVal val = {0};
        val.cid = pExprInfo[j].base.pParam[0].pCol->colId;
4289
        const char* p = metaGetTableTagVal(mr.me.ctbEntry.pTags, pDst->info.type, &val);
wmmhello's avatar
wmmhello 已提交
4290

4291 4292 4293 4294
        char* data = NULL;
        if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL) {
          data = tTagValToData((const STagVal*)p, false);
        } else {
wmmhello's avatar
wmmhello 已提交
4295 4296
          data = (char*)p;
        }
L
Liu Jicong 已提交
4297 4298
        colDataAppend(pDst, count, data,
                      (data == NULL) || (pDst->info.type == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(data)));
4299

4300 4301
        if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL && IS_VAR_DATA_TYPE(((const STagVal*)p)->type) &&
            data != NULL) {
wmmhello's avatar
wmmhello 已提交
4302
          taosMemoryFree(data);
wmmhello's avatar
wmmhello 已提交
4303
        }
H
Haojun Liao 已提交
4304 4305 4306
      }
    }

4307
    count += 1;
wmmhello's avatar
wmmhello 已提交
4308
    if (++pInfo->curPos >= size) {
H
Haojun Liao 已提交
4309
      setOperatorCompleted(pOperator);
H
Haojun Liao 已提交
4310 4311 4312
    }
  }

4313 4314
  metaReaderClear(&mr);

4315
  // qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_TASKID(pRuntimeEnv), count);
H
Haojun Liao 已提交
4316
  if (pOperator->status == OP_EXEC_DONE) {
4317
    setTaskStatus(pTaskInfo, TASK_COMPLETED);
H
Haojun Liao 已提交
4318 4319 4320
  }

  pRes->info.rows = count;
wmmhello's avatar
wmmhello 已提交
4321
  pOperator->resultInfo.totalRows += count;
4322

4323
  return (pRes->info.rows == 0) ? NULL : pInfo->pRes;
H
Haojun Liao 已提交
4324 4325
}

4326
static void destroyTagScanOperatorInfo(void* param) {
H
Haojun Liao 已提交
4327 4328
  STagScanInfo* pInfo = (STagScanInfo*)param;
  pInfo->pRes = blockDataDestroy(pInfo->pRes);
H
Haojun Liao 已提交
4329
  taosArrayDestroy(pInfo->matchInfo.pList);
D
dapan1121 已提交
4330
  taosMemoryFreeClear(param);
H
Haojun Liao 已提交
4331 4332
}

4333 4334
SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode,
                                         STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo) {
4335
  STagScanInfo*  pInfo = taosMemoryCalloc(1, sizeof(STagScanInfo));
H
Haojun Liao 已提交
4336 4337 4338 4339 4340
  SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }

4341 4342 4343 4344
  SDataBlockDescNode* pDescNode = pPhyNode->node.pOutputDataBlockDesc;

  int32_t    numOfExprs = 0;
  SExprInfo* pExprInfo = createExprInfo(pPhyNode->pScanPseudoCols, NULL, &numOfExprs);
4345
  int32_t    code = initExprSupp(&pOperator->exprSupp, pExprInfo, numOfExprs);
4346 4347 4348
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4349

H
Haojun Liao 已提交
4350 4351
  int32_t num = 0;
  code = extractColMatchInfo(pPhyNode->pScanPseudoCols, pDescNode, &num, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
4352 4353 4354
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4355

4356 4357 4358 4359
  pInfo->pTableList = pTableListInfo;
  pInfo->pRes = createResDataBlock(pDescNode);
  pInfo->readHandle = *pReadHandle;
  pInfo->curPos = 0;
4360

L
Liu Jicong 已提交
4361 4362
  setOperatorInfo(pOperator, "TagScanOperator", QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN, false, OP_NOT_OPENED, pInfo,
                  pTaskInfo);
4363
  initResultSizeInfo(&pOperator->resultInfo, 4096);
4364 4365
  blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);

H
Haojun Liao 已提交
4366
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTagScan, NULL, destroyTagScanOperatorInfo, NULL);
H
Haojun Liao 已提交
4367 4368

  return pOperator;
4369

4370
_error:
H
Haojun Liao 已提交
4371 4372 4373 4374 4375
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  terrno = TSDB_CODE_OUT_OF_MEMORY;
  return NULL;
}
4376

H
Haojun Liao 已提交
4377
// todo refactor
4378
static int32_t loadDataBlockFromOneTable(SOperatorInfo* pOperator, STableMergeScanInfo* pTableScanInfo,
H
Haojun Liao 已提交
4379
                                         SSDataBlock* pBlock, uint32_t* status) {
L
Liu Jicong 已提交
4380
  SExecTaskInfo*       pTaskInfo = pOperator->pTaskInfo;
S
shenglian zhou 已提交
4381
  STableMergeScanInfo* pInfo = pOperator->info;
4382 4383 4384 4385 4386 4387 4388

  SFileBlockLoadRecorder* pCost = &pTableScanInfo->readRecorder;

  pCost->totalBlocks += 1;
  pCost->totalRows += pBlock->info.rows;

  *status = pInfo->dataBlockLoadFlag;
H
Haojun Liao 已提交
4389
  if (pOperator->exprSupp.pFilterInfo != NULL ||
4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407
      overlapWithTimeWindow(&pTableScanInfo->interval, &pBlock->info, pTableScanInfo->cond.order)) {
    (*status) = FUNC_DATA_REQUIRED_DATA_LOAD;
  }

  SDataBlockInfo* pBlockInfo = &pBlock->info;
  taosMemoryFreeClear(pBlock->pBlockAgg);

  if (*status == FUNC_DATA_REQUIRED_FILTEROUT) {
    qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
           pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
    pCost->filterOutBlocks += 1;
    return TSDB_CODE_SUCCESS;
  } else if (*status == FUNC_DATA_REQUIRED_NOT_LOAD) {
    qDebug("%s data block skipped, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
           pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
    pCost->skipBlocks += 1;

    // clear all data in pBlock that are set when handing the previous block
4408
    for (int32_t i = 0; i < taosArrayGetSize(pBlock->pDataBlock); ++i) {
4409 4410 4411 4412 4413
      SColumnInfoData* pcol = taosArrayGet(pBlock->pDataBlock, i);
      pcol->pData = NULL;
    }

    return TSDB_CODE_SUCCESS;
H
Haojun Liao 已提交
4414
  } else if (*status == FUNC_DATA_REQUIRED_SMA_LOAD) {
4415 4416 4417 4418 4419 4420
    pCost->loadBlockStatis += 1;

    bool             allColumnsHaveAgg = true;
    SColumnDataAgg** pColAgg = NULL;

    if (allColumnsHaveAgg == true) {
4421
      int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
4422 4423 4424 4425 4426 4427 4428

      // todo create this buffer during creating operator
      if (pBlock->pBlockAgg == NULL) {
        pBlock->pBlockAgg = taosMemoryCalloc(numOfCols, POINTER_BYTES);
      }

      for (int32_t i = 0; i < numOfCols; ++i) {
H
Haojun Liao 已提交
4429 4430
        SColMatchItem* pColMatchInfo = taosArrayGet(pTableScanInfo->matchInfo.pList, i);
        if (!pColMatchInfo->needOutput) {
4431 4432
          continue;
        }
H
Haojun Liao 已提交
4433
        pBlock->pBlockAgg[pColMatchInfo->dstSlotId] = pColAgg[i];
4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445
      }

      return TSDB_CODE_SUCCESS;
    } else {  // failed to load the block sma data, data block statistics does not exist, load data block instead
      *status = FUNC_DATA_REQUIRED_DATA_LOAD;
    }
  }

  ASSERT(*status == FUNC_DATA_REQUIRED_DATA_LOAD);

  // todo filter data block according to the block sma data firstly
#if 0
H
Haojun Liao 已提交
4446
  if (!doFilterByBlockSMA(pBlock->pBlockStatis, pTableScanInfo->pCtx, pBlockInfo->rows)) {
4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457
    pCost->filterOutBlocks += 1;
    qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo), pBlockInfo->window.skey,
           pBlockInfo->window.ekey, pBlockInfo->rows);
    (*status) = FUNC_DATA_REQUIRED_FILTEROUT;
    return TSDB_CODE_SUCCESS;
  }
#endif

  pCost->totalCheckedRows += pBlock->info.rows;
  pCost->loadBlocks += 1;

4458
  STsdbReader* reader = pTableScanInfo->pReader;
4459 4460 4461 4462 4463
  SArray*      pCols = tsdbRetrieveDataBlock(reader, NULL);
  if (pCols == NULL) {
    return terrno;
  }

H
Haojun Liao 已提交
4464
  relocateColumnData(pBlock, pTableScanInfo->matchInfo.pList, pCols, true);
4465 4466

  // currently only the tbname pseudo column
H
Haojun Liao 已提交
4467 4468 4469
  SExprSupp* pSup = &pTableScanInfo->pseudoSup;

  int32_t code = addTagPseudoColumnData(&pTableScanInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pBlock,
4470
                                        pBlock->info.rows, GET_TASKID(pTaskInfo), NULL);
H
Haojun Liao 已提交
4471 4472
  if (code != TSDB_CODE_SUCCESS) {
    T_LONG_JMP(pTaskInfo->env, code);
4473 4474
  }

4475
  if (pOperator->exprSupp.pFilterInfo != NULL) {
4476
    int64_t st = taosGetTimestampMs();
H
Haojun Liao 已提交
4477
    doFilter(pBlock, pOperator->exprSupp.pFilterInfo, &pTableScanInfo->matchInfo);
4478

4479 4480
    double el = (taosGetTimestampUs() - st) / 1000.0;
    pTableScanInfo->readRecorder.filterTime += el;
4481

4482 4483 4484 4485 4486 4487 4488
    if (pBlock->info.rows == 0) {
      pCost->filterOutBlocks += 1;
      qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d, elapsed time:%.2f ms",
             GET_TASKID(pTaskInfo), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, el);
    } else {
      qDebug("%s data block filter applied, elapsed time:%.2f ms", GET_TASKID(pTaskInfo), el);
    }
4489 4490 4491 4492 4493
  }

  return TSDB_CODE_SUCCESS;
}

dengyihao's avatar
dengyihao 已提交
4494
static SSDataBlock* getTableDataBlockImpl(void* param) {
dengyihao's avatar
opt mem  
dengyihao 已提交
4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507
  STableMergeScanSortSourceParam* source = param;
  SOperatorInfo*                  pOperator = source->pOperator;
  STableMergeScanInfo*            pInfo = pOperator->info;
  SExecTaskInfo*                  pTaskInfo = pOperator->pTaskInfo;
  int32_t                         readIdx = source->readerIdx;
  SSDataBlock*                    pBlock = source->inputBlock;
  STableMergeScanInfo*            pTableScanInfo = pOperator->info;

  SQueryTableDataCond* pQueryCond = taosArrayGet(pTableScanInfo->queryConds, readIdx);
  blockDataCleanup(pBlock);

  int64_t st = taosGetTimestampUs();

5
54liuyao 已提交
4508
  void*        p = tableListGetInfo(pInfo->tableListInfo, readIdx + pInfo->tableStartIndex);
dengyihao's avatar
opt mem  
dengyihao 已提交
4509
  SReadHandle* pHandle = &pInfo->readHandle;
dengyihao's avatar
dengyihao 已提交
4510 4511 4512

  int32_t code = tsdbReaderOpen(pHandle->vnode, pQueryCond, p, 1, &pInfo->pReader, GET_TASKID(pTaskInfo));
  if (code != 0) {
H
Haojun Liao 已提交
4513
    T_LONG_JMP(pTaskInfo->env, code);
dengyihao's avatar
dengyihao 已提交
4514
  }
dengyihao's avatar
opt mem  
dengyihao 已提交
4515 4516 4517

  STsdbReader* reader = pInfo->pReader;
  while (tsdbNextDataBlock(reader)) {
H
Haojun Liao 已提交
4518 4519
    if (isTaskKilled(pTaskInfo)) {
      T_LONG_JMP(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED);
dengyihao's avatar
opt mem  
dengyihao 已提交
4520 4521 4522 4523 4524 4525 4526 4527 4528 4529
    }

    // process this data block based on the probabilities
    bool processThisBlock = processBlockWithProbability(&pTableScanInfo->sample);
    if (!processThisBlock) {
      continue;
    }

    blockDataCleanup(pBlock);

H
Haojun Liao 已提交
4530 4531 4532 4533
    int32_t rows = 0;
    tsdbRetrieveDataBlockInfo(reader, &rows, &pBlock->info.uid, &pBlock->info.window);
    blockDataEnsureCapacity(pBlock, rows);
    pBlock->info.rows = rows;
dengyihao's avatar
opt mem  
dengyihao 已提交
4534

H
Haojun Liao 已提交
4535
    if (pQueryCond->order == TSDB_ORDER_ASC) {
dengyihao's avatar
opt mem  
dengyihao 已提交
4536 4537 4538 4539
      pQueryCond->twindows.skey = pBlock->info.window.ekey + 1;
    } else {
      pQueryCond->twindows.ekey = pBlock->info.window.skey - 1;
    }
dengyihao's avatar
opt mem  
dengyihao 已提交
4540 4541

    uint32_t status = 0;
H
Haojun Liao 已提交
4542
    code = loadDataBlockFromOneTable(pOperator, pTableScanInfo, pBlock, &status);
dengyihao's avatar
opt mem  
dengyihao 已提交
4543
    if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4544
      T_LONG_JMP(pTaskInfo->env, code);
dengyihao's avatar
opt mem  
dengyihao 已提交
4545 4546 4547 4548 4549 4550 4551
    }

    // current block is filter out according to filter condition, continue load the next block
    if (status == FUNC_DATA_REQUIRED_FILTEROUT || pBlock->info.rows == 0) {
      continue;
    }

H
Haojun Liao 已提交
4552
    pBlock->info.groupId = getTableGroupId(pTaskInfo->pTableInfoList, pBlock->info.uid);
dengyihao's avatar
opt mem  
dengyihao 已提交
4553

H
Haojun Liao 已提交
4554
    pOperator->resultInfo.totalRows += pBlock->info.rows;
dengyihao's avatar
opt mem  
dengyihao 已提交
4555 4556 4557
    pTableScanInfo->readRecorder.elapsedTime += (taosGetTimestampUs() - st) / 1000.0;

    tsdbReaderClose(pInfo->pReader);
dengyihao's avatar
opt mem  
dengyihao 已提交
4558
    pInfo->pReader = NULL;
dengyihao's avatar
opt mem  
dengyihao 已提交
4559 4560
    return pBlock;
  }
H
Haojun Liao 已提交
4561

dengyihao's avatar
opt mem  
dengyihao 已提交
4562
  tsdbReaderClose(pInfo->pReader);
dengyihao's avatar
opt mem  
dengyihao 已提交
4563
  pInfo->pReader = NULL;
dengyihao's avatar
opt mem  
dengyihao 已提交
4564 4565 4566
  return NULL;
}

4567 4568 4569
SArray* generateSortByTsInfo(SArray* colMatchInfo, int32_t order) {
  int32_t tsTargetSlotId = 0;
  for (int32_t i = 0; i < taosArrayGetSize(colMatchInfo); ++i) {
H
Haojun Liao 已提交
4570
    SColMatchItem* colInfo = taosArrayGet(colMatchInfo, i);
4571
    if (colInfo->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
H
Haojun Liao 已提交
4572
      tsTargetSlotId = colInfo->dstSlotId;
4573 4574 4575
    }
  }

4576 4577 4578
  SArray*         pList = taosArrayInit(1, sizeof(SBlockOrderInfo));
  SBlockOrderInfo bi = {0};
  bi.order = order;
4579
  bi.slotId = tsTargetSlotId;
4580 4581 4582 4583 4584 4585 4586
  bi.nullFirst = NULL_ORDER_FIRST;

  taosArrayPush(pList, &bi);

  return pList;
}

dengyihao's avatar
opt mem  
dengyihao 已提交
4587 4588 4589 4590 4591 4592 4593 4594
int32_t dumpSQueryTableCond(const SQueryTableDataCond* src, SQueryTableDataCond* dst) {
  memcpy((void*)dst, (void*)src, sizeof(SQueryTableDataCond));
  dst->colList = taosMemoryCalloc(src->numOfCols, sizeof(SColumnInfo));
  for (int i = 0; i < src->numOfCols; i++) {
    dst->colList[i] = src->colList[i];
  }
  return 0;
}
H
Haojun Liao 已提交
4595

4596
int32_t startGroupTableMergeScan(SOperatorInfo* pOperator) {
4597 4598 4599
  STableMergeScanInfo* pInfo = pOperator->info;
  SExecTaskInfo*       pTaskInfo = pOperator->pTaskInfo;

S
slzhou 已提交
4600
  {
H
Haojun Liao 已提交
4601
    size_t  numOfTables = tableListGetSize(pInfo->tableListInfo);
S
slzhou 已提交
4602
    int32_t i = pInfo->tableStartIndex + 1;
H
Haojun Liao 已提交
4603 4604
    for (; i < numOfTables; ++i) {
      STableKeyInfo* tableKeyInfo = tableListGetInfo(pInfo->tableListInfo, i);
S
slzhou 已提交
4605 4606 4607 4608 4609 4610
      if (tableKeyInfo->groupId != pInfo->groupId) {
        break;
      }
    }
    pInfo->tableEndIndex = i - 1;
  }
4611

S
slzhou 已提交
4612 4613
  int32_t tableStartIdx = pInfo->tableStartIndex;
  int32_t tableEndIdx = pInfo->tableEndIndex;
4614

dengyihao's avatar
opt mem  
dengyihao 已提交
4615
  pInfo->pReader = NULL;
4616

4617 4618
  // todo the total available buffer should be determined by total capacity of buffer of this task.
  // the additional one is reserved for merge result
S
slzhou 已提交
4619
  pInfo->sortBufSize = pInfo->bufPageSize * (tableEndIdx - tableStartIdx + 1 + 1);
4620
  int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
L
Liu Jicong 已提交
4621 4622
  pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage,
                                             pInfo->pSortInputBlock, pTaskInfo->id.str);
4623

dengyihao's avatar
dengyihao 已提交
4624
  tsortSetFetchRawDataFp(pInfo->pSortHandle, getTableDataBlockImpl, NULL, NULL);
dengyihao's avatar
opt mem  
dengyihao 已提交
4625 4626 4627 4628 4629 4630

  // one table has one data block
  int32_t numOfTable = tableEndIdx - tableStartIdx + 1;
  pInfo->queryConds = taosArrayInit(numOfTable, sizeof(SQueryTableDataCond));

  for (int32_t i = 0; i < numOfTable; ++i) {
4631 4632 4633 4634 4635
    STableMergeScanSortSourceParam param = {0};
    param.readerIdx = i;
    param.pOperator = pOperator;
    param.inputBlock = createOneDataBlock(pInfo->pResBlock, false);
    taosArrayPush(pInfo->sortSourceParams, &param);
dengyihao's avatar
opt mem  
dengyihao 已提交
4636 4637 4638 4639

    SQueryTableDataCond cond;
    dumpSQueryTableCond(&pInfo->cond, &cond);
    taosArrayPush(pInfo->queryConds, &cond);
4640 4641
  }

dengyihao's avatar
opt mem  
dengyihao 已提交
4642
  for (int32_t i = 0; i < numOfTable; ++i) {
4643
    SSortSource*                    ps = taosMemoryCalloc(1, sizeof(SSortSource));
4644
    STableMergeScanSortSourceParam* param = taosArrayGet(pInfo->sortSourceParams, i);
4645 4646 4647 4648 4649 4650 4651
    ps->param = param;
    tsortAddSource(pInfo->pSortHandle, ps);
  }

  int32_t code = tsortOpen(pInfo->pSortHandle);

  if (code != TSDB_CODE_SUCCESS) {
4652
    T_LONG_JMP(pTaskInfo->env, terrno);
4653 4654
  }

4655 4656 4657 4658 4659 4660 4661
  return TSDB_CODE_SUCCESS;
}

int32_t stopGroupTableMergeScan(SOperatorInfo* pOperator) {
  STableMergeScanInfo* pInfo = pOperator->info;
  SExecTaskInfo*       pTaskInfo = pOperator->pTaskInfo;

dengyihao's avatar
dengyihao 已提交
4662
  int32_t numOfTable = taosArrayGetSize(pInfo->queryConds);
4663

4664 4665 4666 4667 4668 4669 4670
  SSortExecInfo sortExecInfo = tsortGetSortExecInfo(pInfo->pSortHandle);
  pInfo->sortExecInfo.sortMethod = sortExecInfo.sortMethod;
  pInfo->sortExecInfo.sortBuffer = sortExecInfo.sortBuffer;
  pInfo->sortExecInfo.loops += sortExecInfo.loops;
  pInfo->sortExecInfo.readBytes += sortExecInfo.readBytes;
  pInfo->sortExecInfo.writeBytes += sortExecInfo.writeBytes;

dengyihao's avatar
dengyihao 已提交
4671
  for (int32_t i = 0; i < numOfTable; ++i) {
4672 4673 4674
    STableMergeScanSortSourceParam* param = taosArrayGet(pInfo->sortSourceParams, i);
    blockDataDestroy(param->inputBlock);
  }
4675 4676
  taosArrayClear(pInfo->sortSourceParams);

4677 4678
  tsortDestroySortHandle(pInfo->pSortHandle);

dengyihao's avatar
opt mem  
dengyihao 已提交
4679 4680 4681
  for (int32_t i = 0; i < taosArrayGetSize(pInfo->queryConds); i++) {
    SQueryTableDataCond* cond = taosArrayGet(pInfo->queryConds, i);
    taosMemoryFree(cond->colList);
4682
  }
dengyihao's avatar
opt mem  
dengyihao 已提交
4683 4684 4685
  taosArrayDestroy(pInfo->queryConds);
  pInfo->queryConds = NULL;

4686 4687 4688
  return TSDB_CODE_SUCCESS;
}

L
Liu Jicong 已提交
4689 4690
SSDataBlock* getSortedTableMergeScanBlockData(SSortHandle* pHandle, SSDataBlock* pResBlock, int32_t capacity,
                                              SOperatorInfo* pOperator) {
4691 4692 4693
  STableMergeScanInfo* pInfo = pOperator->info;
  SExecTaskInfo*       pTaskInfo = pOperator->pTaskInfo;

4694
  blockDataCleanup(pResBlock);
4695 4696

  while (1) {
4697
    STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
4698 4699 4700 4701
    if (pTupleHandle == NULL) {
      break;
    }

4702 4703
    appendOneRowToDataBlock(pResBlock, pTupleHandle);
    if (pResBlock->info.rows >= capacity) {
4704 4705 4706 4707
      break;
    }
  }

4708
  qDebug("%s get sorted row blocks, rows:%d", GET_TASKID(pTaskInfo), pResBlock->info.rows);
4709 4710 4711
  applyLimitOffset(&pInfo->limitInfo, pResBlock, pTaskInfo, pOperator);
  pInfo->limitInfo.numOfOutputRows += pResBlock->info.rows;

4712
  return (pResBlock->info.rows > 0) ? pResBlock : NULL;
4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724
}

SSDataBlock* doTableMergeScan(SOperatorInfo* pOperator) {
  if (pOperator->status == OP_EXEC_DONE) {
    return NULL;
  }

  SExecTaskInfo*       pTaskInfo = pOperator->pTaskInfo;
  STableMergeScanInfo* pInfo = pOperator->info;

  int32_t code = pOperator->fpSet._openFn(pOperator);
  if (code != TSDB_CODE_SUCCESS) {
4725
    T_LONG_JMP(pTaskInfo->env, code);
4726
  }
4727

H
Haojun Liao 已提交
4728
  size_t tableListSize = tableListGetSize(pInfo->tableListInfo);
S
slzhou 已提交
4729 4730
  if (!pInfo->hasGroupId) {
    pInfo->hasGroupId = true;
4731

S
slzhou 已提交
4732
    if (tableListSize == 0) {
H
Haojun Liao 已提交
4733
      setOperatorCompleted(pOperator);
4734 4735
      return NULL;
    }
S
slzhou 已提交
4736
    pInfo->tableStartIndex = 0;
H
Haojun Liao 已提交
4737
    pInfo->groupId = ((STableKeyInfo*)tableListGetInfo(pInfo->tableListInfo, pInfo->tableStartIndex))->groupId;
4738 4739
    startGroupTableMergeScan(pOperator);
  }
4740

S
slzhou 已提交
4741 4742
  SSDataBlock* pBlock = NULL;
  while (pInfo->tableStartIndex < tableListSize) {
L
Liu Jicong 已提交
4743 4744
    pBlock = getSortedTableMergeScanBlockData(pInfo->pSortHandle, pInfo->pResBlock, pOperator->resultInfo.capacity,
                                              pOperator);
S
slzhou 已提交
4745 4746 4747 4748 4749 4750 4751
    if (pBlock != NULL) {
      pBlock->info.groupId = pInfo->groupId;
      pOperator->resultInfo.totalRows += pBlock->info.rows;
      return pBlock;
    } else {
      stopGroupTableMergeScan(pOperator);
      if (pInfo->tableEndIndex >= tableListSize - 1) {
H
Haojun Liao 已提交
4752
        setOperatorCompleted(pOperator);
S
slzhou 已提交
4753 4754 4755
        break;
      }
      pInfo->tableStartIndex = pInfo->tableEndIndex + 1;
H
Haojun Liao 已提交
4756
      pInfo->groupId = tableListGetInfo(pInfo->tableListInfo, pInfo->tableStartIndex)->groupId;
S
slzhou 已提交
4757 4758
      startGroupTableMergeScan(pOperator);
    }
wmmhello's avatar
wmmhello 已提交
4759 4760
  }

4761 4762 4763
  return pBlock;
}

4764
void destroyTableMergeScanOperatorInfo(void* param) {
4765
  STableMergeScanInfo* pTableScanInfo = (STableMergeScanInfo*)param;
4766
  cleanupQueryTableDataCond(&pTableScanInfo->cond);
4767

dengyihao's avatar
dengyihao 已提交
4768 4769 4770
  int32_t numOfTable = taosArrayGetSize(pTableScanInfo->queryConds);

  for (int32_t i = 0; i < numOfTable; i++) {
H
Haojun Liao 已提交
4771 4772
    STableMergeScanSortSourceParam* p = taosArrayGet(pTableScanInfo->sortSourceParams, i);
    blockDataDestroy(p->inputBlock);
4773
  }
H
Haojun Liao 已提交
4774

4775
  taosArrayDestroy(pTableScanInfo->sortSourceParams);
4776

dengyihao's avatar
opt mem  
dengyihao 已提交
4777
  tsdbReaderClose(pTableScanInfo->pReader);
dengyihao's avatar
dengyihao 已提交
4778
  pTableScanInfo->pReader = NULL;
dengyihao's avatar
opt mem  
dengyihao 已提交
4779

dengyihao's avatar
opt mem  
dengyihao 已提交
4780 4781 4782
  for (int i = 0; i < taosArrayGetSize(pTableScanInfo->queryConds); i++) {
    SQueryTableDataCond* pCond = taosArrayGet(pTableScanInfo->queryConds, i);
    taosMemoryFree(pCond->colList);
4783
  }
dengyihao's avatar
opt mem  
dengyihao 已提交
4784
  taosArrayDestroy(pTableScanInfo->queryConds);
4785

H
Haojun Liao 已提交
4786 4787
  if (pTableScanInfo->matchInfo.pList != NULL) {
    taosArrayDestroy(pTableScanInfo->matchInfo.pList);
4788 4789 4790 4791 4792 4793
  }

  pTableScanInfo->pResBlock = blockDataDestroy(pTableScanInfo->pResBlock);
  pTableScanInfo->pSortInputBlock = blockDataDestroy(pTableScanInfo->pSortInputBlock);

  taosArrayDestroy(pTableScanInfo->pSortInfo);
4794
  cleanupExprSupp(&pTableScanInfo->pseudoSup);
L
Liu Jicong 已提交
4795

4796
  taosMemoryFreeClear(pTableScanInfo->rowEntryInfoOffset);
D
dapan1121 已提交
4797
  taosMemoryFreeClear(param);
4798 4799 4800 4801
}

int32_t getTableMergeScanExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
  ASSERT(pOptr != NULL);
4802 4803
  // TODO: merge these two info into one struct
  STableMergeScanExecInfo* execInfo = taosMemoryCalloc(1, sizeof(STableMergeScanExecInfo));
L
Liu Jicong 已提交
4804
  STableMergeScanInfo*     pInfo = pOptr->info;
4805
  execInfo->blockRecorder = pInfo->readRecorder;
4806
  execInfo->sortExecInfo = pInfo->sortExecInfo;
4807 4808 4809

  *pOptrExplain = execInfo;
  *len = sizeof(STableMergeScanExecInfo);
L
Liu Jicong 已提交
4810

4811 4812 4813
  return TSDB_CODE_SUCCESS;
}

4814
SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, STableListInfo* pTableListInfo,
4815
                                                SReadHandle* readHandle, SExecTaskInfo* pTaskInfo) {
4816 4817 4818 4819 4820
  STableMergeScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableMergeScanInfo));
  SOperatorInfo*       pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
  if (pInfo == NULL || pOperator == NULL) {
    goto _error;
  }
4821

4822 4823 4824
  SDataBlockDescNode* pDescNode = pTableScanNode->scan.node.pOutputDataBlockDesc;

  int32_t numOfCols = 0;
4825 4826
  int32_t code = extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID,
                                     &pInfo->matchInfo);
H
Haojun Liao 已提交
4827 4828 4829
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }
4830

H
Haojun Liao 已提交
4831
  code = initQueryTableDataCond(&pInfo->cond, pTableScanNode);
4832
  if (code != TSDB_CODE_SUCCESS) {
H
Haojun Liao 已提交
4833
    taosArrayDestroy(pInfo->matchInfo.pList);
4834 4835 4836 4837
    goto _error;
  }

  if (pTableScanNode->scan.pScanPseudoCols != NULL) {
4838 4839 4840
    SExprSupp* pSup = &pInfo->pseudoSup;
    pSup->pExprInfo = createExprInfo(pTableScanNode->scan.pScanPseudoCols, NULL, &pSup->numOfExprs);
    pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset);
4841 4842 4843 4844
  }

  pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]};

L
Liu Jicong 已提交
4845 4846
  pInfo->readHandle = *readHandle;
  pInfo->interval = extractIntervalInfo(pTableScanNode);
4847
  pInfo->sample.sampleRatio = pTableScanNode->ratio;
L
Liu Jicong 已提交
4848 4849
  pInfo->sample.seed = taosGetTimestampSec();
  pInfo->dataBlockLoadFlag = pTableScanNode->dataRequired;
H
Haojun Liao 已提交
4850 4851 4852 4853 4854 4855

  code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
  if (code != TSDB_CODE_SUCCESS) {
    goto _error;
  }

4856
  pInfo->tableListInfo = pTableListInfo;
L
Liu Jicong 已提交
4857
  pInfo->scanFlag = MAIN_SCAN;
4858

H
Haojun Liao 已提交
4859
  initResultSizeInfo(&pOperator->resultInfo, 1024);
4860
  pInfo->pResBlock = createResDataBlock(pDescNode);
H
Haojun Liao 已提交
4861 4862
  blockDataEnsureCapacity(pInfo->pResBlock, pOperator->resultInfo.capacity);

4863
  pInfo->sortSourceParams = taosArrayInit(64, sizeof(STableMergeScanSortSourceParam));
4864

H
Haojun Liao 已提交
4865
  pInfo->pSortInfo = generateSortByTsInfo(pInfo->matchInfo.pList, pInfo->cond.order);
4866
  pInfo->pSortInputBlock = createOneDataBlock(pInfo->pResBlock, false);
4867
  initLimitInfo(pTableScanNode->scan.node.pLimit, pTableScanNode->scan.node.pSlimit, &pInfo->limitInfo);
4868

4869
  int32_t rowSize = pInfo->pResBlock->info.rowSize;
A
Alex Duan 已提交
4870 4871
  uint32_t nCols = taosArrayGetSize(pInfo->pResBlock->pDataBlock);
  pInfo->bufPageSize = getProperSortPageSize(rowSize, nCols);
4872

L
Liu Jicong 已提交
4873 4874
  setOperatorInfo(pOperator, "TableMergeScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN, false, OP_NOT_OPENED,
                  pInfo, pTaskInfo);
L
Liu Jicong 已提交
4875
  pOperator->exprSupp.numOfExprs = numOfCols;
4876

L
Liu Jicong 已提交
4877 4878
  pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableMergeScan, NULL, destroyTableMergeScanOperatorInfo,
                                         getTableMergeScanExplainExecInfo);
4879 4880 4881 4882 4883 4884 4885 4886 4887
  pOperator->cost.openCost = 0;
  return pOperator;

_error:
  pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
  taosMemoryFree(pInfo);
  taosMemoryFree(pOperator);
  return NULL;
}