• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #5011

03 Apr 2026 03:59PM UTC coverage: 72.3% (+0.008%) from 72.292%
#5011

push

travis-ci

web-flow
merge: from main to 3.0 branch #35067

4053 of 5985 new or added lines in 68 files covered. (67.72%)

732 existing lines in 143 files now uncovered.

257430 of 356056 relevant lines covered (72.3%)

131834103.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

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

16
#include "executorInt.h"
17
#include "filter.h"
18
#include "functionMgt.h"
19
#include "geosWrapper.h"
20
#include "nodes.h"
21
#include "osMemPool.h"
22
#include "querynodes.h"
23
#include "systable.h"
24
#include "tcommon.h"
25
#include "tdef.h"
26
#include "tname.h"
27

28
#include "tdatablock.h"
29
#include "tmsg.h"
30

31
#include "index.h"
32
#include "operator.h"
33
#include "query.h"
34
#include "querytask.h"
35
#include "storageapi.h"
36
#include "tcompare.h"
37
#include "thash.h"
38
#include "trpc.h"
39
#include "ttypes.h"
40
// RPC timeout for virtual table reference validation (5 seconds)
41
#define VTB_REF_RPC_TIMEOUT_MS 5000
42

43
typedef int (*__optSysFilter)(void* a, void* b, int16_t dtype);
44
typedef int32_t (*__sys_filte)(void* pMeta, SNode* cond, SArray* result);
45
typedef int32_t (*__sys_check)(SNode* cond);
46

47
typedef struct SSTabFltArg {
48
  void*        pMeta;
49
  void*        pVnode;
50
  SStorageAPI* pAPI;
51
} SSTabFltArg;
52

53
typedef struct SSysTableIndex {
54
  int8_t  init;
55
  SArray* uids;
56
  int32_t lastIdx;
57
} SSysTableIndex;
58

59
typedef struct {
60
  char vDbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE];
61
  char vStbName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE];
62
  char vTableName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE];
63

64
  char vColName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE];
65

66
  char    refDbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE];
67
  char    refStbName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE];
68
  char    refTableName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE];
69
  char    refColName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE];
70
  int8_t  type;
71
  int8_t  isValid;
72
  int32_t errCode;
73
  char    errMsg[64 + VARSTR_HEADER_SIZE];
74

75
} SVirtualTableRefInfo;
76

77
typedef struct SSysTableScanInfo {
78
  SRetrieveMetaTableRsp* pRsp;
79
  SRetrieveTableReq      req;
80
  SEpSet                 epSet;
81
  tsem_t                 ready;
82
  SReadHandle            readHandle;
83
  const char*            pUser;
84
  int32_t                accountId;
85
  bool                   sysInfo;
86
  bool                   showRewrite;
87
  bool                   restore;
88
  bool                   skipFilterTable;
89
  union {
90
    uint16_t privInfo;
91
    struct {
92
      uint16_t privLevel : 3;  // user privilege level
93
      uint16_t privInfoBasic : 1;
94
      uint16_t privInfoPrivileged : 1;
95
      uint16_t privInfoAudit : 1;
96
      uint16_t privInfoSec : 1;
97
      uint16_t privPerfBasic : 1;
98
      uint16_t privPerfPrivileged : 1;
99
      uint16_t reserved1 : 7;
100
    };
101
  };
102
  SNode*              pCondition;  // db_name filter condition, to discard data that are not in current database
103
  SMTbCursor*         pCur;        // cursor for iterate the local table meta store.
104
  SSysTableIndex*     pIdx;        // idx for local table meta
105
  SHashObj*           pSchema;
106
  SColMatchInfo       matchInfo;
107
  SName               name;
108
  SSDataBlock*        pRes;
109
  int64_t             numOfBlocks;  // extract basic running information.
110
  SLoadRemoteDataInfo loadInfo;
111
  SLimitInfo          limitInfo;
112
  int32_t             tbnameSlotId;
113
  STableListInfo*     pTableListInfo;
114
  SReadHandle*        pHandle;
115
  SStorageAPI*        pAPI;
116

117
  // file set iterate
118
  struct SFileSetReader* pFileSetReader;
119
  SHashObj*              pExtSchema;
120

121
  // for virtual supertable scan
122
  STableListInfo* pSubTableListInfo;
123
} SSysTableScanInfo;
124

125
typedef struct {
126
  const char* name;
127
  __sys_check chkFunc;
128
  __sys_filte fltFunc;
129
} SSTabFltFuncDef;
130

131
typedef struct MergeIndex {
132
  int idx;
133
  int len;
134
} MergeIndex;
135

136
typedef struct SBlockDistInfo {
137
  SSDataBlock*    pResBlock;
138
  STsdbReader*    pHandle;
139
  SReadHandle     readHandle;
140
  STableListInfo* pTableListInfo;
141
  uint64_t        uid;  // table uid
142
} SBlockDistInfo;
143

144
typedef struct {
145
  int8_t   type;
146
  tb_uid_t uid;
147
} STableId;
148

149
static int32_t sysChkFilter__Comm(SNode* pNode);
150
static int32_t sysChkFilter__DBName(SNode* pNode);
151
static int32_t sysChkFilter__VgroupId(SNode* pNode);
152
static int32_t sysChkFilter__TableName(SNode* pNode);
153
static int32_t sysChkFilter__CreateTime(SNode* pNode);
154
static int32_t sysChkFilter__Ncolumn(SNode* pNode);
155
static int32_t sysChkFilter__Ttl(SNode* pNode);
156
static int32_t sysChkFilter__STableName(SNode* pNode);
157
static int32_t sysChkFilter__Uid(SNode* pNode);
158
static int32_t sysChkFilter__Type(SNode* pNode);
159

160
static int32_t sysFilte__DbName(void* arg, SNode* pNode, SArray* result);
161
static int32_t sysFilte__VgroupId(void* arg, SNode* pNode, SArray* result);
162
static int32_t sysFilte__TableName(void* arg, SNode* pNode, SArray* result);
163
static int32_t sysFilte__CreateTime(void* arg, SNode* pNode, SArray* result);
164
static int32_t sysFilte__Ncolumn(void* arg, SNode* pNode, SArray* result);
165
static int32_t sysFilte__Ttl(void* arg, SNode* pNode, SArray* result);
166
static int32_t sysFilte__STableName(void* arg, SNode* pNode, SArray* result);
167
static int32_t sysFilte__Uid(void* arg, SNode* pNode, SArray* result);
168
static int32_t sysFilte__Type(void* arg, SNode* pNode, SArray* result);
169

170
const SSTabFltFuncDef filterDict[] = {
171
    {.name = "table_name", .chkFunc = sysChkFilter__TableName, .fltFunc = sysFilte__TableName},
172
    {.name = "db_name", .chkFunc = sysChkFilter__DBName, .fltFunc = sysFilte__DbName},
173
    {.name = "create_time", .chkFunc = sysChkFilter__CreateTime, .fltFunc = sysFilte__CreateTime},
174
    {.name = "columns", .chkFunc = sysChkFilter__Ncolumn, .fltFunc = sysFilte__Ncolumn},
175
    {.name = "ttl", .chkFunc = sysChkFilter__Ttl, .fltFunc = sysFilte__Ttl},
176
    {.name = "stable_name", .chkFunc = sysChkFilter__STableName, .fltFunc = sysFilte__STableName},
177
    {.name = "vgroup_id", .chkFunc = sysChkFilter__VgroupId, .fltFunc = sysFilte__VgroupId},
178
    {.name = "uid", .chkFunc = sysChkFilter__Uid, .fltFunc = sysFilte__Uid},
179
    {.name = "type", .chkFunc = sysChkFilter__Type, .fltFunc = sysFilte__Type}};
180

181
#define SYSTAB_FILTER_DICT_SIZE (sizeof(filterDict) / sizeof(filterDict[0]))
182

183
static int32_t buildDbTableInfoBlock(const SSysTableScanInfo* pInfo, const SSDataBlock* p,
184
                                     const SSysTableMeta* pSysDbTableMeta, size_t size, const char* dbName,
185
                                     int64_t* pRows);
186

187
static char* SYSTABLE_SPECIAL_COL[] = {"db_name", "vgroup_id"};
188

189
static int32_t        buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity);
190
static SSDataBlock*   buildInfoSchemaTableMetaBlock(char* tableName);
191
static void           destroySysScanOperator(void* param);
192
static int32_t        loadSysTableCallback(void* param, SDataBuf* pMsg, int32_t code);
193
static __optSysFilter optSysGetFilterFunc(int32_t ctype, bool* reverse, bool* equal);
194

195
static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo, SMetaReader* smrSuperTable,
196
                                                SMetaReader* smrChildTable, const char* dbname, const char* tableName,
197
                                                int32_t* pNumOfRows, const SSDataBlock* dataBlock);
198

199
static int32_t sysTableUserColsFillOneTableCols(const char* dbname, int32_t* pNumOfRows, const SSDataBlock* dataBlock,
200
                                                char* tName, SSchemaWrapper* schemaRow, SExtSchema* extSchemaRow,
201
                                                char* tableType, SColRefWrapper* colRef);
202

203
static int32_t sysTableUserColsFillOneVirtualTableCols(const SSysTableScanInfo* pInfo, const char* dbname,
204
                                                       int32_t* pNumOfRows, const SSDataBlock* dataBlock, char* tName,
205
                                                       char* stName, SSchemaWrapper* schemaRow, char* tableType,
206
                                                       SColRefWrapper* colRef, tb_uid_t uid, int32_t vgId);
207

208
// static int32_t sysTableFillOneVirtualTableRef(const SSysTableScanInfo* pInfo, const char* dbname, int32_t*
209
// pNumOfRows,
210
//                                               const SSDataBlock* dataBlock, char* tName, char* stName,
211
//                                               SSchemaWrapper* schemaRow, char* tableType, SColRefWrapper* colRef,
212
//                                               tb_uid_t uid, int32_t vgId);
213

214
static int32_t sysTableFillOneVirtualTableRefImpl(const SSysTableScanInfo* pInfo, SExecTaskInfo* pTaskInfo,
215
                                                  const char* dbname, int32_t* pNumOfRows, const SSDataBlock* dataBlock,
216
                                                  SSchemaWrapper* schemaRow, SColRefWrapper* pRefCol,
217
                                                  SVirtualTableRefInfo* pRef);
218

219
static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
220
                                               SFilterInfo* pFilterInfo, SExecTaskInfo* pTaskInfo);
221

222
static int32_t vnodeEstimateRawDataSize(SOperatorInfo* pOperator, SDbSizeStatisInfo* pStatisInfo);
223

224
int32_t sysFilte__DbName(void* arg, SNode* pNode, SArray* result) {
574,124✔
225
  SSTabFltArg* pArg = arg;
574,124✔
226
  void*        pVnode = pArg->pVnode;
574,124✔
227

228
  const char* db = NULL;
575,448✔
229
  pArg->pAPI->metaFn.getBasicInfo(pVnode, &db, NULL, NULL, NULL);
574,770✔
230

231
  SName   sn = {0};
574,802✔
232
  char    dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
574,802✔
233
  int32_t code = tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
574,802✔
234
  if (code != TSDB_CODE_SUCCESS) {
574,124✔
235
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
236
    return code;
×
237
  }
238

239
  code = tNameGetDbName(&sn, varDataVal(dbname));
574,124✔
240
  if (code != TSDB_CODE_SUCCESS) {
574,802✔
241
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
242
    return code;
×
243
  }
244
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
574,802✔
245

246
  SOperatorNode* pOper = (SOperatorNode*)pNode;
574,802✔
247
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
574,802✔
248

249
  bool           reverse = false;
574,124✔
250
  bool           equal = false;
573,446✔
251
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
574,092✔
252
  if (func == NULL) return -1;
574,124✔
253

254
  int ret = func(dbname, pVal->datum.p, TSDB_DATA_TYPE_VARCHAR);
574,124✔
255
  if (ret == 0) return 0;
574,802✔
256

257
  return -2;
656✔
258
}
259

260
int32_t sysFilte__VgroupId(void* arg, SNode* pNode, SArray* result) {
×
261
  SSTabFltArg* pArg = arg;
×
262
  void*        pVnode = ((SSTabFltArg*)arg)->pVnode;
×
263

264
  int64_t vgId = 0;
×
265
  pArg->pAPI->metaFn.getBasicInfo(pVnode, NULL, (int32_t*)&vgId, NULL, NULL);
×
266

267
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
268
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
269

270
  bool           reverse = false;
×
271
  bool           equal = false;
×
272
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
×
273
  if (func == NULL) return -1;
×
274

275
  int ret = func(&vgId, &pVal->datum.i, TSDB_DATA_TYPE_BIGINT);
×
276
  if (ret == 0) return 0;
×
277

278
  return -1;
×
279
}
280

281
int32_t sysFilte__TableName(void* arg, SNode* pNode, SArray* result) {
293,871✔
282
  SSTabFltArg* pArg = arg;
293,871✔
283

284
  SOperatorNode* pOper = (SOperatorNode*)pNode;
293,871✔
285
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
293,871✔
286

287
  bool           reverse = false, equal = false;
293,871✔
288
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
293,871✔
289
  if (func == NULL) return -1;
293,871✔
290

291
  SMetaFltParam param = {.suid = 0,
293,871✔
292
                         .cid = 0,
293
                         .type = TSDB_DATA_TYPE_VARCHAR,
294
                         .val = pVal->datum.p,
293,871✔
295
                         .reverse = reverse,
296
                         .equal = equal,
297
                         .filterFunc = func};
298
  return -1;
293,871✔
299
}
300

301
int32_t sysFilte__CreateTime(void* arg, SNode* pNode, SArray* result) {
1,736✔
302
  SSTabFltArg* pArg = arg;
1,736✔
303
  SStorageAPI* pAPI = pArg->pAPI;
1,736✔
304

305
  SOperatorNode* pOper = (SOperatorNode*)pNode;
1,736✔
306
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
1,736✔
307

308
  bool           reverse = false, equal = false;
1,736✔
309
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
1,736✔
310
  if (func == NULL) return -1;
1,736✔
311

312
  SMetaFltParam param = {.suid = 0,
3,472✔
313
                         .cid = 0,
314
                         .type = TSDB_DATA_TYPE_BIGINT,
315
                         .val = &pVal->datum.i,
1,736✔
316
                         .reverse = reverse,
317
                         .equal = equal,
318
                         .filterFunc = func};
319

320
  int32_t ret = pAPI->metaFilter.metaFilterCreateTime(pArg->pVnode, &param, result);
1,736✔
321
  return ret;
1,736✔
322
}
323

324
int32_t sysFilte__Ncolumn(void* arg, SNode* pNode, SArray* result) {
×
325
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
×
326

327
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
328
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
329
  bool           reverse = false;
×
330
  bool           equal = false;
×
331
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
×
332
  if (func == NULL) return -1;
×
333
  return -1;
×
334
}
335

336
int32_t sysFilte__Ttl(void* arg, SNode* pNode, SArray* result) {
×
337
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
×
338

339
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
340
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
341
  bool           reverse = false;
×
342
  bool           equal = false;
×
343
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
×
344
  if (func == NULL) return -1;
×
345
  return -1;
×
346
}
347

348
int32_t sysFilte__STableName(void* arg, SNode* pNode, SArray* result) {
7,505✔
349
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
7,505✔
350

351
  SOperatorNode* pOper = (SOperatorNode*)pNode;
7,505✔
352
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
7,505✔
353
  bool           reverse = false;
7,505✔
354
  bool           equal = false;
7,505✔
355
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
7,505✔
356
  if (func == NULL) return -1;
7,505✔
357
  return -1;
7,505✔
358
}
359

360
int32_t sysFilte__Uid(void* arg, SNode* pNode, SArray* result) {
×
361
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
×
362

363
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
364
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
365
  bool           reverse = false;
×
366
  bool           equal = false;
×
367
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
×
368
  if (func == NULL) return -1;
×
369
  return -1;
×
370
}
371

372
int32_t sysFilte__Type(void* arg, SNode* pNode, SArray* result) {
×
373
  void* pMeta = ((SSTabFltArg*)arg)->pMeta;
×
374

375
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
376
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
377
  bool           reverse = false;
×
378
  bool           equal = false;
×
379
  __optSysFilter func = optSysGetFilterFunc(pOper->opType, &reverse, &equal);
×
380
  if (func == NULL) return -1;
×
381
  return -1;
×
382
}
383

384
int optSysDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) {
6,616,554✔
385
  int32_t cmp = func(a, b);
6,616,554✔
386
  switch (comparType) {
6,613,306✔
387
    case OP_TYPE_LOWER_THAN:
4,400,964✔
388
      if (cmp < 0) return 0;
4,400,964✔
389
      break;
×
390
    case OP_TYPE_LOWER_EQUAL: {
×
391
      if (cmp <= 0) return 0;
×
392
      break;
×
393
    }
394
    case OP_TYPE_GREATER_THAN: {
1,640,000✔
395
      if (cmp > 0) return 0;
1,640,000✔
396
      break;
×
397
    }
398
    case OP_TYPE_GREATER_EQUAL: {
×
399
      if (cmp >= 0) return 0;
×
400
      break;
×
401
    }
402
    case OP_TYPE_EQUAL: {
574,146✔
403
      if (cmp == 0) return 0;
574,146✔
404
      break;
×
405
    }
406
    default:
×
407
      return -1;
×
408
  }
409
  return cmp;
×
410
}
411

412
static int optSysFilterFuncImpl__LowerThan(void* a, void* b, int16_t dtype) {
4,404,900✔
413
  __compar_fn_t func = getComparFunc(dtype, 0);
4,404,900✔
414
  if (func == NULL) {
4,401,620✔
415
    return -1;
×
416
  }
417
  return optSysDoCompare(func, OP_TYPE_LOWER_THAN, a, b);
4,401,620✔
418
}
419
static int optSysFilterFuncImpl__LowerEqual(void* a, void* b, int16_t dtype) {
×
420
  __compar_fn_t func = getComparFunc(dtype, 0);
×
421
  if (func == NULL) {
×
422
    return -1;
×
423
  }
424
  return optSysDoCompare(func, OP_TYPE_LOWER_EQUAL, a, b);
×
425
}
426
static int optSysFilterFuncImpl__GreaterThan(void* a, void* b, int16_t dtype) {
1,640,000✔
427
  __compar_fn_t func = getComparFunc(dtype, 0);
1,640,000✔
428
  if (func == NULL) {
1,640,000✔
429
    return -1;
×
430
  }
431
  return optSysDoCompare(func, OP_TYPE_GREATER_THAN, a, b);
1,640,000✔
432
}
433
static int optSysFilterFuncImpl__GreaterEqual(void* a, void* b, int16_t dtype) {
×
434
  __compar_fn_t func = getComparFunc(dtype, 0);
×
435
  if (func == NULL) {
×
436
    return -1;
×
437
  }
438
  return optSysDoCompare(func, OP_TYPE_GREATER_EQUAL, a, b);
×
439
}
440
static int optSysFilterFuncImpl__Equal(void* a, void* b, int16_t dtype) {
574,146✔
441
  __compar_fn_t func = getComparFunc(dtype, 0);
574,146✔
442
  if (func == NULL) {
573,436✔
443
    return -1;
×
444
  }
445
  return optSysDoCompare(func, OP_TYPE_EQUAL, a, b);
573,436✔
446
}
447

448
static int optSysFilterFuncImpl__NoEqual(void* a, void* b, int16_t dtype) {
656✔
449
  __compar_fn_t func = getComparFunc(dtype, 0);
656✔
450
  if (func == NULL) {
656✔
451
    return -1;
×
452
  }
453
  return optSysDoCompare(func, OP_TYPE_NOT_EQUAL, a, b);
656✔
454
}
455

456
static int32_t optSysTabFilte(void* arg, SNode* cond, SArray* result);
457
static int32_t optSysTabFilteImpl(void* arg, SNode* cond, SArray* result);
458
static int32_t optSysCheckOper(SNode* pOpear);
459
static int32_t optSysMergeRslt(SArray* mRslt, SArray* rslt);
460

461
static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableScanInfo* pInfo, const char* name,
462
                                          SExecTaskInfo* pTaskInfo);
463
void                extractTbnameSlotId(SSysTableScanInfo* pInfo, const SScanPhysiNode* pScanNode);
464

465
static void sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScanInfo* pInfo, const char* name,
466
                                   SSDataBlock* pBlock);
467

468
__optSysFilter optSysGetFilterFunc(int32_t ctype, bool* reverse, bool* equal) {
877,914✔
469
  if (ctype == OP_TYPE_LOWER_EQUAL || ctype == OP_TYPE_LOWER_THAN) {
877,914✔
470
    *reverse = true;
1,220✔
471
  }
472
  if (ctype == OP_TYPE_EQUAL) {
878,592✔
473
    *equal = true;
876,200✔
474
  }
475
  if (ctype == OP_TYPE_LOWER_THAN)
878,592✔
476
    return optSysFilterFuncImpl__LowerThan;
1,408✔
477
  else if (ctype == OP_TYPE_LOWER_EQUAL)
877,184✔
478
    return optSysFilterFuncImpl__LowerEqual;
×
479
  else if (ctype == OP_TYPE_GREATER_THAN)
877,184✔
480
    return optSysFilterFuncImpl__GreaterThan;
328✔
481
  else if (ctype == OP_TYPE_GREATER_EQUAL)
876,856✔
482
    return optSysFilterFuncImpl__GreaterEqual;
×
483
  else if (ctype == OP_TYPE_EQUAL)
876,856✔
484
    return optSysFilterFuncImpl__Equal;
876,200✔
485
  else if (ctype == OP_TYPE_NOT_EQUAL)
656✔
486
    return optSysFilterFuncImpl__NoEqual;
656✔
UNCOV
487
  return NULL;
×
488
}
489

490
static bool sysTableIsOperatorCondOnOneTable(SNode* pCond, char* condTable) {
7,512,120✔
491
  SOperatorNode* node = (SOperatorNode*)pCond;
7,512,120✔
492
  if (node->opType == OP_TYPE_EQUAL) {
7,512,120✔
493
    if (nodeType(node->pLeft) == QUERY_NODE_COLUMN &&
2,265,093✔
494
        strcasecmp(nodesGetNameFromColumnNode(node->pLeft), "table_name") == 0 &&
2,265,093✔
495
        nodeType(node->pRight) == QUERY_NODE_VALUE) {
×
496
      SValueNode* pValue = (SValueNode*)node->pRight;
×
497
      if (pValue->node.resType.type == TSDB_DATA_TYPE_NCHAR || pValue->node.resType.type == TSDB_DATA_TYPE_VARCHAR) {
×
498
        char* value = nodesGetValueFromNode(pValue);
1,060✔
499
        tstrncpy(condTable, varDataVal(value), TSDB_TABLE_NAME_LEN);
×
500
        return true;
×
501
      }
502
    }
503
  }
504
  return false;
7,512,120✔
505
}
506

507
static bool sysTableIsOperatorCondOnOneVTableName(SNode* pCond, char* condTable) {
143,868✔
508
  SOperatorNode* node = (SOperatorNode*)pCond;
143,868✔
509
  if (node->opType == OP_TYPE_EQUAL) {
143,868✔
510
    if (nodeType(node->pLeft) == QUERY_NODE_COLUMN &&
141,344✔
511
        strcasecmp(nodesGetNameFromColumnNode(node->pLeft), "virtual_table_name") == 0 &&
141,344✔
512
        nodeType(node->pRight) == QUERY_NODE_VALUE) {
×
513
      SValueNode* pValue = (SValueNode*)node->pRight;
×
514
      if (pValue->node.resType.type == TSDB_DATA_TYPE_NCHAR || pValue->node.resType.type == TSDB_DATA_TYPE_VARCHAR) {
×
515
        char* value = nodesGetValueFromNode(pValue);
×
516
        tstrncpy(condTable, varDataVal(value), TSDB_TABLE_NAME_LEN);
×
517
        return true;
×
518
      }
519
    }
520
  }
521
  return false;
143,868✔
522
}
523

524
static bool sysTableIsCondOnOneVTableName(SNode* pCond, char* condTable) {
73,196✔
525
  if (pCond == NULL) {
73,196✔
526
    return false;
×
527
  }
528
  if (nodeType(pCond) == QUERY_NODE_LOGIC_CONDITION) {
73,196✔
529
    SLogicConditionNode* node = (SLogicConditionNode*)pCond;
70,672✔
530
    if (LOGIC_COND_TYPE_AND == node->condType) {
70,672✔
531
      SNode* pChild = NULL;
70,672✔
532
      FOREACH(pChild, node->pParameterList) {
212,016✔
533
        if (QUERY_NODE_OPERATOR == nodeType(pChild) && sysTableIsOperatorCondOnOneVTableName(pChild, condTable)) {
141,344✔
534
          return true;
×
535
        }
536
      }
537
    }
538
  }
539

540
  if (QUERY_NODE_OPERATOR == nodeType(pCond)) {
73,196✔
541
    return sysTableIsOperatorCondOnOneVTableName(pCond, condTable);
2,524✔
542
  }
543

544
  return false;
70,672✔
545
}
546

547
static bool sysTableIsCondOnOneTable(SNode* pCond, char* condTable) {
6,630,426✔
548
  if (pCond == NULL) {
6,630,426✔
549
    return false;
3,368✔
550
  }
551
  if (nodeType(pCond) == QUERY_NODE_LOGIC_CONDITION) {
6,627,058✔
552
    SLogicConditionNode* node = (SLogicConditionNode*)pCond;
820,293✔
553
    if (LOGIC_COND_TYPE_AND == node->condType) {
820,293✔
554
      SNode* pChild = NULL;
820,293✔
555
      FOREACH(pChild, node->pParameterList) {
2,529,458✔
556
        if (QUERY_NODE_OPERATOR == nodeType(pChild) && sysTableIsOperatorCondOnOneTable(pChild, condTable)) {
1,709,165✔
557
          return true;
×
558
        }
559
      }
560
    }
561
  }
562

563
  if (QUERY_NODE_OPERATOR == nodeType(pCond)) {
6,627,588✔
564
    return sysTableIsOperatorCondOnOneTable(pCond, condTable);
5,806,235✔
565
  }
566

567
  return false;
820,293✔
568
}
569

570
static SSDataBlock* doOptimizeTableNameFilter(SOperatorInfo* pOperator, SSDataBlock* dataBlock, char* dbname) {
×
571
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
×
572
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
×
573
  SSysTableScanInfo* pInfo = pOperator->info;
×
574
  int32_t            numOfRows = 0;
×
575

576
  char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
577
  STR_TO_VARSTR(tableName, pInfo->req.filterTb);
×
578

579
  SMetaReader smrTable = {0};
×
580
  pAPI->metaReaderFn.initReader(&smrTable, pInfo->readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
×
581
  int32_t code = pAPI->metaReaderFn.getTableEntryByName(&smrTable, pInfo->req.filterTb);
×
582
  if (code != TSDB_CODE_SUCCESS) {
×
583
    // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
584
    pAPI->metaReaderFn.clearReader(&smrTable);
×
585
    pInfo->loadInfo.totalRows = 0;
×
586
    return NULL;
×
587
  }
588

589
  if (smrTable.me.type == TSDB_SUPER_TABLE) {
×
590
    pAPI->metaReaderFn.clearReader(&smrTable);
×
591
    pInfo->loadInfo.totalRows = 0;
×
592
    return NULL;
×
593
  }
594

595
  if (smrTable.me.type == TSDB_CHILD_TABLE) {
×
596
    int64_t suid = smrTable.me.ctbEntry.suid;
×
597
    pAPI->metaReaderFn.clearReader(&smrTable);
×
598
    pAPI->metaReaderFn.initReader(&smrTable, pInfo->readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
×
599
    code = pAPI->metaReaderFn.getTableEntryByUid(&smrTable, suid);
×
600
    if (code != TSDB_CODE_SUCCESS) {
×
601
      // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
602
      pAPI->metaReaderFn.clearReader(&smrTable);
×
603
      pInfo->loadInfo.totalRows = 0;
×
604
      return NULL;
×
605
    }
606
  }
607

608
  char            typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
609
  SSchemaWrapper* schemaRow = NULL;
×
610
  SExtSchema*     extSchemaRow = smrTable.me.pExtSchemas;
×
611
  SColRefWrapper* colRef = NULL;
×
612
  if (smrTable.me.type == TSDB_SUPER_TABLE) {
×
613
    schemaRow = &smrTable.me.stbEntry.schemaRow;
×
614
    STR_TO_VARSTR(typeName, "CHILD_TABLE");
×
615
  } else if (smrTable.me.type == TSDB_NORMAL_TABLE) {
×
616
    schemaRow = &smrTable.me.ntbEntry.schemaRow;
×
617
    STR_TO_VARSTR(typeName, "NORMAL_TABLE");
×
618
  } else if (smrTable.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
×
619
    schemaRow = &smrTable.me.ntbEntry.schemaRow;
×
620
    colRef = &smrTable.me.colRef;
×
621
    STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
×
622
  } else if (smrTable.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
×
623
    colRef = &smrTable.me.colRef;
×
624
    STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
×
625
  }
626

627
  code = sysTableUserColsFillOneTableCols(dbname, &numOfRows, dataBlock, tableName, schemaRow, extSchemaRow, typeName,
×
628
                                          colRef);
629
  if (code != TSDB_CODE_SUCCESS) {
×
630
    pAPI->metaReaderFn.clearReader(&smrTable);
×
631
    pInfo->loadInfo.totalRows = 0;
×
632
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
633
    pTaskInfo->code = code;
×
634
    T_LONG_JMP(pTaskInfo->env, code);
×
635
  }
636
  pAPI->metaReaderFn.clearReader(&smrTable);
×
637

638
  if (numOfRows > 0) {
×
639
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
×
640
    numOfRows = 0;
×
641
  }
642

643
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
×
644
  setOperatorCompleted(pOperator);
×
645

646
  qDebug("get cols success, total rows:%" PRIu64 ", current:%" PRId64 " %s", pInfo->loadInfo.totalRows,
×
647
         pInfo->pRes->info.rows, GET_TASKID(pTaskInfo));
648
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
×
649
}
650

651
static SSDataBlock* doOptimizeVTableNameFilter(SOperatorInfo* pOperator, SSDataBlock* dataBlock, char* dbname) {
×
652
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
×
653
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
×
654
  SSysTableScanInfo* pInfo = pOperator->info;
×
655
  int32_t            code = TSDB_CODE_SUCCESS;
×
656
  int32_t            lino = 0;
×
657
  int32_t            numOfRows = 0;
×
658

659
  char vtableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
660
  STR_TO_VARSTR(vtableName, pInfo->req.filterTb);
×
661

662
  SVirtualTableRefInfo* pVtableRefInfo = taosMemoryCalloc(1, sizeof(SVirtualTableRefInfo));
×
663
  if (pVtableRefInfo == NULL) {
×
664
    qError("%s failed at line %d since %s", __func__, __LINE__, terrstr());
×
665
    pTaskInfo->code = terrno;
×
666
    T_LONG_JMP(pTaskInfo->env, terrno);
×
667
  }
668

669
  memcpy(pVtableRefInfo->vDbName, dbname, TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE);
×
670

671
  SMetaReader smrTable = {0};
×
672
  SMetaReader smrSuperTable = {0};
×
673
  bool        smrTableInited = false;
×
674
  bool        smrSuperTableInited = false;
×
675

676
  pAPI->metaReaderFn.initReader(&smrTable, pInfo->readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
×
677
  smrTableInited = true;
×
678
  code = pAPI->metaReaderFn.getTableEntryByName(&smrTable, pInfo->req.filterTb);
×
679
  QUERY_CHECK_CODE(code, lino, _end);
×
680

681
  if (smrTable.me.type != TSDB_VIRTUAL_NORMAL_TABLE && smrTable.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
×
682
    pAPI->metaReaderFn.clearReader(&smrTable);
×
683
    smrTableInited = false;
×
684
    code = TSDB_CODE_SUCCESS;
×
685
    goto _end;
×
686
  }
687

688
  SSchemaWrapper* schemaRow = NULL;
×
689
  SColRefWrapper* colRef = NULL;
×
690

691
  if (smrTable.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
×
692
    schemaRow = &smrTable.me.ntbEntry.schemaRow;
×
693
    colRef = &smrTable.me.colRef;
×
694
    STR_TO_VARSTR(pVtableRefInfo->vStbName, smrTable.me.name);
×
695
    STR_TO_VARSTR(pVtableRefInfo->vTableName, smrTable.me.name);
×
696
    // Release the META_READER_LOCK before calling validateSrcTableColRef,
697
    // which may send RPCs that could deadlock if the lock is held.
698
    // The data (schemaRow, colRef) remains valid until clearReader is called.
699
    pAPI->metaReaderFn.readerReleaseLock(&smrTable);
×
700
  } else if (smrTable.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
×
701
    colRef = &smrTable.me.colRef;
×
702
    STR_TO_VARSTR(pVtableRefInfo->vTableName, smrTable.me.name);
×
703

704
    int64_t suid = smrTable.me.ctbEntry.suid;
×
705
    // Release lock but keep data valid (colRef still points to smrTable internal data)
706
    pAPI->metaReaderFn.readerReleaseLock(&smrTable);
×
707

708
    // Get super table info for virtual child table
709
    pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
×
710
    smrSuperTableInited = true;
×
711
    code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
×
712
    QUERY_CHECK_CODE(code, lino, _end);
×
713

714
    STR_TO_VARSTR(pVtableRefInfo->vStbName, smrSuperTable.me.name);
×
715
    schemaRow = &smrSuperTable.me.stbEntry.schemaRow;
×
716

717
    // Release lock but keep data valid for sysTableFillOneVirtualTableRefImpl
718
    pAPI->metaReaderFn.readerReleaseLock(&smrSuperTable);
×
719
  }
720

721
  if (schemaRow != NULL && schemaRow->pSchema == NULL) {
×
722
    qWarn("doOptimizeVTableNameFilter: vstb schema pSchema is NULL for table %s, returning empty", pInfo->req.filterTb);
×
723
    schemaRow = NULL;
×
724
  }
725

726
  if (schemaRow == NULL) {
×
727
    goto _end;
×
728
  }
729

730
  code = sysTableFillOneVirtualTableRefImpl(pInfo, pTaskInfo, dbname, &numOfRows, dataBlock, schemaRow, colRef,
×
731
                                            pVtableRefInfo);
732
  QUERY_CHECK_CODE(code, lino, _end);
×
733

734
  if (numOfRows > 0) {
×
735
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
×
736
    numOfRows = 0;
×
737
  }
738

739
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
×
740
  setOperatorCompleted(pOperator);
×
741

742
  qDebug("get virtual table ref success, total rows:%" PRIu64 ", current:%" PRId64 " %s", pInfo->loadInfo.totalRows,
×
743
         pInfo->pRes->info.rows, GET_TASKID(pTaskInfo));
744

745
_end:
×
746
  if (smrTableInited) {
×
747
    pAPI->metaReaderFn.clearReader(&smrTable);
×
748
  }
749
  if (smrSuperTableInited) {
×
750
    pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
751
  }
752
  taosMemoryFreeClear(pVtableRefInfo);
×
753
  if (code != TSDB_CODE_SUCCESS) {
×
754
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
755
    pTaskInfo->code = code;
×
756
    T_LONG_JMP(pTaskInfo->env, code);
×
757
  }
758
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
×
759
}
760

761
int32_t doExtractDbName(char* dbname, SSysTableScanInfo* pInfo, SStorageAPI* pAPI) {
18,314,584✔
762
  int32_t     code = TSDB_CODE_SUCCESS;
18,314,584✔
763
  int32_t     lino = 0;
18,314,584✔
764
  SName       sn = {0};
18,314,584✔
765
  const char* db = NULL;
18,315,238✔
766
  int32_t     vgId = 0;
18,315,847✔
767
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, &db, &vgId, NULL, NULL);
18,315,847✔
768
  code = tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
18,316,457✔
769
  QUERY_CHECK_CODE(code, lino, _end);
18,314,011✔
770

771
  code = tNameGetDbName(&sn, varDataVal(dbname));
18,314,011✔
772
  QUERY_CHECK_CODE(code, lino, _end);
18,312,285✔
773

774
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
18,312,285✔
775

776
_end:
18,314,011✔
777
  if (code != TSDB_CODE_SUCCESS) {
18,316,457✔
778
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
779
  }
780
  return code;
18,316,457✔
781
}
782

783
static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
4,760,257✔
784
  int32_t            code = TSDB_CODE_SUCCESS;
4,760,257✔
785
  int32_t            lino = 0;
4,760,257✔
786
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
4,760,257✔
787
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
4,760,787✔
788
  SSysTableScanInfo* pInfo = pOperator->info;
4,760,257✔
789
  int32_t            numOfRows = 0;
4,761,847✔
790
  int32_t            ret = 0;
4,761,847✔
791
  char               dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
4,761,847✔
792
  SSDataBlock*       pDataBlock = NULL;
4,761,317✔
793

794
  if (pOperator->status == OP_EXEC_DONE) {
4,761,317✔
795
    return NULL;
1,191,268✔
796
  }
797

798
  blockDataCleanup(pInfo->pRes);
3,569,519✔
799

800
  pDataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_COLS);
3,570,579✔
801
  QUERY_CHECK_NULL(pDataBlock, code, lino, _end, terrno);
3,570,579✔
802

803
  code = blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
3,570,579✔
804
  QUERY_CHECK_CODE(code, lino, _end);
3,570,579✔
805

806
  code = doExtractDbName(dbname, pInfo, pAPI);
3,570,579✔
807
  QUERY_CHECK_CODE(code, lino, _end);
3,570,579✔
808

809
  // optimize when sql like where table_name='tablename' and xxx.
810
  if (pInfo->req.filterTb[0]) {
3,570,579✔
811
    SSDataBlock* p = doOptimizeTableNameFilter(pOperator, pDataBlock, dbname);
×
812
    blockDataDestroy(pDataBlock);
×
813
    return p;
×
814
  }
815

816
  if (pInfo->pCur == NULL) {
3,570,579✔
817
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
3,568,671✔
818
  } else {
819
    code = pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0);
1,908✔
820
    if (code != 0) {
1,908✔
821
      pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
822
      pInfo->pCur = NULL;
×
823
      QUERY_CHECK_CODE(code, lino, _end);
×
824
    }
825
  }
