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

taosdata / TDengine / #3543

29 Nov 2024 02:58AM UTC coverage: 60.842% (+0.02%) from 60.819%
#3543

push

travis-ci

web-flow
Merge pull request #28973 from taosdata/merge/mainto3.0

merge: from main to 3.0

120460 of 253224 branches covered (47.57%)

Branch coverage included in aggregate %.

706 of 908 new or added lines in 18 files covered. (77.75%)

2401 existing lines in 137 files now uncovered.

201633 of 276172 relevant lines covered (73.01%)

19045673.23 hits per line

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

62.32
/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
static int  metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
21
static int  metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
22
static int  metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME);
23
static int  metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME);
24
static int  metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME);
25
static void metaUpdateTtl(SMeta *pMeta, const SMetaEntry *pME);
26
static int  metaUpdateChangeTime(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs);
27
static int  metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME);
28
static int  metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME);
29
static int  metaUpdateSuidIdx(SMeta *pMeta, const SMetaEntry *pME);
30
static int  metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry);
31
static int  metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *pSuid, int8_t *pSysTbl);
32
static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey);
33
// opt ins_tables query
34
static int metaUpdateBtimeIdx(SMeta *pMeta, const SMetaEntry *pME);
35
static int metaDeleteBtimeIdx(SMeta *pMeta, const SMetaEntry *pME);
36
static int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
37
static int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
38

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

48
    memcpy(p, pWp->pColCmpr, sizeof(SColCmpr) * nCols);
582✔
49

50
    SColCmpr *pCol = p + nCols;
582✔
51
    pCol->id = pSchema->colId;
582✔
52
    pCol->alg = compress;
582✔
53
    pWp->nCols = nCols + 1;
582✔
54
    pWp->version = ver;
582✔
55
    pWp->pColCmpr = p;
582✔
56
  } else {
57
    for (int32_t i = 0; i < nCols; i++) {
20,815!
58
      SColCmpr *pOCmpr = &pWp->pColCmpr[i];
20,815✔
59
      if (pOCmpr->id == pSchema->colId) {
20,815✔
60
        int32_t left = (nCols - i - 1) * sizeof(SColCmpr);
68✔
61
        if (left) {
68✔
62
          memmove(pWp->pColCmpr + i, pWp->pColCmpr + i + 1, left);
35✔
63
        }
64
        nCols--;
68✔
65
        break;
68✔
66
      }
67
    }
68
    pWp->nCols = nCols;
68✔
69
    pWp->version = ver;
68✔
70
  }
71
  return 0;
650✔
72
}
73
static void metaGetEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) {
303,495✔
74
  pInfo->uid = pEntry->uid;
303,495✔
75
  pInfo->version = pEntry->version;
303,495✔
76
  if (pEntry->type == TSDB_SUPER_TABLE) {
303,495✔
77
    pInfo->suid = pEntry->uid;
39,138✔
78
    pInfo->skmVer = pEntry->stbEntry.schemaRow.version;
39,138✔
79
  } else if (pEntry->type == TSDB_CHILD_TABLE) {
264,357✔
80
    pInfo->suid = pEntry->ctbEntry.suid;
248,682✔
81
    pInfo->skmVer = 0;
248,682✔
82
  } else if (pEntry->type == TSDB_NORMAL_TABLE) {
15,675!
83
    pInfo->suid = 0;
16,309✔
84
    pInfo->skmVer = pEntry->ntbEntry.schemaRow.version;
16,309✔
85
  } else {
86
    metaError("meta/table: invalide table type: %" PRId8 " get entry info failed.", pEntry->type);
×
87
  }
88
}
303,495✔
89

90
static int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
16,241✔
91
  pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
16,241✔
92
  if (NULL == pMetaRsp->pSchemas) {
16,241!
93
    return terrno;
×
94
  }
95

96
  pMetaRsp->pSchemaExt = taosMemoryMalloc(pSchema->nCols * sizeof(SSchemaExt));
16,241✔
97
  if (pMetaRsp->pSchemaExt == NULL) {
16,241!
98
    taosMemoryFree(pMetaRsp->pSchemas);
×
99
    return terrno;
×
100
  }
101

102
  tstrncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
16,241✔
103
  pMetaRsp->numOfColumns = pSchema->nCols;
16,241✔
104
  pMetaRsp->tableType = TSDB_NORMAL_TABLE;
16,241✔
105
  pMetaRsp->sversion = pSchema->version;
16,241✔
106
  pMetaRsp->tuid = uid;
16,241✔
107

108
  memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
16,241✔
109

110
  return 0;
16,241✔
111
}
112

113
static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
576✔
114
  int32_t code = 0;
576✔
115

116
#ifdef USE_INVERTED_INDEX
117
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
576!
118
    return TSDB_CODE_INVALID_PARA;
×
119
  }
120
  void       *data = pCtbEntry->ctbEntry.pTags;
576✔
121
  const char *tagName = pSchema->name;
576✔
122

123
  tb_uid_t    suid = pCtbEntry->ctbEntry.suid;
576✔
124
  tb_uid_t    tuid = pCtbEntry->uid;
576✔
125
  const void *pTagData = pCtbEntry->ctbEntry.pTags;
576✔
126
  int32_t     nTagData = 0;
576✔
127

128
  SArray *pTagVals = NULL;
576✔
129
  code = tTagToValArray((const STag *)data, &pTagVals);
576✔
130
  if (code) {
576!
131
    return code;
×
132
  }
133

134
  SIndexMultiTerm *terms = indexMultiTermCreate();
576✔
135
  if (terms == NULL) {
576!
136
    return terrno;
×
137
  }
138

139
  int16_t nCols = taosArrayGetSize(pTagVals);
576✔
140
  for (int i = 0; i < nCols; i++) {
1,513✔
141
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
937✔
142
    char     type = pTagVal->type;
937✔
143

144
    char   *key = pTagVal->pKey;
937✔
145
    int32_t nKey = strlen(key);
937✔
146

147
    SIndexTerm *term = NULL;
937✔
148
    if (type == TSDB_DATA_TYPE_NULL) {
937✔
149
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
24✔
150
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
913✔
151
      if (pTagVal->nData > 0) {
812✔
152
        char *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
796✔
153
        if (val == NULL) {
796!
154
          TAOS_CHECK_GOTO(terrno, NULL, _exception);
×
155
        }
156
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE);
796✔
157
        if (len < 0) {
796!
158
          TAOS_CHECK_GOTO(len, NULL, _exception);
×
159
        }
160
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
796✔
161
        type = TSDB_DATA_TYPE_VARCHAR;
796✔
162
        term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, val, len);
796✔
163
        taosMemoryFree(val);
796✔
164
      } else if (pTagVal->nData == 0) {
16!
165
        term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, pTagVal->pData, 0);
16✔
166
      }
167
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
101✔
168
      double val = *(double *)(&pTagVal->i64);
77✔
169
      int    len = sizeof(val);
77✔
170
      term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
77✔
171
    } else if (type == TSDB_DATA_TYPE_BOOL) {
24!
172
      int val = *(int *)(&pTagVal->i64);
24✔
173
      int len = sizeof(val);
24✔
174
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_BOOL, key, nKey, (const char *)&val, len);
24✔
175
    }
176

177
    if (term != NULL) {
937!
178
      int32_t ret = indexMultiTermAdd(terms, term);
937✔
179
      if (ret < 0) {
937!
180
        metaError("vgId:%d, failed to add term to multi term, uid: %" PRId64 ", key: %s, type: %d, ret: %d",
×
181
                  TD_VID(pMeta->pVnode), tuid, key, type, ret);
182
      }
183
    } else {
184
      code = terrno;
×
185
      goto _exception;
×
186
    }
187
  }
188
  code = indexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
576✔
189
  indexMultiTermDestroy(terms);
576✔
190

191
  taosArrayDestroy(pTagVals);
576✔
192
#endif
193
  return code;
576✔
194
_exception:
×
195
  indexMultiTermDestroy(terms);
×
196
  taosArrayDestroy(pTagVals);
×
197
  return code;
×
198
}
199
int metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
196✔
200
#ifdef USE_INVERTED_INDEX
201
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
196!
202
    return TSDB_CODE_INVALID_PARA;
×
203
  }
204
  void       *data = pCtbEntry->ctbEntry.pTags;
196✔
205
  const char *tagName = pSchema->name;
196✔
206

207
  tb_uid_t    suid = pCtbEntry->ctbEntry.suid;
196✔
208
  tb_uid_t    tuid = pCtbEntry->uid;
196✔
209
  const void *pTagData = pCtbEntry->ctbEntry.pTags;
196✔
210
  int32_t     nTagData = 0;
196✔
211

212
  SArray *pTagVals = NULL;
196✔
213
  int32_t code = tTagToValArray((const STag *)data, &pTagVals);
196✔
214
  if (code) {
196!
215
    return code;
×
216
  }
217

218
  SIndexMultiTerm *terms = indexMultiTermCreate();
196✔
219
  if (terms == NULL) {
196!
220
    return terrno;
×
221
  }
222

223
  int16_t nCols = taosArrayGetSize(pTagVals);
196✔
224
  for (int i = 0; i < nCols; i++) {
555✔
225
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
359✔
226
    char     type = pTagVal->type;
359✔
227

228
    char   *key = pTagVal->pKey;
359✔
229
    int32_t nKey = strlen(key);
359✔
230

231
    SIndexTerm *term = NULL;
359✔
232
    if (type == TSDB_DATA_TYPE_NULL) {
359!
233
      term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
×
234
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
359✔
235
      if (pTagVal->nData > 0) {
355!
236
        char *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
355✔
237
        if (val == NULL) {
355!
238
          TAOS_CHECK_GOTO(terrno, NULL, _exception);
×
239
        }
240
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE);
355✔
241
        if (len < 0) {
355!
242
          TAOS_CHECK_GOTO(len, NULL, _exception);
×
243
        }
244
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
355✔
245
        type = TSDB_DATA_TYPE_VARCHAR;
355✔
246
        term = indexTermCreate(suid, DEL_VALUE, type, key, nKey, val, len);
355✔
247
        taosMemoryFree(val);
355✔
248
      } else if (pTagVal->nData == 0) {
×
249
        term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, pTagVal->pData, 0);
×
250
      }
251
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
4!
252
      double val = *(double *)(&pTagVal->i64);
4✔
253
      int    len = sizeof(val);
4✔
254
      term = indexTermCreate(suid, DEL_VALUE, type, key, nKey, (const char *)&val, len);
4✔
255
    } else if (type == TSDB_DATA_TYPE_BOOL) {
×
256
      int val = *(int *)(&pTagVal->i64);
×
257
      int len = sizeof(val);
×
258
      term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_BOOL, key, nKey, (const char *)&val, len);
×
259
    }
260
    if (term != NULL) {
359!
261
      int32_t ret = indexMultiTermAdd(terms, term);
359✔
262
      if (ret < 0) {
359!
263
        metaError("vgId:%d, failed to add term to multi term, uid: %" PRId64 ", key: %s, type: %d, ret: %d",
×
264
                  TD_VID(pMeta->pVnode), tuid, key, type, ret);
265
      }
266
    } else {
267
      code = terrno;
×
268
      goto _exception;
×
269
    }
270
  }
271
  code = indexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
196✔
272
  indexMultiTermDestroy(terms);
196✔
273
  taosArrayDestroy(pTagVals);
196✔
274
#endif
275
  return code;
196✔
276
_exception:
×
277
  indexMultiTermDestroy(terms);
×
278
  taosArrayDestroy(pTagVals);
×
279
  return code;
×
280
}
281

282
static inline void metaTimeSeriesNotifyCheck(SMeta *pMeta) {
182,775✔
283
#if defined(TD_ENTERPRISE)
284
  int64_t nTimeSeries = metaGetTimeSeriesNum(pMeta, 0);
182,775✔
285
  int64_t deltaTS = nTimeSeries - pMeta->pVnode->config.vndStats.numOfReportedTimeSeries;
182,795✔
286
  if (deltaTS > tsTimeSeriesThreshold) {
182,795✔
287
    if (0 == atomic_val_compare_exchange_8(&dmNotifyHdl.state, 1, 2)) {
119,556✔
288
      if (tsem_post(&dmNotifyHdl.sem) != 0) {
119,546!
289
        metaError("vgId:%d, failed to post semaphore, errno:%d", TD_VID(pMeta->pVnode), errno);
×
290
      }
291
    }
292
  }
293
#endif
294
}
182,817✔
295

296
int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
30,685✔
297
  SMetaEntry  me = {0};
30,685✔
298
  int         kLen = 0;
30,685✔
299
  int         vLen = 0;
30,685✔
300
  const void *pKey = NULL;
30,685✔
301
  const void *pVal = NULL;
30,685✔
302
  void       *pBuf = NULL;
30,685✔
303
  int32_t     szBuf = 0;
30,685✔
304
  void       *p = NULL;
30,685✔
305
  int32_t     code = 0;
30,685✔
306

307
  // validate req
308
  void *pData = NULL;
30,685✔
309
  int   nData = 0;
30,685✔
310
  if (tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData) == 0) {
30,685✔
311
    tb_uid_t uid = *(tb_uid_t *)pData;
33✔
312
    tdbFree(pData);
33✔
313
    SMetaInfo info;
314
    if (metaGetInfo(pMeta, uid, &info, NULL) == TSDB_CODE_NOT_FOUND) {
33!
315
      return terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
×
316
    }
317
    if (info.uid == info.suid) {
33✔
318
      return 0;
29✔
319
    } else {
320
      return terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
4✔
321
    }
322
  }
323

324
  // set structs
325
  me.version = version;
30,915✔
326
  me.type = TSDB_SUPER_TABLE;
30,915✔
327
  me.uid = pReq->suid;
30,915✔
328
  me.name = pReq->name;
30,915✔
329
  me.stbEntry.schemaRow = pReq->schemaRow;
30,915✔
330
  me.stbEntry.schemaTag = pReq->schemaTag;
30,915✔
331
  if (pReq->rollup) {
30,915✔
332
    TABLE_SET_ROLLUP(me.flags);
7✔
333
    me.stbEntry.rsmaParam = pReq->rsmaParam;
7✔
334
  }
335
  if (pReq->colCmpred) {
30,915✔
336
    TABLE_SET_COL_COMPRESSED(me.flags);
30,806✔
337
    me.colCmpr = pReq->colCmpr;
30,806✔
338
  }
339

340
  code = metaHandleEntry(pMeta, &me);
30,915✔
341
  if (code) goto _err;
30,852!
342

343
  ++pMeta->pVnode->config.vndStats.numOfSTables;
30,852✔
344

345
  pMeta->changed = true;
30,852✔
346
  metaDebug("vgId:%d, stb:%s is created, suid:%" PRId64, TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
30,852✔
347

348
  return 0;
30,863✔
349

350
_err:
×
351
  metaError("vgId:%d, failed to create stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
352
            tstrerror(terrno));
353
  return code;
×
354
}
355

356
int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq, SArray *tbUidList) {
3,458✔
357
  void   *pKey = NULL;
3,458✔
358
  int     nKey = 0;
3,458✔
359
  void   *pData = NULL;
3,458✔
360
  int     nData = 0;
3,458✔
361
  int     c = 0;
3,458✔
362
  int     rc = 0;
3,458✔
363
  int32_t lino;
364
  int32_t ret;
365

366
  // check if super table exists
367
  rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
3,458✔
368
  if (rc < 0 || *(tb_uid_t *)pData != pReq->suid) {
3,461✔
369
    tdbFree(pData);
8✔
370
    return terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
8✔
371
  }
372

373
  // drop all child tables
374
  TBC *pCtbIdxc = NULL;
3,453✔
375

376
  rc = tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL);
3,453✔
377
  if (rc) {
3,454!
378
    return (terrno = rc);
×
379
  }
380

381
  rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = pReq->suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
3,454✔
382
  if (rc < 0) {
3,452!
383
    tdbTbcClose(pCtbIdxc);
×
384
    metaWLock(pMeta);
×
385
    goto _drop_super_table;
×
386
  }
387

388
  for (;;) {
389
    rc = tdbTbcNext(pCtbIdxc, &pKey, &nKey, NULL, NULL);
8,615✔
390
    if (rc < 0) break;
8,614✔
391

392
    if (((SCtbIdxKey *)pKey)->suid < pReq->suid) {
6,088✔
393
      continue;
870✔
394
    } else if (((SCtbIdxKey *)pKey)->suid > pReq->suid) {
5,218✔
395
      break;
928✔
396
    }
397

398
    if (taosArrayPush(tbUidList, &(((SCtbIdxKey *)pKey)->uid)) == NULL) {
8,583!
399
      tdbFree(pKey);
×
400
      tdbTbcClose(pCtbIdxc);
×
401
      return terrno;
×
402
    }
403
  }
404

405
  tdbTbcClose(pCtbIdxc);
3,454✔
406

407
  ret = tsdbCacheDropSubTables(pMeta->pVnode->pTsdb, tbUidList, pReq->suid);
3,452✔
408
  if (ret < 0) {
3,455!
409
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
410
              tstrerror(terrno));
411
  }
412

413
  metaWLock(pMeta);
3,455✔
414

415
  for (int32_t iChild = 0; iChild < taosArrayGetSize(tbUidList); iChild++) {
7,761✔
416
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(tbUidList, iChild);
4,307✔
417
    ret = metaDropTableByUid(pMeta, uid, NULL, NULL, NULL);
4,307✔
418
    if (ret < 0) {
4,307!
419
      metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
420
                pReq->suid, tstrerror(terrno));
421
    }
422
  }
423

424
  // drop super table
425
_drop_super_table:
3,454✔
426
  tdbTbGet(pMeta->pUidIdx, &pReq->suid, sizeof(tb_uid_t), &pData, &nData);
3,454✔
427
  ret = tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = ((SUidIdxVal *)pData)[0].version, .uid = pReq->suid},
3,454✔
428
                    sizeof(STbDbKey), pMeta->txn);
429
  if (ret < 0) {
3,455!
430
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
431
              tstrerror(terrno));
432
  }
433

434
  ret = tdbTbDelete(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, pMeta->txn);
3,455✔
435
  if (ret < 0) {
3,455!
436
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
437
              tstrerror(terrno));
438
  }
439

440
  ret = tdbTbDelete(pMeta->pUidIdx, &pReq->suid, sizeof(tb_uid_t), pMeta->txn);
3,455✔
441
  if (ret < 0) {
3,455!
442
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
443
              tstrerror(terrno));
444
  }
445

446
  ret = tdbTbDelete(pMeta->pSuidIdx, &pReq->suid, sizeof(tb_uid_t), pMeta->txn);
3,455✔
447
  if (ret < 0) {
3,455!
448
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
449
              tstrerror(terrno));
450
  }
451

452
  ret = metaStatsCacheDrop(pMeta, pReq->suid);
3,455✔
453
  if (ret < 0) {
3,455✔
454
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
478!
455
              tstrerror(terrno));
456
  }
457

458
  metaULock(pMeta);
3,455✔
459

460
  metaUpdTimeSeriesNum(pMeta);
3,453✔
461

462
  pMeta->changed = true;
3,455✔
463

464
_exit:
3,455✔
465
  tdbFree(pKey);
3,455✔
466
  tdbFree(pData);
3,455✔
467
  metaDebug("vgId:%d, super table %s uid:%" PRId64 " is dropped", TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
3,454✔
468
  return 0;
3,454✔
469
}
470

471
static int32_t metaGetSubtables(SMeta *pMeta, int64_t suid, SArray *uids) {
96✔
472
  if (!uids) return TSDB_CODE_INVALID_PARA;
96!
473

474
  int   c = 0;
96✔
475
  void *pKey = NULL;
96✔
476
  int   nKey = 0;
96✔
477
  TBC  *pCtbIdxc = NULL;
96✔
478

479
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL));
96!
480
  int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
96✔
481
  if (rc < 0) {
96!
482
    tdbTbcClose(pCtbIdxc);
×
483
    metaWLock(pMeta);
×
484
    return 0;
×
485
  }
486

487
  for (;;) {
488
    rc = tdbTbcNext(pCtbIdxc, &pKey, &nKey, NULL, NULL);
336✔
489
    if (rc < 0) break;
336✔
490

491
    if (((SCtbIdxKey *)pKey)->suid < suid) {
240!
492
      continue;
×
493
    } else if (((SCtbIdxKey *)pKey)->suid > suid) {
240!
494
      break;
×
495
    }
496

497
    if (taosArrayPush(uids, &(((SCtbIdxKey *)pKey)->uid)) == NULL) {
480!
498
      tdbFree(pKey);
×
499
      tdbTbcClose(pCtbIdxc);
×
500
      return terrno;
×
501
    }
502
  }
503

504
  tdbFree(pKey);
96✔
505

506
  tdbTbcClose(pCtbIdxc);
96✔
507
  return 0;
96✔
508
}
509

510
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
4,943✔
511
  SMetaEntry  oStbEntry = {0};
4,943✔
512
  SMetaEntry  nStbEntry = {0};
4,943✔
513
  TBC        *pUidIdxc = NULL;
4,943✔
514
  TBC        *pTbDbc = NULL;
4,943✔
515
  const void *pData;
516
  int         nData;
517
  int64_t     oversion;
518
  SDecoder    dc = {0};
4,943✔
519
  int32_t     ret;
520
  int32_t     c = -2;
4,943✔
521

522
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
4,943!
523
  ret = tdbTbcMoveTo(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &c);
4,952✔
524
  if (ret < 0 || c) {
4,941!
525
    tdbTbcClose(pUidIdxc);
×
526

527
    return terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
×
528
  }
529

530
  ret = tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
4,953✔
531
  if (ret < 0) {
4,958!
532
    tdbTbcClose(pUidIdxc);
×
533

534
    return terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
×
535
  }
536

537
  oversion = ((SUidIdxVal *)pData)[0].version;
4,958✔
538

539
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
4,958!
540
  ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c);
4,960✔
541
  if (!(ret == 0 && c == 0)) {
4,954!
542
    tdbTbcClose(pUidIdxc);
7✔
543
    tdbTbcClose(pTbDbc);
×
544

545
    metaError("meta/table: invalide ret: %" PRId32 " or c: %" PRId32 "alter stb failed.", ret, c);
×
546
    return terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
×
547
  }
548

549
  ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
4,947✔
550
  if (ret < 0) {
4,949!
551
    tdbTbcClose(pUidIdxc);
×
552
    tdbTbcClose(pTbDbc);
×
553

554
    return terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
×
555
  }
556

557
  if ((oStbEntry.pBuf = taosMemoryMalloc(nData)) == NULL) {
4,949!
558
    tdbTbcClose(pTbDbc);
×
559
    tdbTbcClose(pUidIdxc);
×
560
    return terrno;
×
561
  }
562
  memcpy(oStbEntry.pBuf, pData, nData);
4,955✔
563
  tDecoderInit(&dc, oStbEntry.pBuf, nData);
4,955✔
564
  ret = metaDecodeEntry(&dc, &oStbEntry);
4,939✔
565
  if (ret < 0) {
4,934!
566
    metaError("vgId:%d, failed to decode stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
567
              pReq->suid, tstrerror(ret));
568
    tDecoderClear(&dc);
×
569
    tdbTbcClose(pTbDbc);
×
570
    tdbTbcClose(pUidIdxc);
×
571
    return terrno;
×
572
  }
573

574
  nStbEntry.version = version;
4,934✔
575
  nStbEntry.type = TSDB_SUPER_TABLE;
4,934✔
576
  nStbEntry.uid = pReq->suid;
4,934✔
577
  nStbEntry.name = pReq->name;
4,934✔
578
  nStbEntry.stbEntry.schemaRow = pReq->schemaRow;
4,934✔
579
  nStbEntry.stbEntry.schemaTag = pReq->schemaTag;
4,934✔
580
  nStbEntry.colCmpr = pReq->colCmpr;
4,934✔
581
  TABLE_SET_COL_COMPRESSED(nStbEntry.flags);
4,934✔
582

583
  int     nCols = pReq->schemaRow.nCols;
4,934✔
584
  int     onCols = oStbEntry.stbEntry.schemaRow.nCols;
4,934✔
585
  int32_t deltaCol = nCols - onCols;
4,934✔
586
  bool    updStat = deltaCol != 0 && !metaTbInFilterCache(pMeta, pReq->name, 1);
4,934!
587

588
  if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
4,940✔
589
    STsdb  *pTsdb = pMeta->pVnode->pTsdb;
128✔
590
    SArray *uids = taosArrayInit(8, sizeof(int64_t));
128✔
591
    if (uids == NULL) {
128!
592
      if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
×
593
      tDecoderClear(&dc);
×
594
      tdbTbcClose(pTbDbc);
×
595
      tdbTbcClose(pUidIdxc);
×
596
      return terrno;
×
597
    }
598
    if (deltaCol == 1) {
128✔
599
      int16_t cid = pReq->schemaRow.pSchema[nCols - 1].colId;
64✔
600
      int8_t  col_type = pReq->schemaRow.pSchema[nCols - 1].type;
64✔
601

602
      TAOS_CHECK_RETURN(metaGetSubtables(pMeta, pReq->suid, uids));
64!
603
      TAOS_CHECK_RETURN(tsdbCacheNewSTableColumn(pTsdb, uids, cid, col_type));
64!
604
    } else if (deltaCol == -1) {
64✔
605
      int16_t cid = -1;
63✔
606
      bool    hasPrimaryKey = false;
63✔
607
      if (onCols >= 2) {
63!
608
        hasPrimaryKey = (oStbEntry.stbEntry.schemaRow.pSchema[1].flags & COL_IS_KEY) ? true : false;
63✔
609
      }
610
      for (int i = 0, j = 0; i < nCols && j < onCols; ++i, ++j) {
400✔
611
        if (pReq->schemaRow.pSchema[i].colId != oStbEntry.stbEntry.schemaRow.pSchema[j].colId) {
369✔
612
          cid = oStbEntry.stbEntry.schemaRow.pSchema[j].colId;
32✔
613
          break;
32✔
614
        }
615
      }
616

617
      if (cid != -1) {
63✔
618
        TAOS_CHECK_RETURN(metaGetSubtables(pMeta, pReq->suid, uids));
32!
619
        TAOS_CHECK_RETURN(tsdbCacheDropSTableColumn(pTsdb, uids, cid, hasPrimaryKey));
32!
620
      }
621
    }
622
    if (uids) taosArrayDestroy(uids);
128✔
623

624
    tsdbCacheInvalidateSchema(pTsdb, pReq->suid, -1, pReq->schemaRow.version);
128✔
625
  }
626

627
  metaWLock(pMeta);
4,939✔
628
  // compare two entry
629
  if (oStbEntry.stbEntry.schemaRow.version != pReq->schemaRow.version) {
4,957✔
630
    ret = metaSaveToSkmDb(pMeta, &nStbEntry);
3,019✔
631
    if (ret < 0) {
3,020!
632
      metaError("vgId:%d, failed to save skm db:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
633
                pReq->suid, tstrerror(ret));
634
    }
635
  }
636

637
  // update table.db
638
  ret = metaSaveToTbDb(pMeta, &nStbEntry);
4,958✔
639
  if (ret < 0) {
4,956!
640
    metaError("vgId:%d, failed to save tb db:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
641
              pReq->suid, tstrerror(ret));
642
  }
643

644
  // update uid index
645
  ret = metaUpdateUidIdx(pMeta, &nStbEntry);
4,956✔
646
  if (ret < 0) {
4,959!
647
    metaError("vgId:%d, failed to update uid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
648
              pReq->suid, tstrerror(ret));
649
  }
650

651
  // metaStatsCacheDrop(pMeta, nStbEntry.uid);
652

653
  if (updStat) {
4,952✔
654
    metaUpdateStbStats(pMeta, pReq->suid, 0, deltaCol);
2,157✔
655
  }
656
  metaULock(pMeta);
4,951✔
657

658
  if (updStat) {
4,955✔
659
    int64_t ctbNum;
660
    ret = metaGetStbStats(pMeta->pVnode, pReq->suid, &ctbNum, NULL);
2,167✔
661
    if (ret < 0) {
2,159!
662
      metaError("vgId:%d, failed to get stb stats:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
663
                pReq->suid, tstrerror(ret));
664
    }
665
    pMeta->pVnode->config.vndStats.numOfTimeSeries += (ctbNum * deltaCol);
2,159✔
666
    metaTimeSeriesNotifyCheck(pMeta);
2,159✔
667
  }
668

669
  pMeta->changed = true;
4,948✔
670

671
_exit:
4,948✔
672
  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
4,948!
673
  tDecoderClear(&dc);
4,954✔
674
  tdbTbcClose(pTbDbc);
4,954✔
675
  tdbTbcClose(pUidIdxc);
4,959✔
676
  return 0;
4,956✔
677
}
678
int metaAddIndexToSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
979✔
679
  SMetaEntry oStbEntry = {0};
979✔
680
  SMetaEntry nStbEntry = {0};
979✔
681
  STbDbKey   tbDbKey = {0};
979✔
682

683
  TBC     *pUidIdxc = NULL;
979✔
684
  TBC     *pTbDbc = NULL;
979✔
685
  void    *pData = NULL;
979✔
686
  int      nData = 0;
979✔
687
  int64_t  oversion;
688
  SDecoder dc = {0};
979✔
689
  int32_t  ret;
690
  int32_t  c = -2;
979✔
691
  tb_uid_t suid = pReq->suid;
979✔
692
  int32_t  code = 0;
979✔
693

694
  // get super table
695
  if ((code = tdbTbGet(pMeta->pUidIdx, &suid, sizeof(tb_uid_t), &pData, &nData)) != 0) {
979!
696
    goto _err;
×
697
  }
698

699
  tbDbKey.uid = suid;
979✔
700
  tbDbKey.version = ((SUidIdxVal *)pData)[0].version;
979✔
701
  if ((code = tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData)) != 0) {
979!
702
    goto _err;
×
703
  }
704

705
  tDecoderInit(&dc, pData, nData);
979✔
706
  code = metaDecodeEntry(&dc, &oStbEntry);
979✔
707
  if (code < 0) {
979!
708
    goto _err;
×
709
  }
710

711
  if (oStbEntry.stbEntry.schemaTag.pSchema == NULL || oStbEntry.stbEntry.schemaTag.pSchema == NULL) {
979!
712
    code = TSDB_CODE_INVALID_PARA;
×
713
    goto _err;
×
714
  }
715

716
  if (oStbEntry.stbEntry.schemaTag.version == pReq->schemaTag.version) {
979!
717
    code = TSDB_CODE_INVALID_PARA;
×
718
    goto _err;
×
719
  }
720

721
  if (oStbEntry.stbEntry.schemaTag.nCols != pReq->schemaTag.nCols) {
979!
722
    code = TSDB_CODE_INVALID_PARA;
×
723
    goto _err;
×
724
  }
725

726
  int diffIdx = -1;
979✔
727
  for (int i = 0; i < pReq->schemaTag.nCols; i++) {
7,656!
728
    SSchema *pNew = pReq->schemaTag.pSchema + i;
7,656✔
729
    SSchema *pOld = oStbEntry.stbEntry.schemaTag.pSchema + i;
7,656✔
730
    if (pNew->type != pOld->type || pNew->colId != pOld->colId || pNew->bytes != pOld->bytes ||
7,656!
731
        strncmp(pOld->name, pNew->name, sizeof(pNew->name))) {
7,656!
732
      code = TSDB_CODE_INVALID_PARA;
×
733
      goto _err;
×
734
    }
735
    if (IS_IDX_ON(pNew) && !IS_IDX_ON(pOld)) {
7,656✔
736
      // if (diffIdx != -1) goto _err;
737
      diffIdx = i;
979✔
738
      break;
979✔
739
    }
740
  }
741

742
  if (diffIdx == -1) {
979!
743
    code = TSDB_CODE_INVALID_PARA;
×
744
    goto _err;
×
745
  }
746

747
  // Get target schema info
748
  SSchemaWrapper *pTagSchema = &pReq->schemaTag;
979✔
749
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
979!
750
    code = TSDB_CODE_INVALID_PARA;
×
751
    goto _err;
×
752
  }
753
  SSchema *pCol = pTagSchema->pSchema + diffIdx;
979✔
754

755
  /*
756
   * iterator all pTdDbc by uid and version
757
   */
758
  TBC *pCtbIdxc = NULL;
979✔
759
  code = tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL);
979✔
760
  if (code != 0) {
979!
761
    goto _err;
×
762
  }
763

764
  code = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
979✔
765
  if (code < 0) {
979!
766
    tdbTbcClose(pCtbIdxc);
×
767
    goto _err;
×
768
  }
769
  for (;;) {
17,051✔
770
    void *pKey = NULL, *pVal = NULL;
18,030✔
771
    int   nKey = 0, nVal = 0;
18,030✔
772
    code = tdbTbcNext(pCtbIdxc, &pKey, &nKey, &pVal, &nVal);
18,030✔
773
    if (code < 0) {
18,030✔
774
      tdbFree(pKey);
979✔
775
      tdbFree(pVal);
979✔
776
      tdbTbcClose(pCtbIdxc);
979✔
777
      pCtbIdxc = NULL;
979✔
778
      break;
979✔
779
    }
780
    if (((SCtbIdxKey *)pKey)->suid != suid) {
17,051✔
781
      tdbFree(pKey);
1,708✔
782
      tdbFree(pVal);
1,708✔
783
      continue;
1,708✔
784
    }
785
    STagIdxKey *pTagIdxKey = NULL;
15,343✔
786
    int32_t     nTagIdxKey;
787

788
    const void *pTagData = NULL;
15,343✔
789
    int32_t     nTagData = 0;
15,343✔
790

791
    SCtbIdxKey *table = (SCtbIdxKey *)pKey;
15,343✔
792
    STagVal     tagVal = {.cid = pCol->colId};
15,343✔
793
    if (tTagGet((const STag *)pVal, &tagVal)) {
15,343!
794
      if (IS_VAR_DATA_TYPE(pCol->type)) {
15,343!
795
        pTagData = tagVal.pData;
2,378✔
796
        nTagData = (int32_t)tagVal.nData;
2,378✔
797
      } else {
798
        pTagData = &(tagVal.i64);
12,965✔
799
        nTagData = tDataTypes[pCol->type].bytes;
12,965✔
800
      }
801
    } else {
802
      if (!IS_VAR_DATA_TYPE(pCol->type)) {
×
803
        nTagData = tDataTypes[pCol->type].bytes;
×
804
      }
805
    }
806
    code = metaCreateTagIdxKey(suid, pCol->colId, pTagData, nTagData, pCol->type, table->uid, &pTagIdxKey, &nTagIdxKey);
15,343✔
807
    tdbFree(pKey);
15,343✔
808
    tdbFree(pVal);
15,343✔
809
    if (code < 0) {
15,343!
810
      metaDestroyTagIdxKey(pTagIdxKey);
×
811
      tdbTbcClose(pCtbIdxc);
×
812
      goto _err;
×
813
    }
814

815
    metaWLock(pMeta);
15,343✔
816
    ret = tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
15,343✔
817
    if (ret < 0) {
15,343!
818
      metaError("vgId:%d, failed to upsert tag idx key:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
819
                pReq->suid, tstrerror(ret));
820
    }
821
    metaULock(pMeta);
15,343✔
822

823
    metaDestroyTagIdxKey(pTagIdxKey);
15,343✔
824
    pTagIdxKey = NULL;
15,343✔
825
  }
826

827
  nStbEntry.version = version;
979✔
828
  nStbEntry.type = TSDB_SUPER_TABLE;
979✔
829
  nStbEntry.uid = pReq->suid;
979✔
830
  nStbEntry.name = pReq->name;
979✔
831
  nStbEntry.stbEntry.schemaRow = pReq->schemaRow;
979✔
832
  nStbEntry.stbEntry.schemaTag = pReq->schemaTag;
979✔
833
  nStbEntry.colCmpr = pReq->colCmpr;
979✔
834

835
  metaWLock(pMeta);
979✔
836
  // update table.db
837
  ret = metaSaveToTbDb(pMeta, &nStbEntry);
979✔
838
  if (ret < 0) {
979!
839
    metaError("vgId:%d, failed to save tb db:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
840
              pReq->suid, tstrerror(ret));
841
  }
842
  // update uid index
843
  ret = metaUpdateUidIdx(pMeta, &nStbEntry);
979✔
844
  if (ret < 0) {
979!
845
    metaError("vgId:%d, failed to update uid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
846
              pReq->suid, tstrerror(ret));
847
  }
848
  metaULock(pMeta);
979✔
849

850
  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
979!
851
  tDecoderClear(&dc);
979✔
852
  tdbFree(pData);
979✔
853

854
  tdbTbcClose(pCtbIdxc);
979✔
855
  return TSDB_CODE_SUCCESS;
979✔
856
_err:
×
857
  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
×
858
  tDecoderClear(&dc);
×
859
  tdbFree(pData);
×
860

861
  return code;
×
862
}
863
int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq) {
2,154✔
864
  int32_t    code = 0;
2,154✔
865
  SMetaEntry oStbEntry = {0};
2,154✔
866
  SMetaEntry nStbEntry = {0};
2,154✔
867

868
  STbDbKey tbDbKey = {0};
2,154✔
869
  TBC     *pUidIdxc = NULL;
2,154✔
870
  TBC     *pTbDbc = NULL;
2,154✔
871
  int      ret = 0;
2,154✔
872
  int      c = -2;
2,154✔
873
  void    *pData = NULL;
2,154✔
874
  int      nData = 0;
2,154✔
875
  int64_t  oversion;
876
  SDecoder dc = {0};
2,154✔
877

878
  tb_uid_t suid = pReq->stbUid;
2,154✔
879

880
  if ((code = tdbTbGet(pMeta->pUidIdx, &suid, sizeof(tb_uid_t), &pData, &nData)) != 0) {
2,154!
881
    goto _err;
×
882
  }
883

884
  tbDbKey.uid = suid;
2,154✔
885
  tbDbKey.version = ((SUidIdxVal *)pData)[0].version;
2,154✔
886
  if ((code = tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData)) != 0) {
2,154!
887
    goto _err;
×
888
  }
889

890
  tDecoderInit(&dc, pData, nData);
2,154✔
891
  code = metaDecodeEntry(&dc, &oStbEntry);
2,154✔
892
  if (code != 0) {
2,154!
893
    goto _err;
×
894
  }
895

896
  SSchema *pCol = NULL;
2,154✔
897
  int32_t  colId = -1;
2,154✔
898
  for (int i = 0; i < oStbEntry.stbEntry.schemaTag.nCols; i++) {
6,736!
899
    SSchema *schema = oStbEntry.stbEntry.schemaTag.pSchema + i;
6,736✔
900
    if (0 == strncmp(schema->name, pReq->colName, sizeof(pReq->colName))) {
6,736✔
901
      if (IS_IDX_ON(schema)) {
2,154!
902
        pCol = schema;
2,154✔
903
      }
904
      break;
2,154✔
905
    }
906
  }
907

908
  if (pCol == NULL) {
2,154!
909
    metaError("vgId:%d, failed to drop index on %s.%s,since %s", TD_VID(pMeta->pVnode), pReq->stb, pReq->colName,
×
910
              tstrerror(TSDB_CODE_VND_COL_NOT_EXISTS));
911
    code = 0;
×
912

913
    goto _err;
×
914
  }
915

916
  /*
917
   * iterator all pTdDbc by uid and version
918
   */
919
  TBC *pCtbIdxc = NULL;
2,154✔
920
  code = tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL);
2,154✔
921
  if (code != 0) {
2,154!
922
    goto _err;
×
923
  }
924

925
  code = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
2,154✔
926
  if (code < 0) {
2,154!
927
    tdbTbcClose(pCtbIdxc);
×
928
    goto _err;
×
929
  }
930
  for (;;) {
15,913✔
931
    void *pKey = NULL, *pVal = NULL;
18,067✔
932
    int   nKey = 0, nVal = 0;
18,067✔
933

934
    code = tdbTbcNext(pCtbIdxc, &pKey, &nKey, &pVal, &nVal);
18,067✔
935
    if (code < 0) {
18,067✔
936
      tdbFree(pKey);
2,154✔
937
      tdbFree(pVal);
2,154✔
938
      tdbTbcClose(pCtbIdxc);
2,154✔
939
      pCtbIdxc = NULL;
2,154✔
940
      break;
2,154✔
941
    }
942
    if (((SCtbIdxKey *)pKey)->suid != suid) {
15,913✔
943
      tdbFree(pKey);
3,863✔
944
      tdbFree(pVal);
3,863✔
945
      continue;
3,863✔
946
    }
947
    STagIdxKey *pTagIdxKey = NULL;
12,050✔
948
    int32_t     nTagIdxKey;
949

950
    const void *pTagData = NULL;
12,050✔
951
    int32_t     nTagData = 0;
12,050✔
952

953
    SCtbIdxKey *table = (SCtbIdxKey *)pKey;
12,050✔
954
    STagVal     tagVal = {.cid = pCol->colId};
12,050✔
955
    if (tTagGet((const STag *)pVal, &tagVal)) {
12,050!
956
      if (IS_VAR_DATA_TYPE(pCol->type)) {
12,050!
957
        pTagData = tagVal.pData;
3,549✔
958
        nTagData = (int32_t)tagVal.nData;
3,549✔
959
      } else {
960
        pTagData = &(tagVal.i64);
8,501✔
961
        nTagData = tDataTypes[pCol->type].bytes;
8,501✔
962
      }
963
    } else {
964
      if (!IS_VAR_DATA_TYPE(pCol->type)) {
×
965
        nTagData = tDataTypes[pCol->type].bytes;
×
966
      }
967
    }
968

969
    code = metaCreateTagIdxKey(suid, pCol->colId, pTagData, nTagData, pCol->type, table->uid, &pTagIdxKey, &nTagIdxKey);
12,050✔
970
    tdbFree(pKey);
12,050✔
971
    tdbFree(pVal);
12,050✔
972
    if (code < 0) {
12,050!
973
      metaDestroyTagIdxKey(pTagIdxKey);
×
974
      tdbTbcClose(pCtbIdxc);
×
975
      goto _err;
×
976
    }
977

978
    metaWLock(pMeta);
12,050✔
979
    ret = tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
12,050✔
980
    if (ret < 0) {
12,050!
981
      metaError("vgId:%d, failed to delete tag idx key:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->stb,
×
982
                pReq->stbUid, tstrerror(ret));
983
    }
984
    metaULock(pMeta);
12,050✔
985
    metaDestroyTagIdxKey(pTagIdxKey);
12,050✔
986
    pTagIdxKey = NULL;
12,050✔
987
  }
988

989
  // clear idx flag
990
  SSCHMEA_SET_IDX_OFF(pCol);
2,154✔
991

992
  nStbEntry.version = version;
2,154✔
993
  nStbEntry.type = TSDB_SUPER_TABLE;
2,154✔
994
  nStbEntry.uid = oStbEntry.uid;
2,154✔
995
  nStbEntry.name = oStbEntry.name;
2,154!
996

997
  SSchemaWrapper  *row = tCloneSSchemaWrapper(&oStbEntry.stbEntry.schemaRow);
2,154!
998
  SSchemaWrapper  *tag = tCloneSSchemaWrapper(&oStbEntry.stbEntry.schemaTag);
2,154!
999
  SColCmprWrapper *cmpr = tCloneSColCmprWrapper(&oStbEntry.colCmpr);
2,154✔
1000
  if (row == NULL || tag == NULL || cmpr == NULL) {
2,154!
1001
    tDeleteSchemaWrapper(row);
1002
    tDeleteSchemaWrapper(tag);
1003
    tDeleteSColCmprWrapper(cmpr);
1004
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1005

1006
    tdbTbcClose(pCtbIdxc);
×
1007
    goto _err;
×
1008
  }
1009

1010
  nStbEntry.stbEntry.schemaRow = *row;
2,154✔
1011
  nStbEntry.stbEntry.schemaTag = *tag;
2,154✔
1012
  nStbEntry.stbEntry.rsmaParam = oStbEntry.stbEntry.rsmaParam;
2,154✔
1013
  nStbEntry.colCmpr = *cmpr;
2,154✔
1014

1015
  nStbEntry.colCmpr = oStbEntry.colCmpr;
2,154✔
1016

1017
  metaWLock(pMeta);
2,154✔
1018
  // update table.db
1019
  ret = metaSaveToTbDb(pMeta, &nStbEntry);
2,154✔
1020
  if (ret < 0) {
2,154!
1021
    metaError("vgId:%d, failed to save tb db:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->stb,
×
1022
              pReq->stbUid, tstrerror(ret));
1023
  }
1024
  // update uid index
1025
  ret = metaUpdateUidIdx(pMeta, &nStbEntry);
2,154✔
1026
  if (ret < 0) {
2,154!
1027
    metaError("vgId:%d, failed to update uid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->stb,
×
1028
              pReq->stbUid, tstrerror(ret));
1029
  }
1030
  metaULock(pMeta);
2,154✔
1031

1032
  tDeleteSchemaWrapper(tag);
1033
  tDeleteSchemaWrapper(row);
1034
  tDeleteSColCmprWrapper(cmpr);
1035

1036
  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
2,154!
1037
  tDecoderClear(&dc);
2,154✔
1038
  tdbFree(pData);
2,154✔
1039

1040
  tdbTbcClose(pCtbIdxc);
2,154✔
1041
  return TSDB_CODE_SUCCESS;
2,154✔
1042
_err:
×
1043
  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
×
1044
  tDecoderClear(&dc);
×
1045
  tdbFree(pData);
×
1046

1047
  return code;
×
1048
}
1049

1050
int metaCreateTable(SMeta *pMeta, int64_t ver, SVCreateTbReq *pReq, STableMetaRsp **pMetaRsp) {
207,435✔
1051
  SMetaEntry  me = {0};
207,435✔
1052
  SMetaReader mr = {0};
207,435✔
1053
  int32_t     ret;
1054

1055
  // validate message
1056
  if (pReq->type != TSDB_CHILD_TABLE && pReq->type != TSDB_NORMAL_TABLE) {
207,435!
1057
    terrno = TSDB_CODE_INVALID_MSG;
×
1058
    goto _err;
×
1059
  }
1060

1061
  if (pReq->type == TSDB_CHILD_TABLE) {
207,435✔
1062
    tb_uid_t suid = metaGetTableEntryUidByName(pMeta, pReq->ctb.stbName);
192,265✔
1063
    if (suid != pReq->ctb.suid) {
192,242!
1064
      return terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
×
1065
    }
1066
  }
1067

1068
  // validate req
1069
  metaReaderDoInit(&mr, pMeta, META_READER_LOCK);
207,412✔
1070
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
207,449✔
1071
    if (pReq->type == TSDB_CHILD_TABLE && pReq->ctb.suid != mr.me.ctbEntry.suid) {
27,363✔
1072
      metaReaderClear(&mr);
9✔
1073
      return terrno = TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
9✔
1074
    }
1075
    pReq->uid = mr.me.uid;
27,354✔
1076
    if (pReq->type == TSDB_CHILD_TABLE) {
27,354✔
1077
      pReq->ctb.suid = mr.me.ctbEntry.suid;
27,348✔
1078
    }
1079
    metaReaderClear(&mr);
27,354✔
1080
    return terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
27,358✔
1081
  } else if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
180,082!
1082
    terrno = TSDB_CODE_SUCCESS;
180,078✔
1083
  }
1084
  metaReaderClear(&mr);
180,072✔
1085

1086
  bool sysTbl = (pReq->type == TSDB_CHILD_TABLE) && metaTbInFilterCache(pMeta, pReq->ctb.stbName, 1);
180,077!
1087

1088
  if (!sysTbl && ((terrno = grantCheck(TSDB_GRANT_TIMESERIES)) < 0)) goto _err;
180,071!
1089

1090
  // build SMetaEntry
1091
  SVnodeStats *pStats = &pMeta->pVnode->config.vndStats;
180,039✔
1092
  me.version = ver;
180,039✔
1093
  me.type = pReq->type;
180,039✔
1094
  me.uid = pReq->uid;
180,039✔
1095
  me.name = pReq->name;
180,039✔
1096
  if (me.type == TSDB_CHILD_TABLE) {
180,039✔
1097
    me.ctbEntry.btime = pReq->btime;
164,840✔
1098
    me.ctbEntry.ttlDays = pReq->ttl;
164,840✔
1099
    me.ctbEntry.commentLen = pReq->commentLen;
164,840✔
1100
    me.ctbEntry.comment = pReq->comment;
164,840✔
1101
    me.ctbEntry.suid = pReq->ctb.suid;
164,840✔
1102
    me.ctbEntry.pTags = pReq->ctb.pTag;
164,840✔
1103

1104
#ifdef TAG_FILTER_DEBUG
1105
    SArray *pTagVals = NULL;
1106
    int32_t code = tTagToValArray((STag *)pReq->ctb.pTag, &pTagVals);
1107
    for (int i = 0; i < taosArrayGetSize(pTagVals); i++) {
1108
      STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
1109

1110
      if (IS_VAR_DATA_TYPE(pTagVal->type)) {
1111
        char *buf = taosMemoryCalloc(pTagVal->nData + 1, 1);
1112
        memcpy(buf, pTagVal->pData, pTagVal->nData);
1113
        metaDebug("metaTag table:%s varchar index:%d cid:%d type:%d value:%s", pReq->name, i, pTagVal->cid,
1114
                  pTagVal->type, buf);
1115
        taosMemoryFree(buf);
1116
      } else {
1117
        double val = 0;
1118
        GET_TYPED_DATA(val, double, pTagVal->type, &pTagVal->i64);
1119
        metaDebug("metaTag table:%s number index:%d cid:%d type:%d value:%f", pReq->name, i, pTagVal->cid,
1120
                  pTagVal->type, val);
1121
      }
1122
    }
1123
#endif
1124

1125
    ++pStats->numOfCTables;
164,840✔
1126

1127
    if (!sysTbl) {
164,840!
1128
      int32_t nCols = 0;
164,847✔
1129
      ret = metaGetStbStats(pMeta->pVnode, me.ctbEntry.suid, 0, &nCols);
164,847✔
1130
      if (ret < 0) {
164,891!
1131
        metaError("vgId:%d, failed to get stb stats:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
1132
                  pReq->ctb.suid, tstrerror(ret));
1133
      }
1134
      pStats->numOfTimeSeries += nCols - 1;
164,889✔
1135
    }
1136

1137
    metaWLock(pMeta);
164,882✔
1138
    metaUpdateStbStats(pMeta, me.ctbEntry.suid, 1, 0);
164,901✔
1139
    ret = metaUidCacheClear(pMeta, me.ctbEntry.suid);
164,877✔
1140
    if (ret < 0) {
164,867!
1141
      metaError("vgId:%d, failed to clear uid cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
1142
                pReq->ctb.suid, tstrerror(ret));
1143
    }
1144
    ret = metaTbGroupCacheClear(pMeta, me.ctbEntry.suid);
164,867✔
1145
    if (ret < 0) {
164,853!
1146
      metaError("vgId:%d, failed to clear group cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
1147
                pReq->ctb.suid, tstrerror(ret));
1148
    }
1149
    metaULock(pMeta);
164,853✔
1150

1151
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
164,883✔
1152
      ret = tsdbCacheNewTable(pMeta->pVnode->pTsdb, me.uid, me.ctbEntry.suid, NULL);
959✔
1153
      if (ret < 0) {
960!
1154
        metaError("vgId:%d, failed to create table:%s since %s", TD_VID(pMeta->pVnode), pReq->name, tstrerror(ret));
×
1155
        goto _err;
×
1156
      }
1157
    }
1158
  } else {
1159
    me.ntbEntry.btime = pReq->btime;
15,199✔
1160
    me.ntbEntry.ttlDays = pReq->ttl;
15,199✔
1161
    me.ntbEntry.commentLen = pReq->commentLen;
15,199✔
1162
    me.ntbEntry.comment = pReq->comment;
15,199✔
1163
    me.ntbEntry.schemaRow = pReq->ntb.schemaRow;
15,199✔
1164
    me.ntbEntry.ncid = me.ntbEntry.schemaRow.pSchema[me.ntbEntry.schemaRow.nCols - 1].colId + 1;
15,199✔
1165
    me.colCmpr = pReq->colCmpr;
15,199✔
1166
    TABLE_SET_COL_COMPRESSED(me.flags);
15,199✔
1167

1168
    ++pStats->numOfNTables;
15,199✔
1169
    pStats->numOfNTimeSeries += me.ntbEntry.schemaRow.nCols - 1;
15,199✔
1170

1171
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
15,199✔
1172
      ret = tsdbCacheNewTable(pMeta->pVnode->pTsdb, me.uid, -1, &me.ntbEntry.schemaRow);
42✔
1173
      if (ret < 0) {
42!
1174
        metaError("vgId:%d, failed to create table:%s since %s", TD_VID(pMeta->pVnode), pReq->name, tstrerror(ret));
×
1175
        goto _err;
×
1176
      }
1177
    }
1178
  }
1179

1180
  if (metaHandleEntry(pMeta, &me) < 0) goto _err;
180,083!
1181

1182
  metaTimeSeriesNotifyCheck(pMeta);
180,055✔
1183

1184
  if (pMetaRsp) {
180,081!
1185
    *pMetaRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
180,084✔
1186

1187
    if (*pMetaRsp) {
180,079!
1188
      if (me.type == TSDB_CHILD_TABLE) {
180,079✔
1189
        (*pMetaRsp)->tableType = TSDB_CHILD_TABLE;
164,880✔
1190
        (*pMetaRsp)->tuid = pReq->uid;
164,880✔
1191
        (*pMetaRsp)->suid = pReq->ctb.suid;
164,880✔
1192
        strcpy((*pMetaRsp)->tbName, pReq->name);
164,880✔
1193
      } else {
1194
        ret = metaUpdateMetaRsp(pReq->uid, pReq->name, &pReq->ntb.schemaRow, *pMetaRsp);
15,199✔
1195
        if (ret < 0) {
15,199!
1196
          metaError("vgId:%d, failed to update meta rsp:%s since %s", TD_VID(pMeta->pVnode), pReq->name,
×
1197
                    tstrerror(ret));
1198
        }
1199
        for (int32_t i = 0; i < pReq->colCmpr.nCols; i++) {
275,386✔
1200
          SColCmpr *p = &pReq->colCmpr.pColCmpr[i];
260,187✔
1201
          (*pMetaRsp)->pSchemaExt[i].colId = p->id;
260,187✔
1202
          (*pMetaRsp)->pSchemaExt[i].compress = p->alg;
260,187✔
1203
        }
1204
      }
1205
    }
1206
  }
1207

1208
  pMeta->changed = true;
180,076✔
1209
  metaDebug("vgId:%d, table:%s uid %" PRId64 " is created, type:%" PRId8, TD_VID(pMeta->pVnode), pReq->name, pReq->uid,
180,076✔
1210
            pReq->type);
1211
  return 0;
180,077✔
1212

1213
_err:
×
1214
  metaError("vgId:%d, failed to create table:%s type:%s since %s", TD_VID(pMeta->pVnode), pReq->name,
×
1215
            pReq->type == TSDB_CHILD_TABLE ? "child table" : "normal table", tstrerror(terrno));
1216
  return TSDB_CODE_FAILED;
×
1217
}
1218

1219
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids, tb_uid_t *tbUid) {
16,113✔
1220
  void    *pData = NULL;
16,113✔
1221
  int      nData = 0;
16,113✔
1222
  int      rc = 0;
16,113✔
1223
  tb_uid_t uid = 0;
16,113✔
1224
  tb_uid_t suid = 0;
16,113✔
1225
  int8_t   sysTbl = 0;
16,113✔
1226
  int      type;
1227

1228
  rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
16,113✔
1229
  if (rc < 0) {
16,113!
1230
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
1231
  }
1232
  uid = *(tb_uid_t *)pData;
16,113✔
1233

1234
  metaWLock(pMeta);
16,113✔
1235
  rc = metaDropTableByUid(pMeta, uid, &type, &suid, &sysTbl);
16,113✔
1236
  metaULock(pMeta);
16,113✔
1237

1238
  if (rc < 0) goto _exit;
16,113!
1239

1240
  if (!sysTbl && type == TSDB_CHILD_TABLE) {
16,113!
1241
    int32_t      nCols = 0;
13,750✔
1242
    SVnodeStats *pStats = &pMeta->pVnode->config.vndStats;
13,750✔
1243
    if (metaGetStbStats(pMeta->pVnode, suid, NULL, &nCols) == 0) {
13,750!
1244
      pStats->numOfTimeSeries -= nCols - 1;
13,750✔
1245
    }
1246
  }
1247

1248
  if ((type == TSDB_CHILD_TABLE || type == TSDB_NORMAL_TABLE) && tbUids) {
16,113!
1249
    if (taosArrayPush(tbUids, &uid) == NULL) {
16,113!
1250
      rc = terrno;
×
1251
      goto _exit;
×
1252
    }
1253

1254
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
16,113✔
1255
      int32_t ret = tsdbCacheDropTable(pMeta->pVnode->pTsdb, uid, suid, NULL);
75✔
1256
      if (ret < 0) {
75!
1257
        metaError("vgId:%d, failed to drop table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, uid,
×
1258
                  tstrerror(ret));
1259
      }
1260
    }
1261
  }
1262

1263
  if ((type == TSDB_CHILD_TABLE) && tbUid) {
16,113!
1264
    *tbUid = uid;
13,750✔
1265
  }
1266

1267
  pMeta->changed = true;
16,113✔
1268
_exit:
16,113✔
1269
  tdbFree(pData);
16,113✔
1270
  return rc;
16,113✔
1271
}
1272

1273
int32_t metaDropTables(SMeta *pMeta, SArray *tbUids) {
64✔
1274
  int32_t code = 0;
64✔
1275
  if (taosArrayGetSize(tbUids) == 0) return TSDB_CODE_SUCCESS;
64!
1276

1277
  int64_t    nCtbDropped = 0;
64✔
1278
  SSHashObj *suidHash = tSimpleHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
64✔
1279
  if (suidHash == NULL) {
64!
1280
    return terrno;
×
1281
  }
1282

1283
  metaWLock(pMeta);
64✔
1284
  for (int i = 0; i < taosArrayGetSize(tbUids); ++i) {
5,333✔
1285
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(tbUids, i);
5,269✔
1286
    tb_uid_t suid = 0;
5,269✔
1287
    int8_t   sysTbl = 0;
5,269✔
1288
    int      type;
1289
    code = metaDropTableByUid(pMeta, uid, &type, &suid, &sysTbl);
5,269✔
1290
    if (code) return code;
5,269!
1291
    if (!sysTbl && type == TSDB_CHILD_TABLE && suid != 0 && suidHash) {
5,269!
1292
      int64_t *pVal = tSimpleHashGet(suidHash, &suid, sizeof(tb_uid_t));
5,258✔
1293
      if (pVal) {
5,258✔
1294
        nCtbDropped = *pVal + 1;
5,199✔
1295
      } else {
1296
        nCtbDropped = 1;
59✔
1297
      }
1298
      code = tSimpleHashPut(suidHash, &suid, sizeof(tb_uid_t), &nCtbDropped, sizeof(int64_t));
5,258✔
1299
      if (code) return code;
5,258!
1300
    }
1301
    /*
1302
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
1303
      tsdbCacheDropTable(pMeta->pVnode->pTsdb, uid, suid, NULL);
1304
    }
1305
    */
1306
    metaDebug("batch drop table:%" PRId64, uid);
5,269✔
1307
  }
1308
  metaULock(pMeta);
64✔
1309

1310
  // update timeseries
1311
  void   *pCtbDropped = NULL;
64✔
1312
  int32_t iter = 0;
64✔
1313
  while ((pCtbDropped = tSimpleHashIterate(suidHash, pCtbDropped, &iter))) {
123✔
1314
    tb_uid_t    *pSuid = tSimpleHashGetKey(pCtbDropped, NULL);
59✔
1315
    int32_t      nCols = 0;
59✔
1316
    SVnodeStats *pStats = &pMeta->pVnode->config.vndStats;
59✔
1317
    if (metaGetStbStats(pMeta->pVnode, *pSuid, NULL, &nCols) == 0) {
59!
1318
      pStats->numOfTimeSeries -= *(int64_t *)pCtbDropped * (nCols - 1);
59✔
1319
    }
1320
  }
1321
  tSimpleHashCleanup(suidHash);
64✔
1322

1323
  pMeta->changed = true;
64✔
1324
  return 0;
64✔
1325
}
1326

1327
static int32_t metaFilterTableByHash(SMeta *pMeta, SArray *uidList) {
88✔
1328
  int32_t code = 0;
88✔
1329
  // 1, tranverse table's
1330
  // 2, validate table name using vnodeValidateTableHash
1331
  // 3, push invalidated table's uid into uidList
1332

1333
  TBC *pCur;
1334
  code = tdbTbcOpen(pMeta->pTbDb, &pCur, NULL);
88✔
1335
  if (code < 0) {
88!
1336
    return code;
×
1337
  }
1338

1339
  code = tdbTbcMoveToFirst(pCur);
88✔
1340
  if (code) {
88!
1341
    tdbTbcClose(pCur);
×
1342
    return code;
×
1343
  }
1344

1345
  void *pData = NULL, *pKey = NULL;
88✔
1346
  int   nData = 0, nKey = 0;
88✔
1347

1348
  while (1) {
10,610✔
1349
    int32_t ret = tdbTbcNext(pCur, &pKey, &nKey, &pData, &nData);
10,698✔
1350
    if (ret < 0) {
10,698✔
1351
      break;
88✔
1352
    }
1353

1354
    SMetaEntry me = {0};
10,610✔
1355
    SDecoder   dc = {0};
10,610✔
1356
    tDecoderInit(&dc, pData, nData);
10,610✔
1357
    code = metaDecodeEntry(&dc, &me);
10,610✔
1358
    if (code < 0) {
10,610!
1359
      tDecoderClear(&dc);
×
1360
      return code;
×
1361
    }
1362

1363
    if (me.type != TSDB_SUPER_TABLE) {
10,610✔
1364
      char tbFName[TSDB_TABLE_FNAME_LEN + 1];
1365
      snprintf(tbFName, sizeof(tbFName), "%s.%s", pMeta->pVnode->config.dbname, me.name);
10,538✔
1366
      tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
10,538✔
1367
      int32_t ret = vnodeValidateTableHash(pMeta->pVnode, tbFName);
10,538✔
1368
      if (ret < 0 && terrno == TSDB_CODE_VND_HASH_MISMATCH) {
10,538!
1369
        if (taosArrayPush(uidList, &me.uid) == NULL) {
5,269!
1370
          code = terrno;
×
1371
          break;
×
1372
        }
1373
      }
1374
    }
1375
    tDecoderClear(&dc);
10,610✔
1376
  }
1377
  tdbFree(pData);
88✔
1378
  tdbFree(pKey);
88✔
1379
  tdbTbcClose(pCur);
88✔
1380

1381
  return 0;
88✔
1382
}
1383

1384
int32_t metaTrimTables(SMeta *pMeta) {
88✔
1385
  int32_t code = 0;
88✔
1386

1387
  SArray *tbUids = taosArrayInit(8, sizeof(int64_t));
88✔
1388
  if (tbUids == NULL) {
88!
1389
    return terrno;
×
1390
  }
1391

1392
  code = metaFilterTableByHash(pMeta, tbUids);
88✔
1393
  if (code != 0) {
88!
1394
    goto end;
×
1395
  }
1396
  if (TARRAY_SIZE(tbUids) == 0) {
88✔
1397
    goto end;
24✔
1398
  }
1399

1400
  metaInfo("vgId:%d, trim %ld tables", TD_VID(pMeta->pVnode), taosArrayGetSize(tbUids));
64!
1401
  code = metaDropTables(pMeta, tbUids);
64✔
1402
  if (code) goto end;
64!
1403

1404
end:
64✔
1405
  taosArrayDestroy(tbUids);
88✔
1406

1407
  return code;
88✔
1408
}
1409

1410
int metaTtlFindExpired(SMeta *pMeta, int64_t timePointMs, SArray *tbUids, int32_t ttlDropMaxCount) {
92,694✔
1411
  metaRLock(pMeta);
92,694✔
1412

1413
  int ret = ttlMgrFindExpired(pMeta->pTtlMgr, timePointMs, tbUids, ttlDropMaxCount);
92,775✔
1414

1415
  metaULock(pMeta);
92,424✔
1416

1417
  if (ret != 0) {
92,703!
1418
    metaError("ttl failed to find expired table, ret:%d", ret);
×
1419
  }
1420

1421
  return ret;
92,599✔
1422
}
1423

1424
static int metaBuildBtimeIdxKey(SBtimeIdxKey *btimeKey, const SMetaEntry *pME) {
317,335✔
1425
  int64_t btime;
1426
  if (pME->type == TSDB_CHILD_TABLE) {
317,335✔
1427
    btime = pME->ctbEntry.btime;
268,830✔
1428
  } else if (pME->type == TSDB_NORMAL_TABLE) {
48,505✔
1429
    btime = pME->ntbEntry.btime;
17,582✔
1430
  } else {
1431
    return TSDB_CODE_FAILED;
30,923✔
1432
  }
1433

1434
  btimeKey->btime = btime;
286,412✔
1435
  btimeKey->uid = pME->uid;
286,412✔
1436
  return 0;
286,412✔
1437
}
1438

1439
static int metaBuildNColIdxKey(SNcolIdxKey *ncolKey, const SMetaEntry *pME) {
19,667✔
1440
  if (pME->type == TSDB_NORMAL_TABLE) {
19,667!
1441
    ncolKey->ncol = pME->ntbEntry.schemaRow.nCols;
19,667✔
1442
    ncolKey->uid = pME->uid;
19,667✔
1443
  } else {
1444
    return TSDB_CODE_FAILED;
×
1445
  }
1446
  return 0;
19,667✔
1447
}
1448

1449
static void metaDeleteTtl(SMeta *pMeta, const SMetaEntry *pME) {
25,737✔
1450
  if (pME->type != TSDB_CHILD_TABLE && pME->type != TSDB_NORMAL_TABLE) return;
25,737!
1451

1452
  STtlDelTtlCtx ctx = {.uid = pME->uid, .pTxn = pMeta->txn};
25,737✔
1453
  if (pME->type == TSDB_CHILD_TABLE) {
25,737✔
1454
    ctx.ttlDays = pME->ctbEntry.ttlDays;
23,341✔
1455
  } else {
1456
    ctx.ttlDays = pME->ntbEntry.ttlDays;
2,396✔
1457
  }
1458

1459
  int32_t ret = ttlMgrDeleteTtl(pMeta->pTtlMgr, &ctx);
25,737✔
1460
  if (ret < 0) {
25,736!
1461
    metaError("vgId:%d, failed to delete ttl for table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pME->name,
×
1462
              pME->uid, tstrerror(ret));
1463
  }
1464
  return;
25,736✔
1465
}
1466

1467
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *pSuid, int8_t *pSysTbl) {
25,687✔
1468
  void      *pData = NULL;
25,687✔
1469
  int        nData = 0;
25,687✔
1470
  int        rc = 0;
25,687✔
1471
  SMetaEntry e = {0};
25,687✔
1472
  SDecoder   dc = {0};
25,687✔
1473
  int32_t    ret = 0;
25,687✔
1474

1475
  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
25,687✔
1476
  if (rc < 0) {
25,690!
1477
    return rc;
×
1478
  }
1479
  int64_t version = ((SUidIdxVal *)pData)[0].version;
25,690✔
1480

1481
  rc = tdbTbGet(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), &pData, &nData);
25,690✔
1482
  if (rc < 0) {
25,690!
1483
    tdbFree(pData);
×
1484
    return rc;
×
1485
  }
1486

1487
  tDecoderInit(&dc, pData, nData);
25,690✔
1488
  rc = metaDecodeEntry(&dc, &e);
25,690✔
1489
  if (rc < 0) {
25,685!
1490
    tDecoderClear(&dc);
×
1491
    return rc;
×
1492
  }
1493

1494
  if (type) *type = e.type;
25,685✔
1495

1496
  if (e.type == TSDB_CHILD_TABLE) {
25,685✔
1497
    if (pSuid) *pSuid = e.ctbEntry.suid;
23,311✔
1498
    void *tData = NULL;
23,311✔
1499
    int   tLen = 0;
23,311✔
1500

1501
    if (tdbTbGet(pMeta->pUidIdx, &e.ctbEntry.suid, sizeof(tb_uid_t), &tData, &tLen) == 0) {
23,311!
1502
      STbDbKey tbDbKey = {.uid = e.ctbEntry.suid, .version = ((SUidIdxVal *)tData)[0].version};
23,316✔
1503
      if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &tData, &tLen) == 0) {
23,316!
1504
        SDecoder   tdc = {0};
23,317✔
1505
        SMetaEntry stbEntry = {0};
23,317✔
1506

1507
        tDecoderInit(&tdc, tData, tLen);
23,317✔
1508
        int32_t ret = metaDecodeEntry(&tdc, &stbEntry);
23,316✔
1509
        if (ret < 0) {
23,313!
1510
          tDecoderClear(&tdc);
×
1511
          metaError("vgId:%d, failed to decode child table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
1512
                    e.ctbEntry.suid, tstrerror(ret));
1513
          return ret;
×
1514
        }
1515

1516
        if (pSysTbl) *pSysTbl = metaTbInFilterCache(pMeta, stbEntry.name, 1) ? 1 : 0;
23,313✔
1517

1518
        SSchema        *pTagColumn = NULL;
23,313✔
1519
        SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
23,313✔
1520
        if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
23,313✔
1521
          pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
196✔
1522
          ret = metaDelJsonVarFromIdx(pMeta, &e, pTagColumn);
196✔
1523
          if (ret < 0) {
196!
1524
            metaError("vgId:%d, failed to delete json var from idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode),
×
1525
                      e.name, e.uid, tstrerror(ret));
1526
          }
1527
        } else {
1528
          for (int i = 0; i < pTagSchema->nCols; i++) {
88,726✔
1529
            pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[i];
65,608✔
1530
            if (!IS_IDX_ON(pTagColumn)) continue;
65,608✔
1531
            STagIdxKey *pTagIdxKey = NULL;
27,932✔
1532
            int32_t     nTagIdxKey;
1533

1534
            const void *pTagData = NULL;
27,932✔
1535
            int32_t     nTagData = 0;
27,932✔
1536

1537
            STagVal tagVal = {.cid = pTagColumn->colId};
27,932✔
1538
            if (tTagGet((const STag *)e.ctbEntry.pTags, &tagVal)) {
27,932✔
1539
              if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
27,207!
1540
                pTagData = tagVal.pData;
6,587✔
1541
                nTagData = (int32_t)tagVal.nData;
6,587✔
1542
              } else {
1543
                pTagData = &(tagVal.i64);
20,620✔
1544
                nTagData = tDataTypes[pTagColumn->type].bytes;
20,620✔
1545
              }
1546
            } else {
1547
              if (!IS_VAR_DATA_TYPE(pTagColumn->type)) {
724!
1548
                nTagData = tDataTypes[pTagColumn->type].bytes;
592✔
1549
              }
1550
            }
1551

1552
            if (metaCreateTagIdxKey(e.ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type, uid,
27,931!
1553
                                    &pTagIdxKey, &nTagIdxKey) == 0) {
1554
              ret = tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
27,935✔
1555
              if (ret < 0) {
27,934!
1556
                metaError("vgId:%d, failed to delete tag idx key:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode),
×
1557
                          e.name, e.uid, tstrerror(ret));
1558
              }
1559
            }
1560
            metaDestroyTagIdxKey(pTagIdxKey);
27,934✔
1561
            pTagIdxKey = NULL;
27,933✔
1562
          }
1563
        }
1564
        tDecoderClear(&tdc);
23,314✔
1565
      }
1566
      tdbFree(tData);
23,316✔
1567
    }
1568
  }
1569

1570
  ret = tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), pMeta->txn);
25,691✔
1571
  if (ret < 0) {
25,690!
1572
    metaError("vgId:%d, failed to delete table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1573
              tstrerror(ret));
1574
  }
1575
  ret = tdbTbDelete(pMeta->pNameIdx, e.name, strlen(e.name) + 1, pMeta->txn);
25,690✔
1576
  if (ret < 0) {
25,690!
1577
    metaError("vgId:%d, failed to delete name idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1578
              tstrerror(ret));
1579
  }
1580
  ret = tdbTbDelete(pMeta->pUidIdx, &uid, sizeof(uid), pMeta->txn);
25,690✔
1581
  if (ret < 0) {
25,690!
1582
    metaError("vgId:%d, failed to delete uid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1583
              tstrerror(ret));
1584
  }
1585

1586
  if (e.type == TSDB_CHILD_TABLE || e.type == TSDB_NORMAL_TABLE) metaDeleteBtimeIdx(pMeta, &e);
25,690!
1587
  if (e.type == TSDB_NORMAL_TABLE) metaDeleteNcolIdx(pMeta, &e);
25,690✔
1588

1589
  if (e.type != TSDB_SUPER_TABLE) metaDeleteTtl(pMeta, &e);
25,690!
1590

1591
  if (e.type == TSDB_CHILD_TABLE) {
25,689✔
1592
    ret =
1593
        tdbTbDelete(pMeta->pCtbIdx, &(SCtbIdxKey){.suid = e.ctbEntry.suid, .uid = uid}, sizeof(SCtbIdxKey), pMeta->txn);
23,315✔
1594
    if (ret < 0) {
23,317!
1595
      metaError("vgId:%d, failed to delete ctb idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1596
                tstrerror(ret));
1597
    }
1598

1599
    --pMeta->pVnode->config.vndStats.numOfCTables;
23,317✔
1600
    metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1, 0);
23,317✔
1601
    ret = metaUidCacheClear(pMeta, e.ctbEntry.suid);
23,316✔
1602
    if (ret < 0) {
23,315!
1603
      metaError("vgId:%d, failed to clear uid cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
1604
                e.ctbEntry.suid, tstrerror(ret));
1605
    }
1606
    ret = metaTbGroupCacheClear(pMeta, e.ctbEntry.suid);
23,315✔
1607
    if (ret < 0) {
23,317!
1608
      metaError("vgId:%d, failed to clear group cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
1609
                e.ctbEntry.suid, tstrerror(ret));
1610
    }
1611
    /*
1612
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
1613
      tsdbCacheDropTable(pMeta->pVnode->pTsdb, e.uid, e.ctbEntry.suid, NULL);
1614
    }
1615
    */
1616
  } else if (e.type == TSDB_NORMAL_TABLE) {
2,374!
1617
    // drop schema.db (todo)
1618

1619
    --pMeta->pVnode->config.vndStats.numOfNTables;
2,374✔
1620
    pMeta->pVnode->config.vndStats.numOfNTimeSeries -= e.ntbEntry.schemaRow.nCols - 1;
2,374✔
1621

1622
    /*
1623
    if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
1624
      tsdbCacheDropTable(pMeta->pVnode->pTsdb, e.uid, -1, &e.ntbEntry.schemaRow);
1625
    }
1626
    */
1627
  } else if (e.type == TSDB_SUPER_TABLE) {
×
1628
    ret = tdbTbDelete(pMeta->pSuidIdx, &e.uid, sizeof(tb_uid_t), pMeta->txn);
×
1629
    if (ret < 0) {
×
1630
      metaError("vgId:%d, failed to delete suid idx:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1631
                tstrerror(ret));
1632
    }
1633
    // drop schema.db (todo)
1634

1635
    ret = metaStatsCacheDrop(pMeta, uid);
×
1636
    if (ret < 0) {
×
1637
      metaError("vgId:%d, failed to drop stats cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1638
                tstrerror(ret));
1639
    }
1640
    ret = metaUidCacheClear(pMeta, uid);
×
1641
    if (ret < 0) {
×
1642
      metaError("vgId:%d, failed to clear uid cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
×
1643
                tstrerror(ret));
1644
    }
1645
    ret = metaTbGroupCacheClear(pMeta, uid);
×
1646
    if (ret < 0) {
×
1647
      metaError("vgId:%d, failed to clear group cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
×
1648
                e.uid, tstrerror(ret));
1649
    }
1650
    --pMeta->pVnode->config.vndStats.numOfSTables;
×
1651
  }
1652

1653
  ret = metaCacheDrop(pMeta, uid);
25,691✔
1654
  if (ret < 0) {
25,690✔
1655
    metaError("vgId:%d, failed to drop cache:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, e.uid,
5,273!
1656
              tstrerror(ret));
1657
  }
1658

1659
  tDecoderClear(&dc);
25,690✔
1660
  tdbFree(pData);
25,691✔
1661

1662
  return 0;
25,691✔
1663
}
1664
// opt ins_tables
1665
int metaUpdateBtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
291,237✔
1666
  SBtimeIdxKey btimeKey = {0};
291,237✔
1667
  if (metaBuildBtimeIdxKey(&btimeKey, pME) < 0) {
291,237✔
1668
    return 0;
30,982✔
1669
  }
1670
  metaTrace("vgId:%d, start to save version:%" PRId64 " uid:%" PRId64 " btime:%" PRId64, TD_VID(pMeta->pVnode),
260,671✔
1671
            pME->version, pME->uid, btimeKey.btime);
1672

1673
  return tdbTbUpsert(pMeta->pBtimeIdx, &btimeKey, sizeof(btimeKey), NULL, 0, pMeta->txn);
260,671✔
1674
}
1675

1676
int metaDeleteBtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
25,690✔
1677
  SBtimeIdxKey btimeKey = {0};
25,690✔
1678
  if (metaBuildBtimeIdxKey(&btimeKey, pME) < 0) {
25,690!
1679
    return 0;
×
1680
  }
1681
  return tdbTbDelete(pMeta->pBtimeIdx, &btimeKey, sizeof(btimeKey), pMeta->txn);
25,690✔
1682
}
1683
int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
16,251✔
1684
  SNcolIdxKey ncolKey = {0};
16,251✔
1685
  if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
16,251!
1686
    return 0;
×
1687
  }
1688
  return tdbTbUpsert(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), NULL, 0, pMeta->txn);
16,251✔
1689
}
1690

1691
int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
3,416✔
1692
  SNcolIdxKey ncolKey = {0};
3,416✔
1693
  if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
3,416!
1694
    return 0;
×
1695
  }
1696
  return tdbTbDelete(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), pMeta->txn);
3,416✔
1697
}
1698

1699
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq, STableMetaRsp *pMetaRsp) {
1,964✔
1700
  void           *pVal = NULL;
1,964✔
1701
  int             nVal = 0;
1,964✔
1702
  const void     *pData = NULL;
1,964✔
1703
  int             nData = 0;
1,964✔
1704
  int             ret = 0;
1,964✔
1705
  tb_uid_t        uid;
1706
  int64_t         oversion;
1707
  SSchema        *pColumn = NULL;
1,964✔
1708
  SMetaEntry      entry = {0};
1,964✔
1709
  SSchemaWrapper *pSchema;
1710
  int             c;
1711
  bool            freeColCmpr = false;
1,964✔
1712
  if (pAlterTbReq->colName == NULL) {
1,964!
1713
    metaError("meta/table: null pAlterTbReq->colName");
×
1714
    return terrno = TSDB_CODE_INVALID_MSG;
×
1715
  }
1716

1717
  // search name index
1718
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
1,964✔
1719
  if (ret < 0) {
1,964!
1720
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
1721
  }
1722

1723
  uid = *(tb_uid_t *)pVal;
1,964✔
1724
  tdbFree(pVal);
1,964✔
1725
  pVal = NULL;
1,964✔
1726

1727
  // search uid index
1728
  TBC *pUidIdxc = NULL;
1,964✔
1729

1730
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
1,964!
1731
  ret = tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
1,964✔
1732
  if (c != 0) {
1,964!
1733
    tdbTbcClose(pUidIdxc);
×
1734
    metaError("meta/table: invalide c: %" PRId32 " alt tb column failed.", c);
×
1735
    return TSDB_CODE_FAILED;
×
1736
  }
1737

1738
  ret = tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
1,964✔
1739
  oversion = ((SUidIdxVal *)pData)[0].version;
1,964✔
1740

1741
  // search table.db
1742
  TBC *pTbDbc = NULL;
1,964✔
1743

1744
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
1,964!
1745
  ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
1,964✔
1746
  if (c != 0) {
1,964!
1747
    tdbTbcClose(pUidIdxc);
×
1748
    tdbTbcClose(pTbDbc);
×
1749
    metaError("meta/table: invalide c: %" PRId32 " alt tb column failed.", c);
×
1750
    return TSDB_CODE_FAILED;
×
1751
  }
1752

1753
  ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
1,964✔
1754

1755
  // get table entry
1756
  SDecoder dc = {0};
1,964✔
1757
  if ((entry.pBuf = taosMemoryMalloc(nData)) == NULL) {
1,964!
1758
    tdbTbcClose(pUidIdxc);
×
1759
    tdbTbcClose(pTbDbc);
×
1760
    return terrno;
×
1761
  }
1762
  memcpy(entry.pBuf, pData, nData);
1,964✔
1763
  tDecoderInit(&dc, entry.pBuf, nData);
1,964✔
1764
  ret = metaDecodeEntry(&dc, &entry);
1,964✔
1765
  if (ret != 0) {
1,964!
1766
    tdbTbcClose(pUidIdxc);
×
1767
    tdbTbcClose(pTbDbc);
×
1768
    tDecoderClear(&dc);
×
1769
    metaError("meta/table: invalide ret: %" PRId32 " alt tb column failed.", ret);
×
1770
    return ret;
×
1771
  }
1772

1773
  if (entry.type != TSDB_NORMAL_TABLE) {
1,964✔
1774
    terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
15✔
1775
    goto _err;
15✔
1776
  }
1777
  // search the column to add/drop/update
1778
  pSchema = &entry.ntbEntry.schemaRow;
1,949✔
1779

1780
  // save old entry
1781
  SMetaEntry oldEntry = {.type = TSDB_NORMAL_TABLE, .uid = entry.uid};
1,949✔
1782
  oldEntry.ntbEntry.schemaRow.nCols = pSchema->nCols;
1,949✔
1783

1784
  int32_t rowLen = -1;
1,949✔
1785
  if (pAlterTbReq->action == TSDB_ALTER_TABLE_ADD_COLUMN ||
1,949✔
1786
      pAlterTbReq->action == TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES) {
870✔
1787
    rowLen = 0;
1,825✔
1788
  }
1789

1790
  int32_t  iCol = 0, jCol = 0;
1,949✔
1791
  SSchema *qColumn = NULL;
1,949✔
1792
  for (;;) {
1793
    qColumn = NULL;
101,083✔
1794

1795
    if (jCol >= pSchema->nCols) break;
101,083✔
1796
    qColumn = &pSchema->pSchema[jCol];
99,135✔
1797

1798
    if (!pColumn && (strcmp(qColumn->name, pAlterTbReq->colName) == 0)) {
99,135✔
1799
      pColumn = qColumn;
1,357✔
1800
      iCol = jCol;
1,357✔
1801
      if (rowLen < 0) break;
1,357✔
1802
    }
1803
    rowLen += qColumn->bytes;
99,134✔
1804
    ++jCol;
99,134✔
1805
  }
1806

1807
  entry.version = version;
1,949✔
1808
  int      tlen;
1809
  SSchema *pNewSchema = NULL;
1,949✔
1810
  SSchema  tScheam;
1811
  switch (pAlterTbReq->action) {
1,949!
1812
    case TSDB_ALTER_TABLE_ADD_COLUMN:
1,080✔
1813
    case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
1814
      if (pColumn) {
1,080✔
1815
        terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
488✔
1816
        goto _err;
488✔
1817
      }
1818
      if ((terrno = grantCheck(TSDB_GRANT_TIMESERIES)) < 0) {
592!
1819
        goto _err;
×
1820
      }
1821
      if (rowLen + pAlterTbReq->bytes > TSDB_MAX_BYTES_PER_ROW) {
592✔
1822
        terrno = TSDB_CODE_PAR_INVALID_ROW_LENGTH;
10✔
1823
        goto _err;
10✔
1824
      }
1825
      pSchema->version++;
582✔
1826
      pSchema->nCols++;
582✔
1827
      pNewSchema = taosMemoryMalloc(sizeof(SSchema) * pSchema->nCols);
582✔
1828
      if (pNewSchema == NULL) {
582!
1829
        goto _err;
×
1830
      }
1831
      memcpy(pNewSchema, pSchema->pSchema, sizeof(SSchema) * (pSchema->nCols - 1));
582✔
1832
      pSchema->pSchema = pNewSchema;
582✔
1833
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].bytes = pAlterTbReq->bytes;
582✔
1834
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].type = pAlterTbReq->type;
582✔
1835
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].flags = pAlterTbReq->flags;
582✔
1836
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].colId = entry.ntbEntry.ncid++;
582✔
1837
      strcpy(pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].name, pAlterTbReq->colName);
582✔
1838

1839
      ++pMeta->pVnode->config.vndStats.numOfNTimeSeries;
582✔
1840
      metaTimeSeriesNotifyCheck(pMeta);
582✔
1841

1842
      if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
582✔
1843
        int16_t cid = pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].colId;
3✔
1844
        int8_t  col_type = pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].type;
3✔
1845
        int32_t ret = tsdbCacheNewNTableColumn(pMeta->pVnode->pTsdb, entry.uid, cid, col_type);
3✔
1846
        if (ret < 0) {
3!
1847
          terrno = ret;
×
1848
          goto _err;
×
1849
        }
1850
      }
1851
      SSchema *pCol = &pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1];
582✔
1852
      uint32_t compress = pAlterTbReq->action == TSDB_ALTER_TABLE_ADD_COLUMN ? createDefaultColCmprByType(pCol->type)
581✔
1853
                                                                             : pAlterTbReq->compress;
582✔
1854
      if (updataTableColCmpr(&entry.colCmpr, pCol, 1, compress) != 0) {
582!
1855
        metaError("vgId:%d, failed to update table col cmpr:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name,
×
1856
                  entry.uid);
1857
      }
1858
      freeColCmpr = true;
582✔
1859
      if (entry.colCmpr.nCols != pSchema->nCols) {
582!
1860
        if (pNewSchema) taosMemoryFree(pNewSchema);
×
1861
        if (freeColCmpr) taosMemoryFree(entry.colCmpr.pColCmpr);
×
1862
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
1863
        goto _err;
×
1864
      }
1865
      break;
582✔
1866
    case TSDB_ALTER_TABLE_DROP_COLUMN:
79✔
1867
      if (pColumn == NULL) {
79!
1868
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
1869
        goto _err;
×
1870
      }
1871
      if (pColumn->colId == 0) {
79!
1872
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
1873
        goto _err;
×
1874
      }
1875
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
79✔
1876
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
11✔
1877
        goto _err;
11✔
1878
      }
1879
      bool hasPrimayKey = false;
68✔
1880
      if (pSchema->nCols >= 2) {
68!
1881
        hasPrimayKey = pSchema->pSchema[1].flags & COL_IS_KEY ? true : false;
68✔
1882
      }
1883

1884
      memcpy(&tScheam, pColumn, sizeof(SSchema));
68✔
1885
      pSchema->version++;
68✔
1886
      tlen = (pSchema->nCols - iCol - 1) * sizeof(SSchema);
68✔
1887
      if (tlen) {
68✔
1888
        memmove(pColumn, pColumn + 1, tlen);
35✔
1889
      }
1890
      pSchema->nCols--;
68✔
1891

1892
      --pMeta->pVnode->config.vndStats.numOfNTimeSeries;
68✔
1893

1894
      if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
68✔
1895
        int16_t cid = pColumn->colId;
3✔
1896

1897
        if (tsdbCacheDropNTableColumn(pMeta->pVnode->pTsdb, entry.uid, cid, hasPrimayKey) != 0) {
3!
1898
          metaError("vgId:%d, failed to drop ntable column:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name,
×
1899
                    entry.uid);
1900
        }
1901
      }
1902

1903
      if (updataTableColCmpr(&entry.colCmpr, &tScheam, 0, 0) != 0) {
68!
1904
        metaError("vgId:%d, failed to update table col cmpr:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name,
×
1905
                  entry.uid);
1906
      }
1907
      if (entry.colCmpr.nCols != pSchema->nCols) {
68!
1908
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
1909
        goto _err;
×
1910
      }
1911
      break;
68✔
1912
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
746✔
1913
      if (pColumn == NULL) {
746!
1914
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
1915
        goto _err;
×
1916
      }
1917
      if (!IS_VAR_DATA_TYPE(pColumn->type) || pColumn->bytes >= pAlterTbReq->colModBytes) {
746!
1918
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
304✔
1919
        goto _err;
304✔
1920
      }
1921
      if (rowLen + pAlterTbReq->colModBytes - pColumn->bytes > TSDB_MAX_BYTES_PER_ROW) {
442✔
1922
        terrno = TSDB_CODE_PAR_INVALID_ROW_LENGTH;
70✔
1923
        goto _err;
70✔
1924
      }
1925
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
372✔
1926
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
13✔
1927
        goto _err;
13✔
1928
      }
1929
      pSchema->version++;
359✔
1930
      pColumn->bytes = pAlterTbReq->colModBytes;
359✔
1931
      break;
359✔
1932
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
44✔
1933
      if (pAlterTbReq->colNewName == NULL) {
44!
1934
        terrno = TSDB_CODE_INVALID_MSG;
×
1935
        goto _err;
×
1936
      }
1937
      if (pColumn == NULL) {
44!
1938
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
1939
        goto _err;
×
1940
      }
1941
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
44✔
1942
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
11✔
1943
        goto _err;
11✔
1944
      }
1945
      pSchema->version++;
33✔
1946
      strcpy(pColumn->name, pAlterTbReq->colNewName);
33✔
1947
      break;
33✔
1948
  }
1949

1950
  if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
1,042✔
1951
    tsdbCacheInvalidateSchema(pMeta->pVnode->pTsdb, 0, entry.uid, pSchema->version);
6✔
1952
  }
1953

1954
  entry.version = version;
1,042✔
1955

1956
  // do actual write
1957
  metaWLock(pMeta);
1,042✔
1958

1959
  if (metaDeleteNcolIdx(pMeta, &oldEntry) < 0) {
1,042!
1960
    metaError("vgId:%d, failed to delete ncol idx:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1961
  }
1962

1963
  if (metaUpdateNcolIdx(pMeta, &entry) < 0) {
1,042!
1964
    metaError("vgId:%d, failed to update ncol idx:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1965
  }
1966

1967
  // save to table db
1968
  if (metaSaveToTbDb(pMeta, &entry) < 0) {
1,042!
1969
    metaError("vgId:%d, failed to save to tb db:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1970
  }
1971

1972
  if (metaUpdateUidIdx(pMeta, &entry) < 0) {
1,042!
1973
    metaError("vgId:%d, failed to update uid idx:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1974
  }
1975

1976
  if (metaSaveToSkmDb(pMeta, &entry) < 0) {
1,042!
1977
    metaError("vgId:%d, failed to save to skm db:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1978
  }
1979

1980
  if (metaUpdateChangeTime(pMeta, entry.uid, pAlterTbReq->ctimeMs) < 0) {
1,042!
1981
    metaError("vgId:%d, failed to update change time:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1982
  }
1983

1984
  metaULock(pMeta);
1,042✔
1985

1986
  if (metaUpdateMetaRsp(uid, pAlterTbReq->tbName, pSchema, pMetaRsp) < 0) {
1,042!
1987
    metaError("vgId:%d, failed to update meta rsp:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
×
1988
  }
1989
  for (int32_t i = 0; i < entry.colCmpr.nCols; i++) {
70,557✔
1990
    SColCmpr *p = &entry.colCmpr.pColCmpr[i];
69,515✔
1991
    pMetaRsp->pSchemaExt[i].colId = p->id;
69,515✔
1992
    pMetaRsp->pSchemaExt[i].compress = p->alg;
69,515✔
1993
  }
1994

1995
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
1,042!
1996
  if (pNewSchema) taosMemoryFree(pNewSchema);
1,042✔
1997
  if (freeColCmpr) taosMemoryFree(entry.colCmpr.pColCmpr);
1,042✔
1998

1999
  tdbTbcClose(pTbDbc);
1,042✔
2000
  tdbTbcClose(pUidIdxc);
1,042✔
2001
  tDecoderClear(&dc);
1,042✔
2002

2003
  return 0;
1,042✔
2004

2005
_err:
922✔
2006
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
922!
2007
  tdbTbcClose(pTbDbc);
922✔
2008
  tdbTbcClose(pUidIdxc);
922✔
2009
  tDecoderClear(&dc);
922✔
2010

2011
  return terrno != 0 ? terrno : TSDB_CODE_FAILED;
922!
2012
}
2013

2014
static int metaUpdateTableMultiTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
5✔
2015
  SMetaEntry  ctbEntry = {0};
5✔
2016
  SMetaEntry  stbEntry = {0};
5✔
2017
  void       *pVal = NULL;
5✔
2018
  int         nVal = 0;
5✔
2019
  int         ret;
2020
  int         c;
2021
  tb_uid_t    uid;
2022
  int64_t     oversion;
2023
  const void *pData = NULL;
5✔
2024
  int         nData = 0;
5✔
2025
  SHashObj   *pTagTable = NULL;
5✔
2026

2027
  // search name index
2028
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
5✔
2029
  if (ret < 0) {
5!
NEW
2030
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2031
  }
2032

2033
  uid = *(tb_uid_t *)pVal;
5✔
2034
  tdbFree(pVal);
5✔
2035
  pVal = NULL;
5✔
2036

2037
  // search uid index
2038
  TBC *pUidIdxc = NULL;
5✔
2039

2040
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
5!
2041
  if (tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c) < 0) {
5!
NEW
2042
    metaTrace("meta/table: failed to move to uid index, uid:%" PRId64, uid);
×
2043
  }
2044
  if (c != 0) {
5!
NEW
2045
    tdbTbcClose(pUidIdxc);
×
NEW
2046
    metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
×
NEW
2047
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2048
  }
2049

2050
  if (tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData) != 0) {
5!
NEW
2051
    tdbTbcClose(pUidIdxc);
×
NEW
2052
    metaError("meta/table: failed to get uid index, uid:%" PRId64, uid);
×
NEW
2053
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2054
  }
2055
  oversion = ((SUidIdxVal *)pData)[0].version;
5✔
2056

2057
  // search table.db
2058
  TBC     *pTbDbc = NULL;
5✔
2059
  SDecoder dc1 = {0};
5✔
2060
  SDecoder dc2 = {0};
5✔
2061

2062
  /* get ctbEntry */
2063
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
5!
2064
  if (tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c) != 0) {
5!
NEW
2065
    metaError("meta/table: failed to move to tb db, uid:%" PRId64, uid);
×
2066
  }
2067
  if (c != 0) {
5!
NEW
2068
    tdbTbcClose(pUidIdxc);
×
NEW
2069
    tdbTbcClose(pTbDbc);
×
NEW
2070
    metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
×
NEW
2071
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2072
  }
2073

2074
  if (tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData) != 0) {
5!
NEW
2075
    metaError("meta/table: failed to get tb db, uid:%" PRId64, uid);
×
NEW
2076
    tdbTbcClose(pUidIdxc);
×
NEW
2077
    tdbTbcClose(pTbDbc);
×
NEW
2078
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2079
  }
2080

2081
  if ((ctbEntry.pBuf = taosMemoryMalloc(nData)) == NULL) {
5!
NEW
2082
    tdbTbcClose(pUidIdxc);
×
NEW
2083
    tdbTbcClose(pTbDbc);
×
NEW
2084
    return terrno;
×
2085
  }
2086
  memcpy(ctbEntry.pBuf, pData, nData);
5✔
2087
  tDecoderInit(&dc1, ctbEntry.pBuf, nData);
5✔
2088
  ret = metaDecodeEntry(&dc1, &ctbEntry);
5✔
2089
  if (ret < 0) {
5!
NEW
2090
    terrno = ret;
×
NEW
2091
    goto _err;
×
2092
  }
2093

2094
  /* get stbEntry*/
2095
  if (tdbTbGet(pMeta->pUidIdx, &ctbEntry.ctbEntry.suid, sizeof(tb_uid_t), &pVal, &nVal) != 0) {
5!
NEW
2096
    metaError("meta/table: failed to get uid index, uid:%" PRId64, ctbEntry.ctbEntry.suid);
×
2097
  }
2098
  if (!pVal) {
5!
NEW
2099
    terrno = TSDB_CODE_INVALID_MSG;
×
NEW
2100
    goto _err;
×
2101
  }
2102

2103
  if (tdbTbGet(pMeta->pTbDb, &((STbDbKey){.uid = ctbEntry.ctbEntry.suid, .version = ((SUidIdxVal *)pVal)[0].version}),
5!
2104
               sizeof(STbDbKey), (void **)&stbEntry.pBuf, &nVal) != 0) {
NEW
2105
    metaError("meta/table: failed to get tb db, uid:%" PRId64, ctbEntry.ctbEntry.suid);
×
2106
  }
2107
  tdbFree(pVal);
5✔
2108
  tDecoderInit(&dc2, stbEntry.pBuf, nVal);
5✔
2109
  ret = metaDecodeEntry(&dc2, &stbEntry);
5✔
2110
  if (ret < 0) {
5!
NEW
2111
    terrno = ret;
×
NEW
2112
    goto _err;
×
2113
  }
2114

2115
  int32_t nTagVals = taosArrayGetSize(pAlterTbReq->pMultiTag);
5✔
2116
  pTagTable = taosHashInit(nTagVals, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
5✔
2117
  if (pTagTable == NULL) {
5!
NEW
2118
    ret = terrno;
×
NEW
2119
    goto _err;
×
2120
  }
2121

2122
  // remove duplicate tag name
2123
  for (int i = 0; i < nTagVals; i++) {
35✔
2124
    SMultiTagUpateVal *pTagVal = taosArrayGet(pAlterTbReq->pMultiTag, i);
30✔
2125
    ret = taosHashPut(pTagTable, pTagVal->tagName, strlen(pTagVal->tagName), pTagVal, sizeof(*pTagVal));
30✔
2126
    if (ret != 0) {
30!
NEW
2127
      goto _err;
×
2128
    }
2129
  }
2130

2131
  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
5✔
2132
  SSchema        *pColumn = NULL;
5✔
2133
  int32_t         iCol = 0;
5✔
2134
  int32_t         count = 0;
5✔
2135

2136
  for (;;) {
2137
    pColumn = NULL;
40✔
2138

2139
    if (iCol >= pTagSchema->nCols) break;
40✔
2140
    pColumn = &pTagSchema->pSchema[iCol];
35✔
2141
    if (taosHashGet(pTagTable, pColumn->name, strlen(pColumn->name)) != NULL) {
35✔
2142
      count++;
30✔
2143
    }
2144
    iCol++;
35✔
2145
  }
2146
  if (count != taosHashGetSize(pTagTable)) {
5!
NEW
2147
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
NEW
2148
    goto _err;
×
2149
  }
2150

2151
  ctbEntry.version = version;
5✔
2152
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
5!
NEW
2153
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
NEW
2154
    goto _err;
×
2155
  } else {
2156
    const STag *pOldTag = (const STag *)ctbEntry.ctbEntry.pTags;
5✔
2157
    STag       *pNewTag = NULL;
5✔
2158
    SArray     *pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
5✔
2159
    if (!pTagArray) {
5!
NEW
2160
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2161
      goto _err;
×
2162
    }
2163
    for (int32_t i = 0; i < pTagSchema->nCols; i++) {
40✔
2164
      SSchema           *pCol = &pTagSchema->pSchema[i];
35✔
2165
      SMultiTagUpateVal *pTagVal = taosHashGet(pTagTable, pCol->name, strlen(pCol->name));
35✔
2166
      if (pTagVal == NULL) {
35✔
2167
        STagVal val = {.cid = pCol->colId};
5✔
2168
        if (tTagGet(pOldTag, &val)) {
5!
2169
          if (taosArrayPush(pTagArray, &val) == NULL) {
5!
NEW
2170
            terrno = TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2171
            taosArrayDestroy(pTagArray);
×
NEW
2172
            goto _err;
×
2173
          }
2174
        }
2175
      } else {
2176
        STagVal val = {0};
30✔
2177
        val.type = pCol->type;
30✔
2178
        val.cid = pCol->colId;
30✔
2179
        if (pTagVal->isNull) continue;
30✔
2180

2181
        if (IS_VAR_DATA_TYPE(pCol->type)) {
24!
2182
          val.pData = pTagVal->pTagVal;
4✔
2183
          val.nData = pTagVal->nTagVal;
4✔
2184
        } else {
2185
          memcpy(&val.i64, pTagVal->pTagVal, pTagVal->nTagVal);
20✔
2186
        }
2187
        if (taosArrayPush(pTagArray, &val) == NULL) {
24!
NEW
2188
          terrno = TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2189
          taosArrayDestroy(pTagArray);
×
NEW
2190
          goto _err;
×
2191
        }
2192
      }
2193
    }
2194
    if ((terrno = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag)) < 0) {
5!
NEW
2195
      taosArrayDestroy(pTagArray);
×
NEW
2196
      goto _err;
×
2197
    }
2198
    ctbEntry.ctbEntry.pTags = (uint8_t *)pNewTag;
5✔
2199
    taosArrayDestroy(pTagArray);
5✔
2200
  }
2201

2202
  metaWLock(pMeta);
5✔
2203

2204
  // save to table.db
2205
  if (metaSaveToTbDb(pMeta, &ctbEntry) < 0) {
5!
NEW
2206
    metaError("meta/table: failed to save to tb db:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2207
  }
2208

2209
  // save to uid.idx
2210
  if (metaUpdateUidIdx(pMeta, &ctbEntry) < 0) {
5!
NEW
2211
    metaError("meta/table: failed to update uid idx:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2212
  }
2213

2214
  if (metaUpdateTagIdx(pMeta, &ctbEntry) < 0) {
5!
NEW
2215
    metaError("meta/table: failed to update tag idx:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2216
  }
2217

2218
  SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid};
5✔
2219
  if (tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags,
5!
2220
                  ((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn) < 0) {
5✔
NEW
2221
    metaError("meta/table: failed to upsert ctb idx:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2222
  }
2223

2224
  if (metaUidCacheClear(pMeta, ctbEntry.ctbEntry.suid) < 0) {
5!
NEW
2225
    metaError("meta/table: failed to clear uid cache:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2226
  }
2227

2228
  if (metaTbGroupCacheClear(pMeta, ctbEntry.ctbEntry.suid) < 0) {
5!
NEW
2229
    metaError("meta/table: failed to clear group cache:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2230
  }
2231

2232
  if (metaUpdateChangeTime(pMeta, ctbEntry.uid, pAlterTbReq->ctimeMs) < 0) {
5!
NEW
2233
    metaError("meta/table: failed to update change time:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2234
  }
2235

2236
  metaULock(pMeta);
5✔
2237

2238
  tDecoderClear(&dc1);
5✔
2239
  tDecoderClear(&dc2);
5✔
2240
  taosMemoryFree((void *)ctbEntry.ctbEntry.pTags);
5✔
2241
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
5!
2242
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
5!
2243
  tdbTbcClose(pTbDbc);
5✔
2244
  tdbTbcClose(pUidIdxc);
5✔
2245
  taosHashCleanup(pTagTable);
5✔
2246
  return 0;
5✔
2247

NEW
2248
_err:
×
NEW
2249
  tDecoderClear(&dc1);
×
NEW
2250
  tDecoderClear(&dc2);
×
NEW
2251
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
×
NEW
2252
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
×
NEW
2253
  tdbTbcClose(pTbDbc);
×
NEW
2254
  tdbTbcClose(pUidIdxc);
×
NEW
2255
  taosHashCleanup(pTagTable);
×
NEW
2256
  return -1;
×
2257
}
2258
static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
3,109✔
2259
  SMetaEntry  ctbEntry = {0};
3,109✔
2260
  SMetaEntry  stbEntry = {0};
3,109✔
2261
  void       *pVal = NULL;
3,109✔
2262
  int         nVal = 0;
3,109✔
2263
  int         ret;
2264
  int         c;
2265
  tb_uid_t    uid;
2266
  int64_t     oversion;
2267
  const void *pData = NULL;
3,109✔
2268
  int         nData = 0;
3,109✔
2269

2270
  if (pAlterTbReq->tagName == NULL) {
3,109!
2271
    return terrno = TSDB_CODE_INVALID_MSG;
×
2272
  }
2273

2274
  // search name index
2275
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
3,109✔
2276
  if (ret < 0) {
3,109✔
2277
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
1✔
2278
  }
2279

2280
  uid = *(tb_uid_t *)pVal;
3,108✔
2281
  tdbFree(pVal);
3,108✔
2282
  pVal = NULL;
3,108✔
2283

2284
  // search uid index
2285
  TBC *pUidIdxc = NULL;
3,108✔
2286

2287
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
3,108!
2288
  if (tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c) < 0) {
3,108!
2289
    metaTrace("meta/table: failed to move to uid index, uid:%" PRId64, uid);
×
2290
  }
2291
  if (c != 0) {
3,108!
2292
    tdbTbcClose(pUidIdxc);
×
2293
    metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
×
2294
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2295
  }
2296

2297
  if (tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData) != 0) {
3,108!
NEW
2298
    tdbTbcClose(pUidIdxc);
×
UNCOV
2299
    metaError("meta/table: failed to get uid index, uid:%" PRId64, uid);
×
NEW
2300
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2301
  }
2302
  oversion = ((SUidIdxVal *)pData)[0].version;
3,108✔
2303

2304
  // search table.db
2305
  TBC     *pTbDbc = NULL;
3,108✔
2306
  SDecoder dc1 = {0};
3,108✔
2307
  SDecoder dc2 = {0};
3,108✔
2308

2309
  /* get ctbEntry */
2310
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
3,108!
2311
  if (tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c) != 0) {
3,108!
2312
    metaError("meta/table: failed to move to tb db, uid:%" PRId64, uid);
×
2313
  }
2314
  if (c != 0) {
3,108!
2315
    tdbTbcClose(pUidIdxc);
×
2316
    tdbTbcClose(pTbDbc);
×
2317
    metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
×
2318
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2319
  }
2320

2321
  if (tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData) != 0) {
3,108!
2322
    metaError("meta/table: failed to get tb db, uid:%" PRId64, uid);
×
NEW
2323
    tdbTbcClose(pUidIdxc);
×
NEW
2324
    tdbTbcClose(pTbDbc);
×
NEW
2325
    return terrno = TSDB_CODE_INVALID_MSG;
×
2326
  }
2327

2328
  if ((ctbEntry.pBuf = taosMemoryMalloc(nData)) == NULL) {
3,108!
2329
    tdbTbcClose(pUidIdxc);
×
2330
    tdbTbcClose(pTbDbc);
×
2331
    return terrno;
×
2332
  }
2333
  memcpy(ctbEntry.pBuf, pData, nData);
3,108✔
2334
  tDecoderInit(&dc1, ctbEntry.pBuf, nData);
3,108✔
2335
  ret = metaDecodeEntry(&dc1, &ctbEntry);
3,108✔
2336
  if (ret < 0) {
3,108!
2337
    terrno = ret;
×
2338
    goto _err;
×
2339
  }
2340

2341
  /* get stbEntry*/
2342
  if (tdbTbGet(pMeta->pUidIdx, &ctbEntry.ctbEntry.suid, sizeof(tb_uid_t), &pVal, &nVal) != 0) {
3,108!
2343
    metaError("meta/table: failed to get uid index, uid:%" PRId64, ctbEntry.ctbEntry.suid);
×
2344
  }
2345
  if (!pVal) {
3,108!
2346
    terrno = TSDB_CODE_INVALID_MSG;
×
2347
    goto _err;
×
2348
  }
2349

2350
  if (tdbTbGet(pMeta->pTbDb, &((STbDbKey){.uid = ctbEntry.ctbEntry.suid, .version = ((SUidIdxVal *)pVal)[0].version}),
3,108!
2351
               sizeof(STbDbKey), (void **)&stbEntry.pBuf, &nVal) != 0) {
2352
    metaError("meta/table: failed to get tb db, uid:%" PRId64, ctbEntry.ctbEntry.suid);
×
2353
  }
2354
  tdbFree(pVal);
3,108✔
2355
  tDecoderInit(&dc2, stbEntry.pBuf, nVal);
3,108✔
2356
  ret = metaDecodeEntry(&dc2, &stbEntry);
3,108✔
2357
  if (ret < 0) {
3,108!
2358
    terrno = ret;
×
2359
    goto _err;
×
2360
  }
2361

2362
  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
3,108✔
2363
  SSchema        *pColumn = NULL;
3,108✔
2364
  int32_t         iCol = 0;
3,108✔
2365

2366
  for (;;) {
2367
    pColumn = NULL;
5,264✔
2368

2369
    if (iCol >= pTagSchema->nCols) break;
5,264!
2370
    pColumn = &pTagSchema->pSchema[iCol];
5,264✔
2371

2372
    if (strcmp(pColumn->name, pAlterTbReq->tagName) == 0) break;
5,264✔
2373
    iCol++;
2,156✔
2374
  }
2375

2376
  if (pColumn == NULL) {
3,108!
2377
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
2378
    goto _err;
×
2379
  }
2380

2381
  ctbEntry.version = version;
3,108✔
2382
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
3,108✔
2383
    ctbEntry.ctbEntry.pTags = taosMemoryMalloc(pAlterTbReq->nTagVal);
205✔
2384
    if (ctbEntry.ctbEntry.pTags == NULL) {
205!
2385
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2386
      goto _err;
×
2387
    }
2388
    memcpy((void *)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
205✔
2389
  } else {
2390
    const STag *pOldTag = (const STag *)ctbEntry.ctbEntry.pTags;
2,903✔
2391
    STag       *pNewTag = NULL;
2,903✔
2392
    SArray     *pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
2,903✔
2393
    if (!pTagArray) {
2,903!
2394
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2395
      goto _err;
×
2396
    }
2397
    for (int32_t i = 0; i < pTagSchema->nCols; i++) {
9,765✔
2398
      SSchema *pCol = &pTagSchema->pSchema[i];
6,862✔
2399
      if (iCol == i) {
6,862✔
2400
        if (pAlterTbReq->isNull) {
2,903✔
2401
          continue;
256✔
2402
        }
2403
        STagVal val = {0};
2,647✔
2404
        val.type = pCol->type;
2,647✔
2405
        val.cid = pCol->colId;
2,647✔
2406
        if (IS_VAR_DATA_TYPE(pCol->type)) {
2,647!
2407
          val.pData = pAlterTbReq->pTagVal;
1,164✔
2408
          val.nData = pAlterTbReq->nTagVal;
1,164✔
2409
        } else {
2410
          memcpy(&val.i64, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
1,483✔
2411
        }
2412
        if (taosArrayPush(pTagArray, &val) == NULL) {
2,647!
2413
          terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2414
          taosArrayDestroy(pTagArray);
×
2415
          goto _err;
×
2416
        }
2417
      } else {
2418
        STagVal val = {.cid = pCol->colId};
3,959✔
2419
        if (tTagGet(pOldTag, &val)) {
3,959✔
2420
          if (taosArrayPush(pTagArray, &val) == NULL) {
3,293!
2421
            terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2422
            taosArrayDestroy(pTagArray);
×
2423
            goto _err;
×
2424
          }
2425
        }
2426
      }
2427
    }
2428
    if ((terrno = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag)) < 0) {
2,903!
2429
      taosArrayDestroy(pTagArray);
×
2430
      goto _err;
×
2431
    }
2432
    ctbEntry.ctbEntry.pTags = (uint8_t *)pNewTag;
2,903✔
2433
    taosArrayDestroy(pTagArray);
2,903✔
2434
  }
2435

2436
  metaWLock(pMeta);
3,108✔
2437

2438
  // save to table.db
2439
  if (metaSaveToTbDb(pMeta, &ctbEntry) < 0) {
3,108!
2440
    metaError("meta/table: failed to save to tb db:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2441
  }
2442

2443
  // save to uid.idx
2444
  if (metaUpdateUidIdx(pMeta, &ctbEntry) < 0) {
3,108!
2445
    metaError("meta/table: failed to update uid idx:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2446
  }
2447

2448
  if (metaUpdateTagIdx(pMeta, &ctbEntry) < 0) {
3,108!
2449
    metaError("meta/table: failed to update tag idx:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2450
  }
2451

2452
  SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid};
3,108✔
2453
  if (tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags,
3,108!
2454
                  ((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn) < 0) {
3,108✔
2455
    metaError("meta/table: failed to upsert ctb idx:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2456
  }
2457

2458
  if (metaUidCacheClear(pMeta, ctbEntry.ctbEntry.suid) < 0) {
3,108!
2459
    metaError("meta/table: failed to clear uid cache:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2460
  }
2461

2462
  if (metaTbGroupCacheClear(pMeta, ctbEntry.ctbEntry.suid) < 0) {
3,108!
2463
    metaError("meta/table: failed to clear group cache:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2464
  }
2465

2466
  if (metaUpdateChangeTime(pMeta, ctbEntry.uid, pAlterTbReq->ctimeMs) < 0) {
3,108!
2467
    metaError("meta/table: failed to update change time:%s uid:%" PRId64, ctbEntry.name, ctbEntry.uid);
×
2468
  }
2469

2470
  metaULock(pMeta);
3,108✔
2471

2472
  tDecoderClear(&dc1);
3,108✔
2473
  tDecoderClear(&dc2);
3,108✔
2474
  taosMemoryFree((void *)ctbEntry.ctbEntry.pTags);
3,108✔
2475
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
3,108!
2476
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
3,108!
2477
  tdbTbcClose(pTbDbc);
3,108✔
2478
  tdbTbcClose(pUidIdxc);
3,108✔
2479
  return 0;
3,108✔
2480

2481
_err:
×
2482
  tDecoderClear(&dc1);
×
2483
  tDecoderClear(&dc2);
×
2484
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
×
2485
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
×
2486
  tdbTbcClose(pTbDbc);
×
2487
  tdbTbcClose(pUidIdxc);
×
2488
  return -1;
×
2489
}
2490

2491
static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
109✔
2492
  void       *pVal = NULL;
109✔
2493
  int         nVal = 0;
109✔
2494
  const void *pData = NULL;
109✔
2495
  int         nData = 0;
109✔
2496
  int         ret = 0;
109✔
2497
  tb_uid_t    uid;
2498
  int64_t     oversion;
2499
  SMetaEntry  entry = {0};
109✔
2500
  int         c = 0;
109✔
2501

2502
  // search name index
2503
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
109✔
2504
  if (ret < 0) {
109!
2505
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2506
  }
2507

2508
  uid = *(tb_uid_t *)pVal;
109✔
2509
  tdbFree(pVal);
109✔
2510
  pVal = NULL;
109✔
2511

2512
  // search uid index
2513
  TBC *pUidIdxc = NULL;
109✔
2514

2515
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL));
109!
2516
  if (tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c) < 0) {
109!
2517
    metaError("meta/table: failed to move to uid index, uid:%" PRId64, uid);
×
2518
  }
2519
  if (c != 0) {
109!
2520
    tdbTbcClose(pUidIdxc);
×
2521
    metaError("meta/table: invalide c: %" PRId32 " update tb options failed.", c);
×
2522
    return TSDB_CODE_FAILED;
×
2523
  }
2524

2525
  if (tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData) < 0) {
109!
2526
    metaError("meta/table: failed to get uid index, uid:%" PRId64, uid);
×
2527
  }
2528
  oversion = ((SUidIdxVal *)pData)[0].version;
109✔
2529

2530
  // search table.db
2531
  TBC *pTbDbc = NULL;
109✔
2532

2533
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL));
109!
2534
  if (tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c) < 0) {
109!
2535
    metaError("meta/table: failed to move to tb db, uid:%" PRId64, uid);
×
2536
  }
2537
  if (c != 0) {
109!
2538
    tdbTbcClose(pUidIdxc);
×
2539
    tdbTbcClose(pTbDbc);
×
2540
    metaError("meta/table: invalide c: %" PRId32 " update tb options failed.", c);
×
2541
    return TSDB_CODE_FAILED;
×
2542
  }
2543

2544
  if (tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData) < 0) {
109!
2545
    metaError("meta/table: failed to get tb db, uid:%" PRId64, uid);
×
2546
  }
2547

2548
  // get table entry
2549
  SDecoder dc = {0};
109✔
2550
  if ((entry.pBuf = taosMemoryMalloc(nData)) == NULL) {
109!
2551
    tdbTbcClose(pUidIdxc);
×
2552
    tdbTbcClose(pTbDbc);
×
2553
    return terrno;
×
2554
  }
2555
  memcpy(entry.pBuf, pData, nData);
109✔
2556
  tDecoderInit(&dc, entry.pBuf, nData);
109✔
2557
  ret = metaDecodeEntry(&dc, &entry);
109✔
2558
  if (ret != 0) {
109!
2559
    tDecoderClear(&dc);
×
2560
    tdbTbcClose(pUidIdxc);
×
2561
    tdbTbcClose(pTbDbc);
×
2562
    metaError("meta/table: invalide ret: %" PRId32 " alt tb options failed.", ret);
×
2563
    return TSDB_CODE_FAILED;
×
2564
  }
2565

2566
  entry.version = version;
109✔
2567
  metaWLock(pMeta);
109✔
2568
  // build SMetaEntry
2569
  if (entry.type == TSDB_CHILD_TABLE) {
109✔
2570
    if (pAlterTbReq->updateTTL) {
56✔
2571
      metaDeleteTtl(pMeta, &entry);
25✔
2572
      entry.ctbEntry.ttlDays = pAlterTbReq->newTTL;
25✔
2573
      metaUpdateTtl(pMeta, &entry);
25✔
2574
    }
2575
    if (pAlterTbReq->newCommentLen >= 0) {
56✔
2576
      entry.ctbEntry.commentLen = pAlterTbReq->newCommentLen;
31✔
2577
      entry.ctbEntry.comment = pAlterTbReq->newComment;
31✔
2578
    }
2579
  } else {
2580
    if (pAlterTbReq->updateTTL) {
53✔
2581
      metaDeleteTtl(pMeta, &entry);
22✔
2582
      entry.ntbEntry.ttlDays = pAlterTbReq->newTTL;
22✔
2583
      metaUpdateTtl(pMeta, &entry);
22✔
2584
    }
2585
    if (pAlterTbReq->newCommentLen >= 0) {
53✔
2586
      entry.ntbEntry.commentLen = pAlterTbReq->newCommentLen;
31✔
2587
      entry.ntbEntry.comment = pAlterTbReq->newComment;
31✔
2588
    }
2589
  }
2590

2591
  // save to table db
2592
  if (metaSaveToTbDb(pMeta, &entry) < 0) {
109!
2593
    metaError("meta/table: failed to save to tb db:%s uid:%" PRId64, entry.name, entry.uid);
×
2594
  }
2595

2596
  if (metaUpdateUidIdx(pMeta, &entry) < 0) {
109!
2597
    metaError("meta/table: failed to update uid idx:%s uid:%" PRId64, entry.name, entry.uid);
×
2598
  }
2599

2600
  if (metaUpdateChangeTime(pMeta, entry.uid, pAlterTbReq->ctimeMs) < 0) {
109!
2601
    metaError("meta/table: failed to update change time:%s uid:%" PRId64, entry.name, entry.uid);
×
2602
  }
2603

2604
  metaULock(pMeta);
109✔
2605

2606
  tdbTbcClose(pTbDbc);
109✔
2607
  tdbTbcClose(pUidIdxc);
109✔
2608
  tDecoderClear(&dc);
109✔
2609
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
109!
2610
  return 0;
109✔
2611
}
2612

2613
static int metaAddTagIndex(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
×
2614
  SMetaEntry  stbEntry = {0};
×
2615
  void       *pVal = NULL;
×
2616
  int         nVal = 0;
×
2617
  int         ret;
2618
  int         c;
2619
  tb_uid_t    uid, suid;
2620
  int64_t     oversion;
2621
  const void *pData = NULL;
×
2622
  int         nData = 0;
×
2623
  SDecoder    dc = {0};
×
2624

2625
  if (pAlterTbReq->tagName == NULL) {
×
2626
    return terrno = TSDB_CODE_INVALID_MSG;
×
2627
  }
2628

2629
  // search name index
2630
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
×
2631
  if (ret < 0) {
×
2632
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2633
  } else {
2634
    uid = *(tb_uid_t *)pVal;
×
2635
    tdbFree(pVal);
×
2636
    pVal = NULL;
×
2637
  }
2638

2639
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(tb_uid_t), &pVal, &nVal) == -1) {
×
2640
    ret = -1;
×
2641
    goto _err;
×
2642
  }
2643
  suid = ((SUidIdxVal *)pVal)[0].suid;
×
2644

2645
  STbDbKey tbDbKey = {0};
×
2646
  tbDbKey.uid = suid;
×
2647
  tbDbKey.version = ((SUidIdxVal *)pVal)[0].version;
×
2648
  ret = tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pVal, &nVal);
×
2649
  if (ret < 0) {
×
2650
    goto _err;
×
2651
  }
2652
  tDecoderInit(&dc, pVal, nVal);
×
2653
  ret = metaDecodeEntry(&dc, &stbEntry);
×
2654
  if (ret < 0) {
×
2655
    tDecoderClear(&dc);
×
2656
    goto _err;
×
2657
  }
2658

2659
  // Get target schema info
2660
  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
×
2661
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
×
2662
    terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
×
2663
    goto _err;
×
2664
  }
2665
  SSchema *pCol = NULL;
×
2666
  int32_t  iCol = 0;
×
2667
  for (;;) {
2668
    pCol = NULL;
×
2669
    if (iCol >= pTagSchema->nCols) break;
×
2670
    pCol = &pTagSchema->pSchema[iCol];
×
2671
    if (strcmp(pCol->name, pAlterTbReq->tagName) == 0) break;
×
2672
    iCol++;
×
2673
  }
2674

2675
  if (iCol == 0) {
×
2676
    terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
×
2677
    goto _err;
×
2678
  }
2679
  if (pCol == NULL) {
×
2680
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
2681
    goto _err;
×
2682
  }
2683

2684
  /*
2685
   * iterator all pTdDbc by uid and version
2686
   */
2687
  TBC *pCtbIdxc = NULL;
×
2688
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL));
×
2689
  int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
×
2690
  if (rc < 0) {
×
2691
    tdbTbcClose(pCtbIdxc);
×
2692
    goto _err;
×
2693
  }
2694
  for (;;) {
×
2695
    void *pKey, *pVal;
2696
    int   nKey, nVal;
2697
    rc = tdbTbcNext(pCtbIdxc, &pKey, &nKey, &pVal, &nVal);
×
2698
    if (rc < 0) break;
×
2699
    if (((SCtbIdxKey *)pKey)->suid != uid) {
×
2700
      tdbFree(pKey);
×
2701
      tdbFree(pVal);
×
2702
      continue;
×
2703
    }
2704
    STagIdxKey *pTagIdxKey = NULL;
×
2705
    int32_t     nTagIdxKey;
2706

2707
    const void *pTagData = NULL;
×
2708
    int32_t     nTagData = 0;
×
2709

2710
    STagVal tagVal = {.cid = pCol->colId};
×
2711
    if (tTagGet((const STag *)pVal, &tagVal)) {
×
2712
      if (IS_VAR_DATA_TYPE(pCol->type)) {
×
2713
        pTagData = tagVal.pData;
×
2714
        nTagData = (int32_t)tagVal.nData;
×
2715
      } else {
2716
        pTagData = &(tagVal.i64);
×
2717
        nTagData = tDataTypes[pCol->type].bytes;
×
2718
      }
2719
    } else {
2720
      if (!IS_VAR_DATA_TYPE(pCol->type)) {
×
2721
        nTagData = tDataTypes[pCol->type].bytes;
×
2722
      }
2723
    }
2724
    if (metaCreateTagIdxKey(suid, pCol->colId, pTagData, nTagData, pCol->type, uid, &pTagIdxKey, &nTagIdxKey) < 0) {
×
2725
      tdbFree(pKey);
×
2726
      tdbFree(pVal);
×
2727
      metaDestroyTagIdxKey(pTagIdxKey);
×
2728
      tdbTbcClose(pCtbIdxc);
×
2729
      goto _err;
×
2730
    }
2731
    ret = tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
×
2732
    if (ret < 0) {
×
2733
      metaError("meta/table: failed to upsert tag idx:%s uid:%" PRId64, stbEntry.name, stbEntry.uid);
×
2734
    }
2735
    metaDestroyTagIdxKey(pTagIdxKey);
×
2736
    pTagIdxKey = NULL;
×
2737
  }
2738
  tdbTbcClose(pCtbIdxc);
×
2739
  return 0;
×
2740

2741
_err:
×
2742
  // tDecoderClear(&dc1);
2743
  // tDecoderClear(&dc2);
2744
  // if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
2745
  // if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
2746
  // tdbTbcClose(pTbDbc);
2747
  // tdbTbcClose(pUidIdxc);
2748
  return TSDB_CODE_FAILED;
×
2749
}
2750

2751
typedef struct SMetaPair {
2752
  void *key;
2753
  int   nkey;
2754
} SMetaPair;
2755

2756
static int metaDropTagIndex(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
×
2757
  SMetaEntry  stbEntry = {0};
×
2758
  void       *pVal = NULL;
×
2759
  int         nVal = 0;
×
2760
  int         ret;
2761
  int         c;
2762
  tb_uid_t    suid;
2763
  int64_t     oversion;
2764
  const void *pData = NULL;
×
2765
  int         nData = 0;
×
2766
  SDecoder    dc = {0};
×
2767

2768
  if (pAlterTbReq->tagName == NULL) {
×
2769
    return terrno = TSDB_CODE_INVALID_MSG;
×
2770
  }
2771

2772
  // search name index
2773
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
×
2774
  if (ret < 0) {
×
2775
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2776
  }
2777
  suid = *(tb_uid_t *)pVal;
×
2778
  tdbFree(pVal);
×
2779
  pVal = NULL;
×
2780

2781
  if (tdbTbGet(pMeta->pUidIdx, &suid, sizeof(tb_uid_t), &pVal, &nVal) == -1) {
×
2782
    ret = -1;
×
2783
    goto _err;
×
2784
  }
2785

2786
  STbDbKey tbDbKey = {0};
×
2787
  tbDbKey.uid = suid;
×
2788
  tbDbKey.version = ((SUidIdxVal *)pVal)[0].version;
×
2789
  ret = tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pVal, &nVal);
×
2790
  if (ret < 0) {
×
2791
    goto _err;
×
2792
  }
2793

2794
  tDecoderInit(&dc, pVal, nVal);
×
2795
  ret = metaDecodeEntry(&dc, &stbEntry);
×
2796
  if (ret < 0) {
×
2797
    tDecoderClear(&dc);
×
2798
    goto _err;
×
2799
  }
2800

2801
  // Get targe schema info
2802
  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
×
2803
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
×
2804
    terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
×
2805
    goto _err;
×
2806
  }
2807
  SSchema *pCol = NULL;
×
2808
  int32_t  iCol = 0;
×
2809
  for (;;) {
2810
    pCol = NULL;
×
2811
    if (iCol >= pTagSchema->nCols) break;
×
2812
    pCol = &pTagSchema->pSchema[iCol];
×
2813
    if (strcmp(pCol->name, pAlterTbReq->tagName) == 0) break;
×
2814
    iCol++;
×
2815
  }
2816
  if (iCol == 0) {
×
2817
    // cannot drop 1th tag index
2818
    terrno = -1;
×
2819
    goto _err;
×
2820
  }
2821
  if (pCol == NULL) {
×
2822
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
×
2823
    goto _err;
×
2824
  }
2825

2826
  if (IS_IDX_ON(pCol)) {
×
2827
    terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
×
2828
    goto _err;
×
2829
  }
2830

2831
  SArray *tagIdxList = taosArrayInit(512, sizeof(SMetaPair));
×
2832
  if (tagIdxList == NULL) {
×
2833
    goto _err;
×
2834
  }
2835

2836
  TBC *pTagIdxc = NULL;
×
2837
  TAOS_CHECK_RETURN(tdbTbcOpen(pMeta->pTagIdx, &pTagIdxc, NULL));
×
2838
  int rc =
2839
      tdbTbcMoveTo(pTagIdxc, &(STagIdxKey){.suid = suid, .cid = INT32_MIN, .type = pCol->type}, sizeof(STagIdxKey), &c);
×
2840
  for (;;) {
×
2841
    void *pKey, *pVal;
2842
    int   nKey, nVal;
2843
    rc = tdbTbcNext(pTagIdxc, &pKey, &nKey, &pVal, &nVal);
×
2844
    STagIdxKey *pIdxKey = (STagIdxKey *)pKey;
×
2845
    if (pIdxKey->suid != suid || pIdxKey->cid != pCol->colId) {
×
2846
      tdbFree(pKey);
×
2847
      tdbFree(pVal);
×
2848
      continue;
×
2849
    }
2850

2851
    SMetaPair pair = {.key = pKey, nKey = nKey};
×
2852
    if (taosArrayPush(tagIdxList, &pair) == NULL) {
×
2853
      goto _err;
×
2854
    }
2855
  }
2856
  tdbTbcClose(pTagIdxc);
2857

2858
  metaWLock(pMeta);
2859
  for (int i = 0; i < taosArrayGetSize(tagIdxList); i++) {
2860
    SMetaPair *pair = taosArrayGet(tagIdxList, i);
2861
    ret = tdbTbDelete(pMeta->pTagIdx, pair->key, pair->nkey, pMeta->txn);
2862
    if (ret < 0) {
2863
      metaError("meta/table: failed to delete tag idx:%s uid:%" PRId64, stbEntry.name, stbEntry.uid);
2864
    }
2865
  }
2866
  metaULock(pMeta);
2867

2868
  taosArrayDestroy(tagIdxList);
2869

2870
  // set pCol->flags; INDEX_ON
2871
  return 0;
2872
_err:
×
2873
  return TSDB_CODE_FAILED;
×
2874
}
2875
int32_t metaUpdateTableColCompress(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
5✔
2876
  // impl later
2877
  SMetaEntry  tbEntry = {0};
5✔
2878
  void       *pVal = NULL;
5✔
2879
  int         nVal = 0;
5✔
2880
  int         ret;
2881
  int         c;
2882
  tb_uid_t    suid;
2883
  int64_t     oversion;
2884
  const void *pData = NULL;
5✔
2885
  int         nData = 0;
5✔
2886
  SDecoder    dc = {0};
5✔
2887
  ret = tdbTbGet(pMeta->pNameIdx, pReq->tbName, strlen(pReq->tbName) + 1, &pVal, &nVal);
5✔
2888
  if (ret < 0) {
5!
2889
    return terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
2890
  }
2891
  suid = *(tb_uid_t *)pVal;
5✔
2892
  tdbFree(pVal);
5✔
2893
  pVal = NULL;
5✔
2894

2895
  if (tdbTbGet(pMeta->pUidIdx, &suid, sizeof(tb_uid_t), &pVal, &nVal) == -1) {
5!
2896
    terrno = TSDB_CODE_INVALID_MSG;
×
2897
    ret = -1;
×
2898
    goto _err;
×
2899
  }
2900

2901
  STbDbKey tbDbKey = {0};
5✔
2902
  tbDbKey.uid = suid;
5✔
2903
  tbDbKey.version = ((SUidIdxVal *)pVal)[0].version;
5✔
2904
  if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pVal, &nVal) < 0) {
5!
2905
    terrno = TSDB_CODE_INVALID_MSG;
×
2906
    tdbFree(pVal);
×
2907
    goto _err;
×
2908
  }
2909

2910
  tDecoderInit(&dc, pVal, nVal);
5✔
2911
  ret = metaDecodeEntry(&dc, &tbEntry);
5✔
2912
  if (ret < 0) {
5!
2913
    terrno = TSDB_CODE_INVALID_MSG;
×
2914
    tdbFree(pVal);
×
2915
    tDecoderClear(&dc);
×
2916
    goto _err;
×
2917
  }
2918
  if (tbEntry.type != TSDB_NORMAL_TABLE && tbEntry.type != TSDB_SUPER_TABLE) {
5!
2919
    terrno = TSDB_CODE_INVALID_MSG;
×
2920
    tdbFree(pVal);
×
2921
    tDecoderClear(&dc);
×
2922
    goto _err;
×
2923
  }
2924
  int8_t           updated = 0;
5✔
2925
  SColCmprWrapper *wp = &tbEntry.colCmpr;
5✔
2926
  for (int32_t i = 0; i < wp->nCols; i++) {
40✔
2927
    SColCmpr *p = &wp->pColCmpr[i];
35✔
2928
    if (p->id == pReq->colId) {
35✔
2929
      uint32_t dst = 0;
5✔
2930
      updated = tUpdateCompress(p->alg, pReq->compress, TSDB_COLVAL_COMPRESS_DISABLED, TSDB_COLVAL_LEVEL_DISABLED,
5✔
2931
                                TSDB_COLVAL_LEVEL_MEDIUM, &dst);
2932
      if (updated > 0) {
5!
2933
        p->alg = dst;
5✔
2934
      }
2935
    }
2936
  }
2937
  if (updated == 0) {
5!
2938
    tdbFree(pVal);
×
2939
    tDecoderClear(&dc);
×
2940
    terrno = TSDB_CODE_VND_COLUMN_COMPRESS_ALREADY_EXIST;
×
2941
    goto _err;
×
2942
  } else if (updated < 0) {
5!
2943
    tdbFree(pVal);
×
2944
    tDecoderClear(&dc);
×
2945
    terrno = TSDB_CODE_TSC_COMPRESS_LEVEL_ERROR;
×
2946
    goto _err;
×
2947
  }
2948
  tbEntry.version = version;
5✔
2949

2950
  metaWLock(pMeta);
5✔
2951
  if (metaSaveToTbDb(pMeta, &tbEntry) < 0) {
5!
2952
    metaError("meta/table: failed to save to tb db:%s uid:%" PRId64, tbEntry.name, tbEntry.uid);
×
2953
  }
2954

2955
  if (metaUpdateUidIdx(pMeta, &tbEntry) < 0) {
5!
2956
    metaError("meta/table: failed to update uid idx:%s uid:%" PRId64, tbEntry.name, tbEntry.uid);
×
2957
  }
2958

2959
  if (metaUpdateChangeTime(pMeta, suid, pReq->ctimeMs) < 0) {
5!
2960
    metaError("meta/table: failed to update change time:%s uid:%" PRId64, tbEntry.name, tbEntry.uid);
×
2961
  }
2962

2963
  metaULock(pMeta);
5✔
2964

2965
  tdbFree(pVal);
5✔
2966
  tDecoderClear(&dc);
5✔
2967

2968
  return 0;
5✔
2969
_err:
×
2970
  return TSDB_CODE_FAILED;
×
2971
}
2972

2973
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
5,192✔
2974
  pMeta->changed = true;
5,192✔
2975
  switch (pReq->action) {
5,192!
2976
    case TSDB_ALTER_TABLE_ADD_COLUMN:
1,964✔
2977
    case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
2978
    case TSDB_ALTER_TABLE_DROP_COLUMN:
2979
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
2980
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
2981
      return metaAlterTableColumn(pMeta, version, pReq, pMetaRsp);
1,964✔
2982
    case TSDB_ALTER_TABLE_UPDATE_TAG_VAL:
3,109✔
2983
      return metaUpdateTableTagVal(pMeta, version, pReq);
3,109✔
2984
    case TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL:
5✔
2985
      return metaUpdateTableMultiTagVal(pMeta, version, pReq);
5✔
2986
      return terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
2987
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
109✔
2988
      return metaUpdateTableOptions(pMeta, version, pReq);
109✔
2989
    case TSDB_ALTER_TABLE_ADD_TAG_INDEX:
×
2990
      return metaAddTagIndex(pMeta, version, pReq);
×
2991
    case TSDB_ALTER_TABLE_DROP_TAG_INDEX:
×
2992
      return metaDropTagIndex(pMeta, version, pReq);
×
2993
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS:
5✔
2994
      return metaUpdateTableColCompress(pMeta, version, pReq);
5✔
2995
    default:
×
2996
      return terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
2997
      break;
2998
  }
2999
}
3000

3001
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
304,070✔
3002
  STbDbKey tbDbKey;
3003
  void    *pKey = NULL;
304,070✔
3004
  void    *pVal = NULL;
304,070✔
3005
  int      kLen = 0;
304,070✔
3006
  int      vLen = 0;
304,070✔
3007
  SEncoder coder = {0};
304,070✔
3008

3009
  // set key and value
3010
  tbDbKey.version = pME->version;
304,070✔
3011
  tbDbKey.uid = pME->uid;
304,070✔
3012

3013
  metaDebug("vgId:%d, start to save table version:%" PRId64 " uid:%" PRId64, TD_VID(pMeta->pVnode), pME->version,
304,070✔
3014
            pME->uid);
3015

3016
  pKey = &tbDbKey;
304,078✔
3017
  kLen = sizeof(tbDbKey);
304,078✔
3018

3019
  int32_t ret = 0;
304,078✔
3020
  tEncodeSize(metaEncodeEntry, pME, vLen, ret);
304,078!
3021
  if (ret < 0) {
303,984!
3022
    goto _err;
×
3023
  }
3024

3025
  pVal = taosMemoryMalloc(vLen);
303,984✔
3026
  if (pVal == NULL) {
304,045!
3027
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3028
    goto _err;
×
3029
  }
3030

3031
  tEncoderInit(&coder, pVal, vLen);
304,045✔
3032

3033
  if (metaEncodeEntry(&coder, pME) < 0) {
304,058!
3034
    goto _err;
×
3035
  }
3036

3037
  tEncoderClear(&coder);
304,030✔
3038

3039
  // write to table.db
3040
  if (tdbTbInsert(pMeta->pTbDb, pKey, kLen, pVal, vLen, pMeta->txn) < 0) {
304,132!
3041
    goto _err;
×
3042
  }
3043

3044
  taosMemoryFree(pVal);
304,117✔
3045
  return 0;
304,077✔
3046

3047
_err:
×
3048
  metaError("vgId:%d, failed to save table version:%" PRId64 "uid:%" PRId64 " %s", TD_VID(pMeta->pVnode), pME->version,
×
3049
            pME->uid, tstrerror(terrno));
3050

3051
  taosMemoryFree(pVal);
×
3052
  return TSDB_CODE_FAILED;
×
3053
}
3054

3055
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
304,010✔
3056
  // upsert cache
3057
  SMetaInfo info;
3058
  metaGetEntryInfo(pME, &info);
304,010✔
3059
  int32_t ret = metaCacheUpsert(pMeta, &info);
304,120✔
3060
  if (ret < 0) {
304,074!
3061
    metaError("vgId:%d, failed to upsert cache, uid: %" PRId64 " %s", TD_VID(pMeta->pVnode), pME->uid, tstrerror(ret));
×
3062
  }
3063

3064
  SUidIdxVal uidIdxVal = {.suid = info.suid, .version = info.version, .skmVer = info.skmVer};
304,074✔
3065

3066
  return tdbTbUpsert(pMeta->pUidIdx, &pME->uid, sizeof(tb_uid_t), &uidIdxVal, sizeof(uidIdxVal), pMeta->txn);
304,074✔
3067
}
3068

3069
static int metaUpdateSuidIdx(SMeta *pMeta, const SMetaEntry *pME) {
30,994✔
3070
  return tdbTbUpsert(pMeta->pSuidIdx, &pME->uid, sizeof(tb_uid_t), NULL, 0, pMeta->txn);
30,994✔
3071
}
3072

3073
static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME) {
291,684✔
3074
  return tdbTbUpsert(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), pMeta->txn);
291,684✔
3075
}
3076

3077
static void metaUpdateTtl(SMeta *pMeta, const SMetaEntry *pME) {
260,771✔
3078
  if (pME->type != TSDB_CHILD_TABLE && pME->type != TSDB_NORMAL_TABLE) return;
260,771!
3079

3080
  STtlUpdTtlCtx ctx = {.uid = pME->uid, .pTxn = pMeta->txn};
260,771✔
3081
  if (pME->type == TSDB_CHILD_TABLE) {
260,771✔
3082
    ctx.ttlDays = pME->ctbEntry.ttlDays;
245,541✔
3083
    ctx.changeTimeMs = pME->ctbEntry.btime;
245,541✔
3084
  } else {
3085
    ctx.ttlDays = pME->ntbEntry.ttlDays;
15,230✔
3086
    ctx.changeTimeMs = pME->ntbEntry.btime;
15,230✔
3087
  }
3088

3089
  int32_t ret = ttlMgrInsertTtl(pMeta->pTtlMgr, &ctx);
260,771✔
3090
  if (ret < 0) {
260,761!
3091
    metaError("vgId:%d, failed to insert ttl, uid: %" PRId64 " %s", TD_VID(pMeta->pVnode), pME->uid, tstrerror(ret));
×
3092
  }
3093

3094
  return;
260,756✔
3095
}
3096

3097
static int metaUpdateChangeTime(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs) {
4,270✔
3098
  if (!tsTtlChangeOnWrite) return 0;
4,270✔
3099

3100
  if (changeTimeMs <= 0) {
1!
3101
    metaWarn("Skip to change ttl deletetion time on write, uid: %" PRId64, uid);
×
3102
    return TSDB_CODE_VERSION_NOT_COMPATIBLE;
×
3103
  }
3104

3105
  STtlUpdCtimeCtx ctx = {.uid = uid, .changeTimeMs = changeTimeMs, .pTxn = pMeta->txn};
1✔
3106

3107
  return ttlMgrUpdateChangeTime(pMeta->pTtlMgr, &ctx);
1✔
3108
}
3109

3110
int metaUpdateChangeTimeWithLock(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs) {
13,876,763✔
3111
  if (!tsTtlChangeOnWrite) return 0;
13,876,763!
3112

3113
  metaWLock(pMeta);
×
3114
  int ret = metaUpdateChangeTime(pMeta, uid, changeTimeMs);
1✔
3115
  metaULock(pMeta);
1✔
3116
  return ret;
1✔
3117
}
3118

3119
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
245,518✔
3120
  SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
245,518✔
3121

3122
  return tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags,
491,034✔
3123
                     ((STag *)(pME->ctbEntry.pTags))->len, pMeta->txn);
245,518✔
3124
}
3125

3126
int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
303,736✔
3127
                        STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
3128
  if (IS_VAR_DATA_TYPE(type)) {
303,736✔
3129
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + VARSTR_HEADER_SIZE + sizeof(tb_uid_t);
40,422✔
3130
  } else {
3131
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + sizeof(tb_uid_t);
263,314✔
3132
  }
3133

3134
  *ppTagIdxKey = (STagIdxKey *)taosMemoryMalloc(*nTagIdxKey);
303,736✔
3135
  if (*ppTagIdxKey == NULL) {
303,748!
3136
    return terrno;
×
3137
  }
3138

3139
  (*ppTagIdxKey)->suid = suid;
303,753✔
3140
  (*ppTagIdxKey)->cid = cid;
303,753✔
3141
  (*ppTagIdxKey)->isNull = (pTagData == NULL) ? 1 : 0;
303,753✔
3142
  (*ppTagIdxKey)->type = type;
303,753✔
3143

3144
  // refactor
3145
  if (IS_VAR_DATA_TYPE(type)) {
303,753✔
3146
    memcpy((*ppTagIdxKey)->data, (uint16_t *)&nTagData, VARSTR_HEADER_SIZE);
40,449✔
3147
    if (pTagData != NULL) memcpy((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE, pTagData, nTagData);
40,449✔
3148
    *(tb_uid_t *)((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE + nTagData) = uid;
40,449✔
3149
  } else {
3150
    if (pTagData != NULL) memcpy((*ppTagIdxKey)->data, pTagData, nTagData);
263,304✔
3151
    *(tb_uid_t *)((*ppTagIdxKey)->data + nTagData) = uid;
263,304✔
3152
  }
3153

3154
  return 0;
303,753✔
3155
}
3156

3157
static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) {
303,339✔
3158
  if (pTagIdxKey) taosMemoryFree(pTagIdxKey);
303,339!
3159
}
303,339✔
3160

3161
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
248,624✔
3162
  void          *pData = NULL;
248,624✔
3163
  int            nData = 0;
248,624✔
3164
  STbDbKey       tbDbKey = {0};
248,624✔
3165
  SMetaEntry     stbEntry = {0};
248,624✔
3166
  STagIdxKey    *pTagIdxKey = NULL;
248,624✔
3167
  int32_t        nTagIdxKey;
3168
  const SSchema *pTagColumn;
3169
  const void    *pTagData = NULL;
248,624✔
3170
  int32_t        nTagData = 0;
248,624✔
3171
  SDecoder       dc = {0};
248,624✔
3172
  int32_t        ret = 0;
248,624✔
3173
  // get super table
3174
  if (tdbTbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData) != 0) {
248,624!
3175
    metaError("vgId:%d, failed to get stable suid for update. version:%" PRId64, TD_VID(pMeta->pVnode),
×
3176
              pCtbEntry->version);
3177
    ret = TSDB_CODE_TDB_INVALID_TABLE_ID;
×
3178
    goto end;
×
3179
  }
3180
  tbDbKey.uid = pCtbEntry->ctbEntry.suid;
248,636✔
3181
  tbDbKey.version = ((SUidIdxVal *)pData)[0].version;
248,636✔
3182
  ret = tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData);
248,636✔
3183
  if (ret < 0) {
248,620!
3184
    metaError("vgId:%d, failed to get stable for update. version:%" PRId64, TD_VID(pMeta->pVnode), pCtbEntry->version);
×
3185
    goto end;
×
3186
  }
3187

3188
  tDecoderInit(&dc, pData, nData);
248,620✔
3189
  ret = metaDecodeEntry(&dc, &stbEntry);
248,605✔
3190
  if (ret < 0) {
248,578!
3191
    goto end;
×
3192
  }
3193

3194
  if (stbEntry.stbEntry.schemaTag.pSchema == NULL) {
248,578!
3195
    ret = TSDB_CODE_INVALID_PARA;
×
3196
    goto end;
×
3197
  }
3198

3199
  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
248,578✔
3200
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
248,578✔
3201
    pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
576✔
3202
    STagVal tagVal = {.cid = pTagColumn->colId};
576✔
3203

3204
    pTagData = pCtbEntry->ctbEntry.pTags;
576✔
3205
    nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
576✔
3206
    ret = metaSaveJsonVarToIdx(pMeta, pCtbEntry, pTagColumn);
576✔
3207
    goto end;
576✔
3208
  } else {
3209
    for (int i = 0; i < pTagSchema->nCols; i++) {
879,372✔
3210
      pTagData = NULL;
631,306✔
3211
      nTagData = 0;
631,306✔
3212
      pTagColumn = &pTagSchema->pSchema[i];
631,306✔
3213
      if (!IS_IDX_ON(pTagColumn)) continue;
631,306✔
3214

3215
      STagVal tagVal = {.cid = pTagColumn->colId};
247,951✔
3216
      if (tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal)) {
247,951✔
3217
        if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
246,788!
3218
          pTagData = tagVal.pData;
27,502✔
3219
          nTagData = (int32_t)tagVal.nData;
27,502✔
3220
        } else {
3221
          pTagData = &(tagVal.i64);
219,286✔
3222
          nTagData = tDataTypes[pTagColumn->type].bytes;
219,286✔
3223
        }
3224
      } else {
3225
        if (!IS_VAR_DATA_TYPE(pTagColumn->type)) {
1,183!
3226
          nTagData = tDataTypes[pTagColumn->type].bytes;
899✔
3227
        }
3228
      }
3229
      if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
247,971!
3230
                              pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
247,971✔
3231
        ret = -1;
×
3232
        goto end;
×
3233
      }
3234
      if (tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn) < 0) {
247,971!
3235
        metaError("vgId:%d, failed to update tag index. version:%" PRId64, TD_VID(pMeta->pVnode), pCtbEntry->version);
×
3236
      }
3237
      metaDestroyTagIdxKey(pTagIdxKey);
248,014✔
3238
      pTagIdxKey = NULL;
248,015✔
3239
    }
3240
  }
3241
end:
248,066✔
3242
  tDecoderClear(&dc);
248,642✔
3243
  tdbFree(pData);
248,627✔
3244
  return ret;
248,653✔
3245
}
3246

3247
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
50,201✔
3248
  SEncoder              coder = {0};
50,201✔
3249
  void                 *pVal = NULL;
50,201✔
3250
  int                   vLen = 0;
50,201✔
3251
  int                   rcode = 0;
50,201✔
3252
  SSkmDbKey             skmDbKey = {0};
50,201✔
3253
  const SSchemaWrapper *pSW;
3254

3255
  if (pME->type == TSDB_SUPER_TABLE) {
50,201✔
3256
    pSW = &pME->stbEntry.schemaRow;
34,026✔
3257
  } else if (pME->type == TSDB_NORMAL_TABLE) {
16,175!
3258
    pSW = &pME->ntbEntry.schemaRow;
16,251✔
3259
  } else {
3260
    metaError("meta/table: invalide table type: %" PRId8 " save skm db failed.", pME->type);
×
3261
    return TSDB_CODE_FAILED;
×
3262
  }
3263

3264
  skmDbKey.uid = pME->uid;
50,277✔
3265
  skmDbKey.sver = pSW->version;
50,277✔
3266

3267
  // if receive tmq meta message is: create stable1 then delete stable1 then create stable1 with multi vgroups
3268
  if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), NULL, NULL) == 0) {
50,277✔
3269
    return rcode;
10✔
3270
  }
3271

3272
  // encode schema
3273
  int32_t ret = 0;
50,281✔
3274
  tEncodeSize(tEncodeSSchemaWrapper, pSW, vLen, ret);
100,554✔
3275
  if (ret < 0) return -1;
50,173!
3276
  pVal = taosMemoryMalloc(vLen);
50,173✔
3277
  if (pVal == NULL) {
50,293!
3278
    rcode = -1;
×
3279
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
3280
    goto _exit;
×
3281
  }
3282

3283
  tEncoderInit(&coder, pVal, vLen);
50,293✔
3284
  ret = tEncodeSSchemaWrapper(&coder, pSW);
50,293✔
3285
  if (ret < 0) {
50,293!
3286
    rcode = -1;
×
3287
    goto _exit;
×
3288
  }
3289

3290
  if (tdbTbInsert(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, pMeta->txn) < 0) {
50,293!
3291
    rcode = -1;
×
3292
    goto _exit;
×
3293
  }
3294

3295
  metaDebug("vgId:%d, set schema:(%" PRId64 ") sver:%d since %s", TD_VID(pMeta->pVnode), pME->uid, pSW->version,
50,295✔
3296
            tstrerror(terrno));
3297

3298
_exit:
39,007✔
3299
  taosMemoryFree(pVal);
50,299✔
3300
  tEncoderClear(&coder);
50,299✔
3301
  return rcode;
50,287✔
3302
}
3303

3304
int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
291,363✔
3305
  int32_t code = 0;
291,363✔
3306
  int32_t line = 0;
291,363✔
3307
  metaWLock(pMeta);
291,363✔
3308

3309
  // save to table.db
3310
  code = metaSaveToTbDb(pMeta, pME);
291,800✔
3311
  VND_CHECK_CODE(code, line, _err);
291,691!
3312

3313
  // update uid.idx
3314
  code = metaUpdateUidIdx(pMeta, pME);
291,691✔
3315
  VND_CHECK_CODE(code, line, _err);
291,742!
3316

3317
  // update name.idx
3318
  code = metaUpdateNameIdx(pMeta, pME);
291,742✔
3319
  VND_CHECK_CODE(code, line, _err);
291,763!
3320

3321
  if (pME->type == TSDB_CHILD_TABLE) {
291,763✔
3322
    // update ctb.idx
3323
    code = metaUpdateCtbIdx(pMeta, pME);
245,525✔
3324
    VND_CHECK_CODE(code, line, _err);
245,517!
3325

3326
    // update tag.idx
3327
    code = metaUpdateTagIdx(pMeta, pME);
245,517✔
3328
    VND_CHECK_CODE(code, line, _err);
245,521!
3329
  } else {
3330
    // update schema.db
3331
    code = metaSaveToSkmDb(pMeta, pME);
46,238✔
3332
    VND_CHECK_CODE(code, line, _err);
46,200!
3333

3334
    if (pME->type == TSDB_SUPER_TABLE) {
46,200✔
3335
      code = metaUpdateSuidIdx(pMeta, pME);
31,010✔
3336
      VND_CHECK_CODE(code, line, _err);
31,029!
3337
    }
3338
  }
3339

3340
  code = metaUpdateBtimeIdx(pMeta, pME);
291,740✔
3341
  VND_CHECK_CODE(code, line, _err);
291,662!
3342

3343
  if (pME->type == TSDB_NORMAL_TABLE) {
291,662✔
3344
    code = metaUpdateNcolIdx(pMeta, pME);
15,209✔
3345
    VND_CHECK_CODE(code, line, _err);
15,209!
3346
  }
3347

3348
  if (pME->type != TSDB_SUPER_TABLE) {
291,662✔
3349
    metaUpdateTtl(pMeta, pME);
260,727✔
3350
  }
3351

3352
  if (pME->type == TSDB_SUPER_TABLE || pME->type == TSDB_NORMAL_TABLE) {
291,646✔
3353
  }
3354

3355
  metaULock(pMeta);
291,646✔
3356
  metaDebug("vgId:%d, handle meta entry, ver:%" PRId64 ", uid:%" PRId64 ", name:%s", TD_VID(pMeta->pVnode),
291,756✔
3357
            pME->version, pME->uid, pME->name);
3358
  return 0;
291,741✔
3359

3360
_err:
×
3361
  metaULock(pMeta);
×
3362
  metaError("vgId:%d, failed to handle meta entry since %s at line:%d, ver:%" PRId64 ", uid:%" PRId64 ", name:%s",
×
3363
            TD_VID(pMeta->pVnode), terrstr(), line, pME->version, pME->uid, pME->name);
3364
  return TSDB_CODE_FAILED;
×
3365
}
3366

3367
static void colCompressDebug(SHashObj *pColCmprObj) {
670,985✔
3368
  void *p = taosHashIterate(pColCmprObj, NULL);
670,985✔
3369
  while (p) {
4,975,187✔
3370
    uint32_t cmprAlg = *(uint32_t *)p;
4,304,374✔
3371
    col_id_t colId = *(col_id_t *)taosHashGetKey(p, NULL);
4,304,374✔
3372
    p = taosHashIterate(pColCmprObj, p);
4,304,339✔
3373

3374
    uint8_t l1, l2, lvl;
3375
    tcompressDebug(cmprAlg, &l1, &l2, &lvl);
4,304,984✔
3376

3377
    const char *l1str = columnEncodeStr(l1);
4,304,829✔
3378
    const char *l2str = columnCompressStr(l2);
4,304,577✔
3379
    const char *lvlstr = columnLevelStr(lvl);
4,304,349✔
3380
    metaDebug("colId: %d, encode:%s, compress:%s,level:%s", colId, l1str, l2str, lvlstr);
4,304,203✔
3381
  }
3382
  return;
670,813✔
3383
}
3384
int32_t metaGetColCmpr(SMeta *pMeta, tb_uid_t uid, SHashObj **ppColCmprObj) {
670,949✔
3385
  int rc = 0;
670,949✔
3386

3387
  SHashObj *pColCmprObj = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
670,949✔
3388
  if (pColCmprObj == NULL) {
670,997!
3389
    pColCmprObj = NULL;
×
3390
    return TSDB_CODE_OUT_OF_MEMORY;
×
3391
  }
3392

3393
  void      *pData = NULL;
670,997✔
3394
  int        nData = 0;
670,997✔
3395
  SMetaEntry e = {0};
670,997✔
3396
  SDecoder   dc = {0};
670,997✔
3397

3398
  *ppColCmprObj = NULL;
670,997✔
3399

3400
  metaRLock(pMeta);
670,997✔
3401
  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
671,022✔
3402
  if (rc < 0) {
671,018✔
3403
    taosHashClear(pColCmprObj);
25✔
3404
    metaULock(pMeta);
25✔
3405
    return TSDB_CODE_FAILED;
25✔
3406
  }
3407
  int64_t version = ((SUidIdxVal *)pData)[0].version;
670,993✔
3408
  rc = tdbTbGet(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), &pData, &nData);
670,993✔
3409
  if (rc < 0) {
670,979!
3410
    metaULock(pMeta);
×
3411
    taosHashClear(pColCmprObj);
×
3412
    metaError("failed to get table entry");
×
3413
    return rc;
×
3414
  }
3415

3416
  tDecoderInit(&dc, pData, nData);
670,979✔
3417
  rc = metaDecodeEntry(&dc, &e);
670,963✔
3418
  if (rc < 0) {
670,922!
3419
    tDecoderClear(&dc);
×
3420
    tdbFree(pData);
×
3421
    metaULock(pMeta);
×
3422
    taosHashClear(pColCmprObj);
×
3423
    return rc;
×
3424
  }
3425
  if (useCompress(e.type)) {
670,922!
3426
    SColCmprWrapper *p = &e.colCmpr;
670,917✔
3427
    for (int32_t i = 0; i < p->nCols; i++) {
4,976,216✔
3428
      SColCmpr *pCmpr = &p->pColCmpr[i];
4,304,995✔
3429
      rc = taosHashPut(pColCmprObj, &pCmpr->id, sizeof(pCmpr->id), &pCmpr->alg, sizeof(pCmpr->alg));
4,304,995✔
3430
      if (rc < 0) {
4,305,335✔
3431
        tDecoderClear(&dc);
36✔
3432
        tdbFree(pData);
×
3433
        metaULock(pMeta);
×
3434
        taosHashClear(pColCmprObj);
×
3435
        return rc;
×
3436
      }
3437
    }
3438
  } else {
3439
    tDecoderClear(&dc);
×
3440
    tdbFree(pData);
×
3441
    metaULock(pMeta);
×
3442
    taosHashClear(pColCmprObj);
×
3443
    return 0;
×
3444
  }
3445
  tDecoderClear(&dc);
671,221✔
3446
  tdbFree(pData);
670,973✔
3447
  metaULock(pMeta);
670,990✔
3448

3449
  *ppColCmprObj = pColCmprObj;
670,983✔
3450
  colCompressDebug(pColCmprObj);
670,983✔
3451

3452
  return 0;
670,908✔
3453
}
3454
// refactor later
3455
void *metaGetIdx(SMeta *pMeta) { return pMeta->pTagIdx; }
43,661✔
3456
void *metaGetIvtIdx(SMeta *pMeta) { return pMeta->pTagIvtIdx; }
43,645✔
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

© 2025 Coveralls, Inc