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

taosdata / TDengine / #5136

05 Nov 2026 03:32AM UTC coverage: 74.371% (+0.1%) from 74.236%
#5136

push

travis-ci

jbjia
fix: capture coverage once from per-thread gcda

Per-case lcov walked the shared build tree and kept each case busy for minutes. Pass GCOV_PREFIX into the test container so each thread writes its own counters, then merge and capture after the suite.

375424 of 504798 relevant lines covered (74.37%)

4400193.13 hits per line

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

70.78
/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) {
15,469 ✔
32
  return qWorkerInit(NODE_TYPE_VNODE, TD_VID(pVnode), (void **)&pVnode->pQuery, &pVnode->msgCb);
15,469 ✔
33
}
34

35
void vnodeQueryPreClose(SVnode *pVnode) { qWorkerStopAllTasks((void *)pVnode->pQuery); }
15,468 ✔
36

37
void vnodeQueryClose(SVnode *pVnode) { qWorkerDestroy((void **)&pVnode->pQuery); }
15,549 ✔
38

39
int32_t fillTableColCmpr(SMetaReader *reader, SSchemaExt *pExt, int32_t numOfCol) {
431,754 ✔
40
  int8_t tblType = reader->me.type;
431,754 ✔
41
  if (withColCompress(tblType)) {
431,754 ✔
42
    SColCmprWrapper *p = &(reader->me.colCmpr);
347,625 ✔
43
    if (numOfCol != p->nCols) {
347,625 ✔
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++) {
3,775,296 ✔
48
      SColCmpr *pCmpr = &p->pColCmpr[i];
3,427,671 ✔
49
      pExt[i].colId = pCmpr->id;
3,427,671 ✔
50
      pExt[i].compress = pCmpr->alg;
3,427,671 ✔
51
    }
52
  }
53
  return 0;
426,258 ✔
54
}
55

56
void vnodeDebugTableMeta(STableMetaRsp *pMeta) {
177,885 ✔
57
  if (!(qDebugFlag & DEBUG_DEBUG)) {
177,885 ✔
58
    return;
110,633 ✔
59
  }
60

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

84
int32_t fillTableColRef(SMetaReader *reader, SColRef *pRef, int32_t numOfCol) {
83,434 ✔
85
  int32_t code = TSDB_CODE_SUCCESS;
83,434 ✔
86
  int32_t line = 0;
83,434 ✔
87
  int8_t tblType = reader->me.type;
83,434 ✔
88
  if (hasColRef(tblType)) {
83,434 ✔
89
    SColRefWrapper *p = &(reader->me.colRef);
83,434 ✔
90
    if (numOfCol != p->nCols) {
83,434 ✔
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++) {
1,364,493 ✔
96
      SColRef *pColRef = &p->pColRef[i];
1,281,059 ✔
97
      pRef[i].hasRef = pColRef->hasRef;
1,281,059 ✔
98
      pRef[i].id = pColRef->id;
1,281,059 ✔
99
      if (pRef[i].hasRef) {
1,281,059 ✔
100
        pRef[i].refType = pColRef->refType;
1,050,093 ✔
101
        tstrncpy(pRef[i].refSourceName, pColRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
1,050,093 ✔
102
        tstrncpy(pRef[i].refSchemaName, pColRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
1,050,093 ✔
103
        tstrncpy(pRef[i].refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
1,050,093 ✔
104
        tstrncpy(pRef[i].refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
1,050,093 ✔
105
        tstrncpy(pRef[i].refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
1,050,093 ✔
106
        if (pColRef->tagCondLen > 0 && pColRef->tagCondJson) {
1,050,093 ✔
107
          pRef[i].tagCondLen = pColRef->tagCondLen;
497 ✔
108
          pRef[i].tagCondJson = taosStrdup(pColRef->tagCondJson);
497 ✔
109
          QUERY_CHECK_NULL(pRef[i].tagCondJson, code, line, _return, terrno);
497 ✔
110
        } else {
111
          pRef[i].tagCondLen = 0;
1,049,596 ✔
112
          pRef[i].tagCondJson = NULL;
1,049,596 ✔
113
        }
114
        if (pColRef->filterCondLen > 0 && pColRef->filterCondJson) {
1,050,093 ✔
115
          pRef[i].filterCondLen = pColRef->filterCondLen;
595 ✔
116
          pRef[i].filterCondJson = taosStrdup(pColRef->filterCondJson);
595 ✔
117
          QUERY_CHECK_NULL(pRef[i].filterCondJson, code, line, _return, terrno);
595 ✔
118
        } else {
119
          pRef[i].filterCondLen = 0;
1,049,498 ✔
120
          pRef[i].filterCondJson = NULL;
1,049,498 ✔
121
        }
122
      }
123
    }
124
  }
125

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

133
int32_t fillTableTagRef(SMetaReader *reader, SColRef *pRef, int32_t numOfTagRefs) {
4,001 ✔
134
  int8_t tblType = reader->me.type;
4,001 ✔
135
  if (hasTagRef(tblType)) {
4,001 ✔
136
    SColRefWrapper *p = &(reader->me.colRef);
4,001 ✔
137
    if (numOfTagRefs != p->nTagRefs) {
4,001 ✔
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++) {
13,128 ✔
142
      SColRef *pTagRef = &p->pTagRef[i];
9,127 ✔
143
      pRef[i].hasRef = pTagRef->hasRef;
9,127 ✔
144
      pRef[i].id = pTagRef->id;
9,127 ✔
145
      if (pRef[i].hasRef) {
9,127 ✔
146
        tstrncpy(pRef[i].refDbName, pTagRef->refDbName, TSDB_DB_NAME_LEN);
7,141 ✔
147
        tstrncpy(pRef[i].refTableName, pTagRef->refTableName, TSDB_TABLE_NAME_LEN);
7,141 ✔
148
        tstrncpy(pRef[i].refColName, pTagRef->refColName, TSDB_COL_NAME_LEN);
7,141 ✔
149
      }
150
    }
151
  }
152
  return 0;
4,001 ✔
153
}
154

155
int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
269,469 ✔
156
  STableInfoReq  infoReq = {0};
269,469 ✔
157
  STableMetaRsp  metaRsp = {0};
269,469 ✔
158
  SMetaReader    mer1 = {0};
269,462 ✔
159
  SMetaReader    mer2 = {0};
269,460 ✔
160
  char           tableFName[TSDB_TABLE_FNAME_LEN];
269,456 ✔
161
  bool           reqTbUid = false;
269,454 ✔
162
  SRpcMsg        rpcMsg = {0};
269,454 ✔
163
  int32_t        code = 0;
269,453 ✔
164
  int32_t        rspLen = 0;
269,453 ✔
165
  void          *pRsp = NULL;
269,453 ✔
166
  SSchemaWrapper schema = {0};
269,453 ✔
167
  SSchemaWrapper schemaTag = {0};
269,454 ✔
168
  uint8_t        autoCreateCtb = 0;
269,449 ✔
169
  SSchema       *pMergedCols = NULL;  // vchild: vstb row schema + own (extension) columns
269,449 ✔
170
  SColRef       *pMergedRefs = NULL;  // vchild: persisted colRef + own column refs
269,449 ✔
171
  int32_t        nMergedCols = 0;
269,444 ✔
172
  SSchema       *pMergedTags = NULL;  // vchild: vstb tag schema + own (extension) tags
269,445 ✔
173
  int32_t        nMergedTags = 0;
269,444 ✔
174

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

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

187
  if (!reqTbUid) {
269,467 ✔
188
    (void)snprintf(tableFName, TSDB_TABLE_FNAME_LEN, "%s.%s", infoReq.dbFName, infoReq.tbName);
267,757 ✔
189
    if (pVnode->mounted) tTrimMountPrefix(tableFName);
267,757 ✔
190
    code = vnodeValidateTableHash(pVnode, tableFName);
267,757 ✔
191
    if (code) {
267,767 ✔
192
      goto _exit4;
×
193
    }
194
  }
195

196
  // query meta
197
  metaReaderDoInit(&mer1, pVnode->pMeta, META_READER_LOCK, infoReq.txnId);
269,477 ✔
198
  if (reqTbUid) {
269,463 ✔
199
    SET_ERRNO(0);
1,697 ✔
200
    uint64_t tbUid = taosStr2UInt64(infoReq.tbName, NULL, 10);
1,697 ✔
201
    if (ERRNO == ERANGE || tbUid == 0) {
1,697 ✔
202
      code = TSDB_CODE_TDB_TABLE_NOT_EXIST;
6 ✔
203
      goto _exit3;
6 ✔
204
    }
205
    SMetaReader mr3 = {0};
1,691 ✔
206
    metaReaderDoInit(&mr3, ((SVnode *)pVnode)->pMeta, META_READER_NOLOCK, infoReq.txnId);
1,691 ✔
207
    if ((code = metaReaderGetTableEntryByUid(&mr3, tbUid)) < 0) {
1,691 ✔
208
      metaReaderClear(&mr3);
493 ✔
209
      TAOS_CHECK_GOTO(code, NULL, _exit3);
493 ✔
210
    }
211
    tstrncpy(metaRsp.tbName, mr3.me.name, TSDB_TABLE_NAME_LEN);
1,198 ✔
212
    metaReaderClear(&mr3);
1,198 ✔
213
    TAOS_CHECK_GOTO(metaGetTableEntryByName(&mer1, metaRsp.tbName), NULL, _exit3);
1,198 ✔
214
  } else if (metaGetTableEntryByName(&mer1, infoReq.tbName) < 0) {
267,766 ✔
215
    code = terrno;
91,070 ✔
216
    goto _exit3;
91,070 ✔
217
  }
218

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

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

240
      tstrncpy(metaRsp.stbName, mer2.me.name, sizeof(metaRsp.stbName));
44,205 ✔
241
      metaRsp.suid = mer2.me.uid;
44,205 ✔
242
      metaRsp.ownerId = mer2.me.stbEntry.ownerId;  // child table inherits ownerId from stb
44,205 ✔
243
      metaRsp.secLvl = mer2.me.stbEntry.securityLevel;  // child table inherits secLvl from stb
44,205 ✔
244
      schema = mer2.me.stbEntry.schemaRow;
44,205 ✔
245
      schemaTag = mer2.me.stbEntry.schemaTag;
44,205 ✔
246
      break;
44,205 ✔
247
    }
248
    case TSDB_NORMAL_TABLE:
37,430 ✔
249
      metaRsp.secLvl = pVnode->config.securityLevel;  // normal table inherits secLvl from vnode config
37,430 ✔
250
    case TSDB_VIRTUAL_NORMAL_TABLE: {
120,855 ✔
251
      schema = mer1.me.ntbEntry.schemaRow;
120,855 ✔
252
      schemaTag = mer1.me.ntbEntry.schemaTag;  // normal/virtual-normal tables may own tags
120,855 ✔
253
      metaRsp.ownerId = mer1.me.ntbEntry.ownerId;
120,855 ✔
254
      break;
120,855 ✔
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;
177,883 ✔
265
  if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
177,883 ✔
266
    code = metaBuildMergedColView(&mer1.me, &schema, &pMergedCols, &pMergedRefs, &nMergedCols);
11,673 ✔
267
    if (code) {
11,673 ✔
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;
11,673 ✔
274
    code = metaBuildMergedTagView(&mer1.me, &schemaTag, &pMergedTags, &nMergedTags);
11,673 ✔
275
    if (code) {
11,673 ✔
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;
177,884 ✔
283
  metaRsp.numOfColumns = nMergedCols;
177,884 ✔
284
  metaRsp.precision = pVnode->config.tsdbCfg.precision;
177,884 ✔
285
  metaRsp.sversion = schema.version;
177,884 ✔
286
  metaRsp.tversion = schemaTag.version;
177,884 ✔
287
  metaRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (metaRsp.numOfColumns + metaRsp.numOfTags));
177,884 ✔
288
  metaRsp.pSchemaExt = (SSchemaExt *)taosMemoryCalloc(metaRsp.numOfColumns, sizeof(SSchemaExt));
177,887 ✔
289
  if (NULL == metaRsp.pSchemas || NULL == metaRsp.pSchemaExt) {
177,879 ✔
290
    code = terrno;
×
291
    goto _exit;
×
292
  }
293
  if (pMergedCols) {
177,880 ✔
294
    (void)memcpy(metaRsp.pSchemas, pMergedCols, sizeof(SSchema) * nMergedCols);
11,673 ✔
295
  } else {
296
    (void)memcpy(metaRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols);
166,207 ✔
297
  }
298
  if (pMergedTags) {
177,880 ✔
299
    (void)memcpy(metaRsp.pSchemas + metaRsp.numOfColumns, pMergedTags, sizeof(SSchema) * nMergedTags);
11,673 ✔
300
  } else if (schemaTag.nCols) {
166,207 ✔
301
    (void)memcpy(metaRsp.pSchemas + metaRsp.numOfColumns, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
45,593 ✔
302
  }
303
  if (metaRsp.pSchemaExt) {
177,880 ✔
304
    SMetaReader *pReader =
178,122 ✔
305
        (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? &mer2 : &mer1;
177,889 ✔
306
    // col compress/ext schema of the vstb part only; own columns keep zeroed ext schema
307
    code = fillTableColCmpr(pReader, metaRsp.pSchemaExt, schema.nCols);
177,889 ✔
308
    if (code < 0) {
177,895 ✔
309
      goto _exit;
×
310
    }
311
    for (int32_t i = 0; i < metaRsp.numOfColumns; i++) {
2,598,237 ✔
312
      metaRsp.pSchemaExt[i].colId = metaRsp.pSchemas[i].colId;
2,420,342 ✔
313
      if (i < schema.nCols) {
2,420,342 ✔
314
        if (pReader->me.pExtSchemas) {
2,420,163 ✔
315
          metaRsp.pSchemaExt[i].typeMod = pReader->me.pExtSchemas[i].typeMod;
79,672 ✔
316
        }
317
      } else if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE && mer1.me.own.pOwnColExtSchemas != NULL &&
179 ✔
318
                 mer1.me.own.nOwnCols == metaRsp.numOfColumns - schema.nCols) {
4 ✔
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;
4 ✔
322
      }
323
    }
324
  } else {
325
    code = TSDB_CODE_OUT_OF_MEMORY;
×
326
    goto _exit;
×
327
  }
328
  if (hasColRef(mer1.me.type)) {
177,895 ✔
329
    metaRsp.rversion = mer1.me.colRef.version;
95,103 ✔
330
    if (pMergedRefs) {
95,103 ✔
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;
11,673 ✔
334
      pMergedRefs = NULL;
11,673 ✔
335
    } else {
336
      metaRsp.pColRefs = (SColRef*)taosMemoryCalloc(metaRsp.numOfColumns, sizeof(SColRef));
83,430 ✔
337
      if (metaRsp.pColRefs) {
83,434 ✔
338
        code = fillTableColRef(&mer1, metaRsp.pColRefs, metaRsp.numOfColumns);
83,435 ✔
339
        if (code < 0) {
83,434 ✔
340
          goto _exit;
×
341
        }
342
      }
343
    }
344
    metaRsp.numOfColRefs = metaRsp.numOfColumns;
95,106 ✔
345

346
    // Fill tag references
347
    if (mer1.me.colRef.nTagRefs > 0) {
95,106 ✔
348
      metaRsp.pTagRefs = (SColRef*)taosMemoryCalloc(mer1.me.colRef.nTagRefs, sizeof(SColRef));
4,001 ✔
349
      if (metaRsp.pTagRefs) {
4,001 ✔
350
        code = fillTableTagRef(&mer1, metaRsp.pTagRefs, mer1.me.colRef.nTagRefs);
4,001 ✔
351
        if (code < 0) {
4,001 ✔
352
          taosMemoryFreeClear(metaRsp.pTagRefs);
×
353
          goto _exit;
×
354
        }
355
      } else {
356
        code = terrno;
×
357
        goto _exit;
×
358
      }
359
      metaRsp.numOfTagRefs = mer1.me.colRef.nTagRefs;
4,001 ✔
360
    } else {
361
      metaRsp.pTagRefs = NULL;
91,105 ✔
362
      metaRsp.numOfTagRefs = 0;
91,105 ✔
363
    }
364
  } else {
365
    metaRsp.pColRefs = NULL;
82,794 ✔
366
    metaRsp.numOfColRefs = 0;
82,794 ✔
367
    metaRsp.pTagRefs = NULL;
82,794 ✔
368
    metaRsp.numOfTagRefs = 0;
82,794 ✔
369
  }
370

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

395
  vnodeDebugTableMeta(&metaRsp);
177,900 ✔
396

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

404
  if (direct) {
177,870 ✔
405
    pRsp = rpcMallocCont(rspLen);
117,368 ✔
406
  } else {
407
    pRsp = taosMemoryCalloc(1, rspLen);
60,502 ✔
408
  }
409

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

415
  rspLen = tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
177,871 ✔
416
  if (rspLen < 0) {
177,893 ✔
417
    code = terrno;
×
418
    goto _exit;
×
419
  }
420

421
_exit:
177,884 ✔
422
  taosMemoryFreeClear(pMergedCols);
177,892 ✔
423
  taosMemoryFreeClear(pMergedTags);
177,892 ✔
424
  if (pMergedRefs) {
177,892 ✔
425
    tFreeSColRefArray(pMergedRefs, nMergedCols);
×
426
    taosMemoryFreeClear(pMergedRefs);
×
427
  }
428
  tFreeSTableMetaRsp(&metaRsp);
177,892 ✔
429
_exit2:
177,876 ✔
430
  metaReaderClear(&mer2);
177,893 ✔
431
_exit3:
269,449 ✔
432
  metaReaderClear(&mer1);
269,449 ✔
433
_exit4:
269,447 ✔
434
  rpcMsg.info = pMsg->info;
269,466 ✔
435
  rpcMsg.pCont = pRsp;
269,466 ✔
436
  rpcMsg.contLen = rspLen;
269,466 ✔
437
  rpcMsg.code = code;
269,466 ✔
438
  rpcMsg.msgType = direct ? pMsg->msgType + 1 : pMsg->msgType;
269,466 ✔
439

440
  if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && autoCreateCtb == 1) {
269,466 ✔
441
    code = TSDB_CODE_SUCCESS;
71,136 ✔
442
  }
443

444
  if (code) {
269,462 ✔
445
    qError("vgId:%d, get table %s meta with %" PRIu8 " failed cause of %s", pVnode->config.vgId, infoReq.tbName,
20,425 ✔
446
           infoReq.option, tstrerror(code));
447
  }
448

449
  if (direct) {
269,449 ✔
450
    tmsgSendRsp(&rpcMsg);
119,323 ✔
451
  } else {
452
    *pMsg = rpcMsg;
150,126 ✔
453
  }
454

455
  return code;
269,449 ✔
456
}
457

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

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

482
  tstrncpy(cfgRsp.tbName, cfgReq.tbName, TSDB_TABLE_NAME_LEN);
253,870 ✔
483
  (void)memcpy(cfgRsp.dbFName, cfgReq.dbFName, sizeof(cfgRsp.dbFName));
253,870 ✔
484

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

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

495
  if (metaGetTableEntryByName(&mer1, cfgReq.tbName) < 0) {
253,870 ✔
496
    code = terrno;
3 ✔
497
    goto _exit;
3 ✔
498
  }
499

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

504
  if (mer1.me.type == TSDB_SUPER_TABLE) {
253,867 ✔
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) {
248,598 ✔
508
    metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK, cfgReq.txnId);
253,000 ✔
509
    if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit;
253,000 ✔
510

511
    tstrncpy(cfgRsp.stbName, mer2.me.name, TSDB_TABLE_NAME_LEN);
253,000 ✔
512
    schema = mer2.me.stbEntry.schemaRow;
253,000 ✔
513
    schemaTag = mer2.me.stbEntry.schemaTag;
253,000 ✔
514
    cfgRsp.ownerId = mer2.me.stbEntry.ownerId;        // child table inherits ownerId from stb
253,000 ✔
515
    cfgRsp.securityLevel = mer2.me.stbEntry.securityLevel;  // child table inherits secLvl from stb
253,000 ✔
516
    cfgRsp.ttl = mer1.me.ctbEntry.ttlDays;
253,000 ✔
517
    cfgRsp.commentLen = mer1.me.ctbEntry.commentLen;
253,000 ✔
518
    if (mer1.me.ctbEntry.commentLen > 0) {
253,000 ✔
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;
253,000 ✔
526
    cfgRsp.tagsLen = pTag->len;
253,000 ✔
527
    cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen);
253,000 ✔
528
    if (NULL == cfgRsp.pTags) {
253,000 ✔
529
      code = terrno;
×
530
      goto _exit;
×
531
    }
532
    (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
253,000 ✔
533
  } else if (mer1.me.type == TSDB_NORMAL_TABLE || mer1.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
867 ✔
534
    schema = mer1.me.ntbEntry.schemaRow;
867 ✔
535
    schemaTag = mer1.me.ntbEntry.schemaTag;  // normal/virtual-normal tables may own tags
867 ✔
536
    cfgRsp.ttl = mer1.me.ntbEntry.ttlDays;
867 ✔
537
    cfgRsp.ownerId = mer1.me.ntbEntry.ownerId;
867 ✔
538
    cfgRsp.securityLevel = mer1.me.type == TSDB_NORMAL_TABLE ? pVnode->config.securityLevel : 0;
867 ✔
539
    cfgRsp.commentLen = mer1.me.ntbEntry.commentLen;
867 ✔
540
    if (mer1.me.ntbEntry.commentLen > 0) {
867 ✔
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) {
867 ✔
550
      STag *pTag = (STag *)mer1.me.ntbEntry.pTags;
136 ✔
551
      cfgRsp.tagsLen = pTag->len;
136 ✔
552
      cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen);
136 ✔
553
      if (NULL == cfgRsp.pTags) {
136 ✔
554
        code = terrno;
×
555
        goto _exit;
×
556
      }
557
      (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
136 ✔
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;
253,867 ✔
568
  if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
253,867 ✔
569
    code = metaBuildMergedColView(&mer1.me, &schema, &pMergedCols, &pMergedRefs, &nMergedCols);
180,440 ✔
570
    if (code) {
180,440 ✔
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;
180,440 ✔
577
    code = metaBuildMergedTagView(&mer1.me, &schemaTag, &pMergedTags, &nMergedTags);
180,440 ✔
578
    if (code) {
180,440 ✔
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;
253,867 ✔
586
  cfgRsp.numOfColumns = nMergedCols;
253,867 ✔
587
  cfgRsp.virtualStb = false; // vnode don't have super table, so it's always false
253,867 ✔
588
  cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags));
253,867 ✔
589
  cfgRsp.pSchemaExt = (SSchemaExt *)taosMemoryCalloc(cfgRsp.numOfColumns, sizeof(SSchemaExt));
253,867 ✔
590
  cfgRsp.pColRefs = (SColRef *)taosMemoryCalloc(cfgRsp.numOfColumns, sizeof(SColRef));
253,867 ✔
591
  cfgRsp.numOfTagRefs = 0;
253,867 ✔
592
  cfgRsp.pTagRefs = NULL;
253,867 ✔
593

594
  if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt || NULL == cfgRsp.pColRefs) {
253,867 ✔
595
    code = terrno;
×
596
    goto _exit;
×
597
  }
598
  if (pMergedCols) {
253,867 ✔
599
    (void)memcpy(cfgRsp.pSchemas, pMergedCols, sizeof(SSchema) * nMergedCols);
180,440 ✔
600
  } else {
601
    (void)memcpy(cfgRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols);
73,427 ✔
602
  }
603
  if (pMergedTags) {
253,867 ✔
604
    (void)memcpy(cfgRsp.pSchemas + cfgRsp.numOfColumns, pMergedTags, sizeof(SSchema) * nMergedTags);
180,440 ✔
605
  } else if (schemaTag.nCols) {
73,427 ✔
606
    (void)memcpy(cfgRsp.pSchemas + cfgRsp.numOfColumns, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
72,696 ✔
607
  }
608

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

612
  if (withExtSchema(cfgRsp.tableType)) {
253,867 ✔
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);
253,867 ✔
616
    if (code < 0) {
253,867 ✔
617
      goto _exit;
×
618
    }
619

620
    for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
2,544,868 ✔
621
      SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i;
2,291,001 ✔
622
      pSchExt->colId = cfgRsp.pSchemas[i].colId;
2,291,001 ✔
623
      if (i < schema.nCols) {
2,291,001 ✔
624
        if (pReader->me.pExtSchemas) {
2,290,882 ✔
625
          pSchExt->typeMod = pReader->me.pExtSchemas[i].typeMod;
111,789 ✔
626
        }
627
      } else if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE && mer1.me.own.pOwnColExtSchemas != NULL &&
119 ✔
628
                 mer1.me.own.nOwnCols == cfgRsp.numOfColumns - schema.nCols) {
4 ✔
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;
4 ✔
632
      }
633
    }
634
  }
635

636
  cfgRsp.virtualStb = false;
253,867 ✔
637
  if (hasColRef(cfgRsp.tableType)) {
253,867 ✔
638
    if (pMergedRefs) {
181,141 ✔
639
      // merged view already validated and deep-copied by metaBuildMergedColView;
640
      // transfer ownership to the response
641
      taosMemoryFreeClear(cfgRsp.pColRefs);
180,440 ✔
642
      cfgRsp.pColRefs = pMergedRefs;
180,440 ✔
643
      pMergedRefs = NULL;
180,440 ✔
644
    } else {
645
      for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
3,095 ✔
646
        SColRef *pRef = &pColRef->pColRef[i];
2,394 ✔
647
        cfgRsp.pColRefs[i].hasRef = pRef->hasRef;
2,394 ✔
648
        cfgRsp.pColRefs[i].id = pRef->id;
2,394 ✔
649
        if (cfgRsp.pColRefs[i].hasRef) {
2,394 ✔
650
          cfgRsp.pColRefs[i].refType = pRef->refType;
1,634 ✔
651
          tstrncpy(cfgRsp.pColRefs[i].refSourceName, pRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
1,634 ✔
652
          tstrncpy(cfgRsp.pColRefs[i].refSchemaName, pRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
1,634 ✔
653
          tstrncpy(cfgRsp.pColRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
1,634 ✔
654
          tstrncpy(cfgRsp.pColRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
1,634 ✔
655
          tstrncpy(cfgRsp.pColRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
1,634 ✔
656
          if (pRef->tagCondJson) {
1,634 ✔
657
            cfgRsp.pColRefs[i].tagCondLen = pRef->tagCondLen;
68 ✔
658
            cfgRsp.pColRefs[i].tagCondJson = taosStrdup(pRef->tagCondJson);
68 ✔
659
          } else {
660
            cfgRsp.pColRefs[i].tagCondLen = 0;
1,566 ✔
661
            cfgRsp.pColRefs[i].tagCondJson = NULL;
1,566 ✔
662
          }
663
        }
664
        if (pRef->filterCondLen > 0 && pRef->filterCondJson) {
2,394 ✔
665
          cfgRsp.pColRefs[i].filterCondLen = pRef->filterCondLen;
399 ✔
666
          cfgRsp.pColRefs[i].filterCondJson = taosStrdup(pRef->filterCondJson);
399 ✔
667
          if (NULL == cfgRsp.pColRefs[i].filterCondJson) {
399 ✔
668
            code = terrno;
×
669
            goto _exit;
×
670
          }
671
        }
672
      }
673
    }
674

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

687
      for (int32_t i = 0; i < cfgRsp.numOfTagRefs; i++) {
331,691 ✔
688
        SColRef *pRef = &pColRef->pTagRef[i];
248,407 ✔
689
        cfgRsp.pTagRefs[i].hasRef = pRef->hasRef;
248,407 ✔
690
        cfgRsp.pTagRefs[i].id = pRef->id;
248,407 ✔
691
        if (cfgRsp.pTagRefs[i].hasRef) {
248,407 ✔
692
          cfgRsp.pTagRefs[i].refType = pRef->refType;
164,917 ✔
693
          tstrncpy(cfgRsp.pTagRefs[i].refSourceName, pRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
164,917 ✔
694
          tstrncpy(cfgRsp.pTagRefs[i].refSchemaName, pRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
164,917 ✔
695
          tstrncpy(cfgRsp.pTagRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
164,917 ✔
696
          tstrncpy(cfgRsp.pTagRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
164,917 ✔
697
          tstrncpy(cfgRsp.pTagRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
164,917 ✔
698
          if (pRef->tagCondJson) {
164,917 ✔
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) {
164,917 ✔
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) {
253,867 ✔
721
    cfgRsp.numOfSeries = mer1.me.series.nSeries;
3,329 ✔
722
    cfgRsp.pSeries = taosMemoryCalloc(mer1.me.series.nSeries, sizeof(SSeriesEntry));
3,329 ✔
723
    if (cfgRsp.pSeries) {
3,329 ✔
724
      for (int32_t i = 0; i < mer1.me.series.nSeries; i++) {
23,117 ✔
725
        SSeriesEntry *src = &mer1.me.series.pSeries[i];
19,788 ✔
726
        SSeriesEntry *dst = &cfgRsp.pSeries[i];
19,788 ✔
727
        tstrncpy(dst->alias, src->alias, TSDB_COL_NAME_LEN);
19,788 ✔
728
        tstrncpy(dst->sourceName, src->sourceName, TSDB_EXT_SOURCE_NAME_LEN);
19,788 ✔
729
        tstrncpy(dst->dbName, src->dbName, TSDB_DB_NAME_LEN);
19,788 ✔
730
        tstrncpy(dst->measurementName, src->measurementName, TSDB_TABLE_NAME_LEN);
19,788 ✔
731
        if (src->tagCondLen > 0) {
19,788 ✔
732
          dst->tagCondJson = taosStrdup(src->tagCondJson);
19,788 ✔
733
          dst->tagCondLen = src->tagCondLen;
19,788 ✔
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);
253,867 ✔
744
  if (rspLen < 0) {
253,867 ✔
745
    code = terrno;
×
746
    goto _exit;
×
747
  }
748

749
  if (direct) {
253,867 ✔
750
    pRsp = rpcMallocCont(rspLen);
253,045 ✔
751
  } else {
752
    pRsp = taosMemoryCalloc(1, rspLen);
822 ✔
753
  }
754

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

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

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

773
  if (code) {
253,870 ✔
774
    qError("get table %s cfg failed cause of %s", cfgReq.tbName, tstrerror(code));
3 ✔
775
  }
776

777
  if (direct) {
253,870 ✔
778
    tmsgSendRsp(&rpcMsg);
253,048 ✔
779
  } else {
780
    *pMsg = rpcMsg;
822 ✔
781
  }
782

783
  tFreeSTableCfgRsp(&cfgRsp);
253,870 ✔
784
  taosMemoryFreeClear(pMergedCols);
253,870 ✔
785
  taosMemoryFreeClear(pMergedTags);
253,870 ✔
786
  if (pMergedRefs) {
253,870 ✔
787
    tFreeSColRefArray(pMergedRefs, nMergedCols);
×
788
    taosMemoryFreeClear(pMergedRefs);
×
789
  }
790
  metaReaderClear(&mer2);
253,870 ✔
791
  metaReaderClear(&mer1);
253,870 ✔
792
  return code;
253,870 ✔
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) {
201,924 ✔
805
  int32_t      code = 0;
201,924 ✔
806
  int32_t      rspSize = 0;
201,924 ✔
807
  SBatchReq    batchReq = {0};
201,924 ✔
808
  SBatchMsg   *req = NULL;
201,932 ✔
809
  SBatchRspMsg rsp = {0};
201,932 ✔
810
  SBatchRsp    batchRsp = {0};
201,810 ✔
811
  SRpcMsg      reqMsg = *pMsg;
201,824 ✔
812
  SRpcMsg      rspMsg = {0};
201,824 ✔
813
  void        *pRsp = NULL;
201,880 ✔
814

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

821
  int32_t msgNum = taosArrayGetSize(batchReq.pMsgs);
201,838 ✔
822
  if (msgNum >= MAX_META_MSG_IN_BATCH) {
201,885 ✔
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));
201,885 ✔
829
  if (NULL == batchRsp.pRsps) {
201,886 ✔
830
    code = terrno;
×
831
    qError("taosArrayInit %d SBatchRspMsg failed", msgNum);
×
832
    goto _exit;
×
833
  }
834

835
  for (int32_t i = 0; i < msgNum; ++i) {
429,483 ✔
836
    req = taosArrayGet(batchReq.pMsgs, i);
227,522 ✔
837
    if (req == NULL) {
227,457 ✔
838
      code = terrno;
×
839
      goto _exit;
×
840
    }
841

842
    reqMsg.msgType = req->msgType;
227,519 ✔
843
    reqMsg.pCont = req->msg;
227,519 ✔
844
    reqMsg.contLen = req->msgLen;
227,519 ✔
845

846
    switch (req->msgType) {
227,519 ✔
847
      case TDMT_VND_TABLE_META:
148,441 ✔
848
        // error code has been set into reqMsg, no need to handle it here.
849
        if (TSDB_CODE_SUCCESS != vnodeGetTableMeta(pVnode, &reqMsg, false)) {
148,441 ✔
850
          qWarn("vnodeGetBatchMeta failed, msgType:%d", req->msgType);
17,976 ✔
851
        }
852
        break;
148,107 ✔
853
      case TDMT_VND_TABLE_NAME:
1,696 ✔
854
        // error code has been set into reqMsg, no need to handle it here.
855
        if (TSDB_CODE_SUCCESS != vnodeGetTableMeta(pVnode, &reqMsg, false)) {
1,696 ✔
856
          qWarn("vnodeGetBatchName failed, msgType:%d", req->msgType);
499 ✔
857
        }
858
        break;
1,696 ✔
859
      case TDMT_VND_TABLE_CFG:
822 ✔
860
        // error code has been set into reqMsg, no need to handle it here.
861
        if (TSDB_CODE_SUCCESS != vnodeGetTableCfg(pVnode, &reqMsg, false)) {
822 ✔
862
          qWarn("vnodeGetBatchMeta failed, msgType:%d", req->msgType);
×
863
        }
864
        break;
822 ✔
865
      case TDMT_VND_VSUBTABLES_META:
76,560 ✔
866
        // error code has been set into reqMsg, no need to handle it here.
867
        if (TSDB_CODE_SUCCESS != vnodeGetVSubtablesMeta(pVnode, &reqMsg)) {
76,560 ✔
868
          qWarn("vnodeGetVSubtablesMeta failed, msgType:%d", req->msgType);
×
869
        }
870
        break;
70,109 ✔
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;
227,571 ✔
892
    rsp.reqType = reqMsg.msgType;
227,571 ✔
893
    rsp.msgLen = reqMsg.contLen;
227,571 ✔
894
    rsp.rspCode = reqMsg.code;
227,571 ✔
895
    rsp.msg = reqMsg.pCont;
227,571 ✔
896

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

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

922
_exit:
201,950 ✔
923

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

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

934
  taosArrayDestroyEx(batchReq.pMsgs, tFreeSBatchReqMsg);
201,953 ✔
935
  taosArrayDestroyEx(batchRsp.pRsps, tFreeSBatchRspMsg);
201,929 ✔
936

937
  tmsgSendRsp(&rspMsg);
201,930 ✔
938

939
  return code;
201,955 ✔
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) {
76,513 ✔
950
  int32_t                    code = TSDB_CODE_SUCCESS;
76,513 ✔
951
  int32_t                    line = 0;
76,530 ✔
952
  SMetaReader                mr = {0};
76,530 ✔
953
  bool                       readerInit = false;
76,463 ✔
954
  SVCTableRefCols*           pTb = NULL;
76,463 ✔
955
  int32_t                    refColsNum = 0;
76,367 ✔
956
  char                       tbFName[TSDB_TABLE_FNAME_LEN];
76,367 ✔
957
  SSHashObj*                 pSrcTbls = NULL;
76,325 ✔
958
  SSHashObj*                 pContentDedup = NULL;
76,325 ✔
959

960
  SArray *pList = taosArrayInit(10, sizeof(uint64_t));
76,325 ✔
961
  QUERY_CHECK_NULL(pList, code, line, _return, terrno);
76,482 ✔
962

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

965
  size_t num = taosArrayGetSize(pList);
76,546 ✔
966
  *ppRes = taosArrayInit(num, POINTER_BYTES);
76,551 ✔
967
  QUERY_CHECK_NULL(*ppRes, code, line, _return, terrno);
76,566 ✔
968
  pSrcTbls = tSimpleHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
76,566 ✔
969
  QUERY_CHECK_NULL(pSrcTbls, code, line, _return, terrno);
76,460 ✔
970
  pContentDedup = tSimpleHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
76,460 ✔
971
  QUERY_CHECK_NULL(pContentDedup, code, line, _return, terrno);
76,432 ✔
972

973
  for (int32_t i = 0; i < num; ++i) {
418,381 ✔
974
    uint64_t* id = taosArrayGet(pList, i);
341,699 ✔
975
    QUERY_CHECK_NULL(id, code, line, _return, terrno);
341,514 ✔
976
    pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn, pHandle->txnId);
341,514 ✔
977
    QUERY_CHECK_CODE(pHandle->api.metaReaderFn.getTableEntryByUid(&mr, *id), line, _return);
341,700 ✔
978
    readerInit = true;
802,886 ✔
979

980
    refColsNum = 0;
312,606 ✔
981
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
4,175,767 ✔
982
      if (mr.me.colRef.pColRef[j].hasRef) {
3,834,215 ✔
983
        refColsNum++;
2,179,582 ✔
984
      }
985
    }
986

987
    int32_t tagRefColsNum = 0;
312,606 ✔
988
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
586,415 ✔
989
      if (mr.me.colRef.pTagRef[j].hasRef) {
244,863 ✔
990
        tagRefColsNum++;
163,275 ✔
991
      }
992
    }
993

994
    if (refColsNum <= 0 && tagRefColsNum <= 0) {
341,552 ✔
995
      pHandle->api.metaReaderFn.clearReader(&mr);
62,636 ✔
996
      readerInit = false;
62,636 ✔
997
      continue;
62,636 ✔
998
    }
999

1000
    // Size the compact block (entries + string arena) and count source tables.
1001
    uint64_t arenaBytes = 0;
278,916 ✔
1002
    tSimpleHashClear(pSrcTbls);
278,916 ✔
1003
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
3,114,510 ✔
1004
      if (!mr.me.colRef.pColRef[j].hasRef) {
2,835,553 ✔
1005
        continue;
655,173 ✔
1006
      }
1007

1008
      arenaBytes += strlen(mr.me.colRef.pColRef[j].refDbName) + 1;
2,180,380 ✔
1009
      arenaBytes += strlen(mr.me.colRef.pColRef[j].refTableName) + 1;
2,180,380 ✔
1010
      arenaBytes += strlen(mr.me.colRef.pColRef[j].refColName) + 1;
2,180,380 ✔
1011
      if (mr.me.colRef.pColRef[j].refSourceName[0] != '\0') {
2,180,380 ✔
1012
        arenaBytes += strlen(mr.me.colRef.pColRef[j].refSourceName) + 1;
479,762 ✔
1013
      }
1014
      if (mr.me.colRef.pColRef[j].refSchemaName[0] != '\0') {
2,180,380 ✔
1015
        arenaBytes += strlen(mr.me.colRef.pColRef[j].refSchemaName) + 1;
115,008 ✔
1016
      }
1017

1018
      snprintf(tbFName, sizeof(tbFName), "%s.%s", mr.me.colRef.pColRef[j].refDbName, mr.me.colRef.pColRef[j].refTableName);
2,180,380 ✔
1019

1020
      if (NULL == tSimpleHashGet(pSrcTbls, tbFName, strlen(tbFName))) {
2,180,380 ✔
1021
        QUERY_CHECK_CODE(tSimpleHashPut(pSrcTbls, tbFName, strlen(tbFName), &code, sizeof(code)), line, _return);
779,696 ✔
1022
      }
1023
    }
1024
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
523,769 ✔
1025
      if (!mr.me.colRef.pTagRef[j].hasRef) {
244,886 ✔
1026
        continue;
81,677 ✔
1027
      }
1028

1029
      arenaBytes += strlen(mr.me.colRef.pTagRef[j].refDbName) + 1;
163,209 ✔
1030
      arenaBytes += strlen(mr.me.colRef.pTagRef[j].refTableName) + 1;
163,209 ✔
1031
      arenaBytes += strlen(mr.me.colRef.pTagRef[j].refColName) + 1;
163,209 ✔
1032
      if (mr.me.colRef.pTagRef[j].refSourceName[0] != '\0') {
163,209 ✔
1033
        arenaBytes += strlen(mr.me.colRef.pTagRef[j].refSourceName) + 1;
×
1034
      }
1035
      if (mr.me.colRef.pTagRef[j].refSchemaName[0] != '\0') {
163,209 ✔
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);
163,209 ✔
1040

1041
      if (NULL == tSimpleHashGet(pSrcTbls, tbFName, strlen(tbFName))) {
163,209 ✔
1042
        QUERY_CHECK_CODE(tSimpleHashPut(pSrcTbls, tbFName, strlen(tbFName), &code, sizeof(code)), line, _return);
3,398 ✔
1043
      }
1044
    }
1045

1046
    SVctRefContent* pContent = tVctRefContentAlloc(refColsNum, tagRefColsNum, arenaBytes);
278,883 ✔
1047
    QUERY_CHECK_NULL(pContent, code, line, _return, terrno);
278,798 ✔
1048

1049
    uint32_t arenaPos = 0;
278,798 ✔
1050
    int32_t  colIdx = 0;
278,763 ✔
1051
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
3,106,762 ✔
1052
      if (!mr.me.colRef.pColRef[j].hasRef) {
2,829,900 ✔
1053
        continue;
654,742 ✔
1054
      }
1055

1056
      SRefColEntry* pEntry = vctContentColAt(pContent, colIdx);
2,175,158 ✔
1057
      pEntry->colId = mr.me.colRef.pColRef[j].id;
2,175,158 ✔
1058
      if (mr.me.colRef.pColRef[j].filterCondLen > 0) {
2,175,158 ✔
1059
        pEntry->flags |= VCT_REF_FLAG_HAS_FILTER_COND;
3,263 ✔
1060
      }
1061
      pEntry->dbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refDbName);
2,175,158 ✔
1062
      pEntry->tbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refTableName);
2,177,977 ✔
1063
      pEntry->colOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refColName);
2,178,191 ✔
1064
      pEntry->srcOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refSourceName);
2,178,123 ✔
1065
      pEntry->schemaOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refSchemaName);
2,176,170 ✔
1066
      colIdx++;
2,173,257 ✔
1067
    }
1068

1069
    // Fill tag refs
1070
    int32_t tagIdx = 0;
257,529 ✔
1071
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
520,988 ✔
1072
      if (!mr.me.colRef.pTagRef[j].hasRef) {
244,533 ✔
1073
        continue;
81,562 ✔
1074
      }
1075

1076
      SRefColEntry* pEntry = vctContentTagAt(pContent, tagIdx);
162,971 ✔
1077
      pEntry->colId = mr.me.colRef.pTagRef[j].id;
162,971 ✔
1078
      pEntry->dbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refDbName);
162,971 ✔
1079
      pEntry->tbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refTableName);
163,104 ✔
1080
      pEntry->colOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refColName);
163,123 ✔
1081
      pEntry->srcOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refSourceName);
163,088 ✔
1082
      pEntry->schemaOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refSchemaName);
162,913 ✔
1083
      tagIdx++;
162,564 ✔
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);
276,455 ✔
1089
    if (NULL != ppKept) {
279,416 ✔
1090
      taosMemoryFree(pContent);
12,092 ✔
1091
      pContent = *ppKept;
12,104 ✔
1092
    } else {
1093
      code = tSimpleHashPut(pContentDedup, pContent, (uint32_t)pContent->bufLen, &pContent, sizeof(pContent));
267,324 ✔
1094
      if (code) {
267,363 ✔
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);
279,467 ✔
1102
    if (NULL == pTb) {
279,204 ✔
1103
      code = terrno;
×
1104
      goto _return;
×
1105
    }
1106

1107
    QUERY_CHECK_NULL(taosArrayPush(*ppRes, &pTb), code, line, _return, terrno);
539,180 ✔
1108
    pTb = NULL;
279,305 ✔
1109

1110
    pHandle->api.metaReaderFn.clearReader(&mr);
279,305 ✔
1111
    readerInit = false;
279,305 ✔
1112
  }
1113

1114
_return:
76,683 ✔
1115

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

1120
  taosArrayDestroy(pList);
76,641 ✔
1121
  taosMemoryFree(pTb);
76,632 ✔
1122
  tSimpleHashCleanup(pSrcTbls);
76,633 ✔
1123
  tSimpleHashCleanup(pContentDedup);
76,635 ✔
1124

1125
  if (code) {
76,632 ✔
1126
    qError("%s failed since %s", __func__, tstrerror(code));
×
1127
  }
1128
  return code;
76,632 ✔
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) {
76,523 ✔
1230
  int32_t        code = 0;
76,523 ✔
1231
  int32_t        rspSize = 0;
76,523 ✔
1232
  SVSubTablesReq req = {0};
76,523 ✔
1233
  SVSubTablesRsp rsp = {0};
76,534 ✔
1234
  SRpcMsg      rspMsg = {0};
76,352 ✔
1235
  void        *pRsp = NULL;
76,352 ✔
1236
  int32_t      line = 0;
76,352 ✔
1237

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

1244
  SReadHandle handle = {0};
76,505 ✔
1245
  handle.vnode = pVnode;
76,523 ✔
1246
  initStorageAPI(&handle.api);
76,523 ✔
1247

1248
  QUERY_CHECK_CODE(vnodeReadVSubtables(&handle, req.suid, &rsp.pTables), line, _return);
76,463 ✔
1249
  rsp.vgId = TD_VID(pVnode);
76,638 ✔
1250

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

1270
_return:
76,636 ✔
1271

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

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

1282
  *pMsg = rspMsg;
76,633 ✔
1283
  
1284
  tDestroySVSubTablesRsp(&rsp);
76,633 ✔
1285

1286
  //tmsgSendRsp(&rspMsg);
1287

1288
  return code;
76,625 ✔
1289
}
1290

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

1297
  code = tDeserializeSVCheckHasCtbReq(pBuf, bufLen, &req);
347 ✔
1298
  if (code != 0) {
347 ✔
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);
347 ✔
1304
  if (pCur == NULL) {
347 ✔
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);
347 ✔
1309
    metaCloseCtbCursor(pCur);
347 ✔
1310
    if (id != 0) {
347 ✔
1311
      code = TSDB_CODE_MND_VST_PARENT_HAS_VCT;
5 ✔
1312
    }
1313
  }
1314

1315
_exit:;
347 ✔
1316
  SRpcMsg rspMsg = {.info = pMsg->info, .code = code};
347 ✔
1317
  tmsgSendRsp(&rspMsg);
347 ✔
1318
  return 0;  // return 0 so fetch worker doesn't double-send response
347 ✔
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) {
404 ✔
1326
  SVCheckStbAlterNameReq req = {0};
404 ✔
1327
  int32_t                code = 0;
404 ✔
1328
  void                  *pBuf = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
404 ✔
1329
  int32_t                bufLen = pMsg->contLen - sizeof(SMsgHead);
404 ✔
1330

1331
  code = tDeserializeSVCheckStbAlterNameReq(pBuf, bufLen, &req);
404 ✔
1332
  if (code != 0) {
404 ✔
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) {
860 ✔
1338
    code = metaCheckOwnNameConflictOfChildTables(pVnode->pMeta, req.suid, (const char *)taosArrayGet(req.pNames, i));
470 ✔
1339
    if (code != 0) {
470 ✔
1340
      vError("vgId:%d, check-stb-alter-name failed for suid:%" PRId64 ", code:0x%x", TD_VID(pVnode), req.suid, code);
14 ✔
1341
      goto _exit;
14 ✔
1342
    }
1343
  }
1344

1345
_exit:;
404 ✔
1346
  tFreeSVCheckStbAlterNameReq(&req);
404 ✔
1347
  SRpcMsg rspMsg = {.info = pMsg->info, .code = code};
404 ✔
1348
  tmsgSendRsp(&rspMsg);
404 ✔
1349
  return 0;  // return 0 so fetch worker doesn't double-send response
404 ✔
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) {
43,098 ✔
1414
  int32_t      code = TSDB_CODE_SUCCESS;
43,098 ✔
1415
  int32_t      line = 0;
43,098 ✔
1416
  int32_t      rspSize = 0;
43,098 ✔
1417
  SVTagCondReq req = {0};
43,098 ✔
1418
  SVTagCondRsp rsp = {0};
43,098 ✔
1419
  SRpcMsg      rspMsg = {0};
43,098 ✔
1420
  void        *pRsp = NULL;
43,098 ✔
1421
  SMetaReader  mer = {0};
43,098 ✔
1422

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

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

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

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

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

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

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

1511
static int32_t vnodeGetCompStorage(SVnode *pVnode, int64_t *output) {
534,589 ✔
1512
  int32_t code = 0;
534,589 ✔
1513
#ifdef TD_ENTERPRISE
1514
  int32_t now = taosGetTimestampSec();
534,589 ✔
1515
  if (llabs(now - pVnode->config.vndStats.storageLastUpd) >= 30) {
534,589 ✔
1516
    pVnode->config.vndStats.storageLastUpd = now;
27,556 ✔
1517

1518
    SDbSizeStatisInfo info = {0};
27,556 ✔
1519
    if (0 == (code = vnodeGetDBSize(pVnode, &info))) {
27,556 ✔
1520
      int64_t compSize =
27,556 ✔
1521
          info.l1Size + info.l2Size + info.l3Size + info.cacheSize + info.walSize + info.metaSize + +info.ssSize;
27,556 ✔
1522
      if (compSize >= 0) {
27,556 ✔
1523
        pVnode->config.vndStats.compStorage = compSize;
27,556 ✔
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));
224 ✔
1530
    }
1531
  }
1532
  if (output) *output = pVnode->config.vndStats.compStorage;
534,589 ✔
1533
#endif
1534
  return code;
534,589 ✔
1535
}
1536

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

1543
    if (pVnode->inUse) {
534,589 ✔
1544
      *bufferSegmentUsed = pVnode->inUse->size;
534,490 ✔
1545
    }
1546
    *bufferSegmentSize = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
534,589 ✔
1547

1548
    (void)taosThreadMutexUnlock(&pVnode->mutex);
534,589 ✔
1549
  }
1550
}
534,589 ✔
1551

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

1557
  pLoad->vgId = TD_VID(pVnode);
534,589 ✔
1558
  pLoad->syncState = state.state;
534,589 ✔
1559
  pLoad->syncRestore = state.restored;
534,589 ✔
1560
  pLoad->syncTerm = state.term;
534,589 ✔
1561
  pLoad->roleTimeMs = state.roleTimeMs;
534,589 ✔
1562
  pLoad->startTimeMs = state.startTimeMs;
534,589 ✔
1563
  pLoad->syncCanRead = state.canRead;
534,589 ✔
1564
  pLoad->cacheUsage = tsdbCacheGetUsage(pVnode);
534,589 ✔
1565
  pLoad->numOfCachedTables = tsdbCacheGetElems(pVnode);
534,589 ✔
1566
  VNODE_DO_META_QUERY(pVnode, pLoad->numOfTables = metaGetTbNum(pVnode->pMeta));
534,589 ✔
1567
  VNODE_DO_META_QUERY(pVnode, pLoad->numOfTimeSeries = metaGetTimeSeriesNum(pVnode->pMeta, 1));
534,589 ✔
1568
  pLoad->totalStorage = (int64_t)3 * 1073741824;  // TODO
534,589 ✔
1569
  (void)vnodeGetCompStorage(pVnode, &pLoad->compStorage);
534,589 ✔
1570
  pLoad->pointsWritten = 100;
534,589 ✔
1571
  pLoad->numOfSelectReqs = 1;
534,589 ✔
1572
  pLoad->numOfInsertReqs = atomic_load_64(&pVnode->statis.nInsert);
534,589 ✔
1573
  pLoad->numOfInsertSuccessReqs = atomic_load_64(&pVnode->statis.nInsertSuccess);
534,589 ✔
1574
  pLoad->numOfBatchInsertReqs = atomic_load_64(&pVnode->statis.nBatchInsert);
534,589 ✔
1575
  pLoad->numOfBatchInsertSuccessReqs = atomic_load_64(&pVnode->statis.nBatchInsertSuccess);
534,589 ✔
1576
  vnodeGetBufferInfo(pVnode, &pLoad->bufferSegmentUsed, &pLoad->bufferSegmentSize);
534,589 ✔
1577
  vDebug("vgId:%d, get vnode load, state:%s snapSeq:%d, learnerProgress:%d, totalIndex:%" PRId64, TD_VID(pVnode),
534,589 ✔
1578
         syncStr(state.state), state.snapSeq, state.progress, state.totalIndex);
1579
  pLoad->learnerProgress = state.progress;
534,589 ✔
1580
  pLoad->snapSeq = state.snapSeq;
534,589 ✔
1581
  pLoad->syncTotalIndex = state.totalIndex;
534,589 ✔
1582
  pLoad->snapshotSending = syncSnapshotSending(pVnode->sync) ? 1 : 0;
534,589 ✔
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;
534,589 ✔
1586
  SArray *pSnapGroups = taosArrayInit(4, sizeof(STsdbSnapSendGroup));
534,589 ✔
1587
  if (pSnapGroups != NULL) {
534,589 ✔
1588
    tsdbGetSnapSendSummary(pVnode->pTsdb, pSnapGroups);
534,589 ✔
1589
    int32_t numGroups = (int32_t)taosArrayGetSize(pSnapGroups);
534,589 ✔
1590
    if (numGroups > 0) {
534,589 ✔
1591
      pLoad->pSnapProgress = taosArrayInit(numGroups, sizeof(SVnodeSnapProgress));
23 ✔
1592
      if (pLoad->pSnapProgress != NULL) {
23 ✔
1593
        for (int32_t g = 0; g < numGroups; g++) {
46 ✔
1594
          STsdbSnapSendGroup *pGroup = (STsdbSnapSendGroup *)taosArrayGet(pSnapGroups, g);
23 ✔
1595
          if (pGroup == NULL) continue;
23 ✔
1596
          SVnodeSnapProgress prog = {.destDnodeId = pGroup->destDnodeId,
23 ✔
1597
                                     .snapTotalSize = pGroup->total,
23 ✔
1598
                                     .snapTransferredSize = pGroup->transferred};
23 ✔
1599
          if (taosArrayPush(pLoad->pSnapProgress, &prog) == NULL) {
46 ✔
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);
23 ✔
1604
      } else {
1605
        vError("vgId:%d, failed to alloc pSnapProgress array for vnode load", TD_VID(pVnode));
×
1606
      }
1607
    }
1608
    taosArrayDestroy(pSnapGroups);
534,589 ✔
1609
  } else {
1610
    vError("vgId:%d, failed to alloc snap send groups array for vnode load", TD_VID(pVnode));
×
1611
  }
1612
  return 0;
534,589 ✔
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) {
10 ✔
1631
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nInsert, pLoad->numOfInsertReqs, 64, "nInsert");
10 ✔
1632
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nInsertSuccess, pLoad->numOfInsertSuccessReqs, 64, "nInsertSuccess");
10 ✔
1633
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nBatchInsert, pLoad->numOfBatchInsertReqs, 64, "nBatchInsert");
10 ✔
1634
  VNODE_GET_LOAD_RESET_VALS(pVnode->statis.nBatchInsertSuccess, pLoad->numOfBatchInsertSuccessReqs, 64,
10 ✔
1635
                            "nBatchInsertSuccess");
1636
}
10 ✔
1637

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

1642
  if (dbname) {
204,550 ✔
1643
    *dbname = pConf->dbname;
203,891 ✔
1644
  }
1645

1646
  if (vgId) {
204,550 ✔
1647
    *vgId = TD_VID(pVnodeObj);
198,806 ✔
1648
  }
1649

1650
  if (pNums) {
204,550 ✔
1651
    pNums->ntb = pConf->vndStats.numOfNTables;
139 ✔
1652
    pNums->ctb = pConf->vndStats.numOfCTables;
139 ✔
1653
    pNums->vtb = pConf->vndStats.numOfVTables;
139 ✔
1654
    pNums->vctb = pConf->vndStats.numOfVCTables;
139 ✔
1655
  }
1656
}
204,550 ✔
1657

1658
int8_t vnodeGetSecurityLevel(void *pVnode) {
5,830 ✔
1659
  SVnode *pVnodeObj = pVnode;
5,830 ✔
1660
  return pVnodeObj->config.securityLevel;
5,830 ✔
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) {
1,365 ✔
1668
  SVnode *pVnodeObj = pVnode;
1,365 ✔
1669
  char    tbFName[TSDB_TABLE_FNAME_LEN + 1];
1,365 ✔
1670
  (void)snprintf(tbFName, sizeof(tbFName), "%s.%s", pVnodeObj->config.dbname, tbName);
1,365 ✔
1671
  tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
1,365 ✔
1672
  if (pVnodeObj->mounted) tTrimMountPrefix(tbFName);
1,365 ✔
1673

1674
  uint32_t hashValue = taosGetTbHashVal(tbFName, (int32_t)strlen(tbFName), pVnodeObj->config.hashMethod,
2,731 ✔
1675
                                        pVnodeObj->config.hashPrefix, pVnodeObj->config.hashSuffix);
1,365 ✔
1676
  return hashValue >= pVnodeObj->config.hashBegin && hashValue <= pVnodeObj->config.hashEnd;
1,366 ✔
1677
}
1678

1679
int8_t vnodeGetTsdbPrecision(void *pVnode) {
68,075 ✔
1680
  SVnode *pVnodeObj = pVnode;
68,075 ✔
1681
  return pVnodeObj->config.tsdbCfg.precision;
68,075 ✔
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) {
47 ✔
1690
  if (type == TSDB_SUPER_TABLE) {
47 ✔
1691
    return vnodeGetStbIdList(pVnode, 0, pList);
47 ✔
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) {
616,581 ✔
1728
  int32_t      code = TSDB_CODE_SUCCESS;
616,581 ✔
1729
  SVnode      *pVnodeObj = pVnode;
616,581 ✔
1730
  SMCtbCursor *pCur = metaOpenCtbCursor(pVnodeObj, suid, 1, 0);
616,581 ✔
1731
  if (NULL == pCur) {
616,039 ✔
1732
    qError("vnode get ctb id list failed, suid:%" PRId64, suid);
×
1733
    return terrno;
×
1734
  }
1735

1736
  while (1) {
2,425,314 ✔
1737
    tb_uid_t id = metaCtbCursorNext(pCur);
3,041,353 ✔
1738
    if (id == 0) {
3,042,335 ✔
1739
      break;
599,701 ✔
1740
    }
1741
    qTrace("vnodeGetCtbIdList: got ctb id %" PRId64 " for suid %" PRId64, id, suid);
2,425,638 ✔
1742
    if (NULL == taosArrayPush(list, &id)) {
2,427,102 ✔
1743
      qError("taosArrayPush failed");
×
1744
      code = terrno;
×
1745
      goto _exit;
×
1746
    }
1747
  }
1748

1749
_exit:
615,623 ✔
1750
  metaCloseCtbCursor(pCur);
615,623 ✔
1751
  return code;
616,472 ✔
1752
}
1753

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

1761
  while (1) {
335,344 ✔
1762
    tb_uid_t id = metaStbCursorNext(pCur);
661,804 ✔
1763
    if (id == 0) {
661,801 ✔
1764
      break;
322,447 ✔
1765
    }
1766

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

1774
_exit:
326,460 ✔
1775
  metaCloseStbCursor(pCur);
326,460 ✔
1776
  return code;
326,464 ✔
1777
}
1778

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

1787
  while (1) {
92 ✔
1788
    tb_uid_t id = metaStbCursorNext(pCur);
176 ✔
1789
    if (id == 0) {
176 ✔
1790
      break;
84 ✔
1791
    }
1792

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

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

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

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

1815
  *num = 0;
26,189 ✔
1816
  while (1) {
28,105 ✔
1817
    tb_uid_t id = metaCtbCursorNext(pCur);
54,057 ✔
1818
    if (id == 0) {
54,057 ✔
1819
      break;
26,087 ✔
1820
    }
1821

1822
    ++(*num);
27,868 ✔
1823
  }
1824

1825
  metaCloseCtbCursor(pCur);
26,189 ✔
1826
  return TSDB_CODE_SUCCESS;
26,187 ✔
1827
}
1828

1829
int32_t vnodeGetStbColumnNum(SVnode *pVnode, tb_uid_t suid, int *num) {
26,186 ✔
1830
  SSchemaWrapper *pSW = metaGetTableSchema(pVnode->pMeta, suid, -1, 0, NULL, 0, false);
26,186 ✔
1831
  if (pSW) {
26,190 ✔
1832
    *num = pSW->nCols;
25,673 ✔
1833
    tDeleteSchemaWrapper(pSW);
204 ✔
1834
  } else {
1835
    *num = 2;
517 ✔
1836
  }
1837

1838
  return TSDB_CODE_SUCCESS;
26,190 ✔
1839
}
1840

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

1845
  int32_t code = metaReaderGetTableEntryByUid(&mr, suid);
26,190 ✔
1846
  if (code == TSDB_CODE_SUCCESS) {
26,189 ✔
1847
    if (keep) *keep = mr.me.stbEntry.keep;
25,672 ✔
1848
    if (flags) *flags = mr.me.flags;
25,672 ✔
1849
  } else {
1850
    if (keep) *keep = 0;
517 ✔
1851
    if (flags) *flags = 0;
517 ✔
1852
  }
1853

1854
  metaReaderClear(&mr);
26,189 ✔
1855
  return TSDB_CODE_SUCCESS;
26,190 ✔
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) {
326,509 ✔
1933
  int32_t      code = TSDB_CODE_SUCCESS;
326,509 ✔
1934
  int32_t      tbNum = 0;
326,509 ✔
1935
  const char **pTbArr = NULL;
326,509 ✔
1936
  const char  *dbName = NULL;
326,509 ✔
1937
  *tbSize = 0;
326,509 ✔
1938

1939
  if (!(dbName = strchr(pVnode->config.dbname, '.'))) return 0;
326,509 ✔
1940
  if (0 == strncmp(++dbName, "log", TSDB_DB_NAME_LEN)) {
326,506 ✔
1941
    tbNum = tkLogStbNum;
46 ✔
1942
    pTbArr = (const char **)&tkLogStb;
46 ✔
1943
  } else if (0 == strncmp(dbName, "audit", TSDB_DB_NAME_LEN) || pVnode->config.isAudit) {
326,460 ✔
1944
    tbNum = tkAuditStbNum;
98 ✔
1945
    pTbArr = (const char **)&tkAuditStb;
98 ✔
1946
  }
1947
  if (tbNum && pTbArr) {
326,506 ✔
1948
    *tbSize = metaSizeOfTbFilterCache(pVnode->pMeta, 0);
144 ✔
1949
    if (*tbSize < tbNum) {
144 ✔
1950
      for (int32_t i = 0; i < tbNum; ++i) {
2,366 ✔
1951
        tb_uid_t suid = metaGetTableEntryUidByName(pVnode->pMeta, pTbArr[i]);
2,316 ✔
1952
        if (suid != 0) {
2,316 ✔
1953
          code = metaPutTbToFilterCache(pVnode->pMeta, &suid, 0);
30 ✔
1954
          if (TSDB_CODE_SUCCESS != code) {
30 ✔
1955
            return code;
16 ✔
1956
          }
1957
        }
1958
      }
1959
      *tbSize = metaSizeOfTbFilterCache(pVnode->pMeta, 0);
50 ✔
1960
    }
1961
  }
1962

1963
  return code;
322,476 ✔
1964
}
1965
#endif
1966

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

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

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

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

1983
  int32_t tbFilterSize = 0;
326,514 ✔
1984
  int32_t code = TSDB_CODE_SUCCESS;
326,513 ✔
1985
#ifdef TD_ENTERPRISE
1986
  code = vnodeGetTimeSeriesBlackList(pVnode, &tbFilterSize);
326,513 ✔
1987
  if (TSDB_CODE_SUCCESS != code) {
326,509 ✔
1988
    goto _exit;
16 ✔
1989
  }
1990
#endif
1991

1992
  if ((!tbFilterSize && vnodeGetStbIdList(pVnode, 0, suidList) < 0) ||
326,493 ✔
1993
      (tbFilterSize && vnodeGetStbIdListByFilter(pVnode, 0, suidList, vnodeTimeSeriesFilter, pVnode) < 0)) {
322,473 ✔
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;
326,488 ✔
2000
  int64_t arrSize = taosArrayGetSize(suidList);
326,488 ✔
2001
  for (int64_t i = 0; i < arrSize; ++i) {
661,758 ✔
2002
    tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i);
335,256 ✔
2003

2004
    int64_t ctbNum = 0;
335,261 ✔
2005
    int32_t numOfCols = 0;
335,266 ✔
2006
    int8_t  flags = 0;
335,271 ✔
2007
    code = metaGetStbStats(pVnode, suid, &ctbNum, &numOfCols, &flags);
335,262 ✔
2008
    if (TSDB_CODE_SUCCESS != code) {
335,263 ✔
2009
      goto _exit;
×
2010
    }
2011
    if (!TABLE_IS_VIRTUAL(flags)) {
335,263 ✔
2012
      *num += ctbNum * (numOfCols - 1);
297,906 ✔
2013
    }
2014
  }
2015

2016
_exit:
326,519 ✔
2017
  taosArrayDestroy(suidList);
326,517 ✔
2018
  return TSDB_CODE_SUCCESS;
326,511 ✔
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) {
10,128 ✔
2049
  if (pVnode == NULL) {
10,128 ✔
2050
    return NULL;
×
2051
  }
2052

2053
  return metaGetIdx(((SVnode *)pVnode)->pMeta);
10,128 ✔
2054
}
2055

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

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

2067
static FORCE_INLINE int32_t vnodeGetDBPrimaryInfo(SVnode *pVnode, SDbSizeStatisInfo *pInfo) {
224 ✔
2068
  int32_t code = 0;
27,596 ✔
2069
  char    path[TSDB_FILENAME_LEN] = {0};
27,596 ✔
2070

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

2074
  vnodeGetPrimaryPath(pVnode, false, path, TSDB_FILENAME_LEN);
27,596 ✔
2075
  int32_t offset = strlen(path);
27,596 ✔
2076

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

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

2104
  code = tsdbGetFsSize(pVnodeObj->pTsdb, pInfo);
27,596 ✔
2105
_exit:
27,372 ✔
2106
  return code;
27,372 ✔
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