826

827
  if (pInfo->pSchema == NULL) {
3,570,579✔
828
    pInfo->pSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
3,567,611✔
829
    taosHashSetFreeFp(pInfo->pSchema, tDeleteSSchemaWrapperForHash);
3,567,611✔
830
  }
831
  if (pInfo->pExtSchema == NULL) {
3,570,579✔
832
    pInfo->pExtSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
3,567,611✔
833
  }
834

835
  if (!pInfo->pCur || !pInfo->pSchema || !pInfo->pExtSchema) {
3,571,639✔
836
    qError("sysTableScanUserCols failed since %s", terrstr());
530✔
837
    blockDataDestroy(pDataBlock);
530✔
838
    pInfo->loadInfo.totalRows = 0;
×
839
    return NULL;
×
840
  }
841

842
  while (((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0)) {
59,607,219✔
843
    char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
56,036,958✔
844
    char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
56,038,548✔
845

846
    SSchemaWrapper* schemaRow = NULL;
56,038,018✔
847
    SExtSchema*     extSchemaRow = NULL;
56,038,018✔
848
    SColRefWrapper* colRef = NULL;
56,038,018✔
849

850
    if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
56,038,018✔
851
      qDebug("sysTableScanUserCols cursor get super table, %s", GET_TASKID(pTaskInfo));
3,635,493✔
852
      void* schema = taosHashGet(pInfo->pSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t));
3,635,493✔
853
      if (schema == NULL) {
3,635,493✔
854
        SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&pInfo->pCur->mr.me.stbEntry.schemaRow);
894,406✔
855
        if (pInfo->pCur->mr.me.stbEntry.schemaRow.pSchema) {
894,406✔
856
          QUERY_CHECK_NULL(schemaWrapper, code, lino, _end, terrno);
894,406✔
857
        }
858
        code = taosHashPut(pInfo->pSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
894,406✔
859
        if (code == TSDB_CODE_DUP_KEY) {
894,406✔
860
          code = TSDB_CODE_SUCCESS;
×
861
        }
862
        QUERY_CHECK_CODE(code, lino, _end);
894,406✔
863
      }
864

865
      void* pExtSchema = taosHashGet(pInfo->pExtSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t));
3,635,493✔
866
      if (pExtSchema == NULL) {
3,635,493✔
867
        SExtSchema* pExtSchema = pInfo->pCur->mr.me.pExtSchemas;
894,406✔
868
        code = taosHashPut(pInfo->pExtSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t), pExtSchema,
894,406✔
869
                           pInfo->pCur->mr.me.stbEntry.schemaRow.nCols * sizeof(SExtSchema));
894,406✔
870
        if (code == TSDB_CODE_DUP_KEY) {
894,406✔
871
          code = TSDB_CODE_SUCCESS;
×
872
        }
873
        QUERY_CHECK_CODE(code, lino, _end);
894,406✔
874
      }
875

876
      continue;
3,635,493✔
877
    } else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
52,403,055✔
878
      qDebug("sysTableScanUserCols cursor get child table, %s", GET_TASKID(pTaskInfo));
49,924,365✔
879

880
      STR_TO_VARSTR(typeName, "CHILD_TABLE");
49,924,895✔
881
      STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
49,924,895✔
882
      int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
49,924,895✔
883
      void*   schema = taosHashGet(pInfo->pSchema, &suid, sizeof(int64_t));
49,924,895✔
884
      void*   pExtSchema = taosHashGet(pInfo->pExtSchema, &suid, sizeof(int64_t));
49,924,895✔
885
      if (schema != NULL && pExtSchema != NULL) {
49,924,895✔
886
        schemaRow = *(SSchemaWrapper**)schema;
47,197,342✔
887
        extSchemaRow = (SExtSchema*)pExtSchema;
47,197,342✔
888
      } else {
889
        SMetaReader smrSuperTable = {0};
2,727,553✔
890
        pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
2,727,553✔
891
        code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
2,727,553✔
892
        if (code != TSDB_CODE_SUCCESS) {
2,727,553✔
893
          // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
894
          qError("sysTableScanUserCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
×
895
                 GET_TASKID(pTaskInfo));
896

897
          pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
898
          blockDataDestroy(pDataBlock);
×
899
          pInfo->loadInfo.totalRows = 0;
×
900
          return NULL;
×
901
        }
902
        SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&smrSuperTable.me.stbEntry.schemaRow);
2,727,553✔
903
        if (smrSuperTable.me.stbEntry.schemaRow.pSchema) {
2,727,553✔
904
          if (schemaWrapper == NULL) {
2,727,553✔
905
            code = terrno;
×
906
            lino = __LINE__;
×
907
            pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
908
            goto _end;
×
909
          }
910
        }
911
        code = taosHashPut(pInfo->pSchema, &suid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
2,727,553✔
912
        if (code == TSDB_CODE_DUP_KEY) {
2,727,553✔
913
          code = TSDB_CODE_SUCCESS;
×
914
        }
915
        SExtSchema* pExtSchema = smrSuperTable.me.pExtSchemas;
2,727,553✔
916
        code = taosHashPut(pInfo->pExtSchema, &suid, sizeof(int64_t), pExtSchema,
2,727,553✔
917
                           smrSuperTable.me.stbEntry.schemaRow.nCols * sizeof(SExtSchema));
2,727,553✔
918
        if (code == TSDB_CODE_DUP_KEY) {
2,727,553✔
919
          code = TSDB_CODE_SUCCESS;
×
920
        }
921
        schemaRow = schemaWrapper;
2,727,553✔
922
        extSchemaRow = taosHashGet(pInfo->pExtSchema, &suid, sizeof(int64_t));
2,727,553✔
923
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
2,727,553✔
924
        QUERY_CHECK_CODE(code, lino, _end);
2,727,553✔
925
      }
926
    } else if (pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE) {
2,477,630✔
927
      qDebug("sysTableScanUserCols cursor get normal table, %s", GET_TASKID(pTaskInfo));
2,406,357✔
928
      schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
2,406,357✔
929
      extSchemaRow = pInfo->pCur->mr.me.pExtSchemas;
2,407,947✔
930
      STR_TO_VARSTR(typeName, "NORMAL_TABLE");
2,407,947✔
931
      STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
2,407,947✔
932
    } else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
71,273✔
933
      qDebug("sysTableScanUserCols cursor get virtual normal table, %s", GET_TASKID(pTaskInfo));
39,371✔
934
      schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
39,371✔
935
      extSchemaRow = pInfo->pCur->mr.me.pExtSchemas;
39,371✔
936
      STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
39,371✔
937
      STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
39,371✔
938
      colRef = &pInfo->pCur->mr.me.colRef;
39,371✔
939
    } else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
31,902✔
940
      qDebug("sysTableScanUserCols cursor get virtual child table, %s", GET_TASKID(pTaskInfo));
31,902✔
941

942
      STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
31,902✔
943
      STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
31,902✔
944

945
      colRef = &pInfo->pCur->mr.me.colRef;
31,902✔
946
      int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
31,902✔
947
      void*   schema = taosHashGet(pInfo->pSchema, &suid, sizeof(int64_t));
31,902✔
948
      void*   pExtSchema = taosHashGet(pInfo->pExtSchema, &suid, sizeof(int64_t));
31,902✔
949
      if (schema != NULL && pExtSchema != NULL) {
31,902✔
950
        schemaRow = *(SSchemaWrapper**)schema;
18,368✔
951
        extSchemaRow = (SExtSchema*)pExtSchema;
18,368✔
952
      } else {
953
        SMetaReader smrSuperTable = {0};
13,534✔
954
        pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
13,534✔
955
        code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
13,534✔
956
        if (code != TSDB_CODE_SUCCESS) {
13,534✔
957
          // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
958
          qError("sysTableScanUserCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
×
959
                 GET_TASKID(pTaskInfo));
960

961
          pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
962
          blockDataDestroy(pDataBlock);
×
963
          pInfo->loadInfo.totalRows = 0;
×
964
          return NULL;
×
965
        }
966
        SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&smrSuperTable.me.stbEntry.schemaRow);
13,534✔
967
        if (smrSuperTable.me.stbEntry.schemaRow.pSchema) {
13,534✔
968
          if (schemaWrapper == NULL) {
13,534✔
969
            code = terrno;
×
970
            lino = __LINE__;
×
971
            pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
972
            goto _end;
×
973
          }
974
        }
975
        code = taosHashPut(pInfo->pSchema, &suid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
13,534✔
976
        if (code == TSDB_CODE_DUP_KEY) {
13,534✔
977
          code = TSDB_CODE_SUCCESS;
×
978
        }
979
        SExtSchema* pExtSchema = smrSuperTable.me.pExtSchemas;
13,534✔
980
        code = taosHashPut(pInfo->pExtSchema, &suid, sizeof(int64_t), pExtSchema,
13,534✔
981
                           smrSuperTable.me.stbEntry.schemaRow.nCols * sizeof(SExtSchema));
13,534✔
982
        if (code == TSDB_CODE_DUP_KEY) {
13,534✔
983
          code = TSDB_CODE_SUCCESS;
×
984
        }
985
        schemaRow = schemaWrapper;
13,534✔
986
        extSchemaRow = taosHashGet(pInfo->pExtSchema, &suid, sizeof(int64_t));
13,534✔
987
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
13,534✔
988
        QUERY_CHECK_CODE(code, lino, _end);
13,534✔
989
      }
990
    } else {
991
      qDebug("sysTableScanUserCols cursor get invalid table, %s", GET_TASKID(pTaskInfo));
×
992
      continue;
×
993
    }
994

995
    if ((numOfRows + schemaRow->nCols) > pOperator->resultInfo.capacity) {
52,404,115✔
996
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, pDataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
5,724✔
997
      numOfRows = 0;
5,724✔
998

999
      if (pInfo->pRes->info.rows > 0) {
5,724✔
1000
        pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
1,908✔
1001
        break;
1,908✔
1002
      }
1003
    }
1004
    // if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock
1005
    code = sysTableUserColsFillOneTableCols(dbname, &numOfRows, pDataBlock, tableName, schemaRow, extSchemaRow,
52,401,677✔
1006
                                            typeName, colRef);
1007
    QUERY_CHECK_CODE(code, lino, _end);
52,401,147✔
1008
  }
1009

1010
  if (numOfRows > 0) {
3,570,579✔
1011
    pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
3,567,543✔
1012
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, pDataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
3,567,013✔
1013
    numOfRows = 0;
3,567,543✔
1014
  }
1015

1016
  blockDataDestroy(pDataBlock);
3,570,579✔
1017
  pDataBlock = NULL;
3,569,519✔
1018
  if (ret != 0) {
3,569,519✔
1019
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
3,567,611✔
1020
    pInfo->pCur = NULL;
3,565,491✔
1021
    setOperatorCompleted(pOperator);
3,566,551✔
1022
  }
1023

1024
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
3,569,519✔
1025
  qDebug("get cols success, rows:%" PRIu64 " %s", pInfo->loadInfo.totalRows, GET_TASKID(pTaskInfo));
3,570,049✔
1026

1027
_end:
3,570,579✔
1028
  if (code != TSDB_CODE_SUCCESS) {
3,570,579✔
1029
    blockDataDestroy(pDataBlock);
×
1030
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1031
    pTaskInfo->code = code;
×
1032
    T_LONG_JMP(pTaskInfo->env, code);
×
1033
  }
1034
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
3,570,579✔
1035
}
1036

1037
static bool virtualChildTableNeedCollect(STableListInfo* pTableListInfo, tb_uid_t tableUid) {
18,332,138✔
1038
  for (int32_t i = 0; i < taosArrayGetSize(pTableListInfo->pTableList); i++) {
39,720,882✔
1039
    tb_uid_t* childUid = taosArrayGet(pTableListInfo->pTableList, i);
31,934,918✔
1040
    if (childUid == NULL) {
31,934,334✔
1041
      return false;
×
1042
    }
1043
    if (*childUid == tableUid) {
31,934,334✔
1044
      return true;
10,545,590✔
1045
    }
1046
  }
1047
  return false;
7,787,171✔
1048
}
1049

1050
static SSDataBlock* sysTableScanUserVcCols(SOperatorInfo* pOperator) {
19,204,968✔
1051
  int32_t            code = TSDB_CODE_SUCCESS;
19,204,968✔
1052
  int32_t            lino = 0;
19,204,968✔
1053
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
19,204,968✔
1054
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
19,209,717✔
1055
  SSysTableScanInfo* pInfo = pOperator->info;
19,207,851✔
1056
  int32_t            numOfRows = 0;
19,206,705✔
1057
  int32_t            ret = 0;
19,207,852✔
1058
  char               dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
19,207,852✔
1059
  SSDataBlock*       pDataBlock = NULL;
19,207,948✔
1060

1061
  if (pOperator->status == OP_EXEC_DONE) {
19,207,948✔
1062
    return NULL;
4,541,767✔
1063
  }
1064

1065
  blockDataCleanup(pInfo->pRes);
14,660,873✔
1066

1067
  pDataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_VC_COLS);
14,670,158✔
1068
  QUERY_CHECK_NULL(pDataBlock, code, lino, _end, terrno);
14,667,870✔
1069

1070
  code = blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
14,667,870✔
1071
  QUERY_CHECK_CODE(code, lino, _end);
14,669,548✔
1072

1073
  code = doExtractDbName(dbname, pInfo, pAPI);
14,669,548✔
1074
  QUERY_CHECK_CODE(code, lino, _end);
14,666,624✔
1075

1076
  // optimize when sql like where table_name='tablename' and xxx.
1077
  if (pInfo->req.filterTb[0]) {
14,666,624✔
1078
    SSDataBlock* p = doOptimizeTableNameFilter(pOperator, pDataBlock, dbname);
×
1079
    blockDataDestroy(pDataBlock);
×
1080
    return p;
×
1081
  }
1082

1083
  if (pInfo->pCur == NULL) {
14,667,822✔
1084
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
14,668,433✔
1085
  } else {
1086
    code = pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0);
579✔
1087
    if (code != 0) {
579✔
1088
      pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
1089
      pInfo->pCur = NULL;
×
1090
      QUERY_CHECK_CODE(code, lino, _end);
×
1091
    }
1092
  }
1093

1094
  if (pInfo->pSchema == NULL) {
14,667,177✔
1095
    pInfo->pSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
14,664,815✔
1096
    taosHashSetFreeFp(pInfo->pSchema, tDeleteSSchemaWrapperForHash);
14,663,157✔
1097
  }
1098

1099
  if (!pInfo->pCur || !pInfo->pSchema) {
14,659,726✔
1100
    qError("sysTableScanUserVcCols failed since %s", terrstr());
2,955✔
1101
    blockDataDestroy(pDataBlock);
2,955✔
1102
    pInfo->loadInfo.totalRows = 0;
×
1103
    return NULL;
×
1104
  }
1105

1106
  while (((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0)) {
272,259,602✔
1107
    char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
257,392,653✔
1108
    char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
257,327,560✔
1109
    char stableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
257,430,716✔
1110

1111
    SSchemaWrapper* schemaRow = NULL;
257,425,030✔
1112
    SColRefWrapper* colRef = NULL;
257,425,030✔
1113

1114
    if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
257,425,030✔
1115
      continue;
19,241,954✔
1116
    } else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
238,361,841✔
1117
      continue;
106,966,795✔
1118
    } else if (pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE) {
131,414,415✔
1119
      continue;
106,816,850✔
1120
    } else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
24,584,537✔
1121
      qDebug("sysTableScanUserVcCols cursor get virtual normal table, %s", GET_TASKID(pTaskInfo));
6,250,608✔
1122

1123
      STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
6,250,608✔
1124
      STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
6,251,776✔
1125
      STR_TO_VARSTR(stableName, pInfo->pCur->mr.me.name);
6,251,163✔
1126

1127
      colRef = &pInfo->pCur->mr.me.colRef;
6,251,243✔
1128
      schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
6,251,192✔
1129
    } else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
18,332,131✔
1130
      qDebug("sysTableScanUserVcCols cursor get virtual child table, %s", GET_TASKID(pTaskInfo));
18,330,241✔
1131

1132
      STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
18,334,021✔
1133
      STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
18,332,761✔
1134
      if (!virtualChildTableNeedCollect(pInfo->pSubTableListInfo, pInfo->pCur->mr.me.uid)) {
18,332,138✔
1135
        qDebug("skip virtual child table:%s uid:%" PRId64 " %s", varDataVal(tableName), pInfo->pCur->mr.me.uid,
7,787,171✔
1136
               GET_TASKID(pTaskInfo));
1137
        continue;
7,787,171✔
1138
      }
1139
      colRef = &pInfo->pCur->mr.me.colRef;
10,545,590✔
1140
      int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
10,545,590✔
1141
      void*   schema = taosHashGet(pInfo->pSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
10,545,590✔
1142
      if (schema != NULL) {
10,544,977✔
1143
        schemaRow = *(SSchemaWrapper**)schema;
6,437,012✔
1144
        SMetaReader smrSuperTable = {0};
6,437,012✔
1145
        pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
6,437,012✔
1146
        code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
6,437,012✔
1147
        if (code != TSDB_CODE_SUCCESS) {
6,437,012✔
1148
          // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
1149
          qError("sysTableScanUserVcCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
×
1150
                 GET_TASKID(pTaskInfo));
1151

1152
          pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1153
          blockDataDestroy(pDataBlock);
×
1154
          pInfo->loadInfo.totalRows = 0;
×
1155
          return NULL;
×
1156
        }
1157
        STR_TO_VARSTR(stableName, smrSuperTable.me.name);
6,437,012✔
1158
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
6,437,012✔
1159
      } else {
1160
        SMetaReader smrSuperTable = {0};
4,107,965✔
1161
        pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
4,108,578✔
1162
        code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
4,108,578✔
1163
        if (code != TSDB_CODE_SUCCESS) {
4,108,578✔
1164
          // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
1165
          qError("sysTableScanUserVcCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
×
1166
                 GET_TASKID(pTaskInfo));
1167

1168
          pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1169
          blockDataDestroy(pDataBlock);
×
1170
          pInfo->loadInfo.totalRows = 0;
×
1171
          return NULL;
×
1172
        }
1173
        STR_TO_VARSTR(stableName, smrSuperTable.me.name);
4,108,578✔
1174
        SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&smrSuperTable.me.stbEntry.schemaRow);
4,108,578✔
1175
        if (smrSuperTable.me.stbEntry.schemaRow.pSchema) {
4,107,990✔
1176
          if (schemaWrapper == NULL) {
4,108,578✔
1177
            code = terrno;
×
1178
            lino = __LINE__;
×
1179
            pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1180
            goto _end;
×
1181
          }
1182
        }
1183
        code = taosHashPut(pInfo->pSchema, &suid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
4,107,990✔
1184
        if (code == TSDB_CODE_DUP_KEY) {
4,108,578✔
1185
          code = TSDB_CODE_SUCCESS;
×
1186
        }
1187
        schemaRow = schemaWrapper;
4,108,578✔
1188
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
4,108,578✔
1189
        QUERY_CHECK_CODE(code, lino, _end);
4,107,990✔
1190
      }
1191
    } else {
1192
      qDebug("sysTableScanUserVcCols cursor get invalid table, %s", GET_TASKID(pTaskInfo));
×
1193
      continue;
×
1194
    }
1195

1196
    if ((numOfRows + schemaRow->nCols) > pOperator->resultInfo.capacity) {
16,796,169✔
1197
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, pDataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
579✔
1198
      numOfRows = 0;
579✔
1199

1200
      if (pInfo->pRes->info.rows > 0) {
579✔
1201
        pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
579✔
1202
        break;
579✔
1203
      }
1204
    }
1205
    // if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock
1206
    code = sysTableUserColsFillOneVirtualTableCols(pInfo, dbname, &numOfRows, pDataBlock, tableName, stableName,
33,592,372✔
1207
                                                   schemaRow, typeName, colRef, pInfo->pCur->mr.me.uid,
16,796,203✔
1208
                                                   pOperator->pTaskInfo->id.vgId);
16,795,641✔
1209
    QUERY_CHECK_CODE(code, lino, _end);
16,795,531✔
1210
  }
1211

1212
  if (numOfRows > 0) {
14,668,990✔
1213
    pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
4,541,767✔
1214
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, pDataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
4,540,574✔
1215
    numOfRows = 0;
4,541,767✔
1216
  }
1217

1218
  blockDataDestroy(pDataBlock);
14,668,990✔
1219
  pDataBlock = NULL;
14,668,938✔
1220
  if (ret != 0) {
14,668,938✔
1221
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
14,668,359✔
1222
    pInfo->pCur = NULL;
14,667,217✔
1223
    setOperatorCompleted(pOperator);
14,667,217✔
1224
  }
1225

1226
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
14,668,964✔
1227
  qDebug("get cols success, rows:%" PRIu64 " %s", pInfo->loadInfo.totalRows, GET_TASKID(pTaskInfo));
14,667,111✔
1228

1229
_end:
14,667,111✔
1230
  if (code != TSDB_CODE_SUCCESS) {
14,666,502✔
1231
    blockDataDestroy(pDataBlock);
×
1232
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1233
    pTaskInfo->code = code;
×
1234
    T_LONG_JMP(pTaskInfo->env, code);
×
1235
  }
1236
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
14,666,502✔
1237
}
1238

1239
static SSDataBlock* sysTableScanVirtualTableRef(SOperatorInfo* pOperator) {
218,957✔
1240
  int32_t            code = TSDB_CODE_SUCCESS;
218,957✔
1241
  int32_t            lino = 0;
218,957✔
1242
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
218,957✔
1243
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
218,957✔
1244
  SSysTableScanInfo* pInfo = pOperator->info;
218,957✔
1245
  int32_t            numOfRows = 0;
218,957✔
1246
  int32_t            ret = 0;
218,957✔
1247
  char               dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
218,957✔
1248
  SSDataBlock*       pDataBlock = NULL;
218,957✔
1249

1250
  // skip mnd read
1251
  if (pInfo->readHandle.mnd != NULL) {
218,957✔
1252
    setOperatorCompleted(pOperator);
71,934✔
1253
    return NULL;
71,934✔
1254
  }
1255

1256
  if (pOperator->status == OP_EXEC_DONE) {
147,023✔
1257
    return NULL;
71,303✔
1258
  }
1259

1260
  blockDataCleanup(pInfo->pRes);
75,720✔
1261

1262
  pDataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_VIRTUAL_TABLES_REFERENCING);
75,720✔
1263
  QUERY_CHECK_NULL(pDataBlock, code, lino, _end, terrno);
75,720✔
1264

1265
  code = blockDataEnsureCapacity(pDataBlock, pOperator->resultInfo.capacity);
75,720✔
1266
  QUERY_CHECK_CODE(code, lino, _end);
75,720✔
1267

1268
  if (pInfo->pCondition && sysTableIsCondOnOneVTableName(pInfo->pCondition, pInfo->req.filterTb)) {
75,720✔
1269
    code = doExtractDbName(dbname, pInfo, pAPI);
×
1270
    QUERY_CHECK_CODE(code, lino, _end);
×
1271

1272
    SSDataBlock* p = doOptimizeVTableNameFilter(pOperator, pDataBlock, dbname);
×
1273
    pInfo->pRes = p;
×
1274
    return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
×
1275
  }
1276

1277
  SVirtualTableRefInfo* pVtableRefInfo = taosMemoryCalloc(1, sizeof(SVirtualTableRefInfo));
75,720✔
1278
  if (pVtableRefInfo == NULL) {
75,720✔
1279
    qError("%s failed at line %d since %s", __func__, __LINE__, terrstr());
×
1280
    pTaskInfo->code = terrno;
×
1281
    T_LONG_JMP(pTaskInfo->env, terrno);
×
1282
  }
1283

1284
  code = doExtractDbName(pVtableRefInfo->vDbName, pInfo, pAPI);
75,720✔
1285
  QUERY_CHECK_CODE(code, lino, _end);
75,720✔
1286

1287
  if (pInfo->pCur == NULL) {
75,720✔
1288
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
75,720✔
1289
  } else {
1290
    code = pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0);
×
1291
    if (code != 0) {
×
1292
      pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
1293
      pInfo->pCur = NULL;
×
1294
      QUERY_CHECK_CODE(code, lino, _end);
×
1295
    }
1296
  }
1297

1298
  if (pInfo->pSchema == NULL) {
75,720✔
1299
    pInfo->pSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
75,720✔
1300
    taosHashSetFreeFp(pInfo->pSchema, tDeleteSSchemaWrapperForHash);
75,720✔
1301
  }
1302

1303
  if (!pInfo->pCur || !pInfo->pSchema) {
75,720✔
1304
    qError("sysTableScanUserVcCols failed since %s", terrstr());
×
1305
    blockDataDestroy(pDataBlock);
×
1306
    pInfo->loadInfo.totalRows = 0;
×
1307
    return NULL;
×
1308
  }
1309

1310
  while (((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0)) {
1,630,504✔
1311
    SSchemaWrapper* schemaRow = NULL;
1,554,784✔
1312
    SColRefWrapper* colRef = NULL;
1,554,784✔
1313

1314
    if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
1,554,784✔
1315
      continue;
366,611✔
1316
    } else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
1,188,173✔
1317
      continue;
219,588✔
1318
    } else if (pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE) {
968,585✔
1319
      continue;
329,382✔
1320
    } else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
639,203✔
1321
      qDebug("sysTableScanUserVcCols cursor get virtual normal table, %s", GET_TASKID(pTaskInfo));
417,722✔
1322

1323
      STR_TO_VARSTR(pVtableRefInfo->vTableName, pInfo->pCur->mr.me.name);
417,722✔
1324
      STR_TO_VARSTR(pVtableRefInfo->vStbName, pInfo->pCur->mr.me.name);
417,722✔
1325

1326
      colRef = &pInfo->pCur->mr.me.colRef;
417,722✔
1327
      schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
417,722✔
1328
    } else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
221,481✔
1329
      qDebug("sysTableScanUserVcCols cursor get virtual child table, %s", GET_TASKID(pTaskInfo));
221,481✔
1330

1331
      STR_TO_VARSTR(pVtableRefInfo->vTableName, pInfo->pCur->mr.me.name);
221,481✔
1332

1333
      colRef = &pInfo->pCur->mr.me.colRef;
221,481✔
1334
      int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
221,481✔
1335
      void*   schema = taosHashGet(pInfo->pSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
221,481✔
1336
      if (schema != NULL) {
221,481✔
1337
        schemaRow = *(SSchemaWrapper**)schema;
148,916✔
1338
        SMetaReader smrSuperTable = {0};
148,916✔
1339
        pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
148,916✔
1340
        code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
148,916✔
1341
        if (code != TSDB_CODE_SUCCESS) {
148,916✔
1342
          // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
1343
          qError("sysTableScanUserVcCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
×
1344
                 GET_TASKID(pTaskInfo));
1345

1346
          pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1347
          blockDataDestroy(pDataBlock);
×
1348
          pInfo->loadInfo.totalRows = 0;
×
1349
          return NULL;
×
1350
        }
1351
        STR_TO_VARSTR(pVtableRefInfo->vStbName, smrSuperTable.me.name);
148,916✔
1352
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
148,916✔
1353
      } else {
1354
        SMetaReader smrSuperTable = {0};
72,565✔
1355
        pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
72,565✔
1356
        code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
72,565✔
1357
        if (code != TSDB_CODE_SUCCESS) {
72,565✔
1358
          // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
1359
          qError("sysTableScanUserVcCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
×
1360
                 GET_TASKID(pTaskInfo));
1361

1362
          pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1363
          blockDataDestroy(pDataBlock);
×
1364
          pInfo->loadInfo.totalRows = 0;
×
1365
          return NULL;
×
1366
        }
1367
        STR_TO_VARSTR(pVtableRefInfo->vStbName, smrSuperTable.me.name);
72,565✔
1368
        bool hasSchema = (smrSuperTable.me.stbEntry.schemaRow.pSchema != NULL);
72,565✔
1369
        SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&smrSuperTable.me.stbEntry.schemaRow);
72,565✔
1370
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
72,565✔
1371
        if (schemaWrapper == NULL) {
72,565✔
1372
          if (!hasSchema) {
×
1373
            qWarn("sysTableScanVirtualTableRef: vstb suid:%" PRId64
×
1374
                  " has no schema, skipping virtual child table %s", suid, pInfo->pCur->mr.me.name);
1375
            continue;
×
1376
          }
1377
          code = terrno;
×
1378
          lino = __LINE__;
×
1379
          goto _end;
×
1380
        }
1381
        code = taosHashPut(pInfo->pSchema, &suid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
72,565✔
1382
        if (code != TSDB_CODE_SUCCESS) {
72,565✔
1383
          tDeleteSchemaWrapper(schemaWrapper);
×
1384
          QUERY_CHECK_CODE(code, lino, _end);
×
1385
        }
1386

1387
        schemaRow = schemaWrapper;
72,565✔
1388
        QUERY_CHECK_CODE(code, lino, _end);
72,565✔
1389
      }
1390
    } else {
1391
      qDebug("sysTableScanUserVcCols cursor get invalid table, %s", GET_TASKID(pTaskInfo));
×
1392
      continue;
×
1393
    }
1394

1395
    if ((numOfRows + schemaRow->nCols) > pOperator->resultInfo.capacity) {
639,203✔
1396
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, pDataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
×
1397
      numOfRows = 0;
×
1398

1399
      if (pInfo->pRes->info.rows > 0) {
×
1400
        pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
×
1401
        break;
×
1402
      }
1403
    }
1404

1405
    // if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock
1406
    code = sysTableFillOneVirtualTableRefImpl(pInfo, pTaskInfo, dbname, &numOfRows, pDataBlock, schemaRow, colRef,
639,203✔
1407
                                              pVtableRefInfo);
1408
    QUERY_CHECK_CODE(code, lino, _end);
639,203✔
1409
  }
1410

1411
  if (numOfRows > 0) {
75,720✔
1412
    pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
72,565✔
1413
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, pDataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
72,565✔
1414
    numOfRows = 0;
72,565✔
1415
  }
1416

1417
  blockDataDestroy(pDataBlock);
75,720✔
1418
  pDataBlock = NULL;
75,720✔
1419
  if (ret != 0) {
75,720✔
1420
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
75,720✔
1421
    pInfo->pCur = NULL;
75,720✔
1422
    setOperatorCompleted(pOperator);
75,720✔
1423
  }
1424

1425
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
75,720✔
1426
  qDebug("get cols success, rows:%" PRIu64 " %s", pInfo->loadInfo.totalRows, GET_TASKID(pTaskInfo));
75,720✔
1427

1428
_end:
75,720✔
1429

1430
  taosMemoryFreeClear(pVtableRefInfo);
75,720✔
1431
  if (code != TSDB_CODE_SUCCESS) {
75,720✔
1432
    blockDataDestroy(pDataBlock);
×
1433
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1434
    pTaskInfo->code = code;
×
1435
    T_LONG_JMP(pTaskInfo->env, code);
×
1436
  }
1437
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
75,720✔
1438
}
1439

1440
static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
1,710,615✔
1441
  int32_t        code = TSDB_CODE_SUCCESS;
1,710,615✔
1442
  int32_t        lino = 0;
1,710,615✔
1443
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
1,710,615✔
1444
  SStorageAPI*   pAPI = &pTaskInfo->storageAPI;
1,710,654✔
1445
  SSDataBlock*   dataBlock = NULL;
1,710,654✔
1446

1447
  SSysTableScanInfo* pInfo = pOperator->info;
1,710,654✔
1448
  if (pOperator->status == OP_EXEC_DONE) {
1,710,654✔
1449
    return NULL;
802,607✔
1450
  }
1451

1452
  blockDataCleanup(pInfo->pRes);
908,047✔
1453
  int32_t numOfRows = 0;
908,047✔
1454

1455
  dataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TAGS);
908,047✔
1456
  QUERY_CHECK_NULL(dataBlock, code, lino, _end, terrno);
908,008✔
1457

1458
  code = blockDataEnsureCapacity(dataBlock, pOperator->resultInfo.capacity);
908,008✔
1459
  QUERY_CHECK_CODE(code, lino, _end);
908,047✔
1460

1461
  const char* db = NULL;
908,047✔
1462
  int32_t     vgId = 0;
908,047✔
1463
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, &db, &vgId, NULL, NULL);
908,047✔
1464

1465
  SName sn = {0};
908,047✔
1466
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
908,047✔
1467
  code = tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
908,047✔
1468
  QUERY_CHECK_CODE(code, lino, _end);
908,047✔
1469

1470
  code = tNameGetDbName(&sn, varDataVal(dbname));
908,047✔
1471
  QUERY_CHECK_CODE(code, lino, _end);
908,047✔
1472

1473
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
908,047✔
1474

1475
  char condTableName[TSDB_TABLE_NAME_LEN] = {0};
908,047✔
1476
  // optimize when sql like where table_name='tablename' and xxx.
1477
  if (pInfo->pCondition && sysTableIsCondOnOneTable(pInfo->pCondition, condTableName)) {
908,047✔
1478
    char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
×
1479
    STR_TO_VARSTR(tableName, condTableName);
×
1480

1481
    SMetaReader smrChildTable = {0};
×
1482
    pAPI->metaReaderFn.initReader(&smrChildTable, pInfo->readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
×
1483
    code = pAPI->metaReaderFn.getTableEntryByName(&smrChildTable, condTableName);
×
1484
    if (code != TSDB_CODE_SUCCESS) {
×
1485
      // terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
1486
      pAPI->metaReaderFn.clearReader(&smrChildTable);
×
1487
      blockDataDestroy(dataBlock);
×
1488
      pInfo->loadInfo.totalRows = 0;
×
1489
      return NULL;
×
1490
    }
1491

1492
    if (smrChildTable.me.type != TSDB_CHILD_TABLE && smrChildTable.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
×
1493
      pAPI->metaReaderFn.clearReader(&smrChildTable);
×
1494
      blockDataDestroy(dataBlock);
×
1495
      pInfo->loadInfo.totalRows = 0;
×
1496
      return NULL;
×
1497
    }
1498

1499
    SMetaReader smrSuperTable = {0};
×
1500
    pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
×
1501
    code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, smrChildTable.me.ctbEntry.suid);
×
1502
    if (code != TSDB_CODE_SUCCESS) {
×
1503
      // terrno has been set by pAPI->metaReaderFn.getTableEntryByUid
1504
      pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1505
      pAPI->metaReaderFn.clearReader(&smrChildTable);
×
1506
      blockDataDestroy(dataBlock);
×
1507
      return NULL;
×
1508
    }
1509

1510
    code = sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &smrChildTable, dbname, tableName, &numOfRows,
×
1511
                                            dataBlock);
1512

1513
    pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1514
    pAPI->metaReaderFn.clearReader(&smrChildTable);
×
1515

1516
    QUERY_CHECK_CODE(code, lino, _end);
×
1517

1518
    if (numOfRows > 0) {
×
1519
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
×
1520
      numOfRows = 0;
×
1521
    }
1522
    blockDataDestroy(dataBlock);
×
1523
    pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
×
1524
    setOperatorCompleted(pOperator);
×
1525
    return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
×
1526
  }
1527

1528
  int32_t ret = 0;
908,047✔
1529
  if (pInfo->pCur == NULL) {
908,047✔
1530
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
908,047✔
1531
    QUERY_CHECK_NULL(pInfo->pCur, code, lino, _end, terrno);
908,047✔
1532
  } else {
1533
    code = pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 0);
×
1534
    QUERY_CHECK_CODE(code, lino, _end);
×
1535
  }
1536

1537
  while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
58,345,121✔
1538
    if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE && pInfo->pCur->mr.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
57,437,002✔
1539
      continue;
105,961✔
1540
    }
1541

1542
    char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
57,331,113✔
1543
    STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
57,331,080✔
1544

1545
    SMetaReader smrSuperTable = {0};
57,331,047✔
1546
    pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
57,331,041✔
1547
    uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
57,331,185✔
1548
    code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
57,331,185✔
1549
    if (code != TSDB_CODE_SUCCESS) {
57,330,942✔
1550
      qError("failed to get super table meta, uid:0x%" PRIx64 ", code:%s, %s", suid, tstrerror(terrno),
×
1551
             GET_TASKID(pTaskInfo));
1552
      pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1553
      pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
1554
      pInfo->pCur = NULL;
×
1555
      blockDataDestroy(dataBlock);
×
1556
      dataBlock = NULL;
×
1557
      T_LONG_JMP(pTaskInfo->env, terrno);
×
1558
    }
1559

1560
    if ((smrSuperTable.me.stbEntry.schemaTag.nCols + numOfRows) > pOperator->resultInfo.capacity) {
57,330,942✔
1561
      relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
×
1562
      numOfRows = 0;
×
1563

1564
      if (pInfo->pRes->info.rows > 0) {
×
1565
        pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
×
1566
        pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1567
        break;
×
1568
      }
1569
    }
1570

1571
    // if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock
1572
    code = sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &pInfo->pCur->mr, dbname, tableName, &numOfRows,
57,331,047✔
1573
                                            dataBlock);
1574

1575
    if (code != TSDB_CODE_SUCCESS) {
57,330,954✔
1576
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
1577
      pAPI->metaReaderFn.clearReader(&smrSuperTable);
×
1578
      pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
1579
      pInfo->pCur = NULL;
×
1580
      blockDataDestroy(dataBlock);
×
1581
      dataBlock = NULL;
×
1582
      T_LONG_JMP(pTaskInfo->env, terrno);
×
1583
    }
