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

taosdata / TDengine / #5131

29 Oct 2026 05:29AM UTC coverage: 68.39% (+4.0%) from 64.429%
#5131

push

travis-ci

kailixu
fix: stub dnode symbols that vmReplicaCfgTest does not execute

The coverage image linker scans mgmt_dnode before vnode, and its CMake cannot rescan that static cycle.

345010 of 504474 relevant lines covered (68.39%)

69639614.09 hits per line

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

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

18
#include "meta.h"
19
#include "tsdb.h"
20
#include "tutil.h"
21
#include "vnd.h"
22

23
#define VNODE_GET_LOAD_RESET_VALS(pVar, oVal, vType, tags)                                                    \
24
  do {                                                                                                        \
25
    int##vType##_t newVal = atomic_sub_fetch_##vType(&(pVar), (oVal));                                        \
26
    if (newVal < 0) {                                                                                         \
27
      vWarn("vgId:%d, %s, abnormal val:%" PRIi64 ", old val:%" PRIi64, TD_VID(pVnode), tags, newVal, (oVal)); \
28
    }                                                                                                         \
29
  } while (0)
30

31
int vnodeQueryOpen(SVnode *pVnode) {
2,074,496 ✔
32
  return qWorkerInit(NODE_TYPE_VNODE, TD_VID(pVnode), (void **)&pVnode->pQuery, &pVnode->msgCb);
2,074,496 ✔
33
}
34

35
void vnodeQueryPreClose(SVnode *pVnode) { qWorkerStopAllTasks((void *)pVnode->pQuery); }
2,074,621 ✔
36

37
void vnodeQueryClose(SVnode *pVnode) { qWorkerDestroy((void **)&pVnode->pQuery); }
2,093,598 ✔
38

39
int32_t fillTableColCmpr(SMetaReader *reader, SSchemaExt *pExt, int32_t numOfCol) {
67,772,580 ✔
40
  int8_t tblType = reader->me.type;
67,772,580 ✔
41
  if (withColCompress(tblType)) {
67,772,580 ✔
42
    SColCmprWrapper *p = &(reader->me.colCmpr);
52,424,912 ✔
43
    if (numOfCol != p->nCols) {
52,424,912 ✔
44
      vError("fillTableColCmpr table type:%d, col num:%d, col cmpr num:%d mismatch", tblType, numOfCol, p->nCols);
×
45
      return TSDB_CODE_APP_ERROR;
×
46
    }
47
    for (int i = 0; i < p->nCols; i++) {
539,613,286 ✔
48
      SColCmpr *pCmpr = &p->pColCmpr[i];
487,188,374 ✔
49
      pExt[i].colId = pCmpr->id;
487,188,374 ✔
50
      pExt[i].compress = pCmpr->alg;
487,188,374 ✔
51
    }
52
  }
53
  return 0;
67,743,756 ✔
54
}
55

56
void vnodeDebugTableMeta(STableMetaRsp *pMeta) {
30,432,367 ✔
57
  if (!(qDebugFlag & DEBUG_DEBUG)) {
30,432,367 ✔
58
    return;
21,107,444 ✔
59
  }
60

61
  qDebug("tbName:%s", pMeta->tbName);
9,324,923 ✔
62
  qDebug("stbName:%s", pMeta->stbName);
9,325,194 ✔
63
  qDebug("dbFName:%s", pMeta->dbFName);
9,325,197 ✔
64
  qDebug("dbId:%" PRId64, pMeta->dbId);
9,325,197 ✔
65
  qDebug("numOfTags:%d", pMeta->numOfTags);
9,325,197 ✔
66
  qDebug("numOfColumns:%d", pMeta->numOfColumns);
9,325,197 ✔
67
  qDebug("precision:%d", pMeta->precision);
9,325,197 ✔
68
  qDebug("tableType:%d", pMeta->tableType);
9,325,197 ✔
69
  qDebug("sversion:%d", pMeta->sversion);
9,325,197 ✔
70
  qDebug("tversion:%d", pMeta->tversion);
9,325,197 ✔
71
  qDebug("suid:%" PRIu64, pMeta->suid);
9,325,197 ✔
72
  qDebug("tuid:%" PRIu64, pMeta->tuid);
9,325,197 ✔
73
  qDebug("vgId:%d", pMeta->vgId);
9,325,197 ✔
74
  qDebug("sysInfo:%d", pMeta->sysInfo);
9,325,197 ✔
75
  if (pMeta->pSchemas) {
9,325,197 ✔
76
    for (int32_t i = 0; i < (pMeta->numOfColumns + pMeta->numOfTags); ++i) {
116,623,403 ✔
77
      SSchema *pSchema = pMeta->pSchemas + i;
107,297,959 ✔
78
      qDebug("%d col/tag: type:%d, flags:%d, colId:%d, bytes:%d, name:%s", i, pSchema->type, pSchema->flags,
107,297,959 ✔
79
             pSchema->colId, pSchema->bytes, pSchema->name);
80
    }
81
  }
82
}
83

84
int32_t fillTableColRef(SMetaReader *reader, SColRef *pRef, int32_t numOfCol) {
15,299,624 ✔
85
  int32_t code = TSDB_CODE_SUCCESS;
15,299,624 ✔
86
  int32_t line = 0;
15,299,624 ✔
87
  int8_t tblType = reader->me.type;
15,299,624 ✔
88
  if (hasColRef(tblType)) {
15,299,624 ✔
89
    SColRefWrapper *p = &(reader->me.colRef);
15,299,624 ✔
90
    if (numOfCol != p->nCols) {
15,299,624 ✔
91
      vError("fillTableColRef table type:%d, col num:%d, col cmpr num:%d mismatch", tblType, numOfCol, p->nCols);
×
92
      code = TSDB_CODE_APP_ERROR;
×
93
      goto _return;
×
94
    }
95
    for (int i = 0; i < p->nCols; i++) {
252,131,954 ✔
96
      SColRef *pColRef = &p->pColRef[i];
236,832,330 ✔
97
      pRef[i].hasRef = pColRef->hasRef;
236,832,330 ✔
98
      pRef[i].id = pColRef->id;
236,832,330 ✔
99
      if (pRef[i].hasRef) {
236,832,330 ✔
100
        pRef[i].refType = pColRef->refType;
194,141,912 ✔
101
        tstrncpy(pRef[i].refSourceName, pColRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
194,141,912 ✔
102
        tstrncpy(pRef[i].refSchemaName, pColRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
194,141,912 ✔
103
        tstrncpy(pRef[i].refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
194,141,912 ✔
104
        tstrncpy(pRef[i].refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
194,141,912 ✔
105
        tstrncpy(pRef[i].refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
194,141,912 ✔
106
        if (pColRef->tagCondLen > 0 && pColRef->tagCondJson) {
194,141,912 ✔
107
          pRef[i].tagCondLen = pColRef->tagCondLen;
120,651 ✔
108
          pRef[i].tagCondJson = taosStrdup(pColRef->tagCondJson);
120,651 ✔
109
          QUERY_CHECK_NULL(pRef[i].tagCondJson, code, line, _return, terrno);
120,651 ✔
110
        } else {
111
          pRef[i].tagCondLen = 0;
194,021,261 ✔
112
          pRef[i].tagCondJson = NULL;
194,021,261 ✔
113
        }
114
        if (pColRef->filterCondLen > 0 && pColRef->filterCondJson) {
194,141,912 ✔
115
          pRef[i].filterCondLen = pColRef->filterCondLen;
×
116
          pRef[i].filterCondJson = taosStrdup(pColRef->filterCondJson);
×
117
          QUERY_CHECK_NULL(pRef[i].filterCondJson, code, line, _return, terrno);
×
118
        } else {
119
          pRef[i].filterCondLen = 0;
194,141,912 ✔
120
          pRef[i].filterCondJson = NULL;
194,141,912 ✔
121
        }
122
      }
123
    }
124
  }
125

126
_return:
15,299,624 ✔
127
  if (TSDB_CODE_SUCCESS != code) {
15,299,624 ✔
128
    qError("%s failed since %s", __func__, tstrerror(code));
×
129
  }
130
  return code;
15,299,803 ✔
131
}
132

133
int32_t fillTableTagRef(SMetaReader *reader, SColRef *pRef, int32_t numOfTagRefs) {
688,006 ✔
134
  int8_t tblType = reader->me.type;
688,006 ✔
135
  if (hasTagRef(tblType)) {
688,006 ✔
136
    SColRefWrapper *p = &(reader->me.colRef);
688,006 ✔
137
    if (numOfTagRefs != p->nTagRefs) {
688,006 ✔
138
      vError("fillTableTagRef table type:%d, tag ref num:%d, expected:%d mismatch", tblType, numOfTagRefs, p->nTagRefs);
×
139
      return TSDB_CODE_APP_ERROR;
×
140
    }
141
    for (int i = 0; i < p->nTagRefs; i++) {
2,258,282 ✔
142
      SColRef *pTagRef = &p->pTagRef[i];
1,570,276 ✔
143
      pRef[i].hasRef = pTagRef->hasRef;
1,570,276 ✔
144
      pRef[i].id = pTagRef->id;
1,570,276 ✔
145
      if (pRef[i].hasRef) {
1,570,276 ✔
146
        tstrncpy(pRef[i].refDbName, pTagRef->refDbName, TSDB_DB_NAME_LEN);
1,230,652 ✔
147
        tstrncpy(pRef[i].refTableName, pTagRef->refTableName, TSDB_TABLE_NAME_LEN);
1,230,652 ✔
148
        tstrncpy(pRef[i].refColName, pTagRef->refColName, TSDB_COL_NAME_LEN);
1,230,652 ✔
149
      }
150
    }
151
  }
152
  return 0;
688,006 ✔
153
}
154

155
int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
40,896,398 ✔
156
  STableInfoReq  infoReq = {0};
40,896,398 ✔
157
  STableMetaRsp  metaRsp = {0};
40,896,519 ✔
158
  SMetaReader    mer1 = {0};
40,896,096 ✔
159
  SMetaReader    mer2 = {0};
40,896,044 ✔
160
  char           tableFName[TSDB_TABLE_FNAME_LEN];
40,895,521 ✔
161
  bool           reqTbUid = false;
40,895,959 ✔
162
  SRpcMsg        rpcMsg = {0};
40,895,959 ✔
163
  int32_t        code = 0;
40,896,148 ✔
164
  int32_t        rspLen = 0;
40,896,148 ✔
165
  void          *pRsp = NULL;
40,896,148 ✔
166
  SSchemaWrapper schema = {0};
40,896,148 ✔
167
  SSchemaWrapper schemaTag = {0};
40,896,326 ✔
168
  uint8_t        autoCreateCtb = 0;
40,896,019 ✔
169
  SSchema       *pMergedCols = NULL;  // vchild: vstb row schema + own (extension) columns
40,896,019 ✔
170
  SColRef       *pMergedRefs = NULL;  // vchild: persisted colRef + own column refs
40,895,641 ✔
171
  int32_t        nMergedCols = 0;
40,895,062 ✔
172
  SSchema       *pMergedTags = NULL;  // vchild: vstb tag schema + own (extension) tags
40,895,251 ✔
173
  int32_t        nMergedTags = 0;
40,895,176 ✔
174

175
  // decode req
176
  if (tDeserializeSTableInfoReq(pMsg->pCont, pMsg->contLen, &infoReq) != 0) {
40,895,176 ✔
177
    code = terrno;
×
178
    goto _exit4;
×
179
  }
180
  autoCreateCtb = infoReq.autoCreateCtb;
40,896,376 ✔
181

182
  if (infoReq.option == REQ_OPT_TBUID) reqTbUid = true;
40,896,376 ✔
183
  metaRsp.dbId = pVnode->config.dbId;
40,896,376 ✔
184
  tstrncpy(metaRsp.tbName, infoReq.tbName, TSDB_TABLE_NAME_LEN);
40,896,376 ✔
185
  (void)memcpy(metaRsp.dbFName, infoReq.dbFName, sizeof(metaRsp.dbFName));
40,896,376 ✔
186

187
  if (!reqTbUid) {
40,896,376 ✔
188
    (void)snprintf(tableFName, TSDB_TABLE_FNAME_LEN, "%s.%s", infoReq.dbFName, infoReq.tbName);
40,812,670 ✔
189
    if (pVnode->mounted) tTrimMountPrefix(tableFName);
40,812,670 ✔
190
    code = vnodeValidateTableHash(pVnode, tableFName);
40,812,670 ✔
191
    if (code) {
40,813,165 ✔
192
      goto _exit4;
×
193
    }
194
  }
195

196
  // query meta
197
  metaReaderDoInit(&mer1, pVnode->pMeta, META_READER_LOCK, infoReq.txnId);
40,896,871 ✔
198
  if (reqTbUid) {
40,896,340 ✔
199
    SET_ERRNO(0);
82,914 ✔
200
    uint64_t tbUid = taosStr2UInt64(infoReq.tbName, NULL, 10);
82,914 ✔
201
    if (ERRNO == ERANGE || tbUid == 0) {
82,914 ✔
202
      code = TSDB_CODE_TDB_TABLE_NOT_EXIST;
1,266 ✔
203
      goto _exit3;
1,266 ✔
204
    }
205
    SMetaReader mr3 = {0};
81,648 ✔
206
    metaReaderDoInit(&mr3, ((SVnode *)pVnode)->pMeta, META_READER_NOLOCK, infoReq.txnId);
81,648 ✔
207
    if ((code = metaReaderGetTableEntryByUid(&mr3, tbUid)) < 0) {
81,648 ✔
208
      metaReaderClear(&mr3);
22,435 ✔
209
      TAOS_CHECK_GOTO(code, NULL, _exit3);
22,435 ✔
210
    }
211
    tstrncpy(metaRsp.tbName, mr3.me.name, TSDB_TABLE_NAME_LEN);
59,213 ✔
212
    metaReaderClear(&mr3);
59,213 ✔
213
    TAOS_CHECK_GOTO(metaGetTableEntryByName(&mer1, metaRsp.tbName), NULL, _exit3);
59,213 ✔
214
  } else if (metaGetTableEntryByName(&mer1, infoReq.tbName) < 0) {
40,813,426 ✔
215
    code = terrno;
10,439,835 ✔
216
    goto _exit3;
10,439,835 ✔
217
  }
218

219
  metaRsp.tableType = mer1.me.type;
30,432,315 ✔
220
  metaRsp.vgId = TD_VID(pVnode);
30,432,315 ✔
221
  metaRsp.tuid = mer1.me.uid;
30,432,315 ✔
222
  metaRsp.isAudit = pVnode->config.isAudit ? 1 : 0;
30,432,315 ✔
223

224
  switch (mer1.me.type) {
30,432,315 ✔
225
    case TSDB_SUPER_TABLE: {
1,576,027 ✔
226
      tstrncpy(metaRsp.stbName, mer1.me.name, sizeof(metaRsp.stbName));
1,576,027 ✔
227
      schema = mer1.me.stbEntry.schemaRow;
1,576,027 ✔
228
      schemaTag = mer1.me.stbEntry.schemaTag;
1,576,027 ✔
229
      metaRsp.suid = mer1.me.uid;
1,576,027 ✔
230
      metaRsp.virtualStb = TABLE_IS_VIRTUAL(mer1.me.flags);
1,576,027 ✔
231
      metaRsp.ownerId = mer1.me.stbEntry.ownerId;
1,576,027 ✔
232
      metaRsp.secLvl = mer1.me.stbEntry.securityLevel;
1,576,027 ✔
233
      break;
1,576,027 ✔
234
    }
235
    case TSDB_CHILD_TABLE:
7,057,055 ✔
236
    case TSDB_VIRTUAL_CHILD_TABLE:{
237
      metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK, infoReq.txnId);
7,057,055 ✔
238
      if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit2;
7,057,213 ✔
239

240
      tstrncpy(metaRsp.stbName, mer2.me.name, sizeof(metaRsp.stbName));
7,057,082 ✔
241
      metaRsp.suid = mer2.me.uid;
7,057,082 ✔
242
      metaRsp.ownerId = mer2.me.stbEntry.ownerId;  // child table inherits ownerId from stb
7,057,082 ✔
243
      metaRsp.secLvl = mer2.me.stbEntry.securityLevel;  // child table inherits secLvl from stb
7,057,082 ✔
244
      schema = mer2.me.stbEntry.schemaRow;
7,057,082 ✔
245
      schemaTag = mer2.me.stbEntry.schemaTag;
7,057,082 ✔
246
      break;
7,057,082 ✔
247
    }
248
    case TSDB_NORMAL_TABLE:
6,499,633 ✔
249
      metaRsp.secLvl = pVnode->config.securityLevel;  // normal table inherits secLvl from vnode config
6,499,633 ✔
250
    case TSDB_VIRTUAL_NORMAL_TABLE: {
21,799,233 ✔
251
      schema = mer1.me.ntbEntry.schemaRow;
21,799,233 ✔
252
      schemaTag = mer1.me.ntbEntry.schemaTag;  // normal/virtual-normal tables may own tags
21,799,233 ✔
253
      metaRsp.ownerId = mer1.me.ntbEntry.ownerId;
21,799,233 ✔
254
      break;
21,799,233 ✔
255
    }
256
    default: {
×
257
      vError("vnodeGetTableMeta get invalid table type:%d", mer1.me.type);
×
258
      goto _exit3;
×
259
    }
260
  }
261

262
  // For a virtual child table, build the merged column view first: vstb row schema followed
263
  // by the vchild's own (extension) columns, persisted colRef followed by own column refs.
264
  nMergedCols = schema.nCols;
30,432,342 ✔
265
  if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
30,432,342 ✔
266
    code = metaBuildMergedColView(&mer1.me, &schema, &pMergedCols, &pMergedRefs, &nMergedCols);
1,566,137 ✔
267
    if (code) {
1,566,137 ✔
268
      vError("vgId:%d, vnodeGetTableMeta build merged col view for %s failed since %s", TD_VID(pVnode),
×
269
             infoReq.tbName, tstrerror(code));
270
      goto _exit;
×
271
    }
272
    // merged tag view: vstb tag schema followed by the vchild's own (extension) tags
273
    nMergedTags = schemaTag.nCols;
1,566,137 ✔
274
    code = metaBuildMergedTagView(&mer1.me, &schemaTag, &pMergedTags, &nMergedTags);
1,566,137 ✔
275
    if (code) {
1,566,137 ✔
276
      vError("vgId:%d, vnodeGetTableMeta build merged tag view for %s failed since %s", TD_VID(pVnode),
×
277
             infoReq.tbName, tstrerror(code));
278
      goto _exit;
×
279
    }
280
  }
281

282
  metaRsp.numOfTags = (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? nMergedTags : schemaTag.nCols;
30,432,566 ✔
283
  metaRsp.numOfColumns = nMergedCols;
30,432,566 ✔
284
  metaRsp.precision = pVnode->config.tsdbCfg.precision;
30,432,566 ✔
285
  metaRsp.sversion = schema.version;
30,432,566 ✔
286
  metaRsp.tversion = schemaTag.version;
30,432,566 ✔
287
  metaRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (metaRsp.numOfColumns + metaRsp.numOfTags));
30,432,566 ✔
288
  metaRsp.pSchemaExt = (SSchemaExt *)taosMemoryCalloc(metaRsp.numOfColumns, sizeof(SSchemaExt));
30,430,844 ✔
289
  if (NULL == metaRsp.pSchemas || NULL == metaRsp.pSchemaExt) {
30,430,480 ✔
290
    code = terrno;
×
291
    goto _exit;
×
292
  }
293
  if (pMergedCols) {
30,430,670 ✔
294
    (void)memcpy(metaRsp.pSchemas, pMergedCols, sizeof(SSchema) * nMergedCols);
1,566,137 ✔
295
  } else {
296
    (void)memcpy(metaRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols);
28,864,533 ✔
297
  }
298
  if (pMergedTags) {
30,430,670 ✔
299
    (void)memcpy(metaRsp.pSchemas + metaRsp.numOfColumns, pMergedTags, sizeof(SSchema) * nMergedTags);
1,566,137 ✔
300
  } else if (schemaTag.nCols) {
28,864,533 ✔
301
    (void)memcpy(metaRsp.pSchemas + metaRsp.numOfColumns, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
7,098,410 ✔
302
  }
303
  if (metaRsp.pSchemaExt) {
30,430,670 ✔
304
    SMetaReader *pReader =
30,433,099 ✔
305
        (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? &mer2 : &mer1;
30,431,625 ✔
306
    // col compress/ext schema of the vstb part only; own columns keep zeroed ext schema
307
    code = fillTableColCmpr(pReader, metaRsp.pSchemaExt, schema.nCols);
30,431,625 ✔
308
    if (code < 0) {
30,431,929 ✔
309
      goto _exit;
×
310
    }
311
    for (int32_t i = 0; i < metaRsp.numOfColumns; i++) {
457,507,333 ✔
312
      metaRsp.pSchemaExt[i].colId = metaRsp.pSchemas[i].colId;
427,075,404 ✔
313
      if (i < schema.nCols) {
427,075,404 ✔
314
        if (pReader->me.pExtSchemas) {
427,049,994 ✔
315
          metaRsp.pSchemaExt[i].typeMod = pReader->me.pExtSchemas[i].typeMod;
7,285,482 ✔
316
        }
317
      } else if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE && mer1.me.own.pOwnColExtSchemas != NULL &&
25,410 ✔
318
                 mer1.me.own.nOwnCols == metaRsp.numOfColumns - schema.nCols) {
840 ✔
319
        // every producer path allocates the own ext area with nOwnCols entries, so a non-NULL
320
        // array covers the whole own range; the count check keeps that local instead of assumed
321
        metaRsp.pSchemaExt[i].typeMod = mer1.me.own.pOwnColExtSchemas[i - schema.nCols].typeMod;
840 ✔
322
      }
323
    }
324
  } else {
325
    code = TSDB_CODE_OUT_OF_MEMORY;
20 ✔
326
    goto _exit;
20 ✔
327
  }
328
  if (hasColRef(mer1.me.type)) {
30,431,929 ✔
329
    metaRsp.rversion = mer1.me.colRef.version;
16,865,940 ✔
330
    if (pMergedRefs) {
16,865,940 ✔
331
      // merged view already validated (persisted colRef aligned with the vstb schema) and
332
      // deep-copied by metaBuildMergedColView; transfer ownership to the response
333
      metaRsp.pColRefs = pMergedRefs;
1,566,137 ✔
334
      pMergedRefs = NULL;
1,566,137 ✔
335
    } else {
336
      metaRsp.pColRefs = (SColRef*)taosMemoryCalloc(metaRsp.numOfColumns, sizeof(SColRef));
15,299,803 ✔
337
      if (metaRsp.pColRefs) {
15,299,624 ✔
338
        code = fillTableColRef(&mer1, metaRsp.pColRefs, metaRsp.numOfColumns);
15,299,624 ✔
339
        if (code < 0) {
15,299,803 ✔
340
          goto _exit;
×
341
        }
342
      }
343
    }
344
    metaRsp.numOfColRefs = metaRsp.numOfColumns;
16,865,940 ✔
345

346
    // Fill tag references
347
    if (mer1.me.colRef.nTagRefs > 0) {
16,865,940 ✔
348
      metaRsp.pTagRefs = (SColRef*)taosMemoryCalloc(mer1.me.colRef.nTagRefs, sizeof(SColRef));
688,006 ✔
349
      if (metaRsp.pTagRefs) {
688,006 ✔
350
        code = fillTableTagRef(&mer1, metaRsp.pTagRefs, mer1.me.colRef.nTagRefs);
688,006 ✔
351
        if (code < 0) {
688,006 ✔
352
          taosMemoryFreeClear(metaRsp.pTagRefs);
×
353
          goto _exit;
×
354
        }
355
      } else {
356
        code = terrno;
×
357
        goto _exit;
×
358
      }
359
      metaRsp.numOfTagRefs = mer1.me.colRef.nTagRefs;
688,006 ✔
360
    } else {
361
      metaRsp.pTagRefs = NULL;
16,177,934 ✔
362
      metaRsp.numOfTagRefs = 0;
16,177,934 ✔
363
    }
364
  } else {
365
    metaRsp.pColRefs = NULL;
13,567,066 ✔
366
    metaRsp.numOfColRefs = 0;
13,567,066 ✔
367
    metaRsp.pTagRefs = NULL;
13,567,066 ✔
368
    metaRsp.numOfTagRefs = 0;
13,567,066 ✔
369
  }
370

371
  // Fill series
372
  if (mer1.me.series.nSeries > 0) {
30,433,006 ✔
373
    metaRsp.numOfSeries = mer1.me.series.nSeries;
24,041 ✔
374
    metaRsp.pSeries = taosMemoryCalloc(mer1.me.series.nSeries, sizeof(SSeriesEntry));
24,041 ✔
375
    if (metaRsp.pSeries) {
24,041 ✔
376
      for (int32_t i = 0; i < mer1.me.series.nSeries; i++) {
131,457 ✔
377
        SSeriesEntry *src = &mer1.me.series.pSeries[i];
107,416 ✔
378
        SSeriesEntry *dst = &metaRsp.pSeries[i];
107,416 ✔
379
        tstrncpy(dst->alias, src->alias, TSDB_COL_NAME_LEN);
107,416 ✔
380
        tstrncpy(dst->sourceName, src->sourceName, TSDB_EXT_SOURCE_NAME_LEN);
107,416 ✔
381
        tstrncpy(dst->dbName, src->dbName, TSDB_DB_NAME_LEN);
107,416 ✔
382
        tstrncpy(dst->measurementName, src->measurementName, TSDB_TABLE_NAME_LEN);
107,416 ✔
383
        dst->tagCondLen = src->tagCondLen;
107,416 ✔
384
        dst->tagCondJson = src->tagCondJson ? taosStrdup(src->tagCondJson) : NULL;
107,416 ✔
385
      }
386
    } else {
387
      code = terrno;
×
388
      goto _exit;
×
389
    }
390
  } else {
391
    metaRsp.numOfSeries = 0;
30,408,965 ✔
392
    metaRsp.pSeries = NULL;
30,408,965 ✔
393
  }
394

395
  vnodeDebugTableMeta(&metaRsp);
30,433,006 ✔
396

397
  // encode and send response
398
  rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
30,432,819 ✔
399
  if (rspLen < 0) {
30,432,239 ✔
400
    code = terrno;
×
401
    goto _exit;
×
402
  }
403

404
  if (direct) {
30,432,239 ✔
405
    pRsp = rpcMallocCont(rspLen);
21,694,081 ✔
406
  } else {
407
    pRsp = taosMemoryCalloc(1, rspLen);
8,738,158 ✔
408
  }
409

410
  if (pRsp == NULL) {
30,430,062 ✔
411
    code = terrno;
×
412
    goto _exit;
×
413
  }
414

415
  rspLen = tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
30,430,062 ✔
416
  if (rspLen < 0) {
30,432,123 ✔
417
    code = terrno;
×
418
    goto _exit;
×
419
  }
420

421
_exit:
30,431,168 ✔
422
  taosMemoryFreeClear(pMergedCols);
30,432,624 ✔
423
  taosMemoryFreeClear(pMergedTags);
30,432,624 ✔
424
  if (pMergedRefs) {
30,432,624 ✔
425
    tFreeSColRefArray(pMergedRefs, nMergedCols);
×
426
    taosMemoryFreeClear(pMergedRefs);
×
427
  }
428
  tFreeSTableMetaRsp(&metaRsp);
30,432,624 ✔
429
_exit2:
30,432,283 ✔
430
  metaReaderClear(&mer2);
30,432,484 ✔
431
_exit3:
40,896,000 ✔
432
  metaReaderClear(&mer1);
40,895,729 ✔
433
_exit4:
40,895,050 ✔
434
  rpcMsg.info = pMsg->info;
40,896,100 ✔
435
  rpcMsg.pCont = pRsp;
40,896,100 ✔
436
  rpcMsg.contLen = rspLen;
40,896,100 ✔
437
  rpcMsg.code = code;
40,896,100 ✔
438
  rpcMsg.msgType = direct ? pMsg->msgType + 1 : pMsg->msgType;
40,896,100 ✔
439

440
  if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && autoCreateCtb == 1) {
40,896,100 ✔
441
    code = TSDB_CODE_SUCCESS;
7,680,170 ✔
442
  }
443

444
  if (code) {
40,896,072 ✔
445
    qError("vgId:%d, get table %s meta with %" PRIu8 " failed cause of %s", pVnode->config.vgId, infoReq.tbName,
2,783,275 ✔
446
           infoReq.option, tstrerror(code));
447
  }
448

449
  if (direct) {
40,896,166 ✔
450
    tmsgSendRsp(&rpcMsg);
21,978,123 ✔
451
  } else {
452
    *pMsg = rpcMsg;
18,918,043 ✔
453
  }
454

455
  return code;
40,896,166 ✔
456
}
457

458
int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
37,340,283 ✔
459
  STableCfgReq   cfgReq = {0};
37,340,283 ✔
460
  STableCfgRsp   cfgRsp = {0};
37,340,283 ✔
461
  SMetaReader    mer1 = {0};
37,340,283 ✔
462
  SMetaReader    mer2 = {0};
37,340,283 ✔
463
  char           tableFName[TSDB_TABLE_FNAME_LEN];
37,340,283 ✔
464
  SRpcMsg        rpcMsg = {0};
37,340,283 ✔
465
  int32_t        code = 0;
37,340,283 ✔
466
  int32_t        rspLen = 0;
37,340,283 ✔
467
  void          *pRsp = NULL;
37,340,283 ✔
468
  SSchemaWrapper schema = {0};
37,340,283 ✔
469
  SSchemaWrapper schemaTag = {0};
37,340,283 ✔
470
  SSchema       *pMergedCols = NULL;  // vchild: vstb row schema + own (extension) columns
37,340,283 ✔
471
  SColRef       *pMergedRefs = NULL;  // vchild: persisted colRef + own column refs
37,340,283 ✔
472
  int32_t        nMergedCols = 0;
37,340,283 ✔
473
  SSchema       *pMergedTags = NULL;  // vchild: vstb tag schema + own (extension) tags
37,340,283 ✔
474
  int32_t        nMergedTags = 0;
37,340,283 ✔
475

476
  // decode req
477
  if (tDeserializeSTableCfgReq(pMsg->pCont, pMsg->contLen, &cfgReq) != 0) {
37,340,283 ✔
478
    code = terrno;
×
479
    goto _exit;
×
480
  }
481

482
  tstrncpy(cfgRsp.tbName, cfgReq.tbName, TSDB_TABLE_NAME_LEN);
37,340,283 ✔
483
  (void)memcpy(cfgRsp.dbFName, cfgReq.dbFName, sizeof(cfgRsp.dbFName));
37,340,283 ✔
484

485
  (void)snprintf(tableFName, TSDB_TABLE_FNAME_LEN, "%s.%s", cfgReq.dbFName, cfgReq.tbName);
37,340,283 ✔
486
  if (pVnode->mounted) tTrimMountPrefix(tableFName);
37,340,283 ✔
487
  code = vnodeValidateTableHash(pVnode, tableFName);
37,340,283 ✔
488
  if (code) {
37,340,283 ✔
489
    goto _exit;
×
490
  }
491

492
  // query meta
493
  metaReaderDoInit(&mer1, pVnode->pMeta, META_READER_LOCK, cfgReq.txnId);
37,340,283 ✔
494

495
  if (metaGetTableEntryByName(&mer1, cfgReq.tbName) < 0) {
37,340,283 ✔
496
    code = terrno;
522 ✔
497
    goto _exit;
522 ✔
498
  }
499

500
  cfgRsp.tableType = mer1.me.type;
37,339,761 ✔
501
  cfgRsp.isAudit = pVnode->config.isAudit ? 1 : 0;
37,339,761 ✔
502
  cfgRsp.secureDelete = pVnode->config.secureDelete;
37,339,761 ✔
503

504
  if (mer1.me.type == TSDB_SUPER_TABLE) {
37,339,761 ✔
505
    code = TSDB_CODE_VND_HASH_MISMATCH;
×
506
    goto _exit;
×
507
  } else if (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
37,312,859 ✔
508
    metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK, cfgReq.txnId);
37,285,700 ✔
509
    if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit;
37,285,700 ✔
510

511
    tstrncpy(cfgRsp.stbName, mer2.me.name, TSDB_TABLE_NAME_LEN);
37,285,700 ✔
512
    schema = mer2.me.stbEntry.schemaRow;
37,285,700 ✔
513
    schemaTag = mer2.me.stbEntry.schemaTag;
37,285,700 ✔
514
    cfgRsp.ownerId = mer2.me.stbEntry.ownerId;        // child table inherits ownerId from stb
37,285,700 ✔
515
    cfgRsp.securityLevel = mer2.me.stbEntry.securityLevel;  // child table inherits secLvl from stb
37,285,700 ✔
516
    cfgRsp.ttl = mer1.me.ctbEntry.ttlDays;
37,285,700 ✔
517
    cfgRsp.commentLen = mer1.me.ctbEntry.commentLen;
37,285,700 ✔
518
    if (mer1.me.ctbEntry.commentLen > 0) {
37,285,700 ✔
519
      cfgRsp.pComment = taosStrdup(mer1.me.ctbEntry.comment);
×
520
      if (NULL == cfgRsp.pComment) {
×
521
        code = terrno;
×
522
        goto _exit;
×
523
      }
524
    }
525
    STag *pTag = (STag *)mer1.me.ctbEntry.pTags;
37,285,700 ✔
526
    cfgRsp.tagsLen = pTag->len;
37,285,700 ✔
527
    cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen);
37,285,700 ✔
528
    if (NULL == cfgRsp.pTags) {
37,285,700 ✔
529
      code = terrno;
×
530
      goto _exit;
×
531
    }
532
    (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
37,285,700 ✔
533
  } else if (mer1.me.type == TSDB_NORMAL_TABLE || mer1.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
54,061 ✔
534
    schema = mer1.me.ntbEntry.schemaRow;
54,061 ✔
535
    schemaTag = mer1.me.ntbEntry.schemaTag;  // normal/virtual-normal tables may own tags
54,061 ✔
536
    cfgRsp.ttl = mer1.me.ntbEntry.ttlDays;
54,061 ✔
537
    cfgRsp.ownerId = mer1.me.ntbEntry.ownerId;
54,061 ✔
538
    cfgRsp.securityLevel = mer1.me.type == TSDB_NORMAL_TABLE ? pVnode->config.securityLevel : 0;
54,061 ✔
539
    cfgRsp.commentLen = mer1.me.ntbEntry.commentLen;
54,061 ✔
540
    if (mer1.me.ntbEntry.commentLen > 0) {
54,061 ✔
541
      cfgRsp.pComment = taosStrdup(mer1.me.ntbEntry.comment);
×
542
      if (NULL == cfgRsp.pComment) {
×
543
        code = terrno;
×
544
        goto _exit;
×
545
      }
546
    }
547
    // owned tag values: copy ntbEntry.pTags so the executor's local-tag reading path
548
    // (which reads cfgRsp.pTags) can project them. Mirrors the child-table branch above.
549
    if (mer1.me.ntbEntry.schemaTag.nCols > 0 && mer1.me.ntbEntry.pTags != NULL) {
54,061 ✔
550
      STag *pTag = (STag *)mer1.me.ntbEntry.pTags;
21,745 ✔
551
      cfgRsp.tagsLen = pTag->len;
21,745 ✔
552
      cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen);
21,745 ✔
553
      if (NULL == cfgRsp.pTags) {
21,745 ✔
554
        code = terrno;
×
555
        goto _exit;
×
556
      }
557
      (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
21,745 ✔
558
    }
559
  } else {
560
    vError("vnodeGetTableCfg get invalid table type:%d", mer1.me.type);
×
561
    code = TSDB_CODE_APP_ERROR;
×
562
    goto _exit;
×
563
  }
564

565
  // For a virtual child table, build the merged column view first: vstb row schema followed
566
  // by the vchild's own (extension) columns, persisted colRef followed by own column refs.
567
  nMergedCols = schema.nCols;
37,339,761 ✔
568
  if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
37,339,761 ✔
569
    code = metaBuildMergedColView(&mer1.me, &schema, &pMergedCols, &pMergedRefs, &nMergedCols);
24,855,887 ✔
570
    if (code) {
24,855,887 ✔
571
      vError("vgId:%d, vnodeGetTableCfg build merged col view for %s failed since %s", TD_VID(pVnode),
×
572
             cfgReq.tbName, tstrerror(code));
573
      goto _exit;
×
574
    }
575
    // merged tag view: vstb tag schema followed by the vchild's own (extension) tags
576
    nMergedTags = schemaTag.nCols;
24,855,887 ✔
577
    code = metaBuildMergedTagView(&mer1.me, &schemaTag, &pMergedTags, &nMergedTags);
24,855,887 ✔
578
    if (code) {
24,855,887 ✔
579
      vError("vgId:%d, vnodeGetTableCfg build merged tag view for %s failed since %s", TD_VID(pVnode),
×
580
             cfgReq.tbName, tstrerror(code));
581
      goto _exit;
×
582
    }
583
  }
