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

taosdata / TDengine / #3660

15 Mar 2025 09:06AM UTC coverage: 62.039% (-1.3%) from 63.314%
#3660

push

travis-ci

web-flow
feat(stream): support stream processing for virtual tables (#30144)

* enh: add client processing

* enh: add mnode vtables processing

* enh: add mnode vtable processing

* enh: add normal child vtable support

* fix: compile issues

* fix: compile issues

* fix: create stream issues

* fix: multi stream scan issue

* fix: remove debug info

* fix: agg task and task level issues

* fix: correct task output type

* fix: split vtablescan from agg

* fix: memory leak issues

* fix: add limitations

* Update 09-error-code.md

* Update 09-error-code.md

* fix: remove usless case

* feat(stream): extract original table data in source scan task

Implemented functionality in the source task to extract data
corresponding to the virtual table from the original table using WAL.
The extracted data is then sent to the downstream merge task for further
processing.

* feat(stream): multi-way merge using loser tree in virtual merge task

Implemented multi-way merge in the merge task using a loser tree to
combine data from multiple original table into a single virtual table.
The merged virtual table data is then pushed downstream for further
processing.  Introduced memory limit handling during the merge process
with configurable behavior when the memory limit is reached.

* fix(test): remove useless cases

---------

Co-authored-by: dapan1121 <wpan@taosdata.com>
Co-authored-by: Pan Wei <72057773+dapan1121@users.noreply.github.com>

154078 of 317582 branches covered (48.52%)

Branch coverage included in aggregate %.

313 of 2391 new or added lines in 34 files covered. (13.09%)

26134 existing lines in 205 files now uncovered.

240261 of 318051 relevant lines covered (75.54%)

16655189.27 hits per line

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

67.11
/source/dnode/mnode/impl/src/mndStb.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
#define _DEFAULT_SOURCE
17
#include "audit.h"
18
#include "mndDb.h"
19
#include "mndDnode.h"
20
#include "mndIndex.h"
21
#include "mndIndexComm.h"
22
#include "mndInfoSchema.h"
23
#include "mndMnode.h"
24
#include "mndPerfSchema.h"
25
#include "mndPrivilege.h"
26
#include "mndScheduler.h"
27
#include "mndShow.h"
28
#include "mndSma.h"
29
#include "mndStb.h"
30
#include "mndTopic.h"
31
#include "mndTrans.h"
32
#include "mndUser.h"
33
#include "mndVgroup.h"
34
#include "tname.h"
35

36
#define STB_VER_NUMBER   3
37
#define STB_RESERVE_SIZE 56
38

39
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
40
static int32_t  mndStbActionInsert(SSdb *pSdb, SStbObj *pStb);
41
static int32_t  mndStbActionDelete(SSdb *pSdb, SStbObj *pStb);
42
static int32_t  mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew);
43
static int32_t  mndProcessTtlTimer(SRpcMsg *pReq);
44
static int32_t  mndProcessTrimDbTimer(SRpcMsg *pReq);
45
static int32_t  mndProcessS3MigrateDbTimer(SRpcMsg *pReq);
46
static int32_t  mndProcessS3MigrateDbRsp(SRpcMsg *pReq);
47
static int32_t  mndProcessCreateStbReq(SRpcMsg *pReq);
48
static int32_t  mndProcessAlterStbReq(SRpcMsg *pReq);
49
static int32_t  mndProcessDropStbReq(SRpcMsg *pReq);
50
static int32_t  mndProcessDropTtltbRsp(SRpcMsg *pReq);
51
static int32_t  mndProcessTrimDbRsp(SRpcMsg *pReq);
52
static int32_t  mndProcessTableMetaReq(SRpcMsg *pReq);
53
static int32_t  mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
54
static int32_t  mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
55
static void     mndCancelGetNextStb(SMnode *pMnode, void *pIter);
56
static int32_t  mndProcessTableCfgReq(SRpcMsg *pReq);
57
static int32_t  mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
58
                               void *alterOriData, int32_t alterOriDataLen);
59
static int32_t  mndAlterStbAndUpdateTagIdxImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
60
                                              void *alterOriData, int32_t alterOriDataLen, const SMAlterStbReq *pAlter);
61

62
static int32_t mndProcessCreateIndexReq(SRpcMsg *pReq);
63
static int32_t mndProcessDropIndexReq(SRpcMsg *pReq);
64

65
static int32_t mndProcessDropStbReqFromMNode(SRpcMsg *pReq);
66
static int32_t mndProcessDropTbWithTsma(SRpcMsg *pReq);
67
static int32_t mndProcessFetchTtlExpiredTbs(SRpcMsg *pReq);
68

69
int32_t mndInitStb(SMnode *pMnode) {
1,748✔
70
  SSdbTable table = {
1,748✔
71
      .sdbType = SDB_STB,
72
      .keyType = SDB_KEY_BINARY,
73
      .encodeFp = (SdbEncodeFp)mndStbActionEncode,
74
      .decodeFp = (SdbDecodeFp)mndStbActionDecode,
75
      .insertFp = (SdbInsertFp)mndStbActionInsert,
76
      .updateFp = (SdbUpdateFp)mndStbActionUpdate,
77
      .deleteFp = (SdbDeleteFp)mndStbActionDelete,
78
  };
79

80
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcessCreateStbReq);
1,748✔
81
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessAlterStbReq);
1,748✔
82
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessDropStbReq);
1,748✔
83
  mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndTransProcessRsp);
1,748✔
84
  mndSetMsgHandle(pMnode, TDMT_VND_DROP_TTL_TABLE_RSP, mndProcessDropTtltbRsp);
1,748✔
85
  mndSetMsgHandle(pMnode, TDMT_VND_TRIM_RSP, mndProcessTrimDbRsp);
1,748✔
86
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndTransProcessRsp);
1,748✔
87
  mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndTransProcessRsp);
1,748✔
88
  mndSetMsgHandle(pMnode, TDMT_MND_TABLE_META, mndProcessTableMetaReq);
1,748✔
89
  mndSetMsgHandle(pMnode, TDMT_MND_TTL_TIMER, mndProcessTtlTimer);
1,748✔
90
  mndSetMsgHandle(pMnode, TDMT_MND_TRIM_DB_TIMER, mndProcessTrimDbTimer);
1,748✔
91
  mndSetMsgHandle(pMnode, TDMT_VND_S3MIGRATE_RSP, mndProcessS3MigrateDbRsp);
1,748✔
92
  mndSetMsgHandle(pMnode, TDMT_MND_S3MIGRATE_DB_TIMER, mndProcessS3MigrateDbTimer);
1,748✔
93
  mndSetMsgHandle(pMnode, TDMT_MND_TABLE_CFG, mndProcessTableCfgReq);
1,748✔
94
  mndSetMsgHandle(pMnode, TDMT_MND_STB_DROP, mndProcessDropStbReqFromMNode);
1,748✔
95
  mndSetMsgHandle(pMnode, TDMT_MND_STB_DROP_RSP, mndTransProcessRsp);
1,748✔
96
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_TB_WITH_TSMA, mndProcessDropTbWithTsma);
1,748✔
97
  mndSetMsgHandle(pMnode, TDMT_VND_FETCH_TTL_EXPIRED_TBS_RSP, mndProcessFetchTtlExpiredTbs);
1,748✔
98
  mndSetMsgHandle(pMnode, TDMT_VND_DROP_TABLE_RSP, mndTransProcessRsp);
1,748✔
99
  //  mndSetMsgHandle(pMnode, TDMT_MND_SYSTABLE_RETRIEVE, mndProcessRetrieveStbReq);
100

101
  // mndSetMsgHandle(pMnode, TDMT_MND_CREATE_INDEX, mndProcessCreateIndexReq);
102
  // mndSetMsgHandle(pMnode, TDMT_MND_DROP_INDEX, mndProcessDropIndexReq);
103
  // mndSetMsgHandle(pMnode, TDMT_VND_CREATE_INDEX_RSP, mndTransProcessRsp);
104
  // mndSetMsgHandle(pMnode, TDMT_VND_DROP_INDEX_RSP, mndTransProcessRsp);
105

106
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb);
1,748✔
107
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STB, mndCancelGetNextStb);
1,748✔
108

109
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_COL, mndRetrieveStbCol);
1,748✔
110
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_COL, mndCancelGetNextStb);
1,748✔
111

112
  return sdbSetTable(pMnode->pSdb, table);
1,748✔
113
}
114

115
void mndCleanupStb(SMnode *pMnode) {}
1,747✔
116

117
SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
37,278✔
118
  int32_t code = 0;
37,278✔
119
  int32_t lino = 0;
37,278✔
120
  bool    hasTypeMod = false;
37,278✔
121
  terrno = TSDB_CODE_OUT_OF_MEMORY;
37,278✔
122

123
  int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + pStb->commentLen +
74,556✔
124
                 pStb->ast1Len + pStb->ast2Len + pStb->numOfColumns * sizeof(SColCmpr) + STB_RESERVE_SIZE +
74,556✔
125
                 taosArrayGetSize(pStb->pFuncs) * TSDB_FUNC_NAME_LEN + sizeof(int32_t) * pStb->numOfColumns;
37,278✔
126
  SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, STB_VER_NUMBER, size);
37,278✔
127
  if (pRaw == NULL) goto _OVER;
37,278!
128

129
  int32_t dataPos = 0;
37,278✔
130
  SDB_SET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, _OVER)
37,278!
131
  SDB_SET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, _OVER)
37,278!
132
  SDB_SET_INT64(pRaw, dataPos, pStb->createdTime, _OVER)
37,278!
133
  SDB_SET_INT64(pRaw, dataPos, pStb->updateTime, _OVER)
37,278!
134
  SDB_SET_INT64(pRaw, dataPos, pStb->uid, _OVER)
37,278!
135
  SDB_SET_INT64(pRaw, dataPos, pStb->dbUid, _OVER)
37,278!
136
  SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
37,278!
137
  SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
37,278!
138
  SDB_SET_INT32(pRaw, dataPos, pStb->smaVer, _OVER)
37,278!
139
  SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
37,278!
140
  SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[0], _OVER)
37,278!
141
  SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[1], _OVER)
37,278!
142
  SDB_SET_INT64(pRaw, dataPos, pStb->watermark[0], _OVER)
37,278!
143
  SDB_SET_INT64(pRaw, dataPos, pStb->watermark[1], _OVER)
37,278!
144
  SDB_SET_INT32(pRaw, dataPos, pStb->ttl, _OVER)
37,278!
145
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, _OVER)
37,278!
146
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, _OVER)
37,278!
147
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfFuncs, _OVER)
37,278!
148
  SDB_SET_INT32(pRaw, dataPos, pStb->commentLen, _OVER)
37,278!
149
  SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER)
37,278!
150
  SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER)
37,278!
151

152
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
2,829,958✔
153
    SSchema *pSchema = &pStb->pColumns[i];
2,792,680✔
154
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
2,792,680!
155
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
2,792,680!
156
    SDB_SET_INT16(pRaw, dataPos, pSchema->colId, _OVER)
2,792,680!
157
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, _OVER)
2,792,680!
158
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
2,792,680!
159
    hasTypeMod = hasTypeMod || HAS_TYPE_MOD(pSchema);
2,792,680✔
160
  }
161

162
  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
454,869✔
163
    SSchema *pSchema = &pStb->pTags[i];
417,591✔
164
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
417,591!
165
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
417,591!
166
    SDB_SET_INT16(pRaw, dataPos, pSchema->colId, _OVER)
417,591!
167
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, _OVER)
417,591!
168
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
417,591!
169
  }
170

171
  for (int32_t i = 0; i < pStb->numOfFuncs; ++i) {
37,290✔
172
    char *func = taosArrayGet(pStb->pFuncs, i);
12✔
173
    SDB_SET_BINARY(pRaw, dataPos, func, TSDB_FUNC_NAME_LEN, _OVER)
12!
174
  }
175

176
  if (pStb->commentLen > 0) {
37,278✔
177
    SDB_SET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
172!
178
  }
179

180
  if (pStb->ast1Len > 0) {
37,278✔
181
    SDB_SET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
12!
182
  }
183

184
  if (pStb->ast2Len > 0) {
37,278✔
185
    SDB_SET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
12!
186
  }
187

188
  if (pStb->pCmpr != NULL) {
37,278!
189
    for (int i = 0; i < pStb->numOfColumns; i++) {
2,829,958✔
190
      SColCmpr *p = &pStb->pCmpr[i];
2,792,680✔
191
      SDB_SET_INT16(pRaw, dataPos, p->id, _OVER)
2,792,680!
192
      SDB_SET_INT32(pRaw, dataPos, p->alg, _OVER)
2,792,680!
193
    }
194
  }
195
  SDB_SET_INT64(pRaw, dataPos, pStb->keep, _OVER)
37,278!
196

197
  if (hasTypeMod) {
37,278✔
198
    for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
2,074,402✔
199
      SDB_SET_INT32(pRaw, dataPos, pStb->pExtSchemas[i].typeMod, _OVER);
2,069,486!
200
    }
201
  }
202

203
  SDB_SET_INT8(pRaw, dataPos, pStb->virtualStb, _OVER)
37,278!
204
  SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
37,278!
205
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
37,278!
206

207
  terrno = 0;
37,278✔
208

209
_OVER:
37,278✔
210
  if (terrno != 0) {
37,278!
UNCOV
211
    mError("stb:%s, failed to encode to raw:%p since %s", pStb->name, pRaw, terrstr());
×
UNCOV
212
    sdbFreeRaw(pRaw);
×
UNCOV
213
    return NULL;
×
214
  }
215

216
  mTrace("stb:%s, encode to raw:%p, row:%p", pStb->name, pRaw, pStb);
37,278✔
217
  return pRaw;
37,278✔
218
}
219

220
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
33,233✔
221
  int32_t code = 0;
33,233✔
222
  int32_t lino = 0;
33,233✔
223
  terrno = TSDB_CODE_OUT_OF_MEMORY;
33,233✔
224
  SSdbRow *pRow = NULL;
33,233✔
225
  SStbObj *pStb = NULL;
33,233✔
226
  bool     hasExtSchemas = false;
33,233✔
227

228
  int8_t sver = 0;
33,233✔
229
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
33,233!
230

231
  if (sver > STB_VER_NUMBER) {
33,233!
UNCOV
232
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
UNCOV
233
    goto _OVER;
×
234
  }
235

236
  pRow = sdbAllocRow(sizeof(SStbObj));
33,233✔
237
  if (pRow == NULL) goto _OVER;
33,233!
238

239
  pStb = sdbGetRowObj(pRow);
33,233✔
240
  if (pStb == NULL) goto _OVER;
33,233!
241

242
  int32_t dataPos = 0;
33,233✔
243
  SDB_GET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, _OVER)
33,233!
244
  SDB_GET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, _OVER)
33,233!
245
  SDB_GET_INT64(pRaw, dataPos, &pStb->createdTime, _OVER)
33,233!
246
  SDB_GET_INT64(pRaw, dataPos, &pStb->updateTime, _OVER)
33,233!
247
  SDB_GET_INT64(pRaw, dataPos, &pStb->uid, _OVER)
33,233!
248
  SDB_GET_INT64(pRaw, dataPos, &pStb->dbUid, _OVER)
33,233!
249
  SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
33,233!
250
  SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
33,233!
251
  SDB_GET_INT32(pRaw, dataPos, &pStb->smaVer, _OVER)
33,233!
252
  SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
33,233!
253
  SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[0], _OVER)
33,233!
254
  SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[1], _OVER)
33,233!
255
  SDB_GET_INT64(pRaw, dataPos, &pStb->watermark[0], _OVER)
33,233!
256
  SDB_GET_INT64(pRaw, dataPos, &pStb->watermark[1], _OVER)
33,233!
257
  SDB_GET_INT32(pRaw, dataPos, &pStb->ttl, _OVER)
33,233!
258
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, _OVER)
33,233!
259
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, _OVER)
33,233!
260
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfFuncs, _OVER)
33,233!
261
  SDB_GET_INT32(pRaw, dataPos, &pStb->commentLen, _OVER)
33,233!
262
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER)
33,233!
263
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER)
33,233!
264

265
  pStb->pColumns = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchema));
33,233!
266
  pStb->pTags = taosMemoryCalloc(pStb->numOfTags, sizeof(SSchema));
33,233!
267
  pStb->pFuncs = taosArrayInit(pStb->numOfFuncs, TSDB_FUNC_NAME_LEN);
33,233✔
268
  if (pStb->pColumns == NULL || pStb->pTags == NULL || pStb->pFuncs == NULL) {
33,233!
UNCOV
269
    goto _OVER;
×
270
  }
271

272
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
6,550,714✔
273
    SSchema *pSchema = &pStb->pColumns[i];
6,517,481✔
274
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
6,517,481!
275
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
6,517,481!
276
    SDB_GET_INT16(pRaw, dataPos, &pSchema->colId, _OVER)
6,517,481!
277
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, _OVER)
6,517,481!
278
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
6,517,481!
279
    hasExtSchemas = hasExtSchemas || HAS_TYPE_MOD(pSchema);
6,517,481✔
280
  }
281

282
  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
651,159✔
283
    SSchema *pSchema = &pStb->pTags[i];
617,926✔
284
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
617,926!
285
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
617,926!
286
    SDB_GET_INT16(pRaw, dataPos, &pSchema->colId, _OVER)
617,926!
287
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, _OVER)
617,926!
288
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
617,926!
289
  }
290

291
  for (int32_t i = 0; i < pStb->numOfFuncs; ++i) {
33,243✔
292
    char funcName[TSDB_FUNC_NAME_LEN] = {0};
10✔
293
    SDB_GET_BINARY(pRaw, dataPos, funcName, TSDB_FUNC_NAME_LEN, _OVER)
10!
294
    if (taosArrayPush(pStb->pFuncs, funcName) == NULL) goto _OVER;
20!
295
  }
296

297
  if (pStb->commentLen > 0) {
33,233✔
298
    pStb->comment = taosMemoryCalloc(pStb->commentLen + 1, 1);
153!
299
    if (pStb->comment == NULL) goto _OVER;
153!
300
    SDB_GET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
153!
301
  }
302

303
  if (pStb->ast1Len > 0) {
33,233✔
304
    pStb->pAst1 = taosMemoryCalloc(pStb->ast1Len, 1);
10!
305
    if (pStb->pAst1 == NULL) goto _OVER;
10!
306
    SDB_GET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
10!
307
  }
308

309
  if (pStb->ast2Len > 0) {
33,233✔
310
    pStb->pAst2 = taosMemoryCalloc(pStb->ast2Len, 1);
10!
311
    if (pStb->pAst2 == NULL) goto _OVER;
10!
312
    SDB_GET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
10!
313
  }
314

315
  pStb->pCmpr = taosMemoryCalloc(pStb->numOfColumns, sizeof(SColCmpr));
33,233!
316
  if (sver < STB_VER_NUMBER - 1) {
33,233!
317
    // compatible with old data, setup default compress value
318
    // impl later
UNCOV
319
    for (int i = 0; i < pStb->numOfColumns; i++) {
×
UNCOV
320
      SSchema  *pSchema = &pStb->pColumns[i];
×
UNCOV
321
      SColCmpr *pCmpr = &pStb->pCmpr[i];
×
UNCOV
322
      pCmpr->id = pSchema->colId;
×
UNCOV
323
      pCmpr->alg = createDefaultColCmprByType(pSchema->type);
×
324
    }
325
  } else {
326
    for (int i = 0; i < pStb->numOfColumns; i++) {
6,550,714✔
327
      SColCmpr *pCmpr = &pStb->pCmpr[i];
6,517,481✔
328
      SDB_GET_INT16(pRaw, dataPos, &pCmpr->id, _OVER)
6,517,481!
329
      SDB_GET_INT32(pRaw, dataPos, (int32_t *)&pCmpr->alg, _OVER)  // compatiable
6,517,481!
330
    }
331
  }
332
  SDB_GET_INT64(pRaw, dataPos, &pStb->keep, _OVER)
33,233!
333

334
  // type mod
335
  if (hasExtSchemas) {
33,233✔
336
    pStb->pExtSchemas = taosMemoryCalloc(pStb->numOfColumns, sizeof(SExtSchema));
12,692!
337
    if (!pStb->pExtSchemas) goto _OVER;
12,692!
338
    for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
6,096,223✔
339
      SSchema *pSchema = &pStb->pColumns[i];
6,083,531✔
340
      SDB_GET_INT32(pRaw, dataPos, &pStb->pExtSchemas[i].typeMod, _OVER)
6,083,531!
341
    }
342
  }
343

344
  if (sver < STB_VER_NUMBER) {
33,233!
UNCOV
345
    pStb->virtualStb = 0;
×
346
  } else {
347
    SDB_GET_INT8(pRaw, dataPos, &pStb->virtualStb, _OVER)
33,233!
348
  }
349

350
  SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
33,233!
351

352
  terrno = 0;
33,233✔
353

354
_OVER:
33,233✔
355
  if (terrno != 0) {
33,233!
UNCOV
356
    mError("stb:%s, failed to decode from raw:%p since %s", pStb == NULL ? "null" : pStb->name, pRaw, terrstr());
×
UNCOV
357
    if (pStb != NULL) {
×
UNCOV
358
      taosMemoryFreeClear(pStb->pColumns);
×
UNCOV
359
      taosMemoryFreeClear(pStb->pTags);
×
UNCOV
360
      taosMemoryFreeClear(pStb->comment);
×
UNCOV
361
      taosMemoryFree(pStb->pCmpr);
×
UNCOV
362
      taosMemoryFreeClear(pStb->pExtSchemas);
×
363
    }
UNCOV
364
    taosMemoryFreeClear(pRow);
×
UNCOV
365
    return NULL;
×
366
  }
367

368
  mTrace("stb:%s, decode from raw:%p, row:%p", pStb->name, pRaw, pStb);
33,233✔
369
  return pRow;
33,233✔
370
}
371

372
void mndFreeStb(SStbObj *pStb) {
41,961✔
373
  taosArrayDestroy(pStb->pFuncs);
41,961✔
374
  taosMemoryFreeClear(pStb->pColumns);
41,961!
375
  taosMemoryFreeClear(pStb->pTags);
41,961!
376
  taosMemoryFreeClear(pStb->comment);
41,961!
377
  taosMemoryFreeClear(pStb->pAst1);
41,961!
378
  taosMemoryFreeClear(pStb->pAst2);
41,961!
379
  taosMemoryFreeClear(pStb->pCmpr);
41,961!
380
  taosMemoryFreeClear(pStb->pExtSchemas);
41,961!
381
}
41,961✔
382

383
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
11,561✔
384
  mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
11,561✔
385
  return 0;
11,561✔
386
}
387

388
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
40,334✔
389
  mTrace("stb:%s, perform delete action, row:%p", pStb->name, pStb);
40,334✔
390
  mndFreeStb(pStb);
40,334✔
391
  return 0;
40,334✔
392
}
393

394
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
16,369✔
395
  terrno = 0;
16,369✔
396
  mTrace("stb:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew);
16,369✔
397

398
  taosWLockLatch(&pOld->lock);
16,369✔
399
  int32_t numOfColumns = pOld->numOfColumns;
16,369✔
400
  if (pOld->numOfColumns < pNew->numOfColumns) {
16,369✔
401
    void *pColumns = taosMemoryMalloc(pNew->numOfColumns * sizeof(SSchema));
3,243!
402
    if (pColumns == NULL) {
3,243!
UNCOV
403
      goto END;
×
404
    }
405
    taosMemoryFree(pOld->pColumns);
3,243!
406
    pOld->pColumns = pColumns;
3,243✔
407
  }
408

409
  if (pOld->numOfTags < pNew->numOfTags) {
16,369✔
410
    void *pTags = taosMemoryMalloc(pNew->numOfTags * sizeof(SSchema));
940!
411
    if (pTags == NULL) {
940!
UNCOV
412
      goto END;
×
413
    }
414
    taosMemoryFree(pOld->pTags);
940!
415
    pOld->pTags = pTags;
940✔
416
  }
417

418
  if (pOld->commentLen < pNew->commentLen && pNew->commentLen > 0) {
16,369!
419
    void *comment = taosMemoryMalloc(pNew->commentLen + 1);
17!
420
    if (comment == NULL) {
17!
421
      goto END;
×
422
    }
423
    taosMemoryFree(pOld->comment);
17!
424
    pOld->comment = comment;
17✔
425
  }
426
  pOld->commentLen = pNew->commentLen;
16,369✔
427

428
  if (pOld->ast1Len < pNew->ast1Len) {
16,369!
UNCOV
429
    void *pAst1 = taosMemoryMalloc(pNew->ast1Len + 1);
×
UNCOV
430
    if (pAst1 == NULL) {
×
UNCOV
431
      goto END;
×
432
    }
UNCOV
433
    taosMemoryFree(pOld->pAst1);
×
UNCOV
434
    pOld->pAst1 = pAst1;
×
435
  }
436

437
  if (pOld->ast2Len < pNew->ast2Len) {
16,369!
UNCOV
438
    void *pAst2 = taosMemoryMalloc(pNew->ast2Len + 1);
×
UNCOV
439
    if (pAst2 == NULL) {
×
UNCOV
440
      goto END;
×
441
    }
UNCOV
442
    taosMemoryFree(pOld->pAst2);
×
UNCOV
443
    pOld->pAst2 = pAst2;
×
444
  }
445

446
  pOld->updateTime = pNew->updateTime;
16,369✔
447
  pOld->tagVer = pNew->tagVer;
16,369✔
448
  pOld->colVer = pNew->colVer;
16,369✔
449
  pOld->smaVer = pNew->smaVer;
16,369✔
450
  pOld->nextColId = pNew->nextColId;
16,369✔
451
  pOld->ttl = pNew->ttl;
16,369✔
452
  pOld->keep = pNew->keep;
16,369✔
453
  
454
  if (pNew->numOfColumns > 0) {
16,369!
455
    pOld->numOfColumns = pNew->numOfColumns;
16,369✔
456
    memcpy(pOld->pColumns, pNew->pColumns, pOld->numOfColumns * sizeof(SSchema));
16,369✔
457
  }
458
  if (pNew->numOfTags > 0) {
16,369!
459
    pOld->numOfTags = pNew->numOfTags;
16,369✔
460
    memcpy(pOld->pTags, pNew->pTags, pOld->numOfTags * sizeof(SSchema));
16,369✔
461
  }
462
  if (pNew->commentLen > 0) {
16,369✔
463
    memcpy(pOld->comment, pNew->comment, pNew->commentLen + 1);
131✔
464
    pOld->commentLen = pNew->commentLen;
131✔
465
  }
466
  if (pNew->ast1Len != 0) {
16,369!
UNCOV
467
    memcpy(pOld->pAst1, pNew->pAst1, pNew->ast1Len);
×
UNCOV
468
    pOld->ast1Len = pNew->ast1Len;
×
469
  }
470
  if (pNew->ast2Len != 0) {
16,369!
UNCOV
471
    memcpy(pOld->pAst2, pNew->pAst2, pNew->ast2Len);
×
UNCOV
472
    pOld->ast2Len = pNew->ast2Len;
×
473
  }
474
  if (numOfColumns < pNew->numOfColumns) {
16,369✔
475
    taosMemoryFree(pOld->pCmpr);
3,243!
476
    pOld->pCmpr = taosMemoryCalloc(pNew->numOfColumns, sizeof(SColCmpr));
3,243!
477
    if (pOld->pCmpr == NULL){
3,243!
UNCOV
478
      goto END;
×
479
    }
480
    memcpy(pOld->pCmpr, pNew->pCmpr, pNew->numOfColumns * sizeof(SColCmpr));
3,243✔
481
  } else {
482
    memcpy(pOld->pCmpr, pNew->pCmpr, pNew->numOfColumns * sizeof(SColCmpr));
13,126✔
483
  }
484

485
  if (pNew->pExtSchemas) {
16,369✔
486
    taosMemoryFreeClear(pOld->pExtSchemas);
12,625!
487
    pOld->pExtSchemas = taosMemoryCalloc(pNew->numOfColumns, sizeof(SExtSchema));
12,625!
488
    if (pOld->pExtSchemas == NULL){
12,625!
UNCOV
489
      goto END;
×
490
    }
491
    memcpy(pOld->pExtSchemas, pNew->pExtSchemas, pNew->numOfColumns * sizeof(SExtSchema));
12,625✔
492
  }
493

494
END:
3,744✔
495
  taosWUnLockLatch(&pOld->lock);
16,369✔
496
  return terrno;
16,369✔
497
}
498