1584
    pAPI->metaReaderFn.clearReader(&smrSuperTable);
57,330,954✔
1585
  }
1586

1587
  if (numOfRows > 0) {
907,870✔
1588
    pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
898,943✔
1589
    relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo, pTaskInfo);
899,120✔
1590
    numOfRows = 0;
899,120✔
1591
  }
1592

1593
  blockDataDestroy(dataBlock);
908,047✔
1594
  dataBlock = NULL;
907,870✔
1595
  if (ret != 0) {
907,870✔
1596
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
907,870✔
1597
    pInfo->pCur = NULL;
907,870✔
1598
    setOperatorCompleted(pOperator);
908,047✔
1599
  }
1600

1601
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
908,047✔
1602

1603
_end:
908,047✔
1604
  if (code != TSDB_CODE_SUCCESS) {
907,870✔
1605
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1606
    blockDataDestroy(dataBlock);
×
1607
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
1608
    pInfo->pCur = NULL;
×
1609
    pTaskInfo->code = code;
×
1610
    T_LONG_JMP(pTaskInfo->env, code);
×
1611
  }
1612
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
907,870✔
1613
}
1614

1615
void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
9,085,373✔
1616
                                        SFilterInfo* pFilterInfo, SExecTaskInfo* pTaskInfo) {
1617
  int32_t code = TSDB_CODE_SUCCESS;
9,085,373✔
1618
  int32_t lino = 0;
9,085,373✔
1619
  dataBlock->info.rows = numOfRows;
9,085,373✔
1620
  pInfo->pRes->info.rows = numOfRows;
9,087,298✔
1621

1622
  code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, dataBlock->pDataBlock, false);
9,086,591✔
1623
  QUERY_CHECK_CODE(code, lino, _end);
9,086,768✔
1624

1625
  code = doFilter(pInfo->pRes, pFilterInfo, NULL, NULL);
9,086,768✔
1626
  QUERY_CHECK_CODE(code, lino, _end);
9,085,099✔
1627

1628
  blockDataCleanup(dataBlock);
9,085,099✔
1629

1630
_end:
9,087,298✔
1631
  if (code != TSDB_CODE_SUCCESS) {
9,087,298✔
1632
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1633
    pTaskInfo->code = code;
×
1634
    T_LONG_JMP(pTaskInfo->env, code);
×
1635
  }
1636
}
9,087,298✔
1637

1638
int32_t convertTagDataToStr(char* str, int32_t strBuffLen, int type, void* buf, int32_t bufSize, int32_t* len) {
933,550,660✔
1639
  int32_t n = 0;
933,550,660✔
1640

1641
  switch (type) {
933,550,660✔
1642
    case TSDB_DATA_TYPE_NULL:
×
1643
      n = snprintf(str, strBuffLen, "null");
×
1644
      break;
×
1645

1646
    case TSDB_DATA_TYPE_BOOL:
737,495,486✔
1647
      n = snprintf(str, strBuffLen, (*(int8_t*)buf) ? "true" : "false");
737,495,486✔
1648
      break;
737,495,519✔
1649

1650
    case TSDB_DATA_TYPE_TINYINT:
556,858✔
1651
      n = snprintf(str, strBuffLen, "%d", *(int8_t*)buf);
556,858✔
1652
      break;
556,858✔
1653

1654
    case TSDB_DATA_TYPE_SMALLINT:
474,671✔
1655
      n = snprintf(str, strBuffLen, "%d", *(int16_t*)buf);
474,671✔
1656
      break;
474,671✔
1657

1658
    case TSDB_DATA_TYPE_INT:
48,431,577✔
1659
      n = snprintf(str, strBuffLen, "%d", *(int32_t*)buf);
48,431,577✔
1660
      break;
48,431,741✔
1661

1662
    case TSDB_DATA_TYPE_BIGINT:
48,282,119✔
1663
    case TSDB_DATA_TYPE_TIMESTAMP:
1664
      n = snprintf(str, strBuffLen, "%" PRId64, *(int64_t*)buf);
48,282,119✔
1665
      break;
48,282,119✔
1666

1667
    case TSDB_DATA_TYPE_FLOAT:
47,123,111✔
1668
      n = snprintf(str, strBuffLen, "%.5f", GET_FLOAT_VAL(buf));
47,123,111✔
1669
      break;
47,123,078✔
1670

1671
    case TSDB_DATA_TYPE_DOUBLE:
46,995,243✔
1672
      n = snprintf(str, strBuffLen, "%.9f", GET_DOUBLE_VAL(buf));
46,995,243✔
1673
      break;
46,995,210✔
1674

1675
    case TSDB_DATA_TYPE_BINARY:
987,744✔
1676
    case TSDB_DATA_TYPE_VARBINARY:
1677
    case TSDB_DATA_TYPE_GEOMETRY:
1678
      if (bufSize < 0) {
987,744✔
1679
        return TSDB_CODE_TSC_INVALID_VALUE;
×
1680
      }
1681

1682
      memcpy(str, buf, bufSize);
987,744✔
1683
      n = bufSize;
987,744✔
1684
      break;
987,744✔
1685
    case TSDB_DATA_TYPE_NCHAR:
664,604✔
1686
      if (bufSize < 0) {
664,604✔
1687
        return TSDB_CODE_TSC_INVALID_VALUE;
×
1688
      }
1689

1690
      int32_t length = taosUcs4ToMbs((TdUcs4*)buf, bufSize, str, NULL);
664,604✔
1691
      if (length <= 0) {
664,571✔
1692
        return TSDB_CODE_TSC_INVALID_VALUE;
×
1693
      }
1694
      n = length;
664,571✔
1695
      break;
664,571✔
1696
    case TSDB_DATA_TYPE_UTINYINT:
331,438✔
1697
      n = snprintf(str, strBuffLen, "%u", *(uint8_t*)buf);
331,438✔
1698
      break;
331,438✔
1699

1700
    case TSDB_DATA_TYPE_USMALLINT:
306,457✔
1701
      n = snprintf(str, strBuffLen, "%u", *(uint16_t*)buf);
306,457✔
1702
      break;
306,457✔
1703

1704
    case TSDB_DATA_TYPE_UINT:
1,602,349✔
1705
      n = snprintf(str, strBuffLen, "%u", *(uint32_t*)buf);
1,602,349✔
1706
      break;
1,602,349✔
1707

1708
    case TSDB_DATA_TYPE_UBIGINT:
307,741✔
1709
      n = snprintf(str, strBuffLen, "%" PRIu64, *(uint64_t*)buf);
307,741✔
1710
      break;
307,741✔
1711

1712
    default:
×
1713
      return TSDB_CODE_TSC_INVALID_VALUE;
×
1714
  }
1715

1716
  if (len) *len = n;
933,559,496✔
1717

1718
  return TSDB_CODE_SUCCESS;
933,559,733✔
1719
}
1720

1721
static int32_t sysTableGetGeomText(char* iGeom, int32_t nGeom, char** output, int32_t* nOutput) {
52,994✔
1722
#ifdef USE_GEOS
1723
  int32_t code = 0;
52,994✔
1724
  char*   outputWKT = NULL;
52,994✔
1725

1726
  if (nGeom == 0) {
52,994✔
1727
    if (!(*output = taosStrdup(""))) code = terrno;
×
1728
    *nOutput = 0;
×
1729
    return code;
×
1730
  }
1731

1732
  if (TSDB_CODE_SUCCESS != (code = initCtxAsText()) ||
105,988✔
1733
      TSDB_CODE_SUCCESS != (code = doAsText(iGeom, nGeom, &outputWKT))) {
52,994✔
1734
    qError("geo text for systable failed:%s", getGeosErrMsg(code));
×
1735
    *output = NULL;
×
1736
    *nOutput = 0;
×
1737
    return code;
×
1738
  }
1739

1740
  *output = outputWKT;
52,994✔
1741
  *nOutput = strlen(outputWKT);
52,994✔
1742

1743
  return code;
52,994✔
1744
#else
1745
  TAOS_RETURN(TSDB_CODE_OPS_NOT_SUPPORT);
1746
#endif
1747
}
1748

1749
static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo, SMetaReader* smrSuperTable,
57,331,047✔
1750
                                                SMetaReader* smrChildTable, const char* dbname, const char* tableName,
1751
                                                int32_t* pNumOfRows, const SSDataBlock* dataBlock) {
1752
  int32_t code = TSDB_CODE_SUCCESS;
57,331,047✔
1753
  int32_t lino = 0;
57,331,047✔
1754
  char    stableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
57,331,047✔
1755
  STR_TO_VARSTR(stableName, (*smrSuperTable).me.name);
57,331,119✔
1756

1757
  int32_t numOfRows = *pNumOfRows;
57,330,855✔
1758

1759
  int32_t numOfTags = (*smrSuperTable).me.stbEntry.schemaTag.nCols;
57,331,218✔
1760
  for (int32_t i = 0; i < numOfTags; ++i) {
993,720,374✔
1761
    SColumnInfoData* pColInfoData = NULL;
936,389,348✔
1762

1763
    // table name
1764
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
936,389,348✔
1765
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
936,385,323✔
1766
    code = colDataSetVal(pColInfoData, numOfRows, tableName, false);
936,385,323✔
1767
    QUERY_CHECK_CODE(code, lino, _end);
936,389,798✔
1768

1769
    // database name
1770
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
936,389,798✔
1771
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
936,380,432✔
1772
    code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
936,380,432✔
1773
    QUERY_CHECK_CODE(code, lino, _end);
936,390,468✔
1774

1775
    // super table name
1776
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
936,390,468✔
1777
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
936,390,462✔
1778
    code = colDataSetVal(pColInfoData, numOfRows, stableName, false);
936,390,462✔
1779
    QUERY_CHECK_CODE(code, lino, _end);
936,390,665✔
1780

1781
    // tag name
1782
    char tagName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
936,390,665✔
1783
    STR_TO_VARSTR(tagName, (*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].name);
936,390,665✔
1784
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
936,390,200✔
1785
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
936,390,817✔
1786
    code = colDataSetVal(pColInfoData, numOfRows, tagName, false);
936,390,817✔
1787
    QUERY_CHECK_CODE(code, lino, _end);
936,390,699✔
1788

1789
    // tag type
1790
    int8_t tagType = (*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].type;
936,390,699✔
1791

1792
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
936,390,660✔
1793
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
936,390,627✔
1794
    int32_t tagStrBufflen = 32;
936,390,627✔
1795
    char    tagTypeStr[VARSTR_HEADER_SIZE + 32];
936,390,627✔
1796
    int     tagTypeLen = snprintf(varDataVal(tagTypeStr), tagStrBufflen, "%s", tDataTypes[tagType].name);
936,390,522✔
1797
    tagStrBufflen -= tagTypeLen;
936,389,699✔
1798
    if (tagStrBufflen <= 0) {
936,389,699✔
1799
      code = TSDB_CODE_INVALID_PARA;
×
1800
      QUERY_CHECK_CODE(code, lino, _end);
×
1801
    }
1802

1803
    if (tagType == TSDB_DATA_TYPE_NCHAR) {
936,389,699✔
1804
      tagTypeLen += snprintf(
767,264✔
1805
          varDataVal(tagTypeStr) + tagTypeLen, tagStrBufflen, "(%d)",
767,264✔
1806
          (int32_t)(((*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
767,264✔
1807
    } else if (IS_VAR_DATA_TYPE(tagType)) {
935,622,435✔
1808
      if (IS_STR_DATA_BLOB(tagType)) {
1,437,402✔
1809
        code = TSDB_CODE_BLOB_NOT_SUPPORT_TAG;
250✔
1810
        QUERY_CHECK_CODE(code, lino, _end);
250✔
1811
      }
1812
      tagTypeLen += snprintf(varDataVal(tagTypeStr) + tagTypeLen, tagStrBufflen, "(%d)",
1,437,503✔
1813
                             (int32_t)((*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].bytes - VARSTR_HEADER_SIZE));
1,437,402✔
1814
    }
1815
    varDataSetLen(tagTypeStr, tagTypeLen);
936,389,800✔
1816
    code = colDataSetVal(pColInfoData, numOfRows, (char*)tagTypeStr, false);
936,389,430✔
1817
    QUERY_CHECK_CODE(code, lino, _end);
936,391,387✔
1818

1819
    STagVal tagVal = {0};
936,391,387✔
1820
    tagVal.cid = (*smrSuperTable).me.stbEntry.schemaTag.pSchema[i].colId;
936,391,354✔
1821
    char*    tagData = NULL;
936,391,348✔
1822
    uint32_t tagLen = 0;
936,391,348✔
1823

1824
    if (tagType == TSDB_DATA_TYPE_JSON) {
936,387,844✔
1825
      tagData = (char*)smrChildTable->me.ctbEntry.pTags;
145,892✔
1826
    } else {
1827
      bool exist = tTagGet((STag*)smrChildTable->me.ctbEntry.pTags, &tagVal);
936,241,952✔
1828
      if (exist) {
936,244,936✔
1829
        if (tagType == TSDB_DATA_TYPE_GEOMETRY) {
933,692,042✔
1830
          code = sysTableGetGeomText(tagVal.pData, tagVal.nData, &tagData, &tagLen);
52,994✔
1831
          QUERY_CHECK_CODE(code, lino, _end);
52,994✔
1832
        } else if (tagType == TSDB_DATA_TYPE_VARBINARY) {
933,639,048✔
1833
          code = taosAscii2Hex(tagVal.pData, tagVal.nData, (void**)&tagData, &tagLen);
345,446✔
1834
          if (code < 0) {
345,446✔
1835
            qError("varbinary for systable failed since %s", tstrerror(code));
×
1836
          }
1837
        } else if (IS_VAR_DATA_TYPE(tagType)) {
933,293,602✔
1838
          tagData = (char*)tagVal.pData;
1,385,772✔
1839
          tagLen = tagVal.nData;
1,385,772✔
1840
        } else {
1841
          tagData = (char*)&tagVal.i64;
931,907,830✔
1842
          tagLen = tDataTypes[tagType].bytes;
931,907,830✔
1843
        }
1844
      }
1845
    }
1846

1847
    char* tagVarChar = NULL;
936,379,543✔
1848
    if (tagData != NULL) {
936,379,543✔
1849
      if (IS_STR_DATA_BLOB(tagType)) {
933,837,790✔
1850
        code = TSDB_CODE_BLOB_NOT_SUPPORT_TAG;
×
1851
        goto _end;
×
1852
      }
1853

1854
      if (tagType == TSDB_DATA_TYPE_JSON) {
933,838,053✔
1855
        char* tagJson = NULL;
145,892✔
1856
        parseTagDatatoJson(tagData, &tagJson, NULL);
145,892✔
1857
        if (tagJson == NULL) {
145,892✔
1858
          code = terrno;
×
1859
          goto _end;
×
1860
        }
1861
        tagVarChar = taosMemoryMalloc(strlen(tagJson) + VARSTR_HEADER_SIZE);
145,892✔
1862
        QUERY_CHECK_NULL(tagVarChar, code, lino, _end, terrno);
145,892✔
1863
        memcpy(varDataVal(tagVarChar), tagJson, strlen(tagJson));
145,892✔
1864
        varDataSetLen(tagVarChar, strlen(tagJson));
145,892✔
1865
        taosMemoryFree(tagJson);
145,892✔
1866
      } else {
1867
        int32_t bufSize = IS_VAR_DATA_TYPE(tagType) ? (tagLen + VARSTR_HEADER_SIZE)
933,692,161✔
1868
                                                    : (3 + DBL_MANT_DIG - DBL_MIN_EXP + VARSTR_HEADER_SIZE);
1869
        tagVarChar = taosMemoryCalloc(1, bufSize + 1);
933,692,161✔
1870
        QUERY_CHECK_NULL(tagVarChar, code, lino, _end, terrno);
933,687,097✔
1871
        int32_t len = -1;
933,687,097✔
1872
        if (tagLen > 0)
933,687,097✔
1873
          convertTagDataToStr(varDataVal(tagVarChar), bufSize + 1 - VARSTR_HEADER_SIZE, tagType, tagData, tagLen, &len);
933,554,922✔
1874
        else
1875
          len = 0;
132,175✔
1876
        varDataSetLen(tagVarChar, len);
933,691,619✔
1877
      }
1878
    }
1879
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
936,378,501✔
1880
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
936,388,773✔
1881
    code = colDataSetVal(pColInfoData, numOfRows, tagVarChar,
936,388,773✔
1882
                         (tagData == NULL) || (tagType == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(tagData)));
936,388,773✔
1883
    QUERY_CHECK_CODE(code, lino, _end);
936,390,954✔
1884

1885
    if (tagType == TSDB_DATA_TYPE_GEOMETRY || tagType == TSDB_DATA_TYPE_VARBINARY) taosMemoryFreeClear(tagData);
936,390,954✔
1886
    taosMemoryFree(tagVarChar);
936,390,954✔
1887
    ++numOfRows;
936,389,618✔
1888
  }
1889

1890
  *pNumOfRows = numOfRows;
57,331,026✔
1891

1892
_end:
57,331,092✔
1893
  if (code != TSDB_CODE_SUCCESS) {
57,331,059✔
1894
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1895
  }
1896
  return code;
57,331,059✔
1897
}
1898

1899
static int32_t sysTableUserColsFillOneTableCols(const char* dbname, int32_t* pNumOfRows, const SSDataBlock* dataBlock,
52,402,207✔
1900
                                                char* tName, SSchemaWrapper* schemaRow, SExtSchema* extSchemaRow,
1901
                                                char* tableType, SColRefWrapper* colRef) {
1902
  int32_t code = TSDB_CODE_SUCCESS;
52,402,207✔
1903
  int32_t lino = 0;
52,402,207✔
1904
  if (schemaRow == NULL) {
52,402,207✔
1905
    qError("sysTableUserColsFillOneTableCols schemaRow is NULL");
×
1906
    return TSDB_CODE_SUCCESS;
×
1907
  }
1908
  int32_t numOfRows = *pNumOfRows;
52,402,207✔
1909

1910
  int32_t numOfCols = schemaRow->nCols;
52,402,207✔
1911
  for (int32_t i = 0; i < numOfCols; ++i) {
1,212,777,084✔
1912
    SColumnInfoData* pColInfoData = NULL;
1,160,374,877✔
1913

1914
    // table name
1915
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
1,160,374,877✔
1916
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,373,817✔
1917
    code = colDataSetVal(pColInfoData, numOfRows, tName, false);
1,160,373,817✔
1918
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,347✔
1919

1920
    // database name
1921
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
1,160,374,347✔
1922
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,374,877✔
1923
    code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
1,160,374,877✔
1924
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,877✔
1925

1926
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
1,160,374,877✔
1927
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,374,877✔
1928
    code = colDataSetVal(pColInfoData, numOfRows, tableType, false);
1,160,374,877✔
1929
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,347✔
1930

1931
    // col name
1932
    char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,160,374,347✔
1933
    STR_TO_VARSTR(colName, schemaRow->pSchema[i].name);
1,160,374,347✔
1934
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
1,160,373,817✔
1935
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,373,287✔
1936
    code = colDataSetVal(pColInfoData, numOfRows, colName, false);
1,160,373,287✔
1937
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,347✔
1938

1939
    // col type
1940
    int8_t colType = schemaRow->pSchema[i].type;
1,160,374,347✔
1941
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
1,160,374,347✔
1942
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,374,877✔
1943
    int32_t colStrBufflen = 32;
1,160,374,877✔
1944
    char    colTypeStr[VARSTR_HEADER_SIZE + 32];
1,160,374,877✔
1945
    int     colTypeLen = snprintf(varDataVal(colTypeStr), colStrBufflen, "%s", tDataTypes[colType].name);
1,160,373,817✔
1946
    colStrBufflen -= colTypeLen;
1,160,373,287✔
1947
    if (colStrBufflen <= 0) {
1,160,373,287✔
1948
      code = TSDB_CODE_INVALID_PARA;
×
1949
      QUERY_CHECK_CODE(code, lino, _end);
×
1950
    }
1951
    if (colType == TSDB_DATA_TYPE_VARCHAR) {
1,160,373,287✔
1952
      colTypeLen += snprintf(varDataVal(colTypeStr) + colTypeLen, colStrBufflen, "(%d)",
13,136,010✔
1953
                             (int32_t)(schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE));
13,136,010✔
1954
    } else if (colType == TSDB_DATA_TYPE_NCHAR) {
1,147,237,277✔
1955
      colTypeLen += snprintf(varDataVal(colTypeStr) + colTypeLen, colStrBufflen, "(%d)",
3,063,142✔
1956
                             (int32_t)((schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
3,063,142✔
1957
    } else if (IS_DECIMAL_TYPE(colType)) {
1,144,174,135✔
1958
      QUERY_CHECK_NULL(extSchemaRow, code, lino, _end, TSDB_CODE_INVALID_PARA);
×
1959
      STypeMod typeMod = extSchemaRow[i].typeMod;
×
1960
      uint8_t  prec = 0, scale = 0;
×
1961
      decimalFromTypeMod(typeMod, &prec, &scale);
×
1962
      colTypeLen += snprintf(varDataVal(colTypeStr) + colTypeLen, sizeof(colTypeStr) - colTypeLen - VARSTR_HEADER_SIZE,
×
1963
                             "(%d,%d)", prec, scale);
1964
    }
1965
    varDataSetLen(colTypeStr, colTypeLen);
1,160,373,287✔
1966
    code = colDataSetVal(pColInfoData, numOfRows, (char*)colTypeStr, false);
1,160,372,757✔
1967
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,877✔
1968

1969
    // col length
1970
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
1,160,374,877✔
1971
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,373,287✔
1972
    code = colDataSetVal(pColInfoData, numOfRows, (const char*)&schemaRow->pSchema[i].bytes, false);
1,160,373,287✔
1973
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,347✔
1974

1975
    // col precision, col scale, col nullable
1976
    for (int32_t j = 6; j <= 8; ++j) {
2,147,483,647✔
1977
      pColInfoData = taosArrayGet(dataBlock->pDataBlock, j);
2,147,483,647✔
1978
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
2,147,483,647✔
1979
      colDataSetNULL(pColInfoData, numOfRows);
2,147,483,647✔
1980
    }
1981

1982
    // col data source
1983
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 9);
1,160,376,593✔
1984
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,373,287✔
1985
    if (!colRef || !colRef->pColRef[i].hasRef) {
1,160,373,287✔
1986
      colDataSetNULL(pColInfoData, numOfRows);
1,159,485,999✔
1987
    } else {
1988
      char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
887,288✔
1989
      char tmpColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
887,288✔
1990

1991
      TSlice refColNameBuf = {0};
887,288✔
1992
      sliceInit(&refColNameBuf, tmpColName, sizeof(tmpColName));
887,288✔
1993

1994
      QUERY_CHECK_CODE(sliceAppend(&refColNameBuf, colRef->pColRef[i].refDbName, strlen(colRef->pColRef[i].refDbName)),
887,288✔
1995
                       lino, _end);
1996
      QUERY_CHECK_CODE(sliceAppend(&refColNameBuf, ".", 1), lino, _end);
887,288✔
1997

1998
      QUERY_CHECK_CODE(
887,288✔
1999
          sliceAppend(&refColNameBuf, colRef->pColRef[i].refTableName, strlen(colRef->pColRef[i].refTableName)), lino,
2000
          _end);
2001

2002
      QUERY_CHECK_CODE(sliceAppend(&refColNameBuf, ".", 1), lino, _end);
887,288✔
2003
      QUERY_CHECK_CODE(
887,288✔
2004
          sliceAppend(&refColNameBuf, colRef->pColRef[i].refColName, strlen(colRef->pColRef[i].refColName)), lino,
2005
          _end);
2006

2007
      STR_TO_VARSTR(refColName, tmpColName);
887,288✔
2008

2009
      code = colDataSetVal(pColInfoData, numOfRows, (char*)refColName, false);
887,288✔
2010
      QUERY_CHECK_CODE(code, lino, _end);
887,288✔
2011
    }
2012

2013
    // col id
2014
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 10);
1,160,373,817✔
2015
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,160,373,817✔
2016
    code = colDataSetVal(pColInfoData, numOfRows, (const char*)&schemaRow->pSchema[i].colId, false);
1,160,373,817✔
2017
    QUERY_CHECK_CODE(code, lino, _end);
1,160,374,877✔
2018

2019
    ++numOfRows;
1,160,374,877✔
2020
  }
2021

2022
  *pNumOfRows = numOfRows;
52,402,207✔
2023

2024
_end:
52,402,207✔
2025
  if (code != TSDB_CODE_SUCCESS) {
52,402,207✔
2026
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2027
  }
2028
  return code;
52,401,147✔
2029
}
2030

2031
static int32_t sysTableUserColsFillOneVirtualTableCols(const SSysTableScanInfo* pInfo, const char* dbname,
16,795,594✔
2032
                                                       int32_t* pNumOfRows, const SSDataBlock* dataBlock, char* tName,
2033
                                                       char* stName, SSchemaWrapper* schemaRow, char* tableType,
2034
                                                       SColRefWrapper* colRef, tb_uid_t uid, int32_t vgId) {
2035
  int32_t code = TSDB_CODE_SUCCESS;
16,795,594✔
2036
  int32_t lino = 0;
16,795,594✔
2037
  if (schemaRow == NULL) {
16,795,594✔
2038
    qError("sysTableUserColsFillOneTableCols schemaRow is NULL");
×
2039
    return TSDB_CODE_SUCCESS;
×
2040
  }
2041
  int32_t numOfRows = *pNumOfRows;
16,795,594✔
2042

2043
  int32_t numOfCols = schemaRow->nCols;
16,793,799✔
2044
  for (int32_t i = 0; i < numOfCols; ++i) {
296,971,262✔
2045
    SColumnInfoData* pColInfoData = NULL;
280,174,475✔
2046

2047
    // table name
2048
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
280,174,475✔
2049
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,156,639✔
2050
    code = colDataSetVal(pColInfoData, numOfRows, tName, false);
280,156,639✔
2051
    QUERY_CHECK_CODE(code, lino, _end);
280,170,104✔
2052

2053
    // stable name
2054
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
280,170,104✔
2055
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,163,462✔
2056
    code = colDataSetVal(pColInfoData, numOfRows, stName, false);
280,163,462✔
2057
    QUERY_CHECK_CODE(code, lino, _end);
280,173,001✔
2058

2059
    // database name
2060
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
280,173,001✔
2061
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,170,725✔
2062
    code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
280,170,725✔
2063
    QUERY_CHECK_CODE(code, lino, _end);
280,178,377✔
2064

2065
    // col name
2066
    char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
280,178,377✔
2067
    STR_TO_VARSTR(colName, schemaRow->pSchema[i].name);
280,177,735✔
2068
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
280,175,963✔
2069
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,173,065✔
2070
    code = colDataSetVal(pColInfoData, numOfRows, colName, false);
280,173,065✔
2071
    QUERY_CHECK_CODE(code, lino, _end);
280,168,076✔
2072

2073
    // uid
2074
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
280,168,076✔
2075
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,162,564✔
2076
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&uid, false);
280,162,564✔
2077
    QUERY_CHECK_CODE(code, lino, _end);
280,165,183✔
2078

2079
    // col data source
2080
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
280,165,183✔
2081
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,160,933✔
2082
    if (!colRef || !colRef->pColRef[i].hasRef) {
280,160,933✔
2083
      colDataSetNULL(pColInfoData, numOfRows);
107,218,962✔
2084
    } else {
2085
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&colRef->pColRef[i].id, false);
172,947,433✔
2086
      QUERY_CHECK_CODE(code, lino, _end);
172,949,822✔
2087
    }
2088

2089
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 6);
280,187,015✔
2090
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,145,011✔
2091
    if (!colRef || !colRef->pColRef[i].hasRef) {
280,145,011✔
2092
      colDataSetNULL(pColInfoData, numOfRows);
107,201,801✔
2093
    } else {
2094
      char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
172,946,186✔
2095
      char tmpColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
172,950,443✔
2096
      TSlice refColNameBuf = {0};
172,956,482✔
2097
      sliceInit(&refColNameBuf, tmpColName, sizeof(tmpColName));
172,955,927✔
2098

2099
      QUERY_CHECK_CODE(sliceAppend(&refColNameBuf, colRef->pColRef[i].refDbName, strlen(colRef->pColRef[i].refDbName)),
172,954,104✔
2100
                       lino, _end);
2101
      QUERY_CHECK_CODE(sliceAppend(&refColNameBuf, ".", 1), lino, _end);
172,947,902✔
2102
      QUERY_CHECK_CODE(
172,948,108✔
2103
          sliceAppend(&refColNameBuf, colRef->pColRef[i].refTableName, strlen(colRef->pColRef[i].refTableName)), lino,
2104
          _end);
2105
      QUERY_CHECK_CODE(sliceAppend(&refColNameBuf, ".", 1), lino, _end);
172,949,891✔
2106
      QUERY_CHECK_CODE(
172,949,256✔
2107
          sliceAppend(&refColNameBuf, colRef->pColRef[i].refColName, strlen(colRef->pColRef[i].refColName)), lino,
2108
          _end);
2109
      STR_TO_VARSTR(refColName, tmpColName);
172,952,668✔
2110

2111
      code = colDataSetVal(pColInfoData, numOfRows, (char*)refColName, false);
172,953,850✔
2112
      QUERY_CHECK_CODE(code, lino, _end);
172,949,157✔
2113
    }
2114

2115
    // vgid
2116
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 7);
280,189,971✔
2117
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,154,664✔
2118
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
280,154,664✔
2119
    QUERY_CHECK_CODE(code, lino, _end);
280,182,267✔
2120

2121
    // col ref version
2122
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 8);
280,182,267✔
2123
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
280,161,966✔
2124
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&colRef->version, false);
280,161,966✔
2125
    QUERY_CHECK_CODE(code, lino, _end);
280,177,483✔
2126
    ++numOfRows;
280,177,483✔
2127
  }
2128

2129
  *pNumOfRows = numOfRows;
16,796,787✔
2130

2131
_end:
16,795,561✔
2132
  if (code != TSDB_CODE_SUCCESS) {
16,795,561✔
2133
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2134
  }
2135
  return code;
16,796,787✔
2136
}
2137

2138
// ===================== Virtual Table Reference Validation =====================
2139

2140
// Context for async RPC used during virtual table reference validation
2141
typedef struct SVtbRefValidateCtx {
2142
  tsem_t  ready;
2143
  int32_t rspCode;
2144
  void*   pRsp;
2145
  int32_t rspLen;
2146
} SVtbRefValidateCtx;
2147

2148
// ===================== Table Schema Cache for Validation =====================
2149

2150
// Cached schema for a single table (used to avoid repeated meta reads)
2151
typedef struct SVtbRefSchemaCache {
2152
  SSchemaWrapper schemaRow;  // Data column schema
2153
  SSchemaWrapper schemaTag;  // Tag schema (optional)
2154
  bool           hasTagSchema;
2155
  bool           ownsSchema;     // true if schema is deep-copied (remote tables), false if shallow (local tables)
2156
  SHashObj*      pColNameIndex;  // Column name hash index for O(1) lookup
2157
} SVtbRefSchemaCache;
2158

2159
// Cache entry for a single table
2160
typedef struct SVtbRefTableCacheEntry {
2161
  int32_t             errCode;       // Table validation result (TSDB_CODE_SUCCESS or error)
2162
  SVtbRefSchemaCache* pSchemaCache;  // Schema cache (NULL if errCode != SUCCESS)
2163
} SVtbRefTableCacheEntry;
2164

2165
static int32_t vtbRefBuildColNameIndex(SSchema* pSchemas, int32_t numOfCols, int32_t numOfTags, SHashObj** ppIndex) {
566,638✔
2166
  int32_t code = 0;
566,638✔
2167
  int32_t totalCols = numOfCols + numOfTags;
566,638✔
2168
  SHashObj* pIndex = taosHashInit(totalCols > 0 ? totalCols : 8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY),
566,638✔
2169
                                  true, HASH_NO_LOCK);
2170
  if (pIndex == NULL) {
566,638✔
2171
    return terrno;
×
2172
  }
2173
  for (int32_t i = 0; i < totalCols; ++i) {
2,836,976✔
2174
    code = taosHashPut(pIndex, pSchemas[i].name, strlen(pSchemas[i].name), &i, sizeof(int32_t));
2,270,338✔
2175
    if (code != TSDB_CODE_SUCCESS) {
2,270,338✔
2176
      taosHashCleanup(pIndex);
×
2177
      return code;
×
2178
    }   
2179
  }
2180
  *ppIndex = pIndex;
566,638✔
2181
  return TSDB_CODE_SUCCESS;
566,638✔
2182
}
2183

2184
static SVtbRefSchemaCache* vtbRefCreateSchemaCache(ETableType type, SMetaReader* pReader) {
251,138✔
2185
  SVtbRefSchemaCache* pCache = taosMemoryCalloc(1, sizeof(SVtbRefSchemaCache));
251,138✔
2186
  if (pCache == NULL) {
251,138✔
2187
    return NULL;
×
2188
  }
2189

2190
  int32_t code = TSDB_CODE_SUCCESS;
251,138✔
2191
  int32_t numOfCols = 0;
251,138✔
2192
  int32_t numOfTags = 0;
251,138✔
2193
  SSchema* pSrcSchemas = NULL;
251,138✔
2194
  SSchema* pSrcTagSchemas = NULL;
251,138✔
2195

2196
  if (type == TSDB_NORMAL_TABLE) {
251,138✔
2197
    numOfCols = pReader->me.ntbEntry.schemaRow.nCols;
184,883✔
2198
    pSrcSchemas = pReader->me.ntbEntry.schemaRow.pSchema;
184,883✔
2199
    pCache->hasTagSchema = false;
184,883✔
2200
  } else if (type == TSDB_CHILD_TABLE || type == TSDB_SUPER_TABLE) {
66,255✔
2201
    numOfCols = pReader->me.stbEntry.schemaRow.nCols;
66,255✔
2202
    numOfTags = pReader->me.stbEntry.schemaTag.nCols;
66,255✔
2203
    pSrcSchemas = pReader->me.stbEntry.schemaRow.pSchema;
66,255✔
2204
    pSrcTagSchemas = pReader->me.stbEntry.schemaTag.pSchema;
66,255✔
2205
    pCache->hasTagSchema = true;
66,255✔
2206
  } else {
2207
    taosMemoryFree(pCache);
×
2208
    return NULL;
×
2209
  }
2210

2211
  // Allocate and copy schemas (deep copy to own the memory)
2212
  int32_t totalCols = numOfCols + numOfTags;
251,138✔
2213
  SSchema* pAllSchemas = taosMemoryMalloc(totalCols * sizeof(SSchema));
251,138✔
2214
  if (pAllSchemas == NULL) {
251,138✔
2215
    taosMemoryFree(pCache);
×
2216
    return NULL;
×
2217
  }
2218

2219
  // Copy column schemas
2220
  if (pSrcSchemas != NULL && numOfCols > 0) {
251,138✔
2221
    memcpy(pAllSchemas, pSrcSchemas, numOfCols * sizeof(SSchema));
251,138✔
2222
  }
2223

2224
  // Copy tag schemas
2225
  if (pSrcTagSchemas != NULL && numOfTags > 0) {
251,138✔
2226
    memcpy(pAllSchemas + numOfCols, pSrcTagSchemas, numOfTags * sizeof(SSchema));
66,255✔
2227
  }
2228

2229
  pCache->schemaRow.nCols = numOfCols;
251,138✔
2230
  pCache->schemaRow.pSchema = pAllSchemas;
251,138✔
2231
  pCache->schemaTag.nCols = numOfTags;
251,138✔
2232
  pCache->schemaTag.pSchema = (numOfTags > 0) ? pAllSchemas + numOfCols : NULL;
251,138✔
2233
  pCache->ownsSchema = true;
251,138✔
2234

2235
  code = vtbRefBuildColNameIndex(pAllSchemas, numOfCols, numOfTags, &pCache->pColNameIndex);
251,138✔
2236

2237
  if (code != TSDB_CODE_SUCCESS) {
251,138✔
2238
    taosMemoryFree(pAllSchemas);
×
2239
    taosMemoryFree(pCache);
×
2240
    return NULL;
×
2241
  }
2242

2243
  return pCache;
251,138✔
2244
}
2245

2246
static void vtbRefFreeSchemaCache(SVtbRefSchemaCache* pCache) {
1,084,689✔
2247
  if (pCache == NULL) {
1,084,689✔
2248
    return;
518,051✔
2249
  }
2250
  if (pCache->ownsSchema) {
566,638✔
2251
    taosMemoryFree(pCache->schemaRow.pSchema);
566,638✔
2252
    // schemaTag.pSchema points into the same memory block as schemaRow.pSchema
2253
    // Only free once to avoid double-free
2254
    pCache->schemaTag.pSchema = NULL;
566,638✔
2255
  }
2256
  taosHashCleanup(pCache->pColNameIndex);
566,638✔
2257
  taosMemoryFree(pCache);
566,638✔
2258
}
2259

2260
// Free cache entry (for hash table cleanup)
2261
static void vtbRefFreeTableCacheEntry(void* p) {
×
2262
  SVtbRefTableCacheEntry* pEntry = (SVtbRefTableCacheEntry*)p;
×
2263
  if (pEntry != NULL) {
×
2264
    vtbRefFreeSchemaCache(pEntry->pSchemaCache);
×
2265
    taosMemoryFree(pEntry);
×
2266
  }
2267
}
×
2268

2269
static bool vtbRefCheckColumnInCache(const SVtbRefSchemaCache* pCache, const char* colName) {
912,426✔
2270
  if (pCache == NULL || colName == NULL || pCache->pColNameIndex == NULL) {
912,426✔
2271
    return false;
×
2272
  }
2273
  return taosHashGet(pCache->pColNameIndex, colName, strlen(colName)) != NULL;
912,426✔
2274
}
2275

2276
static int32_t vtbRefCreateSchemaCacheFromMetaRsp(STableMetaRsp* pMetaRsp, SVtbRefSchemaCache** ppCache) {
315,500✔
2277
  int32_t code = TSDB_CODE_SUCCESS;
315,500✔
2278

2279
  if (pMetaRsp == NULL || pMetaRsp->pSchemas == NULL) {
315,500✔
2280
    code = TSDB_CODE_INVALID_PARA;
×
2281
    return code;
×
2282
  }
2283

2284
  SVtbRefSchemaCache* pCache = taosMemoryCalloc(1, sizeof(SVtbRefSchemaCache));
315,500✔
2285
  if (pCache == NULL) {
315,500✔
2286
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2287
    return code;
×
2288
  }
2289

2290
  int32_t numOfCols = pMetaRsp->numOfColumns;
315,500✔
2291
  int32_t numOfTags = pMetaRsp->numOfTags;
315,500✔
2292
  int32_t totalCols = numOfCols + numOfTags;
315,500✔
2293

2294
  SSchema* pAllSchemas = taosMemoryMalloc(totalCols * sizeof(SSchema));
315,500✔
2295
  if (pAllSchemas == NULL) {
315,500✔
2296
    taosMemoryFree(pCache);
×
2297
    code = TSDB_CODE_OUT_OF_MEMORY;
×
2298
    return code;
×
2299
  }
2300
  memcpy(pAllSchemas, pMetaRsp->pSchemas, totalCols * sizeof(SSchema));
315,500✔
2301

2302
  pCache->schemaRow.nCols = numOfCols;
315,500✔
2303
  pCache->schemaRow.pSchema = pAllSchemas;
315,500✔
2304
  pCache->schemaTag.nCols = numOfTags;
315,500✔
2305
  pCache->schemaTag.pSchema = (numOfTags > 0) ? pAllSchemas + numOfCols : NULL;
315,500✔
2306
  pCache->hasTagSchema = (numOfTags > 0);
315,500✔
2307
  pCache->ownsSchema = true;
315,500✔
2308
  code = vtbRefBuildColNameIndex(pAllSchemas, numOfCols, numOfTags, &pCache->pColNameIndex);
315,500✔
2309

2310
  if (code != TSDB_CODE_SUCCESS) {
315,500✔
2311
    taosMemoryFree(pAllSchemas);
×
2312
    taosMemoryFree(pCache);
×
2313
    return code;
×
2314
  }
2315

2316
  *ppCache = pCache;
315,500✔
2317
  return TSDB_CODE_SUCCESS;
315,500✔
2318
}
2319

2320
static void vtbRefBuildRemoteCacheKey(char* buf, int32_t size, const char* dbName, const char* tableName) {
1,167,981✔
2321
  snprintf(buf, size, "%s.%s", dbName, tableName);
1,167,981✔
2322
}
1,167,981✔
2323

2324
static SVtbRefTableCacheEntry* vtbRefGetRemoteCacheEntry(SHashObj* pTableCache, const char* dbName,
852,481✔
2325
                                                         const char* tableName) {
2326
  char key[TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + 2];
852,481✔
2327
  vtbRefBuildRemoteCacheKey(key, sizeof(key), dbName, tableName);
852,481✔
2328
  return (SVtbRefTableCacheEntry*)taosHashGet(pTableCache, key, strlen(key));
852,481✔
2329
}
2330

2331
static int32_t vtbRefPutRemoteCacheEntry(SHashObj* pTableCache, const char* dbName, const char* tableName,
315,500✔
2332
                                         SVtbRefTableCacheEntry* pEntry) {
2333
  char key[TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + 2];
315,500✔
2334
  vtbRefBuildRemoteCacheKey(key, sizeof(key), dbName, tableName);
315,500✔
2335
  int32_t code = taosHashPut(pTableCache, key, strlen(key), pEntry, sizeof(SVtbRefTableCacheEntry));
315,500✔
2336

2337
  return (code == TSDB_CODE_DUP_KEY) ? TSDB_CODE_SUCCESS : code;
315,500✔
2338
}
2339

2340
// Callback for async RPC responses during validation
2341
static int32_t vtbRefValidateCallback(void* param, SDataBuf* pMsg, int32_t code) {
855,005✔
2342
  SVtbRefValidateCtx* pCtx = (SVtbRefValidateCtx*)param;
855,005✔
2343
  if (TSDB_CODE_SUCCESS == code) {
855,005✔
2344
    pCtx->pRsp = pMsg->pData;
725,019✔
2345
    pCtx->rspLen = (int32_t)pMsg->len;
725,019✔
2346
    pCtx->rspCode = TSDB_CODE_SUCCESS;
725,019✔
2347
  } else {
2348
    pCtx->rspCode = rpcCvtErrCode(code);
129,986✔
2349
    pCtx->pRsp = NULL;
129,986✔
2350
    pCtx->rspLen = 0;
129,986✔
2351
  }
2352
  int32_t res = tsem_post(&pCtx->ready);
855,005✔
2353
  if (res != TSDB_CODE_SUCCESS) {
855,005✔
2354
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(res));
×
2355
  }
2356
  return TSDB_CODE_SUCCESS;
855,005✔
2357
}
2358

2359
// Fetch DB vgroup info from MNode via RPC
2360
static int32_t vtbRefGetDbVgInfo(void* clientRpc, SEpSet* pEpSet, int32_t acctId, const char* dbName, uint64_t reqId,
499,121✔
2361
                                 SDBVgInfo** ppVgInfo) {
2362
  int32_t            code = TSDB_CODE_SUCCESS;
499,121✔
2363
  int32_t            lino = 0;
499,121✔
2364
  SVtbRefValidateCtx ctx = {0};
499,121✔
2365
  SUseDbReq          usedbReq = {0};
499,121✔
2366
  SUseDbRsp          usedbRsp = {0};
499,121✔
2367
  SUseDbOutput       output = {0};
499,121✔
2368
  char*              buf = NULL;
499,121✔
2369

2370
  code = tsem_init(&ctx.ready, 0, 0);
499,121✔
2371
  QUERY_CHECK_CODE(code, lino, _return);
499,121✔
2372

2373
  // Build full db name: "acctId.dbName"
2374
  (void)snprintf(usedbReq.db, sizeof(usedbReq.db), "%d.%s", acctId, dbName);
499,121✔
2375

2376
  int32_t contLen = tSerializeSUseDbReq(NULL, 0, &usedbReq);
499,121✔
2377
  buf = taosMemoryCalloc(1, contLen);
499,121✔
2378
  QUERY_CHECK_NULL(buf, code, lino, _return, terrno);
499,121✔
2379

2380
  int32_t tempRes = tSerializeSUseDbReq(buf, contLen, &usedbReq);
499,121✔
2381
  if (tempRes < 0) {
499,121✔
2382
    code = terrno;
×
2383
    QUERY_CHECK_CODE(code, lino, _return);
×
2384
  }
2385

2386
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
499,121✔
2387
  QUERY_CHECK_NULL(pMsgSendInfo, code, lino, _return, terrno);
499,121✔
2388

2389
  pMsgSendInfo->param = &ctx;
499,121✔
2390
  pMsgSendInfo->msgInfo.pData = buf;
499,121✔
2391
  pMsgSendInfo->msgInfo.len = contLen;
499,121✔
2392
  pMsgSendInfo->msgType = TDMT_MND_GET_DB_INFO;
499,121✔
2393
  pMsgSendInfo->fp = vtbRefValidateCallback;
499,121✔
2394
  pMsgSendInfo->requestId = reqId;
499,121✔
2395

2396
  code = asyncSendMsgToServer(clientRpc, pEpSet, NULL, pMsgSendInfo);
499,121✔
2397
  if (code != TSDB_CODE_SUCCESS) {
499,121✔
2398
    // buf is owned by pMsgSendInfo now, don't free it
2399
    buf = NULL;
×
2400
    QUERY_CHECK_CODE(code, lino, _return);
×
2401
  }
2402
  buf = NULL;  // ownership transferred to pMsgSendInfo
499,121✔
2403

2404
  code = tsem_timewait(&ctx.ready, VTB_REF_RPC_TIMEOUT_MS);
499,121✔
2405
  QUERY_CHECK_CODE(code, lino, _return);
499,121✔
2406

2407
  if (ctx.rspCode != TSDB_CODE_SUCCESS) {
499,121✔
2408
    code = ctx.rspCode;
89,602✔
2409
    QUERY_CHECK_CODE(code, lino, _return);
89,602✔
2410
  }
2411

2412
  // Parse the response
2413
  SUseDbRsp* pRsp = taosMemoryMalloc(sizeof(SUseDbRsp));
409,519✔
2414
  QUERY_CHECK_NULL(pRsp, code, lino, _return, terrno);
409,519✔
2415

2416
  code = tDeserializeSUseDbRsp(ctx.pRsp, ctx.rspLen, pRsp);
409,519✔
2417
  if (code != TSDB_CODE_SUCCESS) {
409,519✔
2418
    taosMemoryFree(pRsp);
×
2419
    QUERY_CHECK_CODE(code, lino, _return);
×
2420
  }
2421

2422
  code = queryBuildUseDbOutput(&output, pRsp);
409,519✔
2423
  tFreeSUsedbRsp(pRsp);
409,519✔
2424
  taosMemoryFree(pRsp);
409,519✔
2425
  QUERY_CHECK_CODE(code, lino, _return);
409,519✔
2426

2427
  *ppVgInfo = output.dbVgroup;
409,519✔
2428
  output.dbVgroup = NULL;  // ownership transferred
409,519✔
2429

2430
_return:
499,121✔
2431
  taosMemoryFreeClear(ctx.pRsp);
499,121✔
2432
  TAOS_UNUSED(tsem_destroy(&ctx.ready));
499,121✔
2433
  taosMemoryFree(buf);
499,121✔
2434
  if (output.dbVgroup) {
499,121✔
2435
    freeVgInfo(output.dbVgroup);
×
2436
  }
2437
  if (code != TSDB_CODE_SUCCESS) {
499,121✔
2438
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
89,602✔
2439
  }
2440
  return code;
499,121✔
2441
}
2442

2443
static int vtbRefVgInfoComp(const void* lp, const void* rp) {
819,038✔
2444
  SVgroupInfo* pLeft = (SVgroupInfo*)lp;
819,038✔
2445
  SVgroupInfo* pRight = (SVgroupInfo*)rp;
819,038✔
2446
  if (pLeft->hashBegin < pRight->hashBegin) return -1;
819,038✔
2447
  if (pLeft->hashBegin > pRight->hashBegin) return 1;
×
2448
  return 0;
×
2449
}
2450

2451
static int vtbRefHashValueComp(const void* lp, const void* rp) {
798,215✔
2452
  uint32_t*    key = (uint32_t*)lp;
798,215✔
2453
  SVgroupInfo* pVg = (SVgroupInfo*)rp;
798,215✔
2454
  if (*key < pVg->hashBegin) return -1;
798,215✔
2455
  if (*key > pVg->hashEnd) return 1;
798,215✔
2456
  return 0;
492,180✔
2457
}
2458

2459
// Calculate vgId for a table within a database's vgroup info
2460
static int32_t vtbRefGetVgId(SDBVgInfo* dbInfo, const char* dbFName, const char* tbName, int32_t* pVgId,
492,180✔
2461
                             SEpSet* pEpSet) {
2462
  int32_t code = TSDB_CODE_SUCCESS;
492,180✔
2463
  int32_t lino = 0;
492,180✔
2464

2465
  // Build vgArray if not already built
2466
  if (dbInfo->vgHash && NULL == dbInfo->vgArray) {
492,180✔
2467
    int32_t vgSize = taosHashGetSize(dbInfo->vgHash);
409,519✔
2468
    dbInfo->vgArray = taosArrayInit(vgSize, sizeof(SVgroupInfo));
409,519✔
2469
    QUERY_CHECK_NULL(dbInfo->vgArray, code, lino, _return, terrno);
409,519✔
2470

2471
    void* pIter = taosHashIterate(dbInfo->vgHash, NULL);
409,519✔
2472
    while (pIter) {
1,228,557✔
2473
      if (NULL == taosArrayPush(dbInfo->vgArray, pIter)) {
1,638,076✔
2474
        taosHashCancelIterate(dbInfo->vgHash, pIter);
×
2475
        code = terrno;
×
2476
        QUERY_CHECK_CODE(code, lino, _return);
×
2477
      }
2478
      pIter = taosHashIterate(dbInfo->vgHash, pIter);
819,038✔
2479
    }
2480

2481
    taosArraySort(dbInfo->vgArray, vtbRefVgInfoComp);
409,519✔
2482
  }
2483

2484
  int32_t vgNum = (int32_t)taosArrayGetSize(dbInfo->vgArray);
492,180✔
2485
  if (vgNum <= 0) {
492,180✔
2486
    qError("db vgroup cache invalid, db:%s, vgroup number:%d", dbFName, vgNum);
×
2487
    code = TSDB_CODE_TSC_DB_NOT_SELECTED;
×
2488
    QUERY_CHECK_CODE(code, lino, _return);
×
2489
  }
2490

2491
  // Calculate hash value for the table
2492
  char tbFullName[TSDB_TABLE_FNAME_LEN];
492,180✔
2493
  (void)snprintf(tbFullName, sizeof(tbFullName), "%s.%s", dbFName, tbName);
492,180✔
2494
  uint32_t hashValue = taosGetTbHashVal(tbFullName, (int32_t)strlen(tbFullName), dbInfo->hashMethod, dbInfo->hashPrefix,
984,360✔
2495
                                        dbInfo->hashSuffix);
492,180✔
2496

2497
  // Binary search for the vgroup
2498
  SVgroupInfo* vgInfo = taosArraySearch(dbInfo->vgArray, &hashValue, vtbRefHashValueComp, TD_EQ);
492,180✔
2499

2500
  if (NULL == vgInfo) {
492,180✔
2501
    qError("no hash range found for hash value [%u], db:%s, numOfVgId:%d", hashValue, dbFName, vgNum);
×
2502
    code = TSDB_CODE_CTG_INTERNAL_ERROR;
×
2503
    QUERY_CHECK_CODE(code, lino, _return);
×
2504
  }
2505

2506
  *pVgId = vgInfo->vgId;
492,180✔
2507
  if (pEpSet) {
492,180✔
2508
    *pEpSet = vgInfo->epSet;
492,180✔
2509
  }
2510

2511
_return:
492,180✔
2512
  if (code != TSDB_CODE_SUCCESS) {
492,180✔
2513
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2514
  }
2515
  return code;
492,180✔
2516
}
2517

2518
// Fetch table schema from a specific vnode via RPC
2519
static int32_t vtbRefFetchTableSchema(void* clientRpc, SEpSet* pVnodeEpSet, int32_t acctId, const char* dbName,
355,884✔
2520
                                      const char* tbName, int32_t vgId, uint64_t reqId, STableMetaRsp* pMetaRsp) {
2521
  int32_t            code = TSDB_CODE_SUCCESS;
355,884✔
2522
  int32_t            lino = 0;
355,884✔
2523
  SVtbRefValidateCtx ctx = {0};
355,884✔
2524
  char*              buf = NULL;
355,884✔
2525

2526
  code = tsem_init(&ctx.ready, 0, 0);
355,884✔
2527
  QUERY_CHECK_CODE(code, lino, _return);
355,884✔
2528

2529
  // Build the table info request
2530
  STableInfoReq infoReq = {0};
355,884✔
2531
  infoReq.header.vgId = vgId;
355,884✔
2532
  infoReq.option = REQ_OPT_TBNAME;
355,884✔
2533
  (void)snprintf(infoReq.dbFName, sizeof(infoReq.dbFName), "%d.%s", acctId, dbName);
355,884✔
2534
  tstrncpy(infoReq.tbName, tbName, TSDB_TABLE_NAME_LEN);
355,884✔
2535

2536
  int32_t contLen = tSerializeSTableInfoReq(NULL, 0, &infoReq);
355,884✔
2537
  buf = taosMemoryCalloc(1, contLen);
355,884✔
2538
  QUERY_CHECK_NULL(buf, code, lino, _return, terrno);
355,884✔
2539

2540
  int32_t tempRes = tSerializeSTableInfoReq(buf, contLen, &infoReq);
355,884✔
2541
  if (tempRes < 0) {
355,884✔
2542
    code = terrno;
×
2543
    QUERY_CHECK_CODE(code, lino, _return);
×
2544
  }
2545

2546
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
355,884✔
2547
  QUERY_CHECK_NULL(pMsgSendInfo, code, lino, _return, terrno);
355,884✔
2548

2549
  pMsgSendInfo->param = &ctx;
355,884✔
2550
  pMsgSendInfo->msgInfo.pData = buf;
355,884✔
2551
  pMsgSendInfo->msgInfo.len = contLen;
355,884✔
2552
  pMsgSendInfo->msgType = TDMT_VND_TABLE_META;
355,884✔
2553
  pMsgSendInfo->fp = vtbRefValidateCallback;
355,884✔
2554
  pMsgSendInfo->requestId = reqId;
355,884✔
2555

2556
  code = asyncSendMsgToServer(clientRpc, pVnodeEpSet, NULL, pMsgSendInfo);
355,884✔
2557
  if (code != TSDB_CODE_SUCCESS) {
355,884✔
2558
    // asyncSendMsgToServer already freed pMsgSendInfo (and buf via destroySendMsgInfo) on failure
2559
    buf = NULL;
×
2560
    QUERY_CHECK_CODE(code, lino, _return);
×
2561
  }
2562
  buf = NULL;  // ownership transferred to pMsgSendInfo, will be freed by destroySendMsgInfo
355,884✔
2563

2564
  code = tsem_timewait(&ctx.ready, VTB_REF_RPC_TIMEOUT_MS);
355,884✔
2565
  QUERY_CHECK_CODE(code, lino, _return);
355,884✔
2566

2567
  if (ctx.rspCode != TSDB_CODE_SUCCESS) {
355,884✔
2568
    code = ctx.rspCode;
40,384✔
2569
    QUERY_CHECK_CODE(code, lino, _return);
40,384✔
2570
  }
2571

2572
  // Deserialize table meta response
2573
  code = tDeserializeSTableMetaRsp(ctx.pRsp, ctx.rspLen, pMetaRsp);
315,500✔
2574
  QUERY_CHECK_CODE(code, lino, _return);
315,500✔
2575

2576
_return:
355,884✔
2577
  taosMemoryFreeClear(ctx.pRsp);
355,884✔
2578
  TAOS_UNUSED(tsem_destroy(&ctx.ready));
355,884✔
2579
  taosMemoryFree(buf);
355,884✔
2580
  if (code != TSDB_CODE_SUCCESS) {
355,884✔
2581
    qError("%s failed at line %d since %s, db:%s, tb:%s", __func__, lino, tstrerror(code), dbName, tbName);
40,384✔
2582
  }
2583
  return code;
355,884✔
2584
}
2585

2586
// Check if a column exists in a table schema
2587
static bool vtbRefColExistsInSchema(SSchema* pSchemas, int32_t numOfCols, int32_t numOfTags, const char* colName) {
315,500✔
2588
  int32_t totalCols = numOfCols + numOfTags;
315,500✔
2589
  for (int32_t j = 0; j < totalCols; ++j) {
793,798✔
2590
    if (strcmp(pSchemas[j].name, colName) == 0) {
792,536✔
2591
      return true;
314,238✔
2592
    }
2593
  }
2594
  return false;
1,262✔
2595
}
2596

2597
// Get table schema from local vnode meta and cache it
2598
// Returns: TSDB_CODE_SUCCESS with pEntry filled, or error code
2599
static int32_t vtbRefGetTableSchemaLocal(const SSysTableScanInfo* pInfo, SStorageAPI* pAPI, const char* refTableName,
1,494,208✔
2600
                                         SHashObj* pTableCache, SVtbRefTableCacheEntry** ppEntry) {
2601
  int32_t     code = TSDB_CODE_SUCCESS;
1,494,208✔
2602
  SMetaReader srcReader = {0};
1,494,208✔
2603

2604
  // Check cache first
2605
  SVtbRefTableCacheEntry* pEntry = taosHashGet(pTableCache, refTableName, strlen(refTableName));
1,494,208✔
2606
  if (pEntry != NULL) {
1,494,208✔
2607
    *ppEntry = pEntry;
725,019✔
2608
    return TSDB_CODE_SUCCESS;
725,019✔
2609
  }
2610

2611
  // Create new cache entry
2612
  pEntry = taosMemoryCalloc(1, sizeof(SVtbRefTableCacheEntry));
769,189✔
2613
  if (pEntry == NULL) {
769,189✔
2614
    return terrno;
×
2615
  }
2616

2617
  pAPI->metaReaderFn.initReader(&srcReader, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
769,189✔
2618
  code = pAPI->metaReaderFn.getTableEntryByName(&srcReader, refTableName);
769,189✔
2619

2620
  if (code != TSDB_CODE_SUCCESS) {
769,189✔
2621
    pAPI->metaReaderFn.clearReader(&srcReader);
518,051✔
2622
    pEntry->errCode = TSDB_CODE_TDB_TABLE_NOT_EXIST;
518,051✔
2623
    pEntry->pSchemaCache = NULL;
518,051✔
2624
  } else {
2625
    ETableType tableType = srcReader.me.type;
251,138✔
2626
    if (tableType == TSDB_CHILD_TABLE) {
251,138✔
2627
      int64_t suid = srcReader.me.ctbEntry.suid;
66,255✔
2628
      pAPI->metaReaderFn.clearReader(&srcReader);
66,255✔
2629
      pAPI->metaReaderFn.initReader(&srcReader, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
66,255✔
2630
      code = pAPI->metaReaderFn.getTableEntryByUid(&srcReader, suid);
66,255✔
2631
      if (code != TSDB_CODE_SUCCESS) {
66,255✔
2632
        pAPI->metaReaderFn.clearReader(&srcReader);
×
2633
        pEntry->errCode = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2634
        pEntry->pSchemaCache = NULL;
×
2635
      } else {
2636
        pEntry->pSchemaCache = vtbRefCreateSchemaCache(srcReader.me.type, &srcReader);
66,255✔
2637
        pEntry->errCode = (pEntry->pSchemaCache != NULL) ? TSDB_CODE_SUCCESS : terrno;
66,255✔
2638
        pAPI->metaReaderFn.clearReader(&srcReader);
66,255✔
2639
      }
2640
    } else if (tableType == TSDB_NORMAL_TABLE || tableType == TSDB_SUPER_TABLE) {
184,883✔
2641
      pEntry->pSchemaCache = vtbRefCreateSchemaCache(tableType, &srcReader);
184,883✔
2642
      pEntry->errCode = (pEntry->pSchemaCache != NULL) ? TSDB_CODE_SUCCESS : terrno;
184,883✔
2643
      pAPI->metaReaderFn.clearReader(&srcReader);
184,883✔
2644
    } else {
2645
      pAPI->metaReaderFn.clearReader(&srcReader);
×
2646
      pEntry->errCode = TSDB_CODE_PAR_INVALID_REF_COLUMN;
×
2647
      pEntry->pSchemaCache = NULL;
×
2648
    }
2649
  }
2650

2651
  // Add to cache
2652
  code = taosHashPut(pTableCache, refTableName, strlen(refTableName), pEntry, sizeof(SVtbRefTableCacheEntry));
769,189✔
2653
  if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_DUP_KEY) {
769,189✔
2654
    vtbRefFreeTableCacheEntry(pEntry);
×
2655
    return code;
×
2656
  }
2657

2658
  if (code == TSDB_CODE_DUP_KEY) {
769,189✔
2659
    // Another thread inserted first - free our new entry completely
2660
    vtbRefFreeTableCacheEntry(pEntry);
×
2661
  } else {
2662
    // Success - free original struct only, schema cache owned by hash table copy
2663
    taosMemoryFree(pEntry);
769,189✔
2664
  }
2665

2666
  // Return pointer to hash table's entry (not the freed original)
2667
  *ppEntry = (SVtbRefTableCacheEntry*)taosHashGet(pTableCache, refTableName, strlen(refTableName));
769,189✔
2668
  return TSDB_CODE_SUCCESS;
769,189✔
2669
}
2670

2671
// Try to validate source table and column using local vnode meta
2672
static int32_t vtbRefValidateLocal(const SSysTableScanInfo* pInfo, SStorageAPI* pAPI, const char* refTableName,
×
2673
                                   const char* refColName, int32_t* pErrCode) {
2674
  int32_t     code = TSDB_CODE_SUCCESS;
×
2675
  SMetaReader srcReader = {0};
×
2676

2677
  pAPI->metaReaderFn.initReader(&srcReader, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
×
2678
  code = pAPI->metaReaderFn.getTableEntryByName(&srcReader, refTableName);
×
2679

2680
  if (code != TSDB_CODE_SUCCESS) {
×
2681
    // Table not found locally - could be on another vnode or deleted
2682
    pAPI->metaReaderFn.clearReader(&srcReader);
×
2683
    *pErrCode = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2684
    return TSDB_CODE_SUCCESS;  // Not a fatal error, just table not on this vnode
×
2685
  }
2686

2687
  // Table found locally, check column existence
2688
  SSchemaWrapper* pSchemaRow = NULL;
×
2689
  SSchemaWrapper* pTagSchema = NULL;
×
2690
  if (srcReader.me.type == TSDB_NORMAL_TABLE) {
×
2691
    pSchemaRow = &srcReader.me.ntbEntry.schemaRow;
×
2692
  } else if (srcReader.me.type == TSDB_CHILD_TABLE) {
×
2693
    // For child table, we need to get the super table schema
2694
    int64_t suid = srcReader.me.ctbEntry.suid;
×
2695
    pAPI->metaReaderFn.clearReader(&srcReader);
×
2696

2697
    pAPI->metaReaderFn.initReader(&srcReader, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
×
2698
    code = pAPI->metaReaderFn.getTableEntryByUid(&srcReader, suid);
×
2699
    if (code != TSDB_CODE_SUCCESS) {
×
2700
      pAPI->metaReaderFn.clearReader(&srcReader);
×
2701
      *pErrCode = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2702
      return TSDB_CODE_SUCCESS;
×
2703
    }
2704
    pSchemaRow = &srcReader.me.stbEntry.schemaRow;
×
2705
    pTagSchema = &srcReader.me.stbEntry.schemaTag;
×
2706
  } else if (srcReader.me.type == TSDB_SUPER_TABLE) {
×
2707
    pSchemaRow = &srcReader.me.stbEntry.schemaRow;
×
2708
    pTagSchema = &srcReader.me.stbEntry.schemaTag;
×
2709
  } else {
2710
    pAPI->metaReaderFn.clearReader(&srcReader);
×
2711
    *pErrCode = TSDB_CODE_PAR_INVALID_REF_COLUMN;
×
2712
    return TSDB_CODE_SUCCESS;
×
2713
  }
2714

2715
  // Check column existence in schema
2716
  bool found = false;
×
2717
  for (int32_t j = 0; j < pSchemaRow->nCols; ++j) {
×
2718
    if (strcmp(pSchemaRow->pSchema[j].name, refColName) == 0) {
×
2719
      found = true;
×
2720
      break;
×
2721
    }
2722
  }
2723
  if (!found && pTagSchema) {
×
2724
    for (int32_t j = 0; j < pTagSchema->nCols; ++j) {
×
2725
      if (strcmp(pTagSchema->pSchema[j].name, refColName) == 0) {
×
2726
        found = true;
×
2727
        break;
×
2728
      }
2729
    }
2730
  }
2731

2732
  pAPI->metaReaderFn.clearReader(&srcReader);
×
2733
  *pErrCode = found ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_INVALID_REF_COLUMN;
×
2734
  return TSDB_CODE_SUCCESS;
×
2735
}
2736

2737
static int32_t vtbRefValidateRemote(void* clientRpc, SEpSet* pMnodeEpSet, int32_t acctId, const char* refDbName,
581,782✔
2738
                                    const char* refTableName, const char* refColName, uint64_t reqId,
2739
                                    SHashObj* pDbVgInfoCache, SHashObj* pTableCache, int32_t localVgId,
2740
                                    int32_t* pErrCode) {
2741
  int32_t       code = TSDB_CODE_SUCCESS;
581,782✔
2742
  int32_t       lino = 0;
581,782✔
2743
  SDBVgInfo*    pDbVgInfo = NULL;
581,782✔
2744
  STableMetaRsp metaRsp = {0};
581,782✔
2745
  bool          metaRspInited = false;
581,782✔
2746

2747
  // Step 1: Get DB vgroup info (with caching)
2748
  SDBVgInfo** ppCached = (SDBVgInfo**)taosHashGet(pDbVgInfoCache, refDbName, strlen(refDbName));
581,782✔
2749
  if (ppCached) {
581,782✔
2750
    pDbVgInfo = *ppCached;
82,661✔
2751
  } else {
2752
    code = vtbRefGetDbVgInfo(clientRpc, pMnodeEpSet, acctId, refDbName, reqId, &pDbVgInfo);
499,121✔
2753
    if (code != TSDB_CODE_SUCCESS) {
499,121✔
2754
      // DB doesn't exist or network error
2755
      *pErrCode = TSDB_CODE_MND_DB_NOT_EXIST;
89,602✔
2756
      code = TSDB_CODE_SUCCESS;  // not a fatal error for validation
89,602✔
2757
      goto _return;
89,602✔
2758
    }
2759
    code = taosHashPut(pDbVgInfoCache, refDbName, strlen(refDbName), &pDbVgInfo, POINTER_BYTES);
409,519✔
2760
    if (code == TSDB_CODE_DUP_KEY) {
409,519✔
2761
      code = TSDB_CODE_SUCCESS;
×
2762
    }
2763
    QUERY_CHECK_CODE(code, lino, _return);
409,519✔
2764
  }
2765

2766
  // Step 2: Calculate vgId for the source table
2767
  int32_t vgId = 0;
492,180✔
2768
  SEpSet  vnodeEpSet = {0};
492,180✔
2769
  char    dbFName[TSDB_DB_FNAME_LEN] = {0};
492,180✔
2770
  (void)snprintf(dbFName, sizeof(dbFName), "%d.%s", acctId, refDbName);
492,180✔
2771

2772
  code = vtbRefGetVgId(pDbVgInfo, dbFName, refTableName, &vgId, &vnodeEpSet);
492,180✔
2773
  if (code != TSDB_CODE_SUCCESS) {
492,180✔
2774
    *pErrCode = TSDB_CODE_PAR_TABLE_NOT_EXIST;
×
2775
    code = TSDB_CODE_SUCCESS;
×
2776
    goto _return;
×
2777
  }
2778

2779
  // If the target vnode is the same as the local vnode, the table was already
2780
  // checked locally (and not found). Skip the RPC to avoid self-deadlock.
2781
  if (vgId == localVgId) {
492,180✔
2782
    *pErrCode = TSDB_CODE_PAR_TABLE_NOT_EXIST;
136,296✔
2783
    code = TSDB_CODE_SUCCESS;
136,296✔
2784
    goto _return;
136,296✔
2785
  }
2786

2787
  // Step 3: Fetch table schema from the target vnode
2788
  code = vtbRefFetchTableSchema(clientRpc, &vnodeEpSet, acctId, refDbName, refTableName, vgId, reqId, &metaRsp);
355,884✔
2789
  metaRspInited = true;
355,884✔
2790
  if (code != TSDB_CODE_SUCCESS) {
355,884✔
2791
    // Table doesn't exist on the target vnode
2792
    *pErrCode = TSDB_CODE_PAR_TABLE_NOT_EXIST;
40,384✔
2793
    code = TSDB_CODE_SUCCESS;
40,384✔
2794
    goto _return;
40,384✔
2795
  }
2796

2797
  bool found = vtbRefColExistsInSchema(metaRsp.pSchemas, metaRsp.numOfColumns, metaRsp.numOfTags, refColName);
315,500✔
2798
  *pErrCode = found ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_INVALID_REF_COLUMN;
315,500✔
2799

2800
  if (pTableCache != NULL) {
315,500✔
2801
    SVtbRefTableCacheEntry* pNewEntry = taosMemoryCalloc(1, sizeof(SVtbRefTableCacheEntry));
315,500✔
2802
    if (pNewEntry != NULL) {
315,500✔
2803
      int32_t cacheCode = vtbRefCreateSchemaCacheFromMetaRsp(&metaRsp, &pNewEntry->pSchemaCache);
315,500✔
2804
      if (cacheCode == TSDB_CODE_SUCCESS) {
315,500✔
2805
        pNewEntry->errCode = TSDB_CODE_SUCCESS;
315,500✔
2806
        int32_t putCode = vtbRefPutRemoteCacheEntry(pTableCache, refDbName, refTableName, pNewEntry);
315,500✔
2807
        if (putCode == TSDB_CODE_SUCCESS) {
315,500✔
2808
          taosMemoryFree(pNewEntry);  // Free struct only, schema cache owned by hash table
315,500✔
2809
        } else {
2810
          vtbRefFreeTableCacheEntry(pNewEntry);  // Free both on failure
×
2811
        }
2812
      } else {
2813
        taosMemoryFree(pNewEntry);
×
2814
      }
2815
    }
2816
  }
2817

2818
_return:
581,782✔
2819
  if (metaRspInited) {
581,782✔
2820
    tFreeSTableMetaRsp(&metaRsp);
355,884✔
2821
  }
2822
  if (code != TSDB_CODE_SUCCESS) {
581,782✔
2823
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2824
  }
2825
  return code;
581,782✔
2826
}
2827

2828
static int32_t validateSrcTableColRef(const SSysTableScanInfo* pInfo, SExecTaskInfo* pTaskInfo, SSchemaWrapper* pSchema,
639,203✔
2829
                                      SColRefWrapper* pColRef, SArray* pResult) {
2830
  int32_t      code = TSDB_CODE_SUCCESS;
639,203✔
2831
  int32_t      lino = 0;
639,203✔
2832
  SStorageAPI* pAPI = &pTaskInfo->storageAPI;
639,203✔
2833

2834
  if (pSchema == NULL || pColRef == NULL || pResult == NULL) {
639,203✔
2835
    return TSDB_CODE_INVALID_PARA;
×
2836
  }
2837

2838
  int32_t localVgId = 0;
639,203✔
2839
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, NULL, &localVgId, NULL, NULL);
639,203✔
2840

2841
  SHashObj* pDbVgInfoCache = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
639,203✔
2842
  if (pDbVgInfoCache == NULL) {
639,203✔
2843
    return terrno;
×
2844
  }
2845

2846
  SHashObj* pTableCache = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
639,203✔
2847
  if (pTableCache == NULL) {
639,203✔
2848
    taosHashCleanup(pDbVgInfoCache);
×
2849
    return terrno;
×
2850
  }
2851

2852
  for (int32_t i = 0; i < pSchema->nCols; ++i) {
2,780,817✔
2853
    int32_t errCode = TSDB_CODE_SUCCESS;
2,141,614✔
2854

2855
    if (i == 0 || pColRef == NULL || i >= pColRef->nCols || !pColRef->pColRef[i].hasRef) {
2,141,614✔
2856
      if (NULL == taosArrayPush(pResult, &errCode)) {
647,406✔
2857
        code = terrno;
×
2858
        QUERY_CHECK_CODE(code, lino, _end);
×
2859
      }
2860
      continue;
647,406✔
2861
    }
2862

2863
    const char* refDbName = pColRef->pColRef[i].refDbName;
1,494,208✔
2864
    const char* refTableName = pColRef->pColRef[i].refTableName;
1,494,208✔
2865
    const char* refColName = pColRef->pColRef[i].refColName;
1,494,208✔
2866

2867
    SVtbRefTableCacheEntry* pEntry = NULL;
1,494,208✔
2868
    code = vtbRefGetTableSchemaLocal(pInfo, pAPI, refTableName, pTableCache, &pEntry);
1,494,208✔
2869
    QUERY_CHECK_CODE(code, lino, _end);
1,494,208✔
2870

2871
    if (pEntry != NULL && pEntry->errCode == TSDB_CODE_SUCCESS && pEntry->pSchemaCache != NULL) {
1,494,208✔
2872
      errCode = vtbRefCheckColumnInCache(pEntry->pSchemaCache, refColName) ? TSDB_CODE_SUCCESS
1,283,454✔
2873
                                                                           : TSDB_CODE_PAR_INVALID_REF_COLUMN;
641,727✔
2874
    } else if (pEntry != NULL && pEntry->errCode == TSDB_CODE_TDB_TABLE_NOT_EXIST) {
852,481✔
2875
      if (pInfo->readHandle.pMsgCb && pInfo->readHandle.pMsgCb->clientRpc) {
1,704,962✔
2876
        SVtbRefTableCacheEntry* pRemoteEntry = vtbRefGetRemoteCacheEntry(pTableCache, refDbName, refTableName);
852,481✔
2877
        if (pRemoteEntry != NULL && pRemoteEntry->errCode == TSDB_CODE_SUCCESS && pRemoteEntry->pSchemaCache != NULL) {
852,481✔
2878
          errCode = vtbRefCheckColumnInCache(pRemoteEntry->pSchemaCache, refColName) ? TSDB_CODE_SUCCESS
541,398✔
2879
                                                                                     : TSDB_CODE_PAR_INVALID_REF_COLUMN;
270,699✔
2880
        } else if (pRemoteEntry != NULL && pRemoteEntry->errCode != TSDB_CODE_SUCCESS) {
581,782✔
2881
          errCode = pRemoteEntry->errCode;
×
2882
        } else {
2883
          errCode = TSDB_CODE_SUCCESS;
581,782✔
2884
          code = vtbRefValidateRemote(pInfo->readHandle.pMsgCb->clientRpc, (SEpSet*)&pInfo->epSet, pInfo->accountId,
581,782✔
2885
                                      refDbName, refTableName, refColName, pTaskInfo->id.queryId, pDbVgInfoCache,
2886
                                      pTableCache, localVgId, &errCode);
2887
          QUERY_CHECK_CODE(code, lino, _end);
581,782✔
2888
        }
2889
      } else {
2890
        errCode = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2891
      }
2892
    } else if (pEntry != NULL) {
×
2893
      errCode = pEntry->errCode;
×
2894
    } else {
2895
      errCode = TSDB_CODE_PAR_INVALID_REF_COLUMN;
×
2896
    }
2897

2898
    if (NULL == taosArrayPush(pResult, &errCode)) {
1,494,208✔
2899
      code = terrno;
×
2900
      QUERY_CHECK_CODE(code, lino, _end);
×
2901
    }
2902
  }
2903

2904
_end : {
639,203✔
2905
  void* pIter = taosHashIterate(pTableCache, NULL);
639,203✔
2906
  while (pIter) {
1,723,892✔
2907
    SVtbRefTableCacheEntry* pEntry = (SVtbRefTableCacheEntry*)pIter;
1,084,689✔
2908
    vtbRefFreeSchemaCache(pEntry->pSchemaCache);
1,084,689✔
2909
    pIter = taosHashIterate(pTableCache, pIter);
1,084,689✔
2910
  }
2911
  taosHashCleanup(pTableCache);
639,203✔
2912
}
2913
  {
2914
    void* pIter = taosHashIterate(pDbVgInfoCache, NULL);
639,203✔
2915
    while (pIter) {
1,048,722✔
2916
      SDBVgInfo** ppVgInfo = (SDBVgInfo**)pIter;
409,519✔
2917
      if (*ppVgInfo) {
409,519✔
2918
        freeVgInfo(*ppVgInfo);
409,519✔
2919
      }
2920
      pIter = taosHashIterate(pDbVgInfoCache, pIter);
409,519✔
2921
    }
2922
    taosHashCleanup(pDbVgInfoCache);
639,203✔
2923
  }
2924

2925
  if (code != TSDB_CODE_SUCCESS) {
639,203✔
2926
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2927
  }
2928
  return code;
639,203✔
2929
}
2930

2931
static int32_t getErrMsgFromCode(int32_t code, char* errMsg, int32_t cap) {
1,502,411✔
2932
  if (errMsg == NULL || cap <= 0) {
1,502,411✔
2933
    return TSDB_CODE_INVALID_PARA;
×
2934
  }
2935
  if (code != 0) {
1,502,411✔
2936
    char buf[128] = {0};
294,046✔
2937
    snprintf(buf, sizeof(buf), "%s", tstrerror(code));
294,046✔
2938
    STR_TO_VARSTR(errMsg, buf);
294,046✔
2939
  } else {
2940
    STR_TO_VARSTR(errMsg, "");
1,208,365✔
2941
  }
2942
  return TSDB_CODE_SUCCESS;
1,502,411✔
2943
}
2944

2945
static int32_t sysTableFillOneVirtualTableRefImpl(const SSysTableScanInfo* pInfo, SExecTaskInfo* pTaskInfo,
639,203✔
2946
                                                  const char* dbname, int32_t* pNumOfRows, const SSDataBlock* dataBlock,
2947
                                                  SSchemaWrapper* schemaRow, SColRefWrapper* pColRef,
2948
                                                  SVirtualTableRefInfo* pRef) {
2949
  int32_t code = TSDB_CODE_SUCCESS;
639,203✔
2950
  int32_t lino = 0;
639,203✔
2951
  if (schemaRow == NULL || schemaRow->pSchema == NULL) {
639,203✔
2952
    qError("sysTableFillOneVirtualTableRefImpl schemaRow or pSchema is NULL");
×
2953
    return TSDB_CODE_INVALID_PARA;
×
2954
  }
2955
  int32_t numOfRows = *pNumOfRows;
639,203✔
2956

2957
  int32_t numOfCols = schemaRow->nCols;
639,203✔
2958

2959
  SArray* pResult = taosArrayInit(numOfCols, sizeof(int32_t));
639,203✔
2960
  if (pResult == NULL) {
639,203✔
2961
    QUERY_CHECK_CODE(code = terrno, lino, _end);
×
2962
  }
2963
  // Only validate if pColRef is valid, otherwise just fill with error codes
2964
  if (pColRef != NULL) {
639,203✔
2965
    code = validateSrcTableColRef(pInfo, pTaskInfo, schemaRow, pColRef, pResult);
639,203✔
2966
    QUERY_CHECK_CODE(code, lino, _end);
639,203✔
2967
  } else {
2968
    // Fill pResult with success codes for all columns (columns without refs)
2969
    for (int32_t i = 0; i < numOfCols; ++i) {
×
2970
      int32_t errCode = TSDB_CODE_SUCCESS;
×
2971
      if (NULL == taosArrayPush(pResult, &errCode)) {
×
2972
        code = terrno;
×
2973
        QUERY_CHECK_CODE(code, lino, _end);
×
2974
      }
2975
    }
2976
  }
2977

2978
  for (int32_t i = 1; i < numOfCols; ++i) {
2,141,614✔
2979
    SColumnInfoData* pColInfoData = NULL;
1,502,411✔
2980

2981
    // Check if this column has a valid reference
2982
    bool    hasValidRef = (pColRef != NULL && i < pColRef->nCols && pColRef->pColRef[i].hasRef);
1,502,411✔
2983

2984
    // virtual db name
2985
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
1,502,411✔
2986
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
2987
    code = colDataSetVal(pColInfoData, numOfRows, pRef->vDbName, false);
1,502,411✔
2988
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
2989

2990
    // virtual stable name
2991
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
1,502,411✔
2992
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
2993
    code = colDataSetVal(pColInfoData, numOfRows, pRef->vStbName, false);
1,502,411✔
2994
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
2995

2996
    // virtual table name
2997
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
1,502,411✔
2998
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
2999
    code = colDataSetVal(pColInfoData, numOfRows, pRef->vTableName, false);
1,502,411✔
3000
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3001

3002
    // virtual col name
3003
    char vColName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,502,411✔
3004
    STR_TO_VARSTR(vColName, schemaRow->pSchema[i].name);
1,502,411✔
3005

3006
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
1,502,411✔
3007
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3008
    code = colDataSetVal(pColInfoData, numOfRows, vColName, false);
1,502,411✔
3009
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3010

3011
    // src db name
3012
    char    db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,502,411✔
3013
    if (hasValidRef) {
1,502,411✔
3014
      STR_TO_VARSTR(db, pColRef->pColRef[i].refDbName);
1,494,208✔
3015
    } else {
3016
      STR_TO_VARSTR(db, "");
8,203✔
3017
    }
3018

3019
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
1,502,411✔
3020
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3021
    code = colDataSetVal(pColInfoData, numOfRows, db, false);
1,502,411✔
3022
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3023

3024
    // src table name
3025
    char srcTableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,502,411✔
3026
    if (hasValidRef) {
1,502,411✔
3027
      STR_TO_VARSTR(srcTableName, pColRef->pColRef[i].refTableName);
1,494,208✔
3028
    } else {
3029
      STR_TO_VARSTR(srcTableName, "");
8,203✔
3030
    }
3031

3032
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
1,502,411✔
3033
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3034
    code = colDataSetVal(pColInfoData, numOfRows, srcTableName, false);
1,502,411✔
3035
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3036

3037
    // src col name
3038
    char srcColName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,502,411✔
3039
    if (hasValidRef) {
1,502,411✔
3040
      STR_TO_VARSTR(srcColName, pColRef->pColRef[i].refColName);
1,494,208✔
3041
    } else {
3042
      STR_TO_VARSTR(srcColName, "");
8,203✔
3043
    }
3044

3045
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 6);
1,502,411✔
3046
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3047
    code = colDataSetVal(pColInfoData, numOfRows, srcColName, false);
1,502,411✔
3048
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3049

3050
    // type (col ref type: 0=column, 1=tag)
3051
    int32_t colType = 0;  // default: column reference
1,502,411✔
3052
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 7);
1,502,411✔
3053
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3054
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&colType, false);
1,502,411✔
3055
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3056

3057
    // err_code
3058
    int32_t* pColErrCode = (int32_t*)taosArrayGet(pResult, i);
1,502,411✔
3059
    int64_t  errCodeVal = pColErrCode ? (int64_t)(*pColErrCode) : 0;
1,502,411✔
3060
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 8);
1,502,411✔
3061
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3062
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&errCodeVal, false);
1,502,411✔
3063
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3064

3065
    // err_msg
3066
    char    errMsg[TSDB_SHOW_VALIDATE_VIRTUAL_TABLE_ERROR + VARSTR_HEADER_SIZE] = {0};
1,502,411✔
3067
    int32_t colErrCode = pColErrCode ? *pColErrCode : 0;
1,502,411✔
3068
    code = getErrMsgFromCode(colErrCode, errMsg, sizeof(errMsg));
1,502,411✔
3069
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3070

3071
    pColInfoData = taosArrayGet(dataBlock->pDataBlock, 9);
1,502,411✔
3072
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
1,502,411✔
3073
    code = colDataSetVal(pColInfoData, numOfRows, errMsg, false);
1,502,411✔
3074
    QUERY_CHECK_CODE(code, lino, _end);
1,502,411✔
3075
    ++numOfRows;
1,502,411✔
3076
  }
3077
  *pNumOfRows = numOfRows;
639,203✔
3078
_end:
639,203✔
3079
  if (code != TSDB_CODE_SUCCESS) {
639,203✔
3080
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3081
  }
3082
  taosArrayDestroy(pResult);
639,203✔
3083
  return code;
639,203✔
3084
}
3085

3086
// static int32_t sysTableFillOneVirtualTableRef(const SSysTableScanInfo* pInfo, const char* dbname, int32_t*
3087
// pNumOfRows,
3088
//                                               const SSDataBlock* dataBlock, char* tName, char* stName,
3089
//                                               SSchemaWrapper* schemaRow, char* tableType, SColRefWrapper* colRef,
3090
//                                               tb_uid_t uid, int32_t vgId) {
3091
//   int32_t code = TSDB_CODE_SUCCESS;
3092
//   int32_t lino = 0;
3093
//   if (schemaRow == NULL) {
3094
//     qError("sysTableUserColsFillOneTableCols schemaRow is NULL");
3095
//     return TSDB_CODE_SUCCESS;
3096
//   }
3097
//   int32_t numOfRows = *pNumOfRows;
3098

3099
//   int32_t numOfCols = schemaRow->nCols;
3100
//   for (int32_t i = 0; i < numOfCols; ++i) {
3101
//     SColumnInfoData* pColInfoData = NULL;
3102

3103
//     // virtual db name
3104
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
3105
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3106
//     code = colDataSetVal(pColInfoData, numOfRows, tName, false);
3107
//     QUERY_CHECK_CODE(code, lino, _end);
3108

3109
//     // virtual stable name
3110
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
3111
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3112
//     code = colDataSetVal(pColInfoData, numOfRows, stName, false);
3113
//     QUERY_CHECK_CODE(code, lino, _end);
3114

3115
//     // virtual table name
3116
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
3117
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3118
//     code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
3119
//     QUERY_CHECK_CODE(code, lino, _end);
3120

3121
//     // virtual col name
3122
//     char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
3123
//     STR_TO_VARSTR(colName, schemaRow->pSchema[i].name);
3124
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
3125
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3126
//     code = colDataSetVal(pColInfoData, numOfRows, colName, false);
3127
//     QUERY_CHECK_CODE(code, lino, _end);
3128

3129
//     // src db name
3130
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
3131
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3132
//     code = colDataSetVal(pColInfoData, numOfRows, (char*)&uid, false);
3133
//     QUERY_CHECK_CODE(code, lino, _end);
3134

3135
//     // src stable name
3136
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
3137
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3138
//     if (!colRef || !colRef->pColRef[i].hasRef) {
3139
//       colDataSetNULL(pColInfoData, numOfRows);
3140
//     } else {
3141
//       code = colDataSetVal(pColInfoData, numOfRows, (char*)&colRef->pColRef[i].id, false);
3142
//       QUERY_CHECK_CODE(code, lino, _end);
3143
//     }
3144
//     // src col name
3145
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 6);
3146
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3147
//     if (!colRef || !colRef->pColRef[i].hasRef) {
3148
//       colDataSetNULL(pColInfoData, numOfRows);
3149
//     } else {
3150
//       char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
3151
//       char tmpColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
3152
//       strcat(tmpColName, colRef->pColRef[i].refDbName);
3153
//       strcat(tmpColName, ".");
3154
//       strcat(tmpColName, colRef->pColRef[i].refTableName);
3155
//       strcat(tmpColName, ".");
3156
//       strcat(tmpColName, colRef->pColRef[i].refColName);
3157
//       STR_TO_VARSTR(refColName, tmpColName);
3158

3159
//       code = colDataSetVal(pColInfoData, numOfRows, (char*)refColName, false);
3160
//       QUERY_CHECK_CODE(code, lino, _end);
3161
//     }
3162

3163
//     // src type
3164
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 7);
3165
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3166
//     code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
3167
//     QUERY_CHECK_CODE(code, lino, _end);
3168

3169
//     // src col is valid
3170
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 8);
3171
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3172
//     code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
3173
//     QUERY_CHECK_CODE(code, lino, _end);
3174

3175
//     // src col err code
3176
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 9);
3177
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3178
//     code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
3179
//     QUERY_CHECK_CODE(code, lino, _end);
3180

3181
//     // src col err msg
3182

3183
//     pColInfoData = taosArrayGet(dataBlock->pDataBlock, 10);
3184
//     QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3185
//     code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
3186
//     QUERY_CHECK_CODE(code, lino, _end);
3187

3188
//     ++numOfRows;
3189
//   }
3190

3191
//   *pNumOfRows = numOfRows;
3192

3193
// _end:
3194
//   if (code != TSDB_CODE_SUCCESS) {
3195
//     qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
3196
//   }
3197
//   return code;
3198
// }
3199

3200
static SSDataBlock* buildInfoSchemaTableMetaBlock(char* tableName) {
20,687,174✔
3201
  size_t               size = 0;
20,687,174✔
3202
  const SSysTableMeta* pMeta = NULL;
20,690,028✔
3203
  getInfosDbMeta(&pMeta, &size);
20,692,901✔
3204

3205
  int32_t index = 0;
20,690,172✔
3206
  for (int32_t i = 0; i < size; ++i) {
283,332,938✔
3207
    if (strcmp(pMeta[i].name, tableName) == 0) {
283,357,691✔
3208
      index = i;
20,679,031✔
3209
      break;
20,679,031✔
3210
    }
3211
  }
3212

3213
  SSDataBlock* pBlock = NULL;
20,654,278✔
3214
  int32_t      code = createDataBlock(&pBlock);
20,682,143✔
3215
  if (code) {
20,685,826✔
3216
    terrno = code;
×
3217
    return NULL;
×
3218
  }
3219

3220
  for (int32_t i = 0; i < pMeta[index].colNum; ++i) {
212,875,859✔
3221
    SColumnInfoData colInfoData =
192,173,835✔
3222
        createColumnInfoData(pMeta[index].schema[i].type, pMeta[index].schema[i].bytes, i + 1);
192,175,848✔
3223
    code = blockDataAppendColInfo(pBlock, &colInfoData);
192,182,204✔
3224
    if (code != TSDB_CODE_SUCCESS) {
192,182,586✔
3225
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
3226
      blockDataDestroy(pBlock);
×
3227
      pBlock = NULL;
×
3228
      terrno = code;
×
3229
      break;
×
3230
    }
3231
  }
3232

3233
  return pBlock;
20,694,791✔
3234
}
3235

3236
int32_t buildDbTableInfoBlock(const SSysTableScanInfo* pInfo, const SSDataBlock* p,
124,740✔
3237
                              const SSysTableMeta* pSysDbTableMeta, size_t size, const char* dbName, int64_t* pRows) {
3238
  int32_t code = TSDB_CODE_SUCCESS;
124,740✔
3239
  int32_t lino = 0;
124,740✔
3240
  char    n[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
124,740✔
3241
  int32_t numOfRows = p->info.rows;
124,740✔
3242

3243
  for (int32_t i = 0; i < size; ++i) {
4,178,790✔
3244
    const SSysTableMeta* pm = &pSysDbTableMeta[i];
4,054,050✔
3245
    if (!pInfo->sysInfo && pm->sysInfo) {
4,054,050✔
3246
      continue;
24,976✔
3247
    }
3248
#ifdef TD_ENTERPRISE
3249
    if (dbName[0] == 'i') {
4,029,074✔
3250
      if (pm->privCat == PRIV_CAT_BASIC) {
3,654,854✔
3251
        if (pInfo->privInfoBasic == 0) continue;
1,932,578✔
3252
      } else if (pm->privCat == PRIV_CAT_PRIVILEGED) {
1,722,276✔
3253
        if (pInfo->privInfoPrivileged == 0) continue;
1,229,560✔
3254
      } else if (pm->privCat == PRIV_CAT_SECURITY) {
492,716✔
3255
        if (pInfo->privInfoSec == 0) continue;
492,716✔
3256
      } else if (pm->privCat == PRIV_CAT_AUDIT) {
×
3257
        if (pInfo->privInfoAudit == 0) continue;
×
3258
      }
3259
    } else if (dbName[0] == 'p') {
374,220✔
3260
      if (pm->privCat == PRIV_CAT_BASIC) {
374,220✔
3261
        if (pInfo->privPerfBasic == 0) continue;
311,850✔
3262
      } else if (pm->privCat == PRIV_CAT_PRIVILEGED) {
62,370✔
3263
        if (pInfo->privPerfPrivileged == 0) continue;
62,370✔
3264
      }
3265
    }
3266
#endif
3267

3268
    if (strcmp(pm->name, TSDB_INS_TABLE_USERS_FULL) == 0) {
4,027,658✔
3269
      continue;
61,478✔
3270
    }
3271

3272
    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
3,966,180✔
3273
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3,966,180✔
3274

3275
    STR_TO_VARSTR(n, pm->name);
3,966,180✔
3276
    code = colDataSetVal(pColInfoData, numOfRows, n, false);
3,966,180✔
3277
    QUERY_CHECK_CODE(code, lino, _end);
3,966,180✔
3278

3279
    // database name
3280
    STR_TO_VARSTR(n, dbName);
3,966,180✔
3281
    pColInfoData = taosArrayGet(p->pDataBlock, 1);
3,966,180✔
3282
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3,966,180✔
3283
    code = colDataSetVal(pColInfoData, numOfRows, n, false);
3,966,180✔
3284
    QUERY_CHECK_CODE(code, lino, _end);
3,966,180✔
3285

3286
    // create time
3287
    pColInfoData = taosArrayGet(p->pDataBlock, 2);
3,966,180✔
3288
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3,966,180✔
3289
    colDataSetNULL(pColInfoData, numOfRows);
3,966,180✔
3290

3291
    // number of columns
3292
    pColInfoData = taosArrayGet(p->pDataBlock, 3);
3,966,180✔
3293
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3,966,180✔
3294
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&pm->colNum, false);
3,966,180✔
3295
    QUERY_CHECK_CODE(code, lino, _end);
3,966,180✔
3296

3297
    for (int32_t j = 4; j <= 8; ++j) {
23,797,080✔
3298
      pColInfoData = taosArrayGet(p->pDataBlock, j);
19,830,900✔
3299
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
19,830,900✔
3300
      colDataSetNULL(pColInfoData, numOfRows);
19,830,900✔
3301
    }
3302

3303
    STR_TO_VARSTR(n, "SYSTEM_TABLE");
3,966,180✔
3304

3305
    pColInfoData = taosArrayGet(p->pDataBlock, 9);
3,966,180✔
3306
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3,966,180✔
3307
    code = colDataSetVal(pColInfoData, numOfRows, n, false);
3,966,180✔
3308
    QUERY_CHECK_CODE(code, lino, _end);
3,966,180✔
3309

3310
    numOfRows += 1;
3,966,180✔
3311
  }
3312

3313
  *pRows = numOfRows;
124,740✔
3314

3315
_end:
124,740✔
3316
  if (code != TSDB_CODE_SUCCESS) {
124,740✔
3317
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3318
  }
3319
  return code;
124,740✔
3320
}
3321

3322
int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity) {
62,370✔
3323
  int32_t      code = TSDB_CODE_SUCCESS;
62,370✔
3324
  int32_t      lino = 0;
62,370✔
3325
  SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
62,370✔
3326
  QUERY_CHECK_NULL(p, code, lino, _end, terrno);
62,370✔
3327

3328
  code = blockDataEnsureCapacity(p, capacity);
62,370✔
3329
  QUERY_CHECK_CODE(code, lino, _end);
62,370✔
3330

3331
  size_t               size = 0;
62,370✔
3332
  const SSysTableMeta* pSysDbTableMeta = NULL;
62,370✔
3333

3334
  getInfosDbMeta(&pSysDbTableMeta, &size);
62,370✔
3335
  code = buildDbTableInfoBlock(pInfo, p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB, &p->info.rows);
62,370✔
3336
  QUERY_CHECK_CODE(code, lino, _end);
62,370✔
3337
  getPerfDbMeta(&pSysDbTableMeta, &size);
62,370✔
3338
  code = buildDbTableInfoBlock(pInfo, p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB, &p->info.rows);
62,370✔
3339
  QUERY_CHECK_CODE(code, lino, _end);
62,370✔
3340

3341
  pInfo->pRes->info.rows = p->info.rows;
62,370✔
3342
  code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
62,370✔
3343
  QUERY_CHECK_CODE(code, lino, _end);
62,370✔
3344

3345
  blockDataDestroy(p);
62,370✔
3346
  p = NULL;
62,370✔
3347

3348
_end:
62,370✔
3349
  if (code != TSDB_CODE_SUCCESS) {
62,370✔
3350
    blockDataDestroy(p);
×
3351
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3352
  }
3353
  return code;
62,370✔
3354
}
3355

3356
static int32_t doSetUserTableMetaInfo(SStoreMetaReader* pMetaReaderFn, SStoreMeta* pMetaFn, void* pVnode,
6,558,548✔
3357
                                      SMetaReader* pMReader, int64_t uid, const char* dbname, int32_t vgId,
3358
                                      SSDataBlock* p, int32_t rowIndex, const char* idStr) {
3359
  char    n[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
6,558,548✔
3360
  int32_t lino = 0;
6,559,860✔
3361
  int32_t code = pMetaReaderFn->getTableEntryByUid(pMReader, uid);
6,559,860✔
3362
  if (code < 0) {
6,551,168✔
3363
    qError("failed to get table meta, uid:%" PRId64 ", code:%s, %s", uid, tstrerror(terrno), idStr);
×
3364
    return code;
×
3365
  }
3366

3367
  STR_TO_VARSTR(n, pMReader->me.name);
6,551,168✔
3368

3369
  // table name
3370
  SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
6,557,892✔
3371
  QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,555,268✔
3372

3373
  code = colDataSetVal(pColInfoData, rowIndex, n, false);
6,555,268✔
3374
  QUERY_CHECK_CODE(code, lino, _end);
6,558,712✔
3375

3376
  // database name
3377
  pColInfoData = taosArrayGet(p->pDataBlock, 1);
6,558,712✔
3378
  QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,557,564✔
3379
  code = colDataSetVal(pColInfoData, rowIndex, dbname, false);
6,557,564✔
3380
  QUERY_CHECK_CODE(code, lino, _end);
6,559,204✔
3381

3382
  // vgId
3383
  pColInfoData = taosArrayGet(p->pDataBlock, 6);
6,559,204✔
3384
  QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,559,204✔
3385
  code = colDataSetVal(pColInfoData, rowIndex, (char*)&vgId, false);
6,559,204✔
3386
  QUERY_CHECK_CODE(code, lino, _end);
6,560,024✔
3387

3388
  int32_t tableType = pMReader->me.type;
6,560,024✔
3389
  if (tableType == TSDB_CHILD_TABLE) {
6,559,860✔
3390
    // create time
3391
    int64_t ts = pMReader->me.ctbEntry.btime;
6,559,860✔
3392
    pColInfoData = taosArrayGet(p->pDataBlock, 2);
6,560,024✔
3393
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,559,860✔
3394
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&ts, false);
6,559,860✔
3395
    QUERY_CHECK_CODE(code, lino, _end);
6,560,024✔
3396

3397
    SMetaReader mr1 = {0};
6,560,024✔
3398
    pMetaReaderFn->initReader(&mr1, pVnode, META_READER_NOLOCK, pMetaFn);
6,560,024✔
3399

3400
    int64_t suid = pMReader->me.ctbEntry.suid;
6,558,876✔
3401
    code = pMetaReaderFn->getTableEntryByUid(&mr1, suid);
6,558,876✔
3402
    if (code != TSDB_CODE_SUCCESS) {
6,534,112✔
3403
      qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pMReader->me.name, suid,
×
3404
             tstrerror(code), idStr);
3405
      pMetaReaderFn->clearReader(&mr1);
×
3406
      QUERY_CHECK_CODE(code, lino, _end);
×
3407
    }
3408

3409
    pColInfoData = taosArrayGet(p->pDataBlock, 3);
6,534,112✔
3410
    if (pColInfoData == NULL) {
6,555,104✔
3411
      pMetaReaderFn->clearReader(&mr1);
×
3412
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3413
    }
3414

3415
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&mr1.me.stbEntry.schemaRow.nCols, false);
6,555,104✔
3416
    if (code != 0) {
6,559,204✔
3417
      pMetaReaderFn->clearReader(&mr1);
×
3418
      QUERY_CHECK_CODE(code, lino, _end);
×
3419
    }
3420

3421
    // super table name
3422
    STR_TO_VARSTR(n, mr1.me.name);
6,559,204✔
3423
    pColInfoData = taosArrayGet(p->pDataBlock, 4);
6,543,460✔
3424
    if (pColInfoData == NULL) {
6,557,400✔
3425
      pMetaReaderFn->clearReader(&mr1);
×
3426
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3427
    }
3428

3429
    code = colDataSetVal(pColInfoData, rowIndex, n, false);
6,557,400✔
3430
    pMetaReaderFn->clearReader(&mr1);
6,552,972✔
3431
    QUERY_CHECK_CODE(code, lino, _end);
6,553,464✔
3432

3433
    // table comment
3434
    pColInfoData = taosArrayGet(p->pDataBlock, 8);
6,553,464✔
3435
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,554,612✔
3436
    if (pMReader->me.ctbEntry.commentLen > 0) {
6,554,612✔
3437
      char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
×
3438
      STR_TO_VARSTR(comment, pMReader->me.ctbEntry.comment);
×
3439
      code = colDataSetVal(pColInfoData, rowIndex, comment, false);
×
3440
      QUERY_CHECK_CODE(code, lino, _end);
×
3441
    } else if (pMReader->me.ctbEntry.commentLen == 0) {
6,544,936✔
3442
      char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
×
3443
      STR_TO_VARSTR(comment, "");
×
3444
      code = colDataSetVal(pColInfoData, rowIndex, comment, false);
×
3445
      QUERY_CHECK_CODE(code, lino, _end);
×
3446
    } else {
3447
      colDataSetNULL(pColInfoData, rowIndex);
6,534,932✔
3448
    }
3449

3450
    // uid
3451
    pColInfoData = taosArrayGet(p->pDataBlock, 5);
6,554,940✔
3452
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,559,040✔
3453
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
6,559,040✔
3454
    QUERY_CHECK_CODE(code, lino, _end);
6,559,368✔
3455

3456
    // ttl
3457
    pColInfoData = taosArrayGet(p->pDataBlock, 7);
6,559,368✔
3458
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,559,368✔
3459
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ctbEntry.ttlDays, false);
6,559,368✔
3460
    QUERY_CHECK_CODE(code, lino, _end);
6,559,368✔
3461

3462
    STR_TO_VARSTR(n, "CHILD_TABLE");
6,559,368✔
3463

3464
  } else if (tableType == TSDB_NORMAL_TABLE) {
×
3465
    // create time
3466
    pColInfoData = taosArrayGet(p->pDataBlock, 2);
×
3467
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3468
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.btime, false);
×
3469
    QUERY_CHECK_CODE(code, lino, _end);
×
3470

3471
    // number of columns
3472
    pColInfoData = taosArrayGet(p->pDataBlock, 3);
×
3473
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3474

3475
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.schemaRow.nCols, false);
×
3476
    QUERY_CHECK_CODE(code, lino, _end);
×
3477

3478
    // super table name
3479
    pColInfoData = taosArrayGet(p->pDataBlock, 4);
×
3480
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3481
    colDataSetNULL(pColInfoData, rowIndex);
×
3482

3483
    // table comment
3484
    pColInfoData = taosArrayGet(p->pDataBlock, 8);
×
3485
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3486
    if (pMReader->me.ntbEntry.commentLen > 0) {
×
3487
      char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
×
3488
      STR_TO_VARSTR(comment, pMReader->me.ntbEntry.comment);
×
3489
      code = colDataSetVal(pColInfoData, rowIndex, comment, false);
×
3490
      QUERY_CHECK_CODE(code, lino, _end);
×
3491
    } else if (pMReader->me.ntbEntry.commentLen == 0) {
×
3492
      char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
×
3493
      STR_TO_VARSTR(comment, "");
×
3494
      code = colDataSetVal(pColInfoData, rowIndex, comment, false);
×
3495
      QUERY_CHECK_CODE(code, lino, _end);
×
3496
    } else {
3497
      colDataSetNULL(pColInfoData, rowIndex);
×
3498
    }
3499

3500
    // uid
3501
    pColInfoData = taosArrayGet(p->pDataBlock, 5);
×
3502
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3503
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
×
3504
    QUERY_CHECK_CODE(code, lino, _end);
×
3505

3506
    // ttl
3507
    pColInfoData = taosArrayGet(p->pDataBlock, 7);
×
3508
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3509
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.ttlDays, false);
×
3510
    QUERY_CHECK_CODE(code, lino, _end);
×
3511

3512
    STR_TO_VARSTR(n, "NORMAL_TABLE");
×
3513
    // impl later
3514
  } else if (tableType == TSDB_VIRTUAL_NORMAL_TABLE) {
×
3515
    // create time
3516
    pColInfoData = taosArrayGet(p->pDataBlock, 2);
×
3517
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3518
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.btime, false);
×
3519
    QUERY_CHECK_CODE(code, lino, _end);
×
3520

3521
    // number of columns
3522
    pColInfoData = taosArrayGet(p->pDataBlock, 3);
×
3523
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3524

3525
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.schemaRow.nCols, false);
×
3526
    QUERY_CHECK_CODE(code, lino, _end);
×
3527

3528
    // super table name
3529
    pColInfoData = taosArrayGet(p->pDataBlock, 4);
×
3530
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3531
    colDataSetNULL(pColInfoData, rowIndex);
×
3532

3533
    // table comment
3534
    pColInfoData = taosArrayGet(p->pDataBlock, 8);
×
3535
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3536
    colDataSetNULL(pColInfoData, rowIndex);
×
3537

3538
    // uid
3539
    pColInfoData = taosArrayGet(p->pDataBlock, 5);
×
3540
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3541
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
×
3542
    QUERY_CHECK_CODE(code, lino, _end);
×
3543

3544
    // ttl
3545
    pColInfoData = taosArrayGet(p->pDataBlock, 7);
×
3546
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3547
    colDataSetNULL(pColInfoData, rowIndex);
×
3548

3549
    STR_TO_VARSTR(n, "VIRTUAL_NORMAL_TABLE");
×
3550
    // impl later
3551
  } else if (tableType == TSDB_VIRTUAL_CHILD_TABLE) {
×
3552
    // create time
3553
    int64_t ts = pMReader->me.ctbEntry.btime;
×
3554
    pColInfoData = taosArrayGet(p->pDataBlock, 2);
×
3555
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3556
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&ts, false);
×
3557
    QUERY_CHECK_CODE(code, lino, _end);
×
3558

3559
    SMetaReader mr1 = {0};
×
3560
    pMetaReaderFn->initReader(&mr1, pVnode, META_READER_NOLOCK, pMetaFn);
×
3561

3562
    int64_t suid = pMReader->me.ctbEntry.suid;
×
3563
    code = pMetaReaderFn->getTableEntryByUid(&mr1, suid);
×
3564
    if (code != TSDB_CODE_SUCCESS) {
×
3565
      qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pMReader->me.name, suid,
×
3566
             tstrerror(code), idStr);
3567
      pMetaReaderFn->clearReader(&mr1);
×
3568
      QUERY_CHECK_CODE(code, lino, _end);
×
3569
    }
3570

3571
    pColInfoData = taosArrayGet(p->pDataBlock, 3);
×
3572
    if (pColInfoData == NULL) {
×
3573
      pMetaReaderFn->clearReader(&mr1);
×
3574
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3575
    }
3576

3577
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&mr1.me.stbEntry.schemaRow.nCols, false);
×
3578
    if (code != 0) {
×
3579
      pMetaReaderFn->clearReader(&mr1);
×
3580
      QUERY_CHECK_CODE(code, lino, _end);
×
3581
    }
3582

3583
    // super table name
3584
    STR_TO_VARSTR(n, mr1.me.name);
×
3585
    pColInfoData = taosArrayGet(p->pDataBlock, 4);
×
3586
    if (pColInfoData == NULL) {
×
3587
      pMetaReaderFn->clearReader(&mr1);
×
3588
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3589
    }
3590

3591
    code = colDataSetVal(pColInfoData, rowIndex, n, false);
×
3592
    pMetaReaderFn->clearReader(&mr1);
×
3593
    QUERY_CHECK_CODE(code, lino, _end);
×
3594

3595
    // table comment
3596
    pColInfoData = taosArrayGet(p->pDataBlock, 8);
×
3597
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3598
    colDataSetNULL(pColInfoData, rowIndex);
×
3599

3600
    // uid
3601
    pColInfoData = taosArrayGet(p->pDataBlock, 5);
×
3602
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3603
    code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
×
3604
    QUERY_CHECK_CODE(code, lino, _end);
×
3605

3606
    // ttl
3607
    pColInfoData = taosArrayGet(p->pDataBlock, 7);
×
3608
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
×
3609
    colDataSetNULL(pColInfoData, rowIndex);
×
3610

3611
    STR_TO_VARSTR(n, "VIRTUAL_CHILD_TABLE");
×
3612
  }
3613

3614
  pColInfoData = taosArrayGet(p->pDataBlock, 9);
6,553,136✔
3615
  QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,557,564✔
3616
  code = colDataSetVal(pColInfoData, rowIndex, n, false);
6,557,564✔
3617
  QUERY_CHECK_CODE(code, lino, _end);
6,557,728✔
3618

3619
_end:
6,556,580✔
3620
  qError("%s failed at line %d since %s, %s", __func__, lino, tstrerror(code), idStr);
6,556,088✔
3621
  return code;
6,560,188✔
3622
}
3623

3624
static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
1,736✔
3625
  int32_t            code = TSDB_CODE_SUCCESS;
1,736✔
3626
  int32_t            lino = 0;
1,736✔
3627
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
1,736✔
3628
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
1,736✔
3629
  SSysTableScanInfo* pInfo = pOperator->info;
1,736✔
3630
  SSysTableIndex*    pIdx = pInfo->pIdx;
1,736✔
3631
  SSDataBlock*       p = NULL;
1,736✔
3632
  blockDataCleanup(pInfo->pRes);
1,736✔
3633
  int32_t numOfRows = 0;
1,736✔
3634

3635
  int ret = 0;
1,736✔
3636

3637
  const char* db = NULL;
1,736✔
3638
  int32_t     vgId = 0;
1,736✔
3639
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, &db, &vgId, NULL, NULL);
1,736✔
3640

3641
  SName sn = {0};
1,736✔
3642
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,736✔
3643
  code = tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
1,736✔
3644
  QUERY_CHECK_CODE(code, lino, _end);
1,736✔
3645

3646
  code = tNameGetDbName(&sn, varDataVal(dbname));
1,736✔
3647
  QUERY_CHECK_CODE(code, lino, _end);
1,736✔
3648

3649
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
1,736✔
3650

3651
  p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
1,736✔
3652
  QUERY_CHECK_NULL(p, code, lino, _end, terrno);
1,736✔
3653

3654
  code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
1,736✔
3655
  QUERY_CHECK_CODE(code, lino, _end);
1,736✔
3656

3657
  int32_t i = pIdx->lastIdx;
1,736✔
3658
  for (; i < taosArrayGetSize(pIdx->uids); i++) {
6,561,924✔
3659
    tb_uid_t* uid = taosArrayGet(pIdx->uids, i);
6,560,024✔
3660
    QUERY_CHECK_NULL(uid, code, lino, _end, terrno);
6,559,860✔
3661

3662
    SMetaReader mr = {0};
6,559,860✔
3663
    pAPI->metaReaderFn.initReader(&mr, pInfo->readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
6,559,696✔
3664

3665
    code = doSetUserTableMetaInfo(&pAPI->metaReaderFn, &pAPI->metaFn, pInfo->readHandle.vnode, &mr, *uid, dbname, vgId,
6,559,204✔
3666
                                  p, numOfRows, GET_TASKID(pTaskInfo));
6,559,368✔
3667

3668
    pAPI->metaReaderFn.clearReader(&mr);
6,560,024✔
3669
    QUERY_CHECK_CODE(code, lino, _end);
6,560,024✔
3670

3671
    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 9);
6,560,024✔
3672
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
6,560,024✔
3673

3674
    if (++numOfRows >= pOperator->resultInfo.capacity) {
6,560,024✔
3675
      p->info.rows = numOfRows;
×
3676
      pInfo->pRes->info.rows = numOfRows;
×
3677

3678
      code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
×
3679
      QUERY_CHECK_CODE(code, lino, _end);
×
3680

3681
      code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
×
3682
      QUERY_CHECK_CODE(code, lino, _end);
×
3683

3684
      blockDataCleanup(p);
×
3685
      numOfRows = 0;
×
3686

3687
      if (pInfo->pRes->info.rows > 0) {
×
3688
        break;
×
3689
      }
3690
    }
3691
  }
3692

3693
  if (numOfRows > 0) {
1,736✔
3694
    p->info.rows = numOfRows;
1,172✔
3695
    pInfo->pRes->info.rows = numOfRows;
1,172✔
3696

3697
    code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
1,172✔
3698
    QUERY_CHECK_CODE(code, lino, _end);
1,172✔
3699

3700
    code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
1,172✔
3701
    QUERY_CHECK_CODE(code, lino, _end);
1,172✔
3702

3703
    blockDataCleanup(p);
1,172✔
3704
    numOfRows = 0;
1,172✔
3705
  }
3706

3707
  if (i >= taosArrayGetSize(pIdx->uids)) {
1,736✔
3708
    setOperatorCompleted(pOperator);
1,736✔
3709
  } else {
3710
    pIdx->lastIdx = i + 1;
×
3711
  }
3712

3713
  blockDataDestroy(p);
1,736✔
3714
  p = NULL;
1,736✔
3715

3716
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
1,736✔
3717

3718
_end:
1,408✔
3719
  if (code != TSDB_CODE_SUCCESS) {
1,736✔
3720
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
3721
    blockDataDestroy(p);
×
3722
    pTaskInfo->code = code;
×
3723
    T_LONG_JMP(pTaskInfo->env, code);
×
3724
  }
3725
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
1,736✔
3726
}
3727

3728
static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
1,398,768✔
3729
  int32_t        code = TSDB_CODE_SUCCESS;
1,398,768✔
3730
  int32_t        lino = 0;
1,398,768✔
3731
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
1,398,768✔
3732
  SStorageAPI*   pAPI = &pTaskInfo->storageAPI;
1,400,303✔
3733
  int8_t         firstMetaCursor = 0;
1,400,303✔
3734
  SSDataBlock*   p = NULL;
1,400,303✔
3735

3736
  SSysTableScanInfo* pInfo = pOperator->info;
1,400,303✔
3737
  if (pInfo->pCur == NULL) {
1,399,756✔
3738
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
1,399,756✔
3739
    QUERY_CHECK_NULL(pInfo->pCur, code, lino, _end, terrno);
1,398,047✔
3740
    firstMetaCursor = 1;
1,398,234✔
3741
  }
3742
  if (!firstMetaCursor) {
1,398,234✔
3743
    code = pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0, 1);
×
3744
    if (code != 0) {
×
3745
      pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
3746
      pInfo->pCur = NULL;
×
3747
      QUERY_CHECK_CODE(code, lino, _end);
×
3748
    }
3749
  }
3750

3751
  blockDataCleanup(pInfo->pRes);
1,398,234✔
3752
  int32_t numOfRows = 0;
1,399,209✔
3753

3754
  const char* db = NULL;
1,399,209✔
3755
  int32_t     vgId = 0;
1,399,209✔
3756
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, &db, &vgId, NULL, NULL);
1,399,756✔
3757

3758
  SName sn = {0};
1,399,082✔
3759
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,399,756✔
3760
  code = tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
1,400,303✔
3761
  QUERY_CHECK_CODE(code, lino, _end);
1,398,072✔
3762

3763
  code = tNameGetDbName(&sn, varDataVal(dbname));
1,398,072✔
3764
  QUERY_CHECK_CODE(code, lino, _end);
1,399,039✔
3765

3766
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
1,399,039✔
3767

3768
  p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_TABLES);
1,398,520✔
3769
  QUERY_CHECK_NULL(p, code, lino, _end, terrno);
1,400,303✔
3770

3771
  code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
1,400,303✔
3772
  QUERY_CHECK_CODE(code, lino, _end);
1,400,303✔
3773

3774
  char n[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1,400,303✔
3775

3776
  int32_t ret = 0;
1,400,303✔
3777
  while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
43,698,126✔
3778
    STR_TO_VARSTR(n, pInfo->pCur->mr.me.name);
42,287,048✔
3779

3780
    // table name
3781
    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
42,298,081✔
3782
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
42,291,467✔
3783
    code = colDataSetVal(pColInfoData, numOfRows, n, false);
42,291,467✔
3784
    QUERY_CHECK_CODE(code, lino, _end);
42,297,315✔
3785

3786
    // database name
3787
    pColInfoData = taosArrayGet(p->pDataBlock, 1);
42,297,315✔
3788
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
42,295,282✔
3789
    code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
42,295,282✔
3790
    QUERY_CHECK_CODE(code, lino, _end);
42,301,236✔
3791

3792
    // vgId
3793
    pColInfoData = taosArrayGet(p->pDataBlock, 6);
42,301,236✔
3794
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
42,297,955✔
3795
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
42,297,955✔
3796
    QUERY_CHECK_CODE(code, lino, _end);
42,298,506✔
3797

3798
    int32_t tableType = pInfo->pCur->mr.me.type;
42,298,506✔
3799
    if (tableType == TSDB_CHILD_TABLE) {
42,299,145✔
3800
      // create time
3801
      int64_t ts = pInfo->pCur->mr.me.ctbEntry.btime;
29,577,730✔
3802
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
29,577,164✔
3803
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
29,576,522✔
3804
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&ts, false);
29,576,522✔
3805
      QUERY_CHECK_CODE(code, lino, _end);
29,578,408✔
3806

3807
      SMetaReader mr = {0};
29,578,408✔
3808
      pAPI->metaReaderFn.initReader(&mr, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
29,577,878✔
3809

3810
      uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
29,579,082✔
3811
      code = pAPI->metaReaderFn.getTableEntryByUid(&mr, suid);
29,578,404✔
3812
      if (code != TSDB_CODE_SUCCESS) {
29,570,349✔
3813
        qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pInfo->pCur->mr.me.name,
×
3814
               suid, tstrerror(terrno), GET_TASKID(pTaskInfo));
3815
        pAPI->metaReaderFn.clearReader(&mr);
×
3816
        pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
3817
        pInfo->pCur = NULL;
×
3818
        blockDataDestroy(p);
×
3819
        T_LONG_JMP(pTaskInfo->env, terrno);
×
3820
      }
3821

3822
      if (isTsmaResSTb(mr.me.name)) {
29,570,349✔
3823
        pAPI->metaReaderFn.clearReader(&mr);
×
3824
        continue;
×
3825
      }
3826

3827
      // number of columns
3828
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
29,573,279✔
3829
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
29,574,346✔
3830
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&mr.me.stbEntry.schemaRow.nCols, false);
29,574,346✔
3831
      QUERY_CHECK_CODE(code, lino, _end);
29,579,082✔
3832

3833
      // super table name
3834
      STR_TO_VARSTR(n, mr.me.name);
29,579,082✔
3835
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
29,575,281✔
3836
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
29,577,694✔
3837
      code = colDataSetVal(pColInfoData, numOfRows, n, false);
29,577,694✔
3838
      QUERY_CHECK_CODE(code, lino, _end);
29,574,976✔
3839
      pAPI->metaReaderFn.clearReader(&mr);
29,574,976✔
3840

3841
      // table comment
3842
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
29,575,088✔
3843
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
29,575,161✔
3844
      if (pInfo->pCur->mr.me.ctbEntry.commentLen > 0) {
29,575,161✔
3845
        char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
17,495✔
3846
        STR_TO_VARSTR(comment, pInfo->pCur->mr.me.ctbEntry.comment);
17,495✔
3847
        code = colDataSetVal(pColInfoData, numOfRows, comment, false);
17,495✔
3848
        QUERY_CHECK_CODE(code, lino, _end);
17,495✔
3849
      } else if (pInfo->pCur->mr.me.ctbEntry.commentLen == 0) {
29,557,482✔
3850
        char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
20,307✔
3851
        STR_TO_VARSTR(comment, "");
20,307✔
3852
        code = colDataSetVal(pColInfoData, numOfRows, comment, false);
20,307✔
3853
        QUERY_CHECK_CODE(code, lino, _end);
20,307✔
3854
      } else {
3855
        colDataSetNULL(pColInfoData, numOfRows);
29,536,979✔
3856
      }
3857

3858
      // uid
3859
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
29,576,326✔
3860
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
29,577,000✔
3861
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
29,577,000✔
3862
      QUERY_CHECK_CODE(code, lino, _end);
29,577,874✔
3863

3864
      // ttl
3865
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
29,577,874✔
3866
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
29,575,681✔
3867
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ctbEntry.ttlDays, false);
29,575,681✔
3868
      QUERY_CHECK_CODE(code, lino, _end);
29,579,082✔
3869

3870
      STR_TO_VARSTR(n, "CHILD_TABLE");
29,579,082✔
3871
    } else if (tableType == TSDB_NORMAL_TABLE) {
12,721,415✔
3872
      // create time
3873
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
11,240,532✔
3874
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
11,239,854✔
3875
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.btime, false);
11,239,854✔
3876
      QUERY_CHECK_CODE(code, lino, _end);
11,241,249✔
3877

3878
      // number of columns
3879
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
11,241,249✔
3880
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
11,241,249✔
3881
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.schemaRow.nCols, false);
11,241,249✔
3882
      QUERY_CHECK_CODE(code, lino, _end);
11,241,249✔
3883

3884
      // super table name
3885
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
11,241,249✔
3886
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
11,239,854✔
3887
      colDataSetNULL(pColInfoData, numOfRows);
11,239,854✔
3888

3889
      // table comment
3890
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
11,239,893✔
3891
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
11,240,532✔
3892
      if (pInfo->pCur->mr.me.ntbEntry.commentLen > 0) {
11,240,532✔
3893
        char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
13,980✔
3894
        STR_TO_VARSTR(comment, pInfo->pCur->mr.me.ntbEntry.comment);
13,980✔
3895
        code = colDataSetVal(pColInfoData, numOfRows, comment, false);
13,980✔
3896
        QUERY_CHECK_CODE(code, lino, _end);
13,980✔
3897
      } else if (pInfo->pCur->mr.me.ntbEntry.commentLen == 0) {
11,225,835✔
3898
        char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
72,412✔
3899
        STR_TO_VARSTR(comment, "");
72,412✔
3900
        code = colDataSetVal(pColInfoData, numOfRows, comment, false);
72,412✔
3901
        QUERY_CHECK_CODE(code, lino, _end);
72,412✔
3902
      } else {
3903
        colDataSetNULL(pColInfoData, numOfRows);
11,154,179✔
3904
      }
3905

3906
      // uid
3907
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
11,239,176✔
3908
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
11,238,502✔
3909
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
11,238,502✔
3910
      QUERY_CHECK_CODE(code, lino, _end);
11,241,253✔
3911

3912
      // ttl
3913
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
11,241,253✔
3914
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
11,237,746✔
3915
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.ttlDays, false);
11,237,746✔
3916
      QUERY_CHECK_CODE(code, lino, _end);
11,241,249✔
3917

3918
      STR_TO_VARSTR(n, "NORMAL_TABLE");
11,241,249✔
3919
    } else if (tableType == TSDB_VIRTUAL_NORMAL_TABLE) {
1,480,883✔
3920
      // create time
3921
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
568,571✔
3922
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
568,571✔
3923
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.btime, false);
568,571✔
3924
      QUERY_CHECK_CODE(code, lino, _end);
568,571✔
3925

3926
      // number of columns
3927
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
568,571✔
3928
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
568,571✔
3929
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.schemaRow.nCols, false);
568,571✔
3930
      QUERY_CHECK_CODE(code, lino, _end);
568,571✔
3931

3932
      // super table name
3933
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
568,571✔
3934
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
568,571✔
3935
      colDataSetNULL(pColInfoData, numOfRows);
568,571✔
3936

3937
      // table comment
3938
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
568,571✔
3939
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
568,571✔
3940
      colDataSetNULL(pColInfoData, numOfRows);
568,571✔
3941

3942
      // uid
3943
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
568,571✔
3944
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
568,571✔
3945
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
568,571✔
3946
      QUERY_CHECK_CODE(code, lino, _end);
568,571✔
3947

3948
      // ttl
3949
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
568,571✔
3950
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
568,571✔
3951
      colDataSetNULL(pColInfoData, numOfRows);
568,571✔
3952

3953
      STR_TO_VARSTR(n, "VIRTUAL_NORMAL_TABLE");
568,571✔
3954
    } else if (tableType == TSDB_VIRTUAL_CHILD_TABLE) {
912,312✔
3955
      // create time
3956
      int64_t ts = pInfo->pCur->mr.me.ctbEntry.btime;
912,312✔
3957
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
912,312✔
3958
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
912,312✔
3959
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&ts, false);
912,312✔
3960
      QUERY_CHECK_CODE(code, lino, _end);
912,312✔
3961

3962
      SMetaReader mr = {0};
912,312✔
3963
      pAPI->metaReaderFn.initReader(&mr, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
912,312✔
3964

3965
      uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
912,312✔
3966
      code = pAPI->metaReaderFn.getTableEntryByUid(&mr, suid);
912,312✔
3967
      if (code != TSDB_CODE_SUCCESS) {
912,312✔
3968
        qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pInfo->pCur->mr.me.name,
×
3969
               suid, tstrerror(terrno), GET_TASKID(pTaskInfo));
3970
        pAPI->metaReaderFn.clearReader(&mr);
×
3971
        pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
3972
        pInfo->pCur = NULL;
×
3973
        blockDataDestroy(p);
×
3974
        T_LONG_JMP(pTaskInfo->env, terrno);
×
3975
      }
3976

3977
      if (isTsmaResSTb(mr.me.name)) {
912,312✔
3978
        pAPI->metaReaderFn.clearReader(&mr);
×
3979
        continue;
×
3980
      }
3981

3982
      // number of columns
3983
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
912,312✔
3984
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
912,312✔
3985
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&mr.me.stbEntry.schemaRow.nCols, false);
912,312✔
3986
      QUERY_CHECK_CODE(code, lino, _end);
912,312✔
3987

3988
      // super table name
3989
      STR_TO_VARSTR(n, mr.me.name);
912,312✔
3990
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
912,312✔
3991
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
912,312✔
3992
      code = colDataSetVal(pColInfoData, numOfRows, n, false);
912,312✔
3993
      QUERY_CHECK_CODE(code, lino, _end);
912,312✔
3994
      pAPI->metaReaderFn.clearReader(&mr);
912,312✔
3995

3996
      // table comment
3997
      pColInfoData = taosArrayGet(p->pDataBlock, 8);
912,312✔
3998
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
912,312✔
3999
      colDataSetNULL(pColInfoData, numOfRows);
912,312✔
4000

4001
      // uid
4002
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
912,312✔
4003
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
912,312✔
4004
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
912,312✔
4005
      QUERY_CHECK_CODE(code, lino, _end);
912,312✔
4006

4007
      // ttl
4008
      pColInfoData = taosArrayGet(p->pDataBlock, 7);
912,312✔
4009
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
912,312✔
4010
      colDataSetNULL(pColInfoData, numOfRows);
912,312✔
4011

4012
      STR_TO_VARSTR(n, "VIRTUAL_CHILD_TABLE");
912,312✔
4013
    }
4014

4015
    pColInfoData = taosArrayGet(p->pDataBlock, 9);
42,296,433✔
4016
    QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
42,295,598✔
4017
    code = colDataSetVal(pColInfoData, numOfRows, n, false);
42,295,598✔
4018
    QUERY_CHECK_CODE(code, lino, _end);
42,294,394✔
4019

4020
    if (++numOfRows >= pOperator->resultInfo.capacity) {
42,294,394✔
4021
      p->info.rows = numOfRows;
×
4022
      pInfo->pRes->info.rows = numOfRows;
×
4023

4024
      code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
×
4025
      QUERY_CHECK_CODE(code, lino, _end);
×
4026

4027
      code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
×
4028
      QUERY_CHECK_CODE(code, lino, _end);
×
4029

4030
      blockDataCleanup(p);
×
4031
      numOfRows = 0;
×
4032

4033
      if (pInfo->pRes->info.rows > 0) {
×
4034
        pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
×
4035
        break;
×
4036
      }
4037
    }
4038
  }
4039

4040
  if (numOfRows > 0) {
1,396,913✔
4041
    pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
1,124,107✔
4042
    p->info.rows = numOfRows;
1,124,107✔
4043
    pInfo->pRes->info.rows = numOfRows;
1,124,107✔
4044

4045
    code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
1,123,428✔
4046
    QUERY_CHECK_CODE(code, lino, _end);
1,124,107✔
4047

4048
    code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
1,124,107✔
4049
    QUERY_CHECK_CODE(code, lino, _end);
1,124,107✔
4050

4051
    blockDataCleanup(p);
1,124,107✔
4052
    numOfRows = 0;
1,124,107✔
4053
  }
4054

4055
  blockDataDestroy(p);
1,396,913✔
4056
  p = NULL;
1,398,737✔
4057

4058
  // todo temporarily free the cursor here, the true reason why the free is not valid needs to be found
4059
  if (ret != 0) {
1,398,737✔
4060
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
1,398,737✔
4061
    pInfo->pCur = NULL;
1,399,403✔
4062
    setOperatorCompleted(pOperator);
1,399,403✔
4063
  }
4064

4065
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
1,398,737✔
4066

4067
_end:
1,403,011✔
4068
  if (code != TSDB_CODE_SUCCESS) {
1,396,844✔
4069
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4070
    blockDataDestroy(p);
×
4071
    pTaskInfo->code = code;
×
4072
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
4073
    pInfo->pCur = NULL;
×
4074
    T_LONG_JMP(pTaskInfo->env, code);
×
4075
  }
4076
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
1,396,844✔
4077
}
4078

4079
static int32_t buildVgDiskUsage(SOperatorInfo* pOperator, SDbSizeStatisInfo* pStaticsInfo) {
6,438✔
4080
  int32_t            code = TSDB_CODE_SUCCESS;
6,438✔
4081
  int32_t            lino = 0;
6,438✔
4082
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
6,438✔
4083
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
6,438✔
4084
  SSysTableScanInfo* pInfo = pOperator->info;
6,438✔
4085
  int32_t            vgId = 0;
6,438✔
4086
  const char*        db = NULL;
6,438✔
4087
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, &pStaticsInfo->dbname, &vgId, NULL, NULL);
6,438✔
4088

4089
  pStaticsInfo->vgId = vgId;
6,438✔
4090

4091
  code = pAPI->metaFn.getDBSize(pInfo->readHandle.vnode, pStaticsInfo);
6,438✔
4092
  QUERY_CHECK_CODE(code, lino, _end);
6,438✔
4093

4094
  code = vnodeEstimateRawDataSize(pOperator, pStaticsInfo);
6,438✔
4095
  QUERY_CHECK_CODE(code, lino, _end);
6,438✔
4096

4097
  pStaticsInfo->memSize = pStaticsInfo->memSize >> 10;
6,438✔
4098
  pStaticsInfo->l1Size = pStaticsInfo->l1Size >> 10;
6,438✔
4099
  pStaticsInfo->l2Size = pStaticsInfo->l2Size >> 10;
6,438✔
4100
  pStaticsInfo->l3Size = pStaticsInfo->l3Size >> 10;
6,438✔
4101
  pStaticsInfo->cacheSize = pStaticsInfo->cacheSize >> 10;
6,438✔
4102
  pStaticsInfo->walSize = pStaticsInfo->walSize >> 10;
6,438✔
4103
  pStaticsInfo->metaSize = pStaticsInfo->metaSize >> 10;
6,438✔
4104
  pStaticsInfo->rawDataSize = pStaticsInfo->rawDataSize >> 10;
6,438✔
4105
  pStaticsInfo->ssSize = pStaticsInfo->ssSize >> 10;
6,438✔
4106

4107
_end:
6,438✔
4108
  return code;
6,438✔
4109
}
4110

4111
static int8_t shouldEstimateRawDataSize(SOperatorInfo* pOperator) {
5,714✔
4112
  int32_t lino = 0;
5,714✔
4113
  size_t  size = 0;
5,714✔
4114
  int32_t index = 0;
5,714✔
4115

4116
  const SSysTableMeta* pMeta = NULL;
5,714✔
4117
  SExecTaskInfo*       pTaskInfo = pOperator->pTaskInfo;
5,529✔
4118

4119
  SSysTableScanInfo* pInfo = pOperator->info;
5,714✔
4120
  getInfosDbMeta(&pMeta, &size);
5,714✔
4121

4122
  for (int32_t i = 0; i < size; ++i) {
217,656✔
4123
    if (strcmp(pMeta[i].name, TSDB_INS_DISK_USAGE) == 0) {
217,656✔
4124
      index = i;
5,714✔
4125
      break;
5,714✔
4126
    }
4127
  }
4128
  if (index >= size) {
5,714✔
4129
    return 1;
×
4130
  }
4131
  const SSysTableMeta* pTgtMeta = &pMeta[index];
5,714✔
4132
  int32_t              colNum = pTgtMeta->colNum;
5,714✔
4133
  SColumnInfoData      colInfoData =
4134
      createColumnInfoData(pTgtMeta->schema[colNum - 1].type, pTgtMeta->schema[colNum - 1].bytes, colNum);
5,382✔
4135
  for (int32_t i = 0; i < taosArrayGetSize(pInfo->matchInfo.pList); i++) {
20,004✔
4136
    SColMatchItem* pItem = taosArrayGet(pInfo->matchInfo.pList, i);
15,384✔
4137
    if (pItem->colId == colInfoData.info.colId) {
15,384✔
4138
      return 1;
1,094✔
4139
    }
4140
  }
4141
  return 0;
4,620✔
4142
}
4143
static SSDataBlock* sysTableBuildVgUsage(SOperatorInfo* pOperator) {
8,288✔
4144
  int32_t            code = TSDB_CODE_SUCCESS;
8,288✔
4145
  int32_t            lino = 0;
8,288✔
4146
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
8,288✔
4147
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
8,288✔
4148
  SSysTableScanInfo* pInfo = pOperator->info;
8,288✔
4149
  SDbSizeStatisInfo  staticsInfo = {.estimateRawData = 1};
8,288✔
4150

4151
  char*        buf = NULL;
8,288✔
4152
  SSDataBlock* p = NULL;
8,288✔
4153

4154
  const char* db = NULL;
8,288✔
4155
  int32_t     numOfCols = 0;
8,288✔
4156
  int32_t     numOfRows = 0;
8,288✔
4157

4158
  // the retrieve is executed on the mnode, so return tables that belongs to the information schema database.
4159
  if (pInfo->readHandle.mnd != NULL) {
8,288✔
4160
    setOperatorCompleted(pOperator);
1,850✔
4161
    return NULL;
1,850✔
4162
  }
4163
  if (pInfo->pCur == NULL) {
6,438✔
4164
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
6,438✔
4165
    if (pInfo->pCur == NULL) {
6,438✔
4166
      code = terrno;
×
4167
      QUERY_CHECK_CODE(code, lino, _end);
×
4168
    }
4169
  }
4170

4171
  SSDataBlock* pBlock = pInfo->pRes;
6,272✔
4172

4173
  if (!pInfo->showRewrite) {
6,438✔
4174
    staticsInfo.estimateRawData = shouldEstimateRawDataSize(pOperator);
5,529✔
4175
  }
4176

4177
  code = buildVgDiskUsage(pOperator, &staticsInfo);
6,457✔
4178
  QUERY_CHECK_CODE(code, lino, _end);
6,438✔
4179

4180
  if (pInfo->showRewrite) {
6,438✔
4181
    SSDataBlock*      pBlock = pInfo->pRes;
724✔
4182
    SDBBlockUsageInfo usageInfo = {0};
724✔
4183
    int32_t           len = tSerializeBlockDbUsage(NULL, 0, &usageInfo);
724✔
4184

4185
    usageInfo.dataInDiskSize = staticsInfo.l1Size + staticsInfo.l2Size + staticsInfo.l3Size;
724✔
4186
    usageInfo.walInDiskSize = staticsInfo.walSize;
724✔
4187
    usageInfo.rawDataSize = staticsInfo.rawDataSize;
724✔
4188

4189
    buf = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
724✔
4190
    QUERY_CHECK_NULL(buf, code, lino, _end, terrno);
724✔
4191

4192
    int32_t tempRes = tSerializeBlockDbUsage(varDataVal(buf), len, &usageInfo);
724✔
4193
    if (tempRes != len) {
724✔
4194
      QUERY_CHECK_CODE(TSDB_CODE_INVALID_MSG, lino, _end);
×
4195
    }
4196

4197
    varDataSetLen(buf, len);
724✔
4198

4199
    int32_t          slotId = 1;
724✔
4200
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 1);
724✔
4201
    QUERY_CHECK_NULL(pColInfo, code, lino, _end, terrno);
724✔
4202
    code = colDataSetVal(pColInfo, 0, buf, false);
724✔
4203
    QUERY_CHECK_CODE(code, lino, _end);
724✔
4204
    taosMemoryFreeClear(buf);
724✔
4205
    if (slotId != 0) {
724✔
4206
      SColumnInfoData* p1 = taosArrayGet(pBlock->pDataBlock, 0);
724✔
4207
      QUERY_CHECK_NULL(p1, code, lino, _end, terrno);
724✔
4208
    }
4209

4210
    pBlock->info.rows = 1;
724✔
4211
    pOperator->status = OP_EXEC_DONE;
724✔
4212
    pInfo->pRes->info.rows = pBlock->info.rows;
724✔
4213
    QUERY_CHECK_CODE(code, lino, _end);
724✔
4214
  } else {
4215
    SName sn = {0};
5,714✔
4216
    char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
5,714✔
4217
    code = tNameFromString(&sn, staticsInfo.dbname, T_NAME_ACCT | T_NAME_DB);
5,714✔
4218
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4219

4220
    code = tNameGetDbName(&sn, varDataVal(dbname));
5,714✔
4221
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4222

4223
    varDataSetLen(dbname, strlen(varDataVal(dbname)));
5,714✔
4224

4225
    p = buildInfoSchemaTableMetaBlock(TSDB_INS_DISK_USAGE);
5,714✔
4226
    QUERY_CHECK_NULL(p, code, lino, _end, terrno);
5,714✔
4227

4228
    code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
5,714✔
4229
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4230

4231
    SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4232
    code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
5,714✔
4233
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4234

4235
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4236
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.vgId, false);
5,714✔
4237
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4238

4239
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4240
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.walSize, false);  // wal
5,714✔
4241
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4242

4243
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4244
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.l1Size, false);  // l1_size
5,714✔
4245
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4246

4247
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4248
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.l2Size, false);  // l2_size
5,714✔
4249
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4250

4251
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4252
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.l3Size, false);  // l3_size
5,714✔
4253
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4254

4255
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4256
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.cacheSize, false);  // cache_size
5,714✔
4257
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4258

4259
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4260
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.metaSize, false);  // meta_size
5,714✔
4261
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4262

4263
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4264
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.ssSize, false);  // ss_size
5,714✔
4265
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4266

4267
    pColInfoData = taosArrayGet(p->pDataBlock, numOfCols++);
5,714✔
4268
    code = colDataSetVal(pColInfoData, numOfRows, (char*)&staticsInfo.rawDataSize, false);  // estimate_size
5,714✔
4269
    QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4270
    numOfRows += 1;
5,714✔
4271

4272
    if (numOfRows > 0) {
5,714✔
4273
      p->info.rows = numOfRows;
5,714✔
4274
      pInfo->pRes->info.rows = numOfRows;
5,714✔
4275

4276
      code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
5,714✔
4277
      QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4278

4279
      code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
5,714✔
4280
      QUERY_CHECK_CODE(code, lino, _end);
5,714✔
4281
    }
4282

4283
    blockDataDestroy(p);
5,714✔
4284
    p = NULL;
5,714✔
4285

4286
    pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
5,714✔
4287
    setOperatorCompleted(pOperator);
5,714✔
4288
  }
4289
_end:
6,438✔
4290
  taosMemoryFree(buf);
6,438✔
4291
  if (pInfo->pCur) {
6,438✔
4292
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
4,620✔
4293
    pInfo->pCur = NULL;
4,620✔
4294
  }
4295
  if (code != TSDB_CODE_SUCCESS) {
6,438✔
4296
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4297
    blockDataDestroy(p);
×
4298
    pTaskInfo->code = code;
×
4299
    T_LONG_JMP(pTaskInfo->env, code);
×
4300
  }
4301
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
6,438✔
4302
}
4303

4304
static SSDataBlock* sysTableScanUserTables(SOperatorInfo* pOperator) {
2,391,867✔
4305
  int32_t            code = TSDB_CODE_SUCCESS;
2,391,867✔
4306
  int32_t            lino = 0;
2,391,867✔
4307
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
2,391,867✔
4308
  SSysTableScanInfo* pInfo = pOperator->info;
2,393,181✔
4309

4310
  SNode* pCondition = pInfo->pCondition;
2,393,836✔
4311
  if (pOperator->status == OP_EXEC_DONE) {
2,392,458✔
4312
    return NULL;
928,727✔
4313
  }
4314

4315
  // the retrieve is executed on the mnode, so return tables that belongs to the information schema database.
4316
  if (pInfo->readHandle.mnd != NULL) {
1,464,409✔
4317
    code = buildSysDbTableInfo(pInfo, pOperator->resultInfo.capacity);
62,370✔
4318
    QUERY_CHECK_CODE(code, lino, _end);
62,370✔
4319

4320
    code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
62,370✔
4321
    QUERY_CHECK_CODE(code, lino, _end);
62,370✔
4322
    pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
62,370✔
4323

4324
    setOperatorCompleted(pOperator);
62,370✔
4325
    return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
62,370✔
4326
  } else {
4327
    if (pInfo->showRewrite == false) {
1,400,818✔
4328
      if (pCondition != NULL && pInfo->pIdx == NULL) {
1,684,038✔
4329
        SSTabFltArg arg = {
770,136✔
4330
            .pMeta = pInfo->readHandle.vnode, .pVnode = pInfo->readHandle.vnode, .pAPI = &pTaskInfo->storageAPI};
770,136✔
4331

4332
        SSysTableIndex* idx = taosMemoryMalloc(sizeof(SSysTableIndex));
770,136✔
4333
        QUERY_CHECK_NULL(idx, code, lino, _end, terrno);
770,136✔
4334
        idx->init = 0;
770,136✔
4335
        idx->uids = taosArrayInit(128, sizeof(int64_t));
769,589✔
4336
        QUERY_CHECK_NULL(idx->uids, code, lino, _end, terrno);
770,136✔
4337
        idx->lastIdx = 0;
769,458✔
4338

4339
        pInfo->pIdx = idx;  // set idx arg
769,458✔
4340

4341
        int flt = optSysTabFilte(&arg, pCondition, idx->uids);
770,136✔
4342
        if (flt == 0) {
769,426✔
4343
          pInfo->pIdx->init = 1;
1,736✔
4344
          SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
1,736✔
4345
          return blk;
1,736✔
4346
        } else if ((flt == -1) || (flt == -2)) {
767,690✔
4347
          qDebug("%s failed to get sys table info by idx, scan sys table one by one", GET_TASKID(pTaskInfo));
767,690✔
4348
        }
4349
      } else if (pCondition != NULL && (pInfo->pIdx != NULL && pInfo->pIdx->init == 1)) {
145,502✔
4350
        SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
×
4351
        return blk;
×
4352
      }
4353
    }
4354

4355
    return sysTableBuildUserTables(pOperator);
1,400,303✔
4356
  }
4357

4358
_end:
×
4359
  if (code != TSDB_CODE_SUCCESS) {
×
4360
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4361
    pTaskInfo->code = code;
×
4362
    T_LONG_JMP(pTaskInfo->env, code);
×
4363
  }
4364
  return NULL;
×
4365
}
4366
static SSDataBlock* sysTableScanUsage(SOperatorInfo* pOperator) {
14,726✔
4367
  int32_t            code = TSDB_CODE_SUCCESS;
14,726✔
4368
  int32_t            lino = 0;
14,726✔
4369
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
14,726✔
4370
  SSysTableScanInfo* pInfo = pOperator->info;
14,726✔
4371

4372
  SNode* pCondition = pInfo->pCondition;
14,726✔
4373
  if (pOperator->status == OP_EXEC_DONE) {
14,726✔
4374
    return NULL;
6,438✔
4375
  }
4376
  return sysTableBuildVgUsage(pOperator);
8,288✔
4377

4378
_end:
4379
  if (code != TSDB_CODE_SUCCESS) {
4380
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4381
    pTaskInfo->code = code;
4382
    T_LONG_JMP(pTaskInfo->env, code);
4383
  }
4384
  return NULL;
4385
}
4386

4387
static SSDataBlock* sysTableScanUserSTables(SOperatorInfo* pOperator) {
×
4388
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
×
4389
  SSysTableScanInfo* pInfo = pOperator->info;
×
4390
  if (pOperator->status == OP_EXEC_DONE) {
×
4391
    return NULL;
×
4392
  }
4393

4394
  pInfo->pRes->info.rows = 0;
×
4395
  pOperator->status = OP_EXEC_DONE;
×
4396

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

4401
static int32_t doSetQueryFileSetRow() {
×
4402
  int32_t code = TSDB_CODE_SUCCESS;
×
4403
  int32_t lino = 0;
×
4404

4405
  // TODO
4406

4407
_exit:
×
4408
  return code;
×
4409
}
4410

4411
static SSDataBlock* sysTableBuildUserFileSets(SOperatorInfo* pOperator) {
164✔
4412
  int32_t            code = TSDB_CODE_SUCCESS;
164✔
4413
  int32_t            lino = 0;
164✔
4414
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
164✔
4415
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
164✔
4416
  SSysTableScanInfo* pInfo = pOperator->info;
164✔
4417
  SSDataBlock*       p = NULL;
164✔
4418

4419
  // open cursor if not opened
4420
  if (pInfo->pFileSetReader == NULL) {
164✔
4421
    code = pAPI->tsdReader.fileSetReaderOpen(pInfo->readHandle.vnode, &pInfo->pFileSetReader);
164✔
4422
    QUERY_CHECK_CODE(code, lino, _end);
164✔
4423
  }
4424

4425
  blockDataCleanup(pInfo->pRes);
164✔
4426
  int32_t numOfRows = 0;
164✔
4427

4428
  const char* db = NULL;
164✔
4429
  int32_t     vgId = 0;
164✔
4430
  pAPI->metaFn.getBasicInfo(pInfo->readHandle.vnode, &db, &vgId, NULL, NULL);
164✔
4431

4432
  SName sn = {0};
164✔
4433
  char  dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
164✔
4434
  code = tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
164✔
4435
  QUERY_CHECK_CODE(code, lino, _end);
164✔
4436

4437
  code = tNameGetDbName(&sn, varDataVal(dbname));
164✔
4438
  QUERY_CHECK_CODE(code, lino, _end);
164✔
4439

4440
  varDataSetLen(dbname, strlen(varDataVal(dbname)));
164✔
4441

4442
  p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_FILESETS);
164✔
4443
  QUERY_CHECK_NULL(p, code, lino, _end, terrno);
164✔
4444

4445
  code = blockDataEnsureCapacity(p, pOperator->resultInfo.capacity);
164✔
4446
  QUERY_CHECK_CODE(code, lino, _end);
164✔
4447

4448
  char    n[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
164✔
4449
  int32_t ret = 0;
164✔
4450

4451
  // loop to query each entry
4452
  for (;;) {
164✔
4453
    int32_t ret = pAPI->tsdReader.fileSetReadNext(pInfo->pFileSetReader);
328✔
4454
    if (ret) {
328✔
4455
      if (ret == TSDB_CODE_NOT_FOUND) {
164✔
4456
        // no more scan entry
4457
        setOperatorCompleted(pOperator);
164✔
4458
        pAPI->tsdReader.fileSetReaderClose(&pInfo->pFileSetReader);
164✔
4459
        break;
164✔
4460
      } else {
4461
        code = ret;
×
4462
        QUERY_CHECK_CODE(code, lino, _end);
×
4463
      }
4464
    }
4465

4466
    // fill the data block
4467
    {
4468
      SColumnInfoData* pColInfoData;
4469
      int32_t          index = 0;
164✔
4470

4471
      // db_name
4472
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4473
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4474
      code = colDataSetVal(pColInfoData, numOfRows, dbname, false);
164✔
4475
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4476

4477
      // vgroup_id
4478
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4479
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4480
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
164✔
4481
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4482

4483
      // fileset_id
4484
      int32_t filesetId = 0;
164✔
4485
      code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "fileset_id", &filesetId);
164✔
4486
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4487
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4488
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4489
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&filesetId, false);
164✔
4490
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4491

4492
      // start_time
4493
      int64_t startTime = 0;
164✔
4494
      code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "start_time", &startTime);
164✔
4495
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4496
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4497
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4498
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&startTime, false);
164✔
4499
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4500

4501
      // end_time
4502
      int64_t endTime = 0;
164✔
4503
      code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "end_time", &endTime);
164✔
4504
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4505
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4506
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4507
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&endTime, false);
164✔
4508
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4509

4510
      // total_size
4511
      int64_t totalSize = 0;
164✔
4512
      code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "total_size", &totalSize);
164✔
4513
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4514
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4515
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4516
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&totalSize, false);
164✔
4517
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4518

4519
      // last_compact
4520
      int64_t lastCompact = 0;
164✔
4521
      code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "last_compact_time", &lastCompact);
164✔
4522
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4523
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4524
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4525
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&lastCompact, false);
164✔
4526
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4527

4528
      // should_compact
4529
      bool shouldCompact = false;
164✔
4530
      code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "should_compact", &shouldCompact);
164✔
4531
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4532
      pColInfoData = taosArrayGet(p->pDataBlock, index++);
164✔
4533
      QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
164✔
4534
      code = colDataSetVal(pColInfoData, numOfRows, (char*)&shouldCompact, false);
164✔
4535
      QUERY_CHECK_CODE(code, lino, _end);
164✔
4536

4537
      // // details
4538
      // const char* details = NULL;
4539
      // code = pAPI->tsdReader.fileSetGetEntryField(pInfo->pFileSetReader, "details", &details);
4540
      // QUERY_CHECK_CODE(code, lino, _end);
4541
      // pColInfoData = taosArrayGet(p->pDataBlock, index++);
4542
      // QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
4543
      // code = colDataSetVal(pColInfoData, numOfRows, (char*)&vgId, false);
4544
      // QUERY_CHECK_CODE(code, lino, _end);
4545
    }
4546

4547
    // check capacity
4548
    if (++numOfRows >= pOperator->resultInfo.capacity) {
164✔
4549
      p->info.rows = numOfRows;
×
4550
      pInfo->pRes->info.rows = numOfRows;
×
4551

4552
      code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
×
4553
      QUERY_CHECK_CODE(code, lino, _end);
×
4554

4555
      code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
×
4556
      QUERY_CHECK_CODE(code, lino, _end);
×
4557

4558
      blockDataCleanup(p);
×
4559
      numOfRows = 0;
×
4560

4561
      if (pInfo->pRes->info.rows > 0) {
×
4562
        break;
×
4563
      }
4564
    }
4565
  }
4566

4567
  if (numOfRows > 0) {
164✔
4568
    p->info.rows = numOfRows;
164✔
4569
    pInfo->pRes->info.rows = numOfRows;
164✔
4570

4571
    code = relocateColumnData(pInfo->pRes, pInfo->matchInfo.pList, p->pDataBlock, false);
164✔
4572
    QUERY_CHECK_CODE(code, lino, _end);
164✔
4573

4574
    code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
164✔
4575
    QUERY_CHECK_CODE(code, lino, _end);
164✔
4576

4577
    blockDataCleanup(p);
164✔
4578
    numOfRows = 0;
164✔
4579
  }
4580

4581
  blockDataDestroy(p);
164✔
4582
  p = NULL;
164✔
4583

4584
  pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
164✔
4585

4586
_end:
164✔
4587
  if (code != TSDB_CODE_SUCCESS) {
164✔
4588
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4589
    blockDataDestroy(p);
×
4590
    pTaskInfo->code = code;
×
4591
    pAPI->tsdReader.fileSetReaderClose(&pInfo->pFileSetReader);
×
4592
    T_LONG_JMP(pTaskInfo->env, code);
×
4593
  }
4594
  return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
164✔
4595
}
4596

4597
static SSDataBlock* sysTableScanUserFileSets(SOperatorInfo* pOperator) {
492✔
4598
  int32_t            code = TSDB_CODE_SUCCESS;
492✔
4599
  int32_t            lino = 0;
492✔
4600
  SSysTableScanInfo* pInfo = pOperator->info;
492✔
4601
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
492✔
4602
  SNode*             pCondition = pInfo->pCondition;
492✔
4603

4604
  if (pOperator->status == OP_EXEC_DONE) {
492✔
4605
    return NULL;
164✔
4606
  }
4607

4608
  if (pInfo->readHandle.mnd != NULL) {
328✔
4609
    // do nothing on mnode
4610
    qTrace("This operator do nothing on mnode, task id:%s", GET_TASKID(pTaskInfo));
164✔
4611
    return NULL;
164✔
4612
  } else {
4613
#if 0
4614
    if (pInfo->showRewrite == false) {
4615
      if (pCondition != NULL && pInfo->pIdx == NULL) {
4616
        SSTabFltArg arg = {
4617
            .pMeta = pInfo->readHandle.vnode, .pVnode = pInfo->readHandle.vnode, .pAPI = &pTaskInfo->storageAPI};
4618

4619
        SSysTableIndex* idx = taosMemoryMalloc(sizeof(SSysTableIndex));
4620
        QUERY_CHECK_NULL(idx, code, lino, _end, terrno);
4621
        idx->init = 0;
4622
        idx->uids = taosArrayInit(128, sizeof(int64_t));
4623
        QUERY_CHECK_NULL(idx->uids, code, lino, _end, terrno);
4624
        idx->lastIdx = 0;
4625

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

4628
        int flt = optSysTabFilte(&arg, pCondition, idx->uids);
4629
        if (flt == 0) {
4630
          pInfo->pIdx->init = 1;
4631
          SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
4632
          return blk;
4633
        } else if ((flt == -1) || (flt == -2)) {
4634
          qDebug("%s failed to get sys table info by idx, scan sys table one by one", GET_TASKID(pTaskInfo));
4635
        }
4636
      } else if (pCondition != NULL && (pInfo->pIdx != NULL && pInfo->pIdx->init == 1)) {
4637
        SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
4638
        return blk;
4639
      }
4640
    }
4641
#endif
4642

4643
    return sysTableBuildUserFileSets(pOperator);
164✔
4644
  }
4645

4646
_end:
4647
  if (code != TSDB_CODE_SUCCESS) {
4648
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
4649
    pTaskInfo->code = code;
4650
    T_LONG_JMP(pTaskInfo->env, code);
4651
  }
4652
  return NULL;
4653
}
4654

4655
static int32_t getSysTableDbNameColId(const char* pTable) {
3,917,963✔
4656
  // if (0 == strcmp(TSDB_INS_TABLE_INDEXES, pTable)) {
4657
  //   return 1;
4658
  // }
4659
  return TSDB_INS_USER_STABLES_DBNAME_COLID;
3,917,963✔
4660
}
4661

4662
static EDealRes getDBNameFromConditionWalker(SNode* pNode, void* pContext) {
19,409,853✔
4663
  int32_t   code = TSDB_CODE_SUCCESS;
19,409,853✔
4664
  ENodeType nType = nodeType(pNode);
19,409,853✔
4665

4666
  switch (nType) {
19,410,383✔
4667
    case QUERY_NODE_OPERATOR: {
9,199,504✔
4668
      SOperatorNode* node = (SOperatorNode*)pNode;
9,199,504✔
4669
      if (OP_TYPE_EQUAL == node->opType) {
9,199,504✔
4670
        *(int32_t*)pContext = 1;
3,917,963✔
4671
        return DEAL_RES_CONTINUE;
3,917,963✔
4672
      }
4673

4674
      *(int32_t*)pContext = 0;
5,281,541✔
4675
      return DEAL_RES_IGNORE_CHILD;
5,281,011✔
4676
    }
4677
    case QUERY_NODE_COLUMN: {
3,918,089✔
4678
      if (1 != *(int32_t*)pContext) {
3,918,089✔
4679
        return DEAL_RES_CONTINUE;
126✔
4680
      }
4681

4682
      SColumnNode* node = (SColumnNode*)pNode;
3,917,963✔
4683
      if (getSysTableDbNameColId(node->tableName) == node->colId) {
3,917,963✔
4684
        *(int32_t*)pContext = 2;
3,432,872✔
4685
        return DEAL_RES_CONTINUE;
3,432,872✔
4686
      }
4687

4688
      *(int32_t*)pContext = 0;
485,091✔
4689
      return DEAL_RES_CONTINUE;
485,091✔
4690
    }
4691
    case QUERY_NODE_VALUE: {
3,915,961✔
4692
      if (2 != *(int32_t*)pContext) {
3,915,961✔
4693
        return DEAL_RES_CONTINUE;
484,965✔
4694
      }
4695

4696
      SValueNode* node = (SValueNode*)pNode;
3,432,872✔
4697
      char*       dbName = nodesGetValueFromNode(node);
3,432,872✔
4698
      tstrncpy((char*)pContext, varDataVal(dbName), TSDB_DB_NAME_LEN);
3,432,872✔
4699
      return DEAL_RES_END;  // stop walk
3,432,872✔
4700
    }
4701
    default:
2,376,829✔
4702
      break;
2,376,829✔
4703
  }
4704
  return DEAL_RES_CONTINUE;
2,376,829✔
4705
}
4706

4707
static void getDBNameFromCondition(SNode* pCondition, const char* dbName) {
13,089,767✔
4708
  if (NULL == pCondition) {
13,089,767✔
4709
    return;
3,907,214✔
4710
  }
4711
  nodesWalkExpr(pCondition, getDBNameFromConditionWalker, (char*)dbName);
9,182,553✔
4712
}
4713

4714
static int32_t doSysTableScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
38,036,274✔
4715
  // build message and send to mnode to fetch the content of system tables.
4716
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
38,036,274✔
4717
  SSysTableScanInfo* pInfo = pOperator->info;
38,042,713✔
4718
  char               dbName[TSDB_DB_NAME_LEN] = {0};
38,039,459✔
4719

4720
  while (1) {
×
4721
    if (isTaskKilled(pOperator->pTaskInfo)) {
38,032,542✔
4722
      setOperatorCompleted(pOperator);
×
4723
      (*ppRes) = NULL;
×
4724
      break;
×
4725
    }
4726

4727
    blockDataCleanup(pInfo->pRes);
38,037,428✔
4728

4729
    const char* name = tNameGetTableName(&pInfo->name);
38,046,294✔
4730
    if (pInfo->showRewrite) {
38,047,377✔
4731
      getDBNameFromCondition(pInfo->pCondition, dbName);
7,361,246✔
4732
      if (strncasecmp(name, TSDB_INS_TABLE_COMPACTS, TSDB_TABLE_FNAME_LEN) != 0 &&
7,361,918✔
4733
          strncasecmp(name, TSDB_INS_TABLE_SCANS, TSDB_TABLE_FNAME_LEN) != 0 &&
6,671,131✔
4734
          strncasecmp(name, TSDB_INS_TABLE_COMPACT_DETAILS, TSDB_TABLE_FNAME_LEN) != 0 &&
6,666,838✔
4735
          strncasecmp(name, TSDB_INS_TABLE_SSMIGRATES, TSDB_TABLE_FNAME_LEN) != 0 &&
6,605,670✔
4736
          strncasecmp(name, TSDB_INS_TABLE_SCAN_DETAILS, TSDB_TABLE_FNAME_LEN) != 0 &&
6,423,417✔
4737
          strncasecmp(name, TSDB_INS_TABLE_TRANSACTION_DETAILS, TSDB_TABLE_FNAME_LEN) != 0) {
6,418,645✔
4738
        TAOS_UNUSED(snprintf(pInfo->req.db, sizeof(pInfo->req.db), "%d.%s", pInfo->accountId, dbName));
6,417,866✔
4739
      }
4740
    } else if (strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0) {
30,682,658✔
4741
      getDBNameFromCondition(pInfo->pCondition, dbName);
5,729,051✔
4742
      if (dbName[0]) TAOS_UNUSED(snprintf(pInfo->req.db, sizeof(pInfo->req.db), "%d.%s", pInfo->accountId, dbName));
5,728,521✔
4743
      (void)sysTableIsCondOnOneTable(pInfo->pCondition, pInfo->req.filterTb);
5,728,521✔
4744
    }
4745
    bool         filter = true;
38,039,844✔
4746
    SSDataBlock* pBlock = NULL;
38,039,844✔
4747
    if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0) {
38,039,844✔
4748
      pBlock = sysTableScanUserTables(pOperator);
2,393,851✔
4749
    } else if (strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0) {
35,645,993✔
4750
      pBlock = sysTableScanUserTags(pOperator);
1,710,615✔
4751
    } else if (strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 && pInfo->readHandle.mnd == NULL) {
33,935,378✔
4752
      pBlock = sysTableScanUserCols(pOperator);
4,761,317✔
4753
    } else if (strncasecmp(name, TSDB_INS_TABLE_VC_COLS, TSDB_TABLE_FNAME_LEN) == 0 && pInfo->readHandle.mnd == NULL) {
29,172,471✔
4754
      pBlock = sysTableScanUserVcCols(pOperator);
19,208,319✔
4755
    } else if (strncasecmp(name, TSDB_INS_TABLE_STABLES, TSDB_TABLE_FNAME_LEN) == 0 && pInfo->showRewrite &&
9,966,340✔
4756
               IS_SYS_DBNAME(dbName)) {
390,338✔
4757
      pBlock = sysTableScanUserSTables(pOperator);
×
4758
    } else if (strncasecmp(name, TSDB_INS_DISK_USAGE, TSDB_TABLE_FNAME_LEN) == 0) {
9,969,718✔
4759
      pBlock = sysTableScanUsage(pOperator);
14,726✔
4760
    } else if (strncasecmp(name, TSDB_INS_TABLE_FILESETS, TSDB_TABLE_FNAME_LEN) == 0) {
9,954,992✔
4761
      pBlock = sysTableScanUserFileSets(pOperator);
492✔
4762
    } else if (strncasecmp(name, TSDB_INS_TABLE_VIRTUAL_TABLES_REFERENCING, TSDB_TABLE_FNAME_LEN) == 0) {
9,954,500✔
4763
      pBlock = sysTableScanVirtualTableRef(pOperator);
218,957✔
4764
    } else {  // load the meta from mnode of the given epset
4765
      pBlock = sysTableScanFromMNode(pOperator, pInfo, name, pTaskInfo);
9,735,543✔
4766
    }
4767

4768
    /* record input rows before filter */
4769
    pOperator->cost.inputRows += (pBlock == NULL) ? 0 : pBlock->info.rows;
38,041,644✔
4770
    if (!pInfo->skipFilterTable) sysTableScanFillTbName(pOperator, pInfo, name, pBlock);
38,042,926✔
4771
    if (pBlock != NULL) {
38,039,479✔
4772
      bool limitReached = applyLimitOffset(&pInfo->limitInfo, pBlock, pTaskInfo);
11,705,503✔
4773
      if (limitReached) {
11,707,059✔
4774
        setOperatorCompleted(pOperator);
42,692✔
4775
      }
4776

4777
      if (pBlock->info.rows == 0) {
11,707,059✔
4778
        continue;
×
4779
      }
4780
      (*ppRes) = pBlock;
11,706,321✔
4781
    } else {
4782
      (*ppRes) = NULL;
26,333,976✔
4783
    }
4784
    break;
38,040,460✔
4785
  }
4786

4787
  if (pTaskInfo->code) {
38,040,460✔
4788
    qError("%s failed since %s", __func__, tstrerror(pTaskInfo->code));
2,482✔
4789
    T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
2,482✔
4790
  }
4791
  return pTaskInfo->code;
38,040,406✔
4792
}
4793

4794
static void sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScanInfo* pInfo, const char* name,
38,038,564✔
4795
                                   SSDataBlock* pBlock) {
4796
  int32_t        code = TSDB_CODE_SUCCESS;
38,038,564✔
4797
  int32_t        lino = 0;
38,038,564✔
4798
  SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
38,038,564✔
4799
  if (pBlock == NULL) {
38,039,667✔
4800
    return;
26,334,178✔
4801
  }
4802

4803
  if (pInfo->tbnameSlotId != -1) {
11,705,489✔
4804
    SColumnInfoData* pColumnInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, pInfo->tbnameSlotId);
4,191✔
4805
    QUERY_CHECK_NULL(pColumnInfoData, code, lino, _end, terrno);
4,191✔
4806
    char varTbName[TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE] = {0};
4,191✔
4807
    STR_TO_VARSTR(varTbName, name);
4,191✔
4808

4809
    code = colDataSetNItems(pColumnInfoData, 0, varTbName, pBlock->info.rows, 1, true);
4,191✔
4810
    QUERY_CHECK_CODE(code, lino, _end);
4,191✔
4811
  }
4812

4813
  code = doFilter(pBlock, pOperator->exprSupp.pFilterInfo, NULL, NULL);
11,706,772✔
4814
  QUERY_CHECK_CODE(code, lino, _end);
11,707,048✔
4815

4816
_end:
11,707,048✔
4817
  if (code != TSDB_CODE_SUCCESS) {
11,707,156✔
4818
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4819
    pTaskInfo->code = code;
×
4820
    T_LONG_JMP(pTaskInfo->env, code);
×
4821
  }
4822
}
4823

4824
static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableScanInfo* pInfo, const char* name,
9,735,543✔
4825
                                          SExecTaskInfo* pTaskInfo) {
4826
  int32_t code = TSDB_CODE_SUCCESS;
9,735,543✔
4827
  int32_t lino = 0;
9,735,543✔
4828
  if (pOperator->status == OP_EXEC_DONE) {
9,735,543✔
4829
    return NULL;
4,089,727✔
4830
  }
4831

4832
  while (1) {
41,662✔
4833
    int64_t startTs = taosGetTimestampUs();
5,687,478✔
4834
    tstrncpy(pInfo->req.tb, tNameGetTableName(&pInfo->name), tListLen(pInfo->req.tb));
5,687,478✔
4835
    tstrncpy(pInfo->req.user, pInfo->pUser, tListLen(pInfo->req.user));
5,687,478✔
4836

4837
    int32_t contLen = tSerializeSRetrieveTableReq(NULL, 0, &pInfo->req);
5,687,478✔
4838
    char*   buf1 = taosMemoryCalloc(1, contLen);
5,687,478✔
4839
    if (!buf1) {
5,687,478✔
4840
      return NULL;
4,233✔
4841
    }
4842
    int32_t tempRes = tSerializeSRetrieveTableReq(buf1, contLen, &pInfo->req);
5,687,478✔
4843
    if (tempRes < 0) {
5,687,478✔
4844
      code = terrno;
×
4845
      taosMemoryFree(buf1);
×
4846
      return NULL;
×
4847
    }
4848

4849
    // send the fetch remote task result reques
4850
    SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
5,687,478✔
4851
    if (NULL == pMsgSendInfo) {
5,686,948✔
4852
      qError("%s prepare message %d failed", GET_TASKID(pTaskInfo), (int32_t)sizeof(SMsgSendInfo));
×
4853
      pTaskInfo->code = terrno;
×
4854
      taosMemoryFree(buf1);
×
4855
      return NULL;
×
4856
    }
4857

4858
    int32_t msgType = (strcasecmp(name, TSDB_INS_TABLE_DNODE_VARIABLES) == 0) ? TDMT_DND_SYSTABLE_RETRIEVE
5,691,181✔
4859
                                                                              : TDMT_MND_SYSTABLE_RETRIEVE;
5,686,948✔
4860

4861
    pMsgSendInfo->param = pOperator;
5,686,948✔
4862
    pMsgSendInfo->msgInfo.pData = buf1;
5,687,478✔
4863
    pMsgSendInfo->msgInfo.len = contLen;
5,686,948✔
4864
    pMsgSendInfo->msgType = msgType;
5,686,948✔
4865
    pMsgSendInfo->fp = loadSysTableCallback;
5,687,478✔
4866
    pMsgSendInfo->requestId = pTaskInfo->id.queryId;
5,687,478✔
4867

4868
    code = asyncSendMsgToServer(pInfo->readHandle.pMsgCb->clientRpc, &pInfo->epSet, NULL, pMsgSendInfo);
5,687,478✔
4869
    if (code != TSDB_CODE_SUCCESS) {
5,687,478✔
4870
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
4871
      pTaskInfo->code = code;
×
4872
      T_LONG_JMP(pTaskInfo->env, code);
×
4873
    }
4874

4875
    code = tsem_timewait(&pInfo->ready, VTB_REF_RPC_TIMEOUT_MS);
5,687,478✔
4876
    if (code != TSDB_CODE_SUCCESS) {
5,687,478✔
4877
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
4878
      pTaskInfo->code = code;
×
4879
      T_LONG_JMP(pTaskInfo->env, code);
×
4880
    }
4881

4882
    if (pTaskInfo->code) {
5,687,478✔
4883
      qError("%s load meta data from mnode failed, totalRows:%" PRIu64 ", code:%s", GET_TASKID(pTaskInfo),
2,482✔
4884
             pInfo->loadInfo.totalRows, tstrerror(pTaskInfo->code));
4885
      return NULL;
2,482✔
4886
    }
4887

4888
    SRetrieveMetaTableRsp* pRsp = pInfo->pRsp;
5,684,996✔
4889
    pInfo->req.showId = pRsp->handle;
5,684,996✔
4890

4891
    if (pRsp->numOfRows == 0 || pRsp->completed) {
5,684,996✔
4892
      pOperator->status = OP_EXEC_DONE;
5,591,958✔
4893
      qDebug("%s load meta data from mnode completed, rowsOfSource:%d, totalRows:%" PRIu64, GET_TASKID(pTaskInfo),
5,591,958✔
4894
             pRsp->numOfRows, pInfo->loadInfo.totalRows);
4895

4896
      if (pRsp->numOfRows == 0) {
5,591,958✔
4897
        taosMemoryFree(pRsp);
354,713✔
4898
        return NULL;
354,713✔
4899
      }
4900
    }
4901

4902
    char* pStart = pRsp->data;
5,330,283✔
4903
    code = extractDataBlockFromFetchRsp(pInfo->pRes, pRsp->data, pInfo->matchInfo.pList, &pStart, false);
5,330,283✔
4904
    if (code != TSDB_CODE_SUCCESS) {
5,330,283✔
4905
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
4906
      pTaskInfo->code = code;
×
4907
      taosMemoryFreeClear(pRsp);
×
4908
      T_LONG_JMP(pTaskInfo->env, code);
×
4909
    }
4910
    updateLoadRemoteInfo(&pInfo->loadInfo, pRsp->numOfRows, pRsp->compLen, startTs, pOperator);
5,330,283✔
4911
    // todo log the filter info
4912
    code = doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
5,330,283✔
4913
    if (code != TSDB_CODE_SUCCESS) {
5,330,283✔
4914
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
4915
      pTaskInfo->code = code;
×
4916
      taosMemoryFreeClear(pRsp);
×
4917
      T_LONG_JMP(pTaskInfo->env, code);
×
4918
    }
4919
    taosMemoryFree(pRsp);
5,330,283✔
4920
    if (pInfo->pRes->info.rows > 0) {
5,330,283✔
4921
      return pInfo->pRes;
4,133,605✔
4922
    } else if (pOperator->status == OP_EXEC_DONE) {
1,196,678✔
4923
      return NULL;
1,155,016✔
4924
    }
4925
  }
4926
}
4927

4928
static int32_t resetSysTableScanOperState(SOperatorInfo* pOper) {
609,260✔
4929
  SSysTableScanInfo* pInfo = pOper->info;
609,260✔
4930

4931
  SSystemTableScanPhysiNode* pScanPhyNode = (SSystemTableScanPhysiNode*)pOper->pPhyNode;
609,260✔
4932
  pOper->status = OP_NOT_OPENED;
609,260✔
4933
  blockDataEmpty(pInfo->pRes);
609,260✔
4934

4935
  if (pInfo->name.type == TSDB_TABLE_NAME_T) {
609,260✔
4936
    const char* name = tNameGetTableName(&pInfo->name);
609,260✔
4937
    if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
609,260✔
4938
        strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 ||
609,260✔
4939
        strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 ||
609,260✔
4940
        strncasecmp(name, TSDB_INS_TABLE_VC_COLS, TSDB_TABLE_FNAME_LEN) == 0 ||
609,260✔
4941
        strncasecmp(name, TSDB_INS_TABLE_VIRTUAL_TABLES_REFERENCING, TSDB_TABLE_FNAME_LEN) == 0 ||
×
4942
        pInfo->pCur != NULL) {
×
4943
      if (pInfo->pAPI != NULL && pInfo->pAPI->metaFn.closeTableMetaCursor != NULL) {
609,260✔
4944
        pInfo->pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
609,260✔
4945
      }
4946

4947
      pInfo->pCur = NULL;
609,260✔
4948
    }
4949
  } else {
4950
    qError("pInfo->name is not initialized");
×
4951
  }
4952

4953
  initLimitInfo(pScanPhyNode->scan.node.pLimit, pScanPhyNode->scan.node.pSlimit, &pInfo->limitInfo);
609,260✔
4954
  pInfo->loadInfo.totalRows = 0;
609,260✔
4955

4956
  if (pScanPhyNode->scan.virtualStableScan) {
609,260✔
4957
    SExecTaskInfo* pTaskInfo = pOper->pTaskInfo;
609,260✔
4958
    tableListDestroy(pInfo->pSubTableListInfo);
609,260✔
4959
    pInfo->pSubTableListInfo = tableListCreate();
609,260✔
4960
    if (!pInfo->pSubTableListInfo) {
609,260✔
4961
      pTaskInfo->code = terrno;
×
4962
      qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
×
4963
      return terrno;
×
4964
    }
4965

4966
    int32_t code = createScanTableListInfo((SScanPhysiNode*)pScanPhyNode, NULL, false, &pInfo->readHandle,
609,260✔
4967
                                           pInfo->pSubTableListInfo, NULL, NULL, pTaskInfo, NULL);
4968
    if (code != TSDB_CODE_SUCCESS) {
609,260✔
4969
      pTaskInfo->code = code;
×
4970
      tableListDestroy(pInfo->pSubTableListInfo);
×
4971
      return code;
×
4972
    }
4973
  }
4974

4975
  if (pInfo->pIdx) {
609,260✔
4976
    taosArrayDestroy(pInfo->pIdx->uids);
×
4977
    taosMemoryFree(pInfo->pIdx);
×
4978
    pInfo->pIdx = NULL;
×
4979
  }
4980

4981
  if (pInfo->pSchema) {
609,260✔
4982
    taosHashCleanup(pInfo->pSchema);
609,260✔
4983
    pInfo->pSchema = NULL;
609,260✔
4984
  }
4985

4986
  if (pInfo->pExtSchema) {
609,260✔
4987
    taosHashCleanup(pInfo->pExtSchema);
×
4988
    pInfo->pExtSchema = NULL;
×
4989
  }
4990
  pInfo->readHandle.mnd = NULL;
609,260✔
4991

4992
  return 0;
609,260✔
4993
}
4994

4995
int32_t createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode,
25,742,927✔
4996
                                       STableListInfo* pTableListInfo, const char* pUser, SExecTaskInfo* pTaskInfo,
4997
                                       SOperatorInfo** pOptrInfo) {
4998
  QRY_PARAM_CHECK(pOptrInfo);
25,742,927✔
4999

5000
  int32_t            code = TSDB_CODE_SUCCESS;
25,746,013✔
5001
  int32_t            lino = 0;
25,746,013✔
5002
  SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
25,746,013✔
5003
  SOperatorInfo*     pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
25,735,056✔
5004
  if (pInfo == NULL || pOperator == NULL) {
25,739,927✔
UNCOV
5005
    code = terrno;
×
5006
    lino = __LINE__;
×
5007
    goto _error;
×
5008
  }
5009
  initOperatorCostInfo(pOperator);
25,739,927✔
5010

5011
  pOperator->pPhyNode = pScanPhyNode;
25,744,920✔
5012
  SScanPhysiNode*     pScanNode = &pScanPhyNode->scan;
25,748,260✔
5013
  SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;
25,747,637✔
5014
  QUERY_CHECK_CODE(code, lino, _error);
25,746,658✔
5015

5016
  int32_t num = 0;
25,746,658✔
5017
  code = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &num, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
25,746,186✔
5018
  QUERY_CHECK_CODE(code, lino, _error);
25,742,617✔
5019

5020
  extractTbnameSlotId(pInfo, pScanNode);
25,742,617✔
5021

5022
  pInfo->pAPI = &pTaskInfo->storageAPI;
25,732,972✔
5023

5024
  pInfo->accountId = pScanPhyNode->accountId;
25,738,745✔
5025
  pInfo->pUser = taosStrdup((void*)pUser);
25,733,410✔
5026
  QUERY_CHECK_NULL(pInfo->pUser, code, lino, _error, terrno);
25,747,474✔
5027
  pInfo->privInfo = pScanPhyNode->privInfo;
25,740,656✔
5028
  pInfo->sysInfo = pScanPhyNode->sysInfo;
25,734,568✔
5029
  pInfo->showRewrite = pScanPhyNode->showRewrite;
25,746,359✔
5030
  pInfo->pRes = createDataBlockFromDescNode(pDescNode);
25,733,376✔
5031
  QUERY_CHECK_NULL(pInfo->pRes, code, lino, _error, terrno);
25,748,138✔
5032

5033
  pInfo->pCondition = pScanNode->node.pConditions;
25,739,550✔
5034

5035
  tNameAssign(&pInfo->name, &pScanNode->tableName);
25,745,375✔
5036
  const char* name = tNameGetTableName(&pInfo->name);
25,732,549✔
5037
  if (pInfo->showRewrite == false) {
25,734,148✔
5038
    code = filterInitFromNode(pScanNode->node.pConditions, &pOperator->exprSupp.pFilterInfo, 0,
21,847,124✔
5039
                              pTaskInfo->pStreamRuntimeInfo);
21,840,255✔
5040
  } else {
5041
    if (strncasecmp(name, TSDB_INS_DISK_USAGE, TSDB_TABLE_FNAME_LEN) == 0) {
3,895,766✔
5042
      pInfo->skipFilterTable = true;
724✔
5043
      code = filterInitFromNode(NULL, &pOperator->exprSupp.pFilterInfo, 0, pTaskInfo->pStreamRuntimeInfo);
724✔
5044
    } else {
5045
      code = filterInitFromNode(pScanNode->node.pConditions, &pOperator->exprSupp.pFilterInfo, 0,
3,895,907✔
5046
                                pTaskInfo->pStreamRuntimeInfo);
3,895,042✔
5047
    }
5048
  }
5049
  QUERY_CHECK_CODE(code, lino, _error);
25,736,413✔
5050

5051
  initLimitInfo(pScanPhyNode->scan.node.pLimit, pScanPhyNode->scan.node.pSlimit, &pInfo->limitInfo);
25,736,413✔
5052
  // since max column changed from 4096 -> 32767, we set the initial result size to 32K
5053
  initResultSizeInfo(&pOperator->resultInfo, 32768);
25,735,644✔
5054
  code = blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
25,732,118✔
5055
  QUERY_CHECK_CODE(code, lino, _error);
25,751,173✔
5056

5057
  if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
25,751,173✔
5058
      strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 ||
24,286,158✔
5059
      strncasecmp(name, TSDB_INS_TABLE_FILESETS, TSDB_TABLE_FNAME_LEN) == 0) {
23,378,641✔
5060
    pInfo->readHandle = *(SReadHandle*)readHandle;
2,375,175✔
5061
  } else {
5062
    if (tsem_init(&pInfo->ready, 0, 0) != TSDB_CODE_SUCCESS) {
23,375,998✔
5063
      code = TSDB_CODE_FAILED;
×
5064
      goto _error;
×
5065
    }
5066
    pInfo->epSet = pScanPhyNode->mgmtEpSet;
23,375,509✔
5067
    pInfo->readHandle = *(SReadHandle*)readHandle;
23,376,723✔
5068
  }
5069

5070
  pInfo->pSubTableListInfo = pTableListInfo;
25,749,508✔
5071

5072
  setOperatorInfo(pOperator, "SysTableScanOperator", QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN, false, OP_NOT_OPENED,
25,748,829✔
5073
                  pInfo, pTaskInfo);
5074
  pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pRes->pDataBlock);
25,748,312✔
5075
  pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doSysTableScanNext, NULL, destroySysScanOperator,
25,751,124✔
5076
                                         optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
5077
  setOperatorResetStateFn(pOperator, resetSysTableScanOperState);
25,748,212✔
5078

5079
  *pOptrInfo = pOperator;
25,749,214✔
5080
  return code;
25,745,982✔
5081

5082
_error:
×
5083
  if (pInfo != NULL) {
×
5084
    destroySysScanOperator(pInfo);
×
5085
  }
5086
  if (code != TSDB_CODE_SUCCESS) {
×
5087
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5088
  }
5089
  if (pOperator != NULL) {
×
5090
    pOperator->info = NULL;
×
5091
    destroyOperator(pOperator);
×
5092
  }
5093
  pTaskInfo->code = code;
×
5094
  return code;
×
5095
}
5096

5097
void extractTbnameSlotId(SSysTableScanInfo* pInfo, const SScanPhysiNode* pScanNode) {
25,741,056✔
5098
  pInfo->tbnameSlotId = -1;
25,741,056✔
5099
  if (pScanNode->pScanPseudoCols != NULL) {
25,745,081✔
5100
    SNode* pNode = NULL;
5,243✔
5101
    FOREACH(pNode, pScanNode->pScanPseudoCols) {
10,486✔
5102
      STargetNode* pTargetNode = NULL;
5,243✔
5103
      if (nodeType(pNode) == QUERY_NODE_TARGET) {
5,243✔
5104
        pTargetNode = (STargetNode*)pNode;
5,243✔
5105
        SNode* expr = pTargetNode->pExpr;
5,243✔
5106
        if (nodeType(expr) == QUERY_NODE_FUNCTION) {
5,243✔
5107
          SFunctionNode* pFuncNode = (SFunctionNode*)expr;
5,243✔
5108
          if (pFuncNode->funcType == FUNCTION_TYPE_TBNAME) {
5,243✔
5109
            pInfo->tbnameSlotId = pTargetNode->slotId;
4,519✔
5110
          }
5111
        }
5112
      }
5113
    }
5114
  }
5115
}
25,737,052✔
5116

5117
void destroySysScanOperator(void* param) {
25,741,306✔
5118
  SSysTableScanInfo* pInfo = (SSysTableScanInfo*)param;
25,741,306✔
5119
  int32_t            code = tsem_destroy(&pInfo->ready);
25,741,306✔
5120
  if (code != TSDB_CODE_SUCCESS) {
25,741,180✔
5121
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
5122
  }
5123
  blockDataDestroy(pInfo->pRes);
25,741,180✔
5124

5125
  if (pInfo->name.type == TSDB_TABLE_NAME_T) {
25,747,839✔
5126
    const char* name = tNameGetTableName(&pInfo->name);
25,749,046✔
5127
    if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
25,749,889✔
5128
        strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 ||
24,283,118✔
5129
        strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 ||
23,376,355✔
5130
        strncasecmp(name, TSDB_INS_TABLE_VC_COLS, TSDB_TABLE_FNAME_LEN) == 0 ||
18,843,691✔
5131
        strncasecmp(name, TSDB_INS_TABLE_VIRTUAL_TABLES_REFERENCING, TSDB_TABLE_FNAME_LEN) == 0 ||
4,786,317✔
5132
        pInfo->pCur != NULL) {
4,638,663✔
5133
      if (pInfo->pAPI != NULL && pInfo->pAPI->metaFn.closeTableMetaCursor != NULL) {
21,111,226✔
5134
        pInfo->pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
20,014,186✔
5135
      }
5136

5137
      pInfo->pCur = NULL;
21,104,680✔
5138
    }
5139
  } else {
5140
    qError("pInfo->name is not initialized");
×
5141
  }
5142

5143
  if (pInfo->pIdx) {
25,751,046✔
5144
    taosArrayDestroy(pInfo->pIdx->uids);
770,136✔
5145
    taosMemoryFree(pInfo->pIdx);
770,136✔
5146
    pInfo->pIdx = NULL;
770,136✔
5147
  }
5148

5149
  if (pInfo->pSchema) {
25,746,829✔
5150
    taosHashCleanup(pInfo->pSchema);
17,701,763✔
5151
    pInfo->pSchema = NULL;
17,700,452✔
5152
  }
5153
  if (pInfo->pExtSchema) {
25,745,524✔
5154
    taosHashCleanup(pInfo->pExtSchema);
3,568,671✔
5155
    pInfo->pExtSchema = NULL;
3,568,671✔
5156
  }
5157
  tableListDestroy(pInfo->pSubTableListInfo);
25,745,437✔
5158

5159
  taosArrayDestroy(pInfo->matchInfo.pList);
25,748,871✔
5160
  taosMemoryFreeClear(pInfo->pUser);
25,751,706✔
5161

5162
  taosMemoryFreeClear(param);
25,749,210✔
5163
}
25,749,781✔
5164

5165
int32_t loadSysTableCallback(void* param, SDataBuf* pMsg, int32_t code) {
5,687,478✔
5166
  SOperatorInfo*     operator=(SOperatorInfo*) param;
5,687,478✔
5167
  SSysTableScanInfo* pScanResInfo = (SSysTableScanInfo*)operator->info;
5,687,478✔
5168
  if (TSDB_CODE_SUCCESS == code) {
5,687,478✔
5169
    pScanResInfo->pRsp = pMsg->pData;
5,684,996✔
5170

5171
    SRetrieveMetaTableRsp* pRsp = pScanResInfo->pRsp;
5,684,996✔
5172
    pRsp->numOfRows = htonl(pRsp->numOfRows);
5,684,996✔
5173
    pRsp->useconds = htobe64(pRsp->useconds);
5,684,996✔
5174
    pRsp->handle = htobe64(pRsp->handle);
5,684,996✔
5175
    pRsp->compLen = htonl(pRsp->compLen);
5,684,996✔
5176
  } else {
5177
    operator->pTaskInfo->code = rpcCvtErrCode(code);
2,482✔
5178
    if (operator->pTaskInfo->code != code) {
2,482✔
5179
      qError("load systable rsp received, error:%s, cvted error:%s", tstrerror(code),
×
5180
             tstrerror(operator->pTaskInfo->code));
5181
    } else {
5182
      qError("load systable rsp received, error:%s", tstrerror(code));
2,482✔
5183
    }
5184
  }
5185

5186
  int32_t res = tsem_post(&pScanResInfo->ready);
5,687,478✔
5187
  if (res != TSDB_CODE_SUCCESS) {
5,687,478✔
5188
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(res));
×
5189
  }
5190
  return TSDB_CODE_SUCCESS;
5,687,478✔
5191
}
5192

5193
static int32_t sysChkFilter__Comm(SNode* pNode) {
303,112✔
5194
  // impl
5195
  SOperatorNode* pOper = (SOperatorNode*)pNode;
303,112✔
5196
  EOperatorType  opType = pOper->opType;
303,112✔
5197
  if (opType != OP_TYPE_EQUAL && opType != OP_TYPE_LOWER_EQUAL && opType != OP_TYPE_LOWER_THAN &&
303,112✔
5198
      opType != OP_TYPE_GREATER_EQUAL && opType != OP_TYPE_GREATER_THAN) {
328✔
5199
    return -1;
×
5200
  }
5201
  return 0;
303,112✔
5202
}
5203

5204
static int32_t sysChkFilter__DBName(SNode* pNode) {
574,802✔
5205
  SOperatorNode* pOper = (SOperatorNode*)pNode;
574,802✔
5206

5207
  if (pOper->opType != OP_TYPE_EQUAL && pOper->opType != OP_TYPE_NOT_EQUAL) {
574,802✔
5208
    return -1;
×
5209
  }
5210

5211
  SValueNode* pVal = (SValueNode*)pOper->pRight;
574,802✔
5212
  if (!IS_STR_DATA_TYPE(pVal->node.resType.type)) {
574,770✔
5213
    return -1;
×
5214
  }
5215

5216
  return 0;
574,802✔
5217
}
5218
static int32_t sysChkFilter__VgroupId(SNode* pNode) {
×
5219
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
5220
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
5221
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
×
5222
    return -1;
×
5223
  }
5224
  return sysChkFilter__Comm(pNode);
×
5225
}
5226
static int32_t sysChkFilter__TableName(SNode* pNode) {
293,871✔
5227
  SOperatorNode* pOper = (SOperatorNode*)pNode;
293,871✔
5228
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
293,871✔
5229
  if (!IS_STR_DATA_TYPE(pVal->node.resType.type)) {
293,871✔
5230
    return -1;
×
5231
  }
5232
  return sysChkFilter__Comm(pNode);
293,871✔
5233
}
5234
static int32_t sysChkFilter__CreateTime(SNode* pNode) {
1,736✔
5235
  SOperatorNode* pOper = (SOperatorNode*)pNode;
1,736✔
5236
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
1,736✔
5237

5238
  if (!IS_TIMESTAMP_TYPE(pVal->node.resType.type)) {
1,736✔
5239
    return -1;
×
5240
  }
5241
  return sysChkFilter__Comm(pNode);
1,736✔
5242
}
5243

5244
static int32_t sysChkFilter__Ncolumn(SNode* pNode) {
×
5245
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
5246
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
5247

5248
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
×
5249
    return -1;
×
5250
  }
5251
  return sysChkFilter__Comm(pNode);
×
5252
}
5253
static int32_t sysChkFilter__Ttl(SNode* pNode) {
×
5254
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
5255
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
5256

5257
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
×
5258
    return -1;
×
5259
  }
5260
  return sysChkFilter__Comm(pNode);
×
5261
}
5262
static int32_t sysChkFilter__STableName(SNode* pNode) {
7,505✔
5263
  SOperatorNode* pOper = (SOperatorNode*)pNode;
7,505✔
5264
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
7,505✔
5265
  if (!IS_STR_DATA_TYPE(pVal->node.resType.type)) {
7,505✔
5266
    return -1;
×
5267
  }
5268
  return sysChkFilter__Comm(pNode);
7,505✔
5269
}
5270
static int32_t sysChkFilter__Uid(SNode* pNode) {
×
5271
  SOperatorNode* pOper = (SOperatorNode*)pNode;
×
5272
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
×
5273
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
×
5274
    return -1;
×
5275
  }
5276
  return sysChkFilter__Comm(pNode);
×
5277
}
5278
static int32_t sysChkFilter__Type(SNode* pNode) {
6,776✔
5279
  SOperatorNode* pOper = (SOperatorNode*)pNode;
6,776✔
5280
  SValueNode*    pVal = (SValueNode*)pOper->pRight;
6,776✔
5281
  if (!IS_INTEGER_TYPE(pVal->node.resType.type)) {
6,776✔
5282
    return -1;
6,776✔
5283
  }
5284
  return sysChkFilter__Comm(pNode);
×
5285
}
5286
static int32_t optSysTabFilteImpl(void* arg, SNode* cond, SArray* result) {
1,189,139✔
5287
  if (optSysCheckOper(cond) != 0) return -1;
1,189,139✔
5288

5289
  SOperatorNode* pNode = (SOperatorNode*)cond;
885,336✔
5290

5291
  int8_t i = 0;
885,336✔
5292
  for (; i < SYSTAB_FILTER_DICT_SIZE; i++) {
1,554,665✔
5293
    if (strcmp(filterDict[i].name, ((SColumnNode*)(pNode->pLeft))->colName) == 0) {
1,554,019✔
5294
      break;
884,690✔
5295
    }
5296
  }
5297
  if (i >= SYSTAB_FILTER_DICT_SIZE) return -1;
885,336✔
5298

5299
  if (filterDict[i].chkFunc(cond) != 0) return -1;
885,336✔
5300

5301
  return filterDict[i].fltFunc(arg, cond, result);
877,914✔
5302
}
5303

5304
static int32_t optSysCheckOper(SNode* pOpear) {
1,189,008✔
5305
  if (nodeType(pOpear) != QUERY_NODE_OPERATOR) return -1;
1,189,008✔
5306

5307
  SOperatorNode* pOper = (SOperatorNode*)pOpear;
1,186,576✔
5308
  if (pOper->opType < OP_TYPE_GREATER_THAN || pOper->opType > OP_TYPE_NOT_EQUAL) {
1,186,576✔
5309
    return -1;
279,256✔
5310
  }
5311

5312
  if (nodeType(pOper->pLeft) != QUERY_NODE_COLUMN || nodeType(pOper->pRight) != QUERY_NODE_VALUE) {
906,095✔
5313
    return -1;
21,952✔
5314
  }
5315
  return 0;
885,368✔
5316
}
5317

5318
static FORCE_INLINE int optSysBinarySearch(SArray* arr, int s, int e, uint64_t k) {
5319
  uint64_t v;
5320
  int32_t  m;
5321
  while (s <= e) {
×
5322
    m = s + (e - s) / 2;
×
5323
    v = *(uint64_t*)taosArrayGet(arr, m);
×
5324
    if (v >= k) {
×
5325
      e = m - 1;
×
5326
    } else {
5327
      s = m + 1;
×
5328
    }
5329
  }
5330
  return s;
×
5331
}
5332

5333
int32_t optSysIntersection(SArray* in, SArray* out) {
415,050✔
5334
  int32_t     code = TSDB_CODE_SUCCESS;
415,050✔
5335
  int32_t     lino = 0;
415,050✔
5336
  MergeIndex* mi = NULL;
415,050✔
5337
  int32_t     sz = (int32_t)taosArrayGetSize(in);
415,050✔
5338
  if (sz <= 0) {
415,728✔
5339
    goto _end;
413,992✔
5340
  }
5341
  mi = taosMemoryCalloc(sz, sizeof(MergeIndex));
1,736✔
5342
  QUERY_CHECK_NULL(mi, code, lino, _end, terrno);
1,736✔
5343
  for (int i = 0; i < sz; i++) {
3,472✔
5344
    SArray* t = taosArrayGetP(in, i);
1,736✔
5345
    mi[i].len = (int32_t)taosArrayGetSize(t);
1,736✔
5346
    mi[i].idx = 0;
1,736✔
5347
  }
5348

5349
  SArray* base = taosArrayGetP(in, 0);
1,736✔
5350
  for (int i = 0; i < taosArrayGetSize(base); i++) {
6,561,924✔
5351
    uint64_t tgt = *(uint64_t*)taosArrayGet(base, i);
6,560,188✔
5352
    bool     has = true;
6,560,188✔
5353
    for (int j = 1; j < taosArrayGetSize(in); j++) {
6,560,188✔
5354
      SArray* oth = taosArrayGetP(in, j);
×
5355
      int     mid = optSysBinarySearch(oth, mi[j].idx, mi[j].len - 1, tgt);
×
5356
      if (mid >= 0 && mid < mi[j].len) {
×
5357
        uint64_t val = *(uint64_t*)taosArrayGet(oth, mid);
×
5358
        has = (val == tgt ? true : false);
×
5359
        mi[j].idx = mid;
×
5360
      } else {
5361
        has = false;
×
5362
      }
5363
    }
5364
    if (has == true) {
6,560,188✔
5365
      void* tmp = taosArrayPush(out, &tgt);
6,560,188✔
5366
      if (!tmp) {
6,560,188✔
5367
        code = terrno;
×
5368
        goto _end;
×
5369
      }
5370
    }
5371
  }
5372

5373
_end:
1,736✔
5374
  taosMemoryFreeClear(mi);
415,728✔
5375
  if (code != TSDB_CODE_SUCCESS) {
415,728✔
5376
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5377
  }
5378
  return code;
415,050✔
5379
}
5380

5381
static int tableUidCompare(const void* a, const void* b) {
49,464,040✔
5382
  int64_t u1 = *(int64_t*)a;
49,464,040✔
5383
  int64_t u2 = *(int64_t*)b;
49,464,040✔
5384
  if (u1 == u2) {
49,464,040✔
5385
    return 0;
×
5386
  }
5387
  return u1 < u2 ? -1 : 1;
49,464,040✔
5388
}
5389

5390
static int32_t optSysMergeRslt(SArray* mRslt, SArray* rslt) {
415,050✔
5391
  // TODO, find comm mem from mRslt
5392
  for (int i = 0; i < taosArrayGetSize(mRslt); i++) {
416,786✔
5393
    SArray* arslt = taosArrayGetP(mRslt, i);
1,736✔
5394
    taosArraySort(arslt, tableUidCompare);
1,736✔
5395
  }
5396
  return optSysIntersection(mRslt, rslt);
415,728✔
5397
}
5398

5399
static int32_t optSysSpecialColumn(SNode* cond) {
416,034✔
5400
  SOperatorNode* pOper = (SOperatorNode*)cond;
416,034✔
5401
  SColumnNode*   pCol = (SColumnNode*)pOper->pLeft;
416,034✔
5402
  for (int i = 0; i < sizeof(SYSTABLE_SPECIAL_COL) / sizeof(SYSTABLE_SPECIAL_COL[0]); i++) {
419,506✔
5403
    if (0 == strcmp(pCol->colName, SYSTABLE_SPECIAL_COL[i])) {
417,770✔
5404
      return 1;
414,976✔
5405
    }
5406
  }
5407
  return 0;
1,736✔
5408
}
5409

5410
static int32_t optSysTabFilte(void* arg, SNode* cond, SArray* result) {
769,458✔
5411
  int ret = TSDB_CODE_FAILED;
769,458✔
5412
  if (nodeType(cond) == QUERY_NODE_OPERATOR) {
769,458✔
5413
    ret = optSysTabFilteImpl(arg, cond, result);
353,730✔
5414
    if (ret == 0) {
354,408✔
5415
      SOperatorNode* pOper = (SOperatorNode*)cond;
160,395✔
5416
      SColumnNode*   pCol = (SColumnNode*)pOper->pLeft;
160,395✔
5417
      if (0 == strcmp(pCol->colName, "create_time")) {
159,848✔
5418
        return 0;
×
5419
      }
5420
      return -1;
159,138✔
5421
    }
5422
    return ret;
194,013✔
5423
  }
5424

5425
  if (nodeType(cond) != QUERY_NODE_LOGIC_CONDITION || ((SLogicConditionNode*)cond)->condType != LOGIC_COND_TYPE_AND) {
415,728✔
5426
    return ret;
×
5427
  }
5428

5429
  SLogicConditionNode* pNode = (SLogicConditionNode*)cond;
415,728✔
5430
  SNodeList*           pList = (SNodeList*)pNode->pParameterList;
415,728✔
5431

5432
  int32_t len = LIST_LENGTH(pList);
415,728✔
5433

5434
  bool    hasIdx = false;
415,728✔
5435
  bool    hasRslt = true;
415,728✔
5436
  SArray* mRslt = taosArrayInit(len, POINTER_BYTES);
415,728✔
5437
  if (!mRslt) {
415,728✔
5438
    return terrno;
×
5439
  }
5440

5441
  SListCell* cell = pList->pHead;
415,728✔
5442
  for (int i = 0; i < len; i++) {
1,251,006✔
5443
    if (cell == NULL) break;
834,600✔
5444

5445
    SArray* aRslt = taosArrayInit(16, sizeof(int64_t));
834,600✔
5446
    if (!aRslt) {
835,278✔
5447
      return terrno;
×
5448
    }
5449

5450
    ret = optSysTabFilteImpl(arg, cell->pNode, aRslt);
835,278✔
5451
    if (ret == 0) {
834,600✔
5452
      // has index
5453
      hasIdx = true;
415,356✔
5454
      if (optSysSpecialColumn(cell->pNode) == 0) {
415,356✔
5455
        void* tmp = taosArrayPush(mRslt, &aRslt);
1,736✔
5456
        if (!tmp) {
1,736✔
5457
          return TSDB_CODE_FAILED;
×
5458
        }
5459
      } else {
5460
        // db_name/vgroup not result
5461
        taosArrayDestroy(aRslt);
414,298✔
5462
      }
5463
    } else if (ret == -2) {
419,244✔
5464
      // current vg
5465
      hasIdx = true;
×
5466
      hasRslt = false;
×
5467
      taosArrayDestroy(aRslt);
×
5468
      break;
×
5469
    } else {
5470
      taosArrayDestroy(aRslt);
419,244✔
5471
    }
5472
    cell = cell->pNext;
835,278✔
5473
  }
5474
  if (hasRslt && hasIdx) {
415,050✔
5475
    int32_t code = optSysMergeRslt(mRslt, result);
415,050✔
5476
    if (code != TSDB_CODE_SUCCESS) {
415,728✔
5477
      return code;
×
5478
    }
5479
  }
5480

5481
  for (int i = 0; i < taosArrayGetSize(mRslt); i++) {
417,464✔
5482
    SArray* aRslt = taosArrayGetP(mRslt, i);
1,736✔
5483
    taosArrayDestroy(aRslt);
1,736✔
5484
  }
5485
  taosArrayDestroy(mRslt);
415,728✔
5486
  if (hasRslt == false) {
414,372✔
5487
    return -2;
×
5488
  }
5489
  if (hasRslt && hasIdx) {
414,372✔
5490
    cell = pList->pHead;
414,372✔
5491
    for (int i = 0; i < len; i++) {
1,249,270✔
5492
      if (cell == NULL) break;
835,278✔
5493
      SOperatorNode* pOper = (SOperatorNode*)cell->pNode;
835,278✔
5494
      SColumnNode*   pCol = (SColumnNode*)pOper->pLeft;
834,600✔
5495
      if (nodeType(pOper->pLeft) == QUERY_NODE_COLUMN && 0 == strcmp(pCol->colName, "create_time")) {
835,278✔
5496
        return 0;
1,736✔
5497
      }
5498
      cell = cell->pNext;
832,186✔
5499
    }
5500
    return -1;
413,992✔
5501
  }
UNCOV
5502
  return -1;
×
5503
}
5504

5505
static int32_t doGetTableRowSize(SReadHandle* pHandle, uint64_t uid, int32_t* rowLen, const char* idstr) {
7,742✔
5506
  *rowLen = 0;
7,742✔
5507

5508
  SMetaReader mr = {0};
7,742✔
5509
  pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn);
7,742✔
5510
  int32_t code = pHandle->api.metaReaderFn.getTableEntryByUid(&mr, uid);
7,742✔
5511
  if (code != TSDB_CODE_SUCCESS) {
7,742✔
5512
    qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", uid, tstrerror(terrno), idstr);
×
5513
    pHandle->api.metaReaderFn.clearReader(&mr);
×
5514
    return terrno;
×
5515
  }
5516

5517
  if (mr.me.type == TSDB_SUPER_TABLE) {
7,742✔
5518
    int32_t numOfCols = mr.me.stbEntry.schemaRow.nCols;
6,398✔
5519
    for (int32_t i = 0; i < numOfCols; ++i) {
44,792✔
5520
      (*rowLen) += mr.me.stbEntry.schemaRow.pSchema[i].bytes;
38,394✔
5521
    }
5522
  } else if (mr.me.type == TSDB_CHILD_TABLE) {
1,344✔
5523
    uint64_t suid = mr.me.ctbEntry.suid;
×
5524
    tDecoderClear(&mr.coder);
×
5525
    code = pHandle->api.metaReaderFn.getTableEntryByUid(&mr, suid);
×
5526
    if (code != TSDB_CODE_SUCCESS) {
×
5527
      qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", suid, tstrerror(terrno), idstr);
×
5528
      pHandle->api.metaReaderFn.clearReader(&mr);
×
5529
      return terrno;
×
5530
    }
5531

5532
    int32_t numOfCols = mr.me.stbEntry.schemaRow.nCols;
×
5533

5534
    for (int32_t i = 0; i < numOfCols; ++i) {
×
5535
      (*rowLen) += mr.me.stbEntry.schemaRow.pSchema[i].bytes;
×
5536
    }
5537
  } else if (mr.me.type == TSDB_NORMAL_TABLE) {
1,344✔
5538
    int32_t numOfCols = mr.me.ntbEntry.schemaRow.nCols;
1,344✔
5539
    for (int32_t i = 0; i < numOfCols; ++i) {
4,032✔
5540
      (*rowLen) += mr.me.ntbEntry.schemaRow.pSchema[i].bytes;
2,688✔
5541
    }
5542
  }
5543

5544
  pHandle->api.metaReaderFn.clearReader(&mr);
7,742✔
5545
  return TSDB_CODE_SUCCESS;
7,742✔
5546
}
5547

5548
static int32_t doBlockInfoScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
11,092✔
5549
  int32_t code = TSDB_CODE_SUCCESS;
11,092✔
5550
  int32_t lino = 0;
11,092✔
5551
  if (pOperator->status == OP_EXEC_DONE) {
11,092✔
5552
    (*ppRes) = NULL;
5,526✔
5553
    return code;
5,526✔
5554
  }
5555

5556
  SBlockDistInfo* pBlockScanInfo = pOperator->info;
5,546✔
5557
  SExecTaskInfo*  pTaskInfo = pOperator->pTaskInfo;
5,546✔
5558
  SStorageAPI*    pAPI = &pTaskInfo->storageAPI;
5,546✔
5559

5560
  STableBlockDistInfo blockDistInfo = {.minRows = INT_MAX, .maxRows = INT_MIN};
5,546✔
5561
  code = doGetTableRowSize(&pBlockScanInfo->readHandle, pBlockScanInfo->uid, (int32_t*)&blockDistInfo.rowSize,
5,546✔
5562
                           GET_TASKID(pTaskInfo));
5,546✔
5563
  QUERY_CHECK_CODE(code, lino, _end);
5,546✔
5564

5565
  code = pAPI->tsdReader.tsdReaderGetDataBlockDistInfo(pBlockScanInfo->pHandle, &blockDistInfo);
5,546✔
5566
  QUERY_CHECK_CODE(code, lino, _end);
5,546✔
5567

5568
  code = (int32_t)pAPI->tsdReader.tsdReaderGetNumOfInMemRows(pBlockScanInfo->pHandle, &blockDistInfo.numOfInmemRows);
5,546✔
5569
  QUERY_CHECK_CODE(code, lino, _end);
5,546✔
5570

5571
  SSDataBlock* pBlock = pBlockScanInfo->pResBlock;
5,546✔
5572

5573
  int32_t          slotId = pOperator->exprSupp.pExprInfo->base.resSchema.slotId;
5,546✔
5574
  SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, slotId);
5,546✔
5575
  QUERY_CHECK_NULL(pColInfo, code, lino, _end, terrno);
5,546✔
5576

5577
  int32_t len = tSerializeBlockDistInfo(NULL, 0, &blockDistInfo);
5,546✔
5578
  char*   p = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
5,546✔
5579
  QUERY_CHECK_NULL(p, code, lino, _end, terrno);
5,546✔
5580

5581
  int32_t tempRes = tSerializeBlockDistInfo(varDataVal(p), len, &blockDistInfo);
5,546✔
5582
  if (tempRes < 0) {
5,546✔
5583
    code = terrno;
×
5584
    QUERY_CHECK_CODE(code, lino, _end);
×
5585
  }
5586
  varDataSetLen(p, len);
5,546✔
5587

5588
  code = colDataSetVal(pColInfo, 0, p, false);
5,546✔
5589
  QUERY_CHECK_CODE(code, lino, _end);
5,546✔
5590

5591
  taosMemoryFree(p);
5,546✔
5592

5593
  // make the valgrind happy that all memory buffer has been initialized already.
5594
  if (slotId != 0) {
5,546✔
5595
    SColumnInfoData* p1 = taosArrayGet(pBlock->pDataBlock, 0);
5,546✔
5596
    QUERY_CHECK_NULL(p1, code, lino, _end, terrno);
5,526✔
5597
    int64_t v = 0;
5,526✔
5598
    colDataSetInt64(p1, 0, &v);
5599
  }
5600

5601
  pBlock->info.rows = 1;
5,546✔
5602
  pOperator->status = OP_EXEC_DONE;
5,546✔
5603

5604
_end:
5,546✔
5605
  if (code != TSDB_CODE_SUCCESS) {
5,546✔
5606
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
5607
    pTaskInfo->code = code;
×
5608
    T_LONG_JMP(pTaskInfo->env, code);
×
5609
  }
5610
  (*ppRes) = pBlock;
5,546✔
5611
  return code;
5,546✔
5612
}
5613

5614
static void destroyBlockDistScanOperatorInfo(void* param) {
5,546✔
5615
  SBlockDistInfo* pDistInfo = (SBlockDistInfo*)param;
5,546✔
5616
  blockDataDestroy(pDistInfo->pResBlock);
5,546✔
5617
  if (pDistInfo->readHandle.api.tsdReader.tsdReaderClose != NULL) {
5,546✔
5618
    pDistInfo->readHandle.api.tsdReader.tsdReaderClose(pDistInfo->pHandle);
5,546✔
5619
  }
5620
  tableListDestroy(pDistInfo->pTableListInfo);
5,546✔
5621
  taosMemoryFreeClear(param);
5,546✔
5622
}
5,546✔
5623

5624
static int32_t initTableblockDistQueryCond(uint64_t uid, SQueryTableDataCond* pCond) {
7,742✔
5625
  memset(pCond, 0, sizeof(SQueryTableDataCond));
7,742✔
5626

5627
  pCond->order = TSDB_ORDER_ASC;
7,742✔
5628
  pCond->numOfCols = 1;
7,742✔
5629
  pCond->colList = taosMemoryCalloc(1, sizeof(SColumnInfo));
7,742✔
5630
  pCond->pSlotList = taosMemoryMalloc(sizeof(int32_t));
7,742✔
5631
  if (pCond->colList == NULL || pCond->pSlotList == NULL) {
7,742✔
5632
    taosMemoryFree(pCond->colList);
×
5633
    taosMemoryFree(pCond->pSlotList);
×
5634
    return terrno;
×
5635
  }
5636

5637
  pCond->colList->colId = 1;
7,742✔
5638
  pCond->colList->type = TSDB_DATA_TYPE_TIMESTAMP;
7,742✔
5639
  pCond->colList->bytes = sizeof(TSKEY);
7,742✔
5640
  pCond->colList->pk = 0;
7,742✔
5641

5642
  pCond->pSlotList[0] = 0;
7,742✔
5643

5644
  pCond->twindows = (STimeWindow){.skey = INT64_MIN, .ekey = INT64_MAX};
7,742✔
5645
  pCond->suid = uid;
7,742✔
5646
  pCond->type = TIMEWINDOW_RANGE_CONTAINED;
7,742✔
5647
  pCond->startVersion = -1;
7,742✔
5648
  pCond->endVersion = -1;
7,742✔
5649

5650
  return TSDB_CODE_SUCCESS;
7,742✔
5651
}
5652

5653
int32_t createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDistScanPhysiNode* pBlockScanNode,
5,546✔
5654
                                        STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo,
5655
                                        SOperatorInfo** pOptrInfo) {
5656
  QRY_PARAM_CHECK(pOptrInfo);
5,546✔
5657

5658
  int32_t         code = 0;
5,546✔
5659
  int32_t         lino = 0;
5,546✔
5660
  SBlockDistInfo* pInfo = taosMemoryCalloc(1, sizeof(SBlockDistInfo));
5,546✔
5661
  SOperatorInfo*  pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
5,546✔
5662
  if (pInfo == NULL || pOperator == NULL) {
5,546✔
5663
    pTaskInfo->code = code = terrno;
×
5664
    goto _error;
×
5665
  }
5666
  initOperatorCostInfo(pOperator);
5,546✔
5667

5668
  pInfo->pResBlock = createDataBlockFromDescNode(pBlockScanNode->node.pOutputDataBlockDesc);
5,546✔
5669
  QUERY_CHECK_NULL(pInfo->pResBlock, code, lino, _error, terrno);
5,546✔
5670
  code = blockDataEnsureCapacity(pInfo->pResBlock, 1);
5,546✔
5671
  QUERY_CHECK_CODE(code, lino, _error);
5,546✔
5672

5673
  {
5674
    SQueryTableDataCond cond = {0};
5,546✔
5675
    code = initTableblockDistQueryCond(pBlockScanNode->suid, &cond);
5,546✔
5676
    QUERY_CHECK_CODE(code, lino, _error);
5,546✔
5677

5678
    pInfo->pTableListInfo = pTableListInfo;
5,546✔
5679
    int32_t num = 0;
5,546✔
5680
    code = tableListGetSize(pTableListInfo, &num);
5,546✔
5681
    QUERY_CHECK_CODE(code, lino, _error);
5,546✔
5682

5683
    void* pList = tableListGetInfo(pTableListInfo, 0);
5,546✔
5684

5685
    code = readHandle->api.tsdReader.tsdReaderOpen(readHandle->vnode, &cond, pList, num, pInfo->pResBlock,
11,092✔
5686
                                                   (void**)&pInfo->pHandle, pTaskInfo->id.str, NULL);
5,546✔
5687
    cleanupQueryTableDataCond(&cond);
5,546✔
5688
    QUERY_CHECK_CODE(code, lino, _error);
5,546✔
5689
  }
5690

5691
  pInfo->readHandle = *readHandle;
5,546✔
5692
  pInfo->uid = (pBlockScanNode->suid != 0) ? pBlockScanNode->suid : pBlockScanNode->uid;
5,546✔
5693

5694
  int32_t    numOfCols = 0;
5,526✔
5695
  SExprInfo* pExprInfo = NULL;
5,546✔
5696
  code = createExprInfo(pBlockScanNode->pScanPseudoCols, NULL, &pExprInfo, &numOfCols);
5,526✔
5697
  QUERY_CHECK_CODE(code, lino, _error);
5,526✔
5698

5699
  code = initExprSupp(&pOperator->exprSupp, pExprInfo, numOfCols, &pTaskInfo->storageAPI.functionStore);
5,526✔
5700
  QUERY_CHECK_CODE(code, lino, _error);
5,546✔
5701

5702
  setOperatorInfo(pOperator, "DataBlockDistScanOperator", QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN, false,
5,546✔
5703
                  OP_NOT_OPENED, pInfo, pTaskInfo);
5704
  pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doBlockInfoScanNext, NULL, destroyBlockDistScanOperatorInfo,
4,790✔
5705
                                         optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
5706
  *pOptrInfo = pOperator;
4,810✔
5707
  return code;
5,546✔
5708

5709
_error:
×
5710
  if (pInfo) {
×
5711
    pInfo->pTableListInfo = NULL;
×
5712
    destroyBlockDistScanOperatorInfo(pInfo);
×
5713
  }
5714
  if (pOperator != NULL) {
×
5715
    pOperator->info = NULL;
×
5716
    destroyOperator(pOperator);
×
5717
  }
5718
  return code;
×
5719
}
5720

5721
static int32_t buildTableListInfo(SOperatorInfo* pOperator, STableId* id, STableListInfo** ppTableListInfo) {
2,196✔
5722
  int32_t            code = TSDB_CODE_SUCCESS;
2,196✔
5723
  int32_t            line = 0;
2,196✔
5724
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
2,196✔
5725
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
2,196✔
5726
  SSysTableScanInfo* pInfo = pOperator->info;
2,196✔
5727
  SReadHandle*       pReadHandle = &pInfo->readHandle;
2,196✔
5728
  SArray*            pList = NULL;
2,196✔
5729

5730
  STableListInfo* pTableListInfo = tableListCreate();
2,196✔
5731
  QUERY_CHECK_NULL(ppTableListInfo, code, line, _end, terrno);
2,196✔
5732

5733
  if (id->type == TSDB_SUPER_TABLE) {
2,196✔
5734
    pList = taosArrayInit(4, sizeof(uint64_t));
1,464✔
5735
    QUERY_CHECK_NULL(pList, code, line, _end, terrno);
1,464✔
5736

5737
    code = pReadHandle->api.metaFn.getChildTableList(pReadHandle->vnode, id->uid, pList);
1,464✔
5738
    QUERY_CHECK_CODE(code, line, _end);
1,464✔
5739

5740
    size_t num = taosArrayGetSize(pList);
1,464✔
5741
    for (int32_t i = 0; i < num; ++i) {
2,196✔
5742
      uint64_t* id = taosArrayGet(pList, i);
732✔
5743
      if (id == NULL) {
732✔
5744
        continue;
×
5745
      }
5746
      code = tableListAddTableInfo(pTableListInfo, *id, 0);
732✔
5747
      QUERY_CHECK_CODE(code, line, _end);
732✔
5748
    }
5749
    taosArrayDestroy(pList);
1,464✔
5750
    pList = NULL;
1,464✔
5751

5752
  } else if (id->type == TSDB_NORMAL_TABLE) {
732✔
5753
    code = tableListAddTableInfo(pTableListInfo, id->uid, 0);
732✔
5754
    QUERY_CHECK_CODE(code, line, _end);
732✔
5755
  }
5756
  *ppTableListInfo = pTableListInfo;
2,196✔
5757
  return code;
2,196✔
5758
_end:
×
5759
  taosArrayDestroy(pList);
×
5760
  tableListDestroy(pTableListInfo);
×
5761
  return code;
×
5762
}
5763
static int32_t vnodeEstimateDataSizeByUid(SOperatorInfo* pOperator, STableId* id, SDbSizeStatisInfo* pStaticInfo) {
2,196✔
5764
  int32_t             code = TSDB_CODE_SUCCESS;
2,196✔
5765
  int32_t             line = 0;
2,196✔
5766
  SExecTaskInfo*      pTaskInfo = pOperator->pTaskInfo;
2,196✔
5767
  SStorageAPI*        pAPI = &pTaskInfo->storageAPI;
2,196✔
5768
  SSysTableScanInfo*  pInfo = pOperator->info;
2,196✔
5769
  SQueryTableDataCond cond = {0};
2,196✔
5770

5771
  SReadHandle* pReadHandle = &pInfo->readHandle;
2,196✔
5772

5773
  STableListInfo* pTableListInfo = NULL;
2,196✔
5774
  code = buildTableListInfo(pOperator, id, &pTableListInfo);
2,196✔
5775
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5776

5777
  tb_uid_t tbId = id->type == TSDB_SUPER_TABLE ? id->uid : 0;
2,196✔
5778

5779
  code = initTableblockDistQueryCond(tbId, &cond);
2,196✔
5780
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5781

5782
  pInfo->pTableListInfo = pTableListInfo;
2,196✔
5783

5784
  int32_t num = 0;
2,196✔
5785
  code = tableListGetSize(pTableListInfo, &num);
2,196✔
5786
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5787

5788
  void* pList = tableListGetInfo(pTableListInfo, 0);
2,196✔
5789

5790
  code = pReadHandle->api.tsdReader.tsdReaderOpen(pReadHandle->vnode, &cond, pList, num, NULL, (void**)&pInfo->pHandle,
4,392✔
5791
                                                  pTaskInfo->id.str, NULL);
2,196✔
5792
  cleanupQueryTableDataCond(&cond);
2,196✔
5793
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5794

5795
  STableBlockDistInfo blockDistInfo = {.minRows = INT_MAX, .maxRows = INT_MIN};
2,196✔
5796
  code = doGetTableRowSize(pReadHandle, id->uid, (int32_t*)&blockDistInfo.rowSize, GET_TASKID(pTaskInfo));
2,196✔
5797
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5798

5799
  code = pAPI->tsdReader.tsdReaderGetDataBlockDistInfo(pInfo->pHandle, &blockDistInfo);
2,196✔
5800
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5801

5802
  code = pAPI->tsdReader.tsdReaderGetNumOfInMemRows(pInfo->pHandle, &blockDistInfo.numOfInmemRows);
2,196✔
5803
  QUERY_CHECK_CODE(code, line, _end);
2,196✔
5804

5805
  int64_t rawDiskSize = 0, rawCacheSize = 0;
2,196✔
5806
  rawDiskSize = (blockDistInfo.totalRows + blockDistInfo.numOfSttRows) * blockDistInfo.rowSize;
2,196✔
5807
  rawCacheSize = blockDistInfo.numOfInmemRows * blockDistInfo.rowSize;
2,196✔
5808
  pStaticInfo->rawDataSize += rawDiskSize;
2,196✔
5809
  pStaticInfo->cacheSize += rawCacheSize;
2,196✔
5810

5811
  if (pInfo->pHandle != NULL) {
2,196✔
5812
    pReadHandle->api.tsdReader.tsdReaderClose(pInfo->pHandle);
2,196✔
5813
    pInfo->pHandle = NULL;
2,196✔
5814
  }
5815

5816
  tableListDestroy(pInfo->pTableListInfo);
2,196✔
5817
  pInfo->pTableListInfo = NULL;
2,196✔
5818
  return code;
2,196✔
5819
_end:
×
5820

5821
  if (pInfo->pHandle != NULL) {
×
5822
    pReadHandle->api.tsdReader.tsdReaderClose(pInfo->pHandle);
×
5823
    pInfo->pHandle = NULL;
×
5824
  }
5825

5826
  tableListDestroy(pInfo->pTableListInfo);
×
5827
  pInfo->pTableListInfo = NULL;
×
5828
  if (code) {
×
5829
    pTaskInfo->code = code;
×
5830
    return code;
×
5831
  }
5832
  cleanupQueryTableDataCond(&cond);
×
5833
  return code;
×
5834
}
5835

5836
static int32_t vnodeEstimateRawDataSizeImpl(SOperatorInfo* pOperator, SArray* pTableList,
1,818✔
5837
                                            SDbSizeStatisInfo* pStaticInfo) {
5838
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
1,818✔
5839
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
1,818✔
5840
  SSysTableScanInfo* pInfo = pOperator->info;
1,818✔
5841

5842
  int32_t rowLen = 0;
1,818✔
5843
  int32_t code = TSDB_CODE_SUCCESS;
1,818✔
5844
  for (int i = 0; i < taosArrayGetSize(pTableList); i++) {
4,014✔
5845
    STableId* id = (STableId*)taosArrayGet(pTableList, i);
2,196✔
5846
    code = vnodeEstimateDataSizeByUid(pOperator, id, pStaticInfo);
2,196✔
5847
    if (code != TSDB_CODE_SUCCESS) {
2,196✔
5848
      return code;
×
5849
    }
5850
  }
5851
  return code;
1,818✔
5852
}
5853

5854
static int32_t vnodeEstimateRawDataSize(SOperatorInfo* pOperator, SDbSizeStatisInfo* pStaticInfo) {
6,438✔
5855
  int32_t code = TSDB_CODE_SUCCESS;
6,438✔
5856

5857
  int32_t line = 0;
6,438✔
5858

5859
  SExecTaskInfo*     pTaskInfo = pOperator->pTaskInfo;
6,438✔
5860
  SStorageAPI*       pAPI = &pTaskInfo->storageAPI;
6,438✔
5861
  SSysTableScanInfo* pInfo = pOperator->info;
6,438✔
5862
  int32_t            numOfRows = 0;
6,438✔
5863
  int32_t            ret = 0;
6,438✔
5864
  if (pStaticInfo->estimateRawData == 0) {
6,438✔
5865
    pStaticInfo->rawDataSize = 0;
4,620✔
5866
    return code;
4,620✔
5867
  }
5868

5869
  if (pStaticInfo->estimateRawData == 0) {
1,818✔
5870
    pStaticInfo->rawDataSize = 0;
×
5871
    return code;
×
5872
  }
5873

5874
  if (pInfo->pCur == NULL) {
1,818✔
5875
    pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
×
5876
    if (pInfo->pCur == NULL) {
×
5877
      TAOS_CHECK_GOTO(terrno, &line, _exit);
×
5878
    }
5879
  }
5880

5881
  SArray* pIdList = taosArrayInit(16, sizeof(STableId));
1,818✔
5882
  if (pIdList == NULL) {
1,818✔
5883
    TAOS_CHECK_GOTO(terrno, &line, _exit);
×
5884
  }
5885

5886
  while (((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_CHILD_TABLE)) == 0)) {
4,014✔
5887
    if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
2,196✔
5888
      STableId id = {.type = TSDB_SUPER_TABLE, .uid = pInfo->pCur->mr.me.uid};
1,464✔
5889
      if (taosArrayPush(pIdList, &id) == NULL) {
1,464✔
5890
        TAOS_CHECK_GOTO(terrno, &line, _exit);
×
5891
      }
5892
    } else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
732✔
5893
      continue;
×
5894
    } else if (pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE) {
732✔
5895
      STableId id = {.type = TSDB_NORMAL_TABLE, .uid = pInfo->pCur->mr.me.uid};
732✔
5896
      if (taosArrayPush(pIdList, &id) == NULL) {
732✔
5897
        TAOS_CHECK_GOTO(terrno, &line, _exit);
×
5898
      }
5899
    }
5900
  }
5901
  if (pInfo->pCur) {
1,818✔
5902
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
1,818✔
5903
    pInfo->pCur = NULL;
1,818✔
5904
  }
5905

5906
  code = vnodeEstimateRawDataSizeImpl(pOperator, pIdList, pStaticInfo);
1,818✔
5907

5908
_exit:
1,818✔
5909
  if (pInfo->pCur) {
1,818✔
5910
    pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
×
5911
    pInfo->pCur = NULL;
×
5912
  }
5913
  if (code != TSDB_CODE_SUCCESS) {
1,818✔
5914
    qError("%s failed at line %d since %s", __func__, line, tstrerror(code));
×
5915
    pTaskInfo->code = code;
×
5916
  }
5917

5918
  taosArrayDestroy(pIdList);
1,818✔
5919
  return code;
1,818✔
5920
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc