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

taosdata / TDengine / #5133

02 Nov 2026 09:27AM UTC coverage: 70.274% (+3.7%) from 66.595%
#5133

push

travis-ci

jbjia
fix: start federated database leases from the coverage runner

Coverage cases dial the hosts the lease publishes. The coverage entrypoint never started that lease, so external tables kept failing against 127.0.0.1.

357648 of 508936 relevant lines covered (70.27%)

67671557.13 hits per line

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

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

35
void vnodeQueryPreClose(SVnode *pVnode) { qWorkerStopAllTasks((void *)pVnode->pQuery); }
1,925,652 ✔
36

37
void vnodeQueryClose(SVnode *pVnode) { qWorkerDestroy((void **)&pVnode->pQuery); }
1,925,547 ✔
38

39
int32_t fillTableColCmpr(SMetaReader *reader, SSchemaExt *pExt, int32_t numOfCol) {
66,990,603 ✔
40
  int8_t tblType = reader->me.type;
66,990,603 ✔
41
  if (withColCompress(tblType)) {
66,990,603 ✔
42
    SColCmprWrapper *p = &(reader->me.colCmpr);
51,486,210 ✔
43
    if (numOfCol != p->nCols) {
51,486,210 ✔
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++) {
545,029,641 ✔
48
      SColCmpr *pCmpr = &p->pColCmpr[i];
493,543,431 ✔
49
      pExt[i].colId = pCmpr->id;
493,543,431 ✔
50
      pExt[i].compress = pCmpr->alg;
493,543,431 ✔
51
    }
52
  }
53
  return 0;
66,987,474 ✔
54
}
55

56
void vnodeDebugTableMeta(STableMetaRsp *pMeta) {
30,204,157 ✔
57
  if (!(qDebugFlag & DEBUG_DEBUG)) {
30,204,157 ✔
58
    return;
21,364,576 ✔
59
  }
60

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

84
int32_t fillTableColRef(SMetaReader *reader, SColRef *pRef, int32_t numOfCol) {
15,468,662 ✔
85
  int32_t code = TSDB_CODE_SUCCESS;
15,468,662 ✔
86
  int32_t line = 0;
15,468,662 ✔
87
  int8_t tblType = reader->me.type;
15,468,662 ✔
88
  if (hasColRef(tblType)) {
15,468,662 ✔
89
    SColRefWrapper *p = &(reader->me.colRef);
15,468,850 ✔
90
    if (numOfCol != p->nCols) {
15,468,850 ✔
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++) {
254,944,443 ✔
96
      SColRef *pColRef = &p->pColRef[i];
239,475,593 ✔
97
      pRef[i].hasRef = pColRef->hasRef;
239,475,593 ✔
98
      pRef[i].id = pColRef->id;
239,475,593 ✔
99
      if (pRef[i].hasRef) {
239,475,593 ✔
100
        pRef[i].refType = pColRef->refType;
196,302,220 ✔
101
        tstrncpy(pRef[i].refSourceName, pColRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
196,302,220 ✔
102
        tstrncpy(pRef[i].refSchemaName, pColRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
196,302,220 ✔
103
        tstrncpy(pRef[i].refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
196,302,220 ✔
104
        tstrncpy(pRef[i].refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
196,302,220 ✔
105
        tstrncpy(pRef[i].refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
196,302,220 ✔
106
        if (pColRef->tagCondLen > 0 && pColRef->tagCondJson) {
196,302,220 ✔
107
          pRef[i].tagCondLen = pColRef->tagCondLen;
1,311 ✔
108
          pRef[i].tagCondJson = taosStrdup(pColRef->tagCondJson);
1,311 ✔
109
          QUERY_CHECK_NULL(pRef[i].tagCondJson, code, line, _return, terrno);
1,311 ✔
110
        } else {
111
          pRef[i].tagCondLen = 0;
196,300,909 ✔
112
          pRef[i].tagCondJson = NULL;
196,300,909 ✔
113
        }
114
        if (pColRef->filterCondLen > 0 && pColRef->filterCondJson) {
196,302,220 ✔
115
          pRef[i].filterCondLen = pColRef->filterCondLen;
×
116
          pRef[i].filterCondJson = taosStrdup(pColRef->filterCondJson);
×
117
          QUERY_CHECK_NULL(pRef[i].filterCondJson, code, line, _return, terrno);
×
118
        } else {
119
          pRef[i].filterCondLen = 0;
196,302,220 ✔
120
          pRef[i].filterCondJson = NULL;
196,302,220 ✔
121
        }
122
      }
123
    }
124
  }
125

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

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

155
int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
39,710,903 ✔
156
  STableInfoReq  infoReq = {0};
39,710,903 ✔
157
  STableMetaRsp  metaRsp = {0};
39,710,903 ✔
158
  SMetaReader    mer1 = {0};
39,709,932 ✔
159
  SMetaReader    mer2 = {0};
39,709,932 ✔
160
  char           tableFName[TSDB_TABLE_FNAME_LEN];
39,710,231 ✔
161
  bool           reqTbUid = false;
39,709,432 ✔
162
  SRpcMsg        rpcMsg = {0};
39,709,432 ✔
163
  int32_t        code = 0;
39,709,286 ✔
164
  int32_t        rspLen = 0;
39,709,286 ✔
165
  void          *pRsp = NULL;
39,709,286 ✔
166
  SSchemaWrapper schema = {0};
39,709,286 ✔
167
  SSchemaWrapper schemaTag = {0};
39,709,142 ✔
168
  uint8_t        autoCreateCtb = 0;
39,708,836 ✔
169
  SSchema       *pMergedCols = NULL;  // vchild: vstb row schema + own (extension) columns
39,708,836 ✔
170
  SColRef       *pMergedRefs = NULL;  // vchild: persisted colRef + own column refs
39,708,269 ✔
171
  int32_t        nMergedCols = 0;
39,707,684 ✔
172
  SSchema       *pMergedTags = NULL;  // vchild: vstb tag schema + own (extension) tags
39,707,684 ✔
173
  int32_t        nMergedTags = 0;
39,707,684 ✔
174

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

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

187
  if (!reqTbUid) {
39,711,132 ✔
188
    (void)snprintf(tableFName, TSDB_TABLE_FNAME_LEN, "%s.%s", infoReq.dbFName, infoReq.tbName);
39,631,603 ✔
189
    if (pVnode->mounted) tTrimMountPrefix(tableFName);
39,631,603 ✔
190
    code = vnodeValidateTableHash(pVnode, tableFName);
39,631,603 ✔
191
    if (code) {
39,632,483 ✔
192
      goto _exit4;
×
193
    }
194
  }
195

196
  // query meta
197
  metaReaderDoInit(&mer1, pVnode->pMeta, META_READER_LOCK, infoReq.txnId);
39,712,012 ✔
198
  if (reqTbUid) {
39,710,919 ✔
199
    SET_ERRNO(0);
78,324 ✔
200
    uint64_t tbUid = taosStr2UInt64(infoReq.tbName, NULL, 10);
78,324 ✔
201
    if (ERRNO == ERANGE || tbUid == 0) {
78,324 ✔
202
      code = TSDB_CODE_TDB_TABLE_NOT_EXIST;
1,290 ✔
203
      goto _exit3;
1,290 ✔
204
    }
205
    SMetaReader mr3 = {0};
77,034 ✔
206
    metaReaderDoInit(&mr3, ((SVnode *)pVnode)->pMeta, META_READER_NOLOCK, infoReq.txnId);
77,034 ✔
207
    if ((code = metaReaderGetTableEntryByUid(&mr3, tbUid)) < 0) {
77,034 ✔
208
      metaReaderClear(&mr3);
21,016 ✔
209
      TAOS_CHECK_GOTO(code, NULL, _exit3);
21,016 ✔
210
    }
211
    tstrncpy(metaRsp.tbName, mr3.me.name, TSDB_TABLE_NAME_LEN);
55,952 ✔
212
    metaReaderClear(&mr3);
55,952 ✔
213
    TAOS_CHECK_GOTO(metaGetTableEntryByName(&mer1, metaRsp.tbName), NULL, _exit3);
56,018 ✔
214
  } else if (metaGetTableEntryByName(&mer1, infoReq.tbName) < 0) {
39,632,595 ✔
215
    code = terrno;
9,483,561 ✔
216
    goto _exit3;
9,483,561 ✔
217
  }
218

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

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

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

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

282
  metaRsp.numOfTags = (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? nMergedTags : schemaTag.nCols;
30,204,452 ✔
283
  metaRsp.numOfColumns = nMergedCols;
30,204,452 ✔
284
  metaRsp.precision = pVnode->config.tsdbCfg.precision;
30,204,452 ✔
285
  metaRsp.sversion = schema.version;
30,204,452 ✔
286
  metaRsp.tversion = schemaTag.version;
30,204,452 ✔
287
  metaRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (metaRsp.numOfColumns + metaRsp.numOfTags));
30,204,452 ✔
288
  metaRsp.pSchemaExt = (SSchemaExt *)taosMemoryCalloc(metaRsp.numOfColumns, sizeof(SSchemaExt));
30,202,771 ✔
289
  if (NULL == metaRsp.pSchemas || NULL == metaRsp.pSchemaExt) {
30,203,775 ✔
290
    code = terrno;
6 ✔
291
    goto _exit;
×
292
  }
293
  if (pMergedCols) {
30,203,769 ✔
294
    (void)memcpy(metaRsp.pSchemas, pMergedCols, sizeof(SSchema) * nMergedCols);
1,583,169 ✔
295
  } else {
296
    (void)memcpy(metaRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols);
28,620,600 ✔
297
  }
298
  if (pMergedTags) {
30,203,769 ✔
299
    (void)memcpy(metaRsp.pSchemas + metaRsp.numOfColumns, pMergedTags, sizeof(SSchema) * nMergedTags);
1,583,169 ✔
300
  } else if (schemaTag.nCols) {
28,620,600 ✔
301
    (void)memcpy(metaRsp.pSchemas + metaRsp.numOfColumns, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
6,970,507 ✔
302
  }
303
  if (metaRsp.pSchemaExt) {
30,203,769 ✔
304
    SMetaReader *pReader =
30,205,348 ✔
305
        (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? &mer2 : &mer1;
30,204,168 ✔
306
    // col compress/ext schema of the vstb part only; own columns keep zeroed ext schema
307
    code = fillTableColCmpr(pReader, metaRsp.pSchemaExt, schema.nCols);
30,204,168 ✔
308
    if (code < 0) {
30,204,072 ✔
309
      goto _exit;
×
310
    }
311
    for (int32_t i = 0; i < metaRsp.numOfColumns; i++) {
478,337,099 ✔
312
      metaRsp.pSchemaExt[i].colId = metaRsp.pSchemas[i].colId;
448,133,027 ✔
313
      if (i < schema.nCols) {
448,133,027 ✔
314
        if (pReader->me.pExtSchemas) {
448,107,012 ✔
315
          metaRsp.pSchemaExt[i].typeMod = pReader->me.pExtSchemas[i].typeMod;
3,526,419 ✔
316
        }
317
      } else if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE && mer1.me.own.pOwnColExtSchemas != NULL &&
26,015 ✔
318
                 mer1.me.own.nOwnCols == metaRsp.numOfColumns - schema.nCols) {
860 ✔
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;
860 ✔
322
      }
323
    }
324
  } else {
325
    code = TSDB_CODE_OUT_OF_MEMORY;
6 ✔
326
    goto _exit;
6 ✔
327
  }
328
  if (hasColRef(mer1.me.type)) {
30,204,072 ✔
329
    metaRsp.rversion = mer1.me.colRef.version;
17,052,038 ✔
330
    if (pMergedRefs) {
17,052,038 ✔
331
      // merged view already validated (persisted colRef aligned with the vstb schema) and
332
      // deep-copied by metaBuildMergedColView; transfer ownership to the response
333
      metaRsp.pColRefs = pMergedRefs;
1,583,169 ✔
334
      pMergedRefs = NULL;
1,583,169 ✔
335
    } else {
336
      metaRsp.pColRefs = (SColRef*)taosMemoryCalloc(metaRsp.numOfColumns, sizeof(SColRef));
15,468,869 ✔
337
      if (metaRsp.pColRefs) {
15,468,662 ✔
338
        code = fillTableColRef(&mer1, metaRsp.pColRefs, metaRsp.numOfColumns);
15,468,850 ✔
339
        if (code < 0) {
15,469,071 ✔
340
          goto _exit;
×
341
        }
342
      }
343
    }
344
    metaRsp.numOfColRefs = metaRsp.numOfColumns;
17,052,052 ✔
345

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

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

395
  vnodeDebugTableMeta(&metaRsp);
30,204,608 ✔
396

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

404
  if (direct) {
30,202,498 ✔
405
    pRsp = rpcMallocCont(rspLen);
21,991,396 ✔
406
  } else {
407
    pRsp = taosMemoryCalloc(1, rspLen);
8,211,102 ✔
408
  }
409

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

415
  rspLen = tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
30,200,335 ✔
416
  if (rspLen < 0) {
30,203,837 ✔
417
    code = terrno;
×
418
    goto _exit;
×
419
  }
420

421
_exit:
30,203,438 ✔
422
  taosMemoryFreeClear(pMergedCols);
30,203,690 ✔
423
  taosMemoryFreeClear(pMergedTags);
30,203,690 ✔
424
  if (pMergedRefs) {
30,203,690 ✔
425
    tFreeSColRefArray(pMergedRefs, nMergedCols);
×
426
    taosMemoryFreeClear(pMergedRefs);
×
427
  }
428
  tFreeSTableMetaRsp(&metaRsp);
30,203,690 ✔
429
_exit2:
30,201,897 ✔
430
  metaReaderClear(&mer2);
30,204,288 ✔
431
_exit3:
39,708,278 ✔
432
  metaReaderClear(&mer1);
39,710,412 ✔
433
_exit4:
39,709,012 ✔
434
  rpcMsg.info = pMsg->info;
39,710,198 ✔
435
  rpcMsg.pCont = pRsp;
39,710,198 ✔
436
  rpcMsg.contLen = rspLen;
39,710,198 ✔
437
  rpcMsg.code = code;
39,710,198 ✔
438
  rpcMsg.msgType = direct ? pMsg->msgType + 1 : pMsg->msgType;
39,710,198 ✔
439

440
  if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && autoCreateCtb == 1) {
39,710,198 ✔
441
    code = TSDB_CODE_SUCCESS;
7,746,506 ✔
442
  }
443

444
  if (code) {
39,710,158 ✔
445
    qError("vgId:%d, get table %s meta with %" PRIu8 " failed cause of %s", pVnode->config.vgId, infoReq.tbName,
1,759,555 ✔
446
           infoReq.option, tstrerror(code));
447
  }
448

449
  if (direct) {
39,708,537 ✔
450
    tmsgSendRsp(&rpcMsg);
22,273,903 ✔
451
  } else {
452
    *pMsg = rpcMsg;
17,434,634 ✔
453
  }
454

455
  return code;
39,708,537 ✔
456
}
457

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

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

482
  tstrncpy(cfgRsp.tbName, cfgReq.tbName, TSDB_TABLE_NAME_LEN);
36,786,410 ✔
483
  (void)memcpy(cfgRsp.dbFName, cfgReq.dbFName, sizeof(cfgRsp.dbFName));
36,786,410 ✔
484

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

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

495
  if (metaGetTableEntryByName(&mer1, cfgReq.tbName) < 0) {
36,786,410 ✔
496
    code = terrno;
542 ✔
497
    goto _exit;
542 ✔
498
  }
499

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

504
  if (mer1.me.type == TSDB_SUPER_TABLE) {
36,785,868 ✔
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) {
36,783,648 ✔
508
    metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK, cfgReq.txnId);
36,743,682 ✔
509
    if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit;
36,743,682 ✔
510

511
    tstrncpy(cfgRsp.stbName, mer2.me.name, TSDB_TABLE_NAME_LEN);
36,743,682 ✔
512
    schema = mer2.me.stbEntry.schemaRow;
36,743,682 ✔
513
    schemaTag = mer2.me.stbEntry.schemaTag;
36,743,682 ✔
514
    cfgRsp.ownerId = mer2.me.stbEntry.ownerId;        // child table inherits ownerId from stb
36,743,682 ✔
515
    cfgRsp.securityLevel = mer2.me.stbEntry.securityLevel;  // child table inherits secLvl from stb
36,743,682 ✔
516
    cfgRsp.ttl = mer1.me.ctbEntry.ttlDays;
36,743,682 ✔
517
    cfgRsp.commentLen = mer1.me.ctbEntry.commentLen;
36,743,682 ✔
518
    if (mer1.me.ctbEntry.commentLen > 0) {
36,743,682 ✔
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;
36,743,682 ✔
526
    cfgRsp.tagsLen = pTag->len;
36,743,682 ✔
527
    cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen);
36,743,682 ✔
528
    if (NULL == cfgRsp.pTags) {
36,743,682 ✔
529
      code = terrno;
×
530
      goto _exit;
×
531
    }
532
    (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
36,743,682 ✔
533
  } else if (mer1.me.type == TSDB_NORMAL_TABLE || mer1.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
42,186 ✔
534
    schema = mer1.me.ntbEntry.schemaRow;
42,186 ✔
535
    schemaTag = mer1.me.ntbEntry.schemaTag;  // normal/virtual-normal tables may own tags
42,186 ✔
536
    cfgRsp.ttl = mer1.me.ntbEntry.ttlDays;
42,186 ✔
537
    cfgRsp.ownerId = mer1.me.ntbEntry.ownerId;
42,186 ✔
538
    cfgRsp.securityLevel = mer1.me.type == TSDB_NORMAL_TABLE ? pVnode->config.securityLevel : 0;
42,186 ✔
539
    cfgRsp.commentLen = mer1.me.ntbEntry.commentLen;
42,186 ✔
540
    if (mer1.me.ntbEntry.commentLen > 0) {
42,186 ✔
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) {
42,186 ✔
550
      STag *pTag = (STag *)mer1.me.ntbEntry.pTags;
21,943 ✔
551
      cfgRsp.tagsLen = pTag->len;
21,943 ✔
552
      cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen);
21,943 ✔
553
      if (NULL == cfgRsp.pTags) {
21,943 ✔
554
        code = terrno;
×
555
        goto _exit;
×
556
      }
557
      (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
21,943 ✔
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;
36,785,868 ✔
568
  if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
36,785,868 ✔
569
    code = metaBuildMergedColView(&mer1.me, &schema, &pMergedCols, &pMergedRefs, &nMergedCols);
24,167,173 ✔
570
    if (code) {
24,167,173 ✔
571
      vError("vgId:%d, vnodeGetTableCfg build merged col view for %s failed since %s", TD_VID(pVnode),
×
572
             cfgReq.tbName, tstrerror(code));
573
      goto _exit;
×
574
    }
575
    // merged tag view: vstb tag schema followed by the vchild's own (extension) tags
576
    nMergedTags = schemaTag.nCols;
24,167,173 ✔
577
    code = metaBuildMergedTagView(&mer1.me, &schemaTag, &pMergedTags, &nMergedTags);
24,167,173 ✔
578
    if (code) {
24,167,173 ✔
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;
36,785,868 ✔
586
  cfgRsp.numOfColumns = nMergedCols;
36,785,868 ✔
587
  cfgRsp.virtualStb = false; // vnode don't have super table, so it's always false
36,785,868 ✔
588
  cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags));
36,785,868 ✔
589
  cfgRsp.pSchemaExt = (SSchemaExt *)taosMemoryCalloc(cfgRsp.numOfColumns, sizeof(SSchemaExt));
36,785,868 ✔
590
  cfgRsp.pColRefs = (SColRef *)taosMemoryCalloc(cfgRsp.numOfColumns, sizeof(SColRef));
36,785,868 ✔
591
  cfgRsp.numOfTagRefs = 0;
36,785,868 ✔
592
  cfgRsp.pTagRefs = NULL;
36,785,868 ✔
593

594
  if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt || NULL == cfgRsp.pColRefs) {
36,785,868 ✔
595
    code = terrno;
×
596
    goto _exit;
×
597
  }
598
  if (pMergedCols) {
36,785,868 ✔
599
    (void)memcpy(cfgRsp.pSchemas, pMergedCols, sizeof(SSchema) * nMergedCols);
24,167,173 ✔
600
  } else {
601
    (void)memcpy(cfgRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols);
12,618,695 ✔
602
  }
603
  if (pMergedTags) {
36,785,868 ✔
604
    (void)memcpy(cfgRsp.pSchemas + cfgRsp.numOfColumns, pMergedTags, sizeof(SSchema) * nMergedTags);
24,167,173 ✔
605
  } else if (schemaTag.nCols) {
12,618,695 ✔
606
    (void)memcpy(cfgRsp.pSchemas + cfgRsp.numOfColumns, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
12,598,452 ✔
607
  }
608

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

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

620
    for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
321,807,205 ✔
621
      SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i;
285,021,337 ✔
622
      pSchExt->colId = cfgRsp.pSchemas[i].colId;
285,021,337 ✔
623
      if (i < schema.nCols) {
285,021,337 ✔
624
        if (pReader->me.pExtSchemas) {
285,008,867 ✔
625
          pSchExt->typeMod = pReader->me.pExtSchemas[i].typeMod;
70,625 ✔
626
        }
627
      } else if (mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE && mer1.me.own.pOwnColExtSchemas != NULL &&
12,470 ✔
628
                 mer1.me.own.nOwnCols == cfgRsp.numOfColumns - schema.nCols) {
860 ✔
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;
860 ✔
632
      }
633
    }
634
  }
635

636
  cfgRsp.virtualStb = false;
36,785,868 ✔
637
  if (hasColRef(cfgRsp.tableType)) {
36,785,868 ✔
638
    if (pMergedRefs) {
24,202,583 ✔
639
      // merged view already validated and deep-copied by metaBuildMergedColView;
640
      // transfer ownership to the response
641
      taosMemoryFreeClear(cfgRsp.pColRefs);
24,167,173 ✔
642
      cfgRsp.pColRefs = pMergedRefs;
24,167,173 ✔
643
      pMergedRefs = NULL;
24,167,173 ✔
644
    } else {
645
      for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
143,965 ✔
646
        SColRef *pRef = &pColRef->pColRef[i];
108,555 ✔
647
        cfgRsp.pColRefs[i].hasRef = pRef->hasRef;
108,555 ✔
648
        cfgRsp.pColRefs[i].id = pRef->id;
108,555 ✔
649
        if (cfgRsp.pColRefs[i].hasRef) {
108,555 ✔
650
          cfgRsp.pColRefs[i].refType = pRef->refType;
66,242 ✔
651
          tstrncpy(cfgRsp.pColRefs[i].refSourceName, pRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
66,242 ✔
652
          tstrncpy(cfgRsp.pColRefs[i].refSchemaName, pRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
66,242 ✔
653
          tstrncpy(cfgRsp.pColRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
66,242 ✔
654
          tstrncpy(cfgRsp.pColRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
66,242 ✔
655
          tstrncpy(cfgRsp.pColRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
66,242 ✔
656
          if (pRef->tagCondJson) {
66,242 ✔
657
            cfgRsp.pColRefs[i].tagCondLen = pRef->tagCondLen;
1,197 ✔
658
            cfgRsp.pColRefs[i].tagCondJson = taosStrdup(pRef->tagCondJson);
1,197 ✔
659
          } else {
660
            cfgRsp.pColRefs[i].tagCondLen = 0;
65,045 ✔
661
            cfgRsp.pColRefs[i].tagCondJson = NULL;
65,045 ✔
662
          }
663
        }
664
        if (pRef->filterCondLen > 0 && pRef->filterCondJson) {
108,555 ✔
665
          cfgRsp.pColRefs[i].filterCondLen = pRef->filterCondLen;
×
666
          cfgRsp.pColRefs[i].filterCondJson = taosStrdup(pRef->filterCondJson);
×
667
          if (NULL == cfgRsp.pColRefs[i].filterCondJson) {
×
668
            code = terrno;
×
669
            goto _exit;
×
670
          }
671
        }
672
      }
673
    }
674

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

687
      for (int32_t i = 0; i < cfgRsp.numOfTagRefs; i++) {
57,555,601 ✔
688
        SColRef *pRef = &pColRef->pTagRef[i];
43,107,501 ✔
689
        cfgRsp.pTagRefs[i].hasRef = pRef->hasRef;
43,107,501 ✔
690
        cfgRsp.pTagRefs[i].id = pRef->id;
43,107,501 ✔
691
        if (cfgRsp.pTagRefs[i].hasRef) {
43,107,501 ✔
692
          cfgRsp.pTagRefs[i].refType = pRef->refType;
28,640,423 ✔
693
          tstrncpy(cfgRsp.pTagRefs[i].refSourceName, pRef->refSourceName, TSDB_EXT_SOURCE_NAME_LEN);
28,640,423 ✔
694
          tstrncpy(cfgRsp.pTagRefs[i].refSchemaName, pRef->refSchemaName, TSDB_EXT_SOURCE_SCHEMA_LEN);
28,640,423 ✔
695
          tstrncpy(cfgRsp.pTagRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
28,640,423 ✔
696
          tstrncpy(cfgRsp.pTagRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
28,640,423 ✔
697
          tstrncpy(cfgRsp.pTagRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
28,640,423 ✔
698
          if (pRef->tagCondJson) {
28,640,423 ✔
699
            cfgRsp.pTagRefs[i].tagCondLen = pRef->tagCondLen;
×
700
            cfgRsp.pTagRefs[i].tagCondJson = taosStrdup(pRef->tagCondJson);
×
701
            if (NULL == cfgRsp.pTagRefs[i].tagCondJson) {
×
702
              code = terrno;
×
703
              goto _exit;
×
704
            }
705
          }
706
          if (pRef->filterCondLen > 0 && pRef->filterCondJson) {
28,640,423 ✔
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) {
36,785,868 ✔
721
    cfgRsp.numOfSeries = mer1.me.series.nSeries;
1,083 ✔
722
    cfgRsp.pSeries = taosMemoryCalloc(mer1.me.series.nSeries, sizeof(SSeriesEntry));
1,083 ✔
723
    if (cfgRsp.pSeries) {
1,083 ✔
724
      for (int32_t i = 0; i < mer1.me.series.nSeries; i++) {
2,679 ✔
725
        SSeriesEntry *src = &mer1.me.series.pSeries[i];
1,596 ✔
726
        SSeriesEntry *dst = &cfgRsp.pSeries[i];
1,596 ✔
727
        tstrncpy(dst->alias, src->alias, TSDB_COL_NAME_LEN);
1,596 ✔
728
        tstrncpy(dst->sourceName, src->sourceName, TSDB_EXT_SOURCE_NAME_LEN);
1,596 ✔
729
        tstrncpy(dst->dbName, src->dbName, TSDB_DB_NAME_LEN);
1,596 ✔
730
        tstrncpy(dst->measurementName, src->measurementName, TSDB_TABLE_NAME_LEN);
1,596 ✔
731
        if (src->tagCondLen > 0) {
1,596 ✔
732
          dst->tagCondJson = taosStrdup(src->tagCondJson);
1,596 ✔
733
          dst->tagCondLen = src->tagCondLen;
1,596 ✔
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);
36,785,868 ✔
744
  if (rspLen < 0) {
36,785,868 ✔
745
    code = terrno;
×
746
    goto _exit;
×
747
  }
748

749
  if (direct) {
36,785,868 ✔
750
    pRsp = rpcMallocCont(rspLen);
36,744,503 ✔
751
  } else {
752
    pRsp = taosMemoryCalloc(1, rspLen);
41,365 ✔
753
  }
754

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

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

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

773
  if (code) {
36,786,410 ✔
774
    qError("get table %s cfg failed cause of %s", cfgReq.tbName, tstrerror(code));
542 ✔
775
  }
776

777
  if (direct) {
36,786,410 ✔
778
    tmsgSendRsp(&rpcMsg);
36,745,045 ✔
779
  } else {
780
    *pMsg = rpcMsg;
41,365 ✔
781
  }
782

783
  tFreeSTableCfgRsp(&cfgRsp);
36,786,410 ✔
784
  taosMemoryFreeClear(pMergedCols);
36,786,410 ✔
785
  taosMemoryFreeClear(pMergedTags);
36,786,410 ✔
786
  if (pMergedRefs) {
36,786,410 ✔
787
    tFreeSColRefArray(pMergedRefs, nMergedCols);
×
788
    taosMemoryFreeClear(pMergedRefs);
×
789
  }
790
  metaReaderClear(&mer2);
36,786,410 ✔
791
  metaReaderClear(&mer1);
36,786,410 ✔
792
  return code;
36,786,410 ✔
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) {
22,848,790 ✔
805
  int32_t      code = 0;
22,848,790 ✔
806
  int32_t      rspSize = 0;
22,848,790 ✔
807
  SBatchReq    batchReq = {0};
22,848,790 ✔
808
  SBatchMsg   *req = NULL;
22,851,164 ✔
809
  SBatchRspMsg rsp = {0};
22,851,164 ✔
810
  SBatchRsp    batchRsp = {0};
22,836,406 ✔
811
  SRpcMsg      reqMsg = *pMsg;
22,837,783 ✔
812
  SRpcMsg      rspMsg = {0};
22,838,515 ✔
813
  void        *pRsp = NULL;
22,843,588 ✔
814

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

821
  int32_t msgNum = taosArrayGetSize(batchReq.pMsgs);
22,843,355 ✔
822
  if (msgNum >= MAX_META_MSG_IN_BATCH) {
22,848,058 ✔
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));
22,848,058 ✔
829
  if (NULL == batchRsp.pRsps) {
22,846,949 ✔
830
    code = terrno;
1,640 ✔
831
    qError("taosArrayInit %d SBatchRspMsg failed", msgNum);
×
832
    goto _exit;
×
833
  }
834

835
  for (int32_t i = 0; i < msgNum; ++i) {
48,480,582 ✔
836
    req = taosArrayGet(batchReq.pMsgs, i);
25,629,545 ✔
837
    if (req == NULL) {
25,624,698 ✔
838
      code = terrno;
6 ✔
839
      goto _exit;
×
840
    }
841

842
    reqMsg.msgType = req->msgType;
25,629,724 ✔
843
    reqMsg.pCont = req->msg;
25,629,724 ✔
844
    reqMsg.contLen = req->msgLen;
25,629,724 ✔
845

846
    switch (req->msgType) {
25,629,724 ✔
847
      case TDMT_VND_TABLE_META:
17,357,677 ✔
848
        // error code has been set into reqMsg, no need to handle it here.
849
        if (TSDB_CODE_SUCCESS != vnodeGetTableMeta(pVnode, &reqMsg, false)) {
17,357,677 ✔
850
          qWarn("vnodeGetBatchMeta failed, msgType:%d", req->msgType);
1,454,742 ✔
851
        }
852
        break;
17,354,843 ✔
853
      case TDMT_VND_TABLE_NAME:
78,324 ✔
854
        // error code has been set into reqMsg, no need to handle it here.
855
        if (TSDB_CODE_SUCCESS != vnodeGetTableMeta(pVnode, &reqMsg, false)) {
78,324 ✔
856
          qWarn("vnodeGetBatchName failed, msgType:%d", req->msgType);
22,306 ✔
857
        }
858
        break;
78,324 ✔
859
      case TDMT_VND_TABLE_CFG:
41,365 ✔
860
        // error code has been set into reqMsg, no need to handle it here.
861
        if (TSDB_CODE_SUCCESS != vnodeGetTableCfg(pVnode, &reqMsg, false)) {
41,365 ✔
862
          qWarn("vnodeGetBatchMeta failed, msgType:%d", req->msgType);
×
863
        }
864
        break;
41,365 ✔
865
      case TDMT_VND_VSUBTABLES_META:
8,152,358 ✔
866
        // error code has been set into reqMsg, no need to handle it here.
867
        if (TSDB_CODE_SUCCESS != vnodeGetVSubtablesMeta(pVnode, &reqMsg)) {
8,152,358 ✔
868
          qWarn("vnodeGetVSubtablesMeta failed, msgType:%d", req->msgType);
×
869
        }
870
        break;
8,156,695 ✔
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;
25,635,107 ✔
892
    rsp.reqType = reqMsg.msgType;
25,635,107 ✔
893
    rsp.msgLen = reqMsg.contLen;
25,635,107 ✔
894
    rsp.rspCode = reqMsg.code;
25,635,107 ✔
895
    rsp.msg = reqMsg.pCont;
25,635,107 ✔
896

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

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

922
_exit:
22,855,269 ✔
923

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

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

934
  taosArrayDestroyEx(batchReq.pMsgs, tFreeSBatchReqMsg);
22,854,932 ✔
935
  taosArrayDestroyEx(batchRsp.pRsps, tFreeSBatchRspMsg);
22,854,022 ✔
936

937
  tmsgSendRsp(&rspMsg);
22,852,270 ✔
938

939
  return code;
22,855,637 ✔
940
}
941

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

949
int32_t vnodeReadVSubtables(SReadHandle* pHandle, int64_t suid, SArray** ppRes) {
8,148,607 ✔
950
  int32_t                    code = TSDB_CODE_SUCCESS;
8,148,607 ✔
951
  int32_t                    line = 0;
8,151,281 ✔
952
  SMetaReader                mr = {0};
8,151,281 ✔
953
  bool                       readerInit = false;
8,130,019 ✔
954
  SVCTableRefCols*           pTb = NULL;
8,130,019 ✔
955
  int32_t                    refColsNum = 0;
8,131,711 ✔
956
  char                       tbFName[TSDB_TABLE_FNAME_LEN];
8,131,711 ✔
957
  SSHashObj*                 pSrcTbls = NULL;
8,130,424 ✔
958
  SSHashObj*                 pContentDedup = NULL;
8,130,424 ✔
959

960
  SArray *pList = taosArrayInit(10, sizeof(uint64_t));
8,130,424 ✔
961
  QUERY_CHECK_NULL(pList, code, line, _return, terrno);
8,143,256 ✔
962

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

965
  size_t num = taosArrayGetSize(pList);
8,153,955 ✔
966
  *ppRes = taosArrayInit(num, POINTER_BYTES);
8,154,177 ✔
967
  QUERY_CHECK_NULL(*ppRes, code, line, _return, terrno);
8,155,151 ✔
968
  pSrcTbls = tSimpleHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
8,155,151 ✔
969
  QUERY_CHECK_NULL(pSrcTbls, code, line, _return, terrno);
8,145,659 ✔
970
  pContentDedup = tSimpleHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
8,145,659 ✔
971
  QUERY_CHECK_NULL(pContentDedup, code, line, _return, terrno);
8,145,955 ✔
972

973
  for (int32_t i = 0; i < num; ++i) {
56,218,143 ✔
974
    uint64_t* id = taosArrayGet(pList, i);
48,059,348 ✔
975
    QUERY_CHECK_NULL(id, code, line, _return, terrno);
48,042,977 ✔
976
    pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn, pHandle->txnId);
48,042,977 ✔
977
    QUERY_CHECK_CODE(pHandle->api.metaReaderFn.getTableEntryByUid(&mr, *id), line, _return);
48,069,662 ✔
978
    readerInit = true;
47,992,856 ✔
979

980
    refColsNum = 0;
47,986,196 ✔
981
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
533,786,986 ✔
982
      if (mr.me.colRef.pColRef[j].hasRef) {
485,798,570 ✔
983
        refColsNum++;
274,839,050 ✔
984
      }
985
    }
986

987
    int32_t tagRefColsNum = 0;
47,986,196 ✔
988
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
90,438,707 ✔
989
      if (mr.me.colRef.pTagRef[j].hasRef) {
42,450,291 ✔
990
        tagRefColsNum++;
28,325,517 ✔
991
      }
992
    }
993

994
    if (refColsNum <= 0 && tagRefColsNum <= 0) {
47,988,416 ✔
995
      pHandle->api.metaReaderFn.clearReader(&mr);
7,779,003 ✔
996
      readerInit = false;
7,779,003 ✔
997
      continue;
7,779,003 ✔
998
    }
999

1000
    // Size the compact block (entries + string arena) and count source tables.
1001
    uint64_t arenaBytes = 0;
40,209,413 ✔
1002
    tSimpleHashClear(pSrcTbls);
40,209,413 ✔
1003
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
402,360,051 ✔
1004
      if (!mr.me.colRef.pColRef[j].hasRef) {
362,203,553 ✔
1005
        continue;
86,967,227 ✔
1006
      }
1007

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

1018
      snprintf(tbFName, sizeof(tbFName), "%s.%s", mr.me.colRef.pColRef[j].refDbName, mr.me.colRef.pColRef[j].refTableName);
275,236,326 ✔
1019

1020
      if (NULL == tSimpleHashGet(pSrcTbls, tbFName, strlen(tbFName))) {
275,236,326 ✔
1021
        QUERY_CHECK_CODE(tSimpleHashPut(pSrcTbls, tbFName, strlen(tbFName), &code, sizeof(code)), line, _return);
53,994,596 ✔
1022
      }
1023
    }
1024
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
82,696,735 ✔
1025
      if (!mr.me.colRef.pTagRef[j].hasRef) {
42,512,031 ✔
1026
        continue;
14,160,077 ✔
1027
      }
1028

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

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

1041
      if (NULL == tSimpleHashGet(pSrcTbls, tbFName, strlen(tbFName))) {
28,351,954 ✔
1042
        QUERY_CHECK_CODE(tSimpleHashPut(pSrcTbls, tbFName, strlen(tbFName), &code, sizeof(code)), line, _return);
655,234 ✔
1043
      }
1044
    }
1045

1046
    SVctRefContent* pContent = tVctRefContentAlloc(refColsNum, tagRefColsNum, arenaBytes);
40,184,704 ✔
1047
    QUERY_CHECK_NULL(pContent, code, line, _return, terrno);
40,221,910 ✔
1048

1049
    uint32_t arenaPos = 0;
40,221,910 ✔
1050
    int32_t  colIdx = 0;
40,224,387 ✔
1051
    for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
401,463,385 ✔
1052
      if (!mr.me.colRef.pColRef[j].hasRef) {
361,518,574 ✔
1053
        continue;
86,932,357 ✔
1054
      }
1055

1056
      SRefColEntry* pEntry = vctContentColAt(pContent, colIdx);
274,586,217 ✔
1057
      pEntry->colId = mr.me.colRef.pColRef[j].id;
274,586,217 ✔
1058
      if (mr.me.colRef.pColRef[j].filterCondLen > 0) {
274,586,217 ✔
1059
        pEntry->flags |= VCT_REF_FLAG_HAS_FILTER_COND;
×
1060
      }
1061
      pEntry->dbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refDbName);
274,586,217 ✔
1062
      pEntry->tbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refTableName);
274,940,689 ✔
1063
      pEntry->colOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refColName);
274,959,512 ✔
1064
      pEntry->srcOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refSourceName);
274,958,201 ✔
1065
      pEntry->schemaOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pColRef[j].refSchemaName);
274,705,296 ✔
1066
      colIdx++;
274,306,641 ✔
1067
    }
1068

1069
    // Fill tag refs
1070
    int32_t tagIdx = 0;
39,942,591 ✔
1071
    for (int32_t j = 0; j < mr.me.colRef.nTagRefs; j++) {
82,350,718 ✔
1072
      if (!mr.me.colRef.pTagRef[j].hasRef) {
42,460,080 ✔
1073
        continue;
14,142,059 ✔
1074
      }
1075

1076
      SRefColEntry* pEntry = vctContentTagAt(pContent, tagIdx);
28,318,021 ✔
1077
      pEntry->colId = mr.me.colRef.pTagRef[j].id;
28,318,021 ✔
1078
      pEntry->dbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refDbName);
28,318,021 ✔
1079
      pEntry->tbOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refTableName);
28,337,600 ✔
1080
      pEntry->colOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refColName);
28,328,814 ✔
1081
      pEntry->srcOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refSourceName);
28,337,432 ✔
1082
      pEntry->schemaOff = tVctRefContentPutStr(pContent, &arenaPos, mr.me.colRef.pTagRef[j].refSchemaName);
28,321,799 ✔
1083
      tagIdx++;
28,263,848 ✔
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);
39,890,638 ✔
1089
    if (NULL != ppKept) {
40,303,159 ✔
1090
      taosMemoryFree(pContent);
2,143,937 ✔
1091
      pContent = *ppKept;
2,145,569 ✔
1092
    } else {
1093
      code = tSimpleHashPut(pContentDedup, pContent, (uint32_t)pContent->bufLen, &pContent, sizeof(pContent));
38,159,222 ✔
1094
      if (code) {
38,170,068 ✔
1095
        // the block is owned by no one else yet; release it on the way out
1096
        taosMemoryFree(pContent);
×
1097
        QUERY_CHECK_CODE(code, line, _return);
×
1098
      }
1099
    }
1100

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

1107
    QUERY_CHECK_NULL(taosArrayPush(*ppRes, &pTb), code, line, _return, terrno);
80,562,620 ✔
1108
    pTb = NULL;
40,290,991 ✔
1109

1110
    pHandle->api.metaReaderFn.clearReader(&mr);
40,290,991 ✔
1111
    readerInit = false;
40,283,011 ✔
1112
  }
1113

1114
_return:
8,158,679 ✔
1115

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

1120
  taosArrayDestroy(pList);
8,159,938 ✔
1121
  taosMemoryFree(pTb);
8,159,737 ✔
1122
  tSimpleHashCleanup(pSrcTbls);
8,159,533 ✔
1123
  tSimpleHashCleanup(pContentDedup);
8,159,132 ✔
1124

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1213
_return:
×
1214

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

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

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

1229
int32_t vnodeGetVSubtablesMeta(SVnode *pVnode, SRpcMsg *pMsg) {
8,144,022 ✔
1230
  int32_t        code = 0;
8,144,022 ✔
1231
  int32_t        rspSize = 0;
8,144,022 ✔
1232
  SVSubTablesReq req = {0};
8,144,022 ✔
1233
  SVSubTablesRsp rsp = {0};
8,145,354 ✔
1234
  SRpcMsg      rspMsg = {0};
8,127,155 ✔
1235
  void        *pRsp = NULL;
8,127,155 ✔
1236
  int32_t      line = 0;
8,127,155 ✔
1237

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

1244
  SReadHandle handle = {0};
8,150,027 ✔
1245
  handle.vnode = pVnode;
8,151,412 ✔
1246
  initStorageAPI(&handle.api);
8,151,412 ✔
1247

1248
  QUERY_CHECK_CODE(vnodeReadVSubtables(&handle, req.suid, &rsp.pTables), line, _return);
8,138,450 ✔
1249
  rsp.vgId = TD_VID(pVnode);
8,160,126 ✔
1250

1251
  rspSize = tSerializeSVSubTablesRsp(NULL, 0, &rsp);
8,160,126 ✔
1252
  if (rspSize < 0) {
8,158,998 ✔
1253
    code = rspSize;
×
1254
    qError("tSerializeSVSubTablesRsp failed, error:%d", rspSize);
×
1255
    goto _return;
×
1256
  }
1257
  pRsp = taosMemoryCalloc(1, rspSize);
8,158,998 ✔
1258
  if (pRsp == NULL) {
8,156,925 ✔
1259
    code = terrno;
×
1260
    qError("rpcMallocCont %d failed, error:%d", rspSize, terrno);
×
1261
    goto _return;
×
1262
  }
1263
  rspSize = tSerializeSVSubTablesRsp(pRsp, rspSize, &rsp);
8,156,925 ✔
1264
  if (rspSize < 0) {
8,159,953 ✔
1265
    code = rspSize;
×
1266
    qError("tSerializeSVSubTablesRsp failed, error:%d", rspSize);
×
1267
    goto _return;
×
1268
  }
1269

1270
_return:
8,159,953 ✔
1271

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

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

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

1286
  //tmsgSendRsp(&rspMsg);
1287

1288
  return code;
8,159,348 ✔
1289
}
1290

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

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

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

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

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

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

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

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

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

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

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

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

1511
static int32_t vnodeGetCompStorage(SVnode *pVnode, int64_t *output) {
61,648,865 ✔
1512
  int32_t code = 0;
61,648,865 ✔
1513
#ifdef TD_ENTERPRISE
1514
  int32_t now = taosGetTimestampSec();
61,648,865 ✔
1515
  if (llabs(now - pVnode->config.vndStats.storageLastUpd) >= 30) {
61,648,865 ✔
1516
    pVnode->config.vndStats.storageLastUpd = now;
3,323,674 ✔
1517

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

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

1543
    if (pVnode->inUse) {
61,648,865 ✔
1544
      *bufferSegmentUsed = pVnode->inUse->size;
61,644,491 ✔
1545
    }
1546
    *bufferSegmentSize = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
61,648,865 ✔
1547

1548
    (void)taosThreadMutexUnlock(&pVnode->mutex);
61,648,865 ✔
1549
  }
1550
}
61,648,865 ✔
1551

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

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

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

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

1642
  if (dbname) {
31,115,383 ✔
1643
    *dbname = pConf->dbname;
30,992,720 ✔
1644
  }
1645

1646
  if (vgId) {
31,115,383 ✔
1647
    *vgId = TD_VID(pVnodeObj);
30,251,574 ✔
1648
  }
1649

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

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

1674
  uint32_t hashValue = taosGetTbHashVal(tbFName, (int32_t)strlen(tbFName), pVnodeObj->config.hashMethod,
256,404 ✔
1675
                                        pVnodeObj->config.hashPrefix, pVnodeObj->config.hashSuffix);
128,198 ✔
1676
  return hashValue >= pVnodeObj->config.hashBegin && hashValue <= pVnodeObj->config.hashEnd;
128,206 ✔
1677
}
1678

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

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

1689
int32_t vnodeGetTableList(void *pVnode, int8_t type, SArray *pList) {
3,046 ✔
1690
  if (type == TSDB_SUPER_TABLE) {
3,046 ✔
1691
    return vnodeGetStbIdList(pVnode, 0, pList);
3,046 ✔
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) {
94,175,101 ✔
1728
  int32_t      code = TSDB_CODE_SUCCESS;
94,175,101 ✔
1729
  SVnode      *pVnodeObj = pVnode;
94,175,101 ✔
1730
  SMCtbCursor *pCur = metaOpenCtbCursor(pVnodeObj, suid, 1, 0);
94,175,101 ✔
1731
  if (NULL == pCur) {
94,155,247 ✔
1732
    qError("vnode get ctb id list failed, suid:%" PRId64, suid);
×
1733
    return terrno;
×
1734
  }
1735

1736
  while (1) {
342,723,503 ✔
1737
    tb_uid_t id = metaCtbCursorNext(pCur);
436,878,750 ✔
1738
    if (id == 0) {
436,646,718 ✔
1739
      break;
94,193,937 ✔
1740
    }
1741
    qTrace("vnodeGetCtbIdList: got ctb id %" PRId64 " for suid %" PRId64, id, suid);
342,441,793 ✔
1742
    if (NULL == taosArrayPush(list, &id)) {
342,564,263 ✔
1743
      qError("taosArrayPush failed");
×
1744
      code = terrno;
×
1745
      goto _exit;
×
1746
    }
1747
  }
1748

1749
_exit:
94,003,639 ✔
1750
  metaCloseCtbCursor(pCur);
94,003,639 ✔
1751
  return code;
94,146,519 ✔
1752
}
1753

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

1761
  while (1) {
18,875,483 ✔
1762
    tb_uid_t id = metaStbCursorNext(pCur);
60,318,149 ✔
1763
    if (id == 0) {
60,319,203 ✔
1764
      break;
41,437,397 ✔
1765
    }
1766

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

1774
_exit:
41,442,953 ✔
1775
  metaCloseStbCursor(pCur);
41,442,953 ✔
1776
  return code;
41,442,186 ✔
1777
}
1778

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

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

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

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

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

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

1815
  *num = 0;
1,971,631 ✔
1816
  while (1) {
1,272,260 ✔
1817
    tb_uid_t id = metaCtbCursorNext(pCur);
3,243,476 ✔
1818
    if (id == 0) {
3,243,516 ✔
1819
      break;
1,971,385 ✔
1820
    }
1821

1822
    ++(*num);
1,271,845 ✔
1823
  }
1824

1825
  metaCloseCtbCursor(pCur);
1,971,671 ✔
1826
  return TSDB_CODE_SUCCESS;
1,971,839 ✔
1827
}
1828

1829
int32_t vnodeGetStbColumnNum(SVnode *pVnode, tb_uid_t suid, int *num) {
1,971,731 ✔
1830
  SSchemaWrapper *pSW = metaGetTableSchema(pVnode->pMeta, suid, -1, 0, NULL, 0, false);
1,971,731 ✔
1831
  if (pSW) {
1,971,939 ✔
1832
    *num = pSW->nCols;
1,967,980 ✔
1833
    tDeleteSchemaWrapper(pSW);
572 ✔
1834
  } else {
1835
    *num = 2;
3,959 ✔
1836
  }
1837

1838
  return TSDB_CODE_SUCCESS;
1,971,939 ✔
1839
}
1840

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

1845
  int32_t code = metaReaderGetTableEntryByUid(&mr, suid);
1,971,939 ✔
1846
  if (code == TSDB_CODE_SUCCESS) {
1,971,939 ✔
1847
    if (keep) *keep = mr.me.stbEntry.keep;
1,967,980 ✔
1848
    if (flags) *flags = mr.me.flags;
1,967,980 ✔
1849
  } else {
1850
    if (keep) *keep = 0;
3,959 ✔
1851
    if (flags) *flags = 0;
3,959 ✔
1852
  }
1853

1854
  metaReaderClear(&mr);
1,971,939 ✔
1855
  return TSDB_CODE_SUCCESS;
1,971,939 ✔
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) {
41,442,034 ✔
1933
  int32_t      code = TSDB_CODE_SUCCESS;
41,442,034 ✔
1934
  int32_t      tbNum = 0;
41,442,034 ✔
1935
  const char **pTbArr = NULL;
41,442,034 ✔
1936
  const char  *dbName = NULL;
41,442,034 ✔
1937
  *tbSize = 0;
41,442,034 ✔
1938

1939
  if (!(dbName = strchr(pVnode->config.dbname, '.'))) return 0;
41,442,034 ✔
1940
  if (0 == strncmp(++dbName, "log", TSDB_DB_NAME_LEN)) {
41,442,034 ✔
1941
    tbNum = tkLogStbNum;
2,784 ✔
1942
    pTbArr = (const char **)&tkLogStb;
2,784 ✔
1943
  } else if (0 == strncmp(dbName, "audit", TSDB_DB_NAME_LEN) || pVnode->config.isAudit) {
41,439,250 ✔
1944
    tbNum = tkAuditStbNum;
2,026 ✔
1945
    pTbArr = (const char **)&tkAuditStb;
2,026 ✔
1946
  }
1947
  if (tbNum && pTbArr) {
41,442,034 ✔
1948
    *tbSize = metaSizeOfTbFilterCache(pVnode->pMeta, 0);
4,810 ✔
1949
    if (*tbSize < tbNum) {
4,810 ✔
1950
      for (int32_t i = 0; i < tbNum; ++i) {
137,750 ✔
1951
        tb_uid_t suid = metaGetTableEntryUidByName(pVnode->pMeta, pTbArr[i]);
135,517 ✔
1952
        if (suid != 0) {
135,517 ✔
1953
          code = metaPutTbToFilterCache(pVnode->pMeta, &suid, 0);
1,727 ✔
1954
          if (TSDB_CODE_SUCCESS != code) {
1,727 ✔
1955
            return code;
1,044 ✔
1956
          }
1957
        }
1958
      }
1959
      *tbSize = metaSizeOfTbFilterCache(pVnode->pMeta, 0);
2,233 ✔
1960
    }
1961
  }
1962

1963
  return code;
41,434,764 ✔
1964
}
1965
#endif
1966

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

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

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

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

1983
  int32_t tbFilterSize = 0;
41,442,541 ✔
1984
  int32_t code = TSDB_CODE_SUCCESS;
41,441,977 ✔
1985
#ifdef TD_ENTERPRISE
1986
  code = vnodeGetTimeSeriesBlackList(pVnode, &tbFilterSize);
41,441,977 ✔
1987
  if (TSDB_CODE_SUCCESS != code) {
41,442,361 ✔
1988
    goto _exit;
1,044 ✔
1989
  }
1990
#endif
1991

1992
  if ((!tbFilterSize && vnodeGetStbIdList(pVnode, 0, suidList) < 0) ||
41,441,317 ✔
1993
      (tbFilterSize && vnodeGetStbIdListByFilter(pVnode, 0, suidList, vnodeTimeSeriesFilter, pVnode) < 0)) {
41,434,636 ✔
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;
41,440,510 ✔
2000
  int64_t arrSize = taosArrayGetSize(suidList);
41,440,510 ✔
2001
  for (int64_t i = 0; i < arrSize; ++i) {
60,312,140 ✔
2002
    tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i);
18,870,146 ✔
2003

2004
    int64_t ctbNum = 0;
18,870,089 ✔
2005
    int32_t numOfCols = 0;
18,871,093 ✔
2006
    int8_t  flags = 0;
18,870,873 ✔
2007
    code = metaGetStbStats(pVnode, suid, &ctbNum, &numOfCols, &flags);
18,870,213 ✔
2008
    if (TSDB_CODE_SUCCESS != code) {
18,870,270 ✔
2009
      goto _exit;
×
2010
    }
2011
    if (!TABLE_IS_VIRTUAL(flags)) {
18,870,270 ✔
2012
      *num += ctbNum * (numOfCols - 1);
15,839,113 ✔
2013
    }
2014
  }
2015

2016
_exit:
41,442,818 ✔
2017
  taosArrayDestroy(suidList);
41,442,794 ✔
2018
  return TSDB_CODE_SUCCESS;
41,442,263 ✔
2019
}
2020

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

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

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

2041
    *num += ctbNum;
×
2042
  }
2043

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

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

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

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

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

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

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

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

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

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

2104
  code = tsdbGetFsSize(pVnodeObj->pTsdb, pInfo);
3,325,786 ✔
2105
_exit:
3,325,160 ✔
2106
  return code;
3,325,160 ✔
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