499
SStbObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
913,772✔
500
  SSdb    *pSdb = pMnode->pSdb;
913,772✔
501
  SStbObj *pStb = sdbAcquire(pSdb, SDB_STB, stbName);
913,772✔
502
  if (pStb == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
913,785!
503
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
16,931✔
504
  }
505
  return pStb;
913,777✔
506
}
507

508
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
905,916✔
509
  SSdb *pSdb = pMnode->pSdb;
905,916✔
510
  sdbRelease(pSdb, pStb);
905,916✔
511
}
905,916✔
512

513
SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
15,154✔
514
  SName name = {0};
15,154✔
515
  if ((terrno = tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE)) != 0) return NULL;
15,154!
516

517
  char db[TSDB_TABLE_FNAME_LEN] = {0};
15,154✔
518
  if ((terrno = tNameGetFullDbName(&name, db)) != 0) return NULL;
15,154!
519

520
  return mndAcquireDb(pMnode, db);
15,154✔
521
}
522

523
static FORCE_INLINE int32_t schemaExColIdCompare(const void *colId, const void *pSchema) {
524
  if (*(col_id_t *)colId < ((SSchema *)pSchema)->colId) {
525
    return -1;
526
  } else if (*(col_id_t *)colId > ((SSchema *)pSchema)->colId) {
527
    return 1;
528
  }
529
  return 0;
530
}
531

532
void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen, void *alterOriData,
28,797✔
533
                            int32_t alterOriDataLen) {
534
  SEncoder       encoder = {0};
28,797✔
535
  int32_t        contLen;
536
  SName          name = {0};
28,797✔
537
  SVCreateStbReq req = {0};
28,797✔
538

539
  if ((terrno = tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE)) != 0) {
28,797!
UNCOV
540
    goto _err;
×
541
  }
542
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
28,797✔
543
  if ((terrno = tNameGetFullDbName(&name, dbFName)) != 0) {
28,797!
UNCOV
544
    goto _err;
×
545
  };
546

547
  req.name = (char *)tNameGetTableName(&name);
28,797✔
548
  req.suid = pStb->uid;
28,797✔
549
  req.rollup = pStb->ast1Len > 0 ? 1 : 0;
28,797✔
550
  req.alterOriData = alterOriData;
28,797✔
551
  req.alterOriDataLen = alterOriDataLen;
28,797✔
552
  req.source = pStb->source;
28,797✔
553
  req.virtualStb = pStb->virtualStb;
28,797✔
554
  // todo
555
  req.schemaRow.nCols = pStb->numOfColumns;
28,797✔
556
  req.schemaRow.version = pStb->colVer;
28,797✔
557
  req.schemaRow.pSchema = pStb->pColumns;
28,797✔
558
  req.schemaTag.nCols = pStb->numOfTags;
28,797✔
559
  req.schemaTag.version = pStb->tagVer;
28,797✔
560
  req.schemaTag.pSchema = pStb->pTags;
28,797✔
561

562
  req.colCmpred = 1;
28,797✔
563
  SColCmprWrapper *pCmpr = &req.colCmpr;
28,797✔
564
  req.keep = pStb->keep;
28,797✔
565
  pCmpr->version = pStb->colVer;
28,797✔
566
  pCmpr->nCols = pStb->numOfColumns;
28,797✔
567

568
  req.colCmpr.pColCmpr = taosMemoryCalloc(pCmpr->nCols, sizeof(SColCmpr));
28,797!
569
  for (int32_t i = 0; i < pStb->numOfColumns; i++) {
2,503,120✔
570
    SColCmpr *p = &pCmpr->pColCmpr[i];
2,474,323✔
571
    p->alg = pStb->pCmpr[i].alg;
2,474,323✔
572
    p->id = pStb->pCmpr[i].id;
2,474,323✔
573
  }
574

575
  if (req.rollup) {
28,797✔
576
    req.rsmaParam.maxdelay[0] = pStb->maxdelay[0];
4✔
577
    req.rsmaParam.maxdelay[1] = pStb->maxdelay[1];
4✔
578
    req.rsmaParam.watermark[0] = pStb->watermark[0];
4✔
579
    req.rsmaParam.watermark[1] = pStb->watermark[1];
4✔
580
    if (pStb->ast1Len > 0) {
4!
581
      if (mndConvertRsmaTask(&req.rsmaParam.qmsg[0], &req.rsmaParam.qmsgLen[0], pStb->pAst1, pStb->uid,
4!
582
                             STREAM_TRIGGER_WINDOW_CLOSE, req.rsmaParam.watermark[0],
583
                             req.rsmaParam.deleteMark[0]) < 0) {
UNCOV
584
        goto _err;
×
585
      }
586
    }
587
    if (pStb->ast2Len > 0) {
4!
588
      if (mndConvertRsmaTask(&req.rsmaParam.qmsg[1], &req.rsmaParam.qmsgLen[1], pStb->pAst2, pStb->uid,
4!
589
                             STREAM_TRIGGER_WINDOW_CLOSE, req.rsmaParam.watermark[1],
590
                             req.rsmaParam.deleteMark[1]) < 0) {
UNCOV
591
        goto _err;
×
592
      }
593
    }
594
  }
595
  req.pExtSchemas = pStb->pExtSchemas; // only reference to it.
28,797✔
596
  // get length
597
  int32_t ret = 0;
28,797✔
598
  tEncodeSize(tEncodeSVCreateStbReq, &req, contLen, ret);
28,797!
599
  if (ret < 0) {
28,797!
600
    goto _err;
×
601
  }
602

603
  contLen += sizeof(SMsgHead);
28,797✔
604

605
  SMsgHead *pHead = taosMemoryCalloc(1, contLen);
28,797!
606
  if (pHead == NULL) {
28,797!
UNCOV
607
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
608
    goto _err;
×
609
  }
610

611
  pHead->contLen = htonl(contLen);
28,797✔
612
  pHead->vgId = htonl(pVgroup->vgId);
28,797✔
613

614
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
28,797✔
615
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
28,797✔
616
  if (tEncodeSVCreateStbReq(&encoder, &req) < 0) {
28,797!
UNCOV
617
    taosMemoryFreeClear(pHead);
×
UNCOV
618
    tEncoderClear(&encoder);
×
UNCOV
619
    goto _err;
×
620
  }
621
  tEncoderClear(&encoder);
28,797✔
622

623
  *pContLen = contLen;
28,797✔
624
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
28,797!
625
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
28,797!
626
  taosMemoryFreeClear(req.colCmpr.pColCmpr);
28,797!
627
  return pHead;
28,797✔
UNCOV
628
_err:
×
UNCOV
629
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
×
UNCOV
630
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
×
UNCOV
631
  taosMemoryFreeClear(req.colCmpr.pColCmpr);
×
UNCOV
632
  return NULL;
×
633
}
634

635
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
24,115✔
636
  SName        name = {0};
24,115✔
637
  SVDropStbReq req = {0};
24,115✔
638
  int32_t      contLen = 0;
24,115✔
639
  int32_t      ret = 0;
24,115✔
640
  SMsgHead    *pHead = NULL;
24,115✔
641
  SEncoder     encoder = {0};
24,115✔
642

643
  if ((terrno = tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE)) != 0) {
24,115!
UNCOV
644
    return NULL;
×
645
  }
646

647
  req.name = (char *)tNameGetTableName(&name);
24,115✔
648
  req.suid = pStb->uid;
24,115✔
649

650
  tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
24,115!
651
  if (ret < 0) return NULL;
24,115!
652

653
  contLen += sizeof(SMsgHead);
24,115✔
654
  pHead = taosMemoryMalloc(contLen);
24,115!
655
  if (pHead == NULL) {
24,115!
656
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
657
    return NULL;
×
658
  }
659

660
  pHead->contLen = htonl(contLen);
24,115✔
661
  pHead->vgId = htonl(pVgroup->vgId);
24,115✔
662

663
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
24,115✔
664

665
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
24,115✔
666
  int32_t code = tEncodeSVDropStbReq(&encoder, &req);
24,115✔
667
  tEncoderClear(&encoder);
24,115✔
668
  if (code != 0) {
24,115!
UNCOV
669
    terrno = code;
×
UNCOV
670
    return NULL;
×
671
  }
672

673
  *pContLen = contLen;
24,115✔
674
  return pHead;
24,115✔
675
}
676

677
int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
8,926✔
678
  int32_t code = 0;
8,926✔
679
  if (pCreate->igExists < 0 || pCreate->igExists > 1) {
8,926!
UNCOV
680
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
681
    TAOS_RETURN(code);
×
682
  }
683

684
  if (pCreate->virtualStb != 0 && pCreate->virtualStb != 1) {
8,926!
UNCOV
685
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
686
    TAOS_RETURN(code);
×
687
  }
688

689
  if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfTags + pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
8,926!
690
    code = TSDB_CODE_PAR_INVALID_COLUMNS_NUM;
×
UNCOV
691
    TAOS_RETURN(code);
×
692
  }
693

694
  if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
8,926!
UNCOV
695
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
696
    TAOS_RETURN(code);
×
697
  }
698

699
  SField *pField = taosArrayGet(pCreate->pColumns, 0);
8,926✔
700
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
8,926!
UNCOV
701
    code = TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
UNCOV
702
    TAOS_RETURN(code);
×
703
  }
704

705
  for (int32_t i = 0; i < pCreate->numOfColumns; ++i) {
193,243✔
706
    SFieldWithOptions *pField1 = taosArrayGet(pCreate->pColumns, i);
184,317✔
707
    if (pField1->type >= TSDB_DATA_TYPE_MAX) {
184,317!
708
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
709
      TAOS_RETURN(code);
×
710
    }
711
    if (pField1->bytes <= 0) {
184,317!
UNCOV
712
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
713
      TAOS_RETURN(code);
×
714
    }
715
    if (pField1->name[0] == 0) {
184,317!
UNCOV
716
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
717
      TAOS_RETURN(code);
×
718
    }
719
  }
720

721
  for (int32_t i = 0; i < pCreate->numOfTags; ++i) {
61,796✔
722
    SField *pField1 = taosArrayGet(pCreate->pTags, i);
52,870✔
723
    if (pField1->type >= TSDB_DATA_TYPE_MAX) {
52,870!
UNCOV
724
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
725
      TAOS_RETURN(code);
×
726
    }
727
    if (pField1->bytes <= 0) {
52,870!
728
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
729
      TAOS_RETURN(code);
×
730
    }
731
    if (pField1->name[0] == 0) {
52,870!
732
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
733
      TAOS_RETURN(code);
×
734
    }
735
  }
736

737
  TAOS_RETURN(code);
8,926✔
738
}
739

UNCOV
740
static int32_t mndSetCreateStbPrepareLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
×
UNCOV
741
  int32_t  code = 0;
×
UNCOV
742
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
×
UNCOV
743
  if (pRedoRaw == NULL) {
×
UNCOV
744
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
745
    if (terrno != 0) code = terrno;
×
UNCOV
746
    TAOS_RETURN(code);
×
747
  }
UNCOV
748
  if ((code = mndTransAppendPrepareLog(pTrans, pRedoRaw)) != 0) {
×
UNCOV
749
    sdbFreeRaw(pRedoRaw);
×
UNCOV
750
    TAOS_RETURN(code);
×
751
  }
UNCOV
752
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
×
753

UNCOV
754
  TAOS_RETURN(code);
×
755
}
756

757
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
8,706✔
758
  int32_t  code = 0;
8,706✔
759
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
8,706✔
760
  if (pCommitRaw == NULL) {
8,706!
UNCOV
761
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
762
    if (terrno != 0) code = terrno;
×
UNCOV
763
    TAOS_RETURN(code);
×
764
  }
765
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
8,706!
UNCOV
766
    sdbFreeRaw(pCommitRaw);
×
UNCOV
767
    TAOS_RETURN(code);
×
768
  }
769
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
8,706!
770

771
  TAOS_RETURN(code);
8,706✔
772
}
773

774
static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
8,706✔
775
  int32_t code = 0;
8,706✔
776
  SSdb   *pSdb = pMnode->pSdb;
8,706✔
777
  SVgObj *pVgroup = NULL;
8,706✔
778
  void   *pIter = NULL;
8,706✔
779
  int32_t contLen;
780

781
  while (1) {
76,011✔
782
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
84,717✔
783
    if (pIter == NULL) break;
84,717✔
784
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
76,011✔
785
      sdbRelease(pSdb, pVgroup);
54,365✔
786
      continue;
54,365✔
787
    }
788

789
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, NULL, 0);
21,646✔
790
    if (pReq == NULL) {
21,646!
791
      sdbCancelFetch(pSdb, pIter);
×
792
      sdbRelease(pSdb, pVgroup);
×
UNCOV
793
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
794
      if (terrno != 0) code = terrno;
×
UNCOV
795
      TAOS_RETURN(code);
×
796
    }
797

798
    STransAction action = {0};
21,646✔
799
    action.mTraceId = pTrans->mTraceId;
21,646✔
800
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
21,646✔
801
    action.pCont = pReq;
21,646✔
802
    action.contLen = contLen;
21,646✔
803
    action.msgType = TDMT_VND_CREATE_STB;
21,646✔
804
    action.acceptableCode = TSDB_CODE_TDB_STB_ALREADY_EXIST;
21,646✔
805
    action.retryCode = TSDB_CODE_TDB_STB_NOT_EXIST;
21,646✔
806
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
21,646!
UNCOV
807
      taosMemoryFree(pReq);
×
UNCOV
808
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
809
      sdbRelease(pSdb, pVgroup);
×
UNCOV
810
      TAOS_RETURN(code);
×
811
    }
812
    sdbRelease(pSdb, pVgroup);
21,646✔
813
  }
814

815
  TAOS_RETURN(code);
8,706✔
816
}
817

818
int32_t mndSetForceDropCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, SStbObj *pStb) {
2✔
819
  int32_t code = 0;
2✔
820
  SSdb   *pSdb = pMnode->pSdb;
2✔
821
  int32_t contLen;
822

823
  void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, NULL, 0);
2✔
824
  if (pReq == NULL) {
2!
UNCOV
825
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
826
    if (terrno != 0) code = terrno;
×
UNCOV
827
    TAOS_RETURN(code);
×
828
  }
829

830
  STransAction action = {0};
2✔
831
  action.mTraceId = pTrans->mTraceId;
2✔
832
  action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
2✔
833
  action.pCont = pReq;
2✔
834
  action.contLen = contLen;
2✔
835
  action.msgType = TDMT_VND_CREATE_STB;
2✔
836
  action.acceptableCode = TSDB_CODE_TDB_STB_ALREADY_EXIST;
2✔
837
  action.retryCode = TSDB_CODE_TDB_STB_NOT_EXIST;
2✔
838
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2!
UNCOV
839
    taosMemoryFree(pReq);
×
UNCOV
840
    TAOS_RETURN(code);
×
841
  }
842

843
  TAOS_RETURN(code);
2✔
844
}
845

846
static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
8,706✔
847
  int32_t code = 0;
8,706✔
848
  SSdb   *pSdb = pMnode->pSdb;
8,706✔
849
  SVgObj *pVgroup = NULL;
8,706✔
850
  void   *pIter = NULL;
8,706✔
851

852
  while (1) {
76,011✔
853
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
84,717✔
854
    if (pIter == NULL) break;
84,717✔
855
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
76,011✔
856
      sdbRelease(pSdb, pVgroup);
54,365✔
857
      continue;
54,365✔
858
    }
859

860
    int32_t contLen = 0;
21,646✔
861
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
21,646✔
862
    if (pReq == NULL) {
21,646!
UNCOV
863
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
864
      sdbRelease(pSdb, pVgroup);
×
UNCOV
865
      code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
866
      TAOS_RETURN(code);
×
867
    }
868

869
    STransAction action = {0};
21,646✔
870
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
21,646✔
871
    action.pCont = pReq;
21,646✔
872
    action.contLen = contLen;
21,646✔
873
    action.msgType = TDMT_VND_DROP_STB;
21,646✔
874
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
21,646✔
875
    if ((code = mndTransAppendUndoAction(pTrans, &action)) != 0) {
21,646!
UNCOV
876
      taosMemoryFree(pReq);
×
UNCOV
877
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
878
      sdbRelease(pSdb, pVgroup);
×
UNCOV
879
      TAOS_RETURN(code);
×
880
    }
881
    sdbRelease(pSdb, pVgroup);
21,646✔
882
  }
883

884
  TAOS_RETURN(code);
8,706✔
885
}
886

UNCOV
887
static SSchema *mndFindStbColumns(const SStbObj *pStb, const char *colName) {
×
UNCOV
888
  for (int32_t col = 0; col < pStb->numOfColumns; ++col) {
×
UNCOV
889
    SSchema *pSchema = &pStb->pColumns[col];
×
UNCOV
890
    if (taosStrncasecmp(pSchema->name, colName, TSDB_COL_NAME_LEN) == 0) {
×
UNCOV
891
      return pSchema;
×
892
    }
893
  }
894
  return NULL;
×
895
}
896

897
int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreate, SDbObj *pDb) {
8,728✔
898
  int32_t code = 0;
8,728✔
899
  bool    hasTypeMods = false;
8,728✔
900
  memcpy(pDst->name, pCreate->name, TSDB_TABLE_FNAME_LEN);
8,728✔
901
  memcpy(pDst->db, pDb->name, TSDB_DB_FNAME_LEN);
8,728✔
902
  pDst->createdTime = taosGetTimestampMs();
8,728✔
903
  pDst->updateTime = pDst->createdTime;
8,728✔
904
  pDst->uid = (pCreate->source == TD_REQ_FROM_TAOX_OLD || pCreate->source == TD_REQ_FROM_TAOX)
8,728✔
905
                  ? pCreate->suid
906
                  : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
17,456!
907
  pDst->dbUid = pDb->uid;
8,728✔
908
  pDst->tagVer = 1;
8,728✔
909
  pDst->colVer = 1;
8,728✔
910
  pDst->smaVer = 1;
8,728✔
911
  pDst->nextColId = 1;
8,728✔
912
  pDst->maxdelay[0] = pCreate->delay1;
8,728✔
913
  pDst->maxdelay[1] = pCreate->delay2;
8,728✔
914
  pDst->watermark[0] = pCreate->watermark1;
8,728✔
915
  pDst->watermark[1] = pCreate->watermark2;
8,728✔
916
  pDst->ttl = pCreate->ttl;
8,728✔
917
  pDst->numOfColumns = pCreate->numOfColumns;
8,728✔
918
  pDst->numOfTags = pCreate->numOfTags;
8,728✔
919
  pDst->numOfFuncs = pCreate->numOfFuncs;
8,728✔
920
  pDst->commentLen = pCreate->commentLen;
8,728✔
921
  pDst->pFuncs = pCreate->pFuncs;
8,728✔
922
  pDst->source = pCreate->source;
8,728✔
923
  pDst->keep = pCreate->keep;
8,728✔
924
  pDst->virtualStb = pCreate->virtualStb;
8,728✔
925
  pCreate->pFuncs = NULL;
8,728✔
926

927
  if (pDst->commentLen > 0) {
8,728✔
928
    pDst->comment = taosMemoryCalloc(pDst->commentLen + 1, 1);
18!
929
    if (pDst->comment == NULL) {
18!
UNCOV
930
      code = terrno;
×
UNCOV
931
      TAOS_RETURN(code);
×
932
    }
933
    memcpy(pDst->comment, pCreate->pComment, pDst->commentLen + 1);
18✔
934
  }
935

936
  pDst->ast1Len = pCreate->ast1Len;
8,728✔
937
  if (pDst->ast1Len > 0) {
8,728✔
938
    pDst->pAst1 = taosMemoryCalloc(pDst->ast1Len, 1);
3!
939
    if (pDst->pAst1 == NULL) {
3!
UNCOV
940
      code = terrno;
×
UNCOV
941
      TAOS_RETURN(code);
×
942
    }
943
    memcpy(pDst->pAst1, pCreate->pAst1, pDst->ast1Len);
3✔
944
  }
945

946
  pDst->ast2Len = pCreate->ast2Len;
8,728✔
947
  if (pDst->ast2Len > 0) {
8,728✔
948
    pDst->pAst2 = taosMemoryCalloc(pDst->ast2Len, 1);
3!
949
    if (pDst->pAst2 == NULL) {
3!
UNCOV
950
      code = terrno;
×
UNCOV
951
      TAOS_RETURN(code);
×
952
    }
953
    memcpy(pDst->pAst2, pCreate->pAst2, pDst->ast2Len);
3✔
954
  }
955

956
  pDst->pColumns = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SSchema));
8,728!
957
  pDst->pTags = taosMemoryCalloc(1, pDst->numOfTags * sizeof(SSchema));
8,728!
958
  if (pDst->pColumns == NULL || pDst->pTags == NULL) {
8,728!
UNCOV
959
    code = terrno;
×
UNCOV
960
    TAOS_RETURN(code);
×
961
  }
962

963
  if (pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags) {
8,728!
UNCOV
964
    code = TSDB_CODE_OUT_OF_RANGE;
×
UNCOV
965
    TAOS_RETURN(code);
×
966
  }
967

968
  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
191,890✔
969
    SFieldWithOptions *pField = taosArrayGet(pCreate->pColumns, i);
183,162✔
970
    SSchema           *pSchema = &pDst->pColumns[i];
183,162✔
971
    pSchema->type = pField->type;
183,162✔
972
    pSchema->bytes = pField->bytes;
183,162✔
973
    pSchema->flags = pField->flags;
183,162✔
974
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
183,162✔
975
    pSchema->colId = pDst->nextColId;
183,162✔
976
    pDst->nextColId++;
183,162✔
977
    hasTypeMods = hasTypeMods || HAS_TYPE_MOD(pSchema);
183,162✔
978
  }
979

980
  for (int32_t i = 0; i < pDst->numOfTags; ++i) {
60,539✔
981
    SField  *pField = taosArrayGet(pCreate->pTags, i);
51,811✔
982
    SSchema *pSchema = &pDst->pTags[i];
51,811✔
983
    pSchema->type = pField->type;
51,811✔
984
    pSchema->bytes = pField->bytes;
51,811✔
985
    if (i == 0) {
51,811✔
986
      SSCHMEA_SET_IDX_ON(pSchema);
8,728✔
987
    }
988
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
51,811✔
989
    pSchema->colId = pDst->nextColId;
51,811✔
990
    pDst->nextColId++;
51,811✔
991
  }
992
  // set col compress
993
  pDst->pCmpr = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SCmprObj));
8,728!
994
  for (int32_t i = 0; i < pDst->numOfColumns; i++) {
191,890✔
995
    SFieldWithOptions *pField = taosArrayGet(pCreate->pColumns, i);
183,162✔
996
    SSchema           *pSchema = &pDst->pColumns[i];
183,162✔
997

998
    SColCmpr *pColCmpr = &pDst->pCmpr[i];
183,162✔
999
    pColCmpr->id = pSchema->colId;
183,162✔
1000
    pColCmpr->alg = pField->compress;
183,162✔
1001
  }
1002

1003
  if (hasTypeMods) {
8,728✔
1004
    pDst->pExtSchemas = taosMemoryCalloc(pDst->numOfColumns, sizeof(SExtSchema));
32!
1005
    if (!pDst->pExtSchemas) {
32!
UNCOV
1006
      code = terrno;
×
UNCOV
1007
      TAOS_RETURN(code);
×
1008
    }
1009
    for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
424✔
1010
      SFieldWithOptions * pField = taosArrayGet(pCreate->pColumns, i);
392✔
1011
      pDst->pExtSchemas[i].typeMod = pField->typeMod;
392✔
1012
    }
1013
  }
1014
  TAOS_RETURN(code);
8,728✔
1015
}
1016
static int32_t mndGenIdxNameForFirstTag(char *fullname, char *dbname, char *stbname, char *tagname) {
7,101✔
1017
  SName name = {0};
7,101✔
1018
  if ((terrno = tNameFromString(&name, stbname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE)) != 0) {
7,101!
UNCOV
1019
    return -1;
×
1020
  }
1021
  return snprintf(fullname, TSDB_INDEX_FNAME_LEN, "%s.%s_%s", dbname, tagname, tNameGetTableName(&name));
7,101✔
1022
}
1023

1024
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
7,101✔
1025
  SStbObj stbObj = {0};
7,101✔
1026
  int32_t code = -1;
7,101✔
1027

1028
  char fullIdxName[TSDB_INDEX_FNAME_LEN * 2] = {0};
7,101✔
1029

1030
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq, "create-stb");
7,101✔
1031
  if (pTrans == NULL) {
7,101!
UNCOV
1032
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
1033
    if (terrno != 0) code = terrno;
×
UNCOV
1034
    goto _OVER;
×
1035
  }
1036

1037
  mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
7,101!
1038
  TAOS_CHECK_GOTO(mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb), NULL, _OVER);
7,101!
1039

1040
  SSchema *pSchema = &(stbObj.pTags[0]);
7,101✔
1041
  if (mndGenIdxNameForFirstTag(fullIdxName, pDb->name, stbObj.name, pSchema->name) < 0) {
7,101!
UNCOV
1042
    goto _OVER;
×
1043
  }
1044
  SSIdx idx = {0};
7,101✔
1045
  if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) {
7,101!
UNCOV
1046
    code = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST;
×
UNCOV
1047
    mndReleaseIdx(pMnode, idx.pIdx);
×
UNCOV
1048
    goto _OVER;
×
1049
  }
1050

1051
  SIdxObj idxObj = {0};
7,101✔
1052
  memcpy(idxObj.name, fullIdxName, TSDB_INDEX_FNAME_LEN);
7,101✔
1053
  memcpy(idxObj.stb, stbObj.name, TSDB_TABLE_FNAME_LEN);
7,101✔
1054
  memcpy(idxObj.db, stbObj.db, TSDB_DB_FNAME_LEN);
7,101✔
1055
  memcpy(idxObj.colName, pSchema->name, TSDB_COL_NAME_LEN);
7,101✔
1056
  idxObj.createdTime = taosGetTimestampMs();
7,101✔
1057
  idxObj.uid = mndGenerateUid(fullIdxName, strlen(fullIdxName));
7,101✔
1058
  idxObj.stbUid = stbObj.uid;
7,101✔
1059
  idxObj.dbUid = stbObj.dbUid;
7,101✔
1060

1061
  TAOS_CHECK_GOTO(mndSetCreateIdxCommitLogs(pMnode, pTrans, &idxObj), NULL, _OVER);
7,101!
1062

1063
  TAOS_CHECK_GOTO(mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj), NULL, _OVER);
7,101✔
1064
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
7,079✔
1065
  code = 0;
7,076✔
1066

1067
_OVER:
7,101✔
1068
  mndTransDrop(pTrans);
7,101✔
1069
  if (mndStbActionDelete(pMnode->pSdb, &stbObj) != 0) mError("failed to mndStbActionDelete");
7,101!
1070
  TAOS_RETURN(code);
7,101✔
1071
}
1072

1073
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
8,728✔
1074
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
8,728✔
1075
  TAOS_CHECK_RETURN(mndTransCheckConflict(pMnode, pTrans));
8,728✔
1076
  TAOS_CHECK_RETURN(mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, pStb));
8,706!
1077
  TAOS_CHECK_RETURN(mndSetCreateStbRedoActions(pMnode, pTrans, pDb, pStb));
8,706!
1078
  TAOS_CHECK_RETURN(mndSetCreateStbUndoActions(pMnode, pTrans, pDb, pStb));
8,706!
1079
  return 0;
8,706✔
1080
}
1081

1082
static int32_t mndProcessTtlTimer(SRpcMsg *pReq) {
6,871✔
1083
  SMnode           *pMnode = pReq->info.node;
6,871✔
1084
  SSdb             *pSdb = pMnode->pSdb;
6,871✔
1085
  SVgObj           *pVgroup = NULL;
6,871✔
1086
  void             *pIter = NULL;
6,871✔
1087
  SVDropTtlTableReq ttlReq = {
6,871✔
1088
      .timestampSec = taosGetTimestampSec(), .ttlDropMaxCount = tsTtlBatchDropNum, .nUids = 0, .pTbUids = NULL};
6,871✔
1089
  int32_t reqLen = tSerializeSVDropTtlTableReq(NULL, 0, &ttlReq);
6,871✔
1090
  int32_t contLen = reqLen + sizeof(SMsgHead);
6,871✔
1091

1092
  mDebug("start to process ttl timer");
6,871✔
1093

1094
  while (1) {
113,317✔
1095
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
120,188✔
1096
    if (pIter == NULL) break;
120,188✔
1097

1098
    int32_t   code = 0;
113,317✔
1099
    SMsgHead *pHead = rpcMallocCont(contLen);
113,317✔
1100
    if (pHead == NULL) {
113,317!
1101
      sdbRelease(pSdb, pVgroup);
×
UNCOV
1102
      continue;
×
1103
    }
1104
    pHead->contLen = htonl(contLen);
113,317✔
1105
    pHead->vgId = htonl(pVgroup->vgId);
113,317✔
1106
    if ((code = tSerializeSVDropTtlTableReq((char *)pHead + sizeof(SMsgHead), reqLen, &ttlReq)) < 0) {
113,317!
UNCOV
1107
      mError("vgId:%d, failed to serialize drop ttl table request since %s", pVgroup->vgId, tstrerror(code));
×
1108
      sdbRelease(pSdb, pVgroup);
×
UNCOV
1109
      continue;
×
1110
    }
1111

1112
    SRpcMsg rpcMsg = {
113,317✔
1113
        .msgType = TDMT_VND_FETCH_TTL_EXPIRED_TBS, .pCont = pHead, .contLen = contLen, .info = pReq->info};
1114
    SEpSet epSet = mndGetVgroupEpset(pMnode, pVgroup);
113,317✔
1115
    code = tmsgSendReq(&epSet, &rpcMsg);
113,317✔
1116
    if (code != 0) {
113,317✔
1117
      mError("vgId:%d, failed to send drop ttl table request to vnode since 0x%x", pVgroup->vgId, code);
47!
1118
    } else {
1119
      mDebug("vgId:%d, send drop ttl table request to vnode, time:%" PRId32, pVgroup->vgId, ttlReq.timestampSec);
113,270✔
1120
    }
1121
    sdbRelease(pSdb, pVgroup);
113,317✔
1122
  }
1123

1124
  return 0;
6,871✔
1125
}
1126

1127
static int32_t mndProcessTrimDbTimer(SRpcMsg *pReq) {
5✔
1128
  SMnode     *pMnode = pReq->info.node;
5✔
1129
  SSdb       *pSdb = pMnode->pSdb;
5✔
1130
  SVgObj     *pVgroup = NULL;
5✔
1131
  void       *pIter = NULL;
5✔
1132
  SVTrimDbReq trimReq = {.timestamp = taosGetTimestampSec()};
5✔
1133
  int32_t     reqLen = tSerializeSVTrimDbReq(NULL, 0, &trimReq);
5✔
1134
  int32_t     contLen = reqLen + sizeof(SMsgHead);
5✔
1135

1136
  while (1) {
239✔
1137
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
244✔
1138
    if (pIter == NULL) break;
244✔
1139

1140
    int32_t code = 0;
239✔
1141

1142
    SMsgHead *pHead = rpcMallocCont(contLen);
239✔
1143
    if (pHead == NULL) {
239!
UNCOV
1144
      sdbCancelFetch(pSdb, pVgroup);
×
UNCOV
1145
      sdbRelease(pSdb, pVgroup);
×
1146
      continue;
×
1147
    }
1148
    pHead->contLen = htonl(contLen);
239✔
1149
    pHead->vgId = htonl(pVgroup->vgId);
239✔
1150
    if ((code = tSerializeSVTrimDbReq((char *)pHead + sizeof(SMsgHead), reqLen, &trimReq)) < 0) {
239!
UNCOV
1151
      mError("vgId:%d, failed to serialize trim db request since %s", pVgroup->vgId, tstrerror(code));
×
1152
    }
1153

1154
    SRpcMsg rpcMsg = {.msgType = TDMT_VND_TRIM, .pCont = pHead, .contLen = contLen};
239✔
1155
    SEpSet  epSet = mndGetVgroupEpset(pMnode, pVgroup);
239✔
1156
    code = tmsgSendReq(&epSet, &rpcMsg);
239✔
1157
    if (code != 0) {
239!
UNCOV
1158
      mError("vgId:%d, timer failed to send vnode-trim request to vnode since 0x%x", pVgroup->vgId, code);
×
1159
    } else {
1160
      mInfo("vgId:%d, timer send vnode-trim request to vnode, time:%d", pVgroup->vgId, trimReq.timestamp);
239!
1161
    }
1162
    sdbRelease(pSdb, pVgroup);
239✔
1163
  }
1164

1165
  return 0;
5✔
1166
}
1167

UNCOV
1168
static int32_t mndProcessS3MigrateDbTimer(SRpcMsg *pReq) {
×
UNCOV
1169
  SMnode          *pMnode = pReq->info.node;
×
UNCOV
1170
  SSdb            *pSdb = pMnode->pSdb;
×
UNCOV
1171
  SVgObj          *pVgroup = NULL;
×
UNCOV
1172
  void            *pIter = NULL;
×
UNCOV
1173
  SVS3MigrateDbReq s3migrateReq = {.timestamp = taosGetTimestampSec()};
×
UNCOV
1174
  int32_t          reqLen = tSerializeSVS3MigrateDbReq(NULL, 0, &s3migrateReq);
×
UNCOV
1175
  int32_t          contLen = reqLen + sizeof(SMsgHead);
×
1176

UNCOV
1177
  while (1) {
×
UNCOV
1178
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
×
UNCOV
1179
    if (pIter == NULL) break;
×
1180

UNCOV
1181
    int32_t code = 0;
×
1182

UNCOV
1183
    SMsgHead *pHead = rpcMallocCont(contLen);
×
UNCOV
1184
    if (pHead == NULL) {
×
UNCOV
1185
      sdbRelease(pSdb, pVgroup);
×
UNCOV
1186
      continue;
×
1187
    }
UNCOV
1188
    pHead->contLen = htonl(contLen);
×
UNCOV
1189
    pHead->vgId = htonl(pVgroup->vgId);
×
UNCOV
1190
    if ((code = tSerializeSVS3MigrateDbReq((char *)pHead + sizeof(SMsgHead), reqLen, &s3migrateReq)) < 0) {
×
UNCOV
1191
      mError("vgId:%d, failed to serialize s3migrate db request since %s", pVgroup->vgId, tstrerror(code));
×
UNCOV
1192
      sdbRelease(pSdb, pVgroup);
×
UNCOV
1193
      continue;
×
1194
    }
1195

UNCOV
1196
    SRpcMsg rpcMsg = {.msgType = TDMT_VND_S3MIGRATE, .pCont = pHead, .contLen = contLen};
×
UNCOV
1197
    SEpSet  epSet = mndGetVgroupEpset(pMnode, pVgroup);
×
UNCOV
1198
    code = tmsgSendReq(&epSet, &rpcMsg);
×
UNCOV
1199
    if (code != 0) {
×
UNCOV
1200
      mError("vgId:%d, timer failed to send vnode-s3migrate request to vnode since 0x%x", pVgroup->vgId, code);
×
1201
    } else {
UNCOV
1202
      mInfo("vgId:%d, timer send vnode-s3migrate request to vnode, time:%d", pVgroup->vgId, s3migrateReq.timestamp);
×
1203
    }
UNCOV
1204
    sdbRelease(pSdb, pVgroup);
×
1205
  }
1206

UNCOV
1207
  return 0;
×
1208
}
1209

1210
static int32_t mndFindSuperTableTagIndex(const SStbObj *pStb, const char *tagName) {
3,688✔
1211
  for (int32_t tag = 0; tag < pStb->numOfTags; tag++) {
92,868✔
1212
    if (strcmp(pStb->pTags[tag].name, tagName) == 0) {
90,590✔
1213
      return tag;
1,410✔
1214
    }
1215
  }
1216

1217
  return -1;
2,278✔
1218
}
1219

1220
static int32_t mndFindSuperTableColumnIndex(const SStbObj *pStb, const char *colName) {
3,015✔
1221
  for (int32_t col = 0; col < pStb->numOfColumns; col++) {
907,882✔
1222
    if (strcmp(pStb->pColumns[col].name, colName) == 0) {
905,584✔
1223
      return col;
717✔
1224
    }
1225
  }
1226

1227
  return -1;
2,298✔
1228
}
1229

1230
static bool mndValidateSchema(SSchema *pSchemas, int32_t nSchema, SArray *pFields, int32_t maxLen) {
1,674✔
1231
  int32_t rowLen = 0;
1,674✔
1232
  for (int32_t i = 0; i < nSchema; ++i) {
531,619✔
1233
    rowLen += (pSchemas + i)->bytes;
529,945✔
1234
  }
1235

1236
  int32_t nField = taosArrayGetSize(pFields);
1,674✔
1237
  for (int32_t i = 0; i < nField; ++i) {
3,348✔
1238
    rowLen += ((SField *)TARRAY_GET_ELEM(pFields, i))->bytes;
1,674✔
1239
  }
1240

1241
  return rowLen <= maxLen;
1,674✔
1242
}
1243

1244
static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq *createReq) {
74✔
1245
  int32_t code = 0;
74✔
1246
  taosRLockLatch(&pStb->lock);
74✔
1247
  memcpy(pDst, pStb, sizeof(SStbObj));
74✔
1248
  taosRUnLockLatch(&pStb->lock);
74✔
1249

1250
  pDst->source = createReq->source;
74✔
1251
  pDst->updateTime = taosGetTimestampMs();
74✔
1252
  pDst->numOfColumns = createReq->numOfColumns;
74✔
1253
  pDst->numOfTags = createReq->numOfTags;
74✔
1254
  pDst->pColumns = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SSchema));
74!
1255
  pDst->pTags = taosMemoryCalloc(1, pDst->numOfTags * sizeof(SSchema));
74!
1256
  pDst->pCmpr = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SColCmpr));
74!
1257
  pDst->pExtSchemas = taosMemoryCalloc(pDst->numOfColumns, sizeof(SExtSchema));
74!
1258

1259
  if (pDst->pColumns == NULL || pDst->pTags == NULL || pDst->pCmpr == NULL || pDst->pExtSchemas == NULL) {
74!
UNCOV
1260
    code = terrno;
×
UNCOV
1261
    TAOS_RETURN(code);
×
1262
  }
1263

1264
  if (pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags) {
74!
UNCOV
1265
    code = TSDB_CODE_OUT_OF_RANGE;
×
UNCOV
1266
    TAOS_RETURN(code);
×
1267
  }
1268

1269
  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
517✔
1270
    SFieldWithOptions *pField = taosArrayGet(createReq->pColumns, i);
443✔
1271
    SSchema           *pSchema = &pDst->pColumns[i];
443✔
1272
    pSchema->type = pField->type;
443✔
1273
    pSchema->bytes = pField->bytes;
443✔
1274
    pSchema->flags = pField->flags;
443✔
1275
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
443✔
1276
    int32_t cIndex = mndFindSuperTableColumnIndex(pStb, pField->name);
443✔
1277
    if (cIndex >= 0) {
443✔
1278
      pSchema->colId = pStb->pColumns[cIndex].colId;
395✔
1279
    } else {
1280
      pSchema->colId = pDst->nextColId++;
48✔
1281
    }
1282
  }
1283

1284
  for (int32_t i = 0; i < pDst->numOfTags; ++i) {
479✔
1285
    SField  *pField = taosArrayGet(createReq->pTags, i);
405✔
1286
    SSchema *pSchema = &pDst->pTags[i];
405✔
1287
    pSchema->type = pField->type;
405✔
1288
    pSchema->bytes = pField->bytes;
405✔
1289
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
405✔
1290
    int32_t cIndex = mndFindSuperTableTagIndex(pStb, pField->name);
405✔
1291
    if (cIndex >= 0) {
405✔
1292
      pSchema->colId = pStb->pTags[cIndex].colId;
367✔
1293
    } else {
1294
      pSchema->colId = pDst->nextColId++;
38✔
1295
    }
1296
  }
1297
  for (int32_t i = 0; i < pDst->numOfColumns; i++) {
517✔
1298
    SColCmpr          *p = pDst->pCmpr + i;
443✔
1299
    SFieldWithOptions *pField = taosArrayGet(createReq->pColumns, i);
443✔
1300
    SSchema           *pSchema = &pDst->pColumns[i];
443✔
1301
    p->id = pSchema->colId;
443✔
1302
    if (pField->compress == 0) {
443!
1303
      p->alg = createDefaultColCmprByType(pSchema->type);
×
1304
    } else {
1305
      p->alg = pField->compress;
443✔
1306
    }
1307
    if (pField->flags & COL_HAS_TYPE_MOD) {
443✔
1308
      pDst->pExtSchemas[i].typeMod = pField->typeMod;
20✔
1309
    }
1310
  }
1311
  pDst->tagVer = createReq->tagVer;
74✔
1312
  pDst->colVer = createReq->colVer;
74✔
1313
  return TSDB_CODE_SUCCESS;
74✔
1314
}
1315

1316
static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
7,299✔
1317
  SMnode        *pMnode = pReq->info.node;
7,299✔
1318
  int32_t        code = -1;
7,299✔
1319
  SStbObj       *pStb = NULL;
7,299✔
1320
  SDbObj        *pDb = NULL;
7,299✔
1321
  SMCreateStbReq createReq = {0};
7,299✔
1322
  bool           isAlter = false;
7,299✔
1323
  SHashObj      *pHash = NULL;
7,299✔
1324

1325
  if (tDeserializeSMCreateStbReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
7,299!
UNCOV
1326
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
1327
    goto _OVER;
×
1328
  }
1329

1330
  mInfo("stb:%s, start to create", createReq.name);
7,299!
1331
  if (mndCheckCreateStbReq(&createReq) != 0) {
7,299!
UNCOV
1332
    code = TSDB_CODE_INVALID_MSG;
×
1333
    goto _OVER;
×
1334
  }
1335

1336
  pStb = mndAcquireStb(pMnode, createReq.name);
7,299✔
1337
  if (pStb != NULL) {
7,299✔
1338
    if (createReq.igExists) {
194✔
1339
      if (createReq.source == TD_REQ_FROM_APP) {
191✔
1340
        mInfo("stb:%s, already exist, ignore exist is set", createReq.name);
12!
1341
        code = 0;
12✔
1342
        goto _OVER;
12✔
1343
      } else if (pStb->uid != createReq.suid) {
179!
UNCOV
1344
        mInfo("stb:%s, alter table does not need to be done, because table is deleted", createReq.name);
×
UNCOV
1345
        code = 0;
×
UNCOV
1346
        goto _OVER;
×
1347
      } else if (createReq.tagVer > 0 || createReq.colVer > 0) {
253!
1348
        int32_t tagDelta = createReq.tagVer - pStb->tagVer;
179✔
1349
        int32_t colDelta = createReq.colVer - pStb->colVer;
179✔
1350
        mInfo("stb:%s, already exist while create, input tagVer:%d colVer:%d, exist tagVer:%d colVer:%d",
179!
1351
              createReq.name, createReq.tagVer, createReq.colVer, pStb->tagVer, pStb->colVer);
1352
        if (tagDelta <= 0 && colDelta <= 0) {
179✔
1353
          mInfo("stb:%s, schema version is not incremented and nothing needs to be done", createReq.name);
105!
1354
          code = 0;
105✔
1355
          goto _OVER;
105✔
1356
        } else if ((tagDelta == 1 && colDelta == 0) || (tagDelta == 0 && colDelta == 1) ||
74!
UNCOV
1357
                   (pStb->colVer == 1 && createReq.colVer > 1) || (pStb->tagVer == 1 && createReq.tagVer > 1)) {
×
1358
          isAlter = true;
74✔
1359
          mInfo("stb:%s, schema version is only increased by 1 number, do alter operation", createReq.name);
74!
1360
        } else {
UNCOV
1361
          mError("stb:%s, schema version increase more than 1 number, error is returned", createReq.name);
×
UNCOV
1362
          code = TSDB_CODE_MND_INVALID_SCHEMA_VER;
×
UNCOV
1363
          goto _OVER;
×
1364
        }
1365
      } else {
UNCOV
1366
        mError("stb:%s, already exist while create, input tagVer:%d colVer:%d is invalid, origin tagVer:%d colVer:%d",
×
1367
               createReq.name, createReq.tagVer, createReq.colVer, pStb->tagVer, pStb->colVer);
UNCOV
1368
        code = TSDB_CODE_MND_INVALID_SCHEMA_VER;
×
1369
        goto _OVER;
×
1370
      }
1371
    } else {
1372
      code = TSDB_CODE_MND_STB_ALREADY_EXIST;
3✔
1373
      goto _OVER;
3✔
1374
    }
1375
  } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) {
7,105!
UNCOV
1376
    goto _OVER;
×
1377
  } else if ((createReq.source == TD_REQ_FROM_TAOX_OLD || createReq.source == TD_REQ_FROM_TAOX) &&
7,105!
1378
             (createReq.tagVer != 1 || createReq.colVer != 1)) {
53✔
1379
    mInfo("stb:%s, alter table does not need to be done, because table is deleted", createReq.name);
3!
1380
    code = 0;
3✔
1381
    goto _OVER;
3✔
1382
  }
1383

1384
  pHash = taosHashInit(createReq.numOfColumns + createReq.numOfTags, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY),
7,176✔
1385
                       false, HASH_NO_LOCK);
1386
  if (pHash == NULL) {
7,176!
1387
    code = TSDB_CODE_OUT_OF_MEMORY;
×
1388
    goto _OVER;
×
1389
  }
1390

1391
  for (int32_t i = 0; i < createReq.numOfColumns; ++i) {
131,605✔
1392
    SFieldWithOptions *pField = taosArrayGet(createReq.pColumns, i);
124,429✔
1393
    if ((code = taosHashPut(pHash, pField->name, strlen(pField->name), NULL, 0)) != 0) {
124,429!
UNCOV
1394
      if (code == TSDB_CODE_DUP_KEY) {
×
UNCOV
1395
        code = TSDB_CODE_TSC_DUP_COL_NAMES;
×
1396
      }
UNCOV
1397
      goto _OVER;
×
1398
    }
1399
  }
1400

1401
  for (int32_t i = 0; i < createReq.numOfTags; ++i) {
56,454✔
1402
    SField *pField = taosArrayGet(createReq.pTags, i);
49,279✔
1403
    if ((code = taosHashPut(pHash, pField->name, strlen(pField->name), NULL, 0)) != 0) {
49,279✔
1404
      if (code == TSDB_CODE_DUP_KEY) {
1!
1405
        code = TSDB_CODE_TSC_DUP_COL_NAMES;
1✔
1406
      }
1407
      goto _OVER;
1✔
1408
    }
1409
  }
1410

1411
  pDb = mndAcquireDbByStb(pMnode, createReq.name);
7,175✔
1412
  if (pDb == NULL) {
7,175!
UNCOV
1413
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
×
UNCOV
1414
    goto _OVER;
×
1415
  }
1416

1417
  if ((code = mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb)) != 0) {
7,175!
UNCOV
1418
    goto _OVER;
×
1419
  }
1420

1421
  int32_t numOfStbs = -1;
7,175✔
1422
  if ((code = mndGetNumOfStbs(pMnode, pDb->name, &numOfStbs)) != 0) {
7,175!
UNCOV
1423
    goto _OVER;
×
1424
  }
1425

1426
  if (pDb->cfg.numOfStables == 1 && numOfStbs != 0) {
7,175!
UNCOV
1427
    code = TSDB_CODE_MND_SINGLE_STB_MODE_DB;
×
UNCOV
1428
    goto _OVER;
×
1429
  }
1430

1431
  if ((code = grantCheck(TSDB_GRANT_STABLE)) < 0) {
7,175!
1432
    goto _OVER;
×
1433
  }
1434

1435
  if (isAlter) {
7,175✔
1436
    bool    needRsp = false;
74✔
1437
    SStbObj pDst = {0};
74✔
1438
    if ((code = mndBuildStbFromAlter(pStb, &pDst, &createReq)) != 0) {
74!
1439
      taosMemoryFreeClear(pDst.pTags);
×
1440
      taosMemoryFreeClear(pDst.pColumns);
×
1441
      taosMemoryFreeClear(pDst.pCmpr);
×
1442
      taosMemoryFreeClear(pDst.pExtSchemas);
×
1443
      goto _OVER;
×
1444
    }
1445

1446
    code = mndAlterStbImp(pMnode, pReq, pDb, &pDst, needRsp, NULL, 0);
74✔
1447
    taosMemoryFreeClear(pDst.pTags);
74!
1448
    taosMemoryFreeClear(pDst.pColumns);
74!
1449
    taosMemoryFreeClear(pDst.pCmpr);
74!
1450
    taosMemoryFreeClear(pDst.pExtSchemas);
74!
1451
  } else {
1452
    code = mndCreateStb(pMnode, pReq, &createReq, pDb);
7,101✔
1453
  }
1454
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
7,175✔
1455

1456
  SName name = {0};
7,175✔
1457
  TAOS_CHECK_RETURN(tNameFromString(&name, createReq.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
7,175!
1458

1459
  if (createReq.sql == NULL && createReq.sqlLen == 0) {
8,058!
1460
    char detail[1000] = {0};
883✔
1461

1462
    (void)tsnprintf(detail, sizeof(detail), "dbname:%s, stable name:%s", name.dbname, name.tname);
883✔
1463

1464
    auditRecord(pReq, pMnode->clusterId, "createStb", name.dbname, name.tname, detail, strlen(detail));
883✔
1465
  } else {
1466
    auditRecord(pReq, pMnode->clusterId, "createStb", name.dbname, name.tname, createReq.sql, createReq.sqlLen);
6,292✔
1467
  }
1468
_OVER:
7,299✔
1469
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
7,299✔
1470
    mError("stb:%s, failed to create since %s", createReq.name, tstrerror(code));
29!
1471
  }
1472

1473
  mndReleaseStb(pMnode, pStb);
7,299✔
1474
  mndReleaseDb(pMnode, pDb);
7,299✔
1475
  tFreeSMCreateStbReq(&createReq);
7,299✔
1476

1477
  if (pHash != NULL) {
7,299✔
1478
    taosHashCleanup(pHash);
7,176✔
1479
  }
1480

1481
  TAOS_RETURN(code);
7,299✔
1482
}
1483

1484
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
3,046✔
1485
  int32_t code = 0;
3,046✔
1486
  if (pAlter->commentLen >= 0) return 0;
3,046!
UNCOV
1487
  if (pAlter->ttl != 0) return 0;
×
UNCOV
1488
  if (pAlter->keep != -1) return 0;
×
1489

1490
  if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
×
UNCOV
1491
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
1492
    TAOS_RETURN(code);
×
1493
  }
1494

UNCOV
1495
  for (int32_t i = 0; i < pAlter->numOfFields; ++i) {
×
UNCOV
1496
    SField *pField = taosArrayGet(pAlter->pFields, i);
×
UNCOV
1497
    if (pField->name[0] == 0) {
×
1498
      code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
1499
      TAOS_RETURN(code);
×
1500
    }
1501
  }
1502

1503
  TAOS_RETURN(code);
×
1504
}
1505

1506
int32_t mndAllocStbSchemas(const SStbObj *pOld, SStbObj *pNew) {
4,439✔
1507
  pNew->pTags = taosMemoryCalloc(pNew->numOfTags, sizeof(SSchema));
4,439!
1508
  pNew->pColumns = taosMemoryCalloc(pNew->numOfColumns, sizeof(SSchema));
4,439!
1509
  pNew->pCmpr = taosMemoryCalloc(pNew->numOfColumns, sizeof(SColCmpr));
4,439!
1510
  if (pNew->pTags == NULL || pNew->pColumns == NULL || pNew->pCmpr == NULL) {
4,439!
UNCOV
1511
    TAOS_RETURN(terrno);
×
1512
  }
1513

1514
  memcpy(pNew->pColumns, pOld->pColumns, sizeof(SSchema) * pOld->numOfColumns);
4,439✔
1515
  memcpy(pNew->pTags, pOld->pTags, sizeof(SSchema) * pOld->numOfTags);
4,439✔
1516
  memcpy(pNew->pCmpr, pOld->pCmpr, sizeof(SColCmpr) * pOld->numOfColumns);
4,439✔
1517
  if (pOld->pExtSchemas) {
4,439✔
1518
    pNew->pExtSchemas = taosMemoryCalloc(pNew->numOfColumns, sizeof(SExtSchema));
2,314!
1519
    if (pNew->pExtSchemas == NULL) {
2,314!
UNCOV
1520
      TAOS_RETURN(terrno);
×
1521
    }
1522
    memcpy(pNew->pExtSchemas, pOld->pExtSchemas, sizeof(SExtSchema) * pOld->numOfColumns);
2,314✔
1523
  }
1524

1525
  TAOS_RETURN(0);
4,439✔
1526
}
1527

1528
static int32_t mndUpdateTableOptions(const SStbObj *pOld, SStbObj *pNew, char *pComment, int32_t commentLen,
22✔
1529
                                     int32_t ttl, int64_t keep) {
1530
  int32_t code = 0;
22✔
1531
  if (commentLen > 0) {
22✔
1532
    pNew->commentLen = commentLen;
17✔
1533
    pNew->comment = taosMemoryCalloc(1, commentLen + 1);
17!
1534
    if (pNew->comment == NULL) {
17!
UNCOV
1535
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
1536
      return -1;
×
1537
    }
1538
    memcpy(pNew->comment, pComment, commentLen + 1);
17✔
1539
  } else if (commentLen == 0) {
5!
1540
    pNew->commentLen = 0;
5✔
1541
  } else {
1542
  }
1543

1544
  if (ttl >= 0) {
22!
1545
    pNew->ttl = ttl;
22✔
1546
  }
1547

1548
  if (keep > 0) {
22!
UNCOV
1549
    pNew->keep = keep;
×
1550
  }
1551

1552
  if ((code = mndAllocStbSchemas(pOld, pNew)) != 0) {
22!
UNCOV
1553
    TAOS_RETURN(code);
×
1554
  }
1555
  TAOS_RETURN(code);
22✔
1556
}
1557

1558
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
448✔
1559
  int32_t code = 0;
448✔
1560
  if (pOld->numOfTags + ntags > TSDB_MAX_TAGS) {
448!
UNCOV
1561
    code = TSDB_CODE_MND_TOO_MANY_TAGS;
×
UNCOV
1562
    TAOS_RETURN(code);
×
1563
  }
1564

1565
  if (pOld->numOfColumns + ntags + pOld->numOfTags > TSDB_MAX_COLUMNS) {
448!
1566
    code = TSDB_CODE_MND_TOO_MANY_COLUMNS;
×
1567
    TAOS_RETURN(code);
×
1568
  }
1569

1570
  if (!mndValidateSchema(pOld->pTags, pOld->numOfTags, pFields, TSDB_MAX_TAGS_LEN)) {
448!
UNCOV
1571
    code = TSDB_CODE_PAR_INVALID_TAGS_LENGTH;
×
UNCOV
1572
    TAOS_RETURN(code);
×
1573
  }
1574

1575
  pNew->numOfTags = pNew->numOfTags + ntags;
448✔
1576
  if ((code = mndAllocStbSchemas(pOld, pNew)) != 0) {
448!
1577
    TAOS_RETURN(code);
×
1578
  }
1579

1580
  if (pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags) {
448!
UNCOV
1581
    code = TSDB_CODE_OUT_OF_RANGE;
×
UNCOV
1582
    TAOS_RETURN(code);
×
1583
  }
1584

1585
  for (int32_t i = 0; i < ntags; i++) {
882✔
1586
    SField *pField = taosArrayGet(pFields, i);
448✔
1587
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
448✔
1588
      code = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
6✔
1589
      TAOS_RETURN(code);
6✔
1590
    }
1591

1592
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
442✔
1593
      code = TSDB_CODE_MND_TAG_ALREADY_EXIST;
8✔
1594
      TAOS_RETURN(code);
8✔
1595
    }
1596

1597
    SSchema *pSchema = &pNew->pTags[pOld->numOfTags + i];
434✔
1598
    pSchema->bytes = pField->bytes;
434✔
1599
    pSchema->type = pField->type;
434✔
1600
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
434✔
1601
    pSchema->colId = pNew->nextColId;
434✔
1602
    pNew->nextColId++;
434✔
1603

1604
    mInfo("stb:%s, start to add tag %s", pNew->name, pSchema->name);
434!
1605
  }
1606

1607
  pNew->tagVer++;
434✔
1608
  TAOS_RETURN(code);
434✔
1609
}
1610

1611
static int32_t mndCheckAlterColForTopic(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
1,289✔
1612
  int32_t code = 0;
1,289✔
1613
  SSdb   *pSdb = pMnode->pSdb;
1,289✔
1614
  void   *pIter = NULL;
1,289✔
1615
  while (1) {
1,027✔
1616
    SMqTopicObj *pTopic = NULL;
2,316✔
1617
    pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
2,316✔
1618
    if (pIter == NULL) break;
2,316✔
1619

1620
    mInfo("topic:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, subType:%d sql:%s",
1,105!
1621
          pTopic->name, stbFullName, suid, colId, pTopic->subType, pTopic->sql);
1622
    if (pTopic->ast == NULL) {
1,105✔
1623
      sdbRelease(pSdb, pTopic);
107✔
1624
      continue;
107✔
1625
    }
1626

1627
    SNode *pAst = NULL;
998✔
1628
    if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
998!
UNCOV
1629
      code = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TOPIC;
×
UNCOV
1630
      mError("topic:%s, create ast error", pTopic->name);
×
1631
      sdbRelease(pSdb, pTopic);
×
1632
      sdbCancelFetch(pSdb, pIter);
×
1633
      TAOS_RETURN(code);
78✔
1634
    }
1635

1636
    SNodeList *pNodeList = NULL;
998✔
1637
    if ((code = nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList)) !=
998!
1638
        0) {
UNCOV
1639
      sdbRelease(pSdb, pTopic);
×
UNCOV
1640
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
1641
      TAOS_RETURN(code);
×
1642
    }
1643
    SNode *pNode = NULL;
998✔
1644
    FOREACH(pNode, pNodeList) {
1,639✔
1645
      SColumnNode *pCol = (SColumnNode *)pNode;
1,560✔
1646
      mInfo("topic:%s, check colId:%d tableId:%" PRId64 " ctbStbUid:%" PRId64, pTopic->name, pCol->colId, pCol->tableId,
1,560!
1647
            pTopic->ctbStbUid);
1648

1649
      if (pCol->tableId != suid && pTopic->ctbStbUid != suid) {
1,560✔
1650
        mInfo("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
841!
1651
        goto NEXT;
841✔
1652
      }
1653
      if (pCol->colId > 0 && pCol->colId == colId) {
719!
1654
        code = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TOPIC;
78✔
1655
        mError("topic:%s, check colId:%d conflicted", pTopic->name, pCol->colId);
78!
1656
        nodesDestroyNode(pAst);
78✔
1657
        nodesDestroyList(pNodeList);
78✔
1658
        sdbCancelFetch(pSdb, pIter);
78✔
1659
        sdbRelease(pSdb, pTopic);
78✔
1660
        TAOS_RETURN(code);
78✔
1661
      }
1662
      mInfo("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
641!
1663
    }
1664

1665
  NEXT:
79✔
1666
    sdbRelease(pSdb, pTopic);
920✔
1667
    nodesDestroyNode(pAst);
920✔
1668
    nodesDestroyList(pNodeList);
920✔
1669
  }
1670
  TAOS_RETURN(code);
1,211✔
1671
}
1672

1673
static int32_t mndCheckAlterColForStream(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
1,211✔
1674
  int32_t code = 0;
1,211✔
1675
  SSdb   *pSdb = pMnode->pSdb;
1,211✔
1676
  void   *pIter = NULL;
1,211✔
1677
  while (1) {
10✔
1678
    SStreamObj *pStream = NULL;
1,221✔
1679
    pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
1,221✔
1680
    if (pIter == NULL) break;
1,221✔
1681

1682
    SNode *pAst = NULL;
30✔
1683
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
30!
UNCOV
1684
      code = TSDB_CODE_MND_INVALID_STREAM_OPTION;
×
UNCOV
1685
      mError("stream:%s, create ast error", pStream->name);
×
UNCOV
1686
      sdbRelease(pSdb, pStream);
×
UNCOV
1687
      sdbCancelFetch(pSdb, pIter);
×
1688
      TAOS_RETURN(code);
20✔
1689
    }
1690

1691
    SNodeList *pNodeList = NULL;
30✔
1692
    if ((code = nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList)) !=
30!
1693
        0) {
UNCOV
1694
      sdbRelease(pSdb, pStream);
×
UNCOV
1695
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
1696
      TAOS_RETURN(code);
×
1697
    }
1698

1699
    SNode *pNode = NULL;
30✔
1700
    FOREACH(pNode, pNodeList) {
95!
1701
      SColumnNode *pCol = (SColumnNode *)pNode;
90✔
1702

1703
      if (pCol->tableId != suid) {
90✔
1704
        mInfo("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
5!
1705
        goto NEXT;
5✔
1706
      }
1707
      if (pCol->colId > 0 && pCol->colId == colId) {
85!
1708
        code = TSDB_CODE_MND_STREAM_MUST_BE_DELETED;
20✔
1709
        mError("stream:%s, check colId:%d conflicted", pStream->name, pCol->colId);
20!
1710
        nodesDestroyNode(pAst);
20✔
1711
        nodesDestroyList(pNodeList);
20✔
1712
        sdbRelease(pSdb, pStream);
20✔
1713
        sdbCancelFetch(pSdb, pIter);
20✔
1714
        TAOS_RETURN(code);
20✔
1715
      }
1716
      mInfo("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
65!
1717
    }
1718

1719
  NEXT:
5✔
1720
    sdbRelease(pSdb, pStream);
10✔
1721
    nodesDestroyNode(pAst);
10✔
1722
    nodesDestroyList(pNodeList);
10✔
1723
  }
1724
  TAOS_RETURN(code);
1,191✔
1725
}
1726

1727
static int32_t mndCheckAlterColForTSma(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
1,191✔
1728
  int32_t code = 0;
1,191✔
1729
  SSdb   *pSdb = pMnode->pSdb;
1,191✔
1730
  void   *pIter = NULL;
1,191✔
1731
  while (1) {
10✔
1732
    SSmaObj *pSma = NULL;
1,201✔
1733
    pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
1,201✔
1734
    if (pIter == NULL) break;
1,201✔
1735

1736
    mInfo("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, sql:%s", pSma->name, stbFullName,
10!
1737
          suid, colId, pSma->sql);
1738

1739
    SNode *pAst = NULL;
10✔
1740
    if (nodesStringToNode(pSma->ast, &pAst) != 0) {
10!
UNCOV
1741
      code = TSDB_CODE_SDB_INVALID_DATA_CONTENT;
×
UNCOV
1742
      mError("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d failed since parse AST err",
×
1743
             pSma->name, stbFullName, suid, colId);
UNCOV
1744
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
1745
      TAOS_RETURN(code);
×
1746
    }
1747

1748
    SNodeList *pNodeList = NULL;
10✔
1749
    if ((code = nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList)) !=
10!
1750
        0) {
UNCOV
1751
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
1752
      TAOS_RETURN(code);
×
1753
    }
1754
    SNode *pNode = NULL;
10✔
1755
    FOREACH(pNode, pNodeList) {
55!
1756
      SColumnNode *pCol = (SColumnNode *)pNode;
50✔
1757
      mInfo("tsma:%s, check colId:%d tableId:%" PRId64, pSma->name, pCol->colId, pCol->tableId);
50!
1758

1759
      if ((pCol->tableId != suid) && (pSma->stbUid != suid)) {
50!
1760
        mInfo("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
5!
1761
        goto NEXT;
5✔
1762
      }
1763
      if ((pCol->colId) > 0 && (pCol->colId == colId)) {
45!
UNCOV
1764
        code = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TSMA;
×
UNCOV
1765
        mError("tsma:%s, check colId:%d conflicted", pSma->name, pCol->colId);
×
UNCOV
1766
        nodesDestroyNode(pAst);
×
UNCOV
1767
        nodesDestroyList(pNodeList);
×
UNCOV
1768
        sdbRelease(pSdb, pSma);
×
UNCOV
1769
        sdbCancelFetch(pSdb, pIter);
×
UNCOV
1770
        TAOS_RETURN(code);
×
1771
      }
1772
      mInfo("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
45!
1773
    }
1774

1775
  NEXT:
5✔
1776
    sdbRelease(pSdb, pSma);
10✔
1777
    nodesDestroyNode(pAst);
10✔
1778
    nodesDestroyList(pNodeList);
10✔
1779
  }
1780
  TAOS_RETURN(code);
1,191✔
1781
}
1782

1783
int32_t mndCheckColAndTagModifiable(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
1,289✔
1784
  TAOS_CHECK_RETURN(mndCheckAlterColForTopic(pMnode, stbFullName, suid, colId));
1,289✔
1785
  TAOS_CHECK_RETURN(mndCheckAlterColForStream(pMnode, stbFullName, suid, colId));
1,211✔
1786
  TAOS_CHECK_RETURN(mndCheckAlterColForTSma(pMnode, stbFullName, suid, colId));
1,191!
1787
  TAOS_RETURN(0);
1,191✔
1788
}
1789

1790
static int32_t mndDropSuperTableTag(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
364✔
1791
  int32_t code = 0;
364✔
1792
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
364✔
1793
  if (tag < 0) {
364✔
1794
    code = TSDB_CODE_MND_TAG_NOT_EXIST;
4✔
1795
    TAOS_RETURN(code);
4✔
1796
  }
1797

1798
  col_id_t colId = pOld->pTags[tag].colId;
360✔
1799
  TAOS_CHECK_RETURN(mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId));
360✔
1800

1801
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
332!
1802

1803
  memmove(pNew->pTags + tag, pNew->pTags + tag + 1, sizeof(SSchema) * (pNew->numOfTags - tag - 1));
332✔
1804
  pNew->numOfTags--;
332✔
1805

1806
  pNew->tagVer++;
332✔
1807

1808
  // if (mndDropIndexByTag(pMnode, pOld, tagName) != 0) {
1809
  //   return -1;
1810
  // }
1811
  mInfo("stb:%s, start to drop tag %s", pNew->name, tagName);
332!
1812
  TAOS_RETURN(code);
332✔
1813
}
1814

1815
static int32_t mndAlterStbTagName(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
625✔
1816
  int32_t code = 0;
625✔
1817
  if ((int32_t)taosArrayGetSize(pFields) != 2) {
625!
UNCOV
1818
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
×
UNCOV
1819
    TAOS_RETURN(code);
×
1820
  }
1821

1822
  SField *pField0 = taosArrayGet(pFields, 0);
625✔
1823
  SField *pField1 = taosArrayGet(pFields, 1);
625✔
1824

1825
  const char *oldTagName = pField0->name;
625✔
1826
  const char *newTagName = pField1->name;
625✔
1827

1828
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
625✔
1829
  if (tag < 0) {
625✔
1830
    code = TSDB_CODE_MND_TAG_NOT_EXIST;
9✔
1831
    TAOS_RETURN(code);
9✔
1832
  }
1833

1834
  col_id_t colId = pOld->pTags[tag].colId;
616✔
1835
  TAOS_CHECK_RETURN(mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId));
616✔
1836

1837
  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
594✔
1838
    code = TSDB_CODE_MND_TAG_ALREADY_EXIST;
11✔
1839
    TAOS_RETURN(code);
11✔
1840
  }
1841

1842
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
583✔
1843
    code = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
1✔
1844
    TAOS_RETURN(code);
1✔
1845
  }
1846

1847
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
582!
1848

1849
  SSchema *pSchema = (SSchema *)(pNew->pTags + tag);
582✔
1850
  memcpy(pSchema->name, newTagName, TSDB_COL_NAME_LEN);
582✔
1851

1852
  pNew->tagVer++;
582✔
1853
  mInfo("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
582!
1854
  TAOS_RETURN(code);
582✔
1855
}
1856

1857
static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
42✔
1858
  int32_t code = 0;
42✔
1859
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
42✔
1860
  if (tag < 0) {
42✔
1861
    code = TSDB_CODE_MND_TAG_NOT_EXIST;
1✔
1862
    TAOS_RETURN(code);
1✔
1863
  }
1864

1865
  col_id_t colId = pOld->pTags[tag].colId;
41✔
1866
  TAOS_CHECK_RETURN(mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId));
41✔
1867

1868
  uint32_t nLen = 0;
32✔
1869
  for (int32_t i = 0; i < pOld->numOfTags; ++i) {
145✔
1870
    nLen += (pOld->pTags[i].colId == colId) ? pField->bytes : pOld->pTags[i].bytes;
113✔
1871
  }
1872

1873
  if (nLen > TSDB_MAX_TAGS_LEN) {
32!
UNCOV
1874
    code = TSDB_CODE_PAR_INVALID_TAGS_LENGTH;
×
1875
    TAOS_RETURN(code);
×
1876
  }
1877

1878
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
32!
1879

1880
  SSchema *pTag = pNew->pTags + tag;
32✔
1881

1882
  if (!(pTag->type == TSDB_DATA_TYPE_BINARY || pTag->type == TSDB_DATA_TYPE_VARBINARY ||
32!
1883
        pTag->type == TSDB_DATA_TYPE_NCHAR || pTag->type == TSDB_DATA_TYPE_GEOMETRY)) {
9!
1884
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
1✔
1885
    TAOS_RETURN(code);
1✔
1886
  }
1887

1888
  if (pField->bytes <= pTag->bytes) {
31✔
1889
    code = TSDB_CODE_MND_INVALID_ROW_BYTES;
1✔
1890
    TAOS_RETURN(code);
1✔
1891
  }
1892

1893
  pTag->bytes = pField->bytes;
30✔
1894
  pNew->tagVer++;
30✔
1895

1896
  mInfo("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
30!
1897
  TAOS_RETURN(code);
30✔
1898
}
1899

1900
static int32_t mndUpdateSuperTableColumnCompress(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pField,
26✔
1901
                                                 int32_t nCols) {
1902
  // if (pColCmpr == NULL || colName == NULL) return -1;
1903

1904
  if (taosArrayGetSize(pField) != nCols) return TSDB_CODE_FAILED;
26!
1905
  TAOS_FIELD *p = taosArrayGet(pField, 0);
26✔
1906

1907
  int32_t code = 0;
26✔
1908
  int32_t idx = mndFindSuperTableColumnIndex(pOld, p->name);
26✔
1909
  if (idx == -1) {
26!
UNCOV
1910
    code = TSDB_CODE_MND_COLUMN_NOT_EXIST;
×
UNCOV
1911
    TAOS_RETURN(code);
×
1912
  }
1913
  SSchema *pTarget = &pOld->pColumns[idx];
26✔
1914
  col_id_t colId = pTarget->colId;
26✔
1915

1916
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
26!
1917
  code = validColCmprByType(pTarget->type, p->bytes);
26✔
1918
  if (code != TSDB_CODE_SUCCESS) {
26✔
1919
    TAOS_RETURN(code);
1✔
1920
  }
1921

1922
  int8_t updated = 0;
25✔
1923
  for (int i = 0; i < pNew->numOfColumns; i++) {
161!
1924
    SColCmpr *pCmpr = &pNew->pCmpr[i];
161✔
1925
    if (pCmpr->id == colId) {
161✔
1926
      uint32_t dst = 0;
25✔
1927
      updated = tUpdateCompress(pCmpr->alg, p->bytes, TSDB_COLVAL_COMPRESS_DISABLED, TSDB_COLVAL_LEVEL_DISABLED,
25✔
1928
                                TSDB_COLVAL_LEVEL_MEDIUM, &dst);
1929
      if (updated > 0) pCmpr->alg = dst;
25✔
1930
      break;
25✔
1931
    }
1932
  }
1933

1934
  if (updated == 0) {
25✔
1935
    code = TSDB_CODE_MND_COLUMN_COMPRESS_ALREADY_EXIST;
7✔
1936
    TAOS_RETURN(code);
7✔
1937
  } else if (updated == -1) {
18!
UNCOV
1938
    code = TSDB_CODE_TSC_COMPRESS_LEVEL_ERROR;
×
UNCOV
1939
    TAOS_RETURN(code);
×
1940
  }
1941

1942
  pNew->colVer++;
18✔
1943

1944
  TAOS_RETURN(code);
18✔
1945
}
1946
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, const SMAlterStbReq* pReq, int32_t ncols,
1,226✔
1947
                                      int8_t withCompress) {
1948
  int32_t code = 0;
1,226✔
1949
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
1,226!
UNCOV
1950
    code = TSDB_CODE_MND_TOO_MANY_COLUMNS;
×
UNCOV
1951
    TAOS_RETURN(code);
×
1952
  }
1953

1954
  if ((code = grantCheck(TSDB_GRANT_TIMESERIES)) != 0) {
1,226!
UNCOV
1955
    TAOS_RETURN(code);
×
1956
  }
1957

1958
  if (!mndValidateSchema(pOld->pColumns, pOld->numOfColumns, pReq->pFields, TSDB_MAX_BYTES_PER_ROW)) {
1,226!
UNCOV
1959
    code = TSDB_CODE_PAR_INVALID_ROW_LENGTH;
×
UNCOV
1960
    TAOS_RETURN(code);
×
1961
  }
1962

1963
  pNew->numOfColumns = pNew->numOfColumns + ncols;
1,226✔
1964

1965
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
1,226!
1966

1967
  if (pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols) {
1,226!
UNCOV
1968
    code = TSDB_CODE_OUT_OF_RANGE;
×
UNCOV
1969
    TAOS_RETURN(code);
×
1970
  }
1971

1972
  for (int32_t i = 0; i < ncols; i++) {
2,435✔
1973
    if (withCompress) {
1,226✔
1974
      SFieldWithOptions *pField = taosArrayGet(pReq->pFields, i);
20✔
1975
      if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
20!
UNCOV
1976
        code = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
×
UNCOV
1977
        TAOS_RETURN(code);
×
1978
      }
1979

1980
      if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
20!
UNCOV
1981
        code = TSDB_CODE_MND_TAG_ALREADY_EXIST;
×
UNCOV
1982
        TAOS_RETURN(code);
×
1983
      }
1984

1985
      SSchema *pSchema = &pNew->pColumns[pOld->numOfColumns + i];
20✔
1986
      pSchema->bytes = pField->bytes;
20✔
1987
      pSchema->type = pField->type;
20✔
1988
      memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
20✔
1989
      pSchema->colId = pNew->nextColId;
20✔
1990
      pNew->nextColId++;
20✔
1991

1992
      SColCmpr *pCmpr = &pNew->pCmpr[pOld->numOfColumns + i];
20✔
1993
      pCmpr->id = pSchema->colId;
20✔
1994
      pCmpr->alg = pField->compress;
20✔
1995
      mInfo("stb:%s, start to add column %s", pNew->name, pSchema->name);
20!
1996
    } else {
1997
      SField *pField = taosArrayGet(pReq->pFields, i);
1,206✔
1998
      if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
1,206✔
1999
        code = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
10✔
2000
        TAOS_RETURN(code);
10✔
2001
      }
2002

2003
      if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
1,196✔
2004
        code = TSDB_CODE_MND_TAG_ALREADY_EXIST;
7✔
2005
        TAOS_RETURN(code);
7✔
2006
      }
2007

2008
      SSchema *pSchema = &pNew->pColumns[pOld->numOfColumns + i];
1,189✔
2009
      pSchema->bytes = pField->bytes;
1,189✔
2010
      pSchema->type = pField->type;
1,189✔
2011
      memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
1,189✔
2012
      pSchema->colId = pNew->nextColId;
1,189✔
2013
      pNew->nextColId++;
1,189✔
2014

2015
      SColCmpr *pCmpr = &pNew->pCmpr[pOld->numOfColumns + i];
1,189✔
2016
      pCmpr->id = pSchema->colId;
1,189✔
2017
      pCmpr->alg = createDefaultColCmprByType(pSchema->type);
1,189✔
2018
      mInfo("stb:%s, start to add column %s", pNew->name, pSchema->name);
1,189!
2019
    }
2020
  }
2021
  // 1. old schema already has extschemas
2022
  // 2. new schema has extschemas
2023
  if (pReq->pTypeMods || pOld->pExtSchemas) {
1,209!
2024
    if (!pNew->pExtSchemas) {
1,207✔
2025
      // all ext schemas reset to zero
2026
      pNew->pExtSchemas = taosMemoryCalloc(pNew->numOfColumns, sizeof(SExtSchema));
51!
2027
      if (!pNew->pExtSchemas) TAOS_RETURN(terrno);
51!
2028
    }
2029
    if (pOld->pExtSchemas) {
1,207✔
2030
      memcpy(pNew->pExtSchemas, pOld->pExtSchemas, pOld->numOfColumns * sizeof(SExtSchema));
1,156✔
2031
    }
2032
    if (taosArrayGetSize(pReq->pTypeMods) > 0) {
1,207!
2033
      // copy added column ext schema
2034
      for (int32_t i = 0; i < ncols; ++i) {
2,414✔
2035
        pNew->pColumns[pOld->numOfColumns + i].flags |= COL_HAS_TYPE_MOD;
1,207✔
2036
        pNew->pExtSchemas[pOld->numOfColumns + i].typeMod = *(STypeMod *)taosArrayGet(pReq->pTypeMods, i);
1,207✔
2037
      }
2038
    }
2039
  }
2040

2041
  pNew->colVer++;
1,209✔
2042
  TAOS_RETURN(code);
1,209✔
2043
}
2044

2045
static int32_t mndDropSuperTableColumn(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *colName) {
227✔
2046
  int32_t code = 0;
227✔
2047
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
227✔
2048
  if (col < 0) {
227✔
2049
    code = TSDB_CODE_MND_COLUMN_NOT_EXIST;
7✔
2050
    TAOS_RETURN(code);
7✔
2051
  }
2052

2053
  if (col == 0) {
220✔
2054
    code = TSDB_CODE_MND_INVALID_STB_ALTER_OPTION;
5✔
2055
    TAOS_RETURN(code);
5✔
2056
  }
2057

2058
  if (pOld->numOfColumns == 2) {
215✔
2059
    code = TSDB_CODE_PAR_INVALID_DROP_COL;
1✔
2060
    TAOS_RETURN(code);
1✔
2061
  }
2062

2063
  col_id_t colId = pOld->pColumns[col].colId;
214✔
2064
  TAOS_CHECK_RETURN(mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId));
214✔
2065

2066
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
187!
2067

2068
  int32_t sz = pNew->numOfColumns - col - 1;
187✔
2069
  memmove(pNew->pColumns + col, pNew->pColumns + col + 1, sizeof(SSchema) * sz);
187✔
2070
  memmove(pNew->pCmpr + col, pNew->pCmpr + col + 1, sizeof(SColCmpr) * sz);
187✔
2071
  if (pOld->pExtSchemas) {
187✔
2072
    memmove(pNew->pExtSchemas + col, pNew->pExtSchemas + col + 1, sizeof(SExtSchema) * sz);
80✔
2073
  }
2074
  pNew->numOfColumns--;
187✔
2075

2076
  pNew->colVer++;
187✔
2077
  mInfo("stb:%s, start to drop col %s", pNew->name, colName);
187!
2078
  TAOS_RETURN(code);
187✔
2079
}
2080

2081
static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
62✔
2082
  int32_t code = 0;
62✔
2083
  int32_t col = mndFindSuperTableColumnIndex(pOld, pField->name);
62✔
2084
  if (col < 0) {
62✔
2085
    code = TSDB_CODE_MND_COLUMN_NOT_EXIST;
3✔
2086
    TAOS_RETURN(code);
3✔
2087
  }
2088

2089
  col_id_t colId = pOld->pColumns[col].colId;
59✔
2090

2091
  uint32_t nLen = 0;
59✔
2092
  for (int32_t i = 0; i < pOld->numOfColumns; ++i) {
339✔
2093
    nLen += (pOld->pColumns[i].colId == colId) ? pField->bytes : pOld->pColumns[i].bytes;
280✔
2094
  }
2095

2096
  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
59✔
2097
    code = TSDB_CODE_MND_INVALID_ROW_BYTES;
1✔
2098
    TAOS_RETURN(code);
1✔
2099
  }
2100

2101
  TAOS_CHECK_RETURN(mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId));
58✔
2102

2103
  TAOS_CHECK_RETURN(mndAllocStbSchemas(pOld, pNew));
46!
2104

2105
  SSchema *pCol = pNew->pColumns + col;
46✔
2106
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_VARBINARY ||
46!
2107
        pCol->type == TSDB_DATA_TYPE_NCHAR || pCol->type == TSDB_DATA_TYPE_GEOMETRY)) {
9!
2108
    code = TSDB_CODE_MND_INVALID_STB_OPTION;
1✔
2109
    TAOS_RETURN(code);
1✔
2110
  }
2111

2112
  if (pField->bytes <= pCol->bytes) {
45✔
2113
    code = TSDB_CODE_MND_INVALID_ROW_BYTES;
1✔
2114
    TAOS_RETURN(code);
1✔
2115
  }
2116

2117
  pCol->bytes = pField->bytes;
44✔
2118
  pNew->colVer++;
44✔
2119

2120
  mInfo("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
44!
2121
  TAOS_RETURN(code);
44✔
2122
}
2123

2124
static int32_t mndSetAlterStbPrepareLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
2,932✔
2125
  int32_t  code = 0;
2,932✔
2126
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
2,932✔
2127
  if (pRedoRaw == NULL) {
2,932!
UNCOV
2128
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2129
    if (terrno != 0) code = terrno;
×
2130
    TAOS_RETURN(code);
×
2131
  }
2132
  if ((code = mndTransAppendPrepareLog(pTrans, pRedoRaw)) != 0) {
2,932!
2133
    sdbFreeRaw(pRedoRaw);
×
2134
    TAOS_RETURN(code);
×
2135
  }
2136
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY));
2,932!
2137

2138
  TAOS_RETURN(code);
2,932✔
2139
}
2140

2141
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
2,932✔
2142
  int32_t  code = 0;
2,932✔
2143
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
2,932✔
2144
  if (pCommitRaw == NULL) {
2,932!
2145
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2146
    if (terrno != 0) code = terrno;
×
2147
    TAOS_RETURN(code);
×
2148
  }
2149
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
2,932!
UNCOV
2150
    sdbFreeRaw(pCommitRaw);
×
UNCOV
2151
    TAOS_RETURN(code);
×
2152
  }
2153
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
2,932!
2154

2155
  TAOS_RETURN(code);
2,932✔
2156
}
2157

2158
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb, void *alterOriData,
2,932✔
2159
                                         int32_t alterOriDataLen) {
2160
  int32_t code = 0;
2,932✔
2161
  SSdb   *pSdb = pMnode->pSdb;
2,932✔
2162
  SVgObj *pVgroup = NULL;
2,932✔
2163
  void   *pIter = NULL;
2,932✔
2164
  int32_t contLen;
2165

2166
  while (1) {
9,567✔
2167
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
12,499✔
2168
    if (pIter == NULL) break;
12,499✔
2169
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
9,567✔
2170
      sdbRelease(pSdb, pVgroup);
3,363✔
2171
      continue;
3,363✔
2172
    }
2173

2174
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, alterOriData, alterOriDataLen);
6,204✔
2175
    if (pReq == NULL) {
6,204!
UNCOV
2176
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2177
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2178
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2179
      if (terrno != 0) code = terrno;
×
UNCOV
2180
      TAOS_RETURN(code);
×
2181
    }
2182
    STransAction action = {0};
6,204✔
2183
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
6,204✔
2184
    action.pCont = pReq;
6,204✔
2185
    action.contLen = contLen;
6,204✔
2186
    action.msgType = TDMT_VND_ALTER_STB;
6,204✔
2187
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
6,204!
UNCOV
2188
      taosMemoryFree(pReq);
×
UNCOV
2189
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2190
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2191
      TAOS_RETURN(code);
×
2192
    }
2193
    sdbRelease(pSdb, pVgroup);
6,204✔
2194
  }
2195

2196
  TAOS_RETURN(code);
2,932✔
2197
}
2198

UNCOV
2199
static int32_t mndSetAlterStbRedoActions2(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb,
×
2200
                                          void *alterOriData, int32_t alterOriDataLen) {
UNCOV
2201
  int32_t code = 0;
×
UNCOV
2202
  SSdb   *pSdb = pMnode->pSdb;
×
UNCOV
2203
  SVgObj *pVgroup = NULL;
×
UNCOV
2204
  void   *pIter = NULL;
×
2205
  int32_t contLen;
2206

UNCOV
2207
  while (1) {
×
UNCOV
2208
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
×
UNCOV
2209
    if (pIter == NULL) break;
×
UNCOV
2210
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
×
UNCOV
2211
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2212
      continue;
×
2213
    }
2214

UNCOV
2215
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, alterOriData, alterOriDataLen);
×
UNCOV
2216
    if (pReq == NULL) {
×
UNCOV
2217
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2218
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2219
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2220
      if (terrno != 0) code = terrno;
×
UNCOV
2221
      TAOS_RETURN(code);
×
2222
    }
2223
    STransAction action = {0};
×
2224
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
×
UNCOV
2225
    action.pCont = pReq;
×
UNCOV
2226
    action.contLen = contLen;
×
UNCOV
2227
    action.msgType = TDMT_VND_CREATE_INDEX;
×
UNCOV
2228
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
×
UNCOV
2229
      taosMemoryFree(pReq);
×
UNCOV
2230
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2231
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2232
      TAOS_RETURN(code);
×
2233
    }
UNCOV
2234
    sdbRelease(pSdb, pVgroup);
×
2235
  }
2236

UNCOV
2237
  TAOS_RETURN(code);
×
2238
}
2239

2240
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
796,727✔
2241
  int32_t code = 0;
796,727✔
2242
  taosRLockLatch(&pStb->lock);
796,727✔
2243

2244
  int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
796,745✔
2245
  pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
796,745!
2246
  if (pRsp->pSchemas == NULL) {
796,732!
UNCOV
2247
    taosRUnLockLatch(&pStb->lock);
×
UNCOV
2248
    code = terrno;
×
UNCOV
2249
    TAOS_RETURN(code);
×
2250
  }
2251
  pRsp->pSchemaExt = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchemaExt));
796,732!
2252
  if (pRsp->pSchemaExt == NULL) {
796,730!
UNCOV
2253
    taosRUnLockLatch(&pStb->lock);
×
UNCOV
2254
    code = terrno;
×
UNCOV
2255
    TAOS_RETURN(code);
×
2256
  }
2257
  pRsp->numOfColRefs = 0;
796,730✔
2258
  pRsp->pColRefs = NULL;
796,730✔
2259
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
796,730✔
2260
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
796,730✔
2261
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
796,730✔
2262
  pRsp->dbId = pDb->uid;
796,730✔
2263
  pRsp->numOfTags = pStb->numOfTags;
796,730✔
2264
  pRsp->numOfColumns = pStb->numOfColumns;
796,730✔
2265
  pRsp->precision = pDb->cfg.precision;
796,730✔
2266
  pRsp->tableType = TSDB_SUPER_TABLE;
796,730✔
2267
  pRsp->sversion = pStb->colVer;
796,730✔
2268
  pRsp->tversion = pStb->tagVer;
796,730✔
2269
  pRsp->suid = pStb->uid;
796,730✔
2270
  pRsp->tuid = pStb->uid;
796,730✔
2271
  pRsp->virtualStb = pStb->virtualStb;
796,730✔
2272

2273
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
21,849,838✔
2274
    SSchema *pSchema = &pRsp->pSchemas[i];
21,053,108✔
2275
    SSchema *pSrcSchema = &pStb->pColumns[i];
21,053,108✔
2276
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
21,053,108✔
2277
    pSchema->type = pSrcSchema->type;
21,053,108✔
2278
    pSchema->flags = pSrcSchema->flags;
21,053,108✔
2279
    pSchema->colId = pSrcSchema->colId;
21,053,108✔
2280
    pSchema->bytes = pSrcSchema->bytes;
21,053,108✔
2281
  }
2282

2283
  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
12,638,678✔
2284
    SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
11,841,948✔
2285
    SSchema *pSrcSchema = &pStb->pTags[i];
11,841,948✔
2286
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
11,841,948✔
2287
    pSchema->type = pSrcSchema->type;
11,841,948✔
2288
    pSchema->flags = pSrcSchema->flags;
11,841,948✔
2289
    pSchema->colId = pSrcSchema->colId;
11,841,948✔
2290
    pSchema->bytes = pSrcSchema->bytes;
11,841,948✔
2291
  }
2292
  for (int32_t i = 0; i < pStb->numOfColumns; i++) {
21,851,351✔
2293
    SColCmpr   *pCmpr = &pStb->pCmpr[i];
21,054,621✔
2294
    SSchemaExt *pSchEx = &pRsp->pSchemaExt[i];
21,054,621✔
2295
    pSchEx->colId = pCmpr->id;
21,054,621✔
2296
    pSchEx->compress = pCmpr->alg;
21,054,621✔
2297
    if (pStb->pExtSchemas) {
21,054,621✔
2298
      pSchEx->typeMod = pStb->pExtSchemas[i].typeMod;
1,074,525✔
2299
    }
2300
  }
2301

2302
  taosRUnLockLatch(&pStb->lock);
796,730✔
2303
  TAOS_RETURN(code);
796,746✔
2304
}
2305

2306
static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableCfgRsp *pRsp) {
42✔
2307
  int32_t code = 0;
42✔
2308
  taosRLockLatch(&pStb->lock);
42✔
2309

2310
  int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
42✔
2311
  pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
42!
2312
  if (pRsp->pSchemas == NULL) {
42!
2313
    taosRUnLockLatch(&pStb->lock);
×
UNCOV
2314
    code = terrno;
×
UNCOV
2315
    TAOS_RETURN(code);
×
2316
  }
2317

2318
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
42✔
2319
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
42✔
2320
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
42✔
2321
  pRsp->numOfTags = pStb->numOfTags;
42✔
2322
  pRsp->numOfColumns = pStb->numOfColumns;
42✔
2323
  pRsp->tableType = TSDB_SUPER_TABLE;
42✔
2324
  pRsp->delay1 = pStb->maxdelay[0];
42✔
2325
  pRsp->delay2 = pStb->maxdelay[1];
42✔
2326
  pRsp->watermark1 = pStb->watermark[0];
42✔
2327
  pRsp->watermark2 = pStb->watermark[1];
42✔
2328
  pRsp->ttl = pStb->ttl;
42✔
2329
  pRsp->commentLen = pStb->commentLen;
42✔
2330
  if (pStb->commentLen > 0) {
42!
UNCOV
2331
    pRsp->pComment = taosStrdup(pStb->comment);
×
2332
  }
2333

2334
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
265✔
2335
    SSchema *pSchema = &pRsp->pSchemas[i];
223✔
2336
    SSchema *pSrcSchema = &pStb->pColumns[i];
223✔
2337
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
223✔
2338
    pSchema->type = pSrcSchema->type;
223✔
2339
    pSchema->flags = pSrcSchema->flags;
223✔
2340
    pSchema->colId = pSrcSchema->colId;
223✔
2341
    pSchema->bytes = pSrcSchema->bytes;
223✔
2342
  }
2343

2344
  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
121✔
2345
    SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
79✔
2346
    SSchema *pSrcSchema = &pStb->pTags[i];
79✔
2347
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
79✔
2348
    pSchema->type = pSrcSchema->type;
79✔
2349
    pSchema->flags = pSrcSchema->flags;
79✔
2350
    pSchema->colId = pSrcSchema->colId;
79✔
2351
    pSchema->bytes = pSrcSchema->bytes;
79✔
2352
  }
2353

2354
  if (pStb->numOfFuncs > 0) {
42!
UNCOV
2355
    pRsp->pFuncs = taosArrayDup(pStb->pFuncs, NULL);
×
2356
  }
2357

2358
  pRsp->pSchemaExt = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchemaExt));
42!
2359
  for (int32_t i = 0; i < pStb->numOfColumns; i++) {
265✔
2360
    SColCmpr *pCmpr = &pStb->pCmpr[i];
223✔
2361

2362
    SSchemaExt *pSchExt = &pRsp->pSchemaExt[i];
223✔
2363
    pSchExt->colId = pCmpr->id;
223✔
2364
    pSchExt->compress = pCmpr->alg;
223✔
2365
    if (pStb->pExtSchemas) {
223✔
2366
      pSchExt->typeMod = pStb->pExtSchemas[i].typeMod;
99✔
2367
    }
2368
  }
2369
  pRsp->virtualStb = pStb->virtualStb;
42✔
2370
  pRsp->pColRefs = NULL;
42✔
2371

2372
  taosRUnLockLatch(&pStb->lock);
42✔
2373
  TAOS_RETURN(code);
42✔
2374
}
2375

2376
static int32_t mndValidateStbVersion(SMnode *pMnode, SSTableVersion *pStbVer, bool *schema, bool *sma) {
92,019✔
2377
  int32_t code = 0;
92,019✔
2378
  char    tbFName[TSDB_TABLE_FNAME_LEN] = {0};
92,019✔
2379
  snprintf(tbFName, sizeof(tbFName), "%s.%s", pStbVer->dbFName, pStbVer->stbName);
92,019✔
2380

2381
  SDbObj *pDb = mndAcquireDb(pMnode, pStbVer->dbFName);
92,019✔
2382
  if (pDb == NULL) {
92,019✔
2383
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
520✔
2384
    TAOS_RETURN(code);
520✔
2385
  }
2386

2387
  if (pDb->uid != pStbVer->dbId) {
91,499✔
2388
    mndReleaseDb(pMnode, pDb);
164✔
2389
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
164✔
2390
    TAOS_RETURN(code);
164✔
2391
  }
2392

2393
  SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
91,335✔
2394
  if (pStb == NULL) {
91,335✔
2395
    mndReleaseDb(pMnode, pDb);
156✔
2396
    code = TSDB_CODE_PAR_TABLE_NOT_EXIST;
156✔
2397
    TAOS_RETURN(code);
156✔
2398
  }
2399

2400
  taosRLockLatch(&pStb->lock);
91,179✔
2401

2402
  if (pStbVer->sversion != pStb->colVer || pStbVer->tversion != pStb->tagVer) {
91,179✔
2403
    *schema = true;
463✔
2404
  } else {
2405
    *schema = false;
90,716✔
2406
  }
2407

2408
  if (pStbVer->smaVer && pStbVer->smaVer != pStb->smaVer) {
91,179!
UNCOV
2409
    *sma = true;
×
2410
  } else {
2411
    *sma = false;
91,179✔
2412
  }
2413

2414
  taosRUnLockLatch(&pStb->lock);
91,179✔
2415

2416
  mndReleaseDb(pMnode, pDb);
91,179✔
2417
  mndReleaseStb(pMnode, pStb);
91,179✔
2418
  return TSDB_CODE_SUCCESS;
91,179✔
2419
}
2420

2421
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp) {
787,872✔
2422
  int32_t code = 0;
787,872✔
2423
  char    tbFName[TSDB_TABLE_FNAME_LEN] = {0};
787,872✔
2424
  snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
787,872✔
2425

2426
  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
787,872✔
2427
  if (pDb == NULL) {
787,863!
UNCOV
2428
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
×
UNCOV
2429
    TAOS_RETURN(code);
×
2430
  }
2431

2432
  SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
787,863✔
2433
  if (pStb == NULL) {
787,861✔
2434
    mndReleaseDb(pMnode, pDb);
1,578✔
2435
    code = TSDB_CODE_PAR_TABLE_NOT_EXIST;
1,578✔
2436
    TAOS_RETURN(code);
1,578✔
2437
  }
2438

2439
  code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
786,283✔
2440
  mndReleaseDb(pMnode, pDb);
786,294✔
2441
  mndReleaseStb(pMnode, pStb);
786,296✔
2442
  TAOS_RETURN(code);
786,296✔
2443
}
2444

2445
static int32_t mndBuildStbCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) {
42✔
2446
  int32_t code = 0;
42✔
2447
  char    tbFName[TSDB_TABLE_FNAME_LEN] = {0};
42✔
2448
  snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
42✔
2449

2450
  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
42✔
2451
  if (pDb == NULL) {
42!
UNCOV
2452
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
×
UNCOV
2453
    TAOS_RETURN(code);
×
2454
  }
2455

2456
  SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
42✔
2457
  if (pStb == NULL) {
42!
UNCOV
2458
    mndReleaseDb(pMnode, pDb);
×
UNCOV
2459
    code = TSDB_CODE_PAR_TABLE_NOT_EXIST;
×
UNCOV
2460
    TAOS_RETURN(code);
×
2461
  }
2462

2463
  code = mndBuildStbCfgImp(pDb, pStb, tbName, pRsp);
42✔
2464

2465
  mndReleaseDb(pMnode, pDb);
42✔
2466
  mndReleaseStb(pMnode, pStb);
42✔
2467
  TAOS_RETURN(code);
42✔
2468
}
2469

2470
static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, SStbObj *pObj, void **pCont, int32_t *pLen) {
2,836✔
2471
  int32_t       code = 0;
2,836✔
2472
  SEncoder      ec = {0};
2,836✔
2473
  uint32_t      contLen = 0;
2,836✔
2474
  SMAlterStbRsp alterRsp = {0};
2,836✔
2475
  SName         name = {0};
2,836✔
2476
  TAOS_CHECK_RETURN(tNameFromString(&name, pObj->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
2,836!
2477

2478
  alterRsp.pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
2,836!
2479
  if (NULL == alterRsp.pMeta) {
2,836!
UNCOV
2480
    code = terrno;
×
UNCOV
2481
    TAOS_RETURN(code);
×
2482
  }
2483

2484
  code = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
2,836✔
2485
  if (code) {
2,836!
UNCOV
2486
    tFreeSMAlterStbRsp(&alterRsp);
×
UNCOV
2487
    return code;
×
2488
  }
2489

2490
  tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, code);
2,836!
2491
  if (code) {
2,836!
UNCOV
2492
    tFreeSMAlterStbRsp(&alterRsp);
×
UNCOV
2493
    return code;
×
2494
  }
2495

2496
  void *cont = taosMemoryMalloc(contLen);
2,836!
2497
  if (NULL == cont) {
2,836!
UNCOV
2498
    code = terrno;
×
UNCOV
2499
    tFreeSMAlterStbRsp(&alterRsp);
×
UNCOV
2500
    TAOS_RETURN(code);
×
2501
  }
2502
  tEncoderInit(&ec, cont, contLen);
2,836✔
2503
  code = tEncodeSMAlterStbRsp(&ec, &alterRsp);
2,836✔
2504
  tEncoderClear(&ec);
2,836✔
2505

2506
  tFreeSMAlterStbRsp(&alterRsp);
2,836✔
2507

2508
  if (code < 0) TAOS_RETURN(code);
2,836!
2509

2510
  *pCont = cont;
2,836✔
2511
  *pLen = contLen;
2,836✔
2512

2513
  TAOS_RETURN(code);
2,836✔
2514
}
2515

2516
int32_t mndBuildSMCreateStbRsp(SMnode *pMnode, char *dbFName, char *stbFName, void **pCont, int32_t *pLen) {
7,618✔
2517
  int32_t code = -1;
7,618✔
2518
  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
7,618✔
2519
  if (NULL == pDb) {
7,618!
UNCOV
2520
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2521
    if (terrno != 0) code = terrno;
×
UNCOV
2522
    TAOS_RETURN(code);
×
2523
  }
2524

2525
  SStbObj *pObj = mndAcquireStb(pMnode, stbFName);
7,618✔
2526
  if (NULL == pObj) {
7,618✔
2527
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
3✔
2528
    if (terrno != 0) code = terrno;
3!
2529
    goto _OVER;
3✔
2530
  }
2531

2532
  SEncoder       ec = {0};
7,615✔
2533
  uint32_t       contLen = 0;
7,615✔
2534
  SMCreateStbRsp stbRsp = {0};
7,615✔
2535
  SName          name = {0};
7,615✔
2536
  TAOS_CHECK_GOTO(tNameFromString(&name, pObj->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE), NULL, _OVER);
7,615!
2537

2538
  stbRsp.pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
7,615!
2539
  if (NULL == stbRsp.pMeta) {
7,615!
UNCOV
2540
    code = terrno;
×
UNCOV
2541
    goto _OVER;
×
2542
  }
2543

2544
  code = mndBuildStbSchemaImp(pDb, pObj, name.tname, stbRsp.pMeta);
7,615✔
2545
  if (code) {
7,615!
UNCOV
2546
    tFreeSMCreateStbRsp(&stbRsp);
×
UNCOV
2547
    goto _OVER;
×
2548
  }
2549

2550
  tEncodeSize(tEncodeSMCreateStbRsp, &stbRsp, contLen, code);
7,615!
2551
  if (code) {
7,615!
UNCOV
2552
    tFreeSMCreateStbRsp(&stbRsp);
×
UNCOV
2553
    goto _OVER;
×
2554
  }
2555

2556
  void *cont = taosMemoryMalloc(contLen);
7,615!
2557
  if (NULL == cont) {
7,615!
UNCOV
2558
    code = terrno;
×
UNCOV
2559
    tFreeSMCreateStbRsp(&stbRsp);
×
UNCOV
2560
    goto _OVER;
×
2561
  }
2562
  tEncoderInit(&ec, cont, contLen);
7,615✔
2563
  TAOS_CHECK_GOTO(tEncodeSMCreateStbRsp(&ec, &stbRsp), NULL, _OVER);
7,615!
2564
  tEncoderClear(&ec);
7,615✔
2565

2566
  tFreeSMCreateStbRsp(&stbRsp);
7,615✔
2567

2568
  *pCont = cont;
7,615✔
2569
  *pLen = contLen;
7,615✔
2570

2571
  code = 0;
7,615✔
2572

2573
_OVER:
7,618✔
2574
  if (pObj) {
7,618✔
2575
    mndReleaseStb(pMnode, pObj);
7,615✔
2576
  }
2577

2578
  if (pDb) {
7,618!
2579
    mndReleaseDb(pMnode, pDb);
7,618✔
2580
  }
2581

2582
  TAOS_RETURN(code);
7,618✔
2583
}
2584

2585
static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
2,018✔
2586
                              void *alterOriData, int32_t alterOriDataLen) {
2587
  int32_t code = -1;
2,018✔
2588
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "alter-stb");
2,018✔
2589
  if (pTrans == NULL) {
2,018!
UNCOV
2590
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2591
    if (terrno != 0) code = terrno;
×
UNCOV
2592
    goto _OVER;
×
2593
  }
2594

2595
  mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
2,018!
2596
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
2,018✔
2597
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
2,018!
2598

2599
  if (needRsp) {
2,018✔
2600
    void   *pCont = NULL;
1,922✔
2601
    int32_t contLen = 0;
1,922✔
2602
    TAOS_CHECK_GOTO(mndBuildSMAlterStbRsp(pDb, pStb, &pCont, &contLen), NULL, _OVER);
1,922!
2603
    mndTransSetRpcRsp(pTrans, pCont, contLen);
1,922✔
2604
  }
2605

2606
  TAOS_CHECK_GOTO(mndSetAlterStbPrepareLogs(pMnode, pTrans, pDb, pStb), NULL, _OVER);
2,018!
2607
  TAOS_CHECK_GOTO(mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb), NULL, _OVER);
2,018!
2608
  TAOS_CHECK_GOTO(mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen), NULL, _OVER);
2,018!
2609
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
2,018!
2610

2611
  code = 0;
2,018✔
2612

2613
_OVER:
2,018✔
2614
  mndTransDrop(pTrans);
2,018✔
2615
  TAOS_RETURN(code);
2,018✔
2616
}
2617

2618
static int32_t mndAlterStbAndUpdateTagIdxImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
914✔
2619
                                             void *alterOriData, int32_t alterOriDataLen, const SMAlterStbReq *pAlter) {
2620
  int32_t code = -1;
914✔
2621
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "alter-stb");
914✔
2622
  if (pTrans == NULL) {
914!
UNCOV
2623
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2624
    if (terrno != 0) code = terrno;
×
UNCOV
2625
    goto _OVER;
×
2626
  }
2627

2628
  mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
914!
2629
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
914✔
2630

2631
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
914!
2632

2633
  if (needRsp) {
914!
2634
    void   *pCont = NULL;
914✔
2635
    int32_t contLen = 0;
914✔
2636
    TAOS_CHECK_GOTO(mndBuildSMAlterStbRsp(pDb, pStb, &pCont, &contLen), NULL, _OVER);
914!
2637
    mndTransSetRpcRsp(pTrans, pCont, contLen);
914✔
2638
  }
2639

2640
  if (pAlter->alterType == TSDB_ALTER_TABLE_DROP_TAG) {
914✔
2641
    SIdxObj idxObj = {0};
332✔
2642
    SField *pField0 = taosArrayGet(pAlter->pFields, 0);
332✔
2643
    bool    exist = false;
332✔
2644
    if (mndGetIdxsByTagName(pMnode, pStb, pField0->name, &idxObj) == 0) {
332✔
2645
      exist = true;
5✔
2646
    }
2647
    TAOS_CHECK_GOTO(mndSetAlterStbPrepareLogs(pMnode, pTrans, pDb, pStb), NULL, _OVER);
332!
2648
    TAOS_CHECK_GOTO(mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb), NULL, _OVER);
332!
2649

2650
    if (exist == true) {
332✔
2651
      TAOS_CHECK_GOTO(mndSetDropIdxPrepareLogs(pMnode, pTrans, &idxObj), NULL, _OVER);
5!
2652
      TAOS_CHECK_GOTO(mndSetDropIdxCommitLogs(pMnode, pTrans, &idxObj), NULL, _OVER);
5!
2653
    }
2654

2655
    TAOS_CHECK_GOTO(mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen), NULL, _OVER);
332!
2656
    TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
332!
2657

2658
  } else if (pAlter->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_NAME) {
582!
2659
    SIdxObj     idxObj = {0};
582✔
2660
    SField     *pField0 = taosArrayGet(pAlter->pFields, 0);
582✔
2661
    SField     *pField1 = taosArrayGet(pAlter->pFields, 1);
582✔
2662
    const char *oTagName = pField0->name;
582✔
2663
    const char *nTagName = pField1->name;
582✔
2664
    bool        exist = false;
582✔
2665

2666
    if (mndGetIdxsByTagName(pMnode, pStb, pField0->name, &idxObj) == 0) {
582✔
2667
      exist = true;
32✔
2668
    }
2669

2670
    TAOS_CHECK_GOTO(mndSetAlterStbPrepareLogs(pMnode, pTrans, pDb, pStb), NULL, _OVER);
582!
2671
    TAOS_CHECK_GOTO(mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb), NULL, _OVER);
582!
2672

2673
    if (exist == true) {
582✔
2674
      memcpy(idxObj.colName, nTagName, strlen(nTagName));
32✔
2675
      idxObj.colName[strlen(nTagName)] = 0;
32✔
2676
      TAOS_CHECK_GOTO(mndSetAlterIdxPrepareLogs(pMnode, pTrans, &idxObj), NULL, _OVER);
32!
2677
      TAOS_CHECK_GOTO(mndSetAlterIdxCommitLogs(pMnode, pTrans, &idxObj), NULL, _OVER);
32!
2678
    }
2679

2680
    TAOS_CHECK_GOTO(mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen), NULL, _OVER);
582!
2681
    TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
582!
2682
  }
2683
  code = 0;
914✔
2684

2685
_OVER:
914✔
2686
  mndTransDrop(pTrans);
914✔
2687
  TAOS_RETURN(code);
914✔
2688
}
2689

2690
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
3,042✔
2691
  bool    needRsp = true;
3,042✔
2692
  int32_t code = -1;
3,042✔
2693
  SField *pField0 = NULL;
3,042✔
2694

2695
  SStbObj stbObj = {0};
3,042✔
2696
  taosRLockLatch(&pOld->lock);
3,042✔
2697
  memcpy(&stbObj, pOld, sizeof(SStbObj));
3,042✔
2698
  taosRUnLockLatch(&pOld->lock);
3,042✔
2699
  stbObj.pColumns = NULL;
3,042✔
2700
  stbObj.pTags = NULL;
3,042✔
2701
  stbObj.pFuncs = NULL;
3,042✔
2702
  stbObj.pCmpr = NULL;
3,042✔
2703
  stbObj.pExtSchemas = NULL;
3,042✔
2704
  stbObj.updateTime = taosGetTimestampMs();
3,042✔
2705
  stbObj.lock = 0;
3,042✔
2706
  bool updateTagIndex = false;
3,042✔
2707
  switch (pAlter->alterType) {
3,042!
2708
    case TSDB_ALTER_TABLE_ADD_TAG:
448✔
2709
      code = mndAddSuperTableTag(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
448✔
2710
      break;
448✔
2711
    case TSDB_ALTER_TABLE_DROP_TAG:
364✔
2712
      pField0 = taosArrayGet(pAlter->pFields, 0);
364✔
2713
      code = mndDropSuperTableTag(pMnode, pOld, &stbObj, pField0->name);
364✔
2714
      updateTagIndex = true;
364✔
2715
      break;
364✔
2716
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
625✔
2717
      code = mndAlterStbTagName(pMnode, pOld, &stbObj, pAlter->pFields);
625✔
2718
      updateTagIndex = true;
625✔
2719
      break;
625✔
2720
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
42✔
2721
      pField0 = taosArrayGet(pAlter->pFields, 0);
42✔
2722
      code = mndAlterStbTagBytes(pMnode, pOld, &stbObj, pField0);
42✔
2723
      break;
42✔
2724
    case TSDB_ALTER_TABLE_ADD_COLUMN:
1,206✔
2725
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter, pAlter->numOfFields, 0);
1,206✔
2726
      break;
1,206✔
2727
    case TSDB_ALTER_TABLE_DROP_COLUMN:
227✔
2728
      pField0 = taosArrayGet(pAlter->pFields, 0);
227✔
2729
      code = mndDropSuperTableColumn(pMnode, pOld, &stbObj, pField0->name);
227✔
2730
      break;
227✔
2731
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
62✔
2732
      pField0 = taosArrayGet(pAlter->pFields, 0);
62✔
2733
      code = mndAlterStbColumnBytes(pMnode, pOld, &stbObj, pField0);
62✔
2734
      break;
62✔
2735
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
22✔
2736
      needRsp = false;
22✔
2737
      code = mndUpdateTableOptions(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl, pAlter->keep);
22✔
2738
      break;
22✔
2739
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS:
26✔
2740
      code = mndUpdateSuperTableColumnCompress(pMnode, pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
26✔
2741
      break;
26✔
2742
    case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
20✔
2743
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter, pAlter->numOfFields, 1);
20✔
2744
      break;
20✔
2745
    default:
×
2746
      needRsp = false;
×
2747
      terrno = TSDB_CODE_OPS_NOT_SUPPORT;
×
UNCOV
2748
      break;
×
2749
  }
2750

2751
  if (code != 0) goto _OVER;
3,042✔
2752
  if (updateTagIndex == false) {
2,858✔
2753
    code = mndAlterStbImp(pMnode, pReq, pDb, &stbObj, needRsp, pReq->pCont, pReq->contLen);
1,944✔
2754
  } else {
2755
    code = mndAlterStbAndUpdateTagIdxImp(pMnode, pReq, pDb, &stbObj, needRsp, pReq->pCont, pReq->contLen, pAlter);
914✔
2756
  }
2757

2758
_OVER:
3,042✔
2759
  taosMemoryFreeClear(stbObj.pTags);
3,042!
2760
  taosMemoryFreeClear(stbObj.pColumns);
3,042!
2761
  taosMemoryFreeClear(stbObj.pCmpr);
3,042!
2762
  if (pAlter->commentLen > 0) {
3,042✔
2763
    taosMemoryFreeClear(stbObj.comment);
17!
2764
  }
2765
  taosMemoryFreeClear(stbObj.pExtSchemas);
3,042!
2766
  TAOS_RETURN(code);
3,042✔
2767
}
2768

2769
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
3,046✔
2770
  SMnode       *pMnode = pReq->info.node;
3,046✔
2771
  int32_t       code = -1;
3,046✔
2772
  SDbObj       *pDb = NULL;
3,046✔
2773
  SStbObj      *pStb = NULL;
3,046✔
2774
  SMAlterStbReq alterReq = {0};
3,046✔
2775

2776
  if (tDeserializeSMAlterStbReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
3,046!
2777
    code = TSDB_CODE_INVALID_MSG;
×
2778
    goto _OVER;
×
2779
  }
2780

2781
  mInfo("stb:%s, start to alter", alterReq.name);
3,046!
2782
  if (mndCheckAlterStbReq(&alterReq) != 0) goto _OVER;
3,046!
2783

2784
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
3,046✔
2785
  if (pDb == NULL) {
3,046✔
2786
    code = TSDB_CODE_MND_DB_NOT_EXIST;
2✔
2787
    goto _OVER;
2✔
2788
  }
2789

2790
  pStb = mndAcquireStb(pMnode, alterReq.name);
3,044✔
2791
  if (pStb == NULL) {
3,044✔
2792
    code = TSDB_CODE_MND_STB_NOT_EXIST;
2✔
2793
    goto _OVER;
2✔
2794
  }
2795

2796
  if ((code = mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb)) != 0) {
3,042!
UNCOV
2797
    goto _OVER;
×
2798
  }
2799

2800
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
3,042✔
2801
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
3,042✔
2802

2803
  SName   name = {0};
3,042✔
2804
  int32_t ret = 0;
3,042✔
2805
  if ((ret = tNameFromString(&name, alterReq.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE)) != 0)
3,042!
UNCOV
2806
    mError("stb:%s, failed to tNameFromString since %s", alterReq.name, tstrerror(ret));
×
2807

2808
  auditRecord(pReq, pMnode->clusterId, "alterStb", name.dbname, name.tname, alterReq.sql, alterReq.sqlLen);
3,042✔
2809

2810
_OVER:
3,046✔
2811
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3,046!
2812
    mError("stb:%s, failed to alter since %s", alterReq.name, tstrerror(code));
188!
2813
  }
2814

2815
  mndReleaseStb(pMnode, pStb);
3,046✔
2816
  mndReleaseDb(pMnode, pDb);
3,046✔
2817
  tFreeSMAltertbReq(&alterReq);
3,046✔
2818

2819
  TAOS_RETURN(code);
3,046✔
2820
}
2821

2822
static int32_t mndSetDropStbPrepareLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
1,043✔
2823
  int32_t  code = 0;
1,043✔
2824
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
1,043✔
2825
  if (pRedoRaw == NULL) {
1,043!
UNCOV
2826
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2827
    if (terrno != 0) code = terrno;
×
UNCOV
2828
    TAOS_RETURN(code);
×
2829
  }
2830
  if ((code = mndTransAppendPrepareLog(pTrans, pRedoRaw)) != 0) {
1,043!
UNCOV
2831
    sdbFreeRaw(pRedoRaw);
×
UNCOV
2832
    TAOS_RETURN(code);
×
2833
  }
2834
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
1,043!
2835

2836
  TAOS_RETURN(code);
1,043✔
2837
}
2838

2839
static int32_t mndSetDropStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
1,043✔
2840
  int32_t  code = 0;
1,043✔
2841
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
1,043✔
2842
  if (pCommitRaw == NULL) {
1,043!
UNCOV
2843
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2844
    if (terrno != 0) code = terrno;
×
UNCOV
2845
    TAOS_RETURN(code);
×
2846
  }
2847
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
1,043!
UNCOV
2848
    sdbFreeRaw(pCommitRaw);
×
UNCOV
2849
    TAOS_RETURN(code);
×
2850
  }
2851
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
1,043!
2852

2853
  TAOS_RETURN(code);
1,043✔
2854
}
2855

2856
static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
1,043✔
2857
  int32_t code = 0;
1,043✔
2858
  SSdb   *pSdb = pMnode->pSdb;
1,043✔
2859
  SVgObj *pVgroup = NULL;
1,043✔
2860
  void   *pIter = NULL;
1,043✔
2861

2862
  while (1) {
6,551✔
2863
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
7,594✔
2864
    if (pIter == NULL) break;
7,594✔
2865
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
6,551✔
2866
      sdbRelease(pSdb, pVgroup);
4,082✔
2867
      continue;
4,082✔
2868
    }
2869

2870
    int32_t contLen = 0;
2,469✔
2871
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
2,469✔
2872
    if (pReq == NULL) {
2,469!
2873
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2874
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2875
      code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
2876
      TAOS_RETURN(code);
×
2877
    }
2878

2879
    STransAction action = {0};
2,469✔
2880
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
2,469✔
2881
    action.pCont = pReq;
2,469✔
2882
    action.contLen = contLen;
2,469✔
2883
    action.msgType = TDMT_VND_DROP_STB;
2,469✔
2884
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
2,469✔
2885
    if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
2,469!
UNCOV
2886
      taosMemoryFree(pReq);
×
UNCOV
2887
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2888
      sdbRelease(pSdb, pVgroup);
×
UNCOV
2889
      TAOS_RETURN(code);
×
2890
    }
2891
    sdbRelease(pSdb, pVgroup);
2,469✔
2892
  }
2893

2894
  TAOS_RETURN(code);
1,043✔
2895
}
2896

2897
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
1,043✔
2898
  int32_t code = -1;
1,043✔
2899
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "drop-stb");
1,043✔
2900
  if (pTrans == NULL) {
1,043!
UNCOV
2901
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
2902
    if (terrno != 0) code = terrno;
×
2903
    goto _OVER;
×
2904
  }
2905

2906
  mInfo("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
1,043!
2907
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
1,043✔
2908
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
1,043!
2909

2910
  TAOS_CHECK_GOTO(mndSetDropStbPrepareLogs(pMnode, pTrans, pStb), NULL, _OVER);
1,043!
2911
  TAOS_CHECK_GOTO(mndSetDropStbCommitLogs(pMnode, pTrans, pStb), NULL, _OVER);
1,043!
2912
  TAOS_CHECK_GOTO(mndSetDropStbRedoActions(pMnode, pTrans, pDb, pStb), NULL, _OVER);
1,043!
2913
  TAOS_CHECK_GOTO(mndDropIdxsByStb(pMnode, pTrans, pDb, pStb), NULL, _OVER);
1,043!
2914
  TAOS_CHECK_GOTO(mndDropSmasByStb(pMnode, pTrans, pDb, pStb), NULL, _OVER);
1,043!
2915
  TAOS_CHECK_GOTO(mndUserRemoveStb(pMnode, pTrans, pStb->name), NULL, _OVER);
1,043!
2916
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
1,043!
2917
  code = 0;
1,043✔
2918

2919
_OVER:
1,043✔
2920
  mndTransDrop(pTrans);
1,043✔
2921
  TAOS_RETURN(code);
1,043✔
2922
}
2923

2924
static int32_t mndCheckDropStbForTopic(SMnode *pMnode, const char *stbFullName, int64_t suid) {
1,047✔
2925
  int32_t code = 0;
1,047✔
2926
  SSdb   *pSdb = pMnode->pSdb;
1,047✔
2927
  void   *pIter = NULL;
1,047✔
2928
  while (1) {
80✔
2929
    SMqTopicObj *pTopic = NULL;
1,127✔
2930
    pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
1,127✔
2931
    if (pIter == NULL) break;
1,127✔
2932

2933
    if (pTopic->subType == TOPIC_SUB_TYPE__TABLE) {
80✔
2934
      if (pTopic->stbUid == suid) {
14!
UNCOV
2935
        sdbRelease(pSdb, pTopic);
×
UNCOV
2936
        sdbCancelFetch(pSdb, pIter);
×
UNCOV
2937
        TAOS_RETURN(-1);
×
2938
      }
2939
    }
2940

2941
    if (pTopic->ast == NULL) {
80✔
2942
      sdbRelease(pSdb, pTopic);
38✔
2943
      continue;
38✔
2944
    }
2945

2946
    SNode *pAst = NULL;
42✔
2947
    if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
42!
UNCOV
2948
      code = TSDB_CODE_MND_INVALID_TOPIC_OPTION;
×
UNCOV
2949
      mError("topic:%s, create ast error", pTopic->name);
×
UNCOV
2950
      sdbRelease(pSdb, pTopic);
×
UNCOV
2951
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2952
      TAOS_RETURN(code);
×
2953
    }
2954

2955
    SNodeList *pNodeList = NULL;
42✔
2956
    if ((code = nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList)) !=
42!
2957
        0) {
UNCOV
2958
      sdbRelease(pSdb, pTopic);
×
UNCOV
2959
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2960
      TAOS_RETURN(code);
×
2961
    }
2962
    SNode *pNode = NULL;
42✔
2963
    FOREACH(pNode, pNodeList) {
42✔
2964
      SColumnNode *pCol = (SColumnNode *)pNode;
28✔
2965

2966
      if (pCol->tableId == suid) {
28!
2967
        sdbRelease(pSdb, pTopic);
×
2968
        nodesDestroyNode(pAst);
×
UNCOV
2969
        nodesDestroyList(pNodeList);
×
UNCOV
2970
        sdbCancelFetch(pSdb, pIter);
×
UNCOV
2971
        TAOS_RETURN(-1);
×
2972
      } else {
2973
        goto NEXT;
28✔
2974
      }
2975
    }
2976
  NEXT:
14✔
2977
    sdbRelease(pSdb, pTopic);
42✔
2978
    nodesDestroyNode(pAst);
42✔
2979
    nodesDestroyList(pNodeList);
42✔
2980
  }
2981
  TAOS_RETURN(code);
1,047✔
2982
}
2983

2984
static int32_t mndCheckDropStbForStream(SMnode *pMnode, const char *stbFullName, int64_t suid) {
1,047✔
2985
  int32_t code = 0;
1,047✔
2986
  SSdb   *pSdb = pMnode->pSdb;
1,047✔
2987
  void   *pIter = NULL;
1,047✔
2988
  while (1) {
404✔
2989
    SStreamObj *pStream = NULL;
1,451✔
2990
    pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
1,451✔
2991
    if (pIter == NULL) break;
1,451✔
2992

2993
    if (pStream->targetStbUid == suid) {
408!
UNCOV
2994
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
2995
      sdbRelease(pSdb, pStream);
×
2996
      TAOS_RETURN(-1);
4✔
2997
    }
2998

2999
    SNode *pAst = NULL;
408✔
3000
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
408!
UNCOV
3001
      code = TSDB_CODE_MND_INVALID_STREAM_OPTION;
×
UNCOV
3002
      mError("stream:%s, create ast error", pStream->name);
×
UNCOV
3003
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
3004
      sdbRelease(pSdb, pStream);
×
UNCOV
3005
      TAOS_RETURN(code);
×
3006
    }
3007

3008
    SNodeList *pNodeList = NULL;
408✔
3009
    if ((code = nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList)) !=
408!
3010
        0) {
UNCOV
3011
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
3012
      sdbRelease(pSdb, pStream);
×
UNCOV
3013
      TAOS_RETURN(code);
×
3014
    }
3015
    SNode *pNode = NULL;
408✔
3016
    FOREACH(pNode, pNodeList) {
408!
3017
      SColumnNode *pCol = (SColumnNode *)pNode;
408✔
3018

3019
      if (pCol->tableId == suid) {
408✔
3020
        sdbCancelFetch(pSdb, pIter);
4✔
3021
        sdbRelease(pSdb, pStream);
4✔
3022
        nodesDestroyNode(pAst);
4✔
3023
        nodesDestroyList(pNodeList);
4✔
3024
        TAOS_RETURN(-1);
4✔
3025
      } else {
3026
        goto NEXT;
404✔
3027
      }
3028
    }
UNCOV
3029
  NEXT:
×
3030
    sdbRelease(pSdb, pStream);
404✔
3031
    nodesDestroyNode(pAst);
404✔
3032
    nodesDestroyList(pNodeList);
404✔
3033
  }
3034
  TAOS_RETURN(code);
1,043✔
3035
}
3036

UNCOV
3037
static int32_t mndProcessDropTtltbRsp(SRpcMsg *pRsp) { return 0; }
×
3038
static int32_t mndProcessTrimDbRsp(SRpcMsg *pRsp) { return 0; }
241✔
3039
static int32_t mndProcessS3MigrateDbRsp(SRpcMsg *pRsp) { return 0; }
×
3040

3041
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
1,364✔
3042
  SMnode      *pMnode = pReq->info.node;
1,364✔
3043
  int32_t      code = -1;
1,364✔
3044
  SDbObj      *pDb = NULL;
1,364✔
3045
  SStbObj     *pStb = NULL;
1,364✔
3046
  SMDropStbReq dropReq = {0};
1,364✔
3047

3048
  TAOS_CHECK_GOTO(tDeserializeSMDropStbReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
1,364!
3049

3050
  mInfo("stb:%s, start to drop", dropReq.name);
1,364!
3051

3052
  pStb = mndAcquireStb(pMnode, dropReq.name);
1,364✔
3053
  if (pStb == NULL) {
1,364✔
3054
    if (dropReq.igNotExists) {
317✔
3055
      mInfo("stb:%s, not exist, ignore not exist is set", dropReq.name);
315!
3056
      code = 0;
315✔
3057
      goto _OVER;
315✔
3058
    } else {
3059
      code = TSDB_CODE_MND_STB_NOT_EXIST;
2✔
3060
      goto _OVER;
2✔
3061
    }
3062
  }
3063

3064
  if ((dropReq.source == TD_REQ_FROM_TAOX_OLD || dropReq.source == TD_REQ_FROM_TAOX) && pStb->uid != dropReq.suid) {
1,047!
UNCOV
3065
    code = 0;
×
UNCOV
3066
    goto _OVER;
×
3067
  }
3068

3069
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
1,047✔
3070
  if (pDb == NULL) {
1,047!
UNCOV
3071
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
×
UNCOV
3072
    goto _OVER;
×
3073
  }
3074

3075
  if ((code = mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb)) != 0) {
1,047!
UNCOV
3076
    goto _OVER;
×
3077
  }
3078

3079
  if (mndCheckDropStbForTopic(pMnode, dropReq.name, pStb->uid) < 0) {
1,047!
3080
    code = TSDB_CODE_MND_TOPIC_MUST_BE_DELETED;
×
3081
    goto _OVER;
×
3082
  }
3083

3084
  if (mndCheckDropStbForStream(pMnode, dropReq.name, pStb->uid) < 0) {
1,047✔
3085
    code = TSDB_CODE_MND_STREAM_MUST_BE_DELETED;
4✔
3086
    goto _OVER;
4✔
3087
  }
3088

3089
  code = mndDropStb(pMnode, pReq, pDb, pStb);
1,043✔
3090
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
1,043!
3091

3092
  SName   name = {0};
1,043✔
3093
  int32_t ret = 0;
1,043✔
3094
  if ((ret = tNameFromString(&name, dropReq.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE)) != 0)
1,043!
UNCOV
3095
    mError("stb:%s, failed to tNameFromString since %s", dropReq.name, tstrerror(ret));
×
3096

3097
  auditRecord(pReq, pMnode->clusterId, "dropStb", name.dbname, name.tname, dropReq.sql, dropReq.sqlLen);
1,043✔
3098

3099
_OVER:
1,364✔
3100
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,364✔
3101
    mError("stb:%s, failed to drop since %s", dropReq.name, tstrerror(code));
6!
3102
  }
3103

3104
  mndReleaseDb(pMnode, pDb);
1,364✔
3105
  mndReleaseStb(pMnode, pStb);
1,364✔
3106
  tFreeSMDropStbReq(&dropReq);
1,364✔
3107
  TAOS_RETURN(code);
1,364✔
3108
}
3109

3110
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
927,242✔
3111
  SMnode       *pMnode = pReq->info.node;
927,242✔
3112
  int32_t       code = -1;
927,242✔
3113
  STableInfoReq infoReq = {0};
927,242✔
3114
  STableMetaRsp metaRsp = {0};
927,242✔
3115
  SUserObj     *pUser = NULL;
927,242✔
3116

3117
  code = mndAcquireUser(pMnode, pReq->info.conn.user, &pUser);
927,242✔
3118
  if (pUser == NULL) return 0;
927,249!
3119
  bool sysinfo = pUser->sysInfo;
927,249✔
3120

3121
  TAOS_CHECK_GOTO(tDeserializeSTableInfoReq(pReq->pCont, pReq->contLen, &infoReq), NULL, _OVER);
927,249!
3122

3123
  if (0 == strcmp(infoReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
927,253✔
3124
    mInfo("information_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
112,825!
3125
    TAOS_CHECK_GOTO(mndBuildInsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, sysinfo, &metaRsp), NULL, _OVER);
112,825✔
3126
  } else if (0 == strcmp(infoReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
814,428✔
3127
    mInfo("performance_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
27,024!
3128
    TAOS_CHECK_GOTO(mndBuildPerfsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp), NULL, _OVER);
27,024✔
3129
  } else {
3130
    mInfo("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
787,404✔
3131
    TAOS_CHECK_GOTO(mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp), NULL, _OVER);
787,431✔
3132
  }
3133

3134
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
925,462✔
3135
  if (rspLen < 0) {
925,422!
UNCOV
3136
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3137
    goto _OVER;
×
3138
  }
3139

3140
  void *pRsp = rpcMallocCont(rspLen);
925,422✔
3141
  if (pRsp == NULL) {
925,419!
UNCOV
3142
    code = terrno;
×
UNCOV
3143
    goto _OVER;
×
3144
  }
3145

3146
  if ((rspLen = tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp)) < 0) {
925,419!
UNCOV
3147
    code = rspLen;
×
UNCOV
3148
    goto _OVER;
×
3149
  }
3150
  pReq->info.rsp = pRsp;
925,451✔
3151
  pReq->info.rspLen = rspLen;
925,451✔
3152
  code = 0;
925,451✔
3153

3154
  mTrace("%s.%s, meta is retrieved", infoReq.dbFName, infoReq.tbName);
925,451✔
3155

3156
_OVER:
923,473✔
3157
  if (code != 0) {
927,249✔
3158
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, tstrerror(code));
1,798!
3159
  }
3160

3161
  mndReleaseUser(pMnode, pUser);
927,249✔
3162
  tFreeSTableMetaRsp(&metaRsp);
927,260✔
3163
  // TODO change to TAOS_RETURN
3164
  return code;
927,240✔
3165
}
3166

3167
static int32_t mndProcessTableCfgReq(SRpcMsg *pReq) {
42✔
3168
  SMnode      *pMnode = pReq->info.node;
42✔
3169
  int32_t      code = -1;
42✔
3170
  STableCfgReq cfgReq = {0};
42✔
3171
  STableCfgRsp cfgRsp = {0};
42✔
3172

3173
  TAOS_CHECK_GOTO(tDeserializeSTableCfgReq(pReq->pCont, pReq->contLen, &cfgReq), NULL, _OVER);
42!
3174

3175
  char dbName[TSDB_DB_NAME_LEN] = {0};
42✔
3176
  TAOS_CHECK_GOTO(mndExtractShortDbNameFromDbFullName(cfgReq.dbFName, dbName), NULL, _OVER);
42!
3177
  if (0 == strcmp(dbName, TSDB_INFORMATION_SCHEMA_DB)) {
42!
UNCOV
3178
    mInfo("information_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
×
3179
    TAOS_CHECK_GOTO(mndBuildInsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp), NULL, _OVER);
×
3180
  } else if (0 == strcmp(dbName, TSDB_PERFORMANCE_SCHEMA_DB)) {
42!
UNCOV
3181
    mInfo("performance_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
×
UNCOV
3182
    TAOS_CHECK_GOTO(mndBuildPerfsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp), NULL, _OVER);
×
3183
  } else {
3184
    mInfo("stb:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
42!
3185
    TAOS_CHECK_GOTO(mndBuildStbCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp), NULL, _OVER);
42!
3186
  }
3187

3188
  int32_t rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp);
42✔
3189
  if (rspLen < 0) {
42!
3190
    code = TSDB_CODE_INVALID_MSG;
×
3191
    goto _OVER;
×
3192
  }
3193

3194
  void *pRsp = rpcMallocCont(rspLen);
42✔
3195
  if (pRsp == NULL) {
42!
3196
    code = terrno;
×
3197
    goto _OVER;
×
3198
  }
3199

3200
  if ((rspLen = tSerializeSTableCfgRsp(pRsp, rspLen, &cfgRsp)) < 0) {
42!
UNCOV
3201
    code = rspLen;
×
3202
    goto _OVER;
×
3203
  }
3204
  pReq->info.rsp = pRsp;
42✔
3205
  pReq->info.rspLen = rspLen;
42✔
3206
  code = 0;
42✔
3207

3208
  mTrace("%s.%s, cfg is retrieved", cfgReq.dbFName, cfgReq.tbName);
42✔
3209

3210
_OVER:
28✔
3211
  if (code != 0) {
42!
UNCOV
3212
    mError("stb:%s.%s, failed to retrieve cfg since %s", cfgReq.dbFName, cfgReq.tbName, tstrerror(code));
×
3213
  }
3214

3215
  tFreeSTableCfgRsp(&cfgRsp);
42✔
3216
  TAOS_RETURN(code);
42✔
3217
}
3218

3219
int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t numOfStbs, void **ppRsp,
75,776✔
3220
                           int32_t *pRspLen) {
3221
  int32_t   code = 0;
75,776✔
3222
  SSTbHbRsp hbRsp = {0};
75,776✔
3223
  hbRsp.pMetaRsp = taosArrayInit(numOfStbs, sizeof(STableMetaRsp));
75,776✔
3224
  if (hbRsp.pMetaRsp == NULL) {
75,776!
UNCOV
3225
    code = terrno;
×
UNCOV
3226
    TAOS_RETURN(code);
×
3227
  }
3228

3229
  hbRsp.pIndexRsp = taosArrayInit(numOfStbs, sizeof(STableIndexRsp));
75,776✔
3230
  if (NULL == hbRsp.pIndexRsp) {
75,776!
UNCOV
3231
    taosArrayDestroy(hbRsp.pMetaRsp);
×
UNCOV
3232
    code = terrno;
×
UNCOV
3233
    TAOS_RETURN(code);
×
3234
  }
3235

3236
  for (int32_t i = 0; i < numOfStbs; ++i) {
167,795✔
3237
    SSTableVersion *pStbVersion = &pStbVersions[i];
92,019✔
3238
    pStbVersion->suid = be64toh(pStbVersion->suid);
92,019✔
3239
    pStbVersion->sversion = ntohl(pStbVersion->sversion);
92,019✔
3240
    pStbVersion->tversion = ntohl(pStbVersion->tversion);
92,019✔
3241
    pStbVersion->smaVer = ntohl(pStbVersion->smaVer);
92,019✔
3242

3243
    bool    schema = false;
92,019✔
3244
    bool    sma = false;
92,019✔
3245
    int32_t code = mndValidateStbVersion(pMnode, pStbVersion, &schema, &sma);
92,019✔
3246
    if (TSDB_CODE_SUCCESS != code) {
92,019✔
3247
      STableMetaRsp metaRsp = {0};
840✔
3248
      metaRsp.numOfColumns = -1;
840✔
3249
      metaRsp.suid = pStbVersion->suid;
840✔
3250
      tstrncpy(metaRsp.dbFName, pStbVersion->dbFName, sizeof(metaRsp.dbFName));
840✔
3251
      tstrncpy(metaRsp.tbName, pStbVersion->stbName, sizeof(metaRsp.tbName));
840✔
3252
      tstrncpy(metaRsp.stbName, pStbVersion->stbName, sizeof(metaRsp.stbName));
840✔
3253
      if (taosArrayPush(hbRsp.pMetaRsp, &metaRsp) == NULL) {
1,680!
UNCOV
3254
        code = terrno;
×
UNCOV
3255
        return code;
×
3256
      }
3257
      continue;
840✔
3258
    }
3259

3260
    if (schema) {
91,179✔
3261
      STableMetaRsp metaRsp = {0};
463✔
3262
      mInfo("stb:%s.%s, start to retrieve meta", pStbVersion->dbFName, pStbVersion->stbName);
463!
3263
      if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp) != 0) {
463!
3264
        metaRsp.numOfColumns = -1;
×
UNCOV
3265
        metaRsp.suid = pStbVersion->suid;
×
3266
        tstrncpy(metaRsp.dbFName, pStbVersion->dbFName, sizeof(metaRsp.dbFName));
×
UNCOV
3267
        tstrncpy(metaRsp.tbName, pStbVersion->stbName, sizeof(metaRsp.tbName));
×
3268
        tstrncpy(metaRsp.stbName, pStbVersion->stbName, sizeof(metaRsp.stbName));
×
UNCOV
3269
        if (taosArrayPush(hbRsp.pMetaRsp, &metaRsp) == NULL) {
×
UNCOV
3270
          code = terrno;
×
UNCOV
3271
          return code;
×
3272
        }
UNCOV
3273
        continue;
×
3274
      }
3275

3276
      if (taosArrayPush(hbRsp.pMetaRsp, &metaRsp) == NULL) {
926!
UNCOV
3277
        code = terrno;
×
UNCOV
3278
        return code;
×
3279
      }
3280
    }
3281

3282
    if (sma) {
91,179!
UNCOV
3283
      bool           exist = false;
×
3284
      char           tbFName[TSDB_TABLE_FNAME_LEN];
UNCOV
3285
      STableIndexRsp indexRsp = {0};
×
UNCOV
3286
      indexRsp.pIndex = taosArrayInit(10, sizeof(STableIndexInfo));
×
UNCOV
3287
      if (NULL == indexRsp.pIndex) {
×
UNCOV
3288
        code = terrno;
×
UNCOV
3289
        TAOS_RETURN(code);
×
3290
      }
3291

UNCOV
3292
      (void)tsnprintf(tbFName, sizeof(tbFName), "%s.%s", pStbVersion->dbFName, pStbVersion->stbName);
×
UNCOV
3293
      int32_t code = mndGetTableSma(pMnode, tbFName, &indexRsp, &exist);
×
UNCOV
3294
      if (code || !exist) {
×
UNCOV
3295
        indexRsp.suid = pStbVersion->suid;
×
UNCOV
3296
        indexRsp.version = -1;
×
UNCOV
3297
        indexRsp.pIndex = NULL;
×
3298
      }
3299

UNCOV
3300
      tstrncpy(indexRsp.dbFName, pStbVersion->dbFName, sizeof(indexRsp.dbFName));
×
UNCOV
3301
      tstrncpy(indexRsp.tbName, pStbVersion->stbName, sizeof(indexRsp.tbName));
×
3302

UNCOV
3303
      if (taosArrayPush(hbRsp.pIndexRsp, &indexRsp) == NULL) {
×
UNCOV
3304
        code = terrno;
×
UNCOV
3305
        return code;
×
3306
      }
3307
    }
3308
  }
3309

3310
  int32_t rspLen = tSerializeSSTbHbRsp(NULL, 0, &hbRsp);
75,776✔
3311
  if (rspLen < 0) {
75,775!
UNCOV
3312
    tFreeSSTbHbRsp(&hbRsp);
×
UNCOV
3313
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
3314
    TAOS_RETURN(code);
×
3315
  }
3316

3317
  void *pRsp = taosMemoryMalloc(rspLen);
75,775!
3318
  if (pRsp == NULL) {
75,776!
UNCOV
3319
    tFreeSSTbHbRsp(&hbRsp);
×
UNCOV
3320
    code = terrno;
×
UNCOV
3321
    TAOS_RETURN(code);
×
3322
  }
3323

3324
  rspLen = tSerializeSSTbHbRsp(pRsp, rspLen, &hbRsp);
75,776✔
3325
  tFreeSSTbHbRsp(&hbRsp);
75,776✔
3326
  if (rspLen < 0) return rspLen;
75,776!
3327
  *ppRsp = pRsp;
75,776✔
3328
  *pRspLen = rspLen;
75,776✔
3329
  TAOS_RETURN(code);
75,776✔
3330
}
3331

3332
int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
8,802✔
3333
  int32_t code = 0;
8,802✔
3334
  SSdb   *pSdb = pMnode->pSdb;
8,802✔
3335
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
8,802✔
3336
  if (pDb == NULL) {
8,802!
UNCOV
3337
    code = TSDB_CODE_MND_DB_NOT_SELECTED;
×
UNCOV
3338
    TAOS_RETURN(code);
×
3339
  }
3340

3341
  int32_t numOfStbs = 0;
8,802✔
3342
  void   *pIter = NULL;
8,802✔
3343
  while (1) {
183,841✔
3344
    SStbObj *pStb = NULL;
192,643✔
3345
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
192,643✔
3346
    if (pIter == NULL) break;
192,643✔
3347

3348
    if (pStb->dbUid == pDb->uid) {
183,841✔
3349
      numOfStbs++;
85,012✔
3350
    }
3351

3352
    sdbRelease(pSdb, pStb);
183,841✔
3353
  }
3354

3355
  *pNumOfStbs = numOfStbs;
8,802✔
3356
  mndReleaseDb(pMnode, pDb);
8,802✔
3357
  TAOS_RETURN(code);
8,802✔
3358
}
3359

UNCOV
3360
int32_t mndExtractDbNameFromStbFullName(const char *stbFullName, char *dst) {
×
UNCOV
3361
  SName name = {0};
×
UNCOV
3362
  TAOS_CHECK_RETURN(tNameFromString(&name, stbFullName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
×
3363

UNCOV
3364
  TAOS_CHECK_RETURN(tNameGetFullDbName(&name, dst));
×
3365

3366
  return 0;
×
3367
}
3368

3369
int32_t mndExtractShortDbNameFromStbFullName(const char *stbFullName, char *dst) {
3✔
3370
  SName name = {0};
3✔
3371
  TAOS_CHECK_RETURN(tNameFromString(&name, stbFullName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
3!
3372

3373
  TAOS_CHECK_RETURN(tNameGetDbName(&name, dst));
3!
3374

3375
  return 0;
3✔
3376
}
3377

3378
int32_t mndExtractShortDbNameFromDbFullName(const char *stbFullName, char *dst) {
42✔
3379
  SName name = {0};
42✔
3380
  TAOS_CHECK_RETURN(tNameFromString(&name, stbFullName, T_NAME_ACCT | T_NAME_DB));
42!
3381

3382
  TAOS_CHECK_RETURN(tNameGetDbName(&name, dst));
42!
3383

3384
  return 0;
42✔
3385
}
3386

3387
void mndExtractTbNameFromStbFullName(const char *stbFullName, char *dst, int32_t dstSize) {
1,661,981✔
3388
  int32_t pos = -1;
1,661,981✔
3389
  int32_t num = 0;
1,661,981✔
3390
  for (pos = 0; stbFullName[pos] != 0; ++pos) {
28,881,191!
3391
    if (stbFullName[pos] == TS_PATH_DELIMITER[0]) num++;
28,881,198✔
3392
    if (num == 2) break;
28,881,198✔
3393
  }
3394

3395
  if (num == 2) {
1,661,981✔
3396
    tstrncpy(dst, stbFullName + pos + 1, dstSize);
1,661,941✔
3397
  }
3398
}
1,661,981✔
3399

3400
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
17,401✔
3401
  SMnode  *pMnode = pReq->info.node;
17,401✔
3402
  SSdb    *pSdb = pMnode->pSdb;
17,401✔
3403
  int32_t  numOfRows = 0;
17,401✔
3404
  SStbObj *pStb = NULL;
17,401✔
3405
  int32_t  cols = 0;
17,401✔
3406
  int32_t  lino = 0;
17,401✔
3407
  int32_t  code = 0;
17,401✔
3408

3409
  SDbObj *pDb = NULL;
17,401✔
3410
  if (strlen(pShow->db) > 0) {
17,401✔
3411
    pDb = mndAcquireDb(pMnode, pShow->db);
407✔
3412
    if (pDb == NULL) return terrno;
407✔
3413
  }
3414

3415
  while (numOfRows < rows) {
908,463✔
3416
    pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
900,202✔
3417
    if (pShow->pIter == NULL) break;
900,092✔
3418

3419
    if (pDb != NULL && pStb->dbUid != pDb->uid) {
890,939✔
3420
      sdbRelease(pSdb, pStb);
879✔
3421
      continue;
891✔
3422
    }
3423

3424
    if (isTsmaResSTb(pStb->name)) {
890,060✔
3425
      sdbRelease(pSdb, pStb);
12✔
3426
      continue;
12✔
3427
    }
3428

3429
    cols = 0;
889,944✔
3430

3431
    SName name = {0};
889,944✔
3432

3433
    char stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
889,944✔
3434
    mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
889,944✔
3435
    varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
889,990✔
3436
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
889,990✔
3437
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)stbName, false), pStb, &lino, _ERROR);
889,843!
3438

3439
    char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
889,298✔
3440
    RETRIEVE_CHECK_GOTO(tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB), pStb, &lino, _ERROR);
889,298!
3441
    RETRIEVE_CHECK_GOTO(tNameGetDbName(&name, varDataVal(db)), pStb, &lino, _ERROR);
889,711!
3442
    varDataSetLen(db, strlen(varDataVal(db)));
889,760✔
3443
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
889,760✔
3444
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)db, false), pStb, &lino, _ERROR);
889,674!
3445

3446
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,949✔
3447
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->createdTime, false), pStb, &lino,
888,762!
3448
                        _ERROR);
3449

3450
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,425✔
3451
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->numOfColumns, false), pStb, &lino,
888,215!
3452
                        _ERROR);
3453

3454
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,227✔
3455
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->numOfTags, false), pStb, &lino, _ERROR);
888,090!
3456

3457
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,208✔
3458
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->updateTime, false), pStb, &lino,
888,044!
3459
                        _ERROR);  // number of tables
3460

3461
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,107✔
3462
    if (pStb->commentLen > 0) {
887,956!
UNCOV
3463
      char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
×
UNCOV
3464
      STR_TO_VARSTR(comment, pStb->comment);
×
UNCOV
3465
      RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, comment, false), pStb, &lino, _ERROR);
×
3466
    } else if (pStb->commentLen == 0) {
888,021✔
3467
      char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
25,993✔
3468
      STR_TO_VARSTR(comment, "");
25,993✔
3469
      RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, comment, false), pStb, &lino, _ERROR);
25,993!
3470
    } else {
3471
      colDataSetNULL(pColInfo, numOfRows);
862,028!
3472
    }
3473

3474
    char watermark[64 + VARSTR_HEADER_SIZE] = {0};
888,088✔
3475
    (void)tsnprintf(varDataVal(watermark), sizeof(watermark) - VARSTR_HEADER_SIZE, "%" PRId64 "a,%" PRId64 "a",
888,088✔
3476
              pStb->watermark[0], pStb->watermark[1]);
888,088✔
3477
    varDataSetLen(watermark, strlen(varDataVal(watermark)));
889,823✔
3478

3479
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
889,823✔
3480
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)watermark, false), pStb, &lino, _ERROR);
889,362!
3481

3482
    char maxDelay[64 + VARSTR_HEADER_SIZE] = {0};
888,644✔
3483
    (void)tsnprintf(varDataVal(maxDelay), sizeof(maxDelay) - VARSTR_HEADER_SIZE, "%" PRId64 "a,%" PRId64 "a",
888,644✔
3484
              pStb->maxdelay[0], pStb->maxdelay[1]);
888,644✔
3485
    varDataSetLen(maxDelay, strlen(varDataVal(maxDelay)));
889,755✔
3486

3487
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
889,755✔
3488
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)maxDelay, false), pStb, &lino, _ERROR);
889,317!
3489

3490
    char    rollup[160 + VARSTR_HEADER_SIZE] = {0};
888,743✔
3491
    int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
888,743✔
3492
    char   *sep = ", ";
888,944✔
3493
    int32_t sepLen = strlen(sep);
888,944✔
3494
    int32_t rollupLen = sizeof(rollup) - VARSTR_HEADER_SIZE - 2;
888,944✔
3495
    for (int32_t i = 0; i < rollupNum; ++i) {
888,947✔
3496
      char *funcName = taosArrayGet(pStb->pFuncs, i);
3✔
3497
      if (i) {
3!
UNCOV
3498
        (void)strncat(varDataVal(rollup), sep, rollupLen);
×
UNCOV
3499
        rollupLen -= sepLen;
×
3500
      }
3501
      (void)strncat(varDataVal(rollup), funcName, rollupLen);
3✔
3502
      rollupLen -= strlen(funcName);
3✔
3503
    }
3504
    varDataSetLen(rollup, strlen(varDataVal(rollup)));
888,944✔
3505

3506
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,944✔
3507
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)rollup, false), pStb, &lino, _ERROR);
888,995!
3508

3509
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
888,598✔
3510
    if (pColInfo) {
888,304!
3511
      RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->uid), false), pStb, &lino, _ERROR);
888,325!
3512
    }
3513

3514
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
887,912✔
3515
    if (pColInfo) {
887,646!
3516
      RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->virtualStb), false), pStb, &lino, _ERROR);
887,660!
3517
    }
3518
    numOfRows++;
887,792✔
3519
    sdbRelease(pSdb, pStb);
887,792✔
3520
  }
3521

3522
  if (pDb != NULL) {
17,414✔
3523
    mndReleaseDb(pMnode, pDb);
404✔
3524
  }
3525

3526
  goto _OVER;
17,404✔
3527

UNCOV
3528
_ERROR:
×
UNCOV
3529
  mError("show:0x%" PRIx64 ", failed to retrieve data at %s:%d since %s", pShow->id, __FUNCTION__, lino,
×
3530
         tstrerror(code));
3531

UNCOV
3532
_OVER:
×
3533
  pShow->numOfRows += numOfRows;
17,404✔
3534
  return numOfRows;
17,404✔
3535
}
3536

3537
static int32_t buildDbColsInfoBlock(const SSDataBlock *p, const SSysTableMeta *pSysDbTableMeta, size_t size,
28,027✔
3538
                                    const char *dbName, const char *tbName) {
3539
  char    tName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
28,027✔
3540
  char    dName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
28,027✔
3541
  char    typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
28,027✔
3542
  int32_t numOfRows = p->info.rows;
28,027✔
3543
  int32_t lino = 0;
28,027✔
3544
  int32_t code = 0;
28,027✔
3545

3546
  STR_TO_VARSTR(dName, dbName);
28,027✔
3547
  STR_TO_VARSTR(typeName, "SYSTEM_TABLE");
28,027✔
3548

3549
  for (int32_t i = 0; i < size; ++i) {
623,557✔
3550
    const SSysTableMeta *pm = &pSysDbTableMeta[i];
602,471✔
3551
    //    if (pm->sysInfo) {
3552
    //      continue;
3553
    //    }
3554
    if (tbName[0] && strncmp(tbName, pm->name, TSDB_TABLE_NAME_LEN) != 0) {
602,471!
UNCOV
3555
      continue;
×
3556
    }
3557

3558
    STR_TO_VARSTR(tName, pm->name);
602,471✔
3559

3560
    for (int32_t j = 0; j < pm->colNum; j++) {
5,957,597✔
3561
      // table name
3562
      SColumnInfoData *pColInfoData = taosArrayGet(p->pDataBlock, 0);
5,362,067✔
3563
      TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, tName, false), &lino, _OVER);
5,358,944!
3564

3565
      // database name
3566
      pColInfoData = taosArrayGet(p->pDataBlock, 1);
5,352,003✔
3567
      TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, dName, false), &lino, _OVER);
5,350,387!
3568

3569
      pColInfoData = taosArrayGet(p->pDataBlock, 2);
5,350,529✔
3570
      TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, typeName, false), &lino, _OVER);
5,349,404!
3571

3572
      // col name
3573
      char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
5,353,196✔
3574
      STR_TO_VARSTR(colName, pm->schema[j].name);
5,353,196✔
3575
      pColInfoData = taosArrayGet(p->pDataBlock, 3);
5,353,196✔
3576
      TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, colName, false), &lino, _OVER);
5,367,661!
3577

3578
      // col type
3579
      int8_t colType = pm->schema[j].type;
5,357,606✔
3580
      pColInfoData = taosArrayGet(p->pDataBlock, 4);
5,357,606✔
3581
      char colTypeStr[VARSTR_HEADER_SIZE + 32];
3582
      int  colTypeLen =
5,380,897✔
3583
          tsnprintf(varDataVal(colTypeStr), sizeof(colTypeStr) - VARSTR_HEADER_SIZE, "%s", tDataTypes[colType].name);
5,356,177✔
3584
      if (colType == TSDB_DATA_TYPE_VARCHAR) {
5,380,897✔
3585
        colTypeLen +=
2,956,778✔
3586
            tsnprintf(varDataVal(colTypeStr) + colTypeLen, sizeof(colTypeStr) - colTypeLen - VARSTR_HEADER_SIZE, "(%d)",
2,956,665✔
3587
                      (int32_t)(pm->schema[j].bytes - VARSTR_HEADER_SIZE));
2,956,665✔
3588
      } else if (colType == TSDB_DATA_TYPE_NCHAR) {
2,424,232!
UNCOV
3589
        colTypeLen +=
×
UNCOV
3590
            tsnprintf(varDataVal(colTypeStr) + colTypeLen, sizeof(colTypeStr) - colTypeLen - VARSTR_HEADER_SIZE, "(%d)",
×
UNCOV
3591
                      (int32_t)((pm->schema[j].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
×
3592
      }
3593
      varDataSetLen(colTypeStr, colTypeLen);
5,381,010✔
3594
      TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, (char *)colTypeStr, false), &lino, _OVER);
5,381,010!
3595

3596
      pColInfoData = taosArrayGet(p->pDataBlock, 5);
5,363,292✔
3597
      TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, (const char *)&pm->schema[j].bytes, false), &lino, _OVER);
5,361,752!
3598
      for (int32_t k = 6; k <= 9; ++k) {
26,712,141✔
3599
        pColInfoData = taosArrayGet(p->pDataBlock, k);
21,357,015✔
3600
        colDataSetNULL(pColInfoData, numOfRows);
21,352,416✔
3601
      }
3602

3603
      numOfRows += 1;
5,355,126✔
3604
    }
3605
  }
3606
  return numOfRows;
21,086✔
UNCOV
3607
_OVER:
×
UNCOV
3608
  mError("failed at %s:%d since %s", __FUNCTION__, lino, tstrerror(code));
×
UNCOV
3609
  return numOfRows;
×
3610
}
3611
#define BUILD_COL_FOR_INFO_DB 1
3612
#define BUILD_COL_FOR_PERF_DB 1 << 1
3613
#define BUILD_COL_FOR_USER_DB 1 << 2
3614
#define BUILD_COL_FOR_ALL_DB  (BUILD_COL_FOR_INFO_DB | BUILD_COL_FOR_PERF_DB | BUILD_COL_FOR_USER_DB)
3615

3616
static int32_t buildSysDbColsInfo(SSDataBlock *p, int8_t buildWhichDBs, char *tb) {
14,016✔
3617
  size_t               size = 0;
14,016✔
3618
  const SSysTableMeta *pSysDbTableMeta = NULL;
14,016✔
3619

3620
  if (buildWhichDBs & BUILD_COL_FOR_INFO_DB) {
14,016!
3621
    getInfosDbMeta(&pSysDbTableMeta, &size);
14,016✔
3622
    p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB, tb);
14,016✔
3623
  }
3624

3625
  if (buildWhichDBs & BUILD_COL_FOR_PERF_DB) {
14,015✔
3626
    getPerfDbMeta(&pSysDbTableMeta, &size);
14,011✔
3627
    p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB, tb);
14,011✔
3628
  }
3629

3630
  return p->info.rows;
14,016✔
3631
}
3632

3633
static int8_t determineBuildColForWhichDBs(const char *db) {
14,016✔
3634
  int8_t buildWhichDBs;
3635
  if (!db[0])
14,016✔
3636
    buildWhichDBs = BUILD_COL_FOR_ALL_DB;
14,012✔
3637
  else {
3638
    char *p = strchr(db, '.');
4✔
3639
    if (p && strcmp(p + 1, TSDB_INFORMATION_SCHEMA_DB) == 0) {
4!
3640
      buildWhichDBs = BUILD_COL_FOR_INFO_DB;
4✔
UNCOV
3641
    } else if (p && strcmp(p + 1, TSDB_PERFORMANCE_SCHEMA_DB) == 0) {
×
UNCOV
3642
      buildWhichDBs = BUILD_COL_FOR_PERF_DB;
×
3643
    } else {
UNCOV
3644
      buildWhichDBs = BUILD_COL_FOR_USER_DB;
×
3645
    }
3646
  }
3647
  return buildWhichDBs;
14,016✔
3648
}
3649

3650
static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
14,016✔
3651
  uint8_t  buildWhichDBs;
3652
  SMnode  *pMnode = pReq->info.node;
14,016✔
3653
  SSdb    *pSdb = pMnode->pSdb;
14,016✔
3654
  SStbObj *pStb = NULL;
14,016✔
3655
  int32_t  numOfRows = 0;
14,016✔
3656
  int32_t  lino = 0;
14,016✔
3657
  int32_t  code = 0;
14,016✔
3658

3659
  buildWhichDBs = determineBuildColForWhichDBs(pShow->db);
14,016✔
3660

3661
  if (!pShow->sysDbRsp) {
14,016!
3662
    numOfRows = buildSysDbColsInfo(pBlock, buildWhichDBs, pShow->filterTb);
14,016✔
3663
    mDebug("mndRetrieveStbCol get system table cols, rows:%d, db:%s", numOfRows, pShow->db);
14,016✔
3664
    pShow->sysDbRsp = true;
14,016✔
3665
  }
3666

3667
  if (buildWhichDBs & BUILD_COL_FOR_USER_DB) {
14,016✔
3668
    SDbObj *pDb = NULL;
14,012✔
3669
    if (strlen(pShow->db) > 0) {
14,012!
UNCOV
3670
      pDb = mndAcquireDb(pMnode, pShow->db);
×
UNCOV
3671
      if (pDb == NULL && TSDB_CODE_MND_DB_NOT_EXIST != terrno && pBlock->info.rows == 0) return terrno;
×
3672
    }
3673

3674
    char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
14,012✔
3675
    STR_TO_VARSTR(typeName, "SUPER_TABLE");
14,012✔
3676
    bool fetch = pShow->restore ? false : true;
14,012✔
3677
    pShow->restore = false;
14,012✔
3678
    while (numOfRows < rows) {
785,853✔
3679
      if (fetch) {
785,852!
3680
        pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
785,852✔
3681
        if (pShow->pIter == NULL) break;
785,743✔
3682
      } else {
3683
        fetch = true;
×
3684
        void *pKey = taosHashGetKey(pShow->pIter, NULL);
×
3685
        pStb = sdbAcquire(pSdb, SDB_STB, pKey);
×
3686
        if (!pStb) continue;
×
3687
      }
3688

3689
      if (pDb != NULL && pStb->dbUid != pDb->uid) {
771,731!
UNCOV
3690
        sdbRelease(pSdb, pStb);
×
UNCOV
3691
        continue;
×
3692
      }
3693

3694
      SName name = {0};
771,731✔
3695
      char  stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
771,731✔
3696
      mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
771,731✔
3697
      if (pShow->filterTb[0] && strncmp(pShow->filterTb, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN) != 0) {
771,826!
UNCOV
3698
        sdbRelease(pSdb, pStb);
×
3699
        continue;
×
3700
      }
3701

3702
      if ((numOfRows + pStb->numOfColumns) > rows) {
771,826!
UNCOV
3703
        pShow->restore = true;
×
UNCOV
3704
        if (numOfRows == 0) {
×
UNCOV
3705
          mError("mndRetrieveStbCol failed to get stable cols since buf:%d less than result:%d, stable name:%s, db:%s",
×
3706
                 rows, pStb->numOfColumns, pStb->name, pStb->db);
3707
        }
UNCOV
3708
        sdbRelease(pSdb, pStb);
×
UNCOV
3709
        break;
×
3710
      }
3711

3712
      varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
771,826✔
3713

3714
      mDebug("mndRetrieveStbCol get stable cols, stable name:%s, db:%s", pStb->name, pStb->db);
771,826✔
3715

3716
      char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
771,826✔
3717
      RETRIEVE_CHECK_GOTO(tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB), pStb, &lino, _OVER);
771,826!
3718
      RETRIEVE_CHECK_GOTO(tNameGetDbName(&name, varDataVal(db)), pStb, &lino, _OVER);
771,780!
3719
      varDataSetLen(db, strlen(varDataVal(db)));
771,845✔
3720

3721
      for (int i = 0; i < pStb->numOfColumns; i++) {
18,554,011✔
3722
        int32_t          cols = 0;
17,987,498✔
3723
        SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,987,498✔
3724
        RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)stbName, false), pStb, &lino, _OVER);
17,925,337!
3725

3726
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,911,833✔
3727
        RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)db, false), pStb, &lino, _OVER);
17,884,705!
3728

3729
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,890,428✔
3730
        RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, typeName, false), pStb, &lino, _OVER);
17,865,592!
3731

3732
        // col name
3733
        char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
17,909,406✔
3734
        STR_TO_VARSTR(colName, pStb->pColumns[i].name);
17,909,406✔
3735
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,909,406✔
3736
        RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, colName, false), pStb, &lino, _OVER);
18,041,749!
3737

3738
        // col type
3739
        int8_t colType = pStb->pColumns[i].type;
17,943,125✔
3740
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,943,125✔
3741
        char colTypeStr[VARSTR_HEADER_SIZE + 32];
3742
        int  colTypeLen =
18,128,232✔
3743
            tsnprintf(varDataVal(colTypeStr), sizeof(colTypeStr) - VARSTR_HEADER_SIZE, "%s", tDataTypes[colType].name);
17,919,826✔
3744
        if (colType == TSDB_DATA_TYPE_VARCHAR) {
18,128,232✔
3745
          colTypeLen +=
1,434,613✔
3746
              tsnprintf(varDataVal(colTypeStr) + colTypeLen, sizeof(colTypeStr) - colTypeLen - VARSTR_HEADER_SIZE,
1,434,648✔
3747
                        "(%d)", (int32_t)(pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE));
1,434,648✔
3748
        } else if (colType == TSDB_DATA_TYPE_NCHAR) {
16,693,584✔
3749
          colTypeLen +=
1,448,902✔
3750
              tsnprintf(varDataVal(colTypeStr) + colTypeLen, sizeof(colTypeStr) - colTypeLen - VARSTR_HEADER_SIZE,
1,448,839✔
3751
                        "(%d)", (int32_t)((pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
1,448,839✔
3752
        } else if (IS_DECIMAL_TYPE(colType)) {
15,244,745!
3753
          STypeMod typeMod = pStb->pExtSchemas[i].typeMod;
10,982✔
3754
          uint8_t prec = 0, scale = 0;
10,982✔
3755
          decimalFromTypeMod(typeMod, &prec, &scale);
10,982✔
UNCOV
3756
          colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d,%d)", prec, scale);
×
3757
        }
3758
        varDataSetLen(colTypeStr, colTypeLen);
18,117,278✔
3759
        RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (char *)colTypeStr, false), pStb, &lino, _OVER);
18,117,278!
3760

3761
        pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
17,957,833✔
3762
        RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->pColumns[i].bytes, false), pStb,
17,933,189!
3763
                            &lino, _OVER);
3764
        while (cols < pShow->numOfColumns) {
88,562,935✔
3765
          pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
70,780,769✔
3766
          colDataSetNULL(pColInfo, numOfRows);
70,652,604✔
3767
        }
3768
        numOfRows++;
17,782,166✔
3769
      }
3770

3771
      sdbRelease(pSdb, pStb);
566,513✔
3772
    }
3773

3774
    if (pDb != NULL) {
14,013!
UNCOV
3775
      mndReleaseDb(pMnode, pDb);
×
3776
    }
3777
  }
3778

3779
  mDebug("mndRetrieveStbCol success, rows:%d, pShow->numOfRows:%d", numOfRows, pShow->numOfRows);
14,016✔
3780
  goto _OVER;
14,016✔
3781

3782
_ERROR:
3783
  mError("failed to mndRetrieveStbCol, rows:%d, pShow->numOfRows:%d, at %s:%d since %s", numOfRows, pShow->numOfRows,
3784
         __FUNCTION__, lino, tstrerror(code));
3785

3786
_OVER:
14,016✔
3787
  pShow->numOfRows += numOfRows;
14,016✔
3788
  return numOfRows;
14,016✔
3789
}
3790

UNCOV
3791
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
×
UNCOV
3792
  SSdb *pSdb = pMnode->pSdb;
×
UNCOV
3793
  sdbCancelFetchByType(pSdb, pIter, SDB_STB);
×
UNCOV
3794
}
×
3795

3796
const char *mndGetStbStr(const char *src) {
35,361✔
3797
  char *posDb = strstr(src, TS_PATH_DELIMITER);
35,361✔
3798
  if (posDb != NULL) ++posDb;
35,361!
3799
  if (posDb == NULL) return src;
35,361!
3800

3801
  char *posStb = strstr(posDb, TS_PATH_DELIMITER);
35,361✔
3802
  if (posStb != NULL) ++posStb;
35,361!
3803
  if (posStb == NULL) return posDb;
35,361!
3804
  return posStb;
35,361✔
3805
}
3806

UNCOV
3807
static int32_t mndCheckIndexReq(SCreateTagIndexReq *pReq) {
×
3808
  // impl
UNCOV
3809
  return TSDB_CODE_SUCCESS;
×
3810
}
3811

3812
/*int32_t mndAddIndexImpl(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp, void *sql,
3813
                        int32_t len) {
3814
  // impl later
3815
  int32_t code = 0;
3816
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "create-stb-index");
3817
  if (pTrans == NULL) goto _OVER;
3818

3819
  mInfo("trans:%d, used to add index to stb:%s", pTrans->id, pStb->name);
3820
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
3821
  if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
3822

3823
  if (mndSetAlterStbPrepareLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
3824
  if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
3825
  if (mndSetAlterStbRedoActions2(pMnode, pTrans, pDb, pStb, sql, len) != 0) goto _OVER;
3826
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
3827

3828
  return code;
3829

3830
_OVER:
3831
  mndTransDrop(pTrans);
3832
  return code;
3833
}
3834
static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *tagIdxReq, SDbObj *pDb, SStbObj *pOld) {
3835
  bool    needRsp = true;
3836
  int32_t code = -1;
3837
  SField *pField0 = NULL;
3838

3839
  SStbObj  stbObj = {0};
3840
  SStbObj *pNew = &stbObj;
3841

3842
  taosRLockLatch(&pOld->lock);
3843
  memcpy(&stbObj, pOld, sizeof(SStbObj));
3844
  taosRUnLockLatch(&pOld->lock);
3845

3846
  stbObj.pColumns = NULL;
3847
  stbObj.pTags = NULL;
3848
  stbObj.updateTime = taosGetTimestampMs();
3849
  stbObj.lock = 0;
3850

3851
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagIdxReq->colName);
3852
  if (tag < 0) {
3853
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
3854
    return -1;
3855
  }
3856
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
3857
    return -1;
3858
  }
3859

3860
  SSchema *pTag = pNew->pTags + tag;
3861
  if (IS_IDX_ON(pTag)) {
3862
    terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST;
3863
    return -1;
3864
  } else {
3865
    pTag->flags |= COL_IDX_ON;
3866
  }
3867
  pNew->tagVer++;
3868

3869
  code = mndAddIndexImpl(pMnode, pReq, pDb, pNew, needRsp, pReq->pCont, pReq->contLen);
3870

3871
  return code;
3872
}
3873
static int32_t mndProcessCreateIndexReq(SRpcMsg *pReq) {
3874
  SMnode            *pMnode = pReq->info.node;
3875
  int32_t            code = -1;
3876
  SDbObj            *pDb = NULL;
3877
  SStbObj           *pStb = NULL;
3878
  SCreateTagIndexReq tagIdxReq = {0};
3879

3880
  if (tDeserializeSCreateTagIdxReq(pReq->pCont, pReq->contLen, &tagIdxReq) != 0) {
3881
    terrno = TSDB_CODE_INVALID_MSG;
3882
    goto _OVER;
3883
  }
3884

3885
  mInfo("stb:%s, start to alter", tagIdxReq.stbName);
3886

3887
  if (mndCheckIndexReq(&tagIdxReq) != TSDB_CODE_SUCCESS) {
3888
    goto _OVER;
3889
  }
3890

3891
  pDb = mndAcquireDbByStb(pMnode, tagIdxReq.dbFName);
3892
  if (pDb == NULL) {
3893
    terrno = TSDB_CODE_MND_DB_NOT_EXIST;
3894
    goto _OVER;
3895
  }
3896

3897
  pStb = mndAcquireStb(pMnode, tagIdxReq.stbName);
3898
  if (pStb == NULL) {
3899
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
3900
    goto _OVER;
3901
  }
3902
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
3903
    goto _OVER;
3904
  }
3905

3906
  code = mndAddIndex(pMnode, pReq, &tagIdxReq, pDb, pStb);
3907
  if (terrno == TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST || terrno == TSDB_CODE_MND_TAG_NOT_EXIST) {
3908
    return terrno;
3909
  } else {
3910
    if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
3911
  }
3912
_OVER:
3913
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3914
    mError("stb:%s, failed to create index since %s", tagIdxReq.stbName, terrstr());
3915
  }
3916
  mndReleaseStb(pMnode, pStb);
3917
  mndReleaseDb(pMnode, pDb);
3918
  return code;
3919
}
3920
static int32_t mndProcessDropIndexReq(SRpcMsg *pReq) {
3921
  SMnode          *pMnode = pReq->info.node;
3922
  int32_t          code = -1;
3923
  SDbObj          *pDb = NULL;
3924
  SStbObj         *pStb = NULL;
3925
  SDropTagIndexReq dropReq = {0};
3926
  if (tDeserializeSDropTagIdxReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
3927
    terrno = TSDB_CODE_INVALID_MSG;
3928
    goto _OVER;
3929
  }
3930
  //
3931
  return TSDB_CODE_SUCCESS;
3932
_OVER:
3933
  return code;
3934
}*/
3935

3936
static int32_t mndProcessDropStbReqFromMNode(SRpcMsg *pReq) {
214✔
3937
  int32_t code = mndProcessDropStbReq(pReq);
214✔
3938
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
214!
UNCOV
3939
    pReq->info.rsp = rpcMallocCont(1);
×
UNCOV
3940
    pReq->info.rspLen = 1;
×
UNCOV
3941
    pReq->info.noResp = false;
×
UNCOV
3942
    pReq->code = code;
×
3943
  }
3944
  return code;
214✔
3945
}
3946

3947
typedef struct SVDropTbVgReqs {
3948
  SArray     *pBatchReqs;
3949
  SVgroupInfo info;
3950
} SVDropTbVgReqs;
3951

3952
typedef struct SMDropTbDbInfo {
3953
  SArray *dbVgInfos;
3954
  int32_t hashPrefix;
3955
  int32_t hashSuffix;
3956
  int32_t hashMethod;
3957
} SMDropTbDbInfo;
3958

3959
typedef struct SMDropTbTsmaInfo {
3960
  char           tsmaResTbDbFName[TSDB_DB_FNAME_LEN];
3961
  char           tsmaResTbNamePrefix[TSDB_TABLE_FNAME_LEN];
3962
  int32_t        suid;
3963
  SMDropTbDbInfo dbInfo;  // reference to DbInfo in pDbMap
3964
} SMDropTbTsmaInfo;
3965

3966
typedef struct SMDropTbTsmaInfos {
3967
  SArray *pTsmaInfos;  // SMDropTbTsmaInfo
3968
} SMDropTbTsmaInfos;
3969

3970
typedef struct SMndDropTbsWithTsmaCtx {
3971
  SHashObj *pVgMap;  // <vgId, SVDropTbVgReqs>
3972
} SMndDropTbsWithTsmaCtx;
3973

3974
static int32_t mndDropTbForSingleVg(SMnode *pMnode, SMndDropTbsWithTsmaCtx *pCtx, SArray *pTbs, int32_t vgId);
3975

3976
static void destroySVDropTbBatchReqs(void *p);
3977
static void mndDestroyDropTbsWithTsmaCtx(SMndDropTbsWithTsmaCtx *p) {
30✔
3978
  if (!p) return;
30!
3979

3980
  if (p->pVgMap) {
30!
3981
    void *pIter = taosHashIterate(p->pVgMap, NULL);
30✔
3982
    while (pIter) {
65✔
3983
      SVDropTbVgReqs *pReqs = pIter;
35✔
3984
      taosArrayDestroyEx(pReqs->pBatchReqs, destroySVDropTbBatchReqs);
35✔
3985
      pIter = taosHashIterate(p->pVgMap, pIter);
35✔
3986
    }
3987
    taosHashCleanup(p->pVgMap);
30✔
3988
  }
3989
  taosMemoryFree(p);
30!
3990
}
3991

3992
static int32_t mndInitDropTbsWithTsmaCtx(SMndDropTbsWithTsmaCtx **ppCtx) {
30✔
3993
  int32_t                 code = 0;
30✔
3994
  SMndDropTbsWithTsmaCtx *pCtx = taosMemoryCalloc(1, sizeof(SMndDropTbsWithTsmaCtx));
30!
3995
  if (!pCtx) return terrno;
30!
3996

3997
  pCtx->pVgMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
30✔
3998
  if (!pCtx->pVgMap) {
30!
UNCOV
3999
    code = terrno;
×
4000
    goto _end;
×
4001
  }
4002

4003
  *ppCtx = pCtx;
30✔
4004
_end:
30✔
4005
  if (code) mndDestroyDropTbsWithTsmaCtx(pCtx);
30!
4006
  return code;
30✔
4007
}
4008

4009
static void *mndBuildVDropTbsReq(SMnode *pMnode, const SVgroupInfo *pVgInfo, const SVDropTbBatchReq *pReq,
35✔
4010
                                 int32_t *len) {
4011
  int32_t   contLen = 0;
35✔
4012
  int32_t   ret = 0;
35✔
4013
  SMsgHead *pHead = NULL;
35✔
4014
  SEncoder  encoder = {0};
35✔
4015

4016
  tEncodeSize(tEncodeSVDropTbBatchReq, pReq, contLen, ret);
35!
4017
  if (ret < 0) return NULL;
35!
4018

4019
  contLen += sizeof(SMsgHead);
35✔
4020
  pHead = taosMemoryMalloc(contLen);
35!
4021
  if (pHead == NULL) {
35!
UNCOV
4022
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
4023
    return NULL;
×
4024
  }
4025

4026
  pHead->contLen = htonl(contLen);
35✔
4027
  pHead->vgId = htonl(pVgInfo->vgId);
35✔
4028

4029
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
35✔
4030

4031
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
35✔
4032
  int32_t code = tEncodeSVDropTbBatchReq(&encoder, pReq);
35✔
4033
  tEncoderClear(&encoder);
35✔
4034
  if (code != 0) return NULL;
35!
4035

4036
  *len = contLen;
35✔
4037
  return pHead;
35✔
4038
}
4039

4040
static int32_t mndSetDropTbsRedoActions(SMnode *pMnode, STrans *pTrans, const SVDropTbVgReqs *pVgReqs, void *pCont,
35✔
4041
                                        int32_t contLen, tmsg_t msgType) {
4042
  STransAction action = {0};
35✔
4043
  action.epSet = pVgReqs->info.epSet;
35✔
4044
  action.pCont = pCont;
35✔
4045
  action.contLen = contLen;
35✔
4046
  action.msgType = msgType;
35✔
4047
  action.acceptableCode = TSDB_CODE_TDB_TABLE_NOT_EXIST;
35✔
4048
  return mndTransAppendRedoAction(pTrans, &action);
35✔
4049
}
4050

4051
static int32_t mndBuildDropTbRedoActions(SMnode *pMnode, STrans *pTrans, SHashObj *pVgMap, tmsg_t msgType) {
30✔
4052
  int32_t code = 0;
30✔
4053
  void   *pIter = taosHashIterate(pVgMap, NULL);
30✔
4054
  while (pIter) {
65✔
4055
    const SVDropTbVgReqs *pVgReqs = pIter;
35✔
4056
    int32_t               len = 0;
35✔
4057
    for (int32_t i = 0; i < taosArrayGetSize(pVgReqs->pBatchReqs) && code == TSDB_CODE_SUCCESS; ++i) {
70!
4058
      SVDropTbBatchReq *pBatchReq = taosArrayGet(pVgReqs->pBatchReqs, i);
35✔
4059
      void             *p = mndBuildVDropTbsReq(pMnode, &pVgReqs->info, pBatchReq, &len);
35✔
4060
      if (!p) {
35!
UNCOV
4061
        code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4062
        if (terrno != 0) code = terrno;
×
4063
        break;
×
4064
      }
4065
      if ((code = mndSetDropTbsRedoActions(pMnode, pTrans, pVgReqs, p, len, msgType)) != 0) {
35!
4066
        break;
×
4067
      }
4068
    }
4069
    if (TSDB_CODE_SUCCESS != code) {
35!
UNCOV
4070
      taosHashCancelIterate(pVgMap, pIter);
×
UNCOV
4071
      break;
×
4072
    }
4073
    pIter = taosHashIterate(pVgMap, pIter);
35✔
4074
  }
4075
  return code;
30✔
4076
}
4077

4078
static int32_t mndCreateDropTbsTxnPrepare(SRpcMsg *pRsp, SMndDropTbsWithTsmaCtx *pCtx) {
30✔
4079
  int32_t code = 0;
30✔
4080
  SMnode *pMnode = pRsp->info.node;
30✔
4081
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pRsp, "drop-tbs");
30✔
4082
  mndTransSetChangeless(pTrans);
30✔
4083
  mndTransSetSerial(pTrans);
30✔
4084
  if (pTrans == NULL) {
30!
UNCOV
4085
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
UNCOV
4086
    if (terrno != 0) code = terrno;
×
UNCOV
4087
    goto _OVER;
×
4088
  }
4089

4090
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
30!
4091

4092
  if ((code = mndBuildDropTbRedoActions(pMnode, pTrans, pCtx->pVgMap, TDMT_VND_DROP_TABLE)) != 0) goto _OVER;
30!
4093
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
30!
4094

4095
_OVER:
30✔
4096
  mndTransDrop(pTrans);
30✔
4097
  TAOS_RETURN(code);
30✔
4098
}
4099

4100
static int32_t mndProcessDropTbWithTsma(SRpcMsg *pReq) {
25✔
4101
  int32_t      code = -1;
25✔
4102
  SMnode      *pMnode = pReq->info.node;
25✔
4103
  SDbObj      *pDb = NULL;
25✔
4104
  SStbObj     *pStb = NULL;
25✔
4105
  SMDropTbsReq dropReq = {0};
25✔
4106
  bool         locked = false;
25✔
4107
  if (tDeserializeSMDropTbsReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
25!
UNCOV
4108
    code = TSDB_CODE_INVALID_MSG;
×
UNCOV
4109
    goto _OVER;
×
4110
  }
4111

4112
  SMndDropTbsWithTsmaCtx *pCtx = NULL;
25✔
4113
  code = mndInitDropTbsWithTsmaCtx(&pCtx);
25✔
4114
  if (code) goto _OVER;
25!
4115
  for (int32_t i = 0; i < dropReq.pVgReqs->size; ++i) {
55✔
4116
    SMDropTbReqsOnSingleVg *pReq = taosArrayGet(dropReq.pVgReqs, i);
30✔
4117
    code = mndDropTbForSingleVg(pMnode, pCtx, pReq->pTbs, pReq->vgInfo.vgId);
30✔
4118
    if (code) goto _OVER;
30!
4119
  }
4120
  code = mndCreateDropTbsTxnPrepare(pReq, pCtx);
25✔
4121
  if (code == 0) {
25!
4122
    code = TSDB_CODE_ACTION_IN_PROGRESS;
25✔
4123
  }
UNCOV
4124
_OVER:
×
4125
  tFreeSMDropTbsReq(&dropReq);
25✔
4126
  if (pCtx) mndDestroyDropTbsWithTsmaCtx(pCtx);
25!
4127
  TAOS_RETURN(code);
25✔
4128
}
4129

4130
static int32_t createDropTbBatchReq(const SVDropTbReq *pReq, SVDropTbBatchReq *pBatchReq) {
35✔
4131
  pBatchReq->nReqs = 1;
35✔
4132
  pBatchReq->pArray = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SVDropTbReq));
35✔
4133
  if (!pBatchReq->pArray) return terrno;
35!
4134
  if (taosArrayPush(pBatchReq->pArray, pReq) == NULL) {
70!
UNCOV
4135
    taosArrayDestroy(pBatchReq->pArray);
×
UNCOV
4136
    pBatchReq->pArray = NULL;
×
UNCOV
4137
    return terrno;
×
4138
  }
4139
  return TSDB_CODE_SUCCESS;
35✔
4140
}
4141

4142
static void destroySVDropTbBatchReqs(void *p) {
35✔
4143
  SVDropTbBatchReq *pReq = p;
35✔
4144
  taosArrayDestroy(pReq->pArray);
35✔
4145
  pReq->pArray = NULL;
35✔
4146
}
35✔
4147

4148
static int32_t mndDropTbAdd(SMnode *pMnode, SHashObj *pVgHashMap, const SVgroupInfo *pVgInfo, char *name, tb_uid_t suid,
35✔
4149
                            bool ignoreNotExists) {
4150
  SVDropTbReq req = {.name = name, .suid = suid, .igNotExists = ignoreNotExists, .uid = 0};
35✔
4151

4152
  SVDropTbVgReqs *pVgReqs = taosHashGet(pVgHashMap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
35✔
4153
  SVDropTbVgReqs  vgReqs = {0};
35✔
4154
  if (pVgReqs == NULL) {
35!
4155
    vgReqs.info = *pVgInfo;
35✔
4156
    vgReqs.pBatchReqs = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SVDropTbBatchReq));
35✔
4157
    if (!vgReqs.pBatchReqs) return terrno;
35!
4158
    SVDropTbBatchReq batchReq = {0};
35✔
4159
    int32_t          code = createDropTbBatchReq(&req, &batchReq);
35✔
4160
    if (TSDB_CODE_SUCCESS != code) return code;
35!
4161
    if (taosArrayPush(vgReqs.pBatchReqs, &batchReq) == NULL) {
70!
UNCOV
4162
      taosArrayDestroy(batchReq.pArray);
×
UNCOV
4163
      return terrno;
×
4164
    }
4165
    if (taosHashPut(pVgHashMap, &pVgInfo->vgId, sizeof(pVgInfo->vgId), &vgReqs, sizeof(vgReqs)) != 0) {
35!
UNCOV
4166
      taosArrayDestroyEx(vgReqs.pBatchReqs, destroySVDropTbBatchReqs);
×
UNCOV
4167
      return terrno;
×
4168
    }
4169
  } else {
UNCOV
4170
    SVDropTbBatchReq batchReq = {0};
×
UNCOV
4171
    int32_t          code = createDropTbBatchReq(&req, &batchReq);
×
UNCOV
4172
    if (TSDB_CODE_SUCCESS != code) return code;
×
UNCOV
4173
    if (taosArrayPush(pVgReqs->pBatchReqs, &batchReq) == NULL) {
×
UNCOV
4174
      taosArrayDestroy(batchReq.pArray);
×
UNCOV
4175
      return terrno;
×
4176
    }
4177
  }
4178
  return 0;
35✔
4179
}
4180

4181
static int32_t mndDropTbForSingleVg(SMnode *pMnode, SMndDropTbsWithTsmaCtx *pCtx, SArray *pTbs, int32_t vgId) {
35✔
4182
  int32_t code = 0;
35✔
4183

4184
  SVgObj *pVgObj = mndAcquireVgroup(pMnode, vgId);
35✔
4185
  if (!pVgObj) {
35!
UNCOV
4186
    code = 0;
×
UNCOV
4187
    goto _end;
×
4188
  }
4189
  SVgroupInfo vgInfo = {.hashBegin = pVgObj->hashBegin,
35✔
4190
                        .hashEnd = pVgObj->hashEnd,
35✔
4191
                        .numOfTable = pVgObj->numOfTables,
35✔
4192
                        .vgId = pVgObj->vgId};
35✔
4193
  vgInfo.epSet = mndGetVgroupEpset(pMnode, pVgObj);
35✔
4194
  mndReleaseVgroup(pMnode, pVgObj);
35✔
4195

4196
  for (int32_t i = 0; i < pTbs->size; ++i) {
70✔
4197
    SVDropTbReq *pTb = taosArrayGet(pTbs, i);
35✔
4198
    TAOS_CHECK_GOTO(mndDropTbAdd(pMnode, pCtx->pVgMap, &vgInfo, pTb->name, pTb->suid, pTb->igNotExists), NULL, _end);
35!
4199
  }
4200
_end:
35✔
4201
  return code;
35✔
4202
}
4203

4204
static int32_t mndProcessFetchTtlExpiredTbs(SRpcMsg *pRsp) {
113,255✔
4205
  int32_t                 code = -1;
113,255✔
4206
  SDecoder                decoder = {0};
113,255✔
4207
  SMnode                 *pMnode = pRsp->info.node;
113,255✔
4208
  SVFetchTtlExpiredTbsRsp rsp = {0};
113,255✔
4209
  SMndDropTbsWithTsmaCtx *pCtx = NULL;
113,255✔
4210
  if (pRsp->code != TSDB_CODE_SUCCESS) {
113,255✔
4211
    code = pRsp->code;
480✔
4212
    goto _end;
480✔
4213
  }
4214
  if (pRsp->contLen == 0) {
112,775✔
4215
    code = 0;
112,770✔
4216
    goto _end;
112,770✔
4217
  }
4218

4219
  tDecoderInit(&decoder, pRsp->pCont, pRsp->contLen);
5✔
4220
  code = tDecodeVFetchTtlExpiredTbsRsp(&decoder, &rsp);
5✔
4221
  if (code) goto _end;
5!
4222

4223
  code = mndInitDropTbsWithTsmaCtx(&pCtx);
5✔
4224
  if (code) goto _end;
5!
4225

4226
  code = mndDropTbForSingleVg(pMnode, pCtx, rsp.pExpiredTbs, rsp.vgId);
5✔
4227
  if (code) goto _end;
5!
4228
  code = mndCreateDropTbsTxnPrepare(pRsp, pCtx);
5✔
4229
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
5!
UNCOV
4230
_end:
×
4231
  if (pCtx) mndDestroyDropTbsWithTsmaCtx(pCtx);
113,255✔
4232
  tDecoderClear(&decoder);
113,255✔
4233
  tFreeFetchTtlExpiredTbsRsp(&rsp);
113,255✔
4234
  TAOS_RETURN(code);
113,255✔
4235
}
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