584

585
  cfgRsp.numOfTags = (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? nMergedTags : schemaTag.nCols;
37,339,761 ✔
586
  cfgRsp.numOfColumns = nMergedCols;
37,339,761 ✔
587
  cfgRsp.virtualStb = false; // vnode don't have super table, so it's always false
37,339,761 ✔
588
  cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags));
37,339,761 ✔
589
  cfgRsp.pSchemaExt = (SSchemaExt *)taosMemoryCalloc(cfgRsp.numOfColumns, sizeof(SSchemaExt));
37,339,761 ✔
590
  cfgRsp.pColRefs = (SColRef *)taosMemoryCalloc(cfgRsp.numOfColumns, sizeof(SColRef));
37,339,761 ✔
591
  cfgRsp.numOfTagRefs = 0;
37,339,761 ✔
592
  cfgRsp.pTagRefs = NULL;
37,339,761 ✔
593

594
  if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt || NULL == cfgRsp.pColRefs) {
37,339,761 ✔
595
    code = terrno;
×
596
    goto _exit;
×
597
  }
598
  if (pMergedCols) {
37,339,761 ✔
599
    (void)memcpy(cfgRsp.pSchemas, pMergedCols, sizeof(SSchema) * nMergedCols);
24,855,887 ✔
600
  } else {
601
    (void)memcpy(cfgRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols);
12,483,874 ✔
602
  }
603
  if (pMergedTags) {
37,339,761 ✔
604
    (void)memcpy(cfgRsp.pSchemas + cfgRsp.numOfColumns, pMergedTags, sizeof(SSchema) * nMergedTags);
24,855,887 ✔
605
  } else if (schemaTag.nCols) {
12,483,874 ✔
606
    (void)memcpy(cfgRsp.pSchemas + cfgRsp.numOfColumns, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
12,451,558 ✔
607
  }
608

609
  SMetaReader    *pReader = (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? &mer2 : &mer1;
37,339,761 ✔
610
  SColRefWrapper *pColRef = &mer1.me.colRef;
37,339,761 ✔
611

612
  if (withExtSchema(cfgRsp.tableType)) {
37,339,761 ✔
613
    // col compress/ext schema of the vstb part; own columns carry typeMod (e.g. decimal
614
    // precision/scale) from the vchild entry's own-col ext area when present.
615
    code = fillTableColCmpr(pReader, cfgRsp.pSchemaExt, schema.nCols);
37,339,761 ✔
616
    if (code < 0) {
37,339,761 ✔
617
      goto _exit;
×
618
    }
619

620
    for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
334,478,352 ✔
621
      SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i;
297,138,591 ✔
622
      pSchExt->colId = cfgRsp.pSchemas[i].colId;
297,138,591 ✔
623
      if (i < schema.nCols) {
297,138,591 ✔
624
        if (pReader->me.pExtSchemas) {
297,126,411 ✔
625
          pSchExt->typeMod = pReader->me.pExtSchemas[i].typeMod;
72,846 ✔
626
        }
627
      } else if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE && mer1.me.own.pOwnColExtSchemas != NULL &&
12,180 ✔
628
                 mer1.me.own.nOwnCols == cfgRsp.numOfColumns - schema.nCols) {
840 ✔
629
        // see the same guard in vnodeGetTableMeta: a non-NULL own ext area is sized nOwnCols;
630
        // verify the count so the index below is provably in range
631
        pSchExt->typeMod = mer1.me.own.pOwnColExtSchemas[i - schema.nCols].typeMod;
840 ✔
632
      }
633
    }
634
  }
635

636
  cfgRsp.virtualStb = false;
37,339,761 ✔
637
  if (hasColRef(cfgRsp.tableType)) {
37,339,761 ✔
638
    if (pMergedRefs) {
24,903,304 ✔
639
      // merged view already validated and deep-copied by metaBuildMergedColView;
640
      // transfer ownership to the response
641
      taosMemoryFreeClear(cfgRsp.pColRefs);
24,855,887 ✔
642
      cfgRsp.pColRefs = pMergedRefs;
24,855,887 ✔
643
      pMergedRefs = NULL;
24,855,887 ✔
644
    } else {
645
      for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
206,094 ✔
646
        SColRef *pRef = &pColRef->pColRef[i];
158,677 ✔
647
        cfgRsp.pColRefs[i].hasRef = pRef->hasRef;
158,677 ✔
648
        cfgRsp.pColRefs[i].id = pRef->id;
158,677 ✔
649
        if (cfgRsp.pColRefs[i].hasRef) {
158,677 ✔
650
          cfgRsp.pColRefs[i].refType = pRef->refType;
104,423 ✔
651
          tstrncpy(cfgRsp.pColRefs[i].refSourceName, pRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
104,423 ✔
652
          tstrncpy(cfgRsp.pColRefs[i].refSchemaName, pRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
104,423 ✔
653
          tstrncpy(cfgRsp.pColRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
104,423 ✔
654
          tstrncpy(cfgRsp.pColRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
104,423 ✔
655
          tstrncpy(cfgRsp.pColRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
104,423 ✔
656
          if (pRef->tagCondJson) {
104,423 ✔
657
            cfgRsp.pColRefs[i].tagCondLen = pRef->tagCondLen;
10,614 ✔
658
            cfgRsp.pColRefs[i].tagCondJson = taosStrdup(pRef->tagCondJson);
10,614 ✔
659
          } else {
660
            cfgRsp.pColRefs[i].tagCondLen = 0;
93,809 ✔
661
            cfgRsp.pColRefs[i].tagCondJson = NULL;
93,809 ✔
662
          }
663
        }
664
        if (pRef->filterCondLen > 0 && pRef->filterCondJson) {
158,677 ✔
665
          cfgRsp.pColRefs[i].filterCondLen = pRef->filterCondLen;
×
666
          cfgRsp.pColRefs[i].filterCondJson = taosStrdup(pRef->filterCondJson);
×
667
          if (NULL == cfgRsp.pColRefs[i].filterCondJson) {
×
668
            code = terrno;
×
669
            goto _exit;
×
670
          }
671
        }
672
      }
673
    }
674

675
    cfgRsp.numOfTagRefs = pColRef->nTagRefs;
24,903,304 ✔
676
    if (cfgRsp.numOfTagRefs > 0) {
24,903,304 ✔
677
      if (NULL == pColRef->pTagRef) {
14,277,628 ✔
678
        code = TSDB_CODE_APP_ERROR;
×
679
        goto _exit;
×
680
      }
681
      cfgRsp.pTagRefs = (SColRef *)taosMemoryCalloc(cfgRsp.numOfTagRefs, sizeof(SColRef));
14,277,628 ✔
682
      if (NULL == cfgRsp.pTagRefs) {
14,277,628 ✔
683
        code = terrno;
×
684
        goto _exit;
×
685
      }
686

687
      for (int32_t i = 0; i < cfgRsp.numOfTagRefs; i++) {
56,875,341 ✔
688
        SColRef *pRef = &pColRef->pTagRef[i];
42,597,713 ✔
689
        cfgRsp.pTagRefs[i].hasRef = pRef->hasRef;
42,597,713 ✔
690
        cfgRsp.pTagRefs[i].id = pRef->id;
42,597,713 ✔
691
        if (cfgRsp.pTagRefs[i].hasRef) {
42,597,713 ✔
692
          cfgRsp.pTagRefs[i].refType = pRef->refType;
28,301,592 ✔
693
          tstrncpy(cfgRsp.pTagRefs[i].refSourceName, pRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
28,301,592 ✔
694
          tstrncpy(cfgRsp.pTagRefs[i].refSchemaName, pRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
28,301,592 ✔
695
          tstrncpy(cfgRsp.pTagRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
28,301,592 ✔
696
          tstrncpy(cfgRsp.pTagRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
28,301,592 ✔
697
          tstrncpy(cfgRsp.pTagRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
28,301,592 ✔
698
          if (pRef->tagCondJson) {
28,301,592 ✔
699
            cfgRsp.pTagRefs[i].tagCondLen = pRef->tagCondLen;
×
700
            cfgRsp.pTagRefs[i].tagCondJson = taosStrdup(pRef->tagCondJson);
×
701
            if (NULL == cfgRsp.pTagRefs[i].tagCondJson) {
×
702
              code = terrno;
×
703
              goto _exit;
×
704
            }
705
          }
706
          if (pRef->filterCondLen > 0 && pRef->filterCondJson) {
28,301,592 ✔
707
            cfgRsp.pTagRefs[i].filterCondLen = pRef->filterCondLen;
×
708
            cfgRsp.pTagRefs[i].filterCondJson = taosStrdup(pRef->filterCondJson);
×
709
            if (NULL == cfgRsp.pTagRefs[i].filterCondJson) {
×
710
              code = terrno;
×
711
              goto _exit;
×
712
            }
713
          }
714
        }
715
      }
716
    }
717
  }
718

719
  // populate series
720
  if (mer1.me.series.nSeries > 0) {
37,339,761 ✔
721
    cfgRsp.numOfSeries = mer1.me.series.nSeries;
650,903 ✔
722
    cfgRsp.pSeries = taosMemoryCalloc(mer1.me.series.nSeries, sizeof(SSeriesEntry));
650,903 ✔
723
    if (cfgRsp.pSeries) {
650,903 ✔
724
      for (int32_t i = 0; i < mer1.me.series.nSeries; i++) {
4,540,390 ✔
725
        SSeriesEntry *src = &mer1.me.series.pSeries[i];
3,889,487 ✔
726
        SSeriesEntry *dst = &cfgRsp.pSeries[i];
3,889,487 ✔
727
        tstrncpy(dst->alias, src->alias, TSDB_COL_NAME_LEN);
3,889,487 ✔
728
        tstrncpy(dst->sourceName, src->sourceName, TSDB_EXT_SOURCE_NAME_LEN);
3,889,487 ✔
729
        tstrncpy(dst->dbName, src->dbName, TSDB_DB_NAME_LEN);
3,889,487 ✔
730
        tstrncpy(dst->measurementName, src->measurementName, TSDB_TABLE_NAME_LEN);
3,889,487 ✔
731
        if (src->tagCondLen > 0) {
3,889,487 ✔
732
          dst->tagCondJson = taosStrdup(src->tagCondJson);
3,889,487 ✔
733
          dst->tagCondLen = src->tagCondLen;
3,889,487 ✔
734
        } else {
735
          dst->tagCondJson = NULL;
×
736
          dst->tagCondLen = 0;
×
737
        }
738
      }
739
    }
740
  }
741

742
  // encode and send response
743
  rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp);
37,339,761 ✔
744
  if (rspLen < 0) {
37,339,761 ✔
745
    code = terrno;
×
746
    goto _exit;
×
747
  }
748

749
  if (direct) {
37,339,761 ✔
750
    pRsp = rpcMallocCont(rspLen);
37,298,097 ✔
751
  } else {
752
    pRsp = taosMemoryCalloc(1, rspLen);
41,664 ✔
753
  }
754

755
  if (pRsp == NULL) {
37,339,761 ✔
756
    code = terrno;
×
757
    goto _exit;
×
758
  }
759

760
  rspLen = tSerializeSTableCfgRsp(pRsp, rspLen, &cfgRsp);
37,339,761 ✔
761
  if (rspLen < 0) {
37,339,761 ✔
762
    code = terrno;
×
763
    goto _exit;
×
764
  }
765

766
_exit:
37,340,283 ✔
767
  rpcMsg.info = pMsg->info;
37,340,283 ✔
768
  rpcMsg.pCont = pRsp;
37,340,283 ✔
769
  rpcMsg.contLen = rspLen;
37,340,283 ✔
770
  rpcMsg.code = code;
37,340,283 ✔
771
  rpcMsg.msgType = pMsg->msgType;
37,340,283 ✔
772

773
  if (code) {
37,340,283 ✔
774
    qError("get table %s cfg failed cause of %s", cfgReq.tbName, tstrerror(code));
522 ✔
775
  }
776

777
  if (direct) {
37,340,283 ✔
778
    tmsgSendRsp(&rpcMsg);
37,298,619 ✔
779
  } else {
780
    *pMsg = rpcMsg;
41,664 ✔
781
  }
782

783
  tFreeSTableCfgRsp(&cfgRsp);
37,340,283 ✔
784
  taosMemoryFreeClear(pMergedCols);
37,340,283 ✔
785
  taosMemoryFreeClear(pMergedTags);
37,340,283 ✔
786
  if (pMergedRefs) {
37,340,283 ✔
787
    tFreeSColRefArray(pMergedRefs, nMergedCols);
×
788
    taosMemoryFreeClear(pMergedRefs);
×
789
  }
790
  metaReaderClear(&mer2);
37,340,283 ✔
791
  metaReaderClear(&mer1);
37,340,283 ✔
792
  return code;
37,340,283 ✔
793
}
794

795
static FORCE_INLINE void vnodeFreeSBatchRspMsg(void *p) {
796
  if (NULL == p) {
797
    return;
798
  }
799

800
  SBatchRspMsg *pRsp = (SBatchRspMsg *)p;
801
  rpcFreeCont(pRsp->msg);
802
}
803

804
int32_t vnodeGetBatchMeta(SVnode *pVnode, SRpcMsg *pMsg) {
24,101,666 ✔
805
  int32_t      code = 0;
24,101,666 ✔
806
  int32_t      rspSize = 0;
24,101,666 ✔
807
  SBatchReq    batchReq = {0};
24,101,666 ✔
808
  SBatchMsg   *req = NULL;
24,104,007 ✔
809
  SBatchRspMsg rsp = {0};
24,104,007 ✔
810
  SBatchRsp    batchRsp = {0};
24,087,645 ✔
811
  SRpcMsg      reqMsg = *pMsg;
24,089,578 ✔
812
  SRpcMsg      rspMsg = {0};
24,089,982 ✔
813
  void        *pRsp = NULL;
24,094,702 ✔
814

815
  if (tDeserializeSBatchReq(pMsg->pCont, pMsg->contLen, &batchReq)) {
24,094,702 ✔
816
    code = terrno;
×
817
    qError("tDeserializeSBatchReq failed");
×
818
    goto _exit;
×
819
  }
820

821
  int32_t msgNum = taosArrayGetSize(batchReq.pMsgs);
24,091,898 ✔
822
  if (msgNum >= MAX_META_MSG_IN_BATCH) {
24,096,561 ✔
823
    code = TSDB_CODE_INVALID_MSG;
×
824
    qError("too many msgs %d in vnode batch meta req", msgNum);
×
825
    goto _exit;
×
826
  }
827

828
  batchRsp.pRsps = taosArrayInit(msgNum, sizeof(SBatchRspMsg));
24,096,561 ✔
829
  if (NULL == batchRsp.pRsps) {
24,094,580 ✔
830
    code = terrno;
×
831
    qError("taosArrayInit %d SBatchRspMsg failed", msgNum);
×
832
    goto _exit;
×
833
  }
834

835
  for (int32_t i = 0; i < msgNum; ++i) {
51,691,653 ✔
836
    req = taosArrayGet(batchReq.pMsgs, i);
27,586,033 ✔
837
    if (req == NULL) {
27,581,718 ✔
838
      code = terrno;
×
839
      goto _exit;
×
840
    }
841

842
    reqMsg.msgType = req->msgType;
27,586,204 ✔
843
    reqMsg.pCont = req->msg;
27,586,204 ✔
844
    reqMsg.contLen = req->msgLen;
27,586,204 ✔
845

846
    switch (req->msgType) {
27,586,204 ✔
847
      case TDMT_VND_TABLE_META:
18,834,969 ✔
848
        // error code has been set into reqMsg, no need to handle it here.
849
        if (TSDB_CODE_SUCCESS != vnodeGetTableMeta(pVnode, &reqMsg, false)) {
18,834,969 ✔
850
          qWarn("vnodeGetBatchMeta failed, msgType:%d", req->msgType);
2,475,761 ✔
851
        }
852
        break;
18,833,130 ✔
853
      case TDMT_VND_TABLE_NAME:
82,914 ✔
854
        // error code has been set into reqMsg, no need to handle it here.
855
        if (TSDB_CODE_SUCCESS != vnodeGetTableMeta(pVnode, &reqMsg, false)) {
82,914 ✔
856
          qWarn("vnodeGetBatchName failed, msgType:%d", req->msgType);
23,701 ✔
857
        }
858
        break;
82,914 ✔
859
      case TDMT_VND_TABLE_CFG:
41,664 ✔
860
        // error code has been set into reqMsg, no need to handle it here.
861
        if (TSDB_CODE_SUCCESS != vnodeGetTableCfg(pVnode, &reqMsg, false)) {
41,664 ✔
862
          qWarn("vnodeGetBatchMeta failed, msgType:%d", req->msgType);
×
863
        }
864
        break;
41,664 ✔
865
      case TDMT_VND_VSUBTABLES_META:
8,626,657 ✔
866
        // error code has been set into reqMsg, no need to handle it here.
867
        if (TSDB_CODE_SUCCESS != vnodeGetVSubtablesMeta(pVnode, &reqMsg)) {
8,626,657 ✔
868
          qWarn("vnodeGetVSubtablesMeta failed, msgType:%d", req->msgType);
×
869
        }
870
        break;
8,614,871 ✔
871
      case TDMT_VND_VSTB_REF_DBS:
×
872
        // error code has been set into reqMsg, no need to handle it here.
873
        if (TSDB_CODE_SUCCESS != vnodeGetVStbRefDbs(pVnode, &reqMsg)) {
×
874
          qWarn("vnodeGetVStbRefDbs failed, msgType:%d", req->msgType);
×
875
        }
876
        break;
×
877
      case TDMT_VND_VTB_TAG_COND:
×
878
        // error code has been set into reqMsg, no need to handle it here.
879
        if (TSDB_CODE_SUCCESS != vnodeGetVTbTagCond(pVnode, &reqMsg, false)) {
×
880
          qWarn("vnodeGetVTbTagCond failed, msgType:%d", req->msgType);
×
881
        }
882
        break;
×
883
      default:
×
884
        qError("invalid req msgType %d", req->msgType);
×
885
        reqMsg.code = TSDB_CODE_INVALID_MSG;
×
886
        reqMsg.pCont = NULL;
×
887
        reqMsg.contLen = 0;
×
888
        break;
×
889
    }
890

891
    rsp.msgIdx = req->msgIdx;
27,597,048 ✔
892
    rsp.reqType = reqMsg.msgType;
27,597,048 ✔
893
    rsp.msgLen = reqMsg.contLen;
27,597,048 ✔
894
    rsp.rspCode = reqMsg.code;
27,597,048 ✔
895
    rsp.msg = reqMsg.pCont;
27,597,048 ✔
896

897
    if (NULL == taosArrayPush(batchRsp.pRsps, &rsp)) {
55,168,810 ✔
898
      qError("taosArrayPush failed");
×
899
      code = terrno;
×
900
      goto _exit;
×
901
    }
902
  }
903

904
  rspSize = tSerializeSBatchRsp(NULL, 0, &batchRsp);
24,105,620 ✔
905
  if (rspSize < 0) {
24,104,976 ✔
906
    qError("tSerializeSBatchRsp failed");
×
907
    code = terrno;
×
908
    goto _exit;
×
909
  }
910
  pRsp = rpcMallocCont(rspSize);
24,104,976 ✔
911
  if (pRsp == NULL) {
24,102,572 ✔
912
    qError("rpcMallocCont %d failed", rspSize);
×
913
    code = terrno;
×
914
    goto _exit;
×
915
  }
916
  if (tSerializeSBatchRsp(pRsp, rspSize, &batchRsp) < 0) {
24,102,572 ✔
917
    qError("tSerializeSBatchRsp %d failed", rspSize);
×
918
    code = terrno;
×
919
    goto _exit;
×
920
  }
921

922
_exit:
24,107,530 ✔
923

924
  rspMsg.info = pMsg->info;
24,107,678 ✔
925
  rspMsg.pCont = pRsp;
24,107,678 ✔
926
  rspMsg.contLen = rspSize;
24,107,678 ✔
927
  rspMsg.code = code;
24,107,678 ✔
928
  rspMsg.msgType = pMsg->msgType;
24,107,678 ✔
929

930
  if (code) {
24,107,678 ✔
931
    qError("vnd get batch meta failed cause of %s", tstrerror(code));
×
932
  }
933

934
  taosArrayDestroyEx(batchReq.pMsgs, tFreeSBatchReqMsg);
24,107,678 ✔
935
  taosArrayDestroyEx(batchRsp.pRsps, tFreeSBatchRspMsg);
24,105,708 ✔
936

937
  tmsgSendRsp(&rspMsg);
24,103,344 ✔
938

939
  return code;
24,107,831 ✔
940
}
941

942
#define VNODE_DO_META_QUERY(pVnode, cmd)                 \
943
  do {                                                   \
944
    (void)taosThreadRwlockRdlock(&(pVnode)->metaRWLock); \
945
    cmd;                                                 \
946
    (void)taosThreadRwlockUnlock(&(pVnode)->metaRWLock); \
947
  } while (0)
948

949
int32_t vnodeReadVSubtables(SReadHandle* pHandle, int64_t suid, SArray** ppRes) {
8,623,782 ✔
950
  int32_t                    code = TSDB_CODE_SUCCESS;
8,623,782 ✔
951
  int32_t                    line = 0;
8,626,707 ✔
952
  SMetaReader                mr = {0};
8,626,707 ✔
953
  bool                       readerInit = false;
8,595,399 ✔
954
  SVCTableRefCols*           pTb = NULL;
8,595,399 ✔
955
  int32_t                    refColsNum = 0;
8,600,779 ✔
956
  char                       tbFName[TSDB_TABLE_FNAME_LEN];
8,600,779 ✔
957
  SSHashObj*                 pSrcTbls = NULL;
8,598,823 ✔
958
  SSHashObj*                 pContentDedup = NULL;
8,598,823 ✔
959

960
  SArray *pList = taosArrayInit(10, sizeof(uint64_t));
8,598,823 ✔
961
  QUERY_CHECK_NULL(pList, code, line, _return, terrno);
8,615,938 ✔
962

963
  QUERY_CHECK_CODE(pHandle->api.metaFn.getChildTableList(pHandle->vnode, suid, pList), line, _return);
8,615,938 ✔
964

965
  size_t num = taosArrayGetSize(pList);
8,630,362 ✔
966
  *ppRes = taosArrayInit(num, POINTER_BYTES);
8,630,592 ✔
967
  QUERY_CHECK_NULL(*ppRes, code, line, _return, terrno);
8,632,212 ✔
968
  pSrcTbls = tSimpleHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
8,632,212 ✔
969
  QUERY_CHECK_NULL(pSrcTbls, code, line, _return, terrno);
8,624,626 ✔
970
  pContentDedup = tSimpleHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
8,624,626 ✔
971
  QUERY_CHECK_NULL(pContentDedup, code, line, _return, terrno);
8,621,660 ✔
972

973
  for (int32_t i = 0; i < num; ++i) {
57,308,002 ✔
974
    uint64_t* id = taosArrayGet(pList, i);
48,666,939 ✔
975
    QUERY_CHECK_NULL(id, code, line, _return, terrno);
48,660,992 ✔
976
    pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn, pHandle->txnId);
48,660,992 ✔
977
    QUERY_CHECK_CODE(pHandle->api.metaReaderFn.getTableEntryByUid(&mr, *id), line, _return);
48,692,397 ✔
978
    readerInit = true;
50,079,922 ✔
979

980
    refColsNum = 0;
48,522,900 ✔
981
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
547,477,960 ✔
982
      if (mr.me.colRef.pColRef[j].hasRef) {
498,861,306 ✔
983
        refColsNum++;
282,985,519 ✔
984
      }
985
    }
986

987
    int32_t tagRefColsNum = 0;
48,522,900 ✔
988
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
90,569,824 ✔
989
      if (mr.me.colRef.pTagRef[j].hasRef) {
41,953,170 ✔
990
        tagRefColsNum++;
27,996,600 ✔
991
      }
992
    }
993

994
    if (refColsNum <= 0 && tagRefColsNum <= 0) {
48,616,654 ✔
995
      pHandle->api.metaReaderFn.clearReader(&mr);
7,979,849 ✔
996
      readerInit = false;
7,979,849 ✔
997
      continue;
7,979,849 ✔
998
    }
999

1000
    // Size the compact block (entries + string arena) and count source tables.
1001
    uint64_t arenaBytes = 0;
40,636,805 ✔
1002
    tSimpleHashClear(pSrcTbls);
40,636,805 ✔
1003
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
412,593,887 ✔
1004
      if (!mr.me.colRef.pColRef[j].hasRef) {
372,009,840 ✔
1005
        continue;
88,590,536 ✔
1006
      }
1007

1008
      arenaBytes += strlen(mr.me.colRef.pColRef[j].refDbName) + 1;
283,419,304 ✔
1009
      arenaBytes += strlen(mr.me.colRef.pColRef[j].refTableName) + 1;
283,419,304 ✔
1010
      arenaBytes += strlen(mr.me.colRef.pColRef[j].refColName) + 1;
283,419,304 ✔
1011
      if (mr.me.colRef.pColRef[j].refSourceName[0] != '\0') {
283,419,304 ✔
1012
        arenaBytes += strlen(mr.me.colRef.pColRef[j].refSourceName) + 1;
10,721,506 ✔
1013
      }
1014
      if (mr.me.colRef.pColRef[j].refSchemaName[0] != '\0') {
283,419,304 ✔
1015
        arenaBytes += strlen(mr.me.colRef.pColRef[j].refSchemaName) + 1;
283 ✔
1016
      }
1017

1018
      snprintf(tbFName, sizeof(tbFName), "%s.%s", mr.me.colRef.pColRef[j].refDbName, mr.me.colRef.pColRef[j].refTableName);
283,419,304 ✔
1019

1020
      if (NULL == tSimpleHashGet(pSrcTbls, tbFName, strlen(tbFName))) {
283,419,304 ✔
1021
        QUERY_CHECK_CODE(tSimpleHashPut(pSrcTbls, tbFName, strlen(tbFName), &code, sizeof(code)), line, _return);
56,194,027 ✔
1022
      }
1023
    }
1024
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
82,628,853 ✔
1025
      if (!mr.me.colRef.pTagRef[j].hasRef) {
42,028,884 ✔
1026
        continue;
13,995,900 ✔
1027
      }
1028

1029
      arenaBytes += strlen(mr.me.colRef.pTagRef[j].refDbName) + 1;
28,032,984 ✔
1030
      arenaBytes += strlen(mr.me.colRef.pTagRef[j].refTableName) + 1;
28,032,984 ✔
1031
      arenaBytes += strlen(mr.me.colRef.pTagRef[j].refColName) + 1;
28,032,984 ✔
1032
      if (mr.me.colRef.pTagRef[j].refSourceName[0] != '\0') {
28,032,984 ✔
1033
        arenaBytes += strlen(mr.me.colRef.pTagRef[j].refSourceName) + 1;
×
1034
      }
1035
      if (mr.me.colRef.pTagRef[j].refSchemaName[0] != '\0') {
28,032,984 ✔
1036
        arenaBytes += strlen(mr.me.colRef.pTagRef[j].refSchemaName) + 1;
×
1037
      }
1038

1039
      snprintf(tbFName, sizeof(tbFName), "%s.%s", mr.me.colRef.pTagRef[j].refDbName, mr.me.colRef.pTagRef[j].refTableName);
28,032,984 ✔
1040

1041
      if (NULL == tSimpleHashGet(pSrcTbls, tbFName, strlen(tbFName))) {
28,032,984 ✔
1042
        QUERY_CHECK_CODE(tSimpleHashPut(pSrcTbls, tbFName, strlen(tbFName), &code, sizeof(code)), line, _return);
646,823 ✔
1043
      }
1044
    }
1045

1046
    SVctRefContent* pContent = tVctRefContentAlloc(refColsNum, tagRefColsNum, arenaBytes);
40,599,969 ✔
1047
    QUERY_CHECK_NULL(pContent, code, line, _return, terrno);
40,655,474 ✔
1048

1049
    uint32_t arenaPos = 0;
40,655,474 ✔
1050
    int32_t  colIdx = 0;
40,658,561 ✔
1051
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
411,782,686 ✔
1052
      if (!mr.me.colRef.pColRef[j].hasRef) {
371,374,476 ✔
1053
        continue;
88,563,721 ✔
1054
      }
1055

1056
      SRefColEntry* pEntry = vctContentColAt(pContent, colIdx);
282,810,755 ✔
1057
      pEntry->colId = mr.me.colRef.pColRef[j].id;
282,810,755 ✔
1058
      if (mr.me.colRef.pColRef[j].filterCondLen > 0) {
282,810,755 ✔
1059
        pEntry->flags |= VCT_REF_FLAG_HAS_FILTER_COND;
×
1060
      }
1061
      pEntry->dbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refDbName);
282,810,755 ✔
1062
      pEntry->tbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refTableName);
283,132,393 ✔
1063
      pEntry->colOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refColName);
283,140,833 ✔
1064
      pEntry->srcOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refSourceName);
283,140,035 ✔
1065
      pEntry->schemaOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refSchemaName);
282,917,643 ✔
1066
      colIdx++;
282,560,404 ✔
1067
    }
1068

1069
    // Fill tag refs
1070
    int32_t tagIdx = 0;
40,344,920 ✔
1071
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
82,339,917 ✔
1072
      if (!mr.me.colRef.pTagRef[j].hasRef) {
41,978,964 ✔
1073
        continue;
13,979,344 ✔
1074
      }
1075

1076
      SRefColEntry* pEntry = vctContentTagAt(pContent, tagIdx);
27,999,620 ✔
1077
      pEntry->colId = mr.me.colRef.pTagRef[j].id;
27,999,620 ✔
1078
      pEntry->dbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refDbName);
27,999,620 ✔
1079
      pEntry->tbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refTableName);
28,024,368 ✔
1080
      pEntry->colOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refColName);
28,003,650 ✔
1081
      pEntry->srcOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refSourceName);
28,020,999 ✔
1082
      pEntry->schemaOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refSchemaName);
28,005,294 ✔
1083
      tagIdx++;
27,952,363 ✔
1084
    }
1085

1086
    // Children over few source tables share one content block per unique
1087
    // ref pattern instead of carrying a private copy each.
1088
    SVctRefContent** ppKept = (SVctRefContent**)tSimpleHashGet(pContentDedup, pContent, (uint32_t)pContent->bufLen);
40,360,953 ✔
1089
    if (NULL != ppKept) {
40,723,454 ✔
1090
      taosMemoryFree(pContent);
2,386,371 ✔
1091
      pContent = *ppKept;
2,387,381 ✔
1092
    } else {
1093
      code = tSimpleHashPut(pContentDedup, pContent, (uint32_t)pContent->bufLen, &pContent, sizeof(pContent));
38,337,083 ✔
1094
      if (code) {
38,345,189 ✔
1095
        // the block is owned by no one else yet; release it on the way out
1096
        taosMemoryFree(pContent);
×
1097
        QUERY_CHECK_CODE(code, line, _return);
×
1098
      }
1099
    }
1100

1101
    pTb = tVctRefRecordNew(mr.me.uid, tSimpleHashGetSize(pSrcTbls), refColsNum, tagRefColsNum, pContent);
40,732,570 ✔
1102
    if (NULL == pTb) {
40,692,990 ✔
1103
      code = terrno;
×
1104
      goto _return;
×
1105
    }
1106

1107
    QUERY_CHECK_NULL(taosArrayPush(*ppRes, &pTb), code, line, _return, terrno);
81,335,558 ✔
1108
    pTb = NULL;
40,705,884 ✔
1109

1110
    pHandle->api.metaReaderFn.clearReader(&mr);
40,705,884 ✔
1111
    readerInit = false;
40,681,093 ✔
1112
  }
1113

1114
_return:
8,635,523 ✔
1115

1116
  if (readerInit) {
8,614,921 ✔
1117
    pHandle->api.metaReaderFn.clearReader(&mr);
×
1118
  }
1119

1120
  taosArrayDestroy(pList);
8,637,723 ✔
1121
  taosMemoryFree(pTb);
8,637,043 ✔
1122
  tSimpleHashCleanup(pSrcTbls);
8,637,043 ✔
1123
  tSimpleHashCleanup(pContentDedup);
8,637,322 ✔
1124

1125
  if (code) {
8,637,877 ✔
1126
    qError("%s failed since %s", __func__, tstrerror(code));
×
1127
  }
1128
  return code;
8,637,877 ✔
1129
}
1130

1131
int32_t vnodeReadVStbRefDbs(SReadHandle* pHandle, int64_t suid, SArray** ppDbs, SArray** ppExtSources) {
×
1132
  int32_t                    code = TSDB_CODE_SUCCESS;
×
1133
  int32_t                    line = 0;
×
1134
  SMetaReader                mr = {0};
×
1135
  bool                       readerInit = false;
×
1136
  SSHashObj*                 pDbNameHash = NULL;
×
1137
  SSHashObj*                 pExtSourceHash = NULL;
×
1138
  SArray*                    pList = NULL;
×
1139

1140
  pList = taosArrayInit(10, sizeof(uint64_t));
×
1141
  QUERY_CHECK_NULL(pList, code, line, _return, terrno);
×
1142

1143
  *ppDbs = taosArrayInit(10, POINTER_BYTES);
×
1144
  QUERY_CHECK_NULL(*ppDbs, code, line, _return, terrno)
×
1145

1146
  *ppExtSources = taosArrayInit(4, POINTER_BYTES);
×
1147
  QUERY_CHECK_NULL(*ppExtSources, code, line, _return, terrno)
×
1148
  
1149
  // lookup in cache
1150
  code = pHandle->api.metaFn.metaGetCachedRefDbs(pHandle->vnode, suid, *ppDbs);
×
1151
  QUERY_CHECK_CODE(code, line, _return);
×
1152

1153
  if (taosArrayGetSize(*ppDbs) > 0) {
×
1154
    // found in cache, also get ext sources from cache
1155
    code = pHandle->api.metaFn.metaGetCachedExtSources(pHandle->vnode, suid, *ppExtSources);
×
1156
    QUERY_CHECK_CODE(code, line, _return);
×
1157
    goto _return;
×
1158
  } else {
1159
    code = pHandle->api.metaFn.getChildTableList(pHandle->vnode, suid, pList);
×
1160
    QUERY_CHECK_CODE(code, line, _return);
×
1161

1162
    size_t num = taosArrayGetSize(pList);
×
1163
    pDbNameHash = tSimpleHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
×
1164
    QUERY_CHECK_NULL(pDbNameHash, code, line, _return, terrno);
×
1165

1166
    pExtSourceHash = tSimpleHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
×
1167
    QUERY_CHECK_NULL(pExtSourceHash, code, line, _return, terrno);
×
1168

1169
    for (int32_t i = 0; i < num; ++i) {
×
1170
      uint64_t* id = taosArrayGet(pList, i);
×
1171
      QUERY_CHECK_NULL(id, code, line, _return, terrno);
×
1172

1173
      pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn, pHandle->txnId);
×
1174
      readerInit = true;
×
1175

1176
      code = pHandle->api.metaReaderFn.getTableEntryByUid(&mr, *id);
×
1177
      QUERY_CHECK_CODE(code, line, _return);
×
1178

1179
      for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
×
1180
        if (mr.me.colRef.pColRef[j].hasRef) {
×
1181
          if (mr.me.colRef.pColRef[j].refSourceName[0] != '\0') {
×
1182
            const char* srcName = mr.me.colRef.pColRef[j].refSourceName;
×
1183
            if (NULL == tSimpleHashGet(pExtSourceHash, srcName, strlen(srcName))) {
×
1184
              char *dup = taosStrdup(srcName);
×
1185
              QUERY_CHECK_NULL(dup, code, line, _return, terrno);
×
1186
              QUERY_CHECK_NULL(taosArrayPush(*ppExtSources, &dup), code, line, _return, terrno);
×
1187
              code = tSimpleHashPut(pExtSourceHash, srcName, strlen(srcName), NULL, 0);
×
1188
              QUERY_CHECK_CODE(code, line, _return);
×
1189
            }
1190
          } else {
1191
            if (NULL == tSimpleHashGet(pDbNameHash, mr.me.colRef.pColRef[j].refDbName, strlen(mr.me.colRef.pColRef[j].refDbName))) {
×
1192
              char *refDbName = taosStrdup(mr.me.colRef.pColRef[j].refDbName);
×
1193
              QUERY_CHECK_NULL(refDbName, code, line, _return, terrno);
×
1194
              QUERY_CHECK_NULL(taosArrayPush(*ppDbs, &refDbName), code, line, _return, terrno);
×
1195
              code = tSimpleHashPut(pDbNameHash, refDbName, strlen(refDbName), NULL, 0);
×
1196
              QUERY_CHECK_CODE(code, line, _return);
×
1197
            }
1198
          }
1199
        }
1200
      }
1201

1202
      pHandle->api.metaReaderFn.clearReader(&mr);
×
1203
      readerInit = false;
×
1204
    }
1205

1206
    code = pHandle->api.metaFn.metaPutRefDbsToCache(pHandle->vnode, suid, *ppDbs);
×
1207
    QUERY_CHECK_CODE(code, line, _return);
×
1208

1209
    code = pHandle->api.metaFn.metaPutExtSourcesToCache(pHandle->vnode, suid, *ppExtSources);
×
1210
    QUERY_CHECK_CODE(code, line, _return);
×
1211
  }
1212

1213
_return:
×
1214

1215
  if (readerInit) {
×
1216
    pHandle->api.metaReaderFn.clearReader(&mr);
×
1217
  }
1218

1219
  taosArrayDestroy(pList);
×
1220
  tSimpleHashCleanup(pDbNameHash);
×
1221
  tSimpleHashCleanup(pExtSourceHash);
×
1222

1223
  if (code) {
×
1224
    qError("%s failed since %s", __func__, tstrerror(code));
×
1225
  }
1226
  return code;
×
1227
}
1228

1229
int32_t vnodeGetVSubtablesMeta(SVnode *pVnode, SRpcMsg *pMsg) {
8,617,949 ✔
1230
  int32_t        code = 0;
8,617,949 ✔
1231
  int32_t        rspSize = 0;
8,617,949 ✔
1232
  SVSubTablesReq req = {0};
8,617,949 ✔
1233
  SVSubTablesRsp rsp = {0};
8,620,334 ✔
1234
  SRpcMsg      rspMsg = {0};
8,597,313 ✔
1235
  void        *pRsp = NULL;
8,597,313 ✔
1236
  int32_t      line = 0;
8,597,313 ✔
1237

1238
  if (tDeserializeSVSubTablesReq(pMsg->pCont, pMsg->contLen, &req)) {
8,597,313 ✔
1239
    code = terrno;
×
1240
    qError("tDeserializeSVSubTablesReq failed");
×
1241
    goto _return;
×
1242
  }
1243

1244
  SReadHandle handle = {0};
8,626,598 ✔
1245
  handle.vnode = pVnode;
8,628,788 ✔
1246
  initStorageAPI(&handle.api);
8,628,788 ✔
1247

1248
  QUERY_CHECK_CODE(vnodeReadVSubtables(&handle, req.suid, &rsp.pTables), line, _return);
8,605,778 ✔
1249
  rsp.vgId = TD_VID(pVnode);
8,637,870 ✔
1250

1251
  rspSize = tSerializeSVSubTablesRsp(NULL, 0, &rsp);
8,637,870 ✔
1252
  if (rspSize < 0) {
8,637,058 ✔
1253
    code = rspSize;
×
1254
    qError("tSerializeSVSubTablesRsp failed, error:%d", rspSize);
×
1255
    goto _return;
×
1256
  }
1257
  pRsp = taosMemoryCalloc(1, rspSize);
8,637,058 ✔
1258
  if (pRsp == NULL) {
8,635,742 ✔
1259
    code = terrno;
×
1260
    qError("rpcMallocCont %d failed, error:%d", rspSize, terrno);
×
1261
    goto _return;
×
1262
  }
1263
  rspSize = tSerializeSVSubTablesRsp(pRsp, rspSize, &rsp);
8,635,742 ✔
1264
  if (rspSize < 0) {
8,637,485 ✔
1265
    code = rspSize;
×
1266
    qError("tSerializeSVSubTablesRsp failed, error:%d", rspSize);
×
1267
    goto _return;
×
1268
  }
1269

1270
_return:
8,637,485 ✔
1271

1272
  rspMsg.info = pMsg->info;
8,637,485 ✔
1273
  rspMsg.pCont = pRsp;
8,637,485 ✔
1274
  rspMsg.contLen = rspSize;
8,637,485 ✔
1275
  rspMsg.code = code;
8,637,485 ✔
1276
  rspMsg.msgType = pMsg->msgType;
8,637,485 ✔
1277

1278
  if (code) {
8,637,485 ✔
1279
    qError("vnd get virtual subtables failed cause of %s", tstrerror(code));
×
1280
  }
1281

1282
  *pMsg = rspMsg;
8,637,485 ✔
1283
  
1284
  tDestroySVSubTablesRsp(&rsp);
8,637,485 ✔
1285

1286
  //tmsgSendRsp(&rspMsg);
1287

1288
  return code;
8,637,266 ✔
1289
}
1290

1291
int32_t vnodeProcessCheckHasCtbReq(SVnode *pVnode, SRpcMsg *pMsg) {
55,970 ✔
1292
  SVCheckHasCtbReq req = {0};
55,970 ✔
1293
  int32_t          code = 0;
55,970 ✔
1294
  void            *pBuf = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
55,970 ✔
1295
  int32_t          bufLen = pMsg->contLen - sizeof(SMsgHead);
55,970 ✔
1296

1297
  code = tDeserializeSVCheckHasCtbReq(pBuf, bufLen, &req);
55,970 ✔
1298
  if (code != 0) {
55,970 ✔
1299
    vError("vgId:%d, failed to deserialize check-has-ctb req", TD_VID(pVnode));
×
1300
    goto _exit;
×
1301
  }
1302

1303
  SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, req.suid, 0, 0);
55,970 ✔
1304
  if (pCur == NULL) {
55,970 ✔
1305
    code = (terrno != 0) ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
1306
    vError("vgId:%d, failed to open ctb cursor for suid:%" PRId64 ", code:0x%x", TD_VID(pVnode), req.suid, code);
×
1307
  } else {
1308
    tb_uid_t id = metaCtbCursorNext(pCur);
55,970 ✔
1309
    metaCloseCtbCursor(pCur);
55,970 ✔
1310
    if (id != 0) {
55,970 ✔
1311
      code = TSDB_CODE_MND_VST_PARENT_HAS_VCT;
860 ✔
1312
    }
1313
  }
1314

1315
_exit:;
55,970 ✔
1316
  SRpcMsg rspMsg = {.info = pMsg->info, .code = code};
55,970 ✔
1317
  tmsgSendRsp(&rspMsg);
55,970 ✔
1318
  return 0;  // return 0 so fetch worker doesn't double-send response
55,970 ✔
1319
}
1320

1321
// Pre-check for a virtual stb alter that introduces new column/tag names: fail with
1322
// TSDB_CODE_VND_COL_ALREADY_EXISTS if any vchild table of the stb already owns one of the
1323
// names as an own (extension) column/tag. Same check as the backstop in metaEntry2.c, run
1324
// ahead of the real alter so the mnode-side trans can fail cleanly.
1325
int32_t vnodeProcessCheckStbAlterNameReq(SVnode *pVnode, SRpcMsg *pMsg) {
72,099 ✔
1326
  SVCheckStbAlterNameReq req = {0};
72,099 ✔
1327
  int32_t                code = 0;
72,099 ✔
1328
  void                  *pBuf = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
72,099 ✔
1329
  int32_t                bufLen = pMsg->contLen - sizeof(SMsgHead);
72,099 ✔
1330

1331
  code = tDeserializeSVCheckStbAlterNameReq(pBuf, bufLen, &req);
72,099 ✔
1332
  if (code != 0) {
72,099 ✔
1333
    vError("vgId:%d, failed to deserialize check-stb-alter-name req", TD_VID(pVnode));
×
1334
    goto _exit;
×
1335
  }
1336

1337
  for (int32_t i = 0; i < taosArrayGetSize(req.pNames); ++i) {
151,968 ✔
1338
    code = metaCheckOwnNameConflictOfChildTables(pVnode->pMeta, req.suid, (const char *)taosArrayGet(req.pNames, i));
82,809 ✔
1339
    if (code != 0) {
82,809 ✔
1340
      vError("vgId:%d, check-stb-alter-name failed for suid:%" PRId64 ", code:0x%x", TD_VID(pVnode), req.suid, code);
2,940 ✔
1341
      goto _exit;
2,940 ✔
1342
    }
1343
  }
1344

1345
_exit:;
72,099 ✔
1346
  tFreeSVCheckStbAlterNameReq(&req);
72,099 ✔
1347
  SRpcMsg rspMsg = {.info = pMsg->info, .code = code};
72,099 ✔
1348
  tmsgSendRsp(&rspMsg);
72,099 ✔
1349
  return 0;  // return 0 so fetch worker doesn't double-send response
72,099 ✔
1350
}
1351

1352
int32_t vnodeGetVStbRefDbs(SVnode *pVnode, SRpcMsg *pMsg) {
×
1353
  int32_t        code = 0;
×
1354
  int32_t        rspSize = 0;
×
1355
  SVStbRefDbsReq req = {0};
×
1356
  SVStbRefDbsRsp rsp = {0};
×
1357
  SRpcMsg        rspMsg = {0};
×
1358
  void          *pRsp = NULL;
×
1359
  int32_t        line = 0;
×
1360

1361
  if (tDeserializeSVStbRefDbsReq(pMsg->pCont, pMsg->contLen, &req)) {
×
1362
    code = terrno;
×
1363
    qError("tDeserializeSVSubTablesReq failed");
×
1364
    goto _return;
×
1365
  }
1366

1367
  SReadHandle handle = {0};
×
1368
  handle.vnode = pVnode;
×
1369
  initStorageAPI(&handle.api);
×
1370

1371
  code = vnodeReadVStbRefDbs(&handle, req.suid, &rsp.pDbs, &rsp.pExtSources);
×
1372
  QUERY_CHECK_CODE(code, line, _return);
×
1373
  rsp.vgId = TD_VID(pVnode);
×
1374

1375
  rspSize = tSerializeSVStbRefDbsRsp(NULL, 0, &rsp);
×
1376
  if (rspSize < 0) {
×
1377
    code = rspSize;
×
1378
    qError("tSerializeSVStbRefDbsRsp failed, error:%d", rspSize);
×
1379
    goto _return;
×
1380
  }
1381
  pRsp = taosMemoryCalloc(1, rspSize);
×
1382
  if (pRsp == NULL) {
×
1383
    code = terrno;
×
1384
    qError("rpcMallocCont %d failed, error:%d", rspSize, terrno);
×
1385
    goto _return;
×
1386
  }
1387
  rspSize = tSerializeSVStbRefDbsRsp(pRsp, rspSize, &rsp);
×
1388
  if (rspSize < 0) {
×
1389
    code = rspSize;
×
1390
    qError("tSerializeSVStbRefDbsRsp failed, error:%d", rspSize);
×
1391
    goto _return;
×
1392
  }
1393

1394
_return:
×
1395

1396
  rspMsg.info = pMsg->info;
×
1397
  rspMsg.pCont = pRsp;
×
1398
  rspMsg.contLen = rspSize;
×
1399
  rspMsg.code = code;
×
1400
  rspMsg.msgType = pMsg->msgType;
×
1401

1402
  if (code) {
×
1403
    qError("vnd get virtual stb ref db failed cause of %s", tstrerror(code));
×
1404
  }
1405

1406
  *pMsg = rspMsg;
×
1407

1408
  tDestroySVStbRefDbsRsp(&rsp);
×
1409

1410
  return code;
×
1411
}
1412

1413
int32_t vnodeGetVTbTagCond(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
745,853 ✔
1414
  int32_t      code = TSDB_CODE_SUCCESS;
745,853 ✔
1415
  int32_t      line = 0;
745,853 ✔
1416
  int32_t      rspSize = 0;
745,853 ✔
1417
  SVTagCondReq req = {0};
745,853 ✔
1418
  SVTagCondRsp rsp = {0};
745,853 ✔
1419
  SRpcMsg      rspMsg = {0};
745,853 ✔
1420
  void        *pRsp = NULL;
745,853 ✔
1421
  SMetaReader  mer = {0};
745,853 ✔
1422

1423
  if (tDeserializeSVTagCondReq(pMsg->pCont, pMsg->contLen, &req)) {
745,853 ✔
1424
    code = terrno;
×
1425
    qError("tDeserializeSVTagCondReq failed");
×
1426
    goto _return;
×
1427
  }
1428

1429
  metaReaderDoInit(&mer, pVnode->pMeta, META_READER_LOCK, 0);
745,853 ✔
1430
  code = metaReaderGetTableEntryByUid(&mer, req.uid);
745,853 ✔
1431
  QUERY_CHECK_CODE(code, line, _return);
745,853 ✔
1432

1433
  rsp.pEntries = taosArrayInit(8, sizeof(SVTagCondEntry));
745,853 ✔
1434
  QUERY_CHECK_NULL(rsp.pEntries, code, line, _return, terrno);
745,853 ✔
1435
  rsp.pFilterConds = taosArrayInit(8, sizeof(SVtbColFilterCond));
745,853 ✔
1436
  QUERY_CHECK_NULL(rsp.pFilterConds, code, line, _return, terrno);
745,853 ✔
1437

1438
  if (hasColRef(mer.me.type)) {
745,853 ✔
1439
    SColRefWrapper *p = &(mer.me.colRef);
745,853 ✔
1440
    int32_t nOwnCols = mer.me.type == TSDB_VIRTUAL_CHILD_TABLE ? mer.me.own.nOwnCols : 0;
745,853 ✔
1441
    for (int32_t i = 0; i < p->nCols + nOwnCols; ++i) {
12,655,729 ✔
1442
      SColRef *pColRef = i < p->nCols ? &p->pColRef[i] : &mer.me.own.pOwnColRefs[i - p->nCols];
11,909,876 ✔
1443
      if (pColRef->hasRef && pColRef->tagCondLen > 0 && pColRef->tagCondJson != NULL) {
11,909,876 ✔
1444
        SVTagCondEntry entry = {0};
9,399,440 ✔
1445
        entry.colId = pColRef->id;
9,399,440 ✔
1446
        entry.tagCondLen = pColRef->tagCondLen;
9,399,440 ✔
1447
        entry.tagCondJson = taosStrdup(pColRef->tagCondJson);
9,399,440 ✔
1448
        QUERY_CHECK_NULL(entry.tagCondJson, code, line, _return, terrno);
9,399,440 ✔
1449
        void *pResult = taosArrayPush(rsp.pEntries, &entry);
9,399,440 ✔
1450
        if (NULL == pResult) {
9,399,440 ✔
1451
          taosMemoryFreeClear(entry.tagCondJson);
×
1452
        }
1453
        QUERY_CHECK_NULL(pResult, code, line, _return, terrno);
9,399,440 ✔
1454
      }
1455

1456
      if (pColRef->hasRef && pColRef->filterCondLen > 0 && pColRef->filterCondJson != NULL) {
11,909,876 ✔
1457
        SVtbColFilterCond filterCond = {0};
×
1458
        filterCond.colId = pColRef->id;
×
1459
        filterCond.filterCondLen = pColRef->filterCondLen;
×
1460
        filterCond.filterCondJson = taosStrdup(pColRef->filterCondJson);
×
1461
        QUERY_CHECK_NULL(filterCond.filterCondJson, code, line, _return, terrno);
×
1462
        void *pResult = taosArrayPush(rsp.pFilterConds, &filterCond);
×
1463
        if (NULL == pResult) {
×
1464
          taosMemoryFreeClear(filterCond.filterCondJson);
×
1465
        }
1466
        QUERY_CHECK_NULL(pResult, code, line, _return, terrno);
×
1467
      }
1468
    }
1469
  }
1470
  rsp.numOfRefs = taosArrayGetSize(rsp.pEntries);
745,853 ✔
1471
  rsp.numOfFilterConds = taosArrayGetSize(rsp.pFilterConds);
745,853 ✔
1472

1473
  rspSize = tSerializeSVTagCondRsp(NULL, 0, &rsp);
745,853 ✔
1474
  if (rspSize < 0) {
745,853 ✔
1475
    code = rspSize;
×
1476
    qError("tSerializeSVTagCondRsp failed, error:%d", rspSize);
×
1477
    goto _return;
×
1478
  }
1479
  if (direct) {
745,853 ✔
1480
    pRsp = rpcMallocCont(rspSize);
745,853 ✔
1481
  } else {
1482
    pRsp = taosMemoryCalloc(1, rspSize);
×
1483
  }
1484
  QUERY_CHECK_NULL(pRsp, code, line, _return, terrno);
745,853 ✔
1485
  rspSize = tSerializeSVTagCondRsp(pRsp, rspSize, &rsp);
745,853 ✔
1486
  if (rspSize < 0) {
745,853 ✔
1487
    code = rspSize;
×
1488
    qError("tSerializeSVTagCondRsp failed, error:%d", rspSize);
×
1489
    goto _return;
×
1490
  }
1491

1492
_return:
745,853 ✔
1493
  metaReaderClear(&mer);
745,853 ✔
1494
  rspMsg.info = pMsg->info;
745,853 ✔
1495
  rspMsg.pCont = pRsp;
745,853 ✔
1496
  rspMsg.contLen = (code == 0) ? rspSize : 0;
745,853 ✔
1497
  rspMsg.code = code;
745,853 ✔
1498
  rspMsg.msgType = pMsg->msgType;
745,853 ✔
1499
  if (code) {
745,853 ✔
1500
    qError("%s failed at line %d since %s", __func__, line, tstrerror(code));
×
1501
  }
1502
  if (direct) {
745,853 ✔
1503
    tmsgSendRsp(&rspMsg);
745,853 ✔
1504
  } else {
1505
    *pMsg = rspMsg;
×
1506
  }
1507
  tDestroySVTagCondRsp(&rsp);
745,853 ✔
1508
  return code;
745,853 ✔
1509
}
1510

1511
static int32_t vnodeGetCompStorage(SVnode *pVnode, int64_t *output) {
69,292,642 ✔
1512
  int32_t code = 0;
69,292,642 ✔
1513
#ifdef TD_ENTERPRISE
1514
  int32_t now = taosGetTimestampSec();
69,292,642 ✔
1515
  if (llabs(now - pVnode->config.vndStats.storageLastUpd) >= 30) {
69,292,642 ✔
1516
    pVnode->config.vndStats.storageLastUpd = now;
3,652,349 ✔
1517

1518
    SDbSizeStatisInfo info = {0};
3,652,349 ✔
1519
    if (0 == (code = vnodeGetDBSize(pVnode, &info))) {
3,652,349 ✔
1520
      int64_t compSize =
3,652,349 ✔
1521
          info.l1Size + info.l2Size + info.l3Size + info.cacheSize + info.walSize + info.metaSize + +info.ssSize;
3,652,349 ✔
1522
      if (compSize >= 0) {
3,652,349 ✔
1523
        pVnode->config.vndStats.compStorage = compSize;
3,652,349 ✔
1524
      } else {
1525
        vError("vnode get comp storage failed since compSize is negative:%" PRIi64, compSize);
×
1526
        code = TSDB_CODE_APP_ERROR;
×
1527
      }
1528
    } else {
1529
      vWarn("vnode get comp storage failed since %s", tstrerror(code));
1,157 ✔
1530
    }
1531
  }
1532
  if (output) *output = pVnode->config.vndStats.compStorage;
69,292,642 ✔
1533
#endif
1534
  return code;
69,292,642 ✔
1535
}
1536

1537
static void vnodeGetBufferInfo(SVnode *pVnode, int64_t *bufferSegmentUsed, int64_t *bufferSegmentSize) {
69,292,642 ✔
1538
  *bufferSegmentUsed = 0;
69,292,642 ✔
1539
  *bufferSegmentSize = 0;
69,292,642 ✔
1540
  if (pVnode) {
69,292,642 ✔
1541
    (void)taosThreadMutexLock(&pVnode->mutex);
69,292,642 ✔
1542

1543
    if (pVnode->inUse) {
69,292,642 ✔
1544
      *bufferSegmentUsed = pVnode->inUse->size;
69,269,492 ✔
1545
    }
1546
    *bufferSegmentSize = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
69,292,642 ✔
1547

1548
    (void)taosThreadMutexUnlock(&pVnode->mutex);
69,292,642 ✔
1549
  }
1550
}
69,292,642 ✔
1551

1552
int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) {
69,292,642 ✔
1553
  SSyncState state = syncGetState(pVnode->sync);
69,292,642 ✔
1554
  pLoad->syncAppliedIndex = pVnode->state.applied;
69,292,642 ✔
1555
  syncGetCommitIndex(pVnode->sync, &pLoad->syncCommitIndex);
69,292,642 ✔
1556

1557
  pLoad->vgId = TD_VID(pVnode);
69,292,642 ✔
1558
  pLoad->syncState = state.state;
69,292,642 ✔
1559
  pLoad->syncRestore = state.restored;
69,292,642 ✔
1560
  pLoad->syncTerm = state.term;
69,292,642 ✔
1561
  pLoad->roleTimeMs = state.roleTimeMs;
69,292,642 ✔
1562
  pLoad->startTimeMs = state.startTimeMs;
69,292,642 ✔
1563
  pLoad->syncCanRead = state.canRead;
69,292,642 ✔
1564
  pLoad->cacheUsage = tsdbCacheGetUsage(pVnode);
69,292,642 ✔
1565
  pLoad->numOfCachedTables = tsdbCacheGetElems(pVnode);
69,292,642 ✔
1566
  VNODE_DO_META_QUERY(pVnode, pLoad->numOfTables = metaGetTbNum(pVnode->pMeta));
69,292,642 ✔
1567
  VNODE_DO_META_QUERY(pVnode, pLoad->numOfTimeSeries = metaGetTimeSeriesNum(pVnode->pMeta, 1));
69,292,642 ✔
1568
  pLoad->totalStorage = (int64_t)3 * 1073741824;  // TODO
69,292,642 ✔
1569
  (void)vnodeGetCompStorage(pVnode, &pLoad->compStorage);
69,292,642 ✔
1570
  pLoad->pointsWritten = 100;
69,292,642 ✔
1571
  pLoad->numOfSelectReqs = 1;
69,292,642 ✔
1572
  pLoad->numOfInsertReqs = atomic_load_64(&pVnode->statis.nInsert);
69,292,642 ✔
1573
  pLoad->numOfInsertSuccessReqs = atomic_load_64(&pVnode->statis.nInsertSuccess);
69,292,642 ✔
1574
  pLoad->numOfBatchInsertReqs = atomic_load_64(&pVnode->statis.nBatchInsert);
69,292,642 ✔
1575
  pLoad->numOfBatchInsertSuccessReqs = atomic_load_64(&pVnode->statis.nBatchInsertSuccess);
69,292,642 ✔
1576
  vnodeGetBufferInfo(pVnode, &pLoad->bufferSegmentUsed, &pLoad->bufferSegmentSize);
69,292,642 ✔
1577
  vDebug("vgId:%d, get vnode load, state:%s snapSeq:%d, learnerProgress:%d, totalIndex:%" PRId64, TD_VID(pVnode),
69,292,642 ✔
1578
         syncStr(state.state), state.snapSeq, state.progress, state.totalIndex);
1579
  pLoad->learnerProgress = state.progress;
69,292,642 ✔
1580
  pLoad->snapSeq = state.snapSeq;
69,292,642 ✔
1581
  pLoad->syncTotalIndex = state.totalIndex;
69,292,642 ✔
1582
  pLoad->snapshotSending = syncSnapshotSending(pVnode->sync) ? 1 : 0;
69,292,642 ✔
1583
  // Report per-target snapshot-send progress, so the mnode can display progress and compute the rate per target follower dnodeId.
1584
  // Fetch the byte summary grouped by destDnodeId from tsdb, and convert each entry into an SVnodeSnapProgress filled into pLoad->pSnapProgress.
1585
  pLoad->pSnapProgress = NULL;
69,292,642 ✔
1586
  SArray *pSnapGroups = taosArrayInit(4, sizeof(STsdbSnapSendGroup));
69,292,642 ✔
1587
  if (pSnapGroups != NULL) {
69,292,642 ✔
1588
    tsdbGetSnapSendSummary(pVnode->pTsdb, pSnapGroups);
69,292,642 ✔
1589
    int32_t numGroups = (int32_t)taosArrayGetSize(pSnapGroups);
69,292,642 ✔
1590
    if (numGroups > 0) {
69,292,642 ✔
1591
      pLoad->pSnapProgress = taosArrayInit(numGroups, sizeof(SVnodeSnapProgress));
4,611 ✔
1592
      if (pLoad->pSnapProgress != NULL) {
4,611 ✔
1593
        for (int32_t g = 0; g < numGroups; g++) {
9,222 ✔
1594
          STsdbSnapSendGroup *pGroup = (STsdbSnapSendGroup *)taosArrayGet(pSnapGroups, g);
4,611 ✔
1595
          if (pGroup == NULL) continue;
4,611 ✔
1596
          SVnodeSnapProgress prog = {.destDnodeId = pGroup->destDnodeId,
4,611 ✔
1597
                                     .snapTotalSize = pGroup->total,
4,611 ✔
1598
                                     .snapTransferredSize = pGroup->transferred};
4,611 ✔
1599
          if (taosArrayPush(pLoad->pSnapProgress, &prog) == NULL) {
9,222 ✔
1600
            vError("vgId:%d, failed to push snap progress for destDnodeId:%d", TD_VID(pVnode), pGroup->destDnodeId);
×
1601
          }
1602
        }
1603
        vDebug("vgId:%d, report snap send progress, numGroups:%d", TD_VID(pVnode), numGroups);
4,611 ✔
1604
      } else {
1605
        vError("vgId:%d, failed to alloc pSnapProgress array for vnode load", TD_VID(pVnode));
×
1606
      }
1607
    }
1608
    taosArrayDestroy(pSnapGroups);
69,292,642 ✔
1609
  } else {
1610
    vError("vgId:%d, failed to alloc snap send groups array for vnode load", TD_VID(pVnode));
×
1611
  }
1612
  return 0;
69,292,642 ✔
1613
}
1614

1615
int32_t vnodeGetLoadLite(SVnode *pVnode, SVnodeLoadLite *pLoad) {
×
1616
  SSyncState syncState = syncGetState(pVnode->sync);
×
1617
  if (syncState.state == TAOS_SYNC_STATE_LEADER || syncState.state == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
×
1618
    pLoad->vgId = TD_VID(pVnode);
×
1619
    pLoad->nTimeSeries = metaGetTimeSeriesNum(pVnode->pMeta, 1);
×
1620
    return 0;
×
1621
  }
1622
  return -1;
×
1623
}
1624
/**
1625
 * @brief Reset the statistics value by monitor interval
1626
 *
1627
 * @param pVnode
1628
 * @param pLoad
1629
 */
1630
void vnodeResetLoad(SVnode *pVnode, SVnodeLoad *pLoad) {
322 ✔
1631
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nInsert, pLoad->numOfInsertReqs, 64, "nInsert");
322 ✔
1632
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nInsertSuccess, pLoad->numOfInsertSuccessReqs, 64, "nInsertSuccess");
322 ✔
1633
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nBatchInsert, pLoad->numOfBatchInsertReqs, 64, "nBatchInsert");
322 ✔
1634
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nBatchInsertSuccess, pLoad->numOfBatchInsertSuccessReqs, 64,
322 ✔
1635
                            "nBatchInsertSuccess");
1636
}
322 ✔
1637

1638
void vnodeGetInfo(void *pVnode, const char **dbname, int32_t *vgId, SVnodeTableNums *pNums) {
31,371,257 ✔
1639
  SVnode    *pVnodeObj = pVnode;
31,371,257 ✔
1640
  SVnodeCfg *pConf = &pVnodeObj->config;
31,371,257 ✔
1641

1642
  if (dbname) {
31,371,257 ✔
1643
    *dbname = pConf->dbname;
31,251,309 ✔
1644
  }
1645

1646
  if (vgId) {
31,371,257 ✔
1647
    *vgId = TD_VID(pVnodeObj);
30,511,552 ✔
1648
  }
1649

1650
  if (pNums) {
31,371,257 ✔
1651
    pNums->ntb = pConf->vndStats.numOfNTables;
8,379 ✔
1652
    pNums->ctb = pConf->vndStats.numOfCTables;
8,379 ✔
1653
    pNums->vtb = pConf->vndStats.numOfVTables;
8,379 ✔
1654
    pNums->vctb = pConf->vndStats.numOfVCTables;
8,379 ✔
1655
  }
1656
}
31,371,257 ✔
1657

1658
int8_t vnodeGetSecurityLevel(void *pVnode) {
581,928 ✔
1659
  SVnode *pVnodeObj = pVnode;
581,928 ✔
1660
  return pVnodeObj->config.securityLevel;
581,928 ✔
1661
}
1662

1663
// Same ownership rule as vnodeValidateTableHash, but takes the bare table name
1664
// and returns a bool instead of raising TSDB_CODE_VND_HASH_MISMATCH, so scans
1665
// can cheaply skip names this vnode cannot own. Mount-prefix trimming mirrors
1666
// the create/lookup paths (metaFilterTableByHash, vnodeGetTableInfo).
1667
bool vnodeTbNameInHashRange(void *pVnode, const char *tbName) {
130,126 ✔
1668
  SVnode *pVnodeObj = pVnode;
130,126 ✔
1669
  char    tbFName[TSDB_TABLE_FNAME_LEN + 1];
130,126 ✔
1670
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", pVnodeObj->config.dbname, tbName);
130,126 ✔
1671
  tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
130,126 ✔
1672
  if (pVnodeObj->mounted) tTrimMountPrefix(tbFName);
130,126 ✔
1673

1674
  uint32_t hashValue = taosGetTbHashVal(tbFName, (int32_t)strlen(tbFName), pVnodeObj->config.hashMethod,
260,426 ✔
1675
                                        pVnodeObj->config.hashPrefix, pVnodeObj->config.hashSuffix);
130,126 ✔
1676
  return hashValue >= pVnodeObj->config.hashBegin && hashValue <= pVnodeObj->config.hashEnd;
130,300 ✔
1677
}
1678

1679
int8_t vnodeGetTsdbPrecision(void *pVnode) {
11,264,818 ✔
1680
  SVnode *pVnodeObj = pVnode;
11,264,818 ✔
1681
  return pVnodeObj->config.tsdbCfg.precision;
11,264,818 ✔
1682
}
1683

1684
bool vnodeHasPendingTxnEntries(void *pVnode) {
×
1685
  SVnode *pVnodeObj = pVnode;
×
1686
  return metaHasPendingTxnEntries(pVnodeObj->pMeta);
×
1687
}
1688

1689
int32_t vnodeGetTableList(void *pVnode, int8_t type, SArray *pList) {
3,159 ✔
1690
  if (type == TSDB_SUPER_TABLE) {
3,159 ✔
1691
    return vnodeGetStbIdList(pVnode, 0, pList);
3,159 ✔
1692
  } else {
1693
    return TSDB_CODE_INVALID_PARA;
×
1694
  }
1695
}
1696

1697
int32_t vnodeGetAllTableList(SVnode *pVnode, uint64_t uid, SArray *list) {
×
1698
  int32_t      code = TSDB_CODE_SUCCESS;
×
1699
  SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, uid, 1, 0);
×
1700
  if (NULL == pCur) {
×
1701
    qError("vnode get all table list failed");
×
1702
    return terrno;
×
1703
  }
1704

1705
  while (1) {
×
1706
    tb_uid_t id = metaCtbCursorNext(pCur);
×
1707
    if (id == 0) {
×
1708
      break;
×
1709
    }
1710

1711
    STableKeyInfo info = {uid = id};
×
1712
    if (NULL == taosArrayPush(list, &info)) {
×
1713
      qError("taosArrayPush failed");
×
1714
      code = terrno;
×
1715
      goto _exit;
×
1716
    }
1717
  }
1718
_exit:
×
1719
  metaCloseCtbCursor(pCur);
×
1720
  return code;
×
1721
}
1722

1723
int32_t vnodeGetCtbIdListByFilter(SVnode *pVnode, int64_t suid, SArray *list, bool (*filter)(void *arg), void *arg) {
×
1724
  return 0;
×
1725
}
1726

1727
int32_t vnodeGetCtbIdList(void *pVnode, int64_t suid, SArray *list) {
93,050,694 ✔
1728
  int32_t      code = TSDB_CODE_SUCCESS;
93,050,694 ✔
1729
  SVnode      *pVnodeObj = pVnode;
93,050,694 ✔
1730
  SMCtbCursor *pCur = metaOpenCtbCursor(pVnodeObj, suid, 1, 0);
93,050,694 ✔
1731
  if (NULL == pCur) {
93,012,632 ✔
1732
    qError("vnode get ctb id list failed, suid:%" PRId64, suid);
×
1733
    return terrno;
×
1734
  }
1735

1736
  while (1) {
341,792,678 ✔
1737
    tb_uid_t id = metaCtbCursorNext(pCur);
434,805,310 ✔
1738
    if (id == 0) {
434,579,492 ✔
1739
      break;
92,993,349 ✔
1740
    }
1741
    qTrace("vnodeGetCtbIdList: got ctb id %" PRId64 " for suid %" PRId64, id, suid);
341,508,263 ✔
1742
    if (NULL == taosArrayPush(list, &id)) {
341,653,692 ✔
1743
      qError("taosArrayPush failed");
×
1744
      code = terrno;
×
1745
      goto _exit;
×
1746
    }
1747
  }
1748

1749
_exit:
92,890,215 ✔
1750
  metaCloseCtbCursor(pCur);
92,890,215 ✔
1751
  return code;
93,019,934 ✔
1752
}
1753

1754
int32_t vnodeGetStbIdList(SVnode *pVnode, int64_t suid, SArray *list) {
48,061,827 ✔
1755
  int32_t      code = TSDB_CODE_SUCCESS;
48,061,827 ✔
1756
  SMStbCursor *pCur = metaOpenStbCursor(pVnode->pMeta, suid);
48,061,827 ✔
1757
  if (!pCur) {
48,062,523 ✔
1758
    return TSDB_CODE_OUT_OF_MEMORY;
×
1759
  }
1760

1761
  while (1) {
18,039,332 ✔
1762
    tb_uid_t id = metaStbCursorNext(pCur);
66,101,855 ✔
1763
    if (id == 0) {
66,104,639 ✔
1764
      break;
48,041,184 ✔
1765
    }
1766

1767
    if (NULL == taosArrayPush(list, &id)) {
18,040,360 ✔
1768
      qError("taosArrayPush failed");
×
1769
      code = terrno;
×
1770
      goto _exit;
×
1771
    }
1772
  }
1773

1774
_exit:
48,062,159 ✔
1775
  metaCloseStbCursor(pCur);
48,062,159 ✔
1776
  return code;
48,062,068 ✔
1777
}
1778

1779
int32_t vnodeGetStbIdListByFilter(SVnode *pVnode, int64_t suid, SArray *list, bool (*filter)(void *arg, void *arg1),
1,578 ✔
1780
                                  void *arg) {
1781
  int32_t      code = TSDB_CODE_SUCCESS;
1,578 ✔
1782
  SMStbCursor *pCur = metaOpenStbCursor(pVnode->pMeta, suid);
1,578 ✔
1783
  if (!pCur) {
1,578 ✔
1784
    return terrno;
×
1785
  }
1786

1787
  while (1) {
2,205 ✔
1788
    tb_uid_t id = metaStbCursorNext(pCur);
3,636 ✔
1789
    if (id == 0) {
3,636 ✔
1790
      break;
1,431 ✔
1791
    }
1792

1793
    if ((*filter) && (*filter)(arg, &id)) {
2,058 ✔
1794
      continue;
2,058 ✔
1795
    }
1796

1797
    if (NULL == taosArrayPush(list, &id)) {
×
1798
      qError("taosArrayPush failed");
×
1799
      code = terrno;
×
1800
      goto _exit;
×
1801
    }
1802
  }
1803

1804
_exit:
1,578 ✔
1805
  metaCloseStbCursor(pCur);
1,578 ✔
1806
  return code;
1,578 ✔
1807
}
1808

1809
int32_t vnodeGetCtbNum(SVnode *pVnode, int64_t suid, int64_t *num) {
1,839,906 ✔
1810
  SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, suid, 0, 0);
1,839,906 ✔
1811
  if (!pCur) {
1,840,001 ✔
1812
    return terrno;
×
1813
  }
1814

1815
  *num = 0;
1,840,064 ✔
1816
  while (1) {
1,255,613 ✔
1817
    tb_uid_t id = metaCtbCursorNext(pCur);
3,094,376 ✔
1818
    if (id == 0) {
3,094,606 ✔
1819
      break;
1,839,922 ✔
1820
    }
1821

1822
    ++(*num);
1,254,312 ✔
1823
  }
1824

1825
  metaCloseCtbCursor(pCur);
1,840,294 ✔
1826
  return TSDB_CODE_SUCCESS;
1,840,233 ✔
1827
}
1828

1829
int32_t vnodeGetStbColumnNum(SVnode *pVnode, tb_uid_t suid, int *num) {
1,840,030 ✔
1830
  SSchemaWrapper *pSW = metaGetTableSchema(pVnode->pMeta, suid, -1, 0, NULL, 0, false);
1,840,030 ✔
1831
  if (pSW) {
1,840,401 ✔
1832
    *num = pSW->nCols;
1,837,073 ✔
1833
    tDeleteSchemaWrapper(pSW);
744 ✔
1834
  } else {
1835
    *num = 2;
3,328 ✔
1836
  }
1837

1838
  return TSDB_CODE_SUCCESS;
1,840,401 ✔
1839
}
1840

1841
int32_t vnodeGetStbInfo(SVnode *pVnode, tb_uid_t suid, int64_t *keep, int8_t *flags) {
1,840,306 ✔
1842
  SMetaReader mr = {0};
1,840,306 ✔
1843
  metaReaderDoInit(&mr, pVnode->pMeta, META_READER_NOLOCK, 0);
1,840,401 ✔
1844

1845
  int32_t code = metaReaderGetTableEntryByUid(&mr, suid);
1,840,293 ✔
1846
  if (code == TSDB_CODE_SUCCESS) {
1,840,401 ✔
1847
    if (keep) *keep = mr.me.stbEntry.keep;
1,837,073 ✔
1848
    if (flags) *flags = mr.me.flags;
1,837,073 ✔
1849
  } else {
1850
    if (keep) *keep = 0;
3,328 ✔
1851
    if (flags) *flags = 0;
3,328 ✔
1852
  }
1853

1854
  metaReaderClear(&mr);
1,840,401 ✔
1855
  return TSDB_CODE_SUCCESS;
1,840,401 ✔
1856
}
1857

1858
#ifdef TD_ENTERPRISE
1859
const char *tkLogStb[] = {"cluster_info",
1860
                          "data_dir",
1861
                          "disk_free",
1862
                          "disk_total",
1863
                          "dnodes_info",
1864
                          "d_info",
1865
                          "explorer_sys",
1866
                          "grants_info",
1867
                          "keeper_monitor",
1868
                          "logs",
1869
                          "log_dir",
1870
                          "log_summary",
1871
                          "http_client_requests",
1872
                          "http_server_requests_idmp",
1873
                          "m_info",
1874
                          "taosadapter_restful_http_request_fail",
1875
                          "taosadapter_restful_http_request_in_flight",
1876
                          "taosadapter_restful_http_request_summary_milliseconds",
1877
                          "taosadapter_restful_http_request_total",
1878
                          "taosadapter_system_cpu_percent",
1879
                          "taosadapter_system_mem_percent",
1880
                          "temp_dir",
1881
                          "vgroups_info",
1882
                          "vnodes_role",
1883
                          "taosd_dnodes_status",
1884
                          "adapter_conn_pool",
1885
                          "taosd_vnodes_info",
1886
                          "taosd_dnodes_metrics",
1887
                          "taosd_vgroups_info",
1888
                          "taos_sql_req",
1889
                          "taosd_mnodes_info",
1890
                          "adapter_c_interface",
1891
                          "taosd_cluster_info",
1892
                          "taosd_sql_req",
1893
                          "taosd_dnodes_info",
1894
                          "adapter_requests",
1895
                          "taosd_write_metrics",
1896
                          "adapter_status",
1897
                          "taos_slow_sql",
1898
                          "taos_slow_sql_detail",
1899
                          "taosd_cluster_basic",
1900
                          "taosd_dnodes_data_dirs",
1901
                          "taosd_dnodes_log_dirs",
1902
                          "xnode_agent_activities",
1903
                          "xnode_task_activities",
1904
                          "xnode_task_metrics",
1905
                          "taosx_sys",
1906
                          "taosx_task_csv",
1907
                          "taosx_task_progress",
1908
                          "taosx_task_kinghist",
1909
                          "taosx_task_tdengine2",
1910
                          "taosx_task_tdengine3",
1911
                          "taosx_task_opc_da",
1912
                          "taosx_task_opc_ua",
1913
                          "taosx_task_kafka",
1914
                          "taosx_task_influxdb",
1915
                          "taosx_task_mqtt",
1916
                          "taosx_task_avevahistorian",
1917
                          "taosx_task_opentsdb",
1918
                          "taosx_task_mysql",
1919
                          "taosx_task_postgres",
1920
                          "taosx_task_oracle",
1921
                          "taosx_task_mssql",
1922
                          "taosx_task_mongodb",
1923
                          "taosx_task_sparkplugb",
1924
                          "taosx_task_orc",
1925
                          "taosx_task_pulsar",
1926
                          "taosx_task_pspace"};
1927
const char *tkAuditStb[] = {"operations"};
1928
const int   tkLogStbNum = ARRAY_SIZE(tkLogStb);
1929
const int   tkAuditStbNum = ARRAY_SIZE(tkAuditStb);
1930

1931
// exclude stbs of taoskeeper log
1932
static int32_t vnodeGetTimeSeriesBlackList(SVnode *pVnode, int32_t *tbSize) {
48,061,162 ✔
1933
  int32_t      code = TSDB_CODE_SUCCESS;
48,061,162 ✔
1934
  int32_t      tbNum = 0;
48,061,162 ✔
1935
  const char **pTbArr = NULL;
48,061,162 ✔
1936
  const char  *dbName = NULL;
48,061,162 ✔
1937
  *tbSize = 0;
48,061,162 ✔
1938

1939
  if (!(dbName = strchr(pVnode->config.dbname, '.'))) return 0;
48,061,162 ✔
1940
  if (0 == strncmp(++dbName, "log", TSDB_DB_NAME_LEN)) {
48,061,162 ✔
1941
    tbNum = tkLogStbNum;
2,880 ✔
1942
    pTbArr = (const char **)&tkLogStb;
2,880 ✔
1943
  } else if (0 == strncmp(dbName, "audit", TSDB_DB_NAME_LEN) || pVnode->config.isAudit) {
48,058,282 ✔
1944
    tbNum = tkAuditStbNum;
1,834 ✔
1945
    pTbArr = (const char **)&tkAuditStb;
1,834 ✔
1946
  }
1947
  if (tbNum && pTbArr) {
48,061,162 ✔
1948
    *tbSize = metaSizeOfTbFilterCache(pVnode->pMeta, 0);
4,714 ✔
1949
    if (*tbSize < tbNum) {
4,714 ✔
1950
      for (int32_t i = 0; i < tbNum; ++i) {
142,424 ✔
1951
        tb_uid_t suid = metaGetTableEntryUidByName(pVnode->pMeta, pTbArr[i]);
140,152 ✔
1952
        if (suid != 0) {
140,152 ✔
1953
          code = metaPutTbToFilterCache(pVnode->pMeta, &suid, 0);
1,776 ✔
1954
          if (TSDB_CODE_SUCCESS != code) {
1,776 ✔
1955
            return code;
1,080 ✔
1956
          }
1957
        }
1958
      }
1959
      *tbSize = metaSizeOfTbFilterCache(pVnode->pMeta, 0);
2,272 ✔
1960
    }
1961
  }
1962

1963
  return code;
48,037,628 ✔
1964
}
1965
#endif
1966

1967
static bool vnodeTimeSeriesFilter(void *arg1, void *arg2) {
2,058 ✔
1968
  SVnode *pVnode = (SVnode *)arg1;
2,058 ✔
1969

1970
  if (metaTbInFilterCache(pVnode->pMeta, arg2, 0)) {
2,058 ✔
1971
    return true;
1,911 ✔
1972
  }
1973
  return false;
×
1974
}
1975

1976
int32_t vnodeGetTimeSeriesNum(SVnode *pVnode, int64_t *num) {
48,060,738 ✔
1977
  SArray *suidList = NULL;
48,060,738 ✔
1978

1979
  if (!(suidList = taosArrayInit(1, sizeof(tb_uid_t)))) {
48,060,738 ✔
1980
    return terrno;
×
1981
  }
1982

1983
  int32_t tbFilterSize = 0;
48,062,494 ✔
1984
  int32_t code = TSDB_CODE_SUCCESS;
48,061,374 ✔
1985
#ifdef TD_ENTERPRISE
1986
  code = vnodeGetTimeSeriesBlackList(pVnode, &tbFilterSize);
48,061,374 ✔
1987
  if (TSDB_CODE_SUCCESS != code) {
48,062,766 ✔
1988
    goto _exit;
1,080 ✔
1989
  }
1990
#endif
1991

1992
  if ((!tbFilterSize && vnodeGetStbIdList(pVnode, 0, suidList) < 0) ||
48,061,686 ✔
1993
      (tbFilterSize && vnodeGetStbIdListByFilter(pVnode, 0, suidList, vnodeTimeSeriesFilter, pVnode) < 0)) {
48,037,987 ✔
1994
    qError("vgId:%d, failed to get stb id list error: %s", TD_VID(pVnode), terrstr());
×
1995
    taosArrayDestroy(suidList);
×
1996
    return terrno;
×
1997
  }
1998

1999
  *num = 0;
48,061,234 ✔
2000
  int64_t arrSize = taosArrayGetSize(suidList);
48,061,234 ✔
2001
  for (int64_t i = 0; i < arrSize; ++i) {
66,097,202 ✔
2002
    tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i);
18,034,728 ✔
2003

2004
    int64_t ctbNum = 0;
18,034,304 ✔
2005
    int32_t numOfCols = 0;
18,036,544 ✔
2006
    int8_t  flags = 0;
18,036,756 ✔
2007
    code = metaGetStbStats(pVnode, suid, &ctbNum, &numOfCols, &flags);
18,036,332 ✔
2008
    if (TSDB_CODE_SUCCESS != code) {
18,037,180 ✔
2009
      goto _exit;
×
2010
    }
2011
    if (!TABLE_IS_VIRTUAL(flags)) {
18,037,180 ✔
2012
      *num += ctbNum * (numOfCols - 1);
14,228,242 ✔
2013
    }
2014
  }
2015

2016
_exit:
48,063,554 ✔
2017
  taosArrayDestroy(suidList);
48,062,826 ✔
2018
  return TSDB_CODE_SUCCESS;
48,062,614 ✔
2019
}
2020

2021
int32_t vnodeGetAllCtbNum(SVnode *pVnode, int64_t *num) {
×
2022
  SMStbCursor *pCur = metaOpenStbCursor(pVnode->pMeta, 0);
×
2023
  if (!pCur) {
×
2024
    return terrno;
×
2025
  }
2026

2027
  *num = 0;
×
2028
  while (1) {
×
2029
    tb_uid_t id = metaStbCursorNext(pCur);
×
2030
    if (id == 0) {
×
2031
      break;
×
2032
    }
2033

2034
    int64_t ctbNum = 0;
×
2035
    int32_t code = vnodeGetCtbNum(pVnode, id, &ctbNum);
×
2036
    if (TSDB_CODE_SUCCESS != code) {
×
2037
      metaCloseStbCursor(pCur);
×
2038
      return code;
×
2039
    }
2040

2041
    *num += ctbNum;
×
2042
  }
2043

2044
  metaCloseStbCursor(pCur);
×
2045
  return TSDB_CODE_SUCCESS;
×
2046
}
2047

2048
void *vnodeGetIdx(void *pVnode) {
1,511,862 ✔
2049
  if (pVnode == NULL) {
1,511,862 ✔
2050
    return NULL;
×
2051
  }
2052

2053
  return metaGetIdx(((SVnode *)pVnode)->pMeta);
1,511,862 ✔
2054
}
2055

2056
void *vnodeGetIvtIdx(void *pVnode) {
1,511,743 ✔
2057
  if (pVnode == NULL) {
1,511,743 ✔
2058
    return NULL;
×
2059
  }
2060
  return metaGetIvtIdx(((SVnode *)pVnode)->pMeta);
1,511,743 ✔
2061
}
2062

2063
int32_t vnodeGetTableSchema(void *pVnode, int64_t uid, STSchema **pSchema, int64_t *suid, SSchemaWrapper **pTagSchema) {
454,459 ✔
2064
  return tsdbGetTableSchema(((SVnode *)pVnode)->pMeta, uid, pSchema, suid, pTagSchema);
454,459 ✔
2065
}
2066

2067
static FORCE_INLINE int32_t vnodeGetDBPrimaryInfo(SVnode *pVnode, SDbSizeStatisInfo *pInfo) {
1,157 ✔
2068
  int32_t code = 0;
3,654,611 ✔
2069
  char    path[TSDB_FILENAME_LEN] = {0};
3,654,611 ✔
2070

2071
  char   *dirName[] = {VNODE_TSDB_DIR, VNODE_WAL_DIR, VNODE_META_DIR, VNODE_TSDB_CACHE_DIR};
3,654,611 ✔
2072
  int64_t dirSize[4];
3,654,611 ✔
2073

2074
  vnodeGetPrimaryPath(pVnode, false, path, TSDB_FILENAME_LEN);
3,654,611 ✔
2075
  int32_t offset = strlen(path);
3,654,611 ✔
2076

2077
  for (int i = 0; i < sizeof(dirName) / sizeof(dirName[0]); i++) {
18,273,055 ✔
2078
    int64_t size = {0};
14,618,444 ✔
2079
    (void)snprintf(path + offset, TSDB_FILENAME_LEN - offset, "%s%s", TD_DIRSEP, dirName[i]);
14,618,444 ✔
2080
    code = taosGetDirSize(path, &size);
14,618,444 ✔
2081
    if (code != 0) {
14,618,444 ✔
2082
      uWarn("vnode %d get dir %s %s size failed since %s", TD_VID(pVnode), path, dirName[i], tstrerror(code));
568 ✔
2083
    }
2084
    path[offset] = 0;
14,618,444 ✔
2085
    dirSize[i] = size;
14,618,444 ✔
2086
  }
2087

2088
  pInfo->l1Size = 0;
3,654,611 ✔
2089
  pInfo->walSize = dirSize[1];
3,654,611 ✔
2090
  pInfo->metaSize = dirSize[2];
3,654,611 ✔
2091
  pInfo->cacheSize = dirSize[3];
3,654,611 ✔
2092
  return code;
3,654,611 ✔
2093
}
2094
int32_t vnodeGetDBSize(void *pVnode, SDbSizeStatisInfo *pInfo) {
3,654,611 ✔
2095
  int32_t code = 0;
3,654,611 ✔
2096
  int32_t lino = 0;
3,654,611 ✔
2097
  SVnode *pVnodeObj = pVnode;
3,654,611 ✔
2098
  if (pVnodeObj == NULL) {
3,654,611 ✔
2099
    return TSDB_CODE_VND_NOT_EXIST;
×
2100
  }
2101
  code = vnodeGetDBPrimaryInfo(pVnode, pInfo);
3,654,611 ✔
2102
  if (code != 0) goto _exit;
3,654,611 ✔
2103

2104
  code = tsdbGetFsSize(pVnodeObj->pTsdb, pInfo);
3,654,611 ✔
2105
_exit:
3,653,454 ✔
2106
  return code;
3,653,454 ✔
2107
}
2108

2109
int32_t vnodeGetLastCacheStats(void *pVnode, SLastCacheStats *pStats) {
×
2110
  SVnode *pVnodeObj = pVnode;
×
2111
  if (pVnodeObj == NULL || pVnodeObj->pTsdb == NULL) {
×
2112
    return TSDB_CODE_INVALID_PARA;
×
2113
  }
2114

2115
  int32_t code = tsdbGetLastCacheStats(pVnodeObj->pTsdb, pStats);
×
2116
  if (code == 0) {
×
2117
    pStats->dnodeId = vnodeGetDnodeId();
×
2118
  }
2119
  return code;
×
2120
}
2121

2122
/*
2123
 * Get raw write metrics for a vnode
2124
 */
2125
int32_t vnodeGetRawWriteMetrics(void *pVnode, SRawWriteMetrics *pRawMetrics) {
×
2126
  if (pVnode == NULL || pRawMetrics == NULL) {
×
2127
    return TSDB_CODE_INVALID_PARA;
×
2128
  }
2129

2130
  SVnode      *pVnode1 = (SVnode *)pVnode;
×
2131
  SSyncMetrics syncMetrics = syncGetMetrics(pVnode1->sync);
×
2132

2133
  // Copy values following SRawWriteMetrics structure order
2134
  pRawMetrics->total_requests = atomic_load_64(&pVnode1->writeMetrics.total_requests);
×
2135
  pRawMetrics->total_rows = atomic_load_64(&pVnode1->writeMetrics.total_rows);
×
2136
  pRawMetrics->total_bytes = atomic_load_64(&pVnode1->writeMetrics.total_bytes);
×
2137
  pRawMetrics->fetch_batch_meta_time = atomic_load_64(&pVnode1->writeMetrics.fetch_batch_meta_time);
×
2138
  pRawMetrics->fetch_batch_meta_count = atomic_load_64(&pVnode1->writeMetrics.fetch_batch_meta_count);
×
2139
  pRawMetrics->preprocess_time = atomic_load_64(&pVnode1->writeMetrics.preprocess_time);
×
2140
  pRawMetrics->wal_write_bytes = atomic_load_64(&syncMetrics.wal_write_bytes);
×
2141
  pRawMetrics->wal_write_time = atomic_load_64(&syncMetrics.wal_write_time);
×
2142
  pRawMetrics->apply_bytes = atomic_load_64(&pVnode1->writeMetrics.apply_bytes);
×
2143
  pRawMetrics->apply_time = atomic_load_64(&pVnode1->writeMetrics.apply_time);
×
2144
  pRawMetrics->commit_count = atomic_load_64(&pVnode1->writeMetrics.commit_count);
×
2145
  pRawMetrics->commit_time = atomic_load_64(&pVnode1->writeMetrics.commit_time);
×
2146
  pRawMetrics->memtable_wait_time = atomic_load_64(&pVnode1->writeMetrics.memtable_wait_time);
×
2147
  pRawMetrics->blocked_commit_count = atomic_load_64(&pVnode1->writeMetrics.blocked_commit_count);
×
2148
  pRawMetrics->blocked_commit_time = atomic_load_64(&pVnode1->writeMetrics.block_commit_time);
×
2149
  pRawMetrics->merge_count = atomic_load_64(&pVnode1->writeMetrics.merge_count);
×
2150
  pRawMetrics->merge_time = atomic_load_64(&pVnode1->writeMetrics.merge_time);
×
2151
  pRawMetrics->last_cache_commit_time = atomic_load_64(&pVnode1->writeMetrics.last_cache_commit_time);
×
2152
  pRawMetrics->last_cache_commit_count = atomic_load_64(&pVnode1->writeMetrics.last_cache_commit_count);
×
2153

2154
  return 0;
×
2155
}
2156

2157
/*
2158
 * Reset raw write metrics for a vnode by subtracting old values
2159
 */
2160
int32_t vnodeResetRawWriteMetrics(void *pVnode, const SRawWriteMetrics *pOldMetrics) {
×
2161
  if (pVnode == NULL || pOldMetrics == NULL) {
×
2162
    return TSDB_CODE_INVALID_PARA;
×
2163
  }
2164

2165
  SVnode *pVnode1 = (SVnode *)pVnode;
×
2166

2167
  // Reset vnode write metrics using atomic operations to subtract old values
2168
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.total_requests, pOldMetrics->total_requests);
×
2169
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.total_rows, pOldMetrics->total_rows);
×
2170
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.total_bytes, pOldMetrics->total_bytes);
×
2171

2172
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.fetch_batch_meta_time, pOldMetrics->fetch_batch_meta_time);
×
2173
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.fetch_batch_meta_count, pOldMetrics->fetch_batch_meta_count);
×
2174
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.preprocess_time, pOldMetrics->preprocess_time);
×
2175
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.apply_bytes, pOldMetrics->apply_bytes);
×
2176
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.apply_time, pOldMetrics->apply_time);
×
2177
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.commit_count, pOldMetrics->commit_count);
×
2178

2179
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.commit_time, pOldMetrics->commit_time);
×
2180
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.merge_time, pOldMetrics->merge_time);
×
2181

2182
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.memtable_wait_time, pOldMetrics->memtable_wait_time);
×
2183
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.blocked_commit_count, pOldMetrics->blocked_commit_count);
×
2184
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.block_commit_time, pOldMetrics->blocked_commit_time);
×
2185
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.merge_count, pOldMetrics->merge_count);
×
2186

2187
  // Reset new cache metrics
2188
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.last_cache_commit_time, pOldMetrics->last_cache_commit_time);
×
2189
  (void)atomic_sub_fetch_64(&pVnode1->writeMetrics.last_cache_commit_count, pOldMetrics->last_cache_commit_count);
×
2190

2191
  // Reset sync metrics
2192
  SSyncMetrics syncMetrics = {
×
2193
      .wal_write_bytes = pOldMetrics->wal_write_bytes,
×
2194
      .wal_write_time = pOldMetrics->wal_write_time,
×
2195
  };
2196
  syncResetMetrics(pVnode1->sync, &syncMetrics);
×
2197

2198
  return 0;
×
2199
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc