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

taosdata / TDengine / #5023

15 Apr 2026 11:15AM UTC coverage: 72.251% (-0.03%) from 72.278%
#5023

push

travis-ci

web-flow
feat: implement fixed bucket table distribution (#35092)

221 of 236 new or added lines in 4 files covered. (93.64%)

613 existing lines in 123 files now uncovered.

257631 of 356577 relevant lines covered (72.25%)

133876647.56 hits per line

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

68.84
/source/dnode/vnode/src/meta/metaTable2.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
#include "scalar.h"
18
#include "tarray.h"
19
#include "tdatablock.h"
20
#include "querynodes.h"
21
#include "thash.h"
22

23
extern int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry);
24
extern int32_t metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, int64_t ownerId,
25
                                 STableMetaRsp *pMetaRsp);
26
extern int32_t metaUpdateVtbMetaRsp(SMetaEntry *pEntry, char *tbName, const SSchemaWrapper *pSchema,
27
                                    const SColRefWrapper *pRef, const SExtSchema *pExtSchemas, int64_t ownerId,
28
                                    STableMetaRsp *pMetaRsp,
29
                                    int8_t tableType);
30
extern int32_t metaFetchEntryByUid(SMeta *pMeta, int64_t uid, SMetaEntry **ppEntry);
31
extern int32_t metaFetchEntryByName(SMeta *pMeta, const char *name, SMetaEntry **ppEntry);
32
extern void    metaFetchEntryFree(SMetaEntry **ppEntry);
33
extern int32_t updataTableColCmpr(SColCmprWrapper *pWp, SSchema *pSchema, int8_t add, uint32_t compress);
34
extern int32_t addTableExtSchema(SMetaEntry *pEntry, const SSchema *pColumn, int32_t newColNum, SExtSchema *pExtSchema);
35
extern int32_t dropTableExtSchema(SMetaEntry *pEntry, int32_t dropColId, int32_t newColNum);
36

37
static int32_t metaValidateVirtualChildColRefReq(SMeta *pMeta, int64_t version, const SVCreateTbReq *pReq,
349,366✔
38
                                                 const SMetaEntry *pStbEntry) {
39
  int32_t expectedCols = pStbEntry->stbEntry.schemaRow.nCols;
349,366✔
40

41
  if (pReq->colRef.nCols != expectedCols) {
349,366✔
42
    metaError("vgId:%d, %s failed at %s:%d since virtual child table %s col ref count %d does not match super table "
×
43
              "%s schema count %d, version:%" PRId64,
44
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->colRef.nCols, pReq->ctb.stbName,
45
              expectedCols, version);
46
    return TSDB_CODE_PAR_INVALID_REF_COLUMN;
×
47
  }
48

49
  if (expectedCols > 0 && pReq->colRef.pColRef == NULL) {
349,366✔
50
    metaError("vgId:%d, %s failed at %s:%d since virtual child table %s col ref is null while super table %s has %d "
×
51
              "columns, version:%" PRId64,
52
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->ctb.stbName, expectedCols,
53
              version);
54
    return TSDB_CODE_PAR_INVALID_REF_COLUMN;
×
55
  }
56

57
  return TSDB_CODE_SUCCESS;
349,366✔
58
}
59

60
static int32_t metaCheckCreateSuperTableReq(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
5,546,377✔
61
  int32_t   vgId = TD_VID(pMeta->pVnode);
5,546,377✔
62
  void     *value = NULL;
5,546,949✔
63
  int32_t   valueSize = 0;
5,547,890✔
64
  SMetaInfo info;
5,540,761✔
65

66
  // check name
67
  if (NULL == pReq->name || strlen(pReq->name) == 0) {
5,546,363✔
68
    metaError("vgId:%d, %s failed at %s:%d since invalid name:%s, version:%" PRId64, vgId, __func__, __FILE__, __LINE__,
203✔
69
              pReq->name, version);
70
    return TSDB_CODE_INVALID_MSG;
×
71
  }
72

73
  int32_t r = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &value, &valueSize);
5,546,952✔
74
  if (r == 0) {  // name exists, check uid and type
5,540,008✔
75
    int64_t uid = *(tb_uid_t *)value;
2,328✔
76
    tdbFree(value);
2,328✔
77

78
    if (pReq->suid != uid) {
2,328✔
79
      metaError("vgId:%d, %s failed at %s:%d since table %s uid:%" PRId64 " already exists, request uid:%" PRId64
2,328✔
80
                " version:%" PRId64,
81
                vgId, __func__, __FILE__, __LINE__, pReq->name, uid, pReq->suid, version);
82
      return TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
2,328✔
83
    }
84

85
    if (metaGetInfo(pMeta, uid, &info, NULL) == TSDB_CODE_NOT_FOUND) {
×
86
      metaError("vgId:%d, %s failed at %s:%d since table %s uid:%" PRId64
×
87
                " not found, this is an internal error in meta, version:%" PRId64,
88
                vgId, __func__, __FILE__, __LINE__, pReq->name, uid, version);
89
      return TSDB_CODE_PAR_TABLE_NOT_EXIST;
×
90
    }
91

92
    if (info.uid == info.suid) {
×
93
      return TSDB_CODE_TDB_STB_ALREADY_EXIST;
×
94
    } else {
95
      metaError("vgId:%d, %s failed at %s:%d since table %s uid:%" PRId64
×
96
                " already exists but not a super table, version:%" PRId64,
97
                vgId, __func__, __FILE__, __LINE__, pReq->name, uid, version);
98
      return TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
×
99
    }
100
  }
101

102
  // check suid
103
  if (metaGetInfo(pMeta, pReq->suid, &info, NULL) != TSDB_CODE_NOT_FOUND) {
5,537,680✔
104
    metaError("vgId:%d, %s failed at %s:%d since table with uid:%" PRId64 " already exist, name:%s version:%" PRId64,
×
105
              vgId, __func__, __FILE__, __LINE__, pReq->suid, pReq->name, version);
106
    return TSDB_CODE_INVALID_MSG;
×
107
  }
108

109
  return TSDB_CODE_SUCCESS;
5,538,796✔
110
}
111

112
static int32_t metaCheckDropTableReq(SMeta *pMeta, int64_t version, SVDropTbReq *pReq) {
1,614,585✔
113
  int32_t   code = TSDB_CODE_SUCCESS;
1,614,585✔
114
  void     *value = NULL;
1,614,585✔
115
  int32_t   valueSize = 0;
1,614,585✔
116
  SMetaInfo info;
1,614,357✔
117

118
  if (NULL == pReq->name || strlen(pReq->name) == 0) {
1,614,585✔
119
    metaError("vgId:%d, %s failed at %s:%d since invalid name:%s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
120
              __FILE__, __LINE__, pReq->name, version);
121
    return TSDB_CODE_INVALID_MSG;
×
122
  }
123

124
  code = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &value, &valueSize);
1,614,585✔
125
  if (TSDB_CODE_SUCCESS != code) {
1,614,585✔
126
    if (pReq->igNotExists) {
×
127
      metaTrace("vgId:%d, %s success since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
128
                pReq->name, version);
129
    } else {
130
      metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode),
×
131
                __func__, __FILE__, __LINE__, pReq->name, version);
132
    }
133
    return TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
134
  }
135
  pReq->uid = *(tb_uid_t *)value;
1,614,585✔
136
  tdbFreeClear(value);
1,614,585✔
137

138
  code = metaGetInfo(pMeta, pReq->uid, &info, NULL);
1,614,585✔
139
  if (TSDB_CODE_SUCCESS != code) {
1,614,585✔
140
    metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64
×
141
              " not found, this is an internal error, version:%" PRId64,
142
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->uid, version);
143
    code = TSDB_CODE_INTERNAL_ERROR;
×
144
    return code;
×
145
  }
146
  pReq->suid = info.suid;
1,614,585✔
147

148
  return code;
1,614,585✔
149
}
150

151
static int32_t metaCheckDropSuperTableReq(SMeta *pMeta, int64_t version, SVDropStbReq *pReq) {
939,672✔
152
  int32_t   code = TSDB_CODE_SUCCESS;
939,672✔
153
  void     *value = NULL;
939,672✔
154
  int32_t   valueSize = 0;
939,672✔
155
  SMetaInfo info;
938,660✔
156

157
  if (NULL == pReq->name || strlen(pReq->name) == 0) {
939,001✔
158
    metaError("vgId:%d, %s failed at %s:%d since invalid name:%s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
1,366✔
159
              __FILE__, __LINE__, pReq->name, version);
160
    return TSDB_CODE_INVALID_MSG;
×
161
  }
162

163
  code = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &value, &valueSize);
938,306✔
164
  if (code) {
939,672✔
165
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
776✔
166
              __FILE__, __LINE__, pReq->name, version);
167
    return TSDB_CODE_TDB_STB_NOT_EXIST;
776✔
168
  } else {
169
    int64_t uid = *(int64_t *)value;
938,896✔
170
    tdbFreeClear(value);
938,896✔
171

172
    if (uid != pReq->suid) {
938,896✔
173
      metaError("vgId:%d, %s failed at %s:%d since table %s uid:%" PRId64 " not match, version:%" PRId64,
776✔
174
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->suid, version);
175
      return TSDB_CODE_TDB_STB_NOT_EXIST;
776✔
176
    }
177
  }
178

179
  code = metaGetInfo(pMeta, pReq->suid, &info, NULL);
936,912✔
180
  if (code) {
938,120✔
181
    metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64
×
182
              " not found, this is an internal error, version:%" PRId64,
183
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->suid, version);
184
    return TSDB_CODE_INTERNAL_ERROR;
×
185
  }
186
  if (info.suid != info.uid) {
938,120✔
187
    metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not a super table, version:%" PRId64,
×
188
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->suid, version);
189
    return TSDB_CODE_INVALID_MSG;
×
190
  }
191
  return code;
938,120✔
192
}
193

194
// Create Super Table
195
int32_t metaCreateSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
5,538,154✔
196
  int32_t code = TSDB_CODE_SUCCESS;
5,538,154✔
197

198
  // check request
199
  code = metaCheckCreateSuperTableReq(pMeta, version, pReq);
5,538,154✔
200
  if (code != TSDB_CODE_SUCCESS) {
5,541,444✔
201
    if (code == TSDB_CODE_TDB_STB_ALREADY_EXIST) {
2,328✔
202
      metaWarn("vgId:%d, super table %s uid:%" PRId64 " already exists, version:%" PRId64, TD_VID(pMeta->pVnode),
×
203
               pReq->name, pReq->suid, version);
204
      TAOS_RETURN(TSDB_CODE_SUCCESS);
×
205
    } else {
206
      TAOS_RETURN(code);
2,328✔
207
    }
208
  }
209

210
  // handle entry
211
  SMetaEntry entry = {
11,064,138✔
212
      .version = version,
213
      .type = TSDB_SUPER_TABLE,
214
      .uid = pReq->suid,
5,536,895✔
215
      .name = pReq->name,
5,531,562✔
216
      .stbEntry.schemaRow = pReq->schemaRow,
217
      .stbEntry.schemaTag = pReq->schemaTag,
218
      .stbEntry.keep = pReq->keep,
5,543,442✔
219
      .stbEntry.ownerId = pReq->ownerId,
5,530,125✔
220
  };
221
  if (pReq->rollup) {
5,529,459✔
222
    TABLE_SET_ROLLUP(entry.flags);
×
223
    entry.stbEntry.rsmaParam = pReq->rsmaParam;
×
224
  }
225
  if (pReq->colCmpred) {
5,531,038✔
226
    TABLE_SET_COL_COMPRESSED(entry.flags);
5,535,299✔
227
    entry.colCmpr = pReq->colCmpr;
5,535,299✔
228
  }
229

230
  entry.pExtSchemas = pReq->pExtSchemas;
5,528,509✔
231

232
  if (pReq->virtualStb) {
5,536,860✔
233
    TABLE_SET_VIRTUAL(entry.flags);
119,619✔
234
  }
235

236
  code = metaHandleEntry2(pMeta, &entry);
5,533,044✔
237
  if (TSDB_CODE_SUCCESS == code) {
5,548,620✔
238
    metaInfo("vgId:%d, super table %s suid:%" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
5,548,620✔
239
             pReq->suid, version);
240
  } else {
241
    metaError("vgId:%d, failed to create stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
×
242
              pReq->suid, tstrerror(code));
243
  }
244
  TAOS_RETURN(code);
5,549,077✔
245
}
246

247
// Drop Super Table
248
int32_t metaDropSuperTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
939,672✔
249
  int32_t code = TSDB_CODE_SUCCESS;
939,672✔
250

251
  // check request
252
  code = metaCheckDropSuperTableReq(pMeta, verison, pReq);
939,672✔
253
  if (code) {
939,243✔
254
    TAOS_RETURN(code);
1,552✔
255
  }
256

257
  // handle entry
258
  SMetaEntry entry = {
937,691✔
259
      .version = verison,
260
      .type = -TSDB_SUPER_TABLE,
261
      .uid = pReq->suid,
938,120✔
262
  };
263
  code = metaHandleEntry2(pMeta, &entry);
938,120✔
264
  if (code) {
938,120✔
265
    metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
×
266
              tstrerror(code));
267
  } else {
268
    metaInfo("vgId:%d, super table %s uid:%" PRId64 " is dropped, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
938,120✔
269
             pReq->suid, verison);
270
  }
271
  TAOS_RETURN(code);
938,120✔
272
}
273

274
// Alter Super Table
275

276
// Create Child Table
277
static int32_t metaCheckCreateChildTableReq(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
63,791,209✔
278
  int32_t   code = TSDB_CODE_SUCCESS;
63,791,209✔
279
  void     *value = NULL;
63,791,209✔
280
  int32_t   valueSize = 0;
63,792,465✔
281
  SMetaInfo info;
63,789,010✔
282

283
  if (NULL == pReq->name || strlen(pReq->name) == 0 || NULL == pReq->ctb.stbName || strlen(pReq->ctb.stbName) == 0 ||
63,791,578✔
284
      pReq->ctb.suid == 0) {
63,793,848✔
285
    metaError("vgId:%d, %s failed at %s:%d since invalid name:%s stb name:%s, version:%" PRId64, TD_VID(pMeta->pVnode),
7,302✔
286
              __func__, __FILE__, __LINE__, pReq->name, pReq->ctb.stbName, version);
287
    return TSDB_CODE_INVALID_MSG;
×
288
  }
289

290
  // check table existence
291
  if (tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &value, &valueSize) == 0) {
63,785,630✔
292
    pReq->uid = *(int64_t *)value;
332,505✔
293
    tdbFreeClear(value);
332,505✔
294

295
    if (metaGetInfo(pMeta, pReq->uid, &info, NULL) != 0) {
332,505✔
296
      metaError("vgId:%d, %s failed at %s:%d since cannot find table with uid %" PRId64
×
297
                ", which is an internal error, version:%" PRId64,
298
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->uid, version);
299
      return TSDB_CODE_INTERNAL_ERROR;
×
300
    }
301

302
    // check table type
303
    if (info.suid == info.uid || info.suid == 0) {
332,505✔
304
      metaError("vgId:%d, %s failed at %s:%d since table with uid %" PRId64 " is not a super table, version:%" PRId64,
1,862✔
305
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->uid, version);
306
      return TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
1,862✔
307
    }
308

309
    // check suid
310
    if (info.suid != pReq->ctb.suid) {
330,643✔
311
      metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " exists in another stable with uid %" PRId64
×
312
                " instead of stable with uid %" PRId64 " version:%" PRId64,
313
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->uid, info.suid, pReq->ctb.suid,
314
                version);
315
      return TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
×
316
    }
317

318
    return TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
330,643✔
319
  }
320

321
  // check super table existence
322
  SMetaEntry *pStbEntry = NULL;
63,456,934✔
323
  code = metaFetchEntryByName(pMeta, pReq->ctb.stbName, &pStbEntry);
63,456,567✔
324
  if (code) {
63,453,982✔
325
    metaError("vgId:%d, %s failed at %s:%d since super table %s does not exist, version:%" PRId64,
33✔
326
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->ctb.stbName, version);
327
    return TSDB_CODE_PAR_TABLE_NOT_EXIST;
33✔
328
  }
329

330
  if (pStbEntry->type != TSDB_SUPER_TABLE) {
63,453,949✔
331
    metaError("vgId:%d, %s failed at %s:%d since table %s is not a super table, version:%" PRId64,
×
332
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->ctb.stbName, version);
333
    metaFetchEntryFree(&pStbEntry);
×
334
    return TSDB_CODE_INVALID_MSG;
×
335
  }
336

337
  if (pStbEntry->uid != pReq->ctb.suid) {
63,450,636✔
338
    metaError("vgId:%d, %s failed at %s:%d since super table %s uid %" PRId64 " does not match request uid %" PRId64
×
339
              ", version:%" PRId64,
340
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->ctb.stbName, pStbEntry->uid, pReq->ctb.suid,
341
              version);
342
    metaFetchEntryFree(&pStbEntry);
×
343
    return TSDB_CODE_PAR_TABLE_NOT_EXIST;
×
344
  }
345

346
  // Check tag value
347
  SSchemaWrapper *pTagSchema = &pStbEntry->stbEntry.schemaTag;
63,441,907✔
348
  const STag     *pTag = (const STag *)pReq->ctb.pTag;
63,457,193✔
349
  if (pTagSchema->nCols != 1 || pTagSchema->pSchema[0].type != TSDB_DATA_TYPE_JSON) {
63,449,284✔
350
    for (int32_t i = 0; i < pTagSchema->nCols; ++i) {
277,535,400✔
351
      STagVal tagVal = {
214,358,130✔
352
          .cid = pTagSchema->pSchema[i].colId,
214,352,793✔
353
      };
354

355
      if (tTagGet(pTag, &tagVal)) {
214,349,385✔
356
        if (pTagSchema->pSchema[i].type != tagVal.type) {
170,595,759✔
357
          metaError("vgId:%d, %s failed at %s:%d since child table %s tag type does not match the expected type, version:%" PRId64,
×
358
                    TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, version);
359
          metaFetchEntryFree(&pStbEntry);
×
360
          return TSDB_CODE_INVALID_MSG;
×
361
        }
362
      }
363
    }
364
  }
365

366
  if (pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
63,450,541✔
367
    code = metaValidateVirtualChildColRefReq(pMeta, version, pReq, pStbEntry);
349,366✔
368
    if (code) {
349,366✔
369
      metaFetchEntryFree(&pStbEntry);
×
370
      return code;
×
371
    }
372
  }
373

374
  metaFetchEntryFree(&pStbEntry);
63,456,096✔
375

376
  // check grant
377
  if (!metaTbInFilterCache(pMeta, pReq->ctb.stbName, 1)) {
63,445,832✔
378
    code = grantCheck(TSDB_GRANT_TIMESERIES);
63,457,351✔
379
    if (TSDB_CODE_SUCCESS != code) {
63,445,435✔
380
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
381
                __FILE__, __LINE__, tstrerror(code), version, pReq->name);
382
    }
383
  }
384
  return code;
63,445,643✔
385
}
386

387
static int32_t metaBuildCreateChildTableRsp(SMeta *pMeta, const SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
63,098,822✔
388
  int32_t code = TSDB_CODE_SUCCESS;
63,098,822✔
389

390
  if (NULL == ppRsp) {
63,098,822✔
391
    return code;
×
392
  }
393

394
  *ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
63,098,822✔
395
  if (NULL == ppRsp) {
63,088,315✔
396
    return terrno;
×
397
  }
398

399
  (*ppRsp)->tableType = TSDB_CHILD_TABLE;
63,088,315✔
400
  (*ppRsp)->tuid = pEntry->uid;
63,095,988✔
401
  (*ppRsp)->suid = pEntry->ctbEntry.suid;
63,103,973✔
402
  tstrncpy((*ppRsp)->tbName, pEntry->name, TSDB_TABLE_NAME_LEN);
63,101,114✔
403

404
  return code;
63,104,142✔
405
}
406

407
static int32_t metaCreateChildTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
63,441,844✔
408
  int32_t code = TSDB_CODE_SUCCESS;
63,441,844✔
409

410
  // check request
411
  code = metaCheckCreateChildTableReq(pMeta, version, pReq);
63,441,844✔
412
  if (code) {
63,423,878✔
413
    if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
332,538✔
414
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
1,895✔
415
                __FILE__, __LINE__, tstrerror(code), version, pReq->name);
416
    }
417
    return code;
332,538✔
418
  }
419

420
  SMetaEntry entry = {
63,091,340✔
421
      .version = version,
422
      .type = TSDB_CHILD_TABLE,
423
      .uid = pReq->uid,
63,095,753✔
424
      .name = pReq->name,
63,086,881✔
425
      .ctbEntry.btime = pReq->btime,
63,104,338✔
426
      .ctbEntry.ttlDays = pReq->ttl,
63,094,622✔
427
      .ctbEntry.commentLen = pReq->commentLen,
63,087,847✔
428
      .ctbEntry.comment = pReq->comment,
63,092,877✔
429
      .ctbEntry.suid = pReq->ctb.suid,
63,105,134✔
430
      .ctbEntry.pTags = pReq->ctb.pTag,
63,099,034✔
431
  };
432

433
  // build response
434
  code = metaBuildCreateChildTableRsp(pMeta, &entry, ppRsp);
63,086,805✔
435
  if (code) {
63,101,938✔
436
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
×
437
              tstrerror(code));
438
  }
439

440
  // handle entry
441
  code = metaHandleEntry2(pMeta, &entry);
63,101,938✔
442
  if (TSDB_CODE_SUCCESS == code) {
63,108,965✔
443
    metaInfo("vgId:%d, index:%" PRId64 ", child table is created, tb:%s uid:%" PRId64 " suid:%" PRId64,
63,109,684✔
444
             TD_VID(pMeta->pVnode), version, pReq->name, pReq->uid, pReq->ctb.suid);
445
  } else {
446
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s suid:%" PRId64 " version:%" PRId64,
×
447
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name,
448
              pReq->ctb.suid, version);
449
  }
450
  return code;
63,112,596✔
451
}
452

453
// Drop Child Table
454

455
// Alter Child Table
456

457
// Create Normal Table
458
static int32_t metaCheckCreateNormalTableReq(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
7,852,677✔
459
  int32_t code = 0;
7,852,677✔
460
  void   *value = NULL;
7,852,677✔
461
  int32_t valueSize = 0;
7,852,677✔
462

463
  if (NULL == pReq->name || strlen(pReq->name) == 0) {
7,852,677✔
464
    metaError("vgId:%d, %s failed at %s:%d since invalid name:%s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
465
              __FILE__, __LINE__, pReq->name, version);
466
    return TSDB_CODE_INVALID_MSG;
×
467
  }
468

469
  // check name
470
  if (tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &value, &valueSize) == 0) {
7,852,677✔
471
    // for auto create table, we return the uid of the existing table
472
    pReq->uid = *(tb_uid_t *)value;
43,437✔
473
    tdbFree(value);
43,437✔
474
    return TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
43,437✔
475
  }
476

477
  // grant check
478
  code = grantCheck(TSDB_GRANT_TIMESERIES);
7,809,240✔
479
  if (code) {
7,809,240✔
480
    metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
481
              __FILE__, __LINE__, tstrerror(code), version, pReq->name);
482
  }
483
  return code;
7,809,240✔
484
}
485

486
static int32_t metaBuildCreateNormalTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
7,611,750✔
487
  int32_t code = TSDB_CODE_SUCCESS;
7,611,750✔
488

489
  if (NULL == ppRsp) {
7,611,750✔
490
    return code;
×
491
  }
492

493
  *ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
7,611,750✔
494
  if (NULL == *ppRsp) {
7,611,750✔
495
    return terrno;
×
496
  }
497

498
  code = metaUpdateMetaRsp(pEntry->uid, pEntry->name, &pEntry->ntbEntry.schemaRow, pEntry->ntbEntry.ownerId, *ppRsp);
7,611,750✔
499
  if (code) {
7,611,750✔
500
    taosMemoryFreeClear(*ppRsp);
×
501
    return code;
×
502
  }
503

504
  for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
87,827,053✔
505
    SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
80,215,303✔
506
    (*ppRsp)->pSchemaExt[i].colId = p->id;
80,215,303✔
507
    (*ppRsp)->pSchemaExt[i].compress = p->alg;
80,215,303✔
508
    if (pEntry->pExtSchemas) {
80,215,303✔
509
      (*ppRsp)->pSchemaExt[i].typeMod = pEntry->pExtSchemas[i].typeMod;
607,559✔
510
    }
511
  }
512

513
  return code;
7,611,750✔
514
}
515

516
static int32_t metaCreateNormalTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
7,655,187✔
517
  int32_t code = TSDB_CODE_SUCCESS;
7,655,187✔
518

519
  // check request
520
  code = metaCheckCreateNormalTableReq(pMeta, version, pReq);
7,655,187✔
521
  if (code) {
7,655,187✔
522
    if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
43,437✔
523
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
524
                __FILE__, __LINE__, tstrerror(code), version, pReq->name);
525
    }
526
    TAOS_RETURN(code);
43,437✔
527
  }
528

529
  SMetaEntry entry = {
15,223,063✔
530
      .version = version,
531
      .type = TSDB_NORMAL_TABLE,
532
      .uid = pReq->uid,
7,611,750✔
533
      .name = pReq->name,
7,611,750✔
534
      .ntbEntry.btime = pReq->btime,
7,611,750✔
535
      .ntbEntry.ttlDays = pReq->ttl,
7,611,750✔
536
      .ntbEntry.commentLen = pReq->commentLen,
7,611,750✔
537
      .ntbEntry.comment = pReq->comment,
7,611,750✔
538
      .ntbEntry.schemaRow = pReq->ntb.schemaRow,
539
      .ntbEntry.ncid = pReq->ntb.schemaRow.pSchema[pReq->ntb.schemaRow.nCols - 1].colId + 1,
7,611,750✔
540
      .ntbEntry.ownerId = pReq->ntb.userId,
7,611,750✔
541
      .colCmpr = pReq->colCmpr,
542
      .pExtSchemas = pReq->pExtSchemas,
7,611,750✔
543
  };
544
  TABLE_SET_COL_COMPRESSED(entry.flags);
7,611,750✔
545

546
  // build response
547
  code = metaBuildCreateNormalTableRsp(pMeta, &entry, ppRsp);
7,611,750✔
548
  if (code) {
7,611,750✔
549
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
×
550
              tstrerror(code));
551
  }
552

553
  // handle entry
554
  code = metaHandleEntry2(pMeta, &entry);
7,611,750✔
555
  if (TSDB_CODE_SUCCESS == code) {
7,611,750✔
556
    metaInfo("vgId:%d, index:%" PRId64 ", normal table is created, tb:%s uid:%" PRId64, TD_VID(pMeta->pVnode), version,
7,611,750✔
557
             pReq->name, pReq->uid);
558
  } else {
559
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
560
              __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
561
  }
562
  TAOS_RETURN(code);
7,611,750✔
563
}
564

565
static int32_t metaBuildCreateVirtualNormalTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
197,490✔
566
  int32_t code = TSDB_CODE_SUCCESS;
197,490✔
567

568
  if (NULL == ppRsp) {
197,490✔
569
    return code;
×
570
  }
571

572
  *ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
197,490✔
573
  if (NULL == *ppRsp) {
197,490✔
574
    return terrno;
×
575
  }
576

577
  code = metaUpdateVtbMetaRsp(pEntry, pEntry->name, &pEntry->ntbEntry.schemaRow, &pEntry->colRef, pEntry->pExtSchemas,
197,490✔
578
                              pEntry->ntbEntry.ownerId, *ppRsp, TSDB_VIRTUAL_NORMAL_TABLE);
579
  if (code) {
197,490✔
580
    taosMemoryFreeClear(*ppRsp);
×
581
    return code;
×
582
  }
583

584
  return code;
197,490✔
585
}
586

587
static int32_t metaCreateVirtualNormalTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
197,490✔
588
  // check request
589
  int32_t code = metaCheckCreateNormalTableReq(pMeta, version, pReq);
197,490✔
590
  if (code) {
197,490✔
591
    if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
×
592
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
593
                __FILE__, __LINE__, tstrerror(code), version, pReq->name);
594
    }
595
    TAOS_RETURN(code);
×
596
  }
597

598
  SMetaEntry entry = {.version = version,
592,356✔
599
                      .type = TSDB_VIRTUAL_NORMAL_TABLE,
600
                      .uid = pReq->uid,
197,490✔
601
                      .name = pReq->name,
197,490✔
602
                      .ntbEntry.btime = pReq->btime,
197,490✔
603
                      .ntbEntry.ttlDays = pReq->ttl,
197,490✔
604
                      .ntbEntry.commentLen = pReq->commentLen,
197,490✔
605
                      .ntbEntry.comment = pReq->comment,
197,490✔
606
                      .ntbEntry.schemaRow = pReq->ntb.schemaRow,
607
                      .ntbEntry.ncid = pReq->ntb.schemaRow.pSchema[pReq->ntb.schemaRow.nCols - 1].colId + 1,
197,490✔
608
                      .ntbEntry.ownerId = pReq->ntb.userId,
197,490✔
609
                      .pExtSchemas = pReq->pExtSchemas,
197,490✔
610
                      .colRef = pReq->colRef};
611

612
  code = metaBuildCreateVirtualNormalTableRsp(pMeta, &entry, ppRsp);
197,490✔
613
  if (code) {
197,490✔
614
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
×
615
              tstrerror(code));
616
    TAOS_RETURN(code);
×
617
  }
618

619
  // handle entry
620
  code = metaHandleEntry2(pMeta, &entry);
197,490✔
621
  if (TSDB_CODE_SUCCESS == code) {
197,490✔
622
    metaInfo("vgId:%d, index:%" PRId64 ", virtual normal table is created, tb:%s uid:%" PRId64, TD_VID(pMeta->pVnode),
197,490✔
623
             version, pReq->name, pReq->uid);
624
  } else {
625
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
626
              __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
627
  }
628
  TAOS_RETURN(code);
197,490✔
629
#if 0
630
  metaTimeSeriesNotifyCheck(pMeta);
631
#endif
632
}
633

634
static int32_t metaBuildCreateVirtualChildTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
349,366✔
635
  int32_t    code = TSDB_CODE_SUCCESS;
349,366✔
636
  SMetaEntry *pSuper = NULL;
349,366✔
637

638
  if (NULL == ppRsp) {
349,366✔
639
    return code;
×
640
  }
641

642
  *ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
349,366✔
643
  if (NULL == *ppRsp) {
349,366✔
644
    return terrno;
×
645
  }
646

647
  code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
349,366✔
648
  if (code != TSDB_CODE_SUCCESS) {
349,366✔
649
    taosMemoryFreeClear(*ppRsp);
×
650
    return code;
×
651
  }
652

653
  code = metaUpdateVtbMetaRsp(pEntry, pEntry->name, &pSuper->stbEntry.schemaRow, &pEntry->colRef, pSuper->pExtSchemas,
698,675✔
654
                              pSuper->stbEntry.ownerId, *ppRsp, TSDB_VIRTUAL_CHILD_TABLE);
349,366✔
655
  if (code) {
349,366✔
656
    metaFetchEntryFree(&pSuper);
×
657
    taosMemoryFreeClear(*ppRsp);
×
658
    return code;
×
659
  }
660

661
  (*ppRsp)->suid = pEntry->ctbEntry.suid;
349,366✔
662
  metaFetchEntryFree(&pSuper);
349,366✔
663

664
  return code;
349,366✔
665
}
666

667
static int32_t metaCreateVirtualChildTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
349,366✔
668
  // check request
669
  int32_t code = metaCheckCreateChildTableReq(pMeta, version, pReq);
349,366✔
670
  if (code) {
349,366✔
671
    if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
×
672
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
673
                __FILE__, __LINE__, tstrerror(code), version, pReq->name);
674
    }
675
    TAOS_RETURN(code);
×
676
  }
677

678
  SMetaEntry entry = {.version = version,
698,675✔
679
                      .type = TSDB_VIRTUAL_CHILD_TABLE,
680
                      .uid = pReq->uid,
349,366✔
681
                      .name = pReq->name,
349,366✔
682
                      .ctbEntry.btime = pReq->btime,
349,366✔
683
                      .ctbEntry.ttlDays = pReq->ttl,
349,366✔
684
                      .ctbEntry.commentLen = pReq->commentLen,
349,366✔
685
                      .ctbEntry.comment = pReq->comment,
349,366✔
686
                      .ctbEntry.suid = pReq->ctb.suid,
349,366✔
687
                      .ctbEntry.pTags = pReq->ctb.pTag,
349,366✔
688
                      .colRef = pReq->colRef};
689

690
  code = metaBuildCreateVirtualChildTableRsp(pMeta, &entry, ppRsp);
349,366✔
691
  if (code) {
349,366✔
692
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
×
693
              tstrerror(code));
694
    TAOS_RETURN(code);
×
695
  }
696

697
  // handle entry
698
  code = metaHandleEntry2(pMeta, &entry);
349,366✔
699
  if (TSDB_CODE_SUCCESS == code) {
349,366✔
700
    metaInfo("vgId:%d, index:%" PRId64 ", virtual child table is created, tb:%s uid:%" PRId64, TD_VID(pMeta->pVnode),
349,366✔
701
             version, pReq->name, pReq->uid);
702
  } else {
703
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
704
              __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
705
  }
706
  TAOS_RETURN(code);
349,366✔
707
#if 0
708
  metaTimeSeriesNotifyCheck(pMeta);
709
#endif
710
}
711

712
// Drop Normal Table
713

714
// Alter Normal Table
715

716
int32_t metaCreateTable2(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
71,643,668✔
717
  int32_t code = TSDB_CODE_SUCCESS;
71,643,668✔
718
  if (TSDB_CHILD_TABLE == pReq->type) {
71,643,668✔
719
    code = metaCreateChildTable(pMeta, version, pReq, ppRsp);
63,443,899✔
720
  } else if (TSDB_NORMAL_TABLE == pReq->type) {
8,202,043✔
721
    code = metaCreateNormalTable(pMeta, version, pReq, ppRsp);
7,655,187✔
722
  } else if (TSDB_VIRTUAL_NORMAL_TABLE == pReq->type) {
546,856✔
723
    code = metaCreateVirtualNormalTable(pMeta, version, pReq, ppRsp);
197,490✔
724
  } else if (TSDB_VIRTUAL_CHILD_TABLE == pReq->type) {
349,366✔
725
    code = metaCreateVirtualChildTable(pMeta, version, pReq, ppRsp);
349,366✔
726
  } else {
727
    code = TSDB_CODE_INVALID_MSG;
×
728
  }
729
  TAOS_RETURN(code);
71,647,053✔
730
}
731

732
int32_t metaDropTable2(SMeta *pMeta, int64_t version, SVDropTbReq *pReq) {
1,614,585✔
733
  int32_t code = TSDB_CODE_SUCCESS;
1,614,585✔
734

735
  // check request
736
  code = metaCheckDropTableReq(pMeta, version, pReq);
1,614,585✔
737
  if (code) {
1,614,585✔
738
    if (TSDB_CODE_TDB_TABLE_NOT_EXIST != code) {
×
739
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
740
                __FILE__, __LINE__, tstrerror(code), version, pReq->name);
741
    }
742
    TAOS_RETURN(code);
×
743
  }
744

745
  if (pReq->suid == pReq->uid) {
1,614,585✔
746
    code = TSDB_CODE_INVALID_PARA;
×
747
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
748
              __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
749
    TAOS_RETURN(code);
×
750
  }
751

752
  SMetaEntry entry = {
1,614,585✔
753
      .version = version,
754
      .uid = pReq->uid,
1,614,585✔
755
  };
756

757
  if (pReq->isVirtual) {
1,614,585✔
758
    if (pReq->suid == 0) {
71,469✔
759
      entry.type = -TSDB_VIRTUAL_NORMAL_TABLE;
40,087✔
760
    } else {
761
      entry.type = -TSDB_VIRTUAL_CHILD_TABLE;
31,382✔
762
    }
763
  } else {
764
    if (pReq->suid == 0) {
1,543,116✔
765
      entry.type = -TSDB_NORMAL_TABLE;
836,160✔
766
    } else {
767
      entry.type = -TSDB_CHILD_TABLE;
706,956✔
768
    }
769
  }
770
  code = metaHandleEntry2(pMeta, &entry);
1,614,585✔
771
  if (code) {
1,614,585✔
772
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
773
              __func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
774
  } else {
775
    metaInfo("vgId:%d, table %s uid %" PRId64 " is dropped, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
1,614,585✔
776
             pReq->uid, version);
777
  }
778
  TAOS_RETURN(code);
1,614,585✔
779
}
780

781
static int32_t metaCheckAlterTableColumnReq(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
4,485,346✔
782
  int32_t code = 0;
4,485,346✔
783

784
  if (NULL == pReq->colName || strlen(pReq->colName) == 0) {
4,485,346✔
785
    metaError("vgId:%d, %s failed at %s:%d since invalid column name:%s, version:%" PRId64, TD_VID(pMeta->pVnode),
×
786
              __func__, __FILE__, __LINE__, pReq->colName, version);
787
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
788
  }
789

790
  // check name
791
  void   *value = NULL;
4,485,346✔
792
  int32_t valueSize = 0;
4,485,346✔
793
  code = tdbTbGet(pMeta->pNameIdx, pReq->tbName, strlen(pReq->tbName) + 1, &value, &valueSize);
4,485,346✔
794
  if (code) {
4,485,346✔
795
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
796
              __FILE__, __LINE__, pReq->tbName, version);
797
    code = TSDB_CODE_TDB_TABLE_NOT_EXIST;
×
798
    TAOS_RETURN(code);
×
799
  }
800
  int64_t uid = *(int64_t *)value;
4,485,346✔
801
  tdbFreeClear(value);
4,485,346✔
802

803
  // check table type
804
  SMetaInfo info;
4,485,118✔
805
  if (metaGetInfo(pMeta, uid, &info, NULL) != 0) {
4,485,346✔
806
    metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64
×
807
              " not found, this is an internal error in meta, version:%" PRId64,
808
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, uid, version);
809
    code = TSDB_CODE_INTERNAL_ERROR;
×
810
    TAOS_RETURN(code);
×
811
  }
812
  if (info.suid != 0 && pReq->action != TSDB_ALTER_TABLE_ALTER_COLUMN_REF &&
4,485,346✔
813
      pReq->action != TSDB_ALTER_TABLE_REMOVE_COLUMN_REF) {
29,885✔
814
    metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not a normal table, version:%" PRId64,
×
815
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, uid, version);
816
    code = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
817
    TAOS_RETURN(code);
×
818
  }
819

820
  // check grant
821
  code = grantCheck(TSDB_GRANT_TIMESERIES);
4,485,346✔
822
  if (code) {
4,485,346✔
823
    metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
×
824
              __FILE__, __LINE__, tstrerror(code), version, pReq->tbName);
825
    TAOS_RETURN(code);
×
826
  }
827
  TAOS_RETURN(code);
4,485,346✔
828
}
829

830
int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
3,712,462✔
831
  int32_t code = TSDB_CODE_SUCCESS;
3,712,462✔
832

833
  // check request
834
  code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
3,712,462✔
835
  if (code) {
3,712,462✔
836
    TAOS_RETURN(code);
×
837
  }
838

839
  // fetch old entry
840
  SMetaEntry *pEntry = NULL;
3,712,462✔
841
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
3,712,462✔
842
  if (code) {
3,712,462✔
843
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
844
              __FILE__, __LINE__, pReq->tbName, version);
845
    TAOS_RETURN(code);
×
846
  }
847
  if (pEntry->version >= version) {
3,712,462✔
848
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
849
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
850
    metaFetchEntryFree(&pEntry);
×
851
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
852
  }
853

854
  // do add column
855
  int32_t         rowSize = 0;
3,712,462✔
856
  SSchemaWrapper *pSchema = &pEntry->ntbEntry.schemaRow;
3,712,462✔
857
  SSchema        *pColumn;
858
  SExtSchema      extSchema = {0};
3,712,462✔
859
  pEntry->version = version;
3,712,462✔
860
  for (int32_t i = 0; i < pSchema->nCols; i++) {
2,147,483,647✔
861
    pColumn = &pSchema->pSchema[i];
2,147,483,647✔
862
    if (strncmp(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
2,147,483,647✔
863
      metaError("vgId:%d, %s failed at %s:%d since column %s already exists in table %s, version:%" PRId64,
328,238✔
864
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colName, pReq->tbName, version);
865
      metaFetchEntryFree(&pEntry);
328,238✔
866
      TAOS_RETURN(TSDB_CODE_VND_COL_ALREADY_EXISTS);
328,238✔
867
    }
868
    rowSize += pColumn->bytes;
2,147,483,647✔
869
  }
870

871
  int32_t maxBytesPerRow = pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE ? TSDB_MAX_BYTES_PER_ROW_VIRTUAL : TSDB_MAX_BYTES_PER_ROW;
3,384,224✔
872
  if (rowSize + pReq->bytes > maxBytesPerRow) {
3,384,224✔
873
    metaError("vgId:%d, %s failed at %s:%d since row size %d + %d > %d, version:%" PRId64, TD_VID(pMeta->pVnode),
6,740✔
874
              __func__, __FILE__, __LINE__, rowSize, pReq->bytes, maxBytesPerRow, version);
875
    metaFetchEntryFree(&pEntry);
6,740✔
876
    TAOS_RETURN(TSDB_CODE_PAR_INVALID_ROW_LENGTH);
6,740✔
877
  }
878

879
  int32_t maxCols = pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE ? TSDB_MAX_COLUMNS : TSDB_MAX_COLUMNS_NON_VIRTUAL;
3,377,484✔
880
  if (pSchema->nCols + 1 > maxCols) {
3,377,484✔
881
    metaError("vgId:%d, %s failed at %s:%d since column count %d + 1 > %d, version:%" PRId64, TD_VID(pMeta->pVnode),
×
882
              __func__, __FILE__, __LINE__, pSchema->nCols, maxCols, version);
883
    metaFetchEntryFree(&pEntry);
×
884
    TAOS_RETURN(TSDB_CODE_PAR_TOO_MANY_COLUMNS);
×
885
  }
886

887
  SSchema *pNewSchema = taosMemoryRealloc(pSchema->pSchema, sizeof(SSchema) * (pSchema->nCols + 1));
3,377,484✔
888
  if (NULL == pNewSchema) {
3,377,484✔
889
    metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
890
              __LINE__, tstrerror(terrno), version);
891
    metaFetchEntryFree(&pEntry);
×
892
    TAOS_RETURN(terrno);
×
893
  }
894
  pSchema->pSchema = pNewSchema;
3,377,484✔
895
  pSchema->version++;
3,377,484✔
896
  pSchema->nCols++;
3,377,484✔
897
  pColumn = &pSchema->pSchema[pSchema->nCols - 1];
3,377,484✔
898
  pColumn->bytes = pReq->bytes;
3,377,484✔
899
  pColumn->type = pReq->type;
3,377,484✔
900
  pColumn->flags = pReq->flags;
3,377,484✔
901
  if (pEntry->ntbEntry.ncid > INT16_MAX) {
3,377,484✔
902
    metaError("vgId:%d, %s failed at %s:%d since column id %d exceeds max column id %d, version:%" PRId64,
573✔
903
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ntbEntry.ncid, INT16_MAX,
904
              version);
905
    metaFetchEntryFree(&pEntry);
573✔
906
    TAOS_RETURN(TSDB_CODE_VND_EXCEED_MAX_COL_ID);
573✔
907
  }
908
  pColumn->colId = pEntry->ntbEntry.ncid++;
3,376,911✔
909
  extSchema.typeMod = pReq->typeMod;
3,376,911✔
910
  tstrncpy(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN);
3,376,911✔
911
  if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
3,376,911✔
912
    SColRef tmpRef;
57,707✔
913
    if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
57,764✔
914
      tmpRef.hasRef = false;
33,308✔
915
      tmpRef.id = pColumn->colId;
33,308✔
916
    } else {
917
      tmpRef.hasRef = true;
24,456✔
918
      tmpRef.id = pColumn->colId;
24,456✔
919
      tstrncpy(tmpRef.refDbName, pReq->refDbName, TSDB_DB_NAME_LEN);
24,456✔
920
      tstrncpy(tmpRef.refTableName, pReq->refTbName, TSDB_TABLE_NAME_LEN);
24,456✔
921
      tstrncpy(tmpRef.refColName, pReq->refColName, TSDB_COL_NAME_LEN);
24,456✔
922
    }
923
    code = updataTableColRef(&pEntry->colRef, pColumn, 1, &tmpRef);
57,764✔
924
    if (code) {
57,764✔
925
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
926
                __LINE__, tstrerror(code), version);
927
      metaFetchEntryFree(&pEntry);
×
928
      TAOS_RETURN(code);
×
929
    }
930
  } else {
931
    uint32_t compress;
932
    if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
3,319,147✔
933
      compress = createDefaultColCmprByType(pColumn->type);
3,311,942✔
934
    } else {
935
      compress = pReq->compress;
7,205✔
936
    }
937
    code = updataTableColCmpr(&pEntry->colCmpr, pColumn, 1, compress);
3,319,147✔
938
    if (code) {
3,319,147✔
939
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
940
                __LINE__, tstrerror(code), version);
941
      metaFetchEntryFree(&pEntry);
×
942
      TAOS_RETURN(code);
×
943
    }
944
  }
945
  code = addTableExtSchema(pEntry, pColumn, pSchema->nCols, &extSchema);
3,376,911✔
946
  if (code) {
3,376,911✔
947
    metaError("vgId:%d, %s failed to add ext schema at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode),
×
948
              __func__, __FILE__, __LINE__, tstrerror(code), version);
949
    metaFetchEntryFree(&pEntry);
×
950
    TAOS_RETURN(code);
×
951
  }
952

953
  // do handle entry
954
  code = metaHandleEntry2(pMeta, pEntry);
3,376,911✔
955
  if (code) {
3,376,911✔
956
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
957
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
958
    metaFetchEntryFree(&pEntry);
×
959
    TAOS_RETURN(code);
×
960
  } else {
961
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
3,376,911✔
962
             pEntry->uid, version);
963
  }
964

965
  if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
3,376,911✔
966
    code = metaUpdateVtbMetaRsp(pEntry, pReq->tbName, pSchema, &pEntry->colRef, pEntry->pExtSchemas,
57,764✔
967
                                pEntry->ntbEntry.ownerId, pRsp, pEntry->type);
57,764✔
968
    if (code) {
57,764✔
969
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
970
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
971
    } else {
972
      for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
19,198,913✔
973
        SColRef *p = &pEntry->colRef.pColRef[i];
19,141,149✔
974
        pRsp->pColRefs[i].hasRef = p->hasRef;
19,141,149✔
975
        pRsp->pColRefs[i].id = p->id;
19,141,149✔
976
        if (p->hasRef) {
19,141,149✔
977
          tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
184,516✔
978
          tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
184,516✔
979
          tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
184,516✔
980
        }
981
      }
982
    }
983
  } else {
984
    code = metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pEntry->ntbEntry.ownerId, pRsp);
3,319,147✔
985
    if (code) {
3,319,147✔
986
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
987
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
988
    } else {
989
      for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
2,147,483,647✔
990
        SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
2,147,483,647✔
991
        pRsp->pSchemaExt[i].colId = p->id;
2,147,483,647✔
992
        pRsp->pSchemaExt[i].compress = p->alg;
2,147,483,647✔
993
      }
994
    }
995
  }
996

997
  metaFetchEntryFree(&pEntry);
3,376,911✔
998
  TAOS_RETURN(code);
3,376,911✔
999
}
1000

1001
int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
102,988✔
1002
  int32_t code = TSDB_CODE_SUCCESS;
102,988✔
1003

1004
  // check request
1005
  code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
102,988✔
1006
  if (code) {
102,988✔
1007
    TAOS_RETURN(code);
×
1008
  }
1009

1010
  // fetch old entry
1011
  SMetaEntry *pEntry = NULL;
102,988✔
1012
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
102,988✔
1013
  if (code) {
102,988✔
1014
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
1015
              __FILE__, __LINE__, pReq->tbName, version);
1016
    TAOS_RETURN(code);
×
1017
  }
1018

1019
  if (pEntry->version >= version) {
102,988✔
1020
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
1021
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
1022
    metaFetchEntryFree(&pEntry);
×
1023
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
1024
  }
1025

1026
  // search the column to drop
1027
  SSchemaWrapper *pSchema = &pEntry->ntbEntry.schemaRow;
102,988✔
1028
  SSchema        *pColumn = NULL;
102,988✔
1029
  SSchema         tColumn;
102,874✔
1030
  int32_t         iColumn = 0;
102,988✔
1031
  for (; iColumn < pSchema->nCols; iColumn++) {
83,937,628✔
1032
    pColumn = &pSchema->pSchema[iColumn];
83,937,628✔
1033
    if (strncmp(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
83,937,628✔
1034
      break;
102,988✔
1035
    }
1036
  }
1037

1038
  if (iColumn == pSchema->nCols) {
102,988✔
1039
    metaError("vgId:%d, %s failed at %s:%d since column %s not found in table %s, version:%" PRId64,
×
1040
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colName, pReq->tbName, version);
1041
    metaFetchEntryFree(&pEntry);
×
1042
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
1043
  }
1044

1045
  if (pColumn->colId == 0 || pColumn->flags & COL_IS_KEY) {
102,988✔
1046
    metaError("vgId:%d, %s failed at %s:%d since column %s is primary key, version:%" PRId64, TD_VID(pMeta->pVnode),
×
1047
              __func__, __FILE__, __LINE__, pReq->colName, version);
1048
    metaFetchEntryFree(&pEntry);
×
1049
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
1050
  }
1051

1052
  tColumn = *pColumn;
102,988✔
1053

1054
  // do drop column
1055
  pEntry->version = version;
102,988✔
1056
  if (pSchema->nCols - iColumn - 1 > 0) {
102,988✔
1057
    memmove(pColumn, pColumn + 1, (pSchema->nCols - iColumn - 1) * sizeof(SSchema));
79,772✔
1058
  }
1059
  pSchema->nCols--;
102,988✔
1060
  pSchema->version++;
102,988✔
1061
  if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
102,988✔
1062
    code = updataTableColRef(&pEntry->colRef, &tColumn, 0, NULL);
31,568✔
1063
    if (code) {
31,568✔
1064
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
1065
                __LINE__, tstrerror(code), version);
1066
      metaFetchEntryFree(&pEntry);
×
1067
      TAOS_RETURN(code);
×
1068
    }
1069
    if (pEntry->colRef.nCols != pSchema->nCols) {
31,568✔
1070
      metaError("vgId:%d, %s failed at %s:%d since column count mismatch, version:%" PRId64, TD_VID(pMeta->pVnode),
×
1071
                __func__, __FILE__, __LINE__, version);
1072
      metaFetchEntryFree(&pEntry);
×
1073
      TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
1074
    }
1075
  } else {
1076
    code = updataTableColCmpr(&pEntry->colCmpr, &tColumn, 0, 0);
71,420✔
1077
    if (code) {
71,420✔
1078
      metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
1079
                __LINE__, tstrerror(code), version);
1080
      metaFetchEntryFree(&pEntry);
×
1081
      TAOS_RETURN(code);
×
1082
    }
1083
    if (pEntry->colCmpr.nCols != pSchema->nCols) {
71,420✔
1084
      metaError("vgId:%d, %s failed at %s:%d since column count mismatch, version:%" PRId64, TD_VID(pMeta->pVnode),
×
1085
                __func__, __FILE__, __LINE__, version);
1086
      metaFetchEntryFree(&pEntry);
×
1087
      TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
1088
    }
1089
  }
1090

1091
  // update column extschema
1092
  code = dropTableExtSchema(pEntry, iColumn, pSchema->nCols);
102,988✔
1093
  if (code) {
102,988✔
1094
    metaError("vgId:%d, %s failed to remove extschema at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode),
×
1095
              __func__, __FILE__, __LINE__, tstrerror(code), version);
1096
    metaFetchEntryFree(&pEntry);
×
1097
    TAOS_RETURN(code);
×
1098
  }
1099

1100
  // do handle entry
1101
  code = metaHandleEntry2(pMeta, pEntry);
102,988✔
1102
  if (code) {
102,988✔
1103
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1104
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1105
    metaFetchEntryFree(&pEntry);
×
1106
    TAOS_RETURN(code);
×
1107
  } else {
1108
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
102,988✔
1109
             pEntry->uid, version);
1110
  }
1111

1112
  // build response
1113
  if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
102,988✔
1114
    code = metaUpdateVtbMetaRsp(pEntry, pReq->tbName, pSchema, &pEntry->colRef, pEntry->pExtSchemas,
31,568✔
1115
                                pEntry->ntbEntry.ownerId, pRsp, pEntry->type);
31,568✔
1116
    if (code) {
31,568✔
1117
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1118
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1119
    } else {
1120
      for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
37,750,979✔
1121
        SColRef *p = &pEntry->colRef.pColRef[i];
37,719,411✔
1122
        pRsp->pColRefs[i].hasRef = p->hasRef;
37,719,411✔
1123
        pRsp->pColRefs[i].id = p->id;
37,719,411✔
1124
        if (p->hasRef) {
37,719,411✔
1125
          tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
18,873,847✔
1126
          tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
18,873,847✔
1127
          tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
18,873,847✔
1128
        }
1129
      }
1130
    }
1131
  } else {
1132
    code = metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pEntry->ntbEntry.ownerId, pRsp);
71,420✔
1133
    if (code) {
71,420✔
1134
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1135
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1136
    } else {
1137
      for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
87,092,426✔
1138
        SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
87,021,006✔
1139
        pRsp->pSchemaExt[i].colId = p->id;
87,021,006✔
1140
        pRsp->pSchemaExt[i].compress = p->alg;
87,021,006✔
1141
      }
1142
    }
1143
  }
1144

1145
  metaFetchEntryFree(&pEntry);
102,988✔
1146
  TAOS_RETURN(code);
102,988✔
1147
}
1148

1149
int32_t metaAlterTableColumnName(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
41,740✔
1150
  int32_t code = TSDB_CODE_SUCCESS;
41,740✔
1151

1152
  // check request
1153
  code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
41,740✔
1154
  if (code) {
41,740✔
1155
    TAOS_RETURN(code);
×
1156
  }
1157

1158
  if (NULL == pReq->colNewName) {
41,740✔
1159
    metaError("vgId:%d, %s failed at %s:%d since invalid new column name, version:%" PRId64, TD_VID(pMeta->pVnode),
×
1160
              __func__, __FILE__, __LINE__, version);
1161
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
1162
  }
1163

1164
  // fetch old entry
1165
  SMetaEntry *pEntry = NULL;
41,740✔
1166
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
41,740✔
1167
  if (code) {
41,740✔
1168
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
1169
              __FILE__, __LINE__, pReq->tbName, version);
1170
    TAOS_RETURN(code);
×
1171
  }
1172

1173
  if (pEntry->version >= version) {
41,740✔
1174
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
1175
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
1176
    metaFetchEntryFree(&pEntry);
×
1177
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
1178
  }
1179

1180
  // search the column to update
1181
  SSchemaWrapper *pSchema = &pEntry->ntbEntry.schemaRow;
41,740✔
1182
  SSchema        *pColumn = NULL;
41,740✔
1183
  int32_t         iColumn = 0;
41,740✔
1184
  for (int32_t i = 0; i < pSchema->nCols; i++) {
195,106✔
1185
    if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
195,106✔
1186
      pColumn = &pSchema->pSchema[i];
41,740✔
1187
      iColumn = i;
41,740✔
1188
      break;
41,740✔
1189
    }
1190
  }
1191

1192
  if (NULL == pColumn) {
41,740✔
1193
    metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
×
1194
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colId, pReq->tbName, version);
1195
    metaFetchEntryFree(&pEntry);
×
1196
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
1197
  }
1198

1199

1200
  // do update column name
1201
  pEntry->version = version;
41,740✔
1202
  tstrncpy(pColumn->name, pReq->colNewName, TSDB_COL_NAME_LEN);
41,740✔
1203
  pSchema->version++;
41,740✔
1204

1205
  // do handle entry
1206
  code = metaHandleEntry2(pMeta, pEntry);
41,740✔
1207
  if (code) {
41,740✔
1208
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1209
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1210
    metaFetchEntryFree(&pEntry);
×
1211
    TAOS_RETURN(code);
×
1212
  } else {
1213
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
41,740✔
1214
             pEntry->uid, version);
1215
  }
1216

1217
  // build response
1218
  if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
41,740✔
1219
    code = metaUpdateVtbMetaRsp(pEntry, pReq->tbName, pSchema, &pEntry->colRef, pEntry->pExtSchemas,
28,754✔
1220
                                pEntry->ntbEntry.ownerId, pRsp, pEntry->type);
28,754✔
1221
    if (code) {
28,754✔
1222
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1223
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1224
    } else {
1225
      for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
203,184✔
1226
        SColRef *p = &pEntry->colRef.pColRef[i];
174,430✔
1227
        pRsp->pColRefs[i].hasRef = p->hasRef;
174,430✔
1228
        pRsp->pColRefs[i].id = p->id;
174,430✔
1229
        if (p->hasRef) {
174,430✔
1230
          tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
107,654✔
1231
          tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
107,654✔
1232
          tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
107,654✔
1233
        }
1234
      }
1235
    }
1236
  } else {
1237
    code = metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pEntry->ntbEntry.ownerId, pRsp);
12,986✔
1238
    if (code) {
12,986✔
1239
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1240
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1241
    } else {
1242
      for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
165,400✔
1243
        SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
152,414✔
1244
        pRsp->pSchemaExt[i].colId = p->id;
152,414✔
1245
        pRsp->pSchemaExt[i].compress = p->alg;
152,414✔
1246
      }
1247
    }
1248
  }
1249

1250
  metaFetchEntryFree(&pEntry);
41,740✔
1251
  TAOS_RETURN(code);
41,740✔
1252
}
1253

1254
int32_t metaAlterTableColumnBytes(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
487,213✔
1255
  int32_t code = TSDB_CODE_SUCCESS;
487,213✔
1256

1257
  // check request
1258
  code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
487,213✔
1259
  if (code) {
487,213✔
1260
    TAOS_RETURN(code);
×
1261
  }
1262

1263
  // fetch old entry
1264
  SMetaEntry *pEntry = NULL;
487,213✔
1265
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
487,213✔
1266
  if (code) {
487,213✔
1267
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
1268
              __FILE__, __LINE__, pReq->tbName, version);
1269
    TAOS_RETURN(code);
×
1270
  }
1271

1272
  if (pEntry->version >= version) {
487,213✔
1273
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
1274
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
1275
    metaFetchEntryFree(&pEntry);
×
1276
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
1277
  }
1278

1279
  // search the column to update
1280
  SSchemaWrapper *pSchema = &pEntry->ntbEntry.schemaRow;
487,213✔
1281
  SSchema        *pColumn = NULL;
487,213✔
1282
  int32_t         iColumn = 0;
487,213✔
1283
  int32_t         rowSize = 0;
487,213✔
1284
  for (int32_t i = 0; i < pSchema->nCols; i++) {
37,978,815✔
1285
    if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
37,491,602✔
1286
      pColumn = &pSchema->pSchema[i];
487,213✔
1287
      iColumn = i;
487,213✔
1288
    }
1289
    rowSize += pSchema->pSchema[i].bytes;
37,491,602✔
1290
  }
1291

1292
  if (NULL == pColumn) {
487,213✔
1293
    metaError("vgId:%d, %s failed at %s:%d since column %s not found in table %s, version:%" PRId64,
×
1294
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colName, pReq->tbName, version);
1295
    metaFetchEntryFree(&pEntry);
×
1296
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
1297
  }
1298

1299
  if (!IS_VAR_DATA_TYPE(pColumn->type) || pColumn->bytes >= pReq->colModBytes) {
487,213✔
1300
    metaError("vgId:%d, %s failed at %s:%d since column %s is not var data type or bytes %d >= %d, version:%" PRId64,
181,980✔
1301
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colName, pColumn->bytes, pReq->colModBytes,
1302
              version);
1303
    metaFetchEntryFree(&pEntry);
181,980✔
1304
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
181,980✔
1305
  }
1306

1307
  int32_t maxBytesPerRow = pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE ? TSDB_MAX_BYTES_PER_ROW_VIRTUAL : TSDB_MAX_BYTES_PER_ROW;
305,233✔
1308
  if (rowSize + pReq->colModBytes - pColumn->bytes > maxBytesPerRow) {
305,233✔
1309
    metaError("vgId:%d, %s failed at %s:%d since row size %d + %d - %d > %d, version:%" PRId64, TD_VID(pMeta->pVnode),
47,180✔
1310
              __func__, __FILE__, __LINE__, rowSize, pReq->colModBytes, pColumn->bytes, maxBytesPerRow,
1311
              version);
1312
    metaFetchEntryFree(&pEntry);
47,180✔
1313
    TAOS_RETURN(TSDB_CODE_PAR_INVALID_ROW_LENGTH);
47,180✔
1314
  }
1315

1316
  // do change the column bytes
1317
  pEntry->version = version;
258,053✔
1318
  pSchema->version++;
258,053✔
1319
  pColumn->bytes = pReq->colModBytes;
258,053✔
1320

1321
  // do handle entry
1322
  code = metaHandleEntry2(pMeta, pEntry);
258,053✔
1323
  if (code) {
258,053✔
1324
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1325
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1326
    metaFetchEntryFree(&pEntry);
×
1327
    TAOS_RETURN(code);
×
1328
  } else {
1329
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
258,053✔
1330
             pEntry->uid, version);
1331
  }
1332

1333
  // build response
1334
  if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
258,053✔
1335
    code = metaUpdateVtbMetaRsp(pEntry, pReq->tbName, pSchema, &pEntry->colRef, pEntry->pExtSchemas,
27,923✔
1336
                                pEntry->ntbEntry.ownerId, pRsp, pEntry->type);
27,923✔
1337
    if (code) {
27,923✔
1338
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1339
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1340
    } else {
1341
      for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
18,965,925✔
1342
        SColRef *p = &pEntry->colRef.pColRef[i];
18,938,002✔
1343
        pRsp->pColRefs[i].hasRef = p->hasRef;
18,938,002✔
1344
        pRsp->pColRefs[i].id = p->id;
18,938,002✔
1345
        if (p->hasRef) {
18,938,002✔
1346
          tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
81,428✔
1347
          tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
81,428✔
1348
          tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
81,428✔
1349
        }
1350
      }
1351
    }
1352
  } else {
1353
    code = metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pEntry->ntbEntry.ownerId, pRsp);
230,130✔
1354
    if (code) {
230,130✔
1355
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
1356
                __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
1357
    } else {
1358
      for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
9,388,170✔
1359
        SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
9,158,040✔
1360
        pRsp->pSchemaExt[i].colId = p->id;
9,158,040✔
1361
        pRsp->pSchemaExt[i].compress = p->alg;
9,158,040✔
1362
      }
1363
    }
1364
  }
1365

1366
  metaFetchEntryFree(&pEntry);
258,053✔
1367
  TAOS_RETURN(code);
258,053✔
1368
}
1369

1370

1371

1372
static bool tagValueChanged(const SUpdatedTagVal* pNewVal, const STag *pOldTag) {
8,391,798✔
1373
  STagVal oldVal = { .cid = pNewVal->colId };
8,391,798✔
1374

1375
  if (pNewVal->isNull) {
8,391,798✔
1376
    return tTagGet(pOldTag, &oldVal);
70,431✔
1377
  }
1378

1379
  if (!tTagGet(pOldTag, &oldVal)){
8,321,367✔
1380
    return true;
204,250✔
1381
  }
1382

1383
  if (!IS_VAR_DATA_TYPE(oldVal.type)) {
8,117,117✔
1384
    return (memcmp(&oldVal.i64, pNewVal->pTagVal, pNewVal->nTagVal) != 0);
7,880,065✔
1385
  }
1386

1387
  if (oldVal.nData != pNewVal->nTagVal) {
237,052✔
1388
    return true;
179,879✔
1389
  }
1390

1391
  return (memcmp(pNewVal->pTagVal, oldVal.pData, oldVal.nData) != 0);
57,173✔
1392
}
1393

1394

1395

1396
static int32_t updatedTagValueArrayToHashMap(SSchemaWrapper* pTagSchema, SArray* arr, SHashObj **hashMap) {
8,220,530✔
1397
  int32_t numOfTags = arr == NULL ? 0 : taosArrayGetSize(arr);
8,220,530✔
1398
  if (numOfTags == 0) {
8,220,530✔
1399
    metaError("%s failed at %s:%d since no tags specified", __func__, __FILE__, __LINE__);
×
1400
    return TSDB_CODE_INVALID_MSG;
×
1401
  }
1402

1403
  *hashMap = taosHashInit(numOfTags, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
8,220,530✔
1404
  if (*hashMap == NULL) {
8,220,530✔
1405
    metaError("%s failed at %s:%d since %s", __func__, __FILE__, __LINE__, tstrerror(terrno));
×
1406
    return terrno;
×
1407
  }
1408

1409
  for (int32_t i = 0; i < taosArrayGetSize(arr); i++) {
16,509,596✔
1410
    SUpdatedTagVal *pTagVal = taosArrayGet(arr, i);
8,289,689✔
1411
    if (taosHashGet(*hashMap, &pTagVal->colId, sizeof(pTagVal->colId)) != NULL) {
8,289,689✔
1412
      metaError("%s failed at %s:%d since duplicate tags %s", __func__, __FILE__, __LINE__, pTagVal->tagName);
×
1413
      taosHashCleanup(*hashMap);
×
1414
      return TSDB_CODE_INVALID_MSG;
×
1415
    }
1416

1417
    int32_t code = taosHashPut(*hashMap, &pTagVal->colId, sizeof(pTagVal->colId), pTagVal, sizeof(*pTagVal));
8,290,383✔
1418
    if (code) {
8,289,066✔
1419
      metaError("%s failed at %s:%d since %s", __func__, __FILE__, __LINE__, tstrerror(code));
×
1420
      taosHashCleanup(*hashMap);
×
1421
      return code;
×
1422
    }
1423
  }
1424

1425
  int32_t changed = 0;
8,219,907✔
1426
  for (int32_t i = 0; i < pTagSchema->nCols; i++) {
17,777,349✔
1427
    int32_t schemaColId = pTagSchema->pSchema[i].colId;
9,557,442✔
1428
    if (taosHashGet(*hashMap, &schemaColId, sizeof(schemaColId)) != NULL) {
9,557,442✔
1429
      changed++;
8,290,383✔
1430
    }
1431
  }
1432
  if (changed < numOfTags) {
8,220,530✔
1433
    metaError("%s failed at %s:%d since tag count mismatch, %d:%d", __func__, __FILE__, __LINE__, changed, numOfTags);
×
1434
    taosHashCleanup(*hashMap);
×
1435
    return TSDB_CODE_VND_COL_NOT_EXISTS;
×
1436
  }
1437

1438
  return TSDB_CODE_SUCCESS;
8,220,530✔
1439
}
1440

1441

1442

1443
static int32_t metaUpdateTableJsonTagValue(SMeta* pMeta, SMetaEntry* pTable, SSchemaWrapper* pTagSchema, SHashObj* pUpdatedTagVals) {
125,109✔
1444
  SSchema *pCol = &pTagSchema->pSchema[0];
125,109✔
1445
  int32_t colId = pCol->colId;
125,109✔
1446
  SUpdatedTagVal *pTagVal = taosHashGet(pUpdatedTagVals, &colId, sizeof(colId));
125,109✔
1447
  void *pNewTag = taosMemoryRealloc(pTable->ctbEntry.pTags, pTagVal->nTagVal);
125,109✔
1448
  if (pNewTag == NULL) {
125,109✔
1449
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1450
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(terrno), pTable->version);
×
1451
    return TSDB_CODE_OUT_OF_MEMORY;
×
1452
  }
1453
  pTable->ctbEntry.pTags = pNewTag;
125,109✔
1454
  memcpy(pTable->ctbEntry.pTags, pTagVal->pTagVal, pTagVal->nTagVal);
125,109✔
1455

1456
  int32_t code = metaHandleEntry2(pMeta, pTable);
125,109✔
1457
  if (code) {
125,109✔
1458
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64;
×
1459
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), pTable->uid, pTable->name, pTable->version);
×
1460
  } else {
1461
    const char* msgFmt = "vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64;
125,109✔
1462
    metaInfo(msgFmt, TD_VID(pMeta->pVnode), pTable->name, pTable->uid, pTable->version);
125,109✔
1463
  }
1464

1465
  return code;
125,109✔
1466
}
1467

1468

1469

1470
static int32_t metaUpdateTableNormalTagValue(SMeta* pMeta, SMetaEntry* pTable, SSchemaWrapper* pTagSchema, SHashObj* pUpdatedTagVals) {
8,324,579✔
1471
  int32_t code = TSDB_CODE_SUCCESS;
8,324,579✔
1472

1473
  const STag *pOldTag = (const STag *)pTable->ctbEntry.pTags;
8,324,579✔
1474
  SArray     *pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
8,324,579✔
1475
  if (pTagArray == NULL) {
8,324,579✔
1476
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1477
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(terrno), pTable->version);
×
1478
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
1479
  }
1480

1481
  bool allSame = true;
8,324,579✔
1482

1483
  for (int32_t i = 0; i < pTagSchema->nCols; i++) {
18,165,182✔
1484
    SSchema *pCol = &pTagSchema->pSchema[i];
9,844,554✔
1485
    STagVal  value = { .cid = pCol->colId };
9,844,554✔
1486

1487
    int32_t colId = pCol->colId;
9,844,554✔
1488
    SUpdatedTagVal *pNewVal = taosHashGet(pUpdatedTagVals, &colId, sizeof(colId));
9,844,554✔
1489
    if (pNewVal == NULL) {
9,844,554✔
1490
      if (!tTagGet(pOldTag, &value)) {
1,452,756✔
1491
        continue;
301,260✔
1492
      }
1493
    } else {
1494
      value.type = pCol->type;
8,391,798✔
1495
      if (tagValueChanged(pNewVal, pOldTag)) {
8,391,798✔
1496
        allSame = false;
8,228,860✔
1497
      }
1498
      if (pNewVal->isNull) {
8,391,175✔
1499
        continue;
70,431✔
1500
      }
1501

1502
      if (IS_VAR_DATA_TYPE(pCol->type)) {
8,320,744✔
1503
        if ((int32_t)pNewVal->nTagVal > (pCol->bytes - VARSTR_HEADER_SIZE)) {
325,173✔
1504
          const char* msgFmt = "vgId:%d, %s failed at %s:%d since value too long for tag %s, version:%" PRId64;
3,951✔
1505
          metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pCol->name, pTable->version);
3,951✔
1506
          taosArrayDestroy(pTagArray);
3,951✔
1507
          TAOS_RETURN(TSDB_CODE_PAR_VALUE_TOO_LONG);
3,951✔
1508
        }
1509
        value.pData = pNewVal->pTagVal;
321,222✔
1510
        value.nData = pNewVal->nTagVal;
321,222✔
1511
      } else {
1512
        memcpy(&value.i64, pNewVal->pTagVal, pNewVal->nTagVal);
7,996,194✔
1513
      }
1514
    }
1515

1516
    if (taosArrayPush(pTagArray, &value) == NULL) {
9,468,912✔
1517
      const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1518
      metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(terrno), pTable->version);
×
1519
      taosArrayDestroy(pTagArray);
×
1520
      TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
1521
    }
1522
  }
1523

1524
  if (allSame) {
8,320,628✔
1525
    const char* msgFmt = "vgId:%d, %s warn at %s:%d all tags are same, version:%" PRId64;
150,017✔
1526
    metaWarn(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pTable->version);
150,017✔
1527
    taosArrayDestroy(pTagArray);
150,017✔
1528
    TAOS_RETURN(TSDB_CODE_VND_SAME_TAG);
150,017✔
1529
  } 
1530

1531
  STag *pNewTag = NULL;
8,170,611✔
1532
  code = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag);
8,170,611✔
1533
  if (code) {
8,170,611✔
1534
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1535
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), pTable->version);
×
1536
    taosArrayDestroy(pTagArray);
×
1537
    TAOS_RETURN(code);
×
1538
  }
1539
  taosArrayDestroy(pTagArray);
8,170,611✔
1540
  taosMemoryFree(pTable->ctbEntry.pTags);
8,170,611✔
1541
  pTable->ctbEntry.pTags = (uint8_t *)pNewTag;
8,170,611✔
1542
  return TSDB_CODE_SUCCESS;
8,170,611✔
1543
}
1544

1545

1546
static int32_t regexReplaceBuildSubstitution(const char *pReplace, const regmatch_t *pmatch, int32_t nmatch,
13,902✔
1547
                                               const char *cursor, char **ppResult, size_t *pResultLen,
1548
                                               size_t *pResultCap) {
1549
  char  *result = *ppResult;
13,902✔
1550
  size_t resultLen = *pResultLen;
13,902✔
1551
  size_t resultCap = *pResultCap;
13,902✔
1552

1553
  const char *r = pReplace;
13,902✔
1554
  while (*r != '\0') {
202,236✔
1555
    const char *chunk = NULL;
188,334✔
1556
    size_t      chunkLen = 0;
188,334✔
1557

1558
    if (*r == '$' && r[1] >= '0' && r[1] <= '9') {
188,334✔
1559
      int32_t groupIdx = r[1] - '0';
21,072✔
1560
      if (groupIdx < nmatch && pmatch[groupIdx].rm_so != -1) {
21,072✔
1561
        chunk = cursor + pmatch[groupIdx].rm_so;
21,072✔
1562
        chunkLen = (size_t)(pmatch[groupIdx].rm_eo - pmatch[groupIdx].rm_so);
21,072✔
1563
      }
1564
      r += 2;
21,072✔
1565
    } else if (*r == '$' && r[1] == '$') {
167,262✔
1566
      chunk = "$";
×
1567
      chunkLen = 1;
×
1568
      r += 2;
×
1569
    } else {
1570
      chunk = r;
167,262✔
1571
      chunkLen = 1;
167,262✔
1572
      r += 1;
167,262✔
1573
    }
1574

1575
    if (chunkLen > 0) {
188,334✔
1576
      if (resultLen + chunkLen >= resultCap) {
188,334✔
1577
        resultCap = (resultLen + chunkLen) * 2 + 1;
6,000✔
1578
        char *tmp = taosMemoryRealloc(result, resultCap);
6,000✔
1579
        if (NULL == tmp) {
6,000✔
1580
          taosMemoryFree(result);
×
1581
          *ppResult = NULL;
×
1582
          return TSDB_CODE_OUT_OF_MEMORY;
×
1583
        }
1584
        result = tmp;
6,000✔
1585
      }
1586
      (void)memcpy(result + resultLen, chunk, chunkLen);
188,334✔
1587
      resultLen += chunkLen;
188,334✔
1588
    }
1589
  }
1590

1591
  *ppResult = result;
13,902✔
1592
  *pResultLen = resultLen;
13,902✔
1593
  *pResultCap = resultCap;
13,902✔
1594
  return TSDB_CODE_SUCCESS;
13,902✔
1595
}
1596

1597
static int32_t regexReplace(const char *pStr, const char *pPattern, const char *pReplace, char **ppResult) {
15,219✔
1598
  regex_t *regex = NULL;
15,219✔
1599
  int32_t  code = threadGetRegComp(&regex, pPattern);
15,219✔
1600
  if (code != 0) {
15,219✔
1601
    return code;
×
1602
  }
1603

1604
  size_t strLen = strlen(pStr);
15,219✔
1605
  size_t resultCap = strLen + 1;
15,219✔
1606
  size_t resultLen = 0;
15,219✔
1607
  char  *result = taosMemoryMalloc(resultCap);
15,219✔
1608
  if (NULL == result) {
15,219✔
1609
    return TSDB_CODE_OUT_OF_MEMORY;
×
1610
  }
1611

1612
  const int32_t nmatch = 10;
15,219✔
1613
  const char   *cursor = pStr;
15,219✔
1614
  regmatch_t    pmatch[10];
15,219✔
1615
  int32_t       execFlags = 0;
15,219✔
1616

1617
  while (*cursor != '\0') {
29,121✔
1618
    int ret = regexec(regex, cursor, nmatch, pmatch, execFlags);
15,219✔
1619
    if (ret == REG_NOMATCH) {
15,219✔
1620
      break;
1,317✔
1621
    }
1622
    if (ret != 0) {
13,902✔
1623
      taosMemoryFree(result);
×
1624
      return TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR;
×
1625
    }
1626

1627
    size_t prefixLen = (size_t)pmatch[0].rm_so;
13,902✔
1628
    if (resultLen + prefixLen >= resultCap) {
13,902✔
1629
      resultCap = (resultLen + prefixLen) * 2 + 1;
×
1630
      char *tmp = taosMemoryRealloc(result, resultCap);
×
1631
      if (NULL == tmp) {
×
1632
        taosMemoryFree(result);
×
1633
        return TSDB_CODE_OUT_OF_MEMORY;
×
1634
      }
1635
      result = tmp;
×
1636
    }
1637
    (void)memcpy(result + resultLen, cursor, prefixLen);
13,902✔
1638
    resultLen += prefixLen;
13,902✔
1639

1640
    code = regexReplaceBuildSubstitution(pReplace, pmatch, nmatch, cursor, &result, &resultLen, &resultCap);
13,902✔
1641
    if (code != TSDB_CODE_SUCCESS) {
13,902✔
1642
      return code;
×
1643
    }
1644

1645
    if (pmatch[0].rm_so == pmatch[0].rm_eo) {
13,902✔
1646
      if (resultLen + 1 >= resultCap) {
×
1647
        resultCap = resultCap * 2 + 1;
×
1648
        char *tmp = taosMemoryRealloc(result, resultCap);
×
1649
        if (NULL == tmp) {
×
1650
          taosMemoryFree(result);
×
1651
          return TSDB_CODE_OUT_OF_MEMORY;
×
1652
        }
1653
        result = tmp;
×
1654
      }
1655
      result[resultLen++] = cursor[pmatch[0].rm_eo];
×
1656
      cursor += pmatch[0].rm_eo + 1;
×
1657
    } else {
1658
      cursor += pmatch[0].rm_eo;
13,902✔
1659
    }
1660

1661
    execFlags = REG_NOTBOL;
13,902✔
1662
  }
1663

1664
  size_t tailLen = strlen(cursor);
15,219✔
1665
  if (resultLen + tailLen + 1 > resultCap) {
15,219✔
1666
    resultCap = resultLen + tailLen + 1;
×
1667
    char *tmp = taosMemoryRealloc(result, resultCap);
×
1668
    if (NULL == tmp) {
×
1669
      taosMemoryFree(result);
×
1670
      return terrno;
×
1671
    }
1672
    result = tmp;
×
1673
  }
1674
  (void)memcpy(result + resultLen, cursor, tailLen);
15,219✔
1675
  resultLen += tailLen;
15,219✔
1676
  result[resultLen] = '\0';
15,219✔
1677

1678
  *ppResult = result;
15,219✔
1679
  return TSDB_CODE_SUCCESS;
15,219✔
1680
}
1681

1682

1683

1684
static int32_t computeNewTagValViaRegexReplace(const STag* pOldTag, SUpdatedTagVal* pNewVal) {
19,170✔
1685
  STagVal oldTagVal = {.cid = pNewVal->colId};
19,170✔
1686
  if (!tTagGet(pOldTag, &oldTagVal)) {
19,170✔
1687
    pNewVal->isNull = 1;
3,951✔
1688
    pNewVal->pTagVal = NULL;
3,951✔
1689
    pNewVal->nTagVal = 0;
3,951✔
1690
    return TSDB_CODE_SUCCESS;
3,951✔
1691
  }
1692

1693
  bool isNchar = (pNewVal->tagType == TSDB_DATA_TYPE_NCHAR);
15,219✔
1694
  char* oldStr = NULL;
15,219✔
1695

1696
  if (isNchar) {
15,219✔
1697
    // NCHAR is stored as UCS-4, convert to MBS (VARCHAR) for regex processing
1698
    int32_t mbsLen = oldTagVal.nData + 1;
3,951✔
1699
    oldStr = taosMemoryMalloc(mbsLen);
3,951✔
1700
    if (oldStr == NULL) {
3,951✔
1701
      return TSDB_CODE_OUT_OF_MEMORY;
×
1702
    }
1703
    int32_t ret = taosUcs4ToMbs((TdUcs4*)oldTagVal.pData, oldTagVal.nData, oldStr, NULL);
3,951✔
1704
    if (ret < 0) {
3,951✔
1705
      taosMemoryFree(oldStr);
×
1706
      return ret;
×
1707
    }
1708
    oldStr[ret] = '\0';
3,951✔
1709
  } else {
1710
    // VARCHAR: build null-terminated string from old tag value
1711
    oldStr = taosMemoryMalloc(oldTagVal.nData + 1);
11,268✔
1712
    if (oldStr == NULL) {
11,268✔
1713
      return TSDB_CODE_OUT_OF_MEMORY;
×
1714
    }
1715
    memcpy(oldStr, oldTagVal.pData, oldTagVal.nData);
11,268✔
1716
    oldStr[oldTagVal.nData] = '\0';
11,268✔
1717
  }
1718

1719
  char* newStr = NULL;
15,219✔
1720
  int32_t code = regexReplace(oldStr, pNewVal->regexp, pNewVal->replacement, &newStr);
15,219✔
1721
  taosMemoryFree(oldStr);
15,219✔
1722
  if (code != TSDB_CODE_SUCCESS) {
15,219✔
1723
    return code;
×
1724
  }
1725

1726
  if (isNchar) {
15,219✔
1727
    // Convert regex result back from MBS to UCS-4 (NCHAR)
1728
    int32_t newStrLen = (int32_t)strlen(newStr);
3,951✔
1729
    int32_t ucs4BufLen = (newStrLen + 1) * TSDB_NCHAR_SIZE;
3,951✔
1730
    char*   ucs4Buf = taosMemoryMalloc(ucs4BufLen);
3,951✔
1731
    if (ucs4Buf == NULL) {
3,951✔
1732
      taosMemoryFree(newStr);
×
1733
      return TSDB_CODE_OUT_OF_MEMORY;
×
1734
    }
1735

1736
    int32_t ucs4Len = 0;
3,951✔
1737
    bool    cvtOk = taosMbsToUcs4(newStr, newStrLen, (TdUcs4*)ucs4Buf, ucs4BufLen, &ucs4Len, NULL);
3,951✔
1738
    taosMemoryFree(newStr);
3,951✔
1739
    if (!cvtOk) {
3,951✔
1740
      taosMemoryFree(ucs4Buf);
×
1741
      return terrno;
×
1742
    }
1743

1744
    pNewVal->isNull = 0;
3,951✔
1745
    pNewVal->pTagVal = (uint8_t*)ucs4Buf;
3,951✔
1746
    pNewVal->nTagVal = (uint32_t)ucs4Len;
3,951✔
1747
  } else {
1748
    pNewVal->isNull = 0;
11,268✔
1749
    pNewVal->pTagVal = (uint8_t*)newStr;
11,268✔
1750
    pNewVal->nTagVal = (uint32_t)strlen(newStr);
11,268✔
1751
  }
1752

1753
  return TSDB_CODE_SUCCESS;
15,219✔
1754
}
1755

1756

1757

1758
static int32_t metaUpdateTableTagValueImpl(SMeta* pMeta, SMetaEntry* pTable, SSchemaWrapper* pTagSchema, SHashObj* pUpdatedTagVals) {
8,449,688✔
1759
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
8,449,688✔
1760
    return metaUpdateTableJsonTagValue(pMeta, pTable, pTagSchema, pUpdatedTagVals);
125,109✔
1761
  }
1762
  
1763
  int32_t   code = TSDB_CODE_SUCCESS, lino = 0;
8,324,579✔
1764
  SHashObj* pNewTagVals = pUpdatedTagVals;
8,324,579✔
1765
  SArray*   pRegexResults = NULL;
8,324,579✔
1766

1767
  void* pIter = taosHashIterate(pUpdatedTagVals, NULL);
8,324,579✔
1768
  while (pIter) {
16,697,207✔
1769
    SUpdatedTagVal* pVal = (SUpdatedTagVal*)pIter;
8,383,896✔
1770
    if (pVal->regexp != NULL) {
8,383,896✔
1771
      break;
11,268✔
1772
    }
1773
    pIter = taosHashIterate(pUpdatedTagVals, pIter);
8,372,628✔
1774
  }
1775

1776
  // if there are regular expressions, compute new tag values and store in a new hash map to avoid
1777
  // modifying the original tag values which may be reused for computing other tag values
1778
  if (pIter != NULL) {
8,324,579✔
1779
    taosHashCancelIterate(pUpdatedTagVals, pIter);
11,268✔
1780
    pIter = NULL;
11,268✔
1781
    
1782
    int32_t sz = taosHashGetSize(pUpdatedTagVals);
11,268✔
1783
    pNewTagVals = taosHashInit(sz, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
11,268✔
1784
    if (pNewTagVals == NULL) {
11,268✔
1785
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
1786
    }
1787

1788
    pRegexResults = taosArrayInit(sz, sizeof(char*));
11,268✔
1789
    if (pRegexResults == NULL) {
11,268✔
1790
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
1791
    }
1792

1793
    pIter = taosHashIterate(pUpdatedTagVals, NULL);
11,268✔
1794
    while (pIter) {
30,438✔
1795
      int32_t       colId = *(int32_t*)taosHashGetKey(pIter, NULL);
19,170✔
1796
      SUpdatedTagVal newVal = *(SUpdatedTagVal *)pIter;
19,170✔
1797
      pIter = taosHashIterate(pUpdatedTagVals, pIter);
19,170✔
1798

1799
      if (newVal.regexp != NULL) {
19,170✔
1800
        const STag* pOldTag = (const STag*)pTable->ctbEntry.pTags;
19,170✔
1801
        TAOS_CHECK_GOTO(computeNewTagValViaRegexReplace(pOldTag, &newVal), &lino, _exit);
19,170✔
1802

1803
        newVal.regexp = NULL;
19,170✔
1804
        newVal.replacement = NULL;
19,170✔
1805
        if (taosArrayPush(pRegexResults, &newVal.pTagVal) == NULL) {
19,170✔
1806
          TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
1807
        }
1808
      }
1809

1810
      TAOS_CHECK_GOTO(taosHashPut(pNewTagVals, &colId, sizeof(colId), &newVal, sizeof(newVal)), &lino, _exit);
19,170✔
1811
    }
1812
  }
1813

1814
  TAOS_CHECK_GOTO(metaUpdateTableNormalTagValue(pMeta, pTable, pTagSchema, pNewTagVals), &lino, _exit);
8,324,579✔
1815
  TAOS_CHECK_GOTO(metaHandleEntry2(pMeta, pTable), &lino, _exit);
8,170,611✔
1816

1817
_exit:
8,324,579✔
1818
  if (code) {
8,324,579✔
1819
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64;
153,968✔
1820
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, lino, tstrerror(code), pTable->uid, pTable->name, pTable->version);
153,968✔
1821
  } else {
1822
    const char* msgFmt = "vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64;
8,170,611✔
1823
    metaInfo(msgFmt, TD_VID(pMeta->pVnode), pTable->name, pTable->uid, pTable->version);
8,170,611✔
1824
  }
1825

1826
  if (pRegexResults != NULL) {
8,324,579✔
1827
    for (int32_t i = 0; i < taosArrayGetSize(pRegexResults); i++) {
30,438✔
1828
      char** pp = taosArrayGet(pRegexResults, i);
19,170✔
1829
      taosMemoryFree(*pp);
19,170✔
1830
    }
1831
    taosArrayDestroy(pRegexResults);
11,268✔
1832
  }
1833

1834
  if (pNewTagVals != pUpdatedTagVals) {
8,324,579✔
1835
    taosHashCleanup(pNewTagVals);
11,268✔
1836
  }
1837

1838
  if (pIter != NULL) {
8,324,579✔
1839
    taosHashCancelIterate(pUpdatedTagVals, pIter);
×
1840
  }
1841

1842
  TAOS_RETURN(code);
8,324,579✔
1843
}
1844

1845

1846

1847
static int32_t metaUpdateTableTagValue(SMeta *pMeta, int64_t version, const char* tbName, SArray* tags) {
8,160,386✔
1848
  int32_t code = TSDB_CODE_SUCCESS;
8,160,386✔
1849
  SMetaEntry *pChild = NULL;
8,160,386✔
1850
  SMetaEntry *pSuper = NULL;
8,160,386✔
1851
  SHashObj* pUpdatedTagVals = NULL;
8,160,386✔
1852

1853
  // fetch child entry
1854
  code = metaFetchEntryByName(pMeta, tbName, &pChild);
8,160,386✔
1855
  if (code) {
8,160,386✔
1856
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64;
×
1857
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tbName, version);
×
1858
    goto _exit;
×
1859
  }
1860

1861
  if (pChild->type != TSDB_CHILD_TABLE && pChild->type != TSDB_VIRTUAL_CHILD_TABLE) {
8,160,386✔
1862
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since table %s is not a child table, version:%" PRId64;
×
1863
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tbName, version);
×
1864
    code = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
1865
    goto _exit;
×
1866
  }
1867

1868
  // fetch super entry
1869
  code = metaFetchEntryByUid(pMeta, pChild->ctbEntry.suid, &pSuper);
8,160,386✔
1870
  if (code) {
8,160,386✔
1871
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64;
×
1872
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pChild->ctbEntry.suid, version);
×
1873
    code = TSDB_CODE_INTERNAL_ERROR;
×
1874
    goto _exit;
×
1875
  }
1876

1877
  // search the tags to update
1878
  SSchemaWrapper *pTagSchema = &pSuper->stbEntry.schemaTag;
8,160,386✔
1879

1880
  code = updatedTagValueArrayToHashMap(pTagSchema, tags, &pUpdatedTagVals);
8,160,386✔
1881
  if (code) {
8,160,386✔
1882
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1883
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
1884
    goto _exit;
×
1885
  }
1886

1887
  // change tag values
1888
  pChild->version = version;
8,160,386✔
1889
  code = metaUpdateTableTagValueImpl(pMeta, pChild, pTagSchema, pUpdatedTagVals);
8,160,386✔
1890
  if (code) {
8,160,386✔
1891
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, name:%s version:%" PRId64;
147,383✔
1892
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), tbName, version);
147,383✔
1893
    goto _exit;
147,383✔
1894
  }
1895

1896
_exit:
8,160,386✔
1897
  taosHashCleanup(pUpdatedTagVals);
8,160,386✔
1898
  metaFetchEntryFree(&pSuper);
8,160,386✔
1899
  metaFetchEntryFree(&pChild);
8,160,386✔
1900
  TAOS_RETURN(code);
8,160,386✔
1901
}
1902

1903

1904

1905
int32_t metaUpdateTableMultiTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
8,149,080✔
1906
  int32_t code = TSDB_CODE_SUCCESS;
8,149,080✔
1907
  SArray* uidList = NULL;
8,149,080✔
1908
  SArray* tagListArray = NULL;
8,149,080✔
1909

1910
  // Pre-allocate uidList for batch notification
1911
  int32_t nTables = taosArrayGetSize(pReq->tables);
8,149,080✔
1912
  uidList = taosArrayInit(nTables, sizeof(tb_uid_t));
8,149,080✔
1913
  if (uidList == NULL) {
8,149,080✔
1914
    code = terrno;
×
1915
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1916
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
1917
    TAOS_RETURN(code);
×
1918
  }
1919
  tagListArray = taosArrayInit(nTables, sizeof(void*));
8,149,080✔
1920
  if (tagListArray == NULL) {
8,149,080✔
1921
    code = terrno;
×
1922
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1923
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
1924
    TAOS_RETURN(code);
×
1925
  }
1926

1927
  for (int32_t i = 0; i < nTables; i++) {
16,309,466✔
1928
    SUpdateTableTagVal *pTable = taosArrayGet(pReq->tables, i);
8,160,386✔
1929
    code = metaUpdateTableTagValue(pMeta, version, pTable->tbName, pTable->tags);
8,160,386✔
1930
    if (code == TSDB_CODE_VND_SAME_TAG) {
8,160,386✔
1931
      // we are updating multiple tables, if one table has same tag,
1932
      // just skip it and continue to update other tables,
1933
      // and return success at the end
1934
      code = TSDB_CODE_SUCCESS;
147,383✔
1935
    } else if (code) {
8,013,003✔
1936
      break;
×
1937
    } else {
1938
      // Collect UID for batch notification
1939
      int64_t uid = metaGetTableEntryUidByName(pMeta, pTable->tbName);
8,013,003✔
1940
      if (uid == 0) {
8,013,003✔
1941
        metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64,
×
1942
                  TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pTable->tbName, version);
1943
        continue;
×
1944
      }
1945
      if (taosArrayPush(uidList, &uid) == NULL){
8,013,003✔
1946
        metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64,
×
1947
                  TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(terrno), version);
1948
        continue;
×
1949
      }
1950
      if (taosArrayPush(tagListArray, &pTable->tags) == NULL){
16,026,006✔
1951
        void* ret = taosArrayPop(uidList);  // make sure the size of uidList and tagListArray are same
×
1952
        metaError("vgId:%d, %s failed at %s:%d since %s, ret:%p, version:%" PRId64,
×
1953
                  TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(terrno), ret, version);
1954
        continue;
×
1955
      }
1956
    }
1957
  }
1958

1959
  if (taosArrayGetSize(uidList) > 0) {
8,149,080✔
1960
    vnodeAlterTagForTmq(pMeta->pVnode, uidList, NULL, tagListArray);
8,001,697✔
1961
  }
1962

1963
  taosArrayDestroy(uidList);
8,149,080✔
1964
  taosArrayDestroy(tagListArray);
8,149,080✔
1965
  DestoryThreadLocalRegComp();
8,149,080✔
1966

1967
  if (code) {
8,149,080✔
1968
    const char* msgFmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
1969
    metaError(msgFmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
1970
  }
1971

1972
  TAOS_RETURN(code);
8,149,080✔
1973
}
1974

1975

1976
// Context for translating tag column/tbname references to tag values/table name
1977
typedef struct STagToValueCtx {
1978
  int32_t     code;
1979
  const void *pTags;  // STag* blob of the child table
1980
  const char *pName;  // table name of the child table
1981
} STagToValueCtx;
1982

1983
// Translate a tag column reference to the corresponding tag value
1984
static EDealRes tagToValue(SNode **pNode, void *pContext) {
1,690,300✔
1985
  STagToValueCtx *pCtx = (STagToValueCtx *)pContext;
1,690,300✔
1986

1987
  bool isTagCol = false, isTbname = false;
1,690,300✔
1988

1989
  if (nodeType(*pNode) == QUERY_NODE_COLUMN) {
1,690,300✔
1990
    SColumnNode *pCol = (SColumnNode *)*pNode;
563,641✔
1991
    if (pCol->colType == COLUMN_TYPE_TBNAME)
562,947✔
1992
      isTbname = true;
131,700✔
1993
    else
1994
      isTagCol = true;
431,941✔
1995
  } else if (nodeType(*pNode) == QUERY_NODE_FUNCTION) {
1,128,528✔
1996
    SFunctionNode *pFunc = (SFunctionNode *)*pNode;
×
1997
    if (pFunc->funcType == FUNCTION_TYPE_TBNAME)
×
1998
      isTbname = true;
×
1999
  }
2000

2001
  if (isTagCol) {
1,690,923✔
2002
    SColumnNode *pSColumnNode = *(SColumnNode **)pNode;
431,318✔
2003
    SValueNode  *res = NULL;
431,318✔
2004
    pCtx->code = nodesMakeNode(QUERY_NODE_VALUE, (SNode **)&res);
432,564✔
2005
    if (NULL == res) {
431,870✔
2006
      return DEAL_RES_ERROR;
×
2007
    }
2008

2009
    res->translate = true;
431,870✔
2010
    res->node.resType = pSColumnNode->node.resType;
431,870✔
2011

2012
    STagVal tagVal = {0};
432,564✔
2013
    tagVal.cid = pSColumnNode->colId;
431,870✔
2014
    const char *p = metaGetTableTagVal(pCtx->pTags, pSColumnNode->node.resType.type, &tagVal);
431,870✔
2015
    if (p == NULL) {
431,247✔
2016
      res->node.resType.type = TSDB_DATA_TYPE_NULL;
×
2017
    } else if (pSColumnNode->node.resType.type == TSDB_DATA_TYPE_JSON) {
431,247✔
2018
      int32_t len = ((const STag *)p)->len;
×
2019
      res->datum.p = taosMemoryCalloc(len + 1, 1);
×
2020
      if (NULL == res->datum.p) {
×
2021
        pCtx->code = terrno;
×
2022
        return DEAL_RES_ERROR;
×
2023
      }
2024
      memcpy(res->datum.p, p, len);
×
2025
    } else if (IS_VAR_DATA_TYPE(pSColumnNode->node.resType.type)) {
431,941✔
2026
      res->datum.p = taosMemoryCalloc(tagVal.nData + VARSTR_HEADER_SIZE + 1, 1);
2,196✔
2027
      if (NULL == res->datum.p) {
2,928✔
2028
        pCtx->code = terrno;
×
2029
        return DEAL_RES_ERROR;
×
2030
      }
2031
      memcpy(varDataVal(res->datum.p), tagVal.pData, tagVal.nData);
2,928✔
2032
      varDataSetLen(res->datum.p, tagVal.nData);
2,928✔
2033
    } else {
2034
      pCtx->code = nodesSetValueNodeValue(res, &(tagVal.i64));
429,636✔
2035
      if (pCtx->code != TSDB_CODE_SUCCESS) {
428,942✔
2036
        return DEAL_RES_ERROR;
×
2037
      }
2038
    }
2039

2040
    nodesDestroyNode(*pNode);
432,564✔
2041
    *pNode = (SNode *)res;
431,870✔
2042

2043
  } else if (isTbname) {
1,259,605✔
2044
    SValueNode *res = NULL;
131,700✔
2045
    pCtx->code = nodesMakeNode(QUERY_NODE_VALUE, (SNode **)&res);
131,700✔
2046
    if (NULL == res) {
131,700✔
2047
      return DEAL_RES_ERROR;
×
2048
    }
2049

2050
    res->translate = true;
131,700✔
2051
    res->node.resType = ((SExprNode *)(*pNode))->resType;
131,700✔
2052

2053
    int32_t len = strlen(pCtx->pName);
131,700✔
2054
    res->datum.p = taosMemoryCalloc(len + VARSTR_HEADER_SIZE + 1, 1);
131,700✔
2055
    if (NULL == res->datum.p) {
131,700✔
2056
      pCtx->code = terrno;
×
2057
      return DEAL_RES_ERROR;
×
2058
    }
2059
    memcpy(varDataVal(res->datum.p), pCtx->pName, len);
131,700✔
2060
    varDataSetLen(res->datum.p, len);
131,700✔
2061
    nodesDestroyNode(*pNode);
131,700✔
2062
    *pNode = (SNode *)res;
131,700✔
2063
  }
2064

2065
  return DEAL_RES_CONTINUE;
1,690,923✔
2066
}
2067

2068

2069
// Check if a single child table qualifies against the tag condition.
2070
static int32_t metaIsChildTableQualified(SMeta *pMeta, tb_uid_t uid, SNode *pTagCond, bool *pQualified) {
563,018✔
2071
  int32_t     code = TSDB_CODE_SUCCESS;
563,018✔
2072
  SMetaEntry *pEntry = NULL;
563,018✔
2073

2074
  *pQualified = false;
563,018✔
2075

2076
  code = metaFetchEntryByUid(pMeta, uid, &pEntry);
563,018✔
2077
  if (code != TSDB_CODE_SUCCESS || pEntry == NULL) {
564,264✔
2078
    return TSDB_CODE_SUCCESS;
×
2079
  }
2080

2081
  // Clone the condition so we can safely rewrite it
2082
  SNode *pTagCondTmp = NULL;
564,264✔
2083
  code = nodesCloneNode(pTagCond, &pTagCondTmp);
564,264✔
2084
  if (code != TSDB_CODE_SUCCESS) {
564,264✔
2085
    metaFetchEntryFree(&pEntry);
×
2086
    return code;
×
2087
  }
2088

2089
  // Replace tag column and tbname references with concrete values
2090
  STagToValueCtx ctx = {.code = TSDB_CODE_SUCCESS, .pTags = pEntry->ctbEntry.pTags, .pName = pEntry->name};
564,264✔
2091
  nodesRewriteExprPostOrder(&pTagCondTmp, tagToValue, &ctx);
564,264✔
2092
  if (ctx.code != TSDB_CODE_SUCCESS) {
563,641✔
2093
    nodesDestroyNode(pTagCondTmp);
×
2094
    metaFetchEntryFree(&pEntry);
×
2095
    return ctx.code;
×
2096
  }
2097

2098
  // Evaluate the fully-resolved expression to a constant boolean
2099
  SNode *pResult = NULL;
563,641✔
2100
  code = scalarCalculateConstants(pTagCondTmp, &pResult);
563,641✔
2101
  if (code != TSDB_CODE_SUCCESS) {
561,701✔
2102
    nodesDestroyNode(pTagCondTmp);
×
2103
    metaFetchEntryFree(&pEntry);
×
2104
    return code;
×
2105
  }
2106

2107
  if (nodeType(pResult) == QUERY_NODE_VALUE) {
561,701✔
2108
    *pQualified = ((SValueNode *)pResult)->datum.b;
563,570✔
2109
  }
2110

2111
  nodesDestroyNode(pResult);
560,313✔
2112
  metaFetchEntryFree(&pEntry);
563,570✔
2113
  return TSDB_CODE_SUCCESS;
562,395✔
2114
}
2115

2116

2117

2118
static int32_t metaGetChildUidsByTagCond(SMeta *pMeta, tb_uid_t suid, SNode *pTagCond, SNode *pTagIndexCond, SArray *pUidList) {
60,144✔
2119
  int32_t       code = TSDB_CODE_SUCCESS;
60,144✔
2120
  int32_t       lino = 0;
60,144✔
2121
  SVnode       *pVnode = pMeta->pVnode;
60,144✔
2122
  SArray       *pCandidateUids = NULL;
59,521✔
2123

2124
  taosArrayClear(pUidList);
59,521✔
2125

2126
  // Step 1: Try index-accelerated pre-filtering with pTagIndexCond
2127
  if (pTagIndexCond != NULL) {
60,144✔
2128
    pCandidateUids = taosArrayInit(64, sizeof(uint64_t));
×
2129
    if (pCandidateUids == NULL) {
×
2130
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _end);
×
2131
    }
2132

2133
    SIndexMetaArg metaArg = {
×
2134
        .metaEx = pVnode,
2135
        .idx = metaGetIdx(pMeta),
×
2136
        .ivtIdx = metaGetIvtIdx(pMeta),
×
2137
        .suid = suid,
2138
    };
2139

2140
    SMetaDataFilterAPI filterAPI = {
×
2141
        .metaFilterTableIds = metaFilterTableIds,
2142
        .metaFilterCreateTime = metaFilterCreateTime,
2143
        .metaFilterTableName = metaFilterTableName,
2144
        .metaFilterTtl = metaFilterTtl,
2145
    };
2146

2147
    SIdxFltStatus idxStatus = SFLT_NOT_INDEX;
×
2148
    code = doFilterTag(pTagIndexCond, &metaArg, pCandidateUids, &idxStatus, &filterAPI);
×
2149
    if (code != TSDB_CODE_SUCCESS || idxStatus == SFLT_NOT_INDEX) {
×
2150
      // Index filtering failed or not supported, fall back to full scan
2151
      const char* msgFmt = "vgId:%d, index filter not used for suid:%" PRId64 ", status:%d code:%s";
×
2152
      metaDebug(msgFmt, TD_VID(pVnode), suid, idxStatus, tstrerror(code));
×
2153
      taosArrayDestroy(pCandidateUids);
×
2154
      pCandidateUids = NULL;
×
2155
      code = TSDB_CODE_SUCCESS;
×
2156
    }
2157
  }
2158

2159
  // Step 2: If index was not used, enumerate all child table UIDs
2160
  if (pCandidateUids == NULL) {
60,144✔
2161
    pCandidateUids = taosArrayInit(256, sizeof(uint64_t));
60,144✔
2162
    if (pCandidateUids == NULL) {
60,144✔
2163
      TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _end);
×
2164
    }
2165

2166
    SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, suid, 1);
60,144✔
2167
    if (pCur == NULL) {
60,144✔
2168
      TAOS_CHECK_GOTO(terrno, &lino, _end);
×
2169
    }
2170

2171
    while (1) {
693,472✔
2172
      tb_uid_t uid = metaCtbCursorNext(pCur);
753,616✔
2173
      if (uid == 0) {
747,386✔
2174
        break;
60,144✔
2175
      }
2176
      if (taosArrayPush(pCandidateUids, &uid) == NULL) {
686,619✔
2177
        code = terrno;
×
2178
        metaCloseCtbCursor(pCur);
×
2179
        TAOS_CHECK_GOTO(code, &lino, _end);
1,869✔
2180
      }
2181
    }
2182
    metaCloseCtbCursor(pCur);
60,144✔
2183
  }
2184

2185
  // Step 3: Apply pTagCond to filter the candidate UIDs
2186
  if (pTagCond == NULL) {
60,144✔
2187
    // No tag condition — all candidates qualify
2188
    taosArraySwap(pUidList, pCandidateUids);
5,268✔
2189
  } else {
2190
    // Evaluate pTagCond per child table
2191
    for (int32_t i = 0; i < taosArrayGetSize(pCandidateUids); i++) {
615,118✔
2192
      uint64_t uid = *(uint64_t*)taosArrayGet(pCandidateUids, i);
564,264✔
2193
      bool qualified = false;
564,264✔
2194
      code = metaIsChildTableQualified(pMeta, uid, pTagCond, &qualified);
563,641✔
2195
      if (code != TSDB_CODE_SUCCESS) {
561,701✔
2196
        const char* msgFmt = "vgId:%d, %s failed to evaluate tag cond for uid:%" PRId64 " suid:%" PRId64 " since %s";
×
2197
        metaError(msgFmt, TD_VID(pVnode), __func__, uid, suid, tstrerror(code));
×
UNCOV
2198
        TAOS_CHECK_GOTO(code, &lino, _end);
×
2199
      }
2200

2201
      if (qualified && taosArrayPush(pUidList, &uid) == NULL) {
716,669✔
2202
        TAOS_CHECK_GOTO(terrno, &lino, _end);
×
2203
      }
2204
    }
2205
  }
2206

2207
_end:
57,510✔
2208
  taosArrayDestroy(pCandidateUids);
60,144✔
2209
  if (code != TSDB_CODE_SUCCESS) {
60,144✔
2210
    const char* msgFmt = "vgId:%d, %s failed at line %d for suid:%" PRId64 " since %s";
×
2211
    metaError(msgFmt, TD_VID(pVnode), __func__, lino, suid, tstrerror(code));
×
2212
  }
2213
  return code;
60,144✔
2214
}
2215

2216

2217
// Convenience wrapper: partition a raw WHERE condition into tag-related parts,
2218
// then call metaGetChildUidsByTagCond to get the filtered child table UIDs.
2219
int32_t metaGetChildUidsByWhere(SMeta *pMeta, tb_uid_t suid, SNode *pWhere, SArray *pUidList) {
60,144✔
2220
  int32_t code = TSDB_CODE_SUCCESS;
60,144✔
2221
  SNode  *pTagCond = NULL;
60,144✔
2222
  SNode  *pTagIndexCond = NULL;
60,144✔
2223

2224
  if (pWhere == NULL) {
60,144✔
2225
    // No WHERE condition — return all child table UIDs
2226
    return metaGetChildUidsByTagCond(pMeta, suid, NULL, NULL, pUidList);
5,268✔
2227
  }
2228

2229
  // Clone pWhere so the caller's node is not destroyed by filterPartitionCond
2230
  SNode *pWhereCopy = NULL;
54,876✔
2231
  code = nodesCloneNode(pWhere, &pWhereCopy);
54,876✔
2232
  if (code != TSDB_CODE_SUCCESS) {
54,876✔
2233
    return code;
×
2234
  }
2235

2236
  // Partition the WHERE condition
2237
  code = filterPartitionCond(&pWhereCopy, NULL, &pTagIndexCond, &pTagCond, NULL);
54,876✔
2238
  if (code != TSDB_CODE_SUCCESS) {
54,876✔
2239
    goto _cleanup;
×
2240
  }
2241

2242
  // Call the core filtering function
2243
  code = metaGetChildUidsByTagCond(pMeta, suid, pTagCond, pTagIndexCond, pUidList);
54,876✔
2244

2245
_cleanup:
54,876✔
2246
  nodesDestroyNode(pTagCond);
54,876✔
2247
  nodesDestroyNode(pTagIndexCond);
54,876✔
2248
  nodesDestroyNode(pWhereCopy);
54,876✔
2249
  return code;
54,876✔
2250
}
2251

2252

2253

2254
int32_t metaUpdateTableChildTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
60,144✔
2255
  int32_t code = TSDB_CODE_SUCCESS;
60,144✔
2256
  SNode* pWhere = NULL;
60,144✔
2257
  SMetaEntry *pSuper = NULL;
60,144✔
2258
  SArray *pUids = NULL;
60,144✔
2259
  SHashObj *pUpdatedTagVals = NULL;
60,144✔
2260
  SArray *uidListForTmq = NULL;
60,144✔
2261

2262
  if (pReq->tbName == NULL || strlen(pReq->tbName) == 0) {
60,144✔
2263
    const char* fmt = "vgId:%d, %s failed at %s:%d since invalid table name, version:%" PRId64;
×
2264
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, version);
×
2265
    code = TSDB_CODE_INVALID_MSG;
×
2266
    goto _exit;
×
2267
  }
2268

2269
  if (pReq->whereLen > 0) {
60,144✔
2270
    code = nodesMsgToNode(pReq->where, pReq->whereLen, &pWhere);
54,876✔
2271
    if (code) {
54,876✔
2272
      const char* fmt = "vgId:%d, %s failed at %s:%d since invalid where condition, version:%" PRId64;
×
2273
      metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, version);
×
2274
      code = TSDB_CODE_INVALID_MSG;
×
2275
      goto _exit;
×
2276
    }
2277
  }
2278

2279
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pSuper);
60,144✔
2280
  if (code) {
60,144✔
2281
    const char* fmt = "vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64;
×
2282
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, version);
×
2283
    goto _exit;
×
2284
  }
2285

2286
  if (pSuper->type != TSDB_SUPER_TABLE) {
60,144✔
2287
    const char* fmt = "vgId:%d, %s failed at %s:%d since table %s is not a super table, version:%" PRId64;
×
2288
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, version);
×
2289
    code = TSDB_CODE_VND_INVALID_TABLE_ACTION;
×
2290
    goto _exit;
×
2291
  }
2292

2293
  code = updatedTagValueArrayToHashMap(&pSuper->stbEntry.schemaTag, pReq->pMultiTag, &pUpdatedTagVals);
59,521✔
2294
  if (code) {
60,144✔
2295
    const char* fmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
2296
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
2297
    goto _exit;
×
2298
  }
2299

2300
  pUids = taosArrayInit(16, sizeof(int64_t));
60,144✔
2301
  if (pUids == NULL) {
60,144✔
2302
    code = terrno;
×
2303
    const char* fmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
2304
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
2305
    goto _exit;
×
2306
  }
2307
  code = metaGetChildUidsByWhere(pMeta, pSuper->uid, pWhere, pUids);
60,144✔
2308
  if (code) {
60,144✔
2309
    const char* fmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
2310
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
2311
    goto _exit;
×
2312
  }
2313

2314
  // Pre-allocate uidList for batch notification
2315
  int32_t nUids = taosArrayGetSize(pUids);
60,144✔
2316
  uidListForTmq = taosArrayInit(nUids, sizeof(tb_uid_t));
60,144✔
2317
  if (uidListForTmq == NULL) {
60,144✔
2318
    code = terrno;
×
2319
    const char* fmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
2320
    metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), version);
×
2321
    goto _exit;
×
2322
  }
2323

2324
  for (int32_t i = 0; i < nUids; i++) {
345,495✔
2325
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(pUids, i);
289,302✔
2326
    SMetaEntry *pChild = NULL;
289,302✔
2327
    code = metaFetchEntryByUid(pMeta, uid, &pChild);
289,302✔
2328
    if (code) {
289,302✔
2329
      const char* fmt = "vgId:%d, %s failed at %s:%d since child table uid %" PRId64 " not found, version:%" PRId64;
×
2330
      metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, uid, version);
×
2331
      goto _exit;
×
2332
    }
2333

2334
    pChild->version = version;
289,302✔
2335
    code = metaUpdateTableTagValueImpl(pMeta, pChild, &pSuper->stbEntry.schemaTag, pUpdatedTagVals);
289,302✔
2336
    if (code == TSDB_CODE_VND_SAME_TAG) {
289,302✔
2337
      // we are updating multiple tables, if one table has same tag,
2338
      // just skip it and continue to update other tables,
2339
      // and return success at the end
2340
      code = TSDB_CODE_SUCCESS;
2,634✔
2341
    } else if (code) {
286,668✔
2342
      const char* fmt = "vgId:%d, %s failed at %s:%d since %s, child table uid %" PRId64 " name %s, version:%" PRId64;
3,951✔
2343
      metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, tstrerror(code), uid, pChild->name, version);
3,951✔
2344
      metaFetchEntryFree(&pChild);
3,951✔
2345
      goto _exit;
3,951✔
2346
    } else {
2347
      // Collect UID for batch notification
2348
      if (taosArrayPush(uidListForTmq, &uid) == NULL) {
282,717✔
2349
        const char* fmt = "vgId:%d, %s failed at %s:%d since %s, version:%" PRId64;
×
2350
        metaError(fmt, TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, terrstr, version);
×
2351
      }
2352
    }
2353

2354
    metaFetchEntryFree(&pChild);
285,351✔
2355
  }
2356

2357
_exit:
60,144✔
2358
  DestoryThreadLocalRegComp();
60,144✔
2359
  if (taosArrayGetSize(uidListForTmq) > 0) {
60,144✔
2360
    vnodeAlterTagForTmq(pMeta->pVnode, uidListForTmq, pReq->pMultiTag, NULL);
22,536✔
2361
  }
2362
  taosArrayDestroy(pUids);
60,144✔
2363
  taosArrayDestroy(uidListForTmq);
60,144✔
2364
  taosHashCleanup(pUpdatedTagVals);
60,144✔
2365
  metaFetchEntryFree(&pSuper);
60,144✔
2366
  nodesDestroyNode(pWhere);
60,144✔
2367
  TAOS_RETURN(code);
60,144✔
2368
}
2369

2370

2371

2372
static int32_t metaCheckUpdateTableOptionsReq(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
23,350✔
2373
  int32_t code = TSDB_CODE_SUCCESS;
23,350✔
2374

2375
  if (pReq->tbName == NULL || strlen(pReq->tbName) == 0) {
23,350✔
2376
    metaError("vgId:%d, %s failed at %s:%d since invalid table name, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2377
              __FILE__, __LINE__, version);
2378
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2379
  }
2380

2381
  return code;
23,350✔
2382
}
2383

2384
int32_t metaUpdateTableOptions2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
23,350✔
2385
  int32_t code = 0;
23,350✔
2386

2387
  code = metaCheckUpdateTableOptionsReq(pMeta, version, pReq);
23,350✔
2388
  if (code) {
23,350✔
2389
    TAOS_RETURN(code);
×
2390
  }
2391

2392
  // fetch entry
2393
  SMetaEntry *pEntry = NULL;
23,350✔
2394
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
23,350✔
2395
  if (code) {
23,350✔
2396
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2397
              __FILE__, __LINE__, pReq->tbName, version);
2398
    TAOS_RETURN(code);
×
2399
  }
2400

2401
  // do change the entry
2402
  pEntry->version = version;
23,350✔
2403
  if (pEntry->type == TSDB_CHILD_TABLE) {
23,350✔
2404
    if (pReq->updateTTL) {
12,302✔
2405
      pEntry->ctbEntry.ttlDays = pReq->newTTL;
4,760✔
2406
    }
2407
    if (pReq->newCommentLen >= 0) {
12,302✔
2408
      char *pNewComment = NULL;
7,542✔
2409
      if (pReq->newCommentLen) {
7,542✔
2410
        pNewComment = taosMemoryRealloc(pEntry->ctbEntry.comment, pReq->newCommentLen + 1);
4,806✔
2411
        if (NULL == pNewComment) {
4,806✔
2412
          metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
2413
                    __LINE__, tstrerror(terrno), version);
2414
          metaFetchEntryFree(&pEntry);
×
2415
          TAOS_RETURN(terrno);
×
2416
        }
2417
        memcpy(pNewComment, pReq->newComment, pReq->newCommentLen + 1);
4,806✔
2418
      } else {
2419
        taosMemoryFreeClear(pEntry->ctbEntry.comment);
2,736✔
2420
      }
2421
      pEntry->ctbEntry.comment = pNewComment;
7,542✔
2422
      pEntry->ctbEntry.commentLen = pReq->newCommentLen;
7,542✔
2423
    }
2424
  } else if (pEntry->type == TSDB_NORMAL_TABLE) {
11,048✔
2425
    if (pReq->updateTTL) {
11,048✔
2426
      pEntry->ntbEntry.ttlDays = pReq->newTTL;
4,886✔
2427
    }
2428
    if (pReq->newCommentLen >= 0) {
11,048✔
2429
      char *pNewComment = NULL;
6,162✔
2430
      if (pReq->newCommentLen > 0) {
6,162✔
2431
        pNewComment = taosMemoryRealloc(pEntry->ntbEntry.comment, pReq->newCommentLen + 1);
3,426✔
2432
        if (NULL == pNewComment) {
3,426✔
2433
          metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
×
2434
                    __LINE__, tstrerror(terrno), version);
2435
          metaFetchEntryFree(&pEntry);
×
2436
          TAOS_RETURN(terrno);
×
2437
        }
2438
        memcpy(pNewComment, pReq->newComment, pReq->newCommentLen + 1);
3,426✔
2439
      } else {
2440
        taosMemoryFreeClear(pEntry->ntbEntry.comment);
2,736✔
2441
      }
2442
      pEntry->ntbEntry.comment = pNewComment;
6,162✔
2443
      pEntry->ntbEntry.commentLen = pReq->newCommentLen;
6,162✔
2444
    }
2445
  } else {
2446
    metaError("vgId:%d, %s failed at %s:%d since table %s type %d is invalid, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2447
              __func__, __FILE__, __LINE__, pReq->tbName, pEntry->type, version);
2448
    metaFetchEntryFree(&pEntry);
×
2449
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2450
  }
2451

2452
  // do handle entry
2453
  code = metaHandleEntry2(pMeta, pEntry);
23,350✔
2454
  if (code) {
23,350✔
2455
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2456
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
2457
    metaFetchEntryFree(&pEntry);
×
2458
    TAOS_RETURN(code);
×
2459
  } else {
2460
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
23,350✔
2461
             pEntry->uid, version);
2462
  }
2463

2464
  metaFetchEntryFree(&pEntry);
23,350✔
2465
  TAOS_RETURN(code);
23,350✔
2466
}
2467

2468
int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
6,393✔
2469
  int32_t code = TSDB_CODE_SUCCESS;
6,393✔
2470

2471
  if (NULL == pReq->tbName || strlen(pReq->tbName) == 0) {
6,393✔
2472
    metaError("vgId:%d, %s failed at %s:%d since invalid table name, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2473
              __FILE__, __LINE__, version);
2474
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2475
  }
2476

2477
  SMetaEntry *pEntry = NULL;
6,393✔
2478
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
6,393✔
2479
  if (code) {
6,393✔
2480
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2481
              __FILE__, __LINE__, pReq->tbName, version);
2482
    TAOS_RETURN(code);
×
2483
  }
2484

2485
  if (pEntry->version >= version) {
6,393✔
2486
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
2487
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
2488
    metaFetchEntryFree(&pEntry);
×
2489
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
2490
  }
2491

2492
  if (pEntry->type != TSDB_NORMAL_TABLE && pEntry->type != TSDB_SUPER_TABLE) {
6,393✔
2493
    metaError("vgId:%d, %s failed at %s:%d since table %s type %d is invalid, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2494
              __func__, __FILE__, __LINE__, pReq->tbName, pEntry->type, version);
2495
    metaFetchEntryFree(&pEntry);
×
2496
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2497
  }
2498

2499
  // do change the entry
2500
  int8_t           updated = 0;
6,393✔
2501
  SColCmprWrapper *wp = &pEntry->colCmpr;
6,393✔
2502
  for (int32_t i = 0; i < wp->nCols; i++) {
51,144✔
2503
    SColCmpr *p = &wp->pColCmpr[i];
44,751✔
2504
    if (p->id == pReq->colId) {
44,751✔
2505
      uint32_t dst = 0;
6,393✔
2506
      updated = tUpdateCompress(p->alg, pReq->compress, TSDB_COLVAL_COMPRESS_DISABLED, TSDB_COLVAL_LEVEL_DISABLED,
6,393✔
2507
                                TSDB_COLVAL_LEVEL_MEDIUM, &dst);
2508
      if (updated > 0) {
6,393✔
2509
        p->alg = dst;
6,393✔
2510
      }
2511
    }
2512
  }
2513

2514
  if (updated == 0) {
6,393✔
2515
    code = TSDB_CODE_VND_COLUMN_COMPRESS_ALREADY_EXIST;
×
2516
    metaError("vgId:%d, %s failed at %s:%d since column %d compress level is not changed, version:%" PRId64,
×
2517
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colId, version);
2518
    metaFetchEntryFree(&pEntry);
×
2519
    TAOS_RETURN(code);
×
2520
  } else if (updated < 0) {
6,393✔
2521
    code = TSDB_CODE_TSC_COMPRESS_LEVEL_ERROR;
×
2522
    metaError("vgId:%d, %s failed at %s:%d since column %d compress level is invalid, version:%" PRId64,
×
2523
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colId, version);
2524
    metaFetchEntryFree(&pEntry);
×
2525
    TAOS_RETURN(code);
×
2526
  }
2527

2528
  pEntry->version = version;
6,393✔
2529

2530
  // do handle entry
2531
  code = metaHandleEntry2(pMeta, pEntry);
6,393✔
2532
  if (code) {
6,393✔
2533
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2534
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
2535
    metaFetchEntryFree(&pEntry);
×
2536
    TAOS_RETURN(code);
×
2537
  } else {
2538
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
6,393✔
2539
             pEntry->uid, version);
2540
  }
2541

2542
  metaFetchEntryFree(&pEntry);
6,393✔
2543
  TAOS_RETURN(code);
6,393✔
2544
}
2545

2546
int32_t metaAlterTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
80,865✔
2547
  int32_t code = TSDB_CODE_SUCCESS;
80,865✔
2548

2549
  // check request
2550
  code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
80,865✔
2551
  if (code) {
80,865✔
2552
    TAOS_RETURN(code);
×
2553
  }
2554

2555
  if (NULL == pReq->refDbName) {
80,865✔
2556
    metaError("vgId:%d, %s failed at %s:%d since invalid ref db name, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2557
              __func__, __FILE__, __LINE__, version);
2558
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2559
  }
2560

2561
  if (NULL == pReq->refTbName) {
80,865✔
2562
    metaError("vgId:%d, %s failed at %s:%d since invalid ref table name, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2563
              __func__, __FILE__, __LINE__, version);
2564
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2565
  }
2566

2567
  if (NULL == pReq->refColName) {
80,865✔
2568
    metaError("vgId:%d, %s failed at %s:%d since invalid ref Col name, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2569
              __func__, __FILE__, __LINE__, version);
2570
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2571
  }
2572

2573
  // fetch old entry
2574
  SMetaEntry *pEntry = NULL;
80,865✔
2575
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
80,865✔
2576
  if (code) {
80,865✔
2577
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2578
              __FILE__, __LINE__, pReq->tbName, version);
2579
    TAOS_RETURN(code);
×
2580
  }
2581

2582
  if (pEntry->version >= version) {
80,865✔
2583
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
2584
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
2585
    metaFetchEntryFree(&pEntry);
×
2586
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
2587
  }
2588

2589
  // fetch super entry
2590
  SMetaEntry *pSuper = NULL;
80,865✔
2591
  if (pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
80,865✔
2592
    code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
29,813✔
2593
    if (code) {
29,813✔
2594
      metaError("vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64,
×
2595
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ctbEntry.suid, version);
2596
      metaFetchEntryFree(&pEntry);
×
2597
      TAOS_RETURN(TSDB_CODE_INTERNAL_ERROR);
×
2598
    }
2599
  }
2600

2601
  // search the column to update
2602
  SSchemaWrapper *pSchema =
80,865✔
2603
      pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? &pSuper->stbEntry.schemaRow : &pEntry->ntbEntry.schemaRow;
80,865✔
2604
  SColRef *pColRef = NULL;
80,865✔
2605
  int32_t  iColumn = 0;
80,865✔
2606
  for (int32_t i = 0; i < pSchema->nCols; i++) {
397,104✔
2607
    if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
397,104✔
2608
      pColRef = &pEntry->colRef.pColRef[i];
80,865✔
2609
      iColumn = i;
80,865✔
2610
      break;
80,865✔
2611
    }
2612
  }
2613

2614
  if (NULL == pColRef) {
80,865✔
2615
    metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
×
2616
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colId, pReq->tbName, version);
2617
    metaFetchEntryFree(&pEntry);
×
2618
    metaFetchEntryFree(&pSuper);
×
2619
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
2620
  }
2621

2622
  // do update column name
2623
  pEntry->version = version;
80,865✔
2624
  pColRef->hasRef = true;
80,865✔
2625
  pColRef->id = pSchema->pSchema[iColumn].colId;
80,865✔
2626
  tstrncpy(pColRef->refDbName, pReq->refDbName, TSDB_DB_NAME_LEN);
80,865✔
2627
  tstrncpy(pColRef->refTableName, pReq->refTbName, TSDB_TABLE_NAME_LEN);
80,865✔
2628
  tstrncpy(pColRef->refColName, pReq->refColName, TSDB_COL_NAME_LEN);
80,865✔
2629
  pSchema->version++;
80,865✔
2630
  pEntry->colRef.version++;
80,865✔
2631

2632
  // do handle entry
2633
  code = metaHandleEntry2(pMeta, pEntry);
80,865✔
2634
  if (code) {
80,865✔
2635
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2636
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
2637
    metaFetchEntryFree(&pEntry);
×
2638
    metaFetchEntryFree(&pSuper);
×
2639
    TAOS_RETURN(code);
×
2640
  } else {
2641
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
80,865✔
2642
             pEntry->uid, version);
2643
  }
2644

2645
  // build response
2646
  code = metaUpdateVtbMetaRsp(
242,595✔
2647
      pEntry, pReq->tbName, pSchema, &pEntry->colRef,
80,865✔
2648
      pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? pSuper->pExtSchemas : pEntry->pExtSchemas,
80,865✔
2649
      pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? pSuper->stbEntry.ownerId : pEntry->ntbEntry.ownerId, pRsp,
80,865✔
2650
      pEntry->type);
80,865✔
2651
  if (code) {
80,865✔
2652
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2653
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
2654
  } else {
2655
    for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
598,255✔
2656
      SColRef *p = &pEntry->colRef.pColRef[i];
517,390✔
2657
      pRsp->pColRefs[i].hasRef = p->hasRef;
517,390✔
2658
      pRsp->pColRefs[i].id = p->id;
517,390✔
2659
      if (p->hasRef) {
517,390✔
2660
        tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
356,229✔
2661
        tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
356,229✔
2662
        tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
356,229✔
2663
      }
2664
    }
2665
  }
2666

2667
  metaFetchEntryFree(&pEntry);
80,865✔
2668
  metaFetchEntryFree(&pSuper);
80,865✔
2669
  TAOS_RETURN(code);
80,865✔
2670
}
2671

2672
int32_t metaRemoveTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
60,078✔
2673
  int32_t code = TSDB_CODE_SUCCESS;
60,078✔
2674

2675
  // check request
2676
  code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
60,078✔
2677
  if (code) {
60,078✔
2678
    TAOS_RETURN(code);
×
2679
  }
2680

2681
  // fetch old entry
2682
  SMetaEntry *pEntry = NULL;
60,078✔
2683
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
60,078✔
2684
  if (code) {
60,078✔
2685
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2686
              __FILE__, __LINE__, pReq->tbName, version);
2687
    TAOS_RETURN(code);
×
2688
  }
2689

2690
  if (pEntry->version >= version) {
60,078✔
2691
    metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
×
2692
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
2693
    metaFetchEntryFree(&pEntry);
×
2694
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
2695
  }
2696

2697
  // fetch super entry
2698
  SMetaEntry *pSuper = NULL;
60,078✔
2699
  if (pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
60,078✔
2700
    code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
29,885✔
2701
    if (code) {
29,885✔
2702
      metaError("vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64,
×
2703
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ctbEntry.suid, version);
2704
      metaFetchEntryFree(&pEntry);
×
2705
      TAOS_RETURN(TSDB_CODE_INTERNAL_ERROR);
×
2706
    }
2707
  }
2708

2709
  // search the column to update
2710
  SSchemaWrapper *pSchema =
60,078✔
2711
      pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? &pSuper->stbEntry.schemaRow : &pEntry->ntbEntry.schemaRow;
60,078✔
2712
  SColRef *pColRef = NULL;
60,078✔
2713
  int32_t  iColumn = 0;
60,078✔
2714
  for (int32_t i = 0; i < pSchema->nCols; i++) {
240,394✔
2715
    if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
240,394✔
2716
      pColRef = &pEntry->colRef.pColRef[i];
60,078✔
2717
      iColumn = i;
60,078✔
2718
      break;
60,078✔
2719
    }
2720
  }
2721

2722
  if (NULL == pColRef) {
60,078✔
2723
    metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
×
2724
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, iColumn + 1, pReq->tbName, version);
2725
    metaFetchEntryFree(&pEntry);
×
2726
    metaFetchEntryFree(&pSuper);
×
2727
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
2728
  }
2729

2730
  // do update column name
2731
  pEntry->version = version;
60,078✔
2732
  pColRef->hasRef = false;
60,078✔
2733
  pColRef->id = pSchema->pSchema[iColumn].colId;
60,078✔
2734
  pSchema->version++;
60,078✔
2735
  pEntry->colRef.version++;
60,078✔
2736

2737
  // do handle entry
2738
  code = metaHandleEntry2(pMeta, pEntry);
60,078✔
2739
  if (code) {
60,078✔
2740
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2741
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
2742
    metaFetchEntryFree(&pEntry);
×
2743
    metaFetchEntryFree(&pSuper);
×
2744
    TAOS_RETURN(code);
×
2745
  } else {
2746
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
60,078✔
2747
             pEntry->uid, version);
2748
  }
2749

2750
  // build response
2751
  code = metaUpdateVtbMetaRsp(
180,234✔
2752
      pEntry, pReq->tbName, pSchema, &pEntry->colRef,
60,078✔
2753
      pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? pSuper->pExtSchemas : pEntry->pExtSchemas,
60,078✔
2754
      pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? pSuper->stbEntry.ownerId : pEntry->ntbEntry.ownerId, pRsp,
60,078✔
2755
      pEntry->type);
60,078✔
2756
  if (code) {
60,078✔
2757
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2758
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
2759
  } else {
2760
    for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
374,069✔
2761
      SColRef *p = &pEntry->colRef.pColRef[i];
313,991✔
2762
      pRsp->pColRefs[i].hasRef = p->hasRef;
313,991✔
2763
      pRsp->pColRefs[i].id = p->id;
313,991✔
2764
      if (p->hasRef) {
313,991✔
2765
        tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
157,629✔
2766
        tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
157,629✔
2767
        tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
157,629✔
2768
      }
2769
    }
2770
  }
2771

2772
  metaFetchEntryFree(&pEntry);
60,078✔
2773
  metaFetchEntryFree(&pSuper);
60,078✔
2774
  TAOS_RETURN(code);
60,078✔
2775
}
2776

2777
int32_t metaAddIndexToSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
18,295✔
2778
  int32_t code = TSDB_CODE_SUCCESS;
18,295✔
2779

2780
  if (NULL == pReq->name || strlen(pReq->name) == 0) {
18,295✔
2781
    metaError("vgId:%d, %s failed at %s:%d since invalid table name, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2782
              __FILE__, __LINE__, version);
2783
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2784
  }
2785

2786
  SMetaEntry *pEntry = NULL;
18,295✔
2787
  code = metaFetchEntryByName(pMeta, pReq->name, &pEntry);
18,295✔
2788
  if (code) {
18,295✔
2789
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2790
              __FILE__, __LINE__, pReq->name, version);
2791
    TAOS_RETURN(code);
×
2792
  }
2793

2794
  if (pEntry->type != TSDB_SUPER_TABLE) {
18,295✔
2795
    metaError("vgId:%d, %s failed at %s:%d since table %s type %d is invalid, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2796
              __func__, __FILE__, __LINE__, pReq->name, pEntry->type, version);
2797
    metaFetchEntryFree(&pEntry);
×
2798
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2799
  }
2800

2801
  if (pEntry->uid != pReq->suid) {
18,295✔
2802
    metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not equal to %" PRId64
×
2803
              ", version:%" PRId64,
2804
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pEntry->uid, pReq->suid, version);
2805
    metaFetchEntryFree(&pEntry);
×
2806
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2807
  }
2808

2809
  // if (pEntry->stbEntry.schemaTag.version >= pReq->schemaTag.version) {
2810
  //   metaError("vgId:%d, %s failed at %s:%d since table %s tag schema version %d is not less than %d, version:%"
2811
  //   PRId64,
2812
  //             TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pEntry->stbEntry.schemaTag.version,
2813
  //             pReq->schemaTag.version, version);
2814
  //   metaFetchEntryFree(&pEntry);
2815
  //   TAOS_RETURN(TSDB_CODE_INVALID_MSG);
2816
  // }
2817

2818
  // do change the entry
2819
  SSchemaWrapper *pOldTagSchema = &pEntry->stbEntry.schemaTag;
18,295✔
2820
  SSchemaWrapper *pNewTagSchema = &pReq->schemaTag;
18,295✔
2821
  if (pOldTagSchema->nCols == 1 && pOldTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
18,295✔
2822
    metaError("vgId:%d, %s failed at %s:%d since table %s has no tag, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2823
              __func__, __FILE__, __LINE__, pReq->name, version);
2824
    metaFetchEntryFree(&pEntry);
×
2825
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
2826
  }
2827

2828
  if (pOldTagSchema->nCols != pNewTagSchema->nCols) {
18,295✔
2829
    metaError(
×
2830
        "vgId:%d, %s failed at %s:%d since table %s tag schema column count %d is not equal to %d, version:%" PRId64,
2831
        TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pOldTagSchema->nCols, pNewTagSchema->nCols,
2832
        version);
2833
    metaFetchEntryFree(&pEntry);
×
2834
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2835
  }
2836

2837
  // if (pOldTagSchema->version >= pNewTagSchema->version) {
2838
  //   metaError("vgId:%d, %s failed at %s:%d since table %s tag schema version %d is not less than %d, version:%"
2839
  //   PRId64,
2840
  //             TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pOldTagSchema->version,
2841
  //             pNewTagSchema->version, version);
2842
  //   metaFetchEntryFree(&pEntry);
2843
  //   TAOS_RETURN(TSDB_CODE_INVALID_MSG);
2844
  // }
2845

2846
  int32_t numOfChangedTags = 0;
18,295✔
2847
  for (int32_t i = 0; i < pOldTagSchema->nCols; i++) {
196,845✔
2848
    SSchema *pOldColumn = pOldTagSchema->pSchema + i;
178,550✔
2849
    SSchema *pNewColumn = pNewTagSchema->pSchema + i;
178,550✔
2850

2851
    if (pOldColumn->type != pNewColumn->type || pOldColumn->colId != pNewColumn->colId ||
178,550✔
2852
        strncmp(pOldColumn->name, pNewColumn->name, sizeof(pNewColumn->name))) {
178,550✔
2853
      metaError("vgId:%d, %s failed at %s:%d since table %s tag schema column %d is not equal, version:%" PRId64,
×
2854
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, i, version);
2855
      metaFetchEntryFree(&pEntry);
×
2856
      TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2857
    }
2858

2859
    if (IS_IDX_ON(pNewColumn) && !IS_IDX_ON(pOldColumn)) {
178,550✔
2860
      numOfChangedTags++;
18,295✔
2861
      SSCHMEA_SET_IDX_ON(pOldColumn);
18,295✔
2862
    } else if (!IS_IDX_ON(pNewColumn) && IS_IDX_ON(pOldColumn)) {
160,255✔
2863
      metaError("vgId:%d, %s failed at %s:%d since table %s tag schema column %d is not equal, version:%" PRId64,
×
2864
                TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, i, version);
2865
      metaFetchEntryFree(&pEntry);
×
2866
      TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2867
    }
2868
  }
2869

2870
  if (numOfChangedTags != 1) {
18,295✔
2871
    metaError(
×
2872
        "vgId:%d, %s failed at %s:%d since table %s tag schema column count %d is not equal to 1, version:%" PRId64,
2873
        TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, numOfChangedTags, version);
2874
    metaFetchEntryFree(&pEntry);
×
2875
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2876
  }
2877

2878
  pEntry->version = version;
18,295✔
2879
  pEntry->stbEntry.schemaTag.version = pNewTagSchema->version;
18,295✔
2880

2881
  // do handle the entry
2882
  code = metaHandleEntry2(pMeta, pEntry);
18,295✔
2883
  if (code) {
18,295✔
2884
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2885
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->name, version);
2886
    metaFetchEntryFree(&pEntry);
×
2887
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2888
  } else {
2889
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
18,295✔
2890
             pEntry->uid, version);
2891
  }
2892

2893
  metaFetchEntryFree(&pEntry);
18,295✔
2894
  TAOS_RETURN(code);
18,295✔
2895
}
2896

2897
int32_t metaDropIndexFromSuperTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq) {
14,886✔
2898
  int32_t code = TSDB_CODE_SUCCESS;
14,886✔
2899

2900
  if (strlen(pReq->colName) == 0 || strlen(pReq->stb) == 0) {
14,886✔
2901
    metaError("vgId:%d, %s failed at %s:%d since invalid table name or column name, version:%" PRId64,
×
2902
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, version);
2903
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
2904
  }
2905

2906
  SMetaEntry *pEntry = NULL;
14,886✔
2907
  code = metaFetchEntryByUid(pMeta, pReq->stbUid, &pEntry);
14,886✔
2908
  if (code) {
14,886✔
2909
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2910
              __FILE__, __LINE__, pReq->stb, version);
2911
    TAOS_RETURN(code);
×
2912
  }
2913

2914
  if (TSDB_SUPER_TABLE != pEntry->type) {
14,886✔
2915
    metaError("vgId:%d, %s failed at %s:%d since table %s type %d is invalid, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2916
              __func__, __FILE__, __LINE__, pReq->stb, pEntry->type, version);
2917
    metaFetchEntryFree(&pEntry);
×
2918
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2919
  }
2920

2921
  SSchemaWrapper *pTagSchema = &pEntry->stbEntry.schemaTag;
14,886✔
2922
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
14,886✔
2923
    metaError("vgId:%d, %s failed at %s:%d since table %s has no tag, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2924
              __func__, __FILE__, __LINE__, pReq->stb, version);
2925
    metaFetchEntryFree(&pEntry);
×
2926
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2927
  }
2928

2929
  // search and set the tag index off
2930
  int32_t numOfChangedTags = 0;
14,886✔
2931
  for (int32_t i = 0; i < pTagSchema->nCols; i++) {
92,142✔
2932
    SSchema *pCol = pTagSchema->pSchema + i;
92,142✔
2933
    if (0 == strncmp(pCol->name, pReq->colName, sizeof(pReq->colName))) {
92,142✔
2934
      if (!IS_IDX_ON(pCol)) {
14,886✔
2935
        metaError("vgId:%d, %s failed at %s:%d since table %s column %s is not indexed, version:%" PRId64,
×
2936
                  TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->stb, pReq->colName, version);
2937
        metaFetchEntryFree(&pEntry);
×
2938
        TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2939
      }
2940
      numOfChangedTags++;
14,886✔
2941
      SSCHMEA_SET_IDX_OFF(pCol);
14,886✔
2942
      break;
14,886✔
2943
    }
2944
  }
2945

2946
  if (numOfChangedTags != 1) {
14,886✔
2947
    metaError("vgId:%d, %s failed at %s:%d since table %s column %s is not found, version:%" PRId64,
×
2948
              TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->stb, pReq->colName, version);
2949
    metaFetchEntryFree(&pEntry);
×
2950
    TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
×
2951
  }
2952

2953
  // do handle the entry
2954
  pEntry->version = version;
14,886✔
2955
  pTagSchema->version++;
14,886✔
2956
  code = metaHandleEntry2(pMeta, pEntry);
14,886✔
2957
  if (code) {
14,886✔
2958
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
2959
              __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->stb, version);
2960
    metaFetchEntryFree(&pEntry);
×
2961
    TAOS_RETURN(code);
×
2962
  } else {
2963
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->stb,
14,886✔
2964
             pEntry->uid, version);
2965
  }
2966

2967
  metaFetchEntryFree(&pEntry);
14,886✔
2968
  TAOS_RETURN(code);
14,886✔
2969
}
2970

2971
int32_t metaAlterSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
7,791,723✔
2972
  int32_t code = TSDB_CODE_SUCCESS;
7,791,723✔
2973

2974
  if (NULL == pReq->name || strlen(pReq->name) == 0) {
7,791,723✔
2975
    metaError("vgId:%d, %s failed at %s:%d since invalid table name, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
5,437✔
2976
              __FILE__, __LINE__, version);
2977
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
5,437✔
2978
  }
2979

2980
  SMetaEntry *pEntry = NULL;
7,787,588✔
2981
  code = metaFetchEntryByName(pMeta, pReq->name, &pEntry);
7,792,580✔
2982
  if (code) {
7,780,634✔
2983
    metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
2984
              __FILE__, __LINE__, pReq->name, version);
2985
    TAOS_RETURN(TSDB_CODE_TDB_STB_NOT_EXIST);
×
2986
  }
2987

2988
  if (pEntry->type != TSDB_SUPER_TABLE) {
7,780,634✔
2989
    metaError("vgId:%d, %s failed at %s:%d since table %s type %d is invalid, version:%" PRId64, TD_VID(pMeta->pVnode),
×
2990
              __func__, __FILE__, __LINE__, pReq->name, pEntry->type, version);
2991
    metaFetchEntryFree(&pEntry);
×
2992
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
2993
  }
2994

2995
  SMetaEntry entry = {
23,314,935✔
2996
      .version = version,
2997
      .type = TSDB_SUPER_TABLE,
2998
      .uid = pReq->suid,
7,771,063✔
2999
      .name = pReq->name,
7,771,927✔
3000
      .stbEntry.schemaRow = pReq->schemaRow,
3001
      .stbEntry.schemaTag = pReq->schemaTag,
3002
      .stbEntry.keep = pReq->keep,
7,767,548✔
3003
      .stbEntry.ownerId = pReq->ownerId,
7,760,640✔
3004
      .colCmpr = pReq->colCmpr,
3005
      .pExtSchemas = pReq->pExtSchemas,
7,778,517✔
3006
  };
3007
  TABLE_SET_COL_COMPRESSED(entry.flags);
7,779,229✔
3008
  if (pReq->virtualStb) {
7,779,229✔
3009
    TABLE_SET_VIRTUAL(entry.flags);
24,560✔
3010
  }
3011
  if(TABLE_IS_ROLLUP(pEntry->flags)) {
7,772,597✔
3012
    TABLE_SET_ROLLUP(entry.flags);
4,632✔
3013
    entry.stbEntry.rsmaParam = pEntry->stbEntry.rsmaParam;
4,632✔
3014
  }
3015

3016
  // do handle the entry
3017
  code = metaHandleEntry2(pMeta, &entry);
7,790,302✔
3018
  if (code) {
7,780,781✔
3019
    metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
×
3020
              __func__, __FILE__, __LINE__, tstrerror(code), pReq->suid, pReq->name, version);
3021
    metaFetchEntryFree(&pEntry);
×
3022
    TAOS_RETURN(code);
×
3023
  } else {
3024
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
7,780,781✔
3025
             pReq->suid, version);
3026
  }
3027

3028
  metaFetchEntryFree(&pEntry);
7,798,303✔
3029
  TAOS_RETURN(code);
7,797,648✔
3030
}
3031

3032
int32_t metaDropMultipleTables(SMeta *pMeta, int64_t version, SArray *uidArray) {
×
3033
  int32_t code = 0;
×
3034

3035
  if (taosArrayGetSize(uidArray) == 0) {
×
3036
    return TSDB_CODE_SUCCESS;
×
3037
  }
3038

3039
  for (int32_t i = 0; i < taosArrayGetSize(uidArray); i++) {
×
3040
    tb_uid_t  uid = *(tb_uid_t *)taosArrayGet(uidArray, i);
×
3041
    SMetaInfo info;
×
3042
    code = metaGetInfo(pMeta, uid, &info, NULL);
×
3043
    if (code) {
×
3044
      metaError("vgId:%d, %s failed at %s:%d since table uid %" PRId64 " not found, code:%d", TD_VID(pMeta->pVnode),
×
3045
                __func__, __FILE__, __LINE__, uid, code);
3046
      return code;
×
3047
    }
3048

3049
    SMetaEntry entry = {
×
3050
        .version = version,
3051
        .uid = uid,
3052
    };
3053

3054
    if (info.suid == 0) {
×
3055
      entry.type = -TSDB_NORMAL_TABLE;
×
3056
    } else if (info.suid == uid) {
×
3057
      entry.type = -TSDB_SUPER_TABLE;
×
3058
    } else {
3059
      entry.type = -TSDB_CHILD_TABLE;
×
3060
    }
3061
    code = metaHandleEntry2(pMeta, &entry);
×
3062
    if (code) {
×
3063
      metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " version:%" PRId64, TD_VID(pMeta->pVnode),
×
3064
                __func__, __FILE__, __LINE__, tstrerror(code), uid, version);
3065
      return code;
×
3066
    }
3067
  }
3068
  return code;
×
3069
}
3070

3071
int metaCreateRsma(SMeta *pMeta, int64_t version, SVCreateRsmaReq *pReq) {
40,966✔
3072
  int32_t code = TSDB_CODE_SUCCESS;
40,966✔
3073

3074
  if (NULL == pReq->name || pReq->name[0] == 0) {
40,966✔
3075
    metaError("vgId:%d, failed at %d to create rsma since invalid rsma name, version:%" PRId64, TD_VID(pMeta->pVnode),
×
3076
              __LINE__, version);
3077
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3078
  }
3079

3080
  SMetaEntry *pEntry = NULL;
40,966✔
3081
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
40,966✔
3082
  if (code) {
40,966✔
3083
    metaError("vgId:%d, failed at %d to create rsma %s since table %s not found, version:%" PRId64,
×
3084
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, pReq->tbName, version);
3085
    TAOS_RETURN(TSDB_CODE_TDB_STB_NOT_EXIST);
×
3086
  }
3087

3088
  if (pEntry->type != TSDB_SUPER_TABLE) {
40,966✔
3089
    metaError("vgId:%d, failed at %d to create rsma %s since table %s type %d is invalid, version:%" PRId64,
×
3090
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, pReq->tbName, pEntry->type, version);
3091
    metaFetchEntryFree(&pEntry);
×
3092
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
3093
  }
3094

3095
  if (pEntry->uid != pReq->tbUid) {
40,966✔
3096
    metaError("vgId:%d, failed at %d to create rsma %s since table %s uid %" PRId64 " is not equal to %" PRId64
×
3097
              ", version:%" PRId64,
3098
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, pReq->tbName, pEntry->uid, pReq->tbUid, version);
3099
    metaFetchEntryFree(&pEntry);
×
3100
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3101
  }
3102

3103
  if (TABLE_IS_ROLLUP(pEntry->flags)) {
40,966✔
3104
    // overwrite the old rsma definition if exists
3105
    taosMemoryFreeClear(pEntry->stbEntry.rsmaParam.funcColIds);
×
3106
    taosMemoryFreeClear(pEntry->stbEntry.rsmaParam.funcIds);
×
3107
  } else {
3108
    TABLE_SET_ROLLUP(pEntry->flags);
40,966✔
3109
  }
3110

3111
  SMetaEntry entry = *pEntry;
40,966✔
3112
  entry.version = version;
40,966✔
3113
  entry.stbEntry.rsmaParam.name = pReq->name;
40,966✔
3114
  entry.stbEntry.rsmaParam.uid = pReq->uid;
40,966✔
3115
  entry.stbEntry.rsmaParam.interval[0] = pReq->interval[0];
40,966✔
3116
  entry.stbEntry.rsmaParam.interval[1] = pReq->interval[1];
40,966✔
3117
  entry.stbEntry.rsmaParam.intervalUnit = pReq->intervalUnit;
40,966✔
3118
  entry.stbEntry.rsmaParam.nFuncs = pReq->nFuncs;
40,966✔
3119
  entry.stbEntry.rsmaParam.funcColIds = pReq->funcColIds;
40,966✔
3120
  entry.stbEntry.rsmaParam.funcIds = pReq->funcIds;
40,966✔
3121

3122
  // do handle the entry
3123
  code = metaHandleEntry2(pMeta, &entry);
40,966✔
3124
  if (code) {
40,966✔
3125
    metaError("vgId:%d, failed at %d to create rsma %s since %s, uid:%" PRId64 ", version:%" PRId64,
×
3126
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, tstrerror(code), pReq->tbUid, version);
3127
    metaFetchEntryFree(&pEntry);
×
3128
    TAOS_RETURN(code);
×
3129
  } else {
3130
    pMeta->pVnode->config.vndStats.numOfRSMAs++;
40,966✔
3131
    pMeta->pVnode->config.isRsma = 1;
40,966✔
3132
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated since rsma created %s:%" PRIi64 ", version:%" PRId64,
40,966✔
3133
             TD_VID(pMeta->pVnode), pReq->tbName, pReq->tbUid, pReq->name, pReq->uid, version);
3134
  }
3135

3136
  metaFetchEntryFree(&pEntry);
40,966✔
3137
  TAOS_RETURN(code);
40,966✔
3138
}
3139

3140
int metaDropRsma(SMeta *pMeta, int64_t version, SVDropRsmaReq *pReq) {
20,620✔
3141
  int32_t code = TSDB_CODE_SUCCESS;
20,620✔
3142

3143
  if (NULL == pReq->name || pReq->name[0] == 0) {
20,620✔
3144
    metaError("vgId:%d, %s failed at %d since invalid rsma name, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
3145
              __LINE__, version);
3146
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3147
  }
3148

3149
  if (NULL == pReq->tbName || pReq->tbName[0] == 0) {
20,620✔
3150
    metaError("vgId:%d, %s failed at %d since invalid table name, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
×
3151
              __LINE__, version);
3152
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3153
  }
3154

3155
  SMetaEntry *pEntry = NULL;
20,620✔
3156
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
20,620✔
3157
  if (code) {
20,620✔
3158
    metaWarn("vgId:%d, %s no need at %d to drop %s since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode),
×
3159
             __func__, __LINE__, pReq->name, pReq->tbName, version);
3160
    TAOS_RETURN(TSDB_CODE_RSMA_NOT_EXIST);
×
3161
  }
3162

3163
  if (pEntry->type != pReq->tbType) {
20,620✔
3164
    metaError("vgId:%d, %s failed at %d to drop %s since table %s type %d is invalid, version:%" PRId64,
×
3165
              TD_VID(pMeta->pVnode), __func__, __LINE__, pReq->name, pReq->tbName, pEntry->type, version);
3166
    metaFetchEntryFree(&pEntry);
×
3167
    TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
3168
  }
3169

3170
  if (pEntry->uid != pReq->tbUid) {
20,620✔
3171
    metaError("vgId:%d, %s failed at %d %s since table %s uid %" PRId64 " is not equal to %" PRId64
×
3172
              ", version:%" PRId64,
3173
              TD_VID(pMeta->pVnode), __func__, __LINE__, pReq->name, pReq->tbName, pEntry->uid, pReq->tbUid, version);
3174
    metaFetchEntryFree(&pEntry);
×
3175
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3176
  }
3177

3178
  if (TABLE_IS_ROLLUP(pEntry->flags)) {
20,620✔
3179
    if (pEntry->stbEntry.rsmaParam.uid != pReq->uid ||
20,620✔
3180
        strncmp(pEntry->stbEntry.rsmaParam.name, pReq->name, TSDB_TABLE_NAME_LEN) != 0) {
20,620✔
3181
      metaError(
×
3182
          "vgId:%d, %s failed at line %d to drop %s since table %s is rollup table with different rsma name %s or "
3183
          "uid:%" PRIi64 ", version:%" PRId64,
3184
          TD_VID(pMeta->pVnode), __func__, __LINE__, pReq->name, pReq->tbName, pEntry->stbEntry.rsmaParam.name,
3185
          pReq->uid, version);
3186
      metaFetchEntryFree(&pEntry);
×
3187
      TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
×
3188
    }
3189
    taosMemoryFreeClear(pEntry->stbEntry.rsmaParam.funcColIds);
20,620✔
3190
    taosMemoryFreeClear(pEntry->stbEntry.rsmaParam.funcIds);
20,620✔
3191
  } else {
3192
    metaWarn("vgId:%d, %s no need at %d to drop %s since table %s is not rollup table, version:%" PRId64,
×
3193
             TD_VID(pMeta->pVnode), __func__, __LINE__, pReq->name, pReq->tbName, version);
3194
    metaFetchEntryFree(&pEntry);
×
3195
    TAOS_RETURN(TSDB_CODE_RSMA_NOT_EXIST);
×
3196
  }
3197

3198
  SMetaEntry entry = *pEntry;
20,620✔
3199
  entry.version = version;
20,620✔
3200
  TABLE_RESET_ROLLUP(entry.flags);
20,620✔
3201
  entry.stbEntry.rsmaParam.uid = 0;
20,620✔
3202
  entry.stbEntry.rsmaParam.name = NULL;
20,620✔
3203
  entry.stbEntry.rsmaParam.nFuncs = 0;
20,620✔
3204
  entry.stbEntry.rsmaParam.funcColIds = NULL;
20,620✔
3205
  entry.stbEntry.rsmaParam.funcIds = NULL;
20,620✔
3206

3207
  // do handle the entry
3208
  code = metaHandleEntry2(pMeta, &entry);
20,620✔
3209
  if (code) {
20,620✔
3210
    metaError("vgId:%d, %s failed at %d to drop %s since %s, uid:%" PRId64 ", version:%" PRId64, TD_VID(pMeta->pVnode),
×
3211
              __func__, __LINE__, pReq->name, tstrerror(code), pReq->uid, version);
3212
    metaFetchEntryFree(&pEntry);
×
3213
    TAOS_RETURN(code);
×
3214
  } else {
3215
    if (--pMeta->pVnode->config.vndStats.numOfRSMAs <= 0) {
20,620✔
3216
      pMeta->pVnode->config.isRsma = 0;
×
3217
    }
3218
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated since rsma created %s:%" PRIi64 ", version:%" PRId64,
20,620✔
3219
             TD_VID(pMeta->pVnode), pReq->tbName, pReq->tbUid, pReq->name, pReq->uid, version);
3220
  }
3221

3222
  metaFetchEntryFree(&pEntry);
20,620✔
3223
  TAOS_RETURN(code);
20,620✔
3224
}
3225

3226
int metaAlterRsma(SMeta *pMeta, int64_t version, SVAlterRsmaReq *pReq) {
12,626✔
3227
  int32_t code = TSDB_CODE_SUCCESS;
12,626✔
3228

3229
  if (NULL == pReq->name || pReq->name[0] == 0) {
12,626✔
3230
    metaError("vgId:%d, failed at %d to alter rsma since invalid rsma name, version:%" PRId64, TD_VID(pMeta->pVnode),
×
3231
              __LINE__, version);
3232
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3233
  }
3234

3235
  SMetaEntry *pEntry = NULL;
12,626✔
3236
  code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
12,626✔
3237
  if (code) {
12,626✔
3238
    metaError("vgId:%d, failed at %d to alter rsma %s since table %s not found, version:%" PRId64,
×
3239
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, pReq->tbName, version);
3240
    TAOS_RETURN(TSDB_CODE_TDB_STB_NOT_EXIST);
×
3241
  }
3242

3243
  if (pEntry->uid != pReq->tbUid) {
12,626✔
3244
    metaError("vgId:%d, failed at %d to alter rsma %s since table %s uid %" PRId64 " is not equal to %" PRId64
×
3245
              ", version:%" PRId64,
3246
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, pReq->tbName, pEntry->uid, pReq->tbUid, version);
3247
    metaFetchEntryFree(&pEntry);
×
3248
    TAOS_RETURN(TSDB_CODE_INVALID_MSG);
×
3249
  }
3250

3251
  if (TABLE_IS_ROLLUP(pEntry->flags)) {
12,626✔
3252
    taosMemoryFreeClear(pEntry->stbEntry.rsmaParam.funcColIds);
12,626✔
3253
    taosMemoryFreeClear(pEntry->stbEntry.rsmaParam.funcIds);
12,626✔
3254
  } else {
3255
    metaError("vgId:%d, failed at %d to alter rsma %s since table %s is not rollup table, version:%" PRId64,
×
3256
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, pReq->tbName, version);
3257
    metaFetchEntryFree(&pEntry);
×
3258
    TAOS_RETURN(TSDB_CODE_RSMA_NOT_EXIST);
×
3259
  }
3260

3261
  SMetaEntry entry = *pEntry;
12,626✔
3262
  entry.version = version;
12,626✔
3263
  if (pReq->alterType == TSDB_ALTER_RSMA_FUNCTION) {
12,626✔
3264
    entry.stbEntry.rsmaParam.nFuncs = pReq->nFuncs;
12,626✔
3265
    entry.stbEntry.rsmaParam.funcColIds = pReq->funcColIds;
12,626✔
3266
    entry.stbEntry.rsmaParam.funcIds = pReq->funcIds;
12,626✔
3267
  }
3268
  // do handle the entry
3269
  code = metaHandleEntry2(pMeta, &entry);
12,626✔
3270
  if (code) {
12,626✔
3271
    metaError("vgId:%d, failed at %d to alter rsma %s since %s, uid:%" PRId64 ", version:%" PRId64,
×
3272
              TD_VID(pMeta->pVnode), __LINE__, pReq->name, tstrerror(code), pReq->tbUid, version);
3273
    metaFetchEntryFree(&pEntry);
×
3274
    TAOS_RETURN(code);
×
3275
  } else {
3276
    metaInfo("vgId:%d, table %s uid %" PRId64 " is updated since rsma altered %s:%" PRIi64 ", version:%" PRId64,
12,626✔
3277
             TD_VID(pMeta->pVnode), pReq->tbName, pReq->tbUid, pReq->name, pReq->uid, version);
3278
  }
3279

3280
  metaFetchEntryFree(&pEntry);
12,626✔
3281
  TAOS_RETURN(code);
12,626✔
3282
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc