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

taosdata / TDengine / #3610

12 Feb 2025 09:54AM UTC coverage: 54.713% (-8.4%) from 63.066%
#3610

push

travis-ci

web-flow
Merge pull request #29745 from taosdata/fix/TD33664-3.0

fix: --version show information check for 3.0

120957 of 286549 branches covered (42.21%)

Branch coverage included in aggregate %.

190849 of 283342 relevant lines covered (67.36%)

4969786.97 hits per line

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

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

16
#include "meta.h"
17

18
extern SDmNotifyHandle dmNotifyHdl;
19

20
int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
21
int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
22
int32_t metaAlterTableColumnName(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
23
int32_t metaAlterTableColumnBytes(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
24
int32_t metaUpdateTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
25
int32_t metaUpdateTableMultiTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
26
int32_t metaUpdateTableOptions2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
27
int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
28

29
int32_t metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
30

31
int32_t    metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
32
static int metaUpdateChangeTime(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs);
33
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *pSuid, int8_t *pSysTbl);
34
void       metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey);
35
// opt ins_tables query
36
static int metaDeleteBtimeIdx(SMeta *pMeta, const SMetaEntry *pME);
37
static int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
38

39
int32_t updataTableColCmpr(SColCmprWrapper *pWp, SSchema *pSchema, int8_t add, uint32_t compress) {
48✔
40
  int32_t nCols = pWp->nCols;
48✔
41
  int32_t ver = pWp->version;
48✔
42
  if (add) {
48✔
43
    SColCmpr *p = taosMemoryRealloc(pWp->pColCmpr, sizeof(SColCmpr) * (nCols + 1));
30!
44
    if (p == NULL) {
30!
45
      return terrno;
×
46
    }
47
    pWp->pColCmpr = p;
30✔
48

49
    SColCmpr *pCol = p + nCols;
30✔
50
    pCol->id = pSchema->colId;
30✔
51
    pCol->alg = compress;
30✔
52
    pWp->nCols = nCols + 1;
30✔
53
    pWp->version = ver;
30✔
54
  } else {
55
    for (int32_t i = 0; i < nCols; i++) {
50!
56
      SColCmpr *pOCmpr = &pWp->pColCmpr[i];
50✔
57
      if (pOCmpr->id == pSchema->colId) {
50✔
58
        int32_t left = (nCols - i - 1) * sizeof(SColCmpr);
18✔
59
        if (left) {
18✔
60
          memmove(pWp->pColCmpr + i, pWp->pColCmpr + i + 1, left);
16✔
61
        }
62
        nCols--;
18✔
63
        break;
18✔
64
      }
65
    }
66
    pWp->nCols = nCols;
18✔
67
    pWp->version = ver;
18✔
68
  }
69
  return 0;
48✔
70
}
71

72
int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
10,385✔
73
  pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
10,385!
74
  if (NULL == pMetaRsp->pSchemas) {
10,385!
75
    return terrno;
×
76
  }
77

78
  pMetaRsp->pSchemaExt = taosMemoryMalloc(pSchema->nCols * sizeof(SSchemaExt));
10,385!
79
  if (pMetaRsp->pSchemaExt == NULL) {
10,385!
80
    taosMemoryFree(pMetaRsp->pSchemas);
×
81
    return terrno;
×
82
  }
83

84
  tstrncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
10,385✔
85
  pMetaRsp->numOfColumns = pSchema->nCols;
10,385✔
86
  pMetaRsp->tableType = TSDB_NORMAL_TABLE;
10,385✔
87
  pMetaRsp->sversion = pSchema->version;
10,385✔
88
  pMetaRsp->tuid = uid;
10,385✔
89

90
  memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
10,385✔
91

92
  return 0;
10,385✔
93
}
94

95
int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
166✔
96
  int32_t code = 0;
166✔
97

98
#ifdef USE_INVERTED_INDEX
99
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
166!
100
    return TSDB_CODE_INVALID_PARA;
×
101
  }
102
  void       *data = pCtbEntry->ctbEntry.pTags;
166✔
103
  const char *tagName = pSchema->name;
166✔
104

105
  tb_uid_t    suid = pCtbEntry->ctbEntry.suid;
166✔
106
  tb_uid_t    tuid = pCtbEntry->uid;
166✔
107
  const void *pTagData = pCtbEntry->ctbEntry.pTags;
166✔
108
  int32_t     nTagData = 0;
166✔
109

110
  SArray *pTagVals = NULL;
166✔
111
  code = tTagToValArray((const STag *)data, &pTagVals);
166✔
112
  if (code) {
166!
113
    return code;
×
114
  }
115

116
  SIndexMultiTerm *terms = indexMultiTermCreate();
166✔
117
  if (terms == NULL) {
166!
118
    return terrno;
×
119
  }
120

121
  int16_t nCols = taosArrayGetSize(pTagVals);
166✔
122
  for (int i = 0; i < nCols; i++) {
384✔
123
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
218✔
124
    char     type = pTagVal->type;
218✔
125

126
    char   *key = pTagVal->pKey;
218✔
127
    int32_t nKey = strlen(key);
218✔
128

129
    SIndexTerm *term = NULL;
218✔
130
    if (type == TSDB_DATA_TYPE_NULL) {
218✔
131
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
24✔
132
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
194✔
133
      if (pTagVal->nData > 0) {
98✔
134
        char *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
82!
135
        if (val == NULL) {
82!
136
          TAOS_CHECK_GOTO(terrno, NULL, _exception);
×
137
        }
138
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE, NULL);
82✔
139
        if (len < 0) {
82!
140
          TAOS_CHECK_GOTO(len, NULL, _exception);
×
141
        }
142
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
82✔
143
        type = TSDB_DATA_TYPE_VARCHAR;
82✔
144
        term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, val, len);
82✔
145
        taosMemoryFree(val);
82!
146
      } else if (pTagVal->nData == 0) {
16!
147
        term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, pTagVal->pData, 0);
16✔
148
      }
149
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
96✔
150
      double val = *(double *)(&pTagVal->i64);
72✔
151
      int    len = sizeof(val);
72✔
152
      term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
72✔
153
    } else if (type == TSDB_DATA_TYPE_BOOL) {
24!
154
      int val = *(int *)(&pTagVal->i64);
24✔
155
      int len = sizeof(val);
24✔
156
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_BOOL, key, nKey, (const char *)&val, len);
24✔
157
    }
158

159
    if (term != NULL) {
218!
160
      int32_t ret = indexMultiTermAdd(terms, term);
218✔
161
      if (ret < 0) {
218!
162
        metaError("vgId:%d, failed to add term to multi term, uid: %" PRId64 ", key: %s, type: %d, ret: %d",
×
163
                  TD_VID(pMeta->pVnode), tuid, key, type, ret);
164
      }
165
    } else {
166
      code = terrno;
×
167
      goto _exception;
×
168
    }
169
  }
170
  code = indexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
166✔
171
  indexMultiTermDestroy(terms);
166✔
172

173
  taosArrayDestroy(pTagVals);
166✔
174
#endif
175
  return code;
166✔
176
_exception:
×
177
  indexMultiTermDestroy(terms);
×
178
  taosArrayDestroy(pTagVals);
×
179
  return code;
×
180
}
181
int metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
16✔
182
#ifdef USE_INVERTED_INDEX
183
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
16!
184
    return TSDB_CODE_INVALID_PARA;
×
185
  }
186
  void       *data = pCtbEntry->ctbEntry.pTags;
16✔
187
  const char *tagName = pSchema->name;
16✔
188

189
  tb_uid_t    suid = pCtbEntry->ctbEntry.suid;
16✔
190
  tb_uid_t    tuid = pCtbEntry->uid;
16✔
191
  const void *pTagData = pCtbEntry->ctbEntry.pTags;
16✔
192
  int32_t     nTagData = 0;
16✔
193

194
  SArray *pTagVals = NULL;
16✔
195
  int32_t code = tTagToValArray((const STag *)data, &pTagVals);
16✔
196
  if (code) {
16!
197
    return code;
×
198
  }
199

200
  SIndexMultiTerm *terms = indexMultiTermCreate();
16✔
201
  if (terms == NULL) {
16!
202
    return terrno;
×
203
  }
204

205
  int16_t nCols = taosArrayGetSize(pTagVals);
16✔
206
  for (int i = 0; i < nCols; i++) {
48✔
207
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
32✔
208
    char     type = pTagVal->type;
32✔
209

210
    char   *key = pTagVal->pKey;
32✔
211
    int32_t nKey = strlen(key);
32✔
212

213
    SIndexTerm *term = NULL;
32✔
214
    if (type == TSDB_DATA_TYPE_NULL) {
32!
215
      term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
×
216
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
32✔
217
      if (pTagVal->nData > 0) {
12!
218
        char *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
12!
219
        if (val == NULL) {
12!
220
          TAOS_CHECK_GOTO(terrno, NULL, _exception);
×
221
        }
222
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE, NULL);
12✔
223
        if (len < 0) {
12!
224
          TAOS_CHECK_GOTO(len, NULL, _exception);
×
225
        }
226
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
12✔
227
        type = TSDB_DATA_TYPE_VARCHAR;
12✔
228
        term = indexTermCreate(suid, DEL_VALUE, type, key, nKey, val, len);
12✔
229
        taosMemoryFree(val);
12!
230
      } else if (pTagVal->nData == 0) {
×
231
        term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, pTagVal->pData, 0);
×
232
      }
233
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
20✔
234
      double val = *(double *)(&pTagVal->i64);
12✔
235
      int    len = sizeof(val);
12✔
236
      term = indexTermCreate(suid, DEL_VALUE, type, key, nKey, (const char *)&val, len);
12✔
237
    } else if (type == TSDB_DATA_TYPE_BOOL) {
8!
238
      int val = *(int *)(&pTagVal->i64);
8✔
239
      int len = sizeof(val);
8✔
240
      term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_BOOL, key, nKey, (const char *)&val, len);
8✔
241
    }
242
    if (term != NULL) {
32!
243
      int32_t ret = indexMultiTermAdd(terms, term);
32✔
244
      if (ret < 0) {
32!
245
        metaError("vgId:%d, failed to add term to multi term, uid: %" PRId64 ", key: %s, type: %d, ret: %d",
×
246
                  TD_VID(pMeta->pVnode), tuid, key, type, ret);
247
      }
248
    } else {
249
      code = terrno;
×
250
      goto _exception;
×
251
    }
252
  }
253
  code = indexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
16✔
254
  indexMultiTermDestroy(terms);
16✔
255
  taosArrayDestroy(pTagVals);
16✔
256
#endif
257
  return code;
16✔
258
_exception:
×
259
  indexMultiTermDestroy(terms);
×
260
  taosArrayDestroy(pTagVals);
×
261
  return code;
×
262
}
263

264
void metaTimeSeriesNotifyCheck(SMeta *pMeta) {
127✔
265
#if defined(TD_ENTERPRISE)
266
  int64_t nTimeSeries = metaGetTimeSeriesNum(pMeta, 0);
127✔
267
  int64_t deltaTS = nTimeSeries - pMeta->pVnode->config.vndStats.numOfReportedTimeSeries;
127✔
268
  if (deltaTS > tsTimeSeriesThreshold) {
127!
269
    if (0 == atomic_val_compare_exchange_8(&dmNotifyHdl.state, 1, 2)) {
×
270
      if (tsem_post(&dmNotifyHdl.sem) != 0) {
×
271
        metaError("vgId:%d, failed to post semaphore, errno:%d", TD_VID(pMeta->pVnode), errno);
×
272
      }
273
    }
274
  }
275
#endif
276
}
127✔
277

278
static int32_t metaDropTables(SMeta *pMeta, SArray *tbUids) {
25✔
279
  int32_t code = 0;
25✔
280
  if (taosArrayGetSize(tbUids) == 0) return TSDB_CODE_SUCCESS;
25!
281

282
  int64_t    nCtbDropped = 0;
25✔
283
  SSHashObj *suidHash = tSimpleHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
25✔
284
  if (suidHash == NULL) {
25!
285
    return terrno;
×
286
  }
287

288
  metaWLock(pMeta);
25✔
289
  for (int i = 0; i < taosArrayGetSize(tbUids); ++i) {
252✔
290
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(tbUids, i);
227✔
291
    tb_uid_t suid = 0;
227✔
292
    int8_t   sysTbl = 0;
227✔
293
    int      type;
294
    code = metaDropTableByUid(pMeta, uid, &type, &suid, &sysTbl);
227✔
295
    if (code) return code;
227!
296
    if (!sysTbl && type == TSDB_CHILD_TABLE && suid != 0 && suidHash) {
227!
297
      int64_t *pVal = tSimpleHashGet(suidHash, &suid, sizeof(tb_uid_t));
226✔
298
      if (pVal) {
226✔
299
        nCtbDropped = *pVal + 1;
202✔
300
      } else {
301
        nCtbDropped = 1;
24✔
302
      }
303
      code = tSimpleHashPut(suidHash, &suid, sizeof(tb_uid_t), &nCtbDropped, sizeof(int64_t));
226✔
304
      if (code) return code;
226!
305
    }
306
    /*
307
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
308
      tsdbCacheDropTable(pMeta->pVnode->pTsdb, uid, suid, NULL);
309
    }
310
    */
311
    metaDebug("batch drop table:%" PRId64, uid);
227!
312
  }
313
  metaULock(pMeta);
25✔
314

315
  // update timeseries
316
  void   *pCtbDropped = NULL;
25✔
317
  int32_t iter = 0;
25✔
318
  while ((pCtbDropped = tSimpleHashIterate(suidHash, pCtbDropped, &iter))) {
49✔
319
    tb_uid_t    *pSuid = tSimpleHashGetKey(pCtbDropped, NULL);
24✔
320
    int32_t      nCols = 0;
24✔
321
    SVnodeStats *pStats = &pMeta->pVnode->config.vndStats;
24✔
322
    if (metaGetStbStats(pMeta->pVnode, *pSuid, NULL, &nCols) == 0) {
24!
323
      pStats->numOfTimeSeries -= *(int64_t *)pCtbDropped * (nCols - 1);
24✔
324
    }
325
  }
326
  tSimpleHashCleanup(suidHash);
25✔
327

328
  pMeta->changed = true;
25✔
329
  return 0;
25✔
330
}
331

332
static int32_t metaFilterTableByHash(SMeta *pMeta, SArray *uidList) {
28✔
333
  int32_t code = 0;
28✔
334
  // 1, tranverse table's
335
  // 2, validate table name using vnodeValidateTableHash
336
  // 3, push invalidated table's uid into uidList
337

338
  TBC *pCur;
339
  code = tdbTbcOpen(pMeta->pTbDb, &pCur, NULL);
28✔
340
  if (code < 0) {
28!
341
    return code;
×
342
  }
343

344
  code = tdbTbcMoveToFirst(pCur);
28✔
345
  if (code) {
28!
346
    tdbTbcClose(pCur);
×
347
    return code;
×
348
  }
349

350
  void *pData = NULL, *pKey = NULL;
28✔
351
  int   nData = 0, nKey = 0;
28✔
352

353
  while (1) {
480✔
354
    int32_t ret = tdbTbcNext(pCur, &pKey, &nKey, &pData, &nData);
508✔
355
    if (ret < 0) {
508✔
356
      break;
28✔
357
    }
358

359
    SMetaEntry me = {0};
480✔
360
    SDecoder   dc = {0};
480✔
361
    tDecoderInit(&dc, pData, nData);
480✔
362
    code = metaDecodeEntry(&dc, &me);
480✔
363
    if (code < 0) {
480!
364
      tDecoderClear(&dc);
×
365
      return code;
×
366
    }
367

368
    if (me.type != TSDB_SUPER_TABLE) {
480✔
369
      char tbFName[TSDB_TABLE_FNAME_LEN + 1];
370
      snprintf(tbFName, sizeof(tbFName), "%s.%s", pMeta->pVnode->config.dbname, me.name);
454✔
371
      tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
454✔
372
      int32_t ret = vnodeValidateTableHash(pMeta->pVnode, tbFName);
454✔
373
      if (ret < 0 && terrno == TSDB_CODE_VND_HASH_MISMATCH) {
454!
374
        if (taosArrayPush(uidList, &me.uid) == NULL) {
227!
375
          code = terrno;
×
376
          break;
×
377
        }
378
      }
379
    }
380
    tDecoderClear(&dc);
480✔
381
  }
382
  tdbFree(pData);
28✔
383
  tdbFree(pKey);
28✔
384
  tdbTbcClose(pCur);
28✔
385

386
  return 0;
28✔
387
}
388

389
int32_t metaTrimTables(SMeta *pMeta, int64_t version) {
28✔
390
  int32_t code = 0;
28✔
391

392
  SArray *tbUids = taosArrayInit(8, sizeof(int64_t));
28✔
393
  if (tbUids == NULL) {
28!
394
    return terrno;
×
395
  }
396

397
  code = metaFilterTableByHash(pMeta, tbUids);
28✔
398
  if (code != 0) {
28!
399
    goto end;
×
400
  }
401
  if (TARRAY_SIZE(tbUids) == 0) {
28✔
402
    goto end;
3✔
403
  }
404

405
  metaInfo("vgId:%d, trim %ld tables", TD_VID(pMeta->pVnode), taosArrayGetSize(tbUids));
25!
406
  code = metaDropTables(pMeta, tbUids);
25✔
407
  if (code) goto end;
25!
408

409
end:
25✔
410
  taosArrayDestroy(tbUids);
28✔
411

412
  return code;
28✔
413
}
414

415
int metaTtlFindExpired(SMeta *pMeta, int64_t timePointMs, SArray *tbUids, int32_t ttlDropMaxCount) {
14,150✔
416
  metaRLock(pMeta);
14,150✔
417

418
  int ret = ttlMgrFindExpired(pMeta->pTtlMgr, timePointMs, tbUids, ttlDropMaxCount);
14,179✔
419

420
  metaULock(pMeta);
14,147✔
421

422
  if (ret != 0) {
14,170!
423
    metaError("ttl failed to find expired table, ret:%d", ret);
×
424
  }
425

426
  return ret;
14,174✔
427
}
428

429
static int metaBuildBtimeIdxKey(SBtimeIdxKey *btimeKey, const SMetaEntry *pME) {
227✔
430
  int64_t btime;
431
  if (pME->type == TSDB_CHILD_TABLE) {
227✔
432
    btime = pME->ctbEntry.btime;
226✔
433
  } else if (pME->type == TSDB_NORMAL_TABLE) {
1!
434
    btime = pME->ntbEntry.btime;
1✔
435
  } else {
436
    return TSDB_CODE_FAILED;
×
437
  }
438

439
  btimeKey->btime = btime;
227✔
440
  btimeKey->uid = pME->uid;
227✔
441
  return 0;
227✔
442
}
443

444
static int metaBuildNColIdxKey(SNcolIdxKey *ncolKey, const SMetaEntry *pME) {
1✔
445
  if (pME->type == TSDB_NORMAL_TABLE) {
1!
446
    ncolKey->ncol = pME->ntbEntry.schemaRow.nCols;
1✔
447
    ncolKey->uid = pME->uid;
1✔
448
  } else {
449
    return TSDB_CODE_FAILED;
×
450
  }
451
  return 0;
1✔
452
}
453

454
static void metaDeleteTtl(SMeta *pMeta, const SMetaEntry *pME) {
227✔
455
  if (pME->type != TSDB_CHILD_TABLE && pME->type != TSDB_NORMAL_TABLE) return;
227!
456

457
  STtlDelTtlCtx ctx = {.uid = pME->uid, .pTxn = pMeta->txn};
227✔
458
  if (pME->type == TSDB_CHILD_TABLE) {
227✔
459
    ctx.ttlDays = pME->ctbEntry.ttlDays;
226✔
460
  } else {
461
    ctx.ttlDays = pME->ntbEntry.ttlDays;
1✔
462
  }
463

464
  int32_t ret = ttlMgrDeleteTtl(pMeta->pTtlMgr, &ctx);
227✔
465
  if (ret < 0) {
227!
466
    metaError("vgId:%d, failed to delete ttl for table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pME->name,
×
467
              pME->uid, tstrerror(ret));
468
  }
469
  return;
227✔
470
}
471

472
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *pSuid, int8_t *pSysTbl) {
227✔
473
  void      *pData = NULL;
227✔
474
  int        nData = 0;
227✔
475
  int        rc = 0;
227✔
476
  SMetaEntry e = {0};
227✔
477
  SDecoder   dc = {0};
227✔
478
  int32_t    ret = 0;
227✔
479

480
  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
227✔
481
  if (rc < 0) {
227!
482
    return rc;
×
483
  }
484
  int64_t version = ((SUidIdxVal *)pData)[0].version;
227✔
485

486
  rc = tdbTbGet(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), &pData, &nData);
227✔
487
  if (rc < 0) {
227!
488
    tdbFree(pData);
×
489
    return rc;
×
490
  }
491

492
  tDecoderInit(&dc, pData, nData);
227✔
493
  rc = metaDecodeEntry(&dc, &e);
227✔
494
  if (rc < 0) {
227!
495
    tDecoderClear(&dc);
×
496
    return rc;
×
497
  }
498

499
  if (type) *type = e.type;
227!
500

501
  if (e.type == TSDB_CHILD_TABLE) {
227✔
502
    if (pSuid) *pSuid = e.ctbEntry.suid;
226!
503
    void *tData = NULL;
226✔
504
    int   tLen = 0;
226✔
505

506
    if (tdbTbGet(pMeta->pUidIdx, &e.ctbEntry.suid, sizeof(tb_uid_t), &tData, &tLen) == 0) {
226!
507
      STbDbKey tbDbKey = {.uid = e.ctbEntry.suid, .version = ((SUidIdxVal *)tData)[0].version};
226✔
508
      if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &tData, &tLen) == 0) {
226!
509
        SDecoder   tdc = {0};
226✔
510
        SMetaEntry stbEntry = {0};
226✔
511

512
        tDecoderInit(&tdc, tData, tLen);
226✔
513
        int32_t ret = metaDecodeEntry(&tdc, &stbEntry);
226✔
514
        if (ret < 0) {
226!
515
          tDecoderClear(&tdc);
×
516
          metaError("vgId:%d, failed to decode child table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
517
                    e.ctbEntry.suid, tstrerror(ret));
518
          return ret;
×
519
        }
520

521
        if (pSysTbl) *pSysTbl = metaTbInFilterCache(pMeta, stbEntry.name, 1) ? 1 : 0;
226!
522

523
        SSchema        *pTagColumn = NULL;
226✔
524
        SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
226✔
525
        if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
226!
526
          pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
×
527
          ret = metaDelJsonVarFromIdx(pMeta, &e, pTagColumn);
×
528
          if (ret < 0) {
×
529
            metaError("vgId:%d, failed to delete json var from idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode),
×
530
                      e.name, e.uid, tstrerror(ret));
531
          }
532
        } else {
533
          for (int i = 0; i < pTagSchema->nCols; i++) {
1,338✔
534
            pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[i];
1,112✔
535
            if (!IS_IDX_ON(pTagColumn)) continue;
1,112✔
536
            STagIdxKey *pTagIdxKey = NULL;
226✔
537
            int32_t     nTagIdxKey;
538

539
            const void *pTagData = NULL;
226✔
540
            int32_t     nTagData = 0;
226✔
541

542
            STagVal tagVal = {.cid = pTagColumn->colId};
226✔
543
            if (tTagGet((const STag *)e.ctbEntry.pTags, &tagVal)) {
226!
544
              if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
226!
545
                pTagData = tagVal.pData;
×
546
                nTagData = (int32_t)tagVal.nData;
×
547
              } else {
548
                pTagData = &(tagVal.i64);
226✔
549
                nTagData = tDataTypes[pTagColumn->type].bytes;
226✔
550
              }
551
            } else {
552
              if (!IS_VAR_DATA_TYPE(pTagColumn->type)) {
×
553
                nTagData = tDataTypes[pTagColumn->type].bytes;
×
554
              }
555
            }
556

557
            if (metaCreateTagIdxKey(e.ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type, uid,
226!
558
                                    &pTagIdxKey, &nTagIdxKey) == 0) {
559
              ret = tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
226✔
560
              if (ret < 0) {
226!
561
                metaError("vgId:%d, failed to delete tag idx key:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode),
×
562
                          e.name, e.uid, tstrerror(ret));
563
              }
564
            }
565
            metaDestroyTagIdxKey(pTagIdxKey);
226✔
566
            pTagIdxKey = NULL;
226✔
567
          }
568
        }
569
        tDecoderClear(&tdc);
226✔
570
      }
571
      tdbFree(tData);
226✔
572
    }
573
  }
574

575
  ret = tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), pMeta->txn);
227✔
576
  if (ret < 0) {
227!
577
    metaError("vgId:%d, failed to delete table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
578
              tstrerror(ret));
579
  }
580
  ret = tdbTbDelete(pMeta->pNameIdx, e.name, strlen(e.name) + 1, pMeta->txn);
227✔
581
  if (ret < 0) {
227!
582
    metaError("vgId:%d, failed to delete name idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
583
              tstrerror(ret));
584
  }
585
  ret = tdbTbDelete(pMeta->pUidIdx, &uid, sizeof(uid), pMeta->txn);
227✔
586
  if (ret < 0) {
227!
587
    metaError("vgId:%d, failed to delete uid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
588
              tstrerror(ret));
589
  }
590

591
  if (e.type == TSDB_CHILD_TABLE || e.type == TSDB_NORMAL_TABLE) metaDeleteBtimeIdx(pMeta, &e);
227!
592
  if (e.type == TSDB_NORMAL_TABLE) metaDeleteNcolIdx(pMeta, &e);
227✔
593

594
  if (e.type != TSDB_SUPER_TABLE) metaDeleteTtl(pMeta, &e);
227!
595

596
  if (e.type == TSDB_CHILD_TABLE) {
227✔
597
    ret =
598
        tdbTbDelete(pMeta->pCtbIdx, &(SCtbIdxKey){.suid = e.ctbEntry.suid, .uid = uid}, sizeof(SCtbIdxKey), pMeta->txn);
226✔
599
    if (ret < 0) {
226!
600
      metaError("vgId:%d, failed to delete ctb idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
601
                tstrerror(ret));
602
    }
603

604
    --pMeta->pVnode->config.vndStats.numOfCTables;
226✔
605
    metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1, 0);
226✔
606
    ret = metaUidCacheClear(pMeta, e.ctbEntry.suid);
226✔
607
    if (ret < 0) {
226!
608
      metaError("vgId:%d, failed to clear uid cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
609
                e.ctbEntry.suid, tstrerror(ret));
610
    }
611
    ret = metaTbGroupCacheClear(pMeta, e.ctbEntry.suid);
226✔
612
    if (ret < 0) {
226!
613
      metaError("vgId:%d, failed to clear group cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
614
                e.ctbEntry.suid, tstrerror(ret));
615
    }
616
    /*
617
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
618
      tsdbCacheDropTable(pMeta->pVnode->pTsdb, e.uid, e.ctbEntry.suid, NULL);
619
    }
620
    */
621
  } else if (e.type == TSDB_NORMAL_TABLE) {
1!
622
    // drop schema.db (todo)
623

624
    --pMeta->pVnode->config.vndStats.numOfNTables;
1✔
625
    pMeta->pVnode->config.vndStats.numOfNTimeSeries -= e.ntbEntry.schemaRow.nCols - 1;
1✔
626

627
    /*
628
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
629
      tsdbCacheDropTable(pMeta->pVnode->pTsdb, e.uid, -1, &e.ntbEntry.schemaRow);
630
    }
631
    */
632
  } else if (e.type == TSDB_SUPER_TABLE) {
×
633
    ret = tdbTbDelete(pMeta->pSuidIdx, &e.uid, sizeof(tb_uid_t), pMeta->txn);
×
634
    if (ret < 0) {
×
635
      metaError("vgId:%d, failed to delete suid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
636
                tstrerror(ret));
637
    }
638
    // drop schema.db (todo)
639

640
    ret = metaStatsCacheDrop(pMeta, uid);
×
641
    if (ret < 0) {
×
642
      metaError("vgId:%d, failed to drop stats cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
643
                tstrerror(ret));
644
    }
645
    ret = metaUidCacheClear(pMeta, uid);
×
646
    if (ret < 0) {
×
647
      metaError("vgId:%d, failed to clear uid cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
648
                tstrerror(ret));
649
    }
650
    ret = metaTbGroupCacheClear(pMeta, uid);
×
651
    if (ret < 0) {
×
652
      metaError("vgId:%d, failed to clear group cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
653
                e.uid, tstrerror(ret));
654
    }
655
    --pMeta->pVnode->config.vndStats.numOfSTables;
×
656
  }
657

658
  ret = metaCacheDrop(pMeta, uid);
227✔
659
  if (ret < 0) {
227!
660
    metaError("vgId:%d, failed to drop cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
227!
661
              tstrerror(ret));
662
  }
663

664
  tDecoderClear(&dc);
227✔
665
  tdbFree(pData);
227✔
666

667
  return 0;
227✔
668
}
669

670
static int metaDeleteBtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
227✔
671
  SBtimeIdxKey btimeKey = {0};
227✔
672
  if (metaBuildBtimeIdxKey(&btimeKey, pME) < 0) {
227!
673
    return 0;
×
674
  }
675
  return tdbTbDelete(pMeta->pBtimeIdx, &btimeKey, sizeof(btimeKey), pMeta->txn);
227✔
676
}
677

678
int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
1✔
679
  SNcolIdxKey ncolKey = {0};
1✔
680
  if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
1!
681
    return 0;
×
682
  }
683
  return tdbTbDelete(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), pMeta->txn);
1✔
684
}
685

686
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
257✔
687
  pMeta->changed = true;
257✔
688
  switch (pReq->action) {
257!
689
    case TSDB_ALTER_TABLE_ADD_COLUMN:
30✔
690
    case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
691
      return metaAddTableColumn(pMeta, version, pReq, pMetaRsp);
30✔
692
    case TSDB_ALTER_TABLE_DROP_COLUMN:
29✔
693
      return metaDropTableColumn(pMeta, version, pReq, pMetaRsp);
29✔
694
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
36✔
695
      return metaAlterTableColumnBytes(pMeta, version, pReq, pMetaRsp);
36✔
696
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
30✔
697
      return metaAlterTableColumnName(pMeta, version, pReq, pMetaRsp);
30✔
698
    case TSDB_ALTER_TABLE_UPDATE_TAG_VAL:
55✔
699
      return metaUpdateTableTagValue(pMeta, version, pReq);
55✔
700
    case TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL:
×
701
      return metaUpdateTableMultiTagValue(pMeta, version, pReq);
×
702
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
77✔
703
      return metaUpdateTableOptions2(pMeta, version, pReq);
77✔
704
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS:
×
705
      return metaUpdateTableColCompress2(pMeta, version, pReq);
×
706
    default:
×
707
      return terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
708
      break;
709
  }
710
}
711

712
static int metaUpdateChangeTime(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs) {
×
713
  if (!tsTtlChangeOnWrite) return 0;
×
714

715
  if (changeTimeMs <= 0) {
×
716
    metaWarn("Skip to change ttl deletetion time on write, uid: %" PRId64, uid);
×
717
    return TSDB_CODE_VERSION_NOT_COMPATIBLE;
×
718
  }
719

720
  STtlUpdCtimeCtx ctx = {.uid = uid, .changeTimeMs = changeTimeMs, .pTxn = pMeta->txn};
×
721

722
  return ttlMgrUpdateChangeTime(pMeta->pTtlMgr, &ctx);
×
723
}
724

725
int metaUpdateChangeTimeWithLock(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs) {
2,022,341✔
726
  if (!tsTtlChangeOnWrite) return 0;
2,022,341!
727

728
  metaWLock(pMeta);
×
729
  int ret = metaUpdateChangeTime(pMeta, uid, changeTimeMs);
×
730
  metaULock(pMeta);
×
731
  return ret;
×
732
}
733

734
int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
74,665✔
735
                        STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
736
  if (IS_VAR_DATA_TYPE(type)) {
74,665!
737
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + VARSTR_HEADER_SIZE + sizeof(tb_uid_t);
16,065✔
738
  } else {
739
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + sizeof(tb_uid_t);
58,600✔
740
  }
741

742
  *ppTagIdxKey = (STagIdxKey *)taosMemoryMalloc(*nTagIdxKey);
74,665!
743
  if (*ppTagIdxKey == NULL) {
74,689!
744
    return terrno;
×
745
  }
746

747
  (*ppTagIdxKey)->suid = suid;
74,689✔
748
  (*ppTagIdxKey)->cid = cid;
74,689✔
749
  (*ppTagIdxKey)->isNull = (pTagData == NULL) ? 1 : 0;
74,689✔
750
  (*ppTagIdxKey)->type = type;
74,689✔
751

752
  // refactor
753
  if (IS_VAR_DATA_TYPE(type)) {
74,689!
754
    memcpy((*ppTagIdxKey)->data, (uint16_t *)&nTagData, VARSTR_HEADER_SIZE);
16,103✔
755
    if (pTagData != NULL) memcpy((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE, pTagData, nTagData);
16,103✔
756
    *(tb_uid_t *)((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE + nTagData) = uid;
16,103✔
757
  } else {
758
    if (pTagData != NULL) memcpy((*ppTagIdxKey)->data, pTagData, nTagData);
58,586✔
759
    *(tb_uid_t *)((*ppTagIdxKey)->data + nTagData) = uid;
58,586✔
760
  }
761

762
  return 0;
74,689✔
763
}
764

765
void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) {
74,649✔
766
  if (pTagIdxKey) taosMemoryFree(pTagIdxKey);
74,649!
767
}
74,649✔
768

769
static void colCompressDebug(SHashObj *pColCmprObj) {
177,179✔
770
  void *p = taosHashIterate(pColCmprObj, NULL);
177,179✔
771
  while (p) {
1,945,347✔
772
    uint32_t cmprAlg = *(uint32_t *)p;
1,768,205✔
773
    col_id_t colId = *(col_id_t *)taosHashGetKey(p, NULL);
1,768,205✔
774
    p = taosHashIterate(pColCmprObj, p);
1,768,094✔
775

776
    uint8_t l1, l2, lvl;
777
    tcompressDebug(cmprAlg, &l1, &l2, &lvl);
1,771,210✔
778

779
    const char *l1str = columnEncodeStr(l1);
1,770,435✔
780
    const char *l2str = columnCompressStr(l2);
1,769,304✔
781
    const char *lvlstr = columnLevelStr(lvl);
1,768,385✔
782
    metaDebug("colId: %d, encode:%s, compress:%s,level:%s", colId, l1str, l2str, lvlstr);
1,768,033✔
783
  }
784
  return;
177,142✔
785
}
786

787
int32_t metaGetColCmpr(SMeta *pMeta, tb_uid_t uid, SHashObj **ppColCmprObj) {
176,971✔
788
  int rc = 0;
176,971✔
789

790
  SHashObj *pColCmprObj = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
176,971✔
791
  if (pColCmprObj == NULL) {
177,076!
792
    pColCmprObj = NULL;
×
793
    return TSDB_CODE_OUT_OF_MEMORY;
×
794
  }
795

796
  void      *pData = NULL;
177,076✔
797
  int        nData = 0;
177,076✔
798
  SMetaEntry e = {0};
177,076✔
799
  SDecoder   dc = {0};
177,076✔
800

801
  *ppColCmprObj = NULL;
177,076✔
802

803
  metaRLock(pMeta);
177,076✔
804
  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
177,238✔
805
  if (rc < 0) {
177,355✔
806
    taosHashClear(pColCmprObj);
16✔
807
    metaULock(pMeta);
16✔
808
    return TSDB_CODE_FAILED;
16✔
809
  }
810
  int64_t version = ((SUidIdxVal *)pData)[0].version;
177,339✔
811
  rc = tdbTbGet(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), &pData, &nData);
177,339✔
812
  if (rc < 0) {
177,342!
813
    metaULock(pMeta);
×
814
    taosHashClear(pColCmprObj);
×
815
    metaError("failed to get table entry");
×
816
    return rc;
×
817
  }
818

819
  tDecoderInit(&dc, pData, nData);
177,342✔
820
  rc = metaDecodeEntry(&dc, &e);
177,274✔
821
  if (rc < 0) {
176,828!
822
    tDecoderClear(&dc);
×
823
    tdbFree(pData);
×
824
    metaULock(pMeta);
×
825
    taosHashClear(pColCmprObj);
×
826
    return rc;
×
827
  }
828
  if (useCompress(e.type)) {
176,828!
829
    SColCmprWrapper *p = &e.colCmpr;
176,861✔
830
    for (int32_t i = 0; i < p->nCols; i++) {
1,948,725✔
831
      SColCmpr *pCmpr = &p->pColCmpr[i];
1,771,031✔
832
      rc = taosHashPut(pColCmprObj, &pCmpr->id, sizeof(pCmpr->id), &pCmpr->alg, sizeof(pCmpr->alg));
1,771,031✔
833
      if (rc < 0) {
1,771,946✔
834
        tDecoderClear(&dc);
82✔
835
        tdbFree(pData);
×
836
        metaULock(pMeta);
×
837
        taosHashClear(pColCmprObj);
×
838
        return rc;
×
839
      }
840
    }
841
  } else {
842
    tDecoderClear(&dc);
×
843
    tdbFree(pData);
×
844
    metaULock(pMeta);
×
845
    taosHashClear(pColCmprObj);
×
846
    return 0;
×
847
  }
848
  tDecoderClear(&dc);
177,694✔
849
  tdbFree(pData);
177,181✔
850
  metaULock(pMeta);
177,305✔
851

852
  *ppColCmprObj = pColCmprObj;
177,271✔
853
  colCompressDebug(pColCmprObj);
177,271✔
854

855
  return 0;
177,104✔
856
}
857
// refactor later
858
void *metaGetIdx(SMeta *pMeta) { return pMeta->pTagIdx; }
3,697✔
859
void *metaGetIvtIdx(SMeta *pMeta) { return pMeta->pTagIvtIdx; }
3,704✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc