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

taosdata / TDengine / #3568

27 Dec 2024 02:27PM UTC coverage: 63.286% (+0.6%) from 62.733%
#3568

push

travis-ci

web-flow
Merge pull request #29378 from taosdata/revert-29377-revert-29165-enh/TD-29974-improve-trans

Revert "Revert "Enh:[td 29974]improve trans""

139941 of 284289 branches covered (49.22%)

Branch coverage included in aggregate %.

105 of 355 new or added lines in 12 files covered. (29.58%)

4077 existing lines in 132 files now uncovered.

218122 of 281494 relevant lines covered (77.49%)

19355607.91 hits per line

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

66.42
/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) {
136✔
40
  int32_t nCols = pWp->nCols;
136✔
41
  int32_t ver = pWp->version;
136✔
42
  if (add) {
136✔
43
    SColCmpr *p = taosMemoryRealloc(pWp->pColCmpr, sizeof(SColCmpr) * (nCols + 1));
79!
44
    if (p == NULL) {
79!
45
      return terrno;
×
46
    }
47
    pWp->pColCmpr = p;
79✔
48

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

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

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

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

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

92
  return 0;
14,362✔
93
}
94

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

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

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

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

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

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

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

129
    SIndexTerm *term = NULL;
233✔
130
    if (type == TSDB_DATA_TYPE_NULL) {
233✔
131
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
24✔
132
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
209✔
133
      if (pTagVal->nData > 0) {
108✔
134
        char *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
92!
135
        if (val == NULL) {
92!
136
          TAOS_CHECK_GOTO(terrno, NULL, _exception);
×
137
        }
138
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE, NULL);
92✔
139
        if (len < 0) {
92!
140
          TAOS_CHECK_GOTO(len, NULL, _exception);
×
141
        }
142
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
92✔
143
        type = TSDB_DATA_TYPE_VARCHAR;
92✔
144
        term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, val, len);
92✔
145
        taosMemoryFree(val);
92!
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) {
101✔
150
      double val = *(double *)(&pTagVal->i64);
77✔
151
      int    len = sizeof(val);
77✔
152
      term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
77✔
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) {
233!
160
      int32_t ret = indexMultiTermAdd(terms, term);
233✔
161
      if (ret < 0) {
233!
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);
191✔
171
  indexMultiTermDestroy(terms);
191✔
172

173
  taosArrayDestroy(pTagVals);
191✔
174
#endif
175
  return code;
191✔
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) {
214✔
265
#if defined(TD_ENTERPRISE)
266
  int64_t nTimeSeries = metaGetTimeSeriesNum(pMeta, 0);
214✔
267
  int64_t deltaTS = nTimeSeries - pMeta->pVnode->config.vndStats.numOfReportedTimeSeries;
214✔
268
  if (deltaTS > tsTimeSeriesThreshold) {
214✔
269
    if (0 == atomic_val_compare_exchange_8(&dmNotifyHdl.state, 1, 2)) {
8!
270
      if (tsem_post(&dmNotifyHdl.sem) != 0) {
8!
271
        metaError("vgId:%d, failed to post semaphore, errno:%d", TD_VID(pMeta->pVnode), errno);
×
272
      }
273
    }
274
  }
275
#endif
276
}
214✔
277

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

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

288
  metaWLock(pMeta);
37✔
289
  for (int i = 0; i < taosArrayGetSize(tbUids); ++i) {
5,263✔
290
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(tbUids, i);
5,226✔
291
    tb_uid_t suid = 0;
5,226✔
292
    int8_t   sysTbl = 0;
5,226✔
293
    int      type;
294
    code = metaDropTableByUid(pMeta, uid, &type, &suid, &sysTbl);
5,226✔
295
    if (code) return code;
5,226!
296
    if (!sysTbl && type == TSDB_CHILD_TABLE && suid != 0 && suidHash) {
5,226!
297
      int64_t *pVal = tSimpleHashGet(suidHash, &suid, sizeof(tb_uid_t));
5,225✔
298
      if (pVal) {
5,225✔
299
        nCtbDropped = *pVal + 1;
5,189✔
300
      } else {
301
        nCtbDropped = 1;
36✔
302
      }
303
      code = tSimpleHashPut(suidHash, &suid, sizeof(tb_uid_t), &nCtbDropped, sizeof(int64_t));
5,225✔
304
      if (code) return code;
5,225!
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);
5,226✔
312
  }
313
  metaULock(pMeta);
37✔
314

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

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

332
static int32_t metaFilterTableByHash(SMeta *pMeta, SArray *uidList) {
40✔
333
  int32_t code = 0;
40✔
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);
40✔
340
  if (code < 0) {
40!
341
    return code;
×
342
  }
343

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

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

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

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

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

386
  return 0;
40✔
387
}
388

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

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

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

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

409
end:
37✔
410
  taosArrayDestroy(tbUids);
40✔
411

412
  return code;
40✔
413
}
414

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

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

420
  metaULock(pMeta);
110,946✔
421

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

426
  return ret;
111,111✔
427
}
428

429
static int metaBuildBtimeIdxKey(SBtimeIdxKey *btimeKey, const SMetaEntry *pME) {
5,226✔
430
  int64_t btime;
431
  if (pME->type == TSDB_CHILD_TABLE) {
5,226✔
432
    btime = pME->ctbEntry.btime;
5,225✔
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;
5,226✔
440
  btimeKey->uid = pME->uid;
5,226✔
441
  return 0;
5,226✔
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) {
5,226✔
455
  if (pME->type != TSDB_CHILD_TABLE && pME->type != TSDB_NORMAL_TABLE) return;
5,226!
456

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

464
  int32_t ret = ttlMgrDeleteTtl(pMeta->pTtlMgr, &ctx);
5,226✔
465
  if (ret < 0) {
5,226!
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;
5,226✔
470
}
471

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

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

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

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

499
  if (type) *type = e.type;
5,226!
500

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

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

512
        tDecoderInit(&tdc, tData, tLen);
5,225✔
513
        int32_t ret = metaDecodeEntry(&tdc, &stbEntry);
5,225✔
514
        if (ret < 0) {
5,225!
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;
5,225!
522

523
        SSchema        *pTagColumn = NULL;
5,225✔
524
        SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
5,225✔
525
        if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
5,225!
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++) {
11,330✔
534
            pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[i];
6,105✔
535
            if (!IS_IDX_ON(pTagColumn)) continue;
6,105✔
536
            STagIdxKey *pTagIdxKey = NULL;
5,225✔
537
            int32_t     nTagIdxKey;
538

539
            const void *pTagData = NULL;
5,225✔
540
            int32_t     nTagData = 0;
5,225✔
541

542
            STagVal tagVal = {.cid = pTagColumn->colId};
5,225✔
543
            if (tTagGet((const STag *)e.ctbEntry.pTags, &tagVal)) {
5,225!
544
              if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
5,225!
545
                pTagData = tagVal.pData;
×
546
                nTagData = (int32_t)tagVal.nData;
×
547
              } else {
548
                pTagData = &(tagVal.i64);
5,225✔
549
                nTagData = tDataTypes[pTagColumn->type].bytes;
5,225✔
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,
5,225!
558
                                    &pTagIdxKey, &nTagIdxKey) == 0) {
559
              ret = tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
5,225✔
560
              if (ret < 0) {
5,225!
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);
5,225✔
566
            pTagIdxKey = NULL;
5,225✔
567
          }
568
        }
569
        tDecoderClear(&tdc);
5,225✔
570
      }
571
      tdbFree(tData);
5,225✔
572
    }
573
  }
574

575
  ret = tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), pMeta->txn);
5,226✔
576
  if (ret < 0) {
5,226!
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);
5,226✔
581
  if (ret < 0) {
5,226!
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);
5,226✔
586
  if (ret < 0) {
5,226!
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);
5,226!
592
  if (e.type == TSDB_NORMAL_TABLE) metaDeleteNcolIdx(pMeta, &e);
5,226✔
593

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

596
  if (e.type == TSDB_CHILD_TABLE) {
5,226✔
597
    ret =
598
        tdbTbDelete(pMeta->pCtbIdx, &(SCtbIdxKey){.suid = e.ctbEntry.suid, .uid = uid}, sizeof(SCtbIdxKey), pMeta->txn);
5,225✔
599
    if (ret < 0) {
5,225!
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;
5,225✔
605
    metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1, 0);
5,225✔
606
    ret = metaUidCacheClear(pMeta, e.ctbEntry.suid);
5,225✔
607
    if (ret < 0) {
5,225!
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);
5,225✔
612
    if (ret < 0) {
5,225!
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);
5,226✔
659
  if (ret < 0) {
5,226!
660
    metaError("vgId:%d, failed to drop cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
5,226!
661
              tstrerror(ret));
662
  }
663

664
  tDecoderClear(&dc);
5,226✔
665
  tdbFree(pData);
5,226✔
666

667
  return 0;
5,226✔
668
}
669

670
static int metaDeleteBtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
5,226✔
671
  SBtimeIdxKey btimeKey = {0};
5,226✔
672
  if (metaBuildBtimeIdxKey(&btimeKey, pME) < 0) {
5,226!
673
    return 0;
×
674
  }
675
  return tdbTbDelete(pMeta->pBtimeIdx, &btimeKey, sizeof(btimeKey), pMeta->txn);
5,226✔
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) {
928✔
687
  pMeta->changed = true;
928✔
688
  switch (pReq->action) {
928!
689
    case TSDB_ALTER_TABLE_ADD_COLUMN:
79✔
690
    case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
691
      return metaAddTableColumn(pMeta, version, pReq, pMetaRsp);
79✔
692
    case TSDB_ALTER_TABLE_DROP_COLUMN:
70✔
693
      return metaDropTableColumn(pMeta, version, pReq, pMetaRsp);
70✔
694
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
40✔
695
      return metaAlterTableColumnBytes(pMeta, version, pReq, pMetaRsp);
40✔
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:
646✔
699
      return metaUpdateTableTagValue(pMeta, version, pReq);
646✔
700
    case TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL:
5✔
701
      return metaUpdateTableMultiTagValue(pMeta, version, pReq);
5✔
702
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
53✔
703
      return metaUpdateTableOptions2(pMeta, version, pReq);
53✔
704
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS:
5✔
705
      return metaUpdateTableColCompress2(pMeta, version, pReq);
5✔
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) {
13,707,468✔
726
  if (!tsTtlChangeOnWrite) return 0;
13,707,468!
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,
228,634✔
735
                        STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
736
  if (IS_VAR_DATA_TYPE(type)) {
228,634!
737
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + VARSTR_HEADER_SIZE + sizeof(tb_uid_t);
22,315✔
738
  } else {
739
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + sizeof(tb_uid_t);
206,319✔
740
  }
741

742
  *ppTagIdxKey = (STagIdxKey *)taosMemoryMalloc(*nTagIdxKey);
228,634!
743
  if (*ppTagIdxKey == NULL) {
228,667!
744
    return terrno;
×
745
  }
746

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

752
  // refactor
753
  if (IS_VAR_DATA_TYPE(type)) {
228,667!
754
    memcpy((*ppTagIdxKey)->data, (uint16_t *)&nTagData, VARSTR_HEADER_SIZE);
22,358✔
755
    if (pTagData != NULL) memcpy((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE, pTagData, nTagData);
22,358✔
756
    *(tb_uid_t *)((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE + nTagData) = uid;
22,358✔
757
  } else {
758
    if (pTagData != NULL) memcpy((*ppTagIdxKey)->data, pTagData, nTagData);
206,309✔
759
    *(tb_uid_t *)((*ppTagIdxKey)->data + nTagData) = uid;
206,309✔
760
  }
761

762
  return 0;
228,667✔
763
}
764

765
void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) {
228,262✔
766
  if (pTagIdxKey) taosMemoryFree(pTagIdxKey);
228,262!
767
}
228,267✔
768

769
static void colCompressDebug(SHashObj *pColCmprObj) {
620,065✔
770
  void *p = taosHashIterate(pColCmprObj, NULL);
620,065✔
771
  while (p) {
4,333,655✔
772
    uint32_t cmprAlg = *(uint32_t *)p;
3,713,766✔
773
    col_id_t colId = *(col_id_t *)taosHashGetKey(p, NULL);
3,713,766✔
774
    p = taosHashIterate(pColCmprObj, p);
3,713,652✔
775

776
    uint8_t l1, l2, lvl;
777
    tcompressDebug(cmprAlg, &l1, &l2, &lvl);
3,714,606✔
778

779
    const char *l1str = columnEncodeStr(l1);
3,714,182✔
780
    const char *l2str = columnCompressStr(l2);
3,713,922✔
781
    const char *lvlstr = columnLevelStr(lvl);
3,713,760✔
782
    metaDebug("colId: %d, encode:%s, compress:%s,level:%s", colId, l1str, l2str, lvlstr);
3,713,594✔
783
  }
784
  return;
619,889✔
785
}
786

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

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

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

801
  *ppColCmprObj = NULL;
620,055✔
802

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

819
  tDecoderInit(&dc, pData, nData);
620,082✔
820
  rc = metaDecodeEntry(&dc, &e);
620,076✔
821
  if (rc < 0) {
619,979!
822
    tDecoderClear(&dc);
×
823
    tdbFree(pData);
×
824
    metaULock(pMeta);
×
825
    taosHashClear(pColCmprObj);
×
826
    return rc;
×
827
  }
828
  if (useCompress(e.type)) {
619,979!
829
    SColCmprWrapper *p = &e.colCmpr;
620,000✔
830
    for (int32_t i = 0; i < p->nCols; i++) {
4,333,407✔
831
      SColCmpr *pCmpr = &p->pColCmpr[i];
3,713,124✔
832
      rc = taosHashPut(pColCmprObj, &pCmpr->id, sizeof(pCmpr->id), &pCmpr->alg, sizeof(pCmpr->alg));
3,713,124✔
833
      if (rc < 0) {
3,713,400!
UNCOV
834
        tDecoderClear(&dc);
×
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);
620,283✔
849
  tdbFree(pData);
620,058✔
850
  metaULock(pMeta);
620,083✔
851

852
  *ppColCmprObj = pColCmprObj;
620,087✔
853
  colCompressDebug(pColCmprObj);
620,087✔
854

855
  return 0;
619,970✔
856
}
857
// refactor later
858
void *metaGetIdx(SMeta *pMeta) { return pMeta->pTagIdx; }
37,616✔
859
void *metaGetIvtIdx(SMeta *pMeta) { return pMeta->pTagIvtIdx; }
37,561✔
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