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

S
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "mndStb.h"
S
Shengliang Guan 已提交
18
#include "mndDb.h"
S
Shengliang Guan 已提交
19
#include "mndDnode.h"
S
Shengliang Guan 已提交
20
#include "mndInfoSchema.h"
S
Shengliang Guan 已提交
21
#include "mndMnode.h"
H
Hongze Cheng 已提交
22
#include "mndPerfSchema.h"
23
#include "mndPrivilege.h"
C
Cary Xu 已提交
24
#include "mndScheduler.h"
S
Shengliang Guan 已提交
25
#include "mndShow.h"
26
#include "mndSma.h"
27
#include "mndTopic.h"
S
Shengliang Guan 已提交
28 29
#include "mndTrans.h"
#include "mndUser.h"
30
#include "mndVgroup.h"
S
Shengliang Guan 已提交
31
#include "tname.h"
S
Shengliang Guan 已提交
32

S
Shengliang Guan 已提交
33 34
#define STB_VER_NUMBER   1
#define STB_RESERVE_SIZE 64
S
Shengliang Guan 已提交
35 36 37 38

static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
static int32_t  mndStbActionInsert(SSdb *pSdb, SStbObj *pStb);
static int32_t  mndStbActionDelete(SSdb *pSdb, SStbObj *pStb);
S
Shengliang Guan 已提交
39
static int32_t  mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew);
S
Shengliang Guan 已提交
40
static int32_t  mndProcessTtlTimer(SRpcMsg *pReq);
41 42 43
static int32_t  mndProcessCreateStbReq(SRpcMsg *pReq);
static int32_t  mndProcessAlterStbReq(SRpcMsg *pReq);
static int32_t  mndProcessDropStbReq(SRpcMsg *pReq);
wmmhello's avatar
wmmhello 已提交
44
static int32_t  mndProcessDropTtltbReq(SRpcMsg *pReq);
S
Shengliang Guan 已提交
45 46
static int32_t  mndProcessTableMetaReq(SRpcMsg *pReq);
static int32_t  mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
S
Shengliang Guan 已提交
47
static void     mndCancelGetNextStb(SMnode *pMnode, void *pIter);
D
dapan1121 已提交
48
static int32_t  mndProcessTableCfgReq(SRpcMsg *pReq);
49 50 51
static int32_t  mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
                               void *alterOriData, int32_t alterOriDataLen);
static int32_t  mndCheckColAndTagModifiable(SMnode *pMnode, const char *stbname, int64_t suid, col_id_t colId);
S
Shengliang Guan 已提交
52 53

int32_t mndInitStb(SMnode *pMnode) {
S
Shengliang Guan 已提交
54 55 56 57 58 59 60 61 62
  SSdbTable table = {
      .sdbType = SDB_STB,
      .keyType = SDB_KEY_BINARY,
      .encodeFp = (SdbEncodeFp)mndStbActionEncode,
      .decodeFp = (SdbDecodeFp)mndStbActionDecode,
      .insertFp = (SdbInsertFp)mndStbActionInsert,
      .updateFp = (SdbUpdateFp)mndStbActionUpdate,
      .deleteFp = (SdbDeleteFp)mndStbActionDelete,
  };
S
Shengliang Guan 已提交
63

64 65 66
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcessCreateStbReq);
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessAlterStbReq);
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessDropStbReq);
67
  mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndTransProcessRsp);
wmmhello's avatar
wmmhello 已提交
68
  mndSetMsgHandle(pMnode, TDMT_VND_DROP_TTL_TABLE_RSP, mndProcessDropTtltbReq);
69 70
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndTransProcessRsp);
  mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndTransProcessRsp);
D
dapan1121 已提交
71
  mndSetMsgHandle(pMnode, TDMT_MND_TABLE_META, mndProcessTableMetaReq);
S
Shengliang Guan 已提交
72
  mndSetMsgHandle(pMnode, TDMT_MND_TTL_TIMER, mndProcessTtlTimer);
D
dapan1121 已提交
73
  mndSetMsgHandle(pMnode, TDMT_MND_TABLE_CFG, mndProcessTableCfgReq);
S
Shengliang Guan 已提交
74 75 76

  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STB, mndCancelGetNextStb);
S
Shengliang Guan 已提交
77 78

  return sdbSetTable(pMnode->pSdb, table);
S
Shengliang Guan 已提交
79 80
}

S
Shengliang Guan 已提交
81
void mndCleanupStb(SMnode *pMnode) {}
S
Shengliang Guan 已提交
82

83
SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
84 85
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
86
  int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + pStb->commentLen +
D
dapan1121 已提交
87
                 pStb->ast1Len + pStb->ast2Len + STB_RESERVE_SIZE + taosArrayGetSize(pStb->pFuncs) * TSDB_FUNC_NAME_LEN;
S
Shengliang Guan 已提交
88
  SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, STB_VER_NUMBER, size);
89
  if (pRaw == NULL) goto _OVER;
S
Shengliang Guan 已提交
90 91

  int32_t dataPos = 0;
92 93 94 95 96 97
  SDB_SET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, _OVER)
  SDB_SET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->createdTime, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->updateTime, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->uid, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->dbUid, _OVER)
98 99
  SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
S
Shengliang Guan 已提交
100
  SDB_SET_INT32(pRaw, dataPos, pStb->smaVer, _OVER)
101
  SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
102 103 104 105
  SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[0], _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[1], _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->watermark[0], _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->watermark[1], _OVER)
106 107 108
  SDB_SET_INT32(pRaw, dataPos, pStb->ttl, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, _OVER)
S
Shengliang Guan 已提交
109
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfFuncs, _OVER)
110
  SDB_SET_INT32(pRaw, dataPos, pStb->commentLen, _OVER)
111 112
  SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER)
S
Shengliang Guan 已提交
113

S
Shengliang Guan 已提交
114 115
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
116
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
S
Shengliang Guan 已提交
117
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
118 119 120
    SDB_SET_INT16(pRaw, dataPos, pSchema->colId, _OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
121 122 123 124
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
125
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
S
Shengliang Guan 已提交
126
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
127 128 129
    SDB_SET_INT16(pRaw, dataPos, pSchema->colId, _OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
130 131
  }

S
Shengliang Guan 已提交
132 133 134 135 136
  for (int32_t i = 0; i < pStb->numOfFuncs; ++i) {
    char *func = taosArrayGet(pStb->pFuncs, i);
    SDB_SET_BINARY(pRaw, dataPos, func, TSDB_FUNC_NAME_LEN, _OVER)
  }

S
sma  
Shengliang Guan 已提交
137
  if (pStb->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
138
    SDB_SET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
S
sma  
Shengliang Guan 已提交
139
  }
S
Shengliang Guan 已提交
140

141 142 143
  if (pStb->ast1Len > 0) {
    SDB_SET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
  }
S
Shengliang Guan 已提交
144

145 146 147
  if (pStb->ast2Len > 0) {
    SDB_SET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
  }
S
Shengliang Guan 已提交
148

S
Shengliang Guan 已提交
149
  SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
150
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
151 152 153

  terrno = 0;

154
_OVER:
155 156 157 158 159
  if (terrno != 0) {
    mError("stb:%s, failed to encode to raw:%p since %s", pStb->name, pRaw, terrstr());
    sdbFreeRaw(pRaw);
    return NULL;
  }
S
Shengliang Guan 已提交
160

161
  mTrace("stb:%s, encode to raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
162 163 164
  return pRaw;
}

S
Shengliang Guan 已提交
165
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
166
  terrno = TSDB_CODE_OUT_OF_MEMORY;
167 168
  SSdbRow *pRow = NULL;
  SStbObj *pStb = NULL;
169

S
Shengliang Guan 已提交
170
  int8_t sver = 0;
171
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
172

S
Shengliang Guan 已提交
173
  if (sver != STB_VER_NUMBER) {
S
Shengliang Guan 已提交
174
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
175
    goto _OVER;
S
Shengliang Guan 已提交
176 177
  }

178
  pRow = sdbAllocRow(sizeof(SStbObj));
179
  if (pRow == NULL) goto _OVER;
180

181
  pStb = sdbGetRowObj(pRow);
182
  if (pStb == NULL) goto _OVER;
S
Shengliang Guan 已提交
183 184

  int32_t dataPos = 0;
185 186 187 188 189 190
  SDB_GET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, _OVER)
  SDB_GET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->createdTime, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->updateTime, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->uid, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->dbUid, _OVER)
191 192
  SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
S
Shengliang Guan 已提交
193
  SDB_GET_INT32(pRaw, dataPos, &pStb->smaVer, _OVER)
194
  SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
195 196 197 198
  SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[0], _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[1], _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->watermark[0], _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->watermark[1], _OVER)
199 200 201
  SDB_GET_INT32(pRaw, dataPos, &pStb->ttl, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, _OVER)
S
Shengliang Guan 已提交
202
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfFuncs, _OVER)
203
  SDB_GET_INT32(pRaw, dataPos, &pStb->commentLen, _OVER)
204 205
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER)
S
Shengliang Guan 已提交
206

wafwerar's avatar
wafwerar 已提交
207 208
  pStb->pColumns = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchema));
  pStb->pTags = taosMemoryCalloc(pStb->numOfTags, sizeof(SSchema));
S
Shengliang Guan 已提交
209
  pStb->pFuncs = taosArrayInit(pStb->numOfFuncs, TSDB_FUNC_NAME_LEN);
S
Shengliang Guan 已提交
210
  if (pStb->pColumns == NULL || pStb->pTags == NULL || pStb->pFuncs == NULL) {
211
    goto _OVER;
S
Shengliang 已提交
212
  }
S
Shengliang Guan 已提交
213

S
Shengliang Guan 已提交
214 215
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
216
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
S
Shengliang Guan 已提交
217
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
218 219 220
    SDB_GET_INT16(pRaw, dataPos, &pSchema->colId, _OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, _OVER)
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
221 222 223 224
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
225
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
S
Shengliang Guan 已提交
226
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
227 228 229
    SDB_GET_INT16(pRaw, dataPos, &pSchema->colId, _OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, _OVER)
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
230 231
  }

S
Shengliang Guan 已提交
232 233 234 235 236 237
  for (int32_t i = 0; i < pStb->numOfFuncs; ++i) {
    char funcName[TSDB_FUNC_NAME_LEN] = {0};
    SDB_GET_BINARY(pRaw, dataPos, funcName, TSDB_FUNC_NAME_LEN, _OVER)
    taosArrayPush(pStb->pFuncs, funcName);
  }

S
sma  
Shengliang Guan 已提交
238
  if (pStb->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
239
    pStb->comment = taosMemoryCalloc(pStb->commentLen + 1, 1);
240
    if (pStb->comment == NULL) goto _OVER;
wmmhello's avatar
wmmhello 已提交
241
    SDB_GET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
S
sma  
Shengliang Guan 已提交
242
  }
S
Shengliang Guan 已提交
243

244 245 246 247 248
  if (pStb->ast1Len > 0) {
    pStb->pAst1 = taosMemoryCalloc(pStb->ast1Len, 1);
    if (pStb->pAst1 == NULL) goto _OVER;
    SDB_GET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
  }
S
Shengliang Guan 已提交
249

250 251 252 253 254
  if (pStb->ast2Len > 0) {
    pStb->pAst2 = taosMemoryCalloc(pStb->ast2Len, 1);
    if (pStb->pAst2 == NULL) goto _OVER;
    SDB_GET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
  }
S
Shengliang Guan 已提交
255
  SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
256 257 258

  terrno = 0;

259
_OVER:
260
  if (terrno != 0) {
261 262 263 264 265 266
    mError("stb:%s, failed to decode from raw:%p since %s", pStb == NULL ? "null" : pStb->name, pRaw, terrstr());
    if (pStb != NULL) {
      taosMemoryFreeClear(pStb->pColumns);
      taosMemoryFreeClear(pStb->pTags);
      taosMemoryFreeClear(pStb->comment);
    }
wafwerar's avatar
wafwerar 已提交
267
    taosMemoryFreeClear(pRow);
268 269
    return NULL;
  }
S
Shengliang Guan 已提交
270

271
  mTrace("stb:%s, decode from raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
272 273 274
  return pRow;
}

L
Liu Jicong 已提交
275 276 277 278 279 280 281 282 283
void mndFreeStb(SStbObj *pStb) {
  taosArrayDestroy(pStb->pFuncs);
  taosMemoryFreeClear(pStb->pColumns);
  taosMemoryFreeClear(pStb->pTags);
  taosMemoryFreeClear(pStb->comment);
  taosMemoryFreeClear(pStb->pAst1);
  taosMemoryFreeClear(pStb->pAst2);
}

S
Shengliang Guan 已提交
284
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
285
  mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
S
Shengliang Guan 已提交
286 287 288
  return 0;
}

S
Shengliang Guan 已提交
289
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
290
  mTrace("stb:%s, perform delete action, row:%p", pStb->name, pStb);
L
Liu Jicong 已提交
291
  mndFreeStb(pStb);
S
Shengliang Guan 已提交
292 293 294
  return 0;
}

S
Shengliang Guan 已提交
295 296
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
  mTrace("stb:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew);
S
Shengliang Guan 已提交
297

S
Shengliang Guan 已提交
298
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
299 300

  if (pOld->numOfColumns < pNew->numOfColumns) {
wafwerar's avatar
wafwerar 已提交
301
    void *pColumns = taosMemoryMalloc(pNew->numOfColumns * sizeof(SSchema));
S
Shengliang Guan 已提交
302
    if (pColumns != NULL) {
wafwerar's avatar
wafwerar 已提交
303
      taosMemoryFree(pOld->pColumns);
S
Shengliang Guan 已提交
304
      pOld->pColumns = pColumns;
S
Shengliang Guan 已提交
305 306 307 308 309 310 311 312
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

  if (pOld->numOfTags < pNew->numOfTags) {
wafwerar's avatar
wafwerar 已提交
313
    void *pTags = taosMemoryMalloc(pNew->numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
314
    if (pTags != NULL) {
wafwerar's avatar
wafwerar 已提交
315
      taosMemoryFree(pOld->pTags);
S
Shengliang Guan 已提交
316
      pOld->pTags = pTags;
S
Shengliang Guan 已提交
317 318 319 320
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
321
    }
S
Shengliang Guan 已提交
322 323
  }

324
  if (pOld->commentLen < pNew->commentLen && pNew->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
325
    void *comment = taosMemoryMalloc(pNew->commentLen + 1);
S
Shengliang Guan 已提交
326
    if (comment != NULL) {
wafwerar's avatar
wafwerar 已提交
327
      taosMemoryFree(pOld->comment);
S
Shengliang Guan 已提交
328 329 330 331 332 333 334
      pOld->comment = comment;
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }
S
Shengliang Guan 已提交
335
  pOld->commentLen = pNew->commentLen;
S
Shengliang Guan 已提交
336

337
  if (pOld->ast1Len < pNew->ast1Len) {
S
Shengliang Guan 已提交
338
    void *pAst1 = taosMemoryMalloc(pNew->ast1Len + 1);
339 340 341 342 343 344 345 346 347 348 349
    if (pAst1 != NULL) {
      taosMemoryFree(pOld->pAst1);
      pOld->pAst1 = pAst1;
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

  if (pOld->ast2Len < pNew->ast2Len) {
S
Shengliang Guan 已提交
350
    void *pAst2 = taosMemoryMalloc(pNew->ast2Len + 1);
351 352 353 354 355 356 357 358 359 360
    if (pAst2 != NULL) {
      taosMemoryFree(pOld->pAst2);
      pOld->pAst2 = pAst2;
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

S
Shengliang Guan 已提交
361
  pOld->updateTime = pNew->updateTime;
362 363
  pOld->tagVer = pNew->tagVer;
  pOld->colVer = pNew->colVer;
364
  pOld->smaVer = pNew->smaVer;
365
  pOld->nextColId = pNew->nextColId;
S
Shengliang 已提交
366
  pOld->ttl = pNew->ttl;
367 368 369 370 371 372 373 374
  if (pNew->numOfColumns > 0) {
    pOld->numOfColumns = pNew->numOfColumns;
    memcpy(pOld->pColumns, pNew->pColumns, pOld->numOfColumns * sizeof(SSchema));
  }
  if (pNew->numOfTags > 0) {
    pOld->numOfTags = pNew->numOfTags;
    memcpy(pOld->pTags, pNew->pTags, pOld->numOfTags * sizeof(SSchema));
  }
375
  if (pNew->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
376
    memcpy(pOld->comment, pNew->comment, pNew->commentLen + 1);
S
Shengliang Guan 已提交
377
    pOld->commentLen = pNew->commentLen;
S
Shengliang Guan 已提交
378
  }
379 380
  if (pNew->ast1Len != 0) {
    memcpy(pOld->pAst1, pNew->pAst1, pNew->ast1Len);
S
Shengliang Guan 已提交
381
    pOld->ast1Len = pNew->ast1Len;
382 383 384
  }
  if (pNew->ast2Len != 0) {
    memcpy(pOld->pAst2, pNew->pAst2, pNew->ast2Len);
S
Shengliang Guan 已提交
385
    pOld->ast2Len = pNew->ast2Len;
386
  }
S
Shengliang Guan 已提交
387
  taosWUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
388 389 390
  return 0;
}

S
Shengliang Guan 已提交
391
SStbObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
392
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
393
  SStbObj *pStb = sdbAcquire(pSdb, SDB_STB, stbName);
S
Shengliang Guan 已提交
394
  if (pStb == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
S
Shengliang Guan 已提交
395 396 397
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
  }
  return pStb;
S
Shengliang Guan 已提交
398 399
}

S
Shengliang Guan 已提交
400
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
S
Shengliang Guan 已提交
401 402 403 404
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pStb);
}

405
SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
S
Shengliang Guan 已提交
406 407
  SName name = {0};
  tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
S
Shengliang Guan 已提交
408

S
Shengliang Guan 已提交
409 410
  char db[TSDB_TABLE_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, db);
S
Shengliang Guan 已提交
411

S
Shengliang Guan 已提交
412 413
  return mndAcquireDb(pMnode, db);
}
S
Shengliang Guan 已提交
414

415
static FORCE_INLINE int32_t schemaExColIdCompare(const void *colId, const void *pSchema) {
H
Hongze Cheng 已提交
416
  if (*(col_id_t *)colId < ((SSchema *)pSchema)->colId) {
C
Cary Xu 已提交
417
    return -1;
H
Hongze Cheng 已提交
418
  } else if (*(col_id_t *)colId > ((SSchema *)pSchema)->colId) {
C
Cary Xu 已提交
419 420 421 422 423
    return 1;
  }
  return 0;
}

424 425
static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen,
                                   void *alterOriData, int32_t alterOriDataLen) {
H
Hongze Cheng 已提交
426
  SEncoder       encoder = {0};
H
Hongze Cheng 已提交
427 428 429
  int32_t        contLen;
  SName          name = {0};
  SVCreateStbReq req = {0};
H
Hongze Cheng 已提交
430

S
Shengliang Guan 已提交
431
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
X
Xiaoyu Wang 已提交
432 433
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, dbFName);
434

S
Shengliang Guan 已提交
435
  req.name = (char *)tNameGetTableName(&name);
H
Hongze Cheng 已提交
436
  req.suid = pStb->uid;
437
  req.rollup = pStb->ast1Len > 0 ? 1 : 0;
wmmhello's avatar
wmmhello 已提交
438 439
  req.alterOriData = alterOriData;
  req.alterOriDataLen = alterOriDataLen;
440 441
  // todo
  req.schemaRow.nCols = pStb->numOfColumns;
442
  req.schemaRow.version = pStb->colVer;
443
  req.schemaRow.pSchema = pStb->pColumns;
H
Hongze Cheng 已提交
444
  req.schemaTag.nCols = pStb->numOfTags;
445
  req.schemaTag.version = pStb->tagVer;
H
Hongze Cheng 已提交
446
  req.schemaTag.pSchema = pStb->pTags;
H
more  
Hongze Cheng 已提交
447

C
Cary Xu 已提交
448
  if (req.rollup) {
C
Cary Xu 已提交
449 450
    req.rsmaParam.maxdelay[0] = pStb->maxdelay[0];
    req.rsmaParam.maxdelay[1] = pStb->maxdelay[1];
C
Cary Xu 已提交
451 452
    req.rsmaParam.watermark[0] = pStb->watermark[0];
    req.rsmaParam.watermark[1] = pStb->watermark[1];
C
Cary Xu 已提交
453
    if (pStb->ast1Len > 0) {
C
Cary Xu 已提交
454
      if (mndConvertRsmaTask(&req.rsmaParam.qmsg[0], &req.rsmaParam.qmsgLen[0], pStb->pAst1, pStb->uid,
455 456
                             STREAM_TRIGGER_WINDOW_CLOSE, req.rsmaParam.watermark[0],
                             req.rsmaParam.deleteMark[0]) < 0) {
457
        goto _err;
C
Cary Xu 已提交
458
      }
C
Cary Xu 已提交
459 460
    }
    if (pStb->ast2Len > 0) {
C
Cary Xu 已提交
461
      if (mndConvertRsmaTask(&req.rsmaParam.qmsg[1], &req.rsmaParam.qmsgLen[1], pStb->pAst2, pStb->uid,
462 463
                             STREAM_TRIGGER_WINDOW_CLOSE, req.rsmaParam.watermark[1],
                             req.rsmaParam.deleteMark[1]) < 0) {
464
        goto _err;
C
Cary Xu 已提交
465
      }
C
Cary Xu 已提交
466
    }
H
Hongze Cheng 已提交
467
  }
H
Hongze Cheng 已提交
468
  // get length
wafwerar's avatar
wafwerar 已提交
469 470 471
  int32_t ret = 0;
  tEncodeSize(tEncodeSVCreateStbReq, &req, contLen, ret);
  if (ret < 0) {
472
    goto _err;
H
Hongze Cheng 已提交
473 474
  }

H
Hongze Cheng 已提交
475
  contLen += sizeof(SMsgHead);
C
Cary Xu 已提交
476

D
dapan1121 已提交
477
  SMsgHead *pHead = taosMemoryCalloc(1, contLen);
S
Shengliang Guan 已提交
478
  if (pHead == NULL) {
H
more  
Hongze Cheng 已提交
479
    terrno = TSDB_CODE_OUT_OF_MEMORY;
480
    goto _err;
H
more  
Hongze Cheng 已提交
481 482
  }

S
Shengliang Guan 已提交
483 484
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);
H
more  
Hongze Cheng 已提交
485

S
Shengliang Guan 已提交
486
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
H
Hongze Cheng 已提交
487 488
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  if (tEncodeSVCreateStbReq(&encoder, &req) < 0) {
489 490
    taosMemoryFreeClear(pHead);
    tEncoderClear(&encoder);
491
    goto _err;
H
Hongze Cheng 已提交
492
  }
H
Hongze Cheng 已提交
493
  tEncoderClear(&encoder);
H
more  
Hongze Cheng 已提交
494

S
Shengliang Guan 已提交
495
  *pContLen = contLen;
C
Cary Xu 已提交
496 497
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
S
Shengliang Guan 已提交
498
  return pHead;
499
_err:
C
Cary Xu 已提交
500 501
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
502
  return NULL;
503 504
}

S
Shengliang Guan 已提交
505
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
H
Hongze Cheng 已提交
506 507 508 509 510
  SName        name = {0};
  SVDropStbReq req = {0};
  int32_t      contLen = 0;
  int32_t      ret = 0;
  SMsgHead    *pHead = NULL;
H
Hongze Cheng 已提交
511
  SEncoder     encoder = {0};
H
Hongze Cheng 已提交
512

S
Shengliang Guan 已提交
513 514 515 516
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

  req.name = (char *)tNameGetTableName(&name);
  req.suid = pStb->uid;
517

H
Hongze Cheng 已提交
518 519 520 521 522
  tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
  if (ret < 0) return NULL;

  contLen += sizeof(SMsgHead);
  pHead = taosMemoryMalloc(contLen);
S
Shengliang Guan 已提交
523
  if (pHead == NULL) {
524 525 526 527
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
528 529 530 531
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);

  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
H
Hongze Cheng 已提交
532

H
Hongze Cheng 已提交
533 534 535
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  tEncodeSVDropStbReq(&encoder, &req);
  tEncoderClear(&encoder);
536

S
Shengliang Guan 已提交
537 538
  *pContLen = contLen;
  return pHead;
539 540
}

541
int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
S
Shengliang Guan 已提交
542
  if (pCreate->igExists < 0 || pCreate->igExists > 1) {
S
Shengliang Guan 已提交
543
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
544 545
    return -1;
  }
S
Shengliang Guan 已提交
546

547
  if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfTags + pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
5
54liuyao 已提交
548
    terrno = TSDB_CODE_PAR_INVALID_COLUMNS_NUM;
S
Shengliang Guan 已提交
549 550
    return -1;
  }
S
Shengliang Guan 已提交
551

S
Shengliang Guan 已提交
552
  if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
S
Shengliang Guan 已提交
553
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
554 555
    return -1;
  }
S
Shengliang Guan 已提交
556

S
Shengliang Guan 已提交
557
  SField *pField = taosArrayGet(pCreate->pColumns, 0);
S
Shengliang Guan 已提交
558
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
5
54liuyao 已提交
559
    terrno = TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
S
Shengliang Guan 已提交
560 561 562
    return -1;
  }

S
Shengliang Guan 已提交
563
  for (int32_t i = 0; i < pCreate->numOfColumns; ++i) {
564
    SField *pField1 = taosArrayGet(pCreate->pColumns, i);
S
Shengliang Guan 已提交
565
    if (pField1->type >= TSDB_DATA_TYPE_MAX) {
S
Shengliang Guan 已提交
566 567 568
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
569
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
570 571 572
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
573
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
574 575 576 577 578 579
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
  }

  for (int32_t i = 0; i < pCreate->numOfTags; ++i) {
580
    SField *pField1 = taosArrayGet(pCreate->pTags, i);
S
Shengliang Guan 已提交
581
    if (pField1->type >= TSDB_DATA_TYPE_MAX) {
S
Shengliang Guan 已提交
582
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
583 584
      return -1;
    }
585
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
586
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
587 588
      return -1;
    }
589
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
590
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
591 592 593
      return -1;
    }
  }
S
Shengliang Guan 已提交
594

S
Shengliang Guan 已提交
595 596 597
  return 0;
}

598
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
599 600
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
601 602 603 604
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
605 606 607 608 609
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1;

  return 0;
}

610
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
611 612
  SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
  if (pUndoRaw == NULL) return -1;
S
Shengliang Guan 已提交
613 614 615 616
  if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) {
    sdbFreeRaw(pUndoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
617 618 619 620 621
  if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

622
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
623 624
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
625 626 627 628
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
629 630 631 632 633
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

634
static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
635
  SSdb   *pSdb = pMnode->pSdb;
636
  SVgObj *pVgroup = NULL;
637
  void   *pIter = NULL;
S
Shengliang Guan 已提交
638
  int32_t contLen;
639 640 641 642

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
643
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
644 645 646 647
      sdbRelease(pSdb, pVgroup);
      continue;
    }

wmmhello's avatar
wmmhello 已提交
648
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, NULL, 0);
S
Shengliang Guan 已提交
649
    if (pReq == NULL) {
650 651 652 653
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
S
Shengliang Guan 已提交
654

655 656
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
657
    action.pCont = pReq;
S
Shengliang Guan 已提交
658
    action.contLen = contLen;
H
Hongze Cheng 已提交
659
    action.msgType = TDMT_VND_CREATE_STB;
S
Shengliang Guan 已提交
660
    action.acceptableCode = TSDB_CODE_TDB_STB_ALREADY_EXIST;
661
    action.retryCode = TSDB_CODE_TDB_STB_NOT_EXIST;
662
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
663
      taosMemoryFree(pReq);
664 665 666 667 668 669
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
670 671 672 673

  return 0;
}

674
static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
675
  SSdb   *pSdb = pMnode->pSdb;
676
  SVgObj *pVgroup = NULL;
677
  void   *pIter = NULL;
678 679 680 681

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
682
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
683 684 685 686
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
687
    int32_t contLen = 0;
S
Shengliang Guan 已提交
688
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
689
    if (pReq == NULL) {
690 691 692 693 694
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
695

696 697
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
698
    action.pCont = pReq;
S
Shengliang Guan 已提交
699
    action.contLen = contLen;
H
Hongze Cheng 已提交
700
    action.msgType = TDMT_VND_DROP_STB;
S
Shengliang Guan 已提交
701
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
702
    if (mndTransAppendUndoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
703
      taosMemoryFree(pReq);
704 705 706 707 708 709
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
710 711 712 713

  return 0;
}

S
sma  
Shengliang Guan 已提交
714
static SSchema *mndFindStbColumns(const SStbObj *pStb, const char *colName) {
C
Cary Xu 已提交
715
  for (int32_t col = 0; col < pStb->numOfColumns; ++col) {
S
sma  
Shengliang Guan 已提交
716
    SSchema *pSchema = &pStb->pColumns[col];
C
Cary Xu 已提交
717
    if (strncasecmp(pSchema->name, colName, TSDB_COL_NAME_LEN) == 0) {
S
sma  
Shengliang Guan 已提交
718 719 720 721 722 723
      return pSchema;
    }
  }
  return NULL;
}

724 725 726 727 728
int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreate, SDbObj *pDb) {
  memcpy(pDst->name, pCreate->name, TSDB_TABLE_FNAME_LEN);
  memcpy(pDst->db, pDb->name, TSDB_DB_FNAME_LEN);
  pDst->createdTime = taosGetTimestampMs();
  pDst->updateTime = pDst->createdTime;
729 730
  pDst->uid =
      (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->suid : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
731
  pDst->dbUid = pDb->uid;
732 733
  pDst->tagVer = 1;
  pDst->colVer = 1;
S
Shengliang Guan 已提交
734
  pDst->smaVer = 1;
735
  pDst->nextColId = 1;
736 737 738 739
  pDst->maxdelay[0] = pCreate->delay1;
  pDst->maxdelay[1] = pCreate->delay2;
  pDst->watermark[0] = pCreate->watermark1;
  pDst->watermark[1] = pCreate->watermark2;
740 741 742
  pDst->ttl = pCreate->ttl;
  pDst->numOfColumns = pCreate->numOfColumns;
  pDst->numOfTags = pCreate->numOfTags;
S
Shengliang Guan 已提交
743
  pDst->numOfFuncs = pCreate->numOfFuncs;
744
  pDst->commentLen = pCreate->commentLen;
D
dapan1121 已提交
745 746
  pDst->pFuncs = pCreate->pFuncs;
  pCreate->pFuncs = NULL;
747

748
  if (pDst->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
749
    pDst->comment = taosMemoryCalloc(pDst->commentLen + 1, 1);
750
    if (pDst->comment == NULL) {
S
sma  
Shengliang Guan 已提交
751 752 753
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
754
    memcpy(pDst->comment, pCreate->pComment, pDst->commentLen + 1);
S
sma  
Shengliang Guan 已提交
755
  }
S
Shengliang Guan 已提交
756

757 758 759 760
  pDst->ast1Len = pCreate->ast1Len;
  if (pDst->ast1Len > 0) {
    pDst->pAst1 = taosMemoryCalloc(pDst->ast1Len, 1);
    if (pDst->pAst1 == NULL) {
761 762 763
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
764
    memcpy(pDst->pAst1, pCreate->pAst1, pDst->ast1Len);
765 766
  }

767 768 769 770
  pDst->ast2Len = pCreate->ast2Len;
  if (pDst->ast2Len > 0) {
    pDst->pAst2 = taosMemoryCalloc(pDst->ast2Len, 1);
    if (pDst->pAst2 == NULL) {
771 772 773
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
774
    memcpy(pDst->pAst2, pCreate->pAst2, pDst->ast2Len);
775 776
  }

777 778 779
  pDst->pColumns = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SSchema));
  pDst->pTags = taosMemoryCalloc(1, pDst->numOfTags * sizeof(SSchema));
  if (pDst->pColumns == NULL || pDst->pTags == NULL) {
S
Shengliang Guan 已提交
780 781 782
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
783

784
  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
S
Shengliang Guan 已提交
785
    SField  *pField = taosArrayGet(pCreate->pColumns, i);
786
    SSchema *pSchema = &pDst->pColumns[i];
S
Shengliang Guan 已提交
787 788
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
789
    pSchema->flags = pField->flags;
S
Shengliang Guan 已提交
790
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
791 792
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
793 794
  }

795
  for (int32_t i = 0; i < pDst->numOfTags; ++i) {
S
Shengliang Guan 已提交
796
    SField  *pField = taosArrayGet(pCreate->pTags, i);
797
    SSchema *pSchema = &pDst->pTags[i];
S
Shengliang Guan 已提交
798 799 800
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
801 802
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
803
  }
804 805 806
  return 0;
}

S
Shengliang Guan 已提交
807
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
808
  SStbObj stbObj = {0};
S
Shengliang 已提交
809
  int32_t code = -1;
810

811
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq, "create-stb");
812
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
813

814
  mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
815
  if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
816
  if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
817
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
818 819
  code = 0;

820
_OVER:
S
Shengliang Guan 已提交
821
  mndTransDrop(pTrans);
822
  mndStbActionDelete(pMnode->pSdb, &stbObj);
S
Shengliang Guan 已提交
823
  return code;
S
Shengliang Guan 已提交
824
}
S
Shengliang Guan 已提交
825

826
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
827
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
828
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) return -1;
829 830 831 832 833 834 835
  if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbUndoActions(pMnode, pTrans, pDb, pStb) != 0) return -1;
  return 0;
}
S
Shengliang Guan 已提交
836

S
Shengliang Guan 已提交
837
static int32_t mndProcessTtlTimer(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
838 839 840 841 842 843 844
  SMnode           *pMnode = pReq->info.node;
  SSdb             *pSdb = pMnode->pSdb;
  SVgObj           *pVgroup = NULL;
  void             *pIter = NULL;
  SVDropTtlTableReq ttlReq = {.timestamp = taosGetTimestampSec()};
  int32_t           reqLen = tSerializeSVDropTtlTableReq(NULL, 0, &ttlReq);
  int32_t           contLen = reqLen + sizeof(SMsgHead);
wmmhello's avatar
wmmhello 已提交
845

846 847
  mInfo("start to process ttl timer");

wmmhello's avatar
wmmhello 已提交
848 849 850 851
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
852
    SMsgHead *pHead = rpcMallocCont(contLen);
wmmhello's avatar
wmmhello 已提交
853
    if (pHead == NULL) {
S
Shengliang Guan 已提交
854
      sdbCancelFetch(pSdb, pVgroup);
wmmhello's avatar
wmmhello 已提交
855 856 857 858 859
      sdbRelease(pSdb, pVgroup);
      continue;
    }
    pHead->contLen = htonl(contLen);
    pHead->vgId = htonl(pVgroup->vgId);
S
Shengliang Guan 已提交
860
    tSerializeSVDropTtlTableReq((char *)pHead + sizeof(SMsgHead), contLen, &ttlReq);
wmmhello's avatar
wmmhello 已提交
861 862

    SRpcMsg rpcMsg = {.msgType = TDMT_VND_DROP_TTL_TABLE, .pCont = pHead, .contLen = contLen};
S
Shengliang Guan 已提交
863
    SEpSet  epSet = mndGetVgroupEpset(pMnode, pVgroup);
wmmhello's avatar
wmmhello 已提交
864
    int32_t code = tmsgSendReq(&epSet, &rpcMsg);
S
Shengliang Guan 已提交
865
    if (code != 0) {
S
Shengliang Guan 已提交
866
      mError("vgId:%d, failed to send drop ttl table request to vnode since 0x%x", pVgroup->vgId, code);
S
Shengliang Guan 已提交
867
    } else {
868
      mInfo("vgId:%d, send drop ttl table request to vnode, time:%d", pVgroup->vgId, ttlReq.timestamp);
wmmhello's avatar
wmmhello 已提交
869 870 871
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
872

wmmhello's avatar
wmmhello 已提交
873 874 875
  return 0;
}

wmmhello's avatar
wmmhello 已提交
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
static int32_t mndFindSuperTableTagIndex(const SStbObj *pStb, const char *tagName) {
  for (int32_t tag = 0; tag < pStb->numOfTags; tag++) {
    if (strcasecmp(pStb->pTags[tag].name, tagName) == 0) {
      return tag;
    }
  }

  return -1;
}

static int32_t mndFindSuperTableColumnIndex(const SStbObj *pStb, const char *colName) {
  for (int32_t col = 0; col < pStb->numOfColumns; col++) {
    if (strcasecmp(pStb->pColumns[col].name, colName) == 0) {
      return col;
    }
  }

  return -1;
}

static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq *createReq) {
  taosRLockLatch(&pStb->lock);
  memcpy(pDst, pStb, sizeof(SStbObj));
  taosRUnLockLatch(&pStb->lock);

  pDst->updateTime = taosGetTimestampMs();
  pDst->numOfColumns = createReq->numOfColumns;
  pDst->numOfTags = createReq->numOfTags;
  pDst->pColumns = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SSchema));
  pDst->pTags = taosMemoryCalloc(1, pDst->numOfTags * sizeof(SSchema));
  if (pDst->pColumns == NULL || pDst->pTags == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
    SField  *pField = taosArrayGet(createReq->pColumns, i);
    SSchema *pSchema = &pDst->pColumns[i];
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    pSchema->flags = pField->flags;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
    int32_t cIndex = mndFindSuperTableColumnIndex(pStb, pField->name);
919
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
920
      pSchema->colId = pStb->pColumns[cIndex].colId;
921
    } else {
wmmhello's avatar
wmmhello 已提交
922 923 924 925 926 927 928 929 930 931 932
      pSchema->colId = pDst->nextColId++;
    }
  }

  for (int32_t i = 0; i < pDst->numOfTags; ++i) {
    SField  *pField = taosArrayGet(createReq->pTags, i);
    SSchema *pSchema = &pDst->pTags[i];
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
    int32_t cIndex = mndFindSuperTableTagIndex(pStb, pField->name);
933
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
934
      pSchema->colId = pStb->pTags[cIndex].colId;
935
    } else {
wmmhello's avatar
wmmhello 已提交
936 937 938 939 940 941 942 943
      pSchema->colId = pDst->nextColId++;
    }
  }
  pDst->tagVer = createReq->tagVer;
  pDst->colVer = createReq->colVer;
  return TSDB_CODE_SUCCESS;
}

944
static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
945
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
946 947 948 949
  int32_t        code = -1;
  SStbObj       *pStb = NULL;
  SDbObj        *pDb = NULL;
  SMCreateStbReq createReq = {0};
950
  bool           isAlter = false;
S
Shengliang Guan 已提交
951

S
Shengliang Guan 已提交
952
  if (tDeserializeSMCreateStbReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
953
    terrno = TSDB_CODE_INVALID_MSG;
954
    goto _OVER;
S
Shengliang Guan 已提交
955
  }
S
Shengliang Guan 已提交
956

957
  mInfo("stb:%s, start to create", createReq.name);
S
Shengliang Guan 已提交
958 959
  if (mndCheckCreateStbReq(&createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
960
    goto _OVER;
S
Shengliang Guan 已提交
961
  }
S
Shengliang Guan 已提交
962

S
Shengliang Guan 已提交
963
  pStb = mndAcquireStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
964
  if (pStb != NULL) {
S
Shengliang Guan 已提交
965
    if (createReq.igExists) {
966
      if (createReq.source == TD_REQ_FROM_APP) {
967
        mInfo("stb:%s, already exist, ignore exist is set", createReq.name);
968 969 970 971 972 973 974 975
        code = 0;
        goto _OVER;
      } else if (pStb->uid != createReq.suid) {
        mError("stb:%s, already exist while create, input suid:%" PRId64 " not match with exist suid:%" PRId64,
               createReq.name, createReq.suid, pStb->uid);
        terrno = TSDB_CODE_MND_STABLE_UID_NOT_MATCH;
        goto _OVER;
      } else if (createReq.tagVer > 0 || createReq.colVer > 0) {
wmmhello's avatar
wmmhello 已提交
976 977 978
        int32_t tagDelta = createReq.tagVer - pStb->tagVer;
        int32_t colDelta = createReq.colVer - pStb->colVer;
        int32_t verDelta = tagDelta + colDelta;
979 980 981 982 983 984 985
        mInfo("stb:%s, already exist while create, input tagVer:%d colVer:%d, exist tagVer:%d colVer:%d",
              createReq.name, createReq.tagVer, createReq.colVer, pStb->tagVer, pStb->colVer);
        if (tagDelta <= 0 && colDelta <= 0) {
          mInfo("stb:%s, schema version is not incremented and nothing needs to be done", createReq.name);
          code = 0;
          goto _OVER;
        } else if ((tagDelta == 1 || colDelta == 1) && (verDelta == 1)) {
986
          isAlter = true;
987 988 989 990 991 992 993
          mInfo("stb:%s, schema version is only increased by 1 number, do alter operation", createReq.name);
        } else {
          mError("stb:%s, schema version increase more than 1 number, error is returned", createReq.name);
          terrno = TSDB_CODE_MND_INVALID_SCHEMA_VER;
          goto _OVER;
        }
      } else {
S
Shengliang Guan 已提交
994 995
        mError("stb:%s, already exist while create, input tagVer:%d colVer:%d is invalid, origin tagVer:%d colVer:%d",
               createReq.name, createReq.tagVer, createReq.colVer, pStb->tagVer, pStb->colVer);
996 997 998
        terrno = TSDB_CODE_MND_INVALID_SCHEMA_VER;
        goto _OVER;
      }
S
Shengliang Guan 已提交
999 1000
    } else {
      terrno = TSDB_CODE_MND_STB_ALREADY_EXIST;
1001
      goto _OVER;
S
Shengliang Guan 已提交
1002
    }
S
Shengliang Guan 已提交
1003
  } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) {
1004
    goto _OVER;
1005
  } else if (createReq.source == TD_REQ_FROM_TAOX && (createReq.tagVer != 1 || createReq.colVer != 1)) {
1006 1007 1008
    mInfo("stb:%s, alter table does not need to be done, because table is deleted", createReq.name);
    code = 0;
    goto _OVER;
S
Shengliang Guan 已提交
1009 1010
  }

S
Shengliang Guan 已提交
1011
  pDb = mndAcquireDbByStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
1012 1013
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
1014
    goto _OVER;
S
Shengliang Guan 已提交
1015 1016
  }

1017
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1018
    goto _OVER;
S
Shengliang Guan 已提交
1019 1020
  }

1021
  int32_t numOfStbs = -1;
S
Shengliang Guan 已提交
1022 1023 1024 1025
  if (mndGetNumOfStbs(pMnode, pDb->name, &numOfStbs) != 0) {
    goto _OVER;
  }

L
Liu Jicong 已提交
1026
  if (pDb->cfg.numOfStables == 1 && numOfStbs != 0) {
1027 1028 1029 1030
    terrno = TSDB_CODE_MND_SINGLE_STB_MODE_DB;
    goto _OVER;
  }

wafwerar's avatar
wafwerar 已提交
1031 1032 1033 1034 1035
  if ((terrno = grantCheck(TSDB_GRANT_STABLE)) < 0) {
    code = -1;
    goto _OVER;
  }

1036
  if (isAlter) {
1037
    bool    needRsp = false;
wmmhello's avatar
wmmhello 已提交
1038
    SStbObj pDst = {0};
wmmhello's avatar
wmmhello 已提交
1039 1040 1041
    if (mndBuildStbFromAlter(pStb, &pDst, &createReq) != 0) {
      taosMemoryFreeClear(pDst.pTags);
      taosMemoryFreeClear(pDst.pColumns);
wmmhello's avatar
wmmhello 已提交
1042 1043 1044 1045 1046 1047
      goto _OVER;
    }

    code = mndAlterStbImp(pMnode, pReq, pDb, &pDst, needRsp, NULL, 0);
    taosMemoryFreeClear(pDst.pTags);
    taosMemoryFreeClear(pDst.pColumns);
1048 1049 1050
  } else {
    code = mndCreateStb(pMnode, pReq, &createReq, pDb);
  }
S
Shengliang Guan 已提交
1051
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1052

1053
_OVER:
S
Shengliang Guan 已提交
1054
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1055
    mError("stb:%s, failed to create since %s", createReq.name, terrstr());
S
Shengliang Guan 已提交
1056 1057
  }

S
Shengliang Guan 已提交
1058 1059
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1060
  tFreeSMCreateStbReq(&createReq);
S
Shengliang Guan 已提交
1061 1062

  return code;
S
Shengliang Guan 已提交
1063 1064
}

S
Shengliang Guan 已提交
1065
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
S
Shengliang Guan 已提交
1066 1067
  if (pAlter->commentLen >= 0) return 0;
  if (pAlter->ttl != 0) return 0;
S
Shengliang 已提交
1068

S
Shengliang Guan 已提交
1069 1070 1071 1072
  if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }
S
Shengliang Guan 已提交
1073

S
Shengliang Guan 已提交
1074 1075 1076
  for (int32_t i = 0; i < pAlter->numOfFields; ++i) {
    SField *pField = taosArrayGet(pAlter->pFields, i);
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
1077 1078 1079
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
1080 1081 1082 1083 1084
  }

  return 0;
}

S
Shengliang Guan 已提交
1085
static int32_t mndAllocStbSchemas(const SStbObj *pOld, SStbObj *pNew) {
wafwerar's avatar
wafwerar 已提交
1086 1087
  pNew->pTags = taosMemoryCalloc(pNew->numOfTags, sizeof(SSchema));
  pNew->pColumns = taosMemoryCalloc(pNew->numOfColumns, sizeof(SSchema));
S
Shengliang Guan 已提交
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
  if (pNew->pTags == NULL || pNew->pColumns == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  memcpy(pNew->pColumns, pOld->pColumns, sizeof(SSchema) * pOld->numOfColumns);
  memcpy(pNew->pTags, pOld->pTags, sizeof(SSchema) * pOld->numOfTags);
  return 0;
}

S
Shengliang 已提交
1098 1099
static int32_t mndUpdateStbCommentAndTTL(const SStbObj *pOld, SStbObj *pNew, char *pComment, int32_t commentLen,
                                         int32_t ttl) {
S
Shengliang 已提交
1100 1101
  if (commentLen > 0) {
    pNew->commentLen = commentLen;
wmmhello's avatar
wmmhello 已提交
1102
    pNew->comment = taosMemoryCalloc(1, commentLen + 1);
S
Shengliang 已提交
1103 1104 1105 1106
    if (pNew->comment == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
wmmhello's avatar
wmmhello 已提交
1107
    memcpy(pNew->comment, pComment, commentLen + 1);
1108
  } else if (commentLen == 0) {
wmmhello's avatar
wmmhello 已提交
1109
    pNew->commentLen = 0;
S
Shengliang Guan 已提交
1110
  } else {
S
Shengliang 已提交
1111
  }
wmmhello's avatar
wmmhello 已提交
1112

S
Shengliang 已提交
1113 1114 1115
  if (ttl >= 0) {
    pNew->ttl = ttl;
  }
S
Shengliang 已提交
1116 1117 1118 1119 1120 1121 1122

  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }
  return 0;
}

S
Shengliang Guan 已提交
1123
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
  if (pOld->numOfTags + ntags > TSDB_MAX_TAGS) {
    terrno = TSDB_CODE_MND_TOO_MANY_TAGS;
    return -1;
  }

  if (pOld->numOfColumns + ntags + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
1134 1135 1136 1137 1138
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1139
  for (int32_t i = 0; i < ntags; i++) {
S
Shengliang Guan 已提交
1140
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1141
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1142
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1143 1144 1145
      return -1;
    }

S
Shengliang 已提交
1146
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1147
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1148 1149 1150
      return -1;
    }

S
Shengliang Guan 已提交
1151 1152 1153 1154
    SSchema *pSchema = &pNew->pTags[pOld->numOfTags + i];
    pSchema->bytes = pField->bytes;
    pSchema->type = pField->type;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
S
Shengliang Guan 已提交
1155 1156
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1157

1158
    mInfo("stb:%s, start to add tag %s", pNew->name, pSchema->name);
S
Shengliang Guan 已提交
1159 1160
  }

1161
  pNew->tagVer++;
S
Shengliang Guan 已提交
1162 1163 1164
  return 0;
}

1165
static int32_t mndCheckAlterColForTopic(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
1166 1167 1168 1169 1170 1171 1172
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SMqTopicObj *pTopic = NULL;
    pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
    if (pIter == NULL) break;

1173
    mInfo("topic:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, subType:%d sql:%s",
H
Hongze Cheng 已提交
1174
          pTopic->name, stbFullName, suid, colId, pTopic->subType, pTopic->sql);
1175 1176 1177 1178 1179 1180 1181
    if (pTopic->subType != TOPIC_SUB_TYPE__COLUMN) {
      sdbRelease(pSdb, pTopic);
      continue;
    }

    SNode *pAst = NULL;
    if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
S
Shengliang Guan 已提交
1182 1183 1184
      terrno = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TOPIC;
      mError("topic:%s, create ast error", pTopic->name);
      sdbRelease(pSdb, pTopic);
1185 1186 1187 1188 1189 1190 1191 1192
      return -1;
    }

    SNodeList *pNodeList = NULL;
    nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList);
    SNode *pNode = NULL;
    FOREACH(pNode, pNodeList) {
      SColumnNode *pCol = (SColumnNode *)pNode;
H
Hongze Cheng 已提交
1193 1194
      mInfo("topic:%s, check colId:%d tableId:%" PRId64 " ctbStbUid:%" PRId64, pTopic->name, pCol->colId, pCol->tableId,
            pTopic->ctbStbUid);
1195 1196

      if (pCol->tableId != suid && pTopic->ctbStbUid != suid) {
1197
        mInfo("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
1198 1199 1200 1201 1202
        goto NEXT;
      }
      if (pCol->colId > 0 && pCol->colId == colId) {
        terrno = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TOPIC;
        mError("topic:%s, check colId:%d conflicted", pTopic->name, pCol->colId);
L
Liu Jicong 已提交
1203 1204 1205
        nodesDestroyNode(pAst);
        nodesDestroyList(pNodeList);
        sdbRelease(pSdb, pTopic);
1206 1207
        return -1;
      }
1208
      mInfo("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
1209 1210 1211 1212 1213
    }

  NEXT:
    sdbRelease(pSdb, pTopic);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1214
    nodesDestroyList(pNodeList);
1215
  }
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
  return 0;
}

static int32_t mndCheckAlterColForStream(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SStreamObj *pStream = NULL;
    pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
    if (pIter == NULL) break;

    SNode *pAst = NULL;
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
S
Shengliang Guan 已提交
1229 1230 1231
      terrno = TSDB_CODE_MND_INVALID_STREAM_OPTION;
      mError("stream:%s, create ast error", pStream->name);
      sdbRelease(pSdb, pStream);
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
      return -1;
    }

    SNodeList *pNodeList = NULL;
    nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList);
    SNode *pNode = NULL;
    FOREACH(pNode, pNodeList) {
      SColumnNode *pCol = (SColumnNode *)pNode;

      if (pCol->tableId != suid) {
1242
        mInfo("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
1243 1244 1245 1246 1247
        goto NEXT;
      }
      if (pCol->colId > 0 && pCol->colId == colId) {
        terrno = TSDB_CODE_MND_STREAM_MUST_BE_DELETED;
        mError("stream:%s, check colId:%d conflicted", pStream->name, pCol->colId);
L
Liu Jicong 已提交
1248 1249 1250
        nodesDestroyNode(pAst);
        nodesDestroyList(pNodeList);
        sdbRelease(pSdb, pStream);
1251 1252
        return -1;
      }
1253
      mInfo("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
1254 1255 1256 1257 1258
    }

  NEXT:
    sdbRelease(pSdb, pStream);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1259
    nodesDestroyList(pNodeList);
1260 1261 1262
  }
  return 0;
}
1263

1264 1265 1266
static int32_t mndCheckAlterColForTSma(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
1267 1268 1269 1270 1271
  while (1) {
    SSmaObj *pSma = NULL;
    pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
    if (pIter == NULL) break;

H
Hongze Cheng 已提交
1272 1273
    mInfo("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, sql:%s", pSma->name, stbFullName,
          suid, colId, pSma->sql);
1274 1275 1276 1277 1278

    SNode *pAst = NULL;
    if (nodesStringToNode(pSma->ast, &pAst) != 0) {
      terrno = TSDB_CODE_SDB_INVALID_DATA_CONTENT;
      mError("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d failed since parse AST err",
1279
             pSma->name, stbFullName, suid, colId);
1280 1281 1282 1283 1284 1285 1286 1287
      return -1;
    }

    SNodeList *pNodeList = NULL;
    nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList);
    SNode *pNode = NULL;
    FOREACH(pNode, pNodeList) {
      SColumnNode *pCol = (SColumnNode *)pNode;
1288
      mInfo("tsma:%s, check colId:%d tableId:%" PRId64, pSma->name, pCol->colId, pCol->tableId);
1289 1290

      if ((pCol->tableId != suid) && (pSma->stbUid != suid)) {
1291
        mInfo("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
1292
        goto NEXT;
1293 1294 1295 1296
      }
      if ((pCol->colId) > 0 && (pCol->colId == colId)) {
        terrno = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TSMA;
        mError("tsma:%s, check colId:%d conflicted", pSma->name, pCol->colId);
L
Liu Jicong 已提交
1297 1298 1299
        nodesDestroyNode(pAst);
        nodesDestroyList(pNodeList);
        sdbRelease(pSdb, pSma);
1300 1301
        return -1;
      }
1302
      mInfo("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
1303 1304
    }

1305
  NEXT:
1306 1307
    sdbRelease(pSdb, pSma);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1308
    nodesDestroyList(pNodeList);
1309
  }
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319
  return 0;
}

int32_t mndCheckColAndTagModifiable(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
  if (mndCheckAlterColForTopic(pMnode, stbFullName, suid, colId) < 0) {
    return -1;
  }
  if (mndCheckAlterColForStream(pMnode, stbFullName, suid, colId) < 0) {
    return -1;
  }
1320

1321 1322 1323
  if (mndCheckAlterColForTSma(pMnode, stbFullName, suid, colId) < 0) {
    return -1;
  }
1324 1325 1326
  return 0;
}

1327
static int32_t mndDropSuperTableTag(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
S
Shengliang Guan 已提交
1328 1329 1330 1331 1332 1333
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1334
  col_id_t colId = pOld->pTags[tag].colId;
1335
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1336 1337 1338
    return -1;
  }

S
Shengliang Guan 已提交
1339 1340 1341 1342 1343
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  memmove(pNew->pTags + tag, pNew->pTags + tag + 1, sizeof(SSchema) * (pNew->numOfTags - tag - 1));
S
Shengliang Guan 已提交
1344
  pNew->numOfTags--;
S
Shengliang Guan 已提交
1345

1346
  pNew->tagVer++;
1347
  mInfo("stb:%s, start to drop tag %s", pNew->name, tagName);
S
Shengliang Guan 已提交
1348 1349 1350
  return 0;
}

1351
static int32_t mndAlterStbTagName(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
S
Shengliang Guan 已提交
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
  if ((int32_t)taosArrayGetSize(pFields) != 2) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }

  SField *pField0 = taosArrayGet(pFields, 0);
  SField *pField1 = taosArrayGet(pFields, 1);

  const char *oldTagName = pField0->name;
  const char *newTagName = pField1->name;

S
Shengliang Guan 已提交
1363 1364 1365 1366 1367 1368
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1369
  col_id_t colId = pOld->pTags[tag].colId;
1370
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1371 1372 1373
    return -1;
  }

S
Shengliang Guan 已提交
1374
  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
S
Shengliang Guan 已提交
1375
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1376 1377 1378
    return -1;
  }

S
Shengliang Guan 已提交
1379 1380
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390
    return -1;
  }

  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pSchema = (SSchema *)(pNew->pTags + tag);
  memcpy(pSchema->name, newTagName, TSDB_COL_NAME_LEN);

1391
  pNew->tagVer++;
1392
  mInfo("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
S
Shengliang Guan 已提交
1393 1394 1395
  return 0;
}

1396
static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1397
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1398 1399 1400 1401 1402
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1403
  col_id_t colId = pOld->pTags[tag].colId;
1404
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1405 1406 1407
    return -1;
  }

S
Shengliang Guan 已提交
1408 1409 1410 1411 1412 1413
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pTag = pNew->pTags + tag;

S
Shengliang Guan 已提交
1414 1415 1416 1417 1418
  if (!(pTag->type == TSDB_DATA_TYPE_BINARY || pTag->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }

S
Shengliang Guan 已提交
1419
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
1420 1421 1422 1423
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

S
Shengliang Guan 已提交
1424
  pTag->bytes = pField->bytes;
1425
  pNew->tagVer++;
S
Shengliang Guan 已提交
1426

1427
  mInfo("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1428 1429 1430
  return 0;
}

S
Shengliang Guan 已提交
1431
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ncols) {
S
Shengliang Guan 已提交
1432 1433 1434 1435 1436
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
1437 1438 1439 1440 1441
  pNew->numOfColumns = pNew->numOfColumns + ncols;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1442
  for (int32_t i = 0; i < ncols; i++) {
S
Shengliang Guan 已提交
1443
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1444
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1445
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1446 1447 1448
      return -1;
    }

S
Shengliang 已提交
1449
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1450
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1451 1452 1453
      return -1;
    }

S
Shengliang Guan 已提交
1454 1455 1456 1457
    SSchema *pSchema = &pNew->pColumns[pOld->numOfColumns + i];
    pSchema->bytes = pField->bytes;
    pSchema->type = pField->type;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
S
Shengliang Guan 已提交
1458 1459
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1460

1461
    mInfo("stb:%s, start to add column %s", pNew->name, pSchema->name);
S
Shengliang Guan 已提交
1462 1463
  }

1464
  pNew->colVer++;
S
Shengliang Guan 已提交
1465 1466 1467
  return 0;
}

1468
static int32_t mndDropSuperTableColumn(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *colName) {
S
Shengliang Guan 已提交
1469
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
S
Shengliang Guan 已提交
1470
  if (col < 0) {
S
Shengliang Guan 已提交
1471 1472 1473 1474
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484
  if (col == 0) {
    terrno = TSDB_CODE_MND_INVALID_STB_ALTER_OPTION;
    return -1;
  }

  if (pOld->numOfColumns == 2) {
    terrno = TSDB_CODE_MND_INVALID_STB_ALTER_OPTION;
    return -1;
  }

1485
  col_id_t colId = pOld->pColumns[col].colId;
1486
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1487 1488 1489
    return -1;
  }

S
Shengliang Guan 已提交
1490 1491 1492 1493 1494
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  memmove(pNew->pColumns + col, pNew->pColumns + col + 1, sizeof(SSchema) * (pNew->numOfColumns - col - 1));
S
Shengliang Guan 已提交
1495
  pNew->numOfColumns--;
S
Shengliang Guan 已提交
1496

1497
  pNew->colVer++;
1498
  mInfo("stb:%s, start to drop col %s", pNew->name, colName);
S
Shengliang Guan 已提交
1499 1500 1501
  return 0;
}

1502
static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1503
  int32_t col = mndFindSuperTableColumnIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1504 1505 1506 1507 1508 1509 1510
  if (col < 0) {
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

  uint32_t nLen = 0;
  for (int32_t i = 0; i < pOld->numOfColumns; ++i) {
S
Shengliang Guan 已提交
1511
    nLen += (pOld->pColumns[i].colId == col) ? pField->bytes : pOld->pColumns[i].bytes;
S
Shengliang Guan 已提交
1512 1513 1514 1515 1516 1517 1518
  }

  if (nLen > TSDB_MAX_BYTES_PER_ROW) {
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

1519
  col_id_t colId = pOld->pColumns[col].colId;
1520
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1521 1522 1523
    return -1;
  }

S
Shengliang Guan 已提交
1524 1525 1526 1527 1528
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pCol = pNew->pColumns + col;
S
Shengliang Guan 已提交
1529 1530
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
1531 1532 1533
    return -1;
  }

S
Shengliang Guan 已提交
1534
  if (pField->bytes <= pCol->bytes) {
S
Shengliang Guan 已提交
1535
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
S
Shengliang Guan 已提交
1536 1537 1538
    return -1;
  }

S
Shengliang Guan 已提交
1539
  pCol->bytes = pField->bytes;
1540
  pNew->colVer++;
S
Shengliang Guan 已提交
1541

1542
  mInfo("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1543 1544 1545
  return 0;
}

S
Shengliang Guan 已提交
1546
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1547 1548
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1549 1550 1551 1552
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1553
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
S
Shengliang Guan 已提交
1554 1555 1556 1557

  return 0;
}

S
Shengliang Guan 已提交
1558
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1559 1560
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
1561 1562 1563 1564
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1565 1566 1567 1568 1569
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

1570 1571
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb, void *alterOriData,
                                         int32_t alterOriDataLen) {
S
Shengliang Guan 已提交
1572 1573 1574 1575 1576 1577 1578 1579
  SSdb   *pSdb = pMnode->pSdb;
  SVgObj *pVgroup = NULL;
  void   *pIter = NULL;
  int32_t contLen;

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
1580
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
1581 1582 1583 1584
      sdbRelease(pSdb, pVgroup);
      continue;
    }

wmmhello's avatar
wmmhello 已提交
1585
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, alterOriData, alterOriDataLen);
S
Shengliang Guan 已提交
1586 1587 1588 1589 1590 1591 1592 1593 1594
    if (pReq == NULL) {
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
    action.pCont = pReq;
    action.contLen = contLen;
S
Shengliang Guan 已提交
1595
    action.msgType = TDMT_VND_ALTER_STB;
S
Shengliang Guan 已提交
1596
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
1597
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

D
dapan1121 已提交
1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
  taosRLockLatch(&pStb->lock);

  int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
  pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
  if (pRsp->pSchemas == NULL) {
    taosRUnLockLatch(&pStb->lock);
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

S
Shengliang Guan 已提交
1619 1620 1621
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
D
dapan1121 已提交
1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653
  pRsp->dbId = pDb->uid;
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->precision = pDb->cfg.precision;
  pRsp->tableType = TSDB_SUPER_TABLE;
  pRsp->sversion = pStb->colVer;
  pRsp->tversion = pStb->tagVer;
  pRsp->suid = pStb->uid;
  pRsp->tuid = pStb->uid;

  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pRsp->pSchemas[i];
    SSchema *pSrcSchema = &pStb->pColumns[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
    SSchema *pSrcSchema = &pStb->pTags[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
  }

  taosRUnLockLatch(&pStb->lock);
  return 0;
}

D
dapan1121 已提交
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableCfgRsp *pRsp) {
  taosRLockLatch(&pStb->lock);

  int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
  pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
  if (pRsp->pSchemas == NULL) {
    taosRUnLockLatch(&pStb->lock);
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

S
Shengliang Guan 已提交
1665 1666 1667
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
D
dapan1121 已提交
1668 1669 1670
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->tableType = TSDB_SUPER_TABLE;
D
dapan1121 已提交
1671 1672 1673 1674
  pRsp->delay1 = pStb->maxdelay[0];
  pRsp->delay2 = pStb->maxdelay[1];
  pRsp->watermark1 = pStb->watermark[0];
  pRsp->watermark2 = pStb->watermark[1];
D
dapan1121 已提交
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
  pRsp->ttl = pStb->ttl;
  pRsp->commentLen = pStb->commentLen;
  if (pStb->commentLen > 0) {
    pRsp->pComment = strdup(pStb->comment);
  }

  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pRsp->pSchemas[i];
    SSchema *pSrcSchema = &pStb->pColumns[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
    SSchema *pSrcSchema = &pStb->pTags[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
  }

S
Shengliang Guan 已提交
1699
  if (pStb->numOfFuncs > 0) {
H
Haojun Liao 已提交
1700
    pRsp->pFuncs = taosArrayDup(pStb->pFuncs, NULL);
D
dapan1121 已提交
1701
  }
1702

D
dapan1121 已提交
1703 1704 1705 1706
  taosRUnLockLatch(&pStb->lock);
  return 0;
}

L
Liu Jicong 已提交
1707 1708
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp,
                                 int32_t *smaVer) {
D
dapan1121 已提交
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720
  char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
  snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);

  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

  SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
  if (pStb == NULL) {
    mndReleaseDb(pMnode, pDb);
D
dapan1121 已提交
1721
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
D
dapan1121 已提交
1722 1723 1724
    return -1;
  }

D
dapan1121 已提交
1725 1726 1727 1728
  if (smaVer) {
    *smaVer = pStb->smaVer;
  }

D
dapan1121 已提交
1729 1730 1731 1732 1733 1734
  int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}

D
dapan1121 已提交
1735
static int32_t mndBuildStbCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) {
1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750
  char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
  snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);

  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

  SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
  if (pStb == NULL) {
    mndReleaseDb(pMnode, pDb);
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
    return -1;
  }
D
dapan1121 已提交
1751

1752
  int32_t code = mndBuildStbCfgImp(pDb, pStb, tbName, pRsp);
D
dapan1121 已提交
1753

1754 1755 1756 1757
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}
D
dapan1121 已提交
1758

1759
static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, SStbObj *pObj, void **pCont, int32_t *pLen) {
1760
  int32_t       ret;
D
dapan1121 已提交
1761
  SEncoder      ec = {0};
1762
  uint32_t      contLen = 0;
D
dapan1121 已提交
1763
  SMAlterStbRsp alterRsp = {0};
1764
  SName         name = {0};
1765
  tNameFromString(&name, pObj->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
D
dapan1121 已提交
1766 1767 1768 1769 1770 1771

  alterRsp.pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
  if (NULL == alterRsp.pMeta) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
1772

D
dapan1121 已提交
1773
  ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
D
dapan1121 已提交
1774 1775 1776 1777
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }
1778

D
dapan1121 已提交
1779 1780 1781 1782 1783 1784
  tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }

1785
  void *cont = taosMemoryMalloc(contLen);
D
dapan1121 已提交
1786 1787 1788 1789 1790 1791 1792 1793
  tEncoderInit(&ec, cont, contLen);
  tEncodeSMAlterStbRsp(&ec, &alterRsp);
  tEncoderClear(&ec);

  tFreeSMAlterStbRsp(&alterRsp);

  *pCont = cont;
  *pLen = contLen;
1794

D
dapan1121 已提交
1795 1796 1797
  return 0;
}

L
Liu Jicong 已提交
1798 1799
int32_t mndBuildSMCreateStbRsp(SMnode *pMnode, char *dbFName, char *stbFName, void **pCont, int32_t *pLen) {
  int32_t ret = -1;
1800 1801 1802 1803 1804 1805 1806 1807 1808
  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
  if (NULL == pDb) {
    return -1;
  }

  SStbObj *pObj = mndAcquireStb(pMnode, stbFName);
  if (NULL == pObj) {
    goto _OVER;
  }
L
Liu Jicong 已提交
1809 1810 1811

  SEncoder       ec = {0};
  uint32_t       contLen = 0;
1812
  SMCreateStbRsp stbRsp = {0};
L
Liu Jicong 已提交
1813
  SName          name = {0};
1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844
  tNameFromString(&name, pObj->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

  stbRsp.pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
  if (NULL == stbRsp.pMeta) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _OVER;
  }

  ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, stbRsp.pMeta);
  if (ret) {
    tFreeSMCreateStbRsp(&stbRsp);
    goto _OVER;
  }

  tEncodeSize(tEncodeSMCreateStbRsp, &stbRsp, contLen, ret);
  if (ret) {
    tFreeSMCreateStbRsp(&stbRsp);
    goto _OVER;
  }

  void *cont = taosMemoryMalloc(contLen);
  tEncoderInit(&ec, cont, contLen);
  tEncodeSMCreateStbRsp(&ec, &stbRsp);
  tEncoderClear(&ec);

  tFreeSMCreateStbRsp(&stbRsp);

  *pCont = cont;
  *pLen = contLen;

  ret = 0;
L
Liu Jicong 已提交
1845

1846 1847 1848 1849
_OVER:
  if (pObj) {
    mndReleaseStb(pMnode, pObj);
  }
L
Liu Jicong 已提交
1850

1851 1852 1853 1854 1855 1856 1857
  if (pDb) {
    mndReleaseDb(pMnode, pDb);
  }

  return ret;
}

1858 1859
static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
                              void *alterOriData, int32_t alterOriDataLen) {
1860
  int32_t code = -1;
1861
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "alter-stb");
1862 1863
  if (pTrans == NULL) goto _OVER;

1864
  mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
1865
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
1866
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
1867 1868 1869 1870 1871 1872 1873 1874 1875 1876

  if (needRsp) {
    void   *pCont = NULL;
    int32_t contLen = 0;
    if (mndBuildSMAlterStbRsp(pDb, pStb, &pCont, &contLen) != 0) goto _OVER;
    mndTransSetRpcRsp(pTrans, pCont, contLen);
  }

  if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
  if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
wmmhello's avatar
wmmhello 已提交
1877
  if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen) != 0) goto _OVER;
1878 1879 1880 1881 1882 1883 1884 1885 1886
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;

  code = 0;

_OVER:
  mndTransDrop(pTrans);
  return code;
}

S
Shengliang Guan 已提交
1887
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
1888 1889 1890 1891
  bool    needRsp = true;
  int32_t code = -1;
  SField *pField0 = NULL;

S
Shengliang Guan 已提交
1892 1893 1894
  SStbObj stbObj = {0};
  taosRLockLatch(&pOld->lock);
  memcpy(&stbObj, pOld, sizeof(SStbObj));
1895
  taosRUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
1896 1897 1898
  stbObj.pColumns = NULL;
  stbObj.pTags = NULL;
  stbObj.updateTime = taosGetTimestampMs();
D
dapan1121 已提交
1899
  stbObj.lock = 0;
S
Shengliang Guan 已提交
1900

S
Shengliang Guan 已提交
1901
  switch (pAlter->alterType) {
S
Shengliang Guan 已提交
1902
    case TSDB_ALTER_TABLE_ADD_TAG:
S
Shengliang Guan 已提交
1903
      code = mndAddSuperTableTag(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1904
      break;
S
Shengliang Guan 已提交
1905
    case TSDB_ALTER_TABLE_DROP_TAG:
S
Shengliang 已提交
1906
      pField0 = taosArrayGet(pAlter->pFields, 0);
1907
      code = mndDropSuperTableTag(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1908
      break;
S
Shengliang Guan 已提交
1909
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
1910
      code = mndAlterStbTagName(pMnode, pOld, &stbObj, pAlter->pFields);
S
Shengliang Guan 已提交
1911
      break;
S
Shengliang Guan 已提交
1912
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
S
Shengliang 已提交
1913
      pField0 = taosArrayGet(pAlter->pFields, 0);
1914
      code = mndAlterStbTagBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1915 1916
      break;
    case TSDB_ALTER_TABLE_ADD_COLUMN:
S
Shengliang Guan 已提交
1917
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1918 1919
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
S
Shengliang 已提交
1920
      pField0 = taosArrayGet(pAlter->pFields, 0);
1921
      code = mndDropSuperTableColumn(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1922
      break;
S
Shengliang Guan 已提交
1923
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
S
Shengliang 已提交
1924
      pField0 = taosArrayGet(pAlter->pFields, 0);
1925
      code = mndAlterStbColumnBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1926
      break;
S
Shengliang 已提交
1927
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
D
dapan1121 已提交
1928
      needRsp = false;
S
Shengliang 已提交
1929
      code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
S
Shengliang 已提交
1930
      break;
S
Shengliang Guan 已提交
1931
    default:
D
dapan1121 已提交
1932
      needRsp = false;
S
Shengliang 已提交
1933
      terrno = TSDB_CODE_OPS_NOT_SUPPORT;
S
Shengliang Guan 已提交
1934 1935 1936
      break;
  }

1937
  if (code != 0) goto _OVER;
wmmhello's avatar
wmmhello 已提交
1938
  code = mndAlterStbImp(pMnode, pReq, pDb, &stbObj, needRsp, pReq->pCont, pReq->contLen);
S
Shengliang Guan 已提交
1939

1940
_OVER:
wafwerar's avatar
wafwerar 已提交
1941 1942
  taosMemoryFreeClear(stbObj.pTags);
  taosMemoryFreeClear(stbObj.pColumns);
1943 1944 1945
  if (pAlter->commentLen > 0) {
    taosMemoryFreeClear(stbObj.comment);
  }
S
Shengliang Guan 已提交
1946 1947
  return code;
}
S
Shengliang Guan 已提交
1948

1949
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
1950
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1951 1952 1953 1954
  int32_t       code = -1;
  SDbObj       *pDb = NULL;
  SStbObj      *pStb = NULL;
  SMAlterStbReq alterReq = {0};
S
Shengliang Guan 已提交
1955

S
Shengliang Guan 已提交
1956
  if (tDeserializeSMAlterStbReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
1957
    terrno = TSDB_CODE_INVALID_MSG;
1958
    goto _OVER;
S
Shengliang Guan 已提交
1959
  }
S
Shengliang Guan 已提交
1960

1961
  mInfo("stb:%s, start to alter", alterReq.name);
1962
  if (mndCheckAlterStbReq(&alterReq) != 0) goto _OVER;
S
Shengliang Guan 已提交
1963

S
Shengliang Guan 已提交
1964
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1965 1966
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_INVALID_DB;
1967
    goto _OVER;
S
Shengliang Guan 已提交
1968 1969
  }

S
Shengliang Guan 已提交
1970
  pStb = mndAcquireStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1971 1972
  if (pStb == NULL) {
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
1973
    goto _OVER;
S
Shengliang Guan 已提交
1974
  }
S
Shengliang Guan 已提交
1975

1976
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1977
    goto _OVER;
S
Shengliang Guan 已提交
1978 1979
  }

S
Shengliang Guan 已提交
1980
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
S
Shengliang Guan 已提交
1981
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1982

1983
_OVER:
S
Shengliang Guan 已提交
1984
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1985
    mError("stb:%s, failed to alter since %s", alterReq.name, terrstr());
S
Shengliang Guan 已提交
1986 1987
  }

S
Shengliang Guan 已提交
1988 1989
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
1990
  tFreeSMAltertbReq(&alterReq);
S
Shengliang Guan 已提交
1991 1992

  return code;
S
Shengliang Guan 已提交
1993
}
S
Shengliang Guan 已提交
1994

S
Shengliang Guan 已提交
1995 1996 1997
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1998 1999 2000 2001
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
2002 2003 2004 2005 2006 2007 2008 2009
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING) != 0) return -1;

  return 0;
}

static int32_t mndSetDropStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
2010 2011 2012 2013
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
2014 2015 2016 2017 2018
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

S
Shengliang Guan 已提交
2019 2020 2021 2022
static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
  SSdb   *pSdb = pMnode->pSdb;
  SVgObj *pVgroup = NULL;
  void   *pIter = NULL;
S
Shengliang Guan 已提交
2023

S
Shengliang Guan 已提交
2024 2025 2026
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
2027
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
2028 2029 2030 2031
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
2032
    int32_t contLen = 0;
S
Shengliang Guan 已提交
2033
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045
    if (pReq == NULL) {
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }

    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
    action.pCont = pReq;
    action.contLen = contLen;
    action.msgType = TDMT_VND_DROP_STB;
S
Shengliang Guan 已提交
2046
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
S
Shengliang Guan 已提交
2047
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
2048
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
2049 2050 2051 2052 2053 2054 2055 2056 2057 2058
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

S
Shengliang Guan 已提交
2059
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
2060
  int32_t code = -1;
2061
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "drop-stb");
2062
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
2063

2064
  mInfo("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
2065
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
2066
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
2067

2068 2069 2070
  if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
  if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
  if (mndSetDropStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
2071
  if (mndDropSmasByStb(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
2072
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
2073

S
Shengliang Guan 已提交
2074 2075
  code = 0;

2076
_OVER:
S
Shengliang Guan 已提交
2077
  mndTransDrop(pTrans);
S
Shengliang 已提交
2078
  return code;
S
Shengliang Guan 已提交
2079 2080
}

2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102
static int32_t mndCheckDropStbForTopic(SMnode *pMnode, const char *stbFullName, int64_t suid) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SMqTopicObj *pTopic = NULL;
    pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
    if (pIter == NULL) break;

    if (pTopic->subType == TOPIC_SUB_TYPE__TABLE) {
      if (pTopic->stbUid == suid) {
        sdbRelease(pSdb, pTopic);
        return -1;
      }
    }

    if (pTopic->subType != TOPIC_SUB_TYPE__COLUMN) {
      sdbRelease(pSdb, pTopic);
      continue;
    }

    SNode *pAst = NULL;
    if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
S
Shengliang Guan 已提交
2103 2104 2105
      terrno = TSDB_CODE_MND_INVALID_TOPIC_OPTION;
      mError("topic:%s, create ast error", pTopic->name);
      sdbRelease(pSdb, pTopic);
2106 2107 2108 2109 2110 2111 2112 2113 2114
      return -1;
    }

    SNodeList *pNodeList = NULL;
    nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList);
    SNode *pNode = NULL;
    FOREACH(pNode, pNodeList) {
      SColumnNode *pCol = (SColumnNode *)pNode;

L
Liu Jicong 已提交
2115
      if (pCol->tableId == suid) {
2116 2117
        sdbRelease(pSdb, pTopic);
        nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2118
        nodesDestroyList(pNodeList);
2119 2120 2121 2122 2123 2124 2125 2126
        return -1;
      } else {
        goto NEXT;
      }
    }
  NEXT:
    sdbRelease(pSdb, pTopic);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2127
    nodesDestroyList(pNodeList);
2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
  }
  return 0;
}

static int32_t mndCheckDropStbForStream(SMnode *pMnode, const char *stbFullName, int64_t suid) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SStreamObj *pStream = NULL;
    pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
    if (pIter == NULL) break;

L
Liu Jicong 已提交
2140 2141 2142 2143 2144 2145
    if (pStream->smaId != 0) {
      sdbRelease(pSdb, pStream);
      continue;
    }

    if (pStream->targetStbUid == suid) {
L
Liu Jicong 已提交
2146 2147 2148 2149
      sdbRelease(pSdb, pStream);
      return -1;
    }

2150 2151
    SNode *pAst = NULL;
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
S
Shengliang Guan 已提交
2152 2153 2154
      terrno = TSDB_CODE_MND_INVALID_STREAM_OPTION;
      mError("stream:%s, create ast error", pStream->name);
      sdbRelease(pSdb, pStream);
2155 2156 2157 2158 2159 2160 2161 2162 2163
      return -1;
    }

    SNodeList *pNodeList = NULL;
    nodesCollectColumns((SSelectStmt *)pAst, SQL_CLAUSE_FROM, NULL, COLLECT_COL_TYPE_ALL, &pNodeList);
    SNode *pNode = NULL;
    FOREACH(pNode, pNodeList) {
      SColumnNode *pCol = (SColumnNode *)pNode;

L
Liu Jicong 已提交
2164
      if (pCol->tableId == suid) {
2165 2166
        sdbRelease(pSdb, pStream);
        nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2167
        nodesDestroyList(pNodeList);
2168 2169 2170 2171 2172 2173 2174 2175
        return -1;
      } else {
        goto NEXT;
      }
    }
  NEXT:
    sdbRelease(pSdb, pStream);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2176
    nodesDestroyList(pNodeList);
2177 2178 2179 2180
  }
  return 0;
}

wmmhello's avatar
wmmhello 已提交
2181 2182 2183 2184
static int32_t mndProcessDropTtltbReq(SRpcMsg *pRsp) {
  return 0;
}

2185
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
2186
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2187 2188 2189
  int32_t      code = -1;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
2190
  SMDropStbReq dropReq = {0};
S
Shengliang Guan 已提交
2191

S
Shengliang Guan 已提交
2192
  if (tDeserializeSMDropStbReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
2193
    terrno = TSDB_CODE_INVALID_MSG;
2194
    goto _OVER;
S
Shengliang Guan 已提交
2195
  }
S
Shengliang Guan 已提交
2196

2197
  mInfo("stb:%s, start to drop", dropReq.name);
S
Shengliang Guan 已提交
2198

S
Shengliang Guan 已提交
2199
  pStb = mndAcquireStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
2200
  if (pStb == NULL) {
S
Shengliang Guan 已提交
2201
    if (dropReq.igNotExists) {
2202
      mInfo("stb:%s, not exist, ignore not exist is set", dropReq.name);
S
Shengliang Guan 已提交
2203
      code = 0;
2204
      goto _OVER;
S
Shengliang Guan 已提交
2205 2206
    } else {
      terrno = TSDB_CODE_MND_STB_NOT_EXIST;
2207
      goto _OVER;
S
Shengliang Guan 已提交
2208 2209 2210
    }
  }

wmmhello's avatar
wmmhello 已提交
2211 2212
  if (dropReq.source == TD_REQ_FROM_TAOX && pStb->uid != dropReq.suid) {
    code = 0;
wmmhello's avatar
wmmhello 已提交
2213 2214 2215
    goto _OVER;
  }

S
Shengliang Guan 已提交
2216
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
2217 2218
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
2219
    goto _OVER;
S
Shengliang Guan 已提交
2220 2221
  }

2222
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
2223
    goto _OVER;
S
Shengliang Guan 已提交
2224 2225
  }

2226 2227 2228 2229 2230 2231 2232 2233 2234 2235
  if (mndCheckDropStbForTopic(pMnode, dropReq.name, pStb->uid) < 0) {
    terrno = TSDB_CODE_MND_TOPIC_MUST_BE_DELETED;
    goto _OVER;
  }

  if (mndCheckDropStbForStream(pMnode, dropReq.name, pStb->uid) < 0) {
    terrno = TSDB_CODE_MND_STREAM_MUST_BE_DELETED;
    goto _OVER;
  }

S
Shengliang Guan 已提交
2236
  code = mndDropStb(pMnode, pReq, pDb, pStb);
S
Shengliang Guan 已提交
2237
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
2238

2239
_OVER:
S
Shengliang Guan 已提交
2240
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
2241
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
2242 2243
  }

S
Shengliang Guan 已提交
2244 2245 2246
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
S
Shengliang Guan 已提交
2247
}
S
Shengliang Guan 已提交
2248

S
Shengliang Guan 已提交
2249 2250
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2251 2252 2253
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
2254

2255 2256 2257 2258
  SUserObj *pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
  if (pUser == NULL) return 0;
  bool sysinfo = pUser->sysInfo;

S
Shengliang Guan 已提交
2259
  if (tDeserializeSTableInfoReq(pReq->pCont, pReq->contLen, &infoReq) != 0) {
S
Shengliang Guan 已提交
2260
    terrno = TSDB_CODE_INVALID_MSG;
2261
    goto _OVER;
S
Shengliang Guan 已提交
2262
  }
D
dapan 已提交
2263

D
dapan1121 已提交
2264
  if (0 == strcmp(infoReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
2265
    mInfo("information_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
2266
    if (mndBuildInsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, sysinfo, &metaRsp) != 0) {
2267
      goto _OVER;
D
dapan1121 已提交
2268
    }
D
dapan1121 已提交
2269
  } else if (0 == strcmp(infoReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
2270
    mInfo("performance_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2271
    if (mndBuildPerfsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
2272
      goto _OVER;
D
dapan1121 已提交
2273
    }
D
dapan1121 已提交
2274
  } else {
2275
    mInfo("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2276
    if (mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp, NULL) != 0) {
2277
      goto _OVER;
D
dapan1121 已提交
2278
    }
S
Shengliang Guan 已提交
2279
  }
S
Shengliang Guan 已提交
2280

S
Shengliang Guan 已提交
2281 2282 2283
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
2284
    goto _OVER;
S
Shengliang Guan 已提交
2285
  }
S
Shengliang Guan 已提交
2286

S
Shengliang Guan 已提交
2287
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
2288 2289
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
2290
    goto _OVER;
S
Shengliang Guan 已提交
2291
  }
D
dapan 已提交
2292

S
Shengliang Guan 已提交
2293
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
S
Shengliang Guan 已提交
2294 2295
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = rspLen;
S
Shengliang Guan 已提交
2296
  code = 0;
S
Shengliang Guan 已提交
2297

2298
  mTrace("%s.%s, meta is retrieved", infoReq.dbFName, infoReq.tbName);
D
dapan 已提交
2299

2300
_OVER:
S
Shengliang Guan 已提交
2301 2302 2303
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
2304

2305
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
2306 2307 2308
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
2309

D
dapan1121 已提交
2310
static int32_t mndProcessTableCfgReq(SRpcMsg *pReq) {
2311 2312 2313 2314
  SMnode      *pMnode = pReq->info.node;
  int32_t      code = -1;
  STableCfgReq cfgReq = {0};
  STableCfgRsp cfgRsp = {0};
D
dapan1121 已提交
2315 2316 2317 2318 2319 2320 2321

  if (tDeserializeSTableCfgReq(pReq->pCont, pReq->contLen, &cfgReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto _OVER;
  }

  if (0 == strcmp(cfgReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
2322
    mInfo("information_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
D
dapan1121 已提交
2323 2324 2325 2326
    if (mndBuildInsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  } else if (0 == strcmp(cfgReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
2327
    mInfo("performance_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
D
dapan1121 已提交
2328 2329 2330 2331
    if (mndBuildPerfsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  } else {
2332
    mInfo("stb:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
D
dapan1121 已提交
2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365
    if (mndBuildStbCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  }

  int32_t rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto _OVER;
  }

  void *pRsp = rpcMallocCont(rspLen);
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _OVER;
  }

  tSerializeSTableCfgRsp(pRsp, rspLen, &cfgRsp);
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = rspLen;
  code = 0;

  mTrace("%s.%s, cfg is retrieved", cfgReq.dbFName, cfgReq.tbName);

_OVER:
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve cfg since %s", cfgReq.dbFName, cfgReq.tbName, terrstr());
  }

  tFreeSTableCfgRsp(&cfgRsp);
  return code;
}

D
dapan1121 已提交
2366
int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t numOfStbs, void **ppRsp,
S
Shengliang Guan 已提交
2367
                           int32_t *pRspLen) {
D
dapan1121 已提交
2368
  SSTbHbRsp hbRsp = {0};
D
dapan1121 已提交
2369 2370
  hbRsp.pMetaRsp = taosArrayInit(numOfStbs, sizeof(STableMetaRsp));
  if (hbRsp.pMetaRsp == NULL) {
S
Shengliang Guan 已提交
2371 2372 2373
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
2374

D
dapan1121 已提交
2375
  hbRsp.pIndexRsp = taosArrayInit(numOfStbs, sizeof(STableIndexRsp));
D
dapan1121 已提交
2376
  if (NULL == hbRsp.pIndexRsp) {
D
dapan1121 已提交
2377
    taosArrayDestroy(hbRsp.pMetaRsp);
D
dapan1121 已提交
2378 2379 2380
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
L
Liu Jicong 已提交
2381

S
Shengliang Guan 已提交
2382
  for (int32_t i = 0; i < numOfStbs; ++i) {
D
dapan1121 已提交
2383
    SSTableVersion *pStbVersion = &pStbVersions[i];
S
Shengliang Guan 已提交
2384 2385 2386
    pStbVersion->suid = be64toh(pStbVersion->suid);
    pStbVersion->sversion = ntohs(pStbVersion->sversion);
    pStbVersion->tversion = ntohs(pStbVersion->tversion);
D
dapan1121 已提交
2387
    pStbVersion->smaVer = ntohl(pStbVersion->smaVer);
S
Shengliang Guan 已提交
2388

S
Shengliang Guan 已提交
2389
    STableMetaRsp metaRsp = {0};
L
Liu Jicong 已提交
2390
    int32_t       smaVer = 0;
2391
    mInfo("stb:%s.%s, start to retrieve meta", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2392
    if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
S
Shengliang Guan 已提交
2393 2394
      metaRsp.numOfColumns = -1;
      metaRsp.suid = pStbVersion->suid;
D
dapan1121 已提交
2395
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2396
      continue;
D
dapan 已提交
2397
    }
S
Shengliang Guan 已提交
2398

D
dapan1121 已提交
2399
    if (pStbVersion->sversion != metaRsp.sversion || pStbVersion->tversion != metaRsp.tversion) {
D
dapan1121 已提交
2400
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2401 2402
    } else {
      tFreeSTableMetaRsp(&metaRsp);
S
Shengliang Guan 已提交
2403
    }
D
dapan1121 已提交
2404

D
dapan1121 已提交
2405
    if (pStbVersion->smaVer && pStbVersion->smaVer != smaVer) {
L
Liu Jicong 已提交
2406 2407
      bool           exist = false;
      char           tbFName[TSDB_TABLE_FNAME_LEN];
D
dapan1121 已提交
2408
      STableIndexRsp indexRsp = {0};
D
dapan1121 已提交
2409 2410 2411 2412 2413
      indexRsp.pIndex = taosArrayInit(10, sizeof(STableIndexInfo));
      if (NULL == indexRsp.pIndex) {
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        return -1;
      }
L
Liu Jicong 已提交
2414

D
dapan1121 已提交
2415
      sprintf(tbFName, "%s.%s", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2416
      int32_t code = mndGetTableSma(pMnode, tbFName, &indexRsp, &exist);
D
dapan1121 已提交
2417
      if (code || !exist) {
D
dapan1121 已提交
2418 2419 2420
        indexRsp.suid = pStbVersion->suid;
        indexRsp.version = -1;
        indexRsp.pIndex = NULL;
D
dapan1121 已提交
2421
      }
D
dapan1121 已提交
2422

D
dapan1121 已提交
2423 2424
      strcpy(indexRsp.dbFName, pStbVersion->dbFName);
      strcpy(indexRsp.tbName, pStbVersion->stbName);
D
dapan1121 已提交
2425 2426

      taosArrayPush(hbRsp.pIndexRsp, &indexRsp);
D
dapan1121 已提交
2427
    }
S
Shengliang Guan 已提交
2428
  }
S
Shengliang Guan 已提交
2429

D
dapan1121 已提交
2430
  int32_t rspLen = tSerializeSSTbHbRsp(NULL, 0, &hbRsp);
S
Shengliang Guan 已提交
2431
  if (rspLen < 0) {
D
dapan1121 已提交
2432
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2433 2434
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
2435 2436
  }

wafwerar's avatar
wafwerar 已提交
2437
  void *pRsp = taosMemoryMalloc(rspLen);
S
Shengliang Guan 已提交
2438
  if (pRsp == NULL) {
D
dapan1121 已提交
2439
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2440 2441
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
2442 2443
  }

D
dapan1121 已提交
2444 2445
  tSerializeSSTbHbRsp(pRsp, rspLen, &hbRsp);
  tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2446 2447
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
2448 2449 2450
  return 0;
}

2451
int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
2452
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2453 2454 2455 2456 2457 2458
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
2459
  int32_t numOfStbs = 0;
2460
  void   *pIter = NULL;
S
Shengliang Guan 已提交
2461
  while (1) {
S
Shengliang Guan 已提交
2462
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
2463
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2464 2465
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
2466
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
2467
      numOfStbs++;
S
Shengliang Guan 已提交
2468 2469
    }

S
Shengliang Guan 已提交
2470
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2471 2472
  }

S
Shengliang Guan 已提交
2473
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
2474
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
2475 2476 2477
  return 0;
}

L
Liu Jicong 已提交
2478 2479 2480 2481 2482 2483 2484 2485
void mndExtractDbNameFromStbFullName(const char *stbFullName, char *dst) {
  SName name = {0};
  tNameFromString(&name, stbFullName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

  tNameGetFullDbName(&name, dst);
}

void mndExtractTbNameFromStbFullName(const char *stbFullName, char *dst, int32_t dstSize) {
S
Shengliang Guan 已提交
2486 2487
  int32_t pos = -1;
  int32_t num = 0;
L
Liu Jicong 已提交
2488 2489
  for (pos = 0; stbFullName[pos] != 0; ++pos) {
    if (stbFullName[pos] == TS_PATH_DELIMITER[0]) num++;
S
Shengliang Guan 已提交
2490 2491 2492 2493
    if (num == 2) break;
  }

  if (num == 2) {
L
Liu Jicong 已提交
2494
    tstrncpy(dst, stbFullName + pos + 1, dstSize);
S
Shengliang Guan 已提交
2495 2496 2497
  }
}

S
Shengliang Guan 已提交
2498 2499
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode  *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2500
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2501 2502 2503
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
2504

H
Hongze Cheng 已提交
2505
  SDbObj *pDb = NULL;
H
Haojun Liao 已提交
2506 2507
  if (strlen(pShow->db) > 0) {
    pDb = mndAcquireDb(pMnode, pShow->db);
D
dapan1121 已提交
2508
    if (pDb == NULL) return terrno;
H
Haojun Liao 已提交
2509
  }
S
Shengliang Guan 已提交
2510

S
Shengliang Guan 已提交
2511
  while (numOfRows < rows) {
S
Shengliang Guan 已提交
2512
    pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2513 2514
    if (pShow->pIter == NULL) break;

H
Haojun Liao 已提交
2515
    if (pDb != NULL && pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
2516
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2517 2518 2519 2520 2521
      continue;
    }

    cols = 0;

H
Haojun Liao 已提交
2522
    SName name = {0};
H
Hongze Cheng 已提交
2523
    char  stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
L
Liu Jicong 已提交
2524
    mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
2525
    varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
S
Shengliang Guan 已提交
2526

H
Hongze Cheng 已提交
2527
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2528
    colDataSetVal(pColInfo, numOfRows, (const char *)stbName, false);
2529

H
Hongze Cheng 已提交
2530 2531
    char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
2532 2533 2534
    tNameGetDbName(&name, varDataVal(db));
    varDataSetLen(db, strlen(varDataVal(db)));

2535
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2536
    colDataSetVal(pColInfo, numOfRows, (const char *)db, false);
2537 2538

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2539
    colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->createdTime, false);
2540 2541

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2542
    colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->numOfColumns, false);
2543 2544

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2545
    colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->numOfTags, false);
2546 2547

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2548
    colDataSetVal(pColInfo, numOfRows, (const char *)&pStb->updateTime, false);  // number of tables
2549

2550
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
wmmhello's avatar
wmmhello 已提交
2551 2552 2553
    if (pStb->commentLen > 0) {
      char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
      STR_TO_VARSTR(comment, pStb->comment);
2554
      colDataSetVal(pColInfo, numOfRows, comment, false);
2555
    } else if (pStb->commentLen == 0) {
wmmhello's avatar
wmmhello 已提交
2556 2557
      char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
      STR_TO_VARSTR(comment, "");
2558
      colDataSetVal(pColInfo, numOfRows, comment, false);
wmmhello's avatar
wmmhello 已提交
2559 2560
    } else {
      colDataAppendNULL(pColInfo, numOfRows);
S
Shengliang Guan 已提交
2561
    }
H
Haojun Liao 已提交
2562

2563 2564 2565 2566 2567
    char watermark[64 + VARSTR_HEADER_SIZE] = {0};
    sprintf(varDataVal(watermark), "%" PRId64 "a,%" PRId64 "a", pStb->watermark[0], pStb->watermark[1]);
    varDataSetLen(watermark, strlen(varDataVal(watermark)));

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2568
    colDataSetVal(pColInfo, numOfRows, (const char *)watermark, false);
2569 2570 2571 2572 2573 2574

    char maxDelay[64 + VARSTR_HEADER_SIZE] = {0};
    sprintf(varDataVal(maxDelay), "%" PRId64 "a,%" PRId64 "a", pStb->maxdelay[0], pStb->maxdelay[1]);
    varDataSetLen(maxDelay, strlen(varDataVal(maxDelay)));

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2575
    colDataSetVal(pColInfo, numOfRows, (const char *)maxDelay, false);
2576

S
Shengliang Guan 已提交
2577
    char    rollup[160 + VARSTR_HEADER_SIZE] = {0};
2578
    int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
D
dapan1121 已提交
2579 2580
    char   *sep = ", ";
    int32_t sepLen = strlen(sep);
D
dapan1121 已提交
2581
    int32_t rollupLen = sizeof(rollup) - VARSTR_HEADER_SIZE - 2;
2582 2583 2584
    for (int32_t i = 0; i < rollupNum; ++i) {
      char *funcName = taosArrayGet(pStb->pFuncs, i);
      if (i) {
D
dapan1121 已提交
2585 2586
        strncat(varDataVal(rollup), sep, rollupLen);
        rollupLen -= sepLen;
2587
      }
D
dapan1121 已提交
2588 2589
      strncat(varDataVal(rollup), funcName, rollupLen);
      rollupLen -= strlen(funcName);
2590 2591 2592 2593
    }
    varDataSetLen(rollup, strlen(varDataVal(rollup)));

    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2594
    colDataSetVal(pColInfo, numOfRows, (const char *)rollup, false);
2595

S
Shengliang Guan 已提交
2596
    numOfRows++;
S
Shengliang Guan 已提交
2597
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2598 2599
  }

H
Haojun Liao 已提交
2600 2601 2602 2603
  if (pDb != NULL) {
    mndReleaseDb(pMnode, pDb);
  }

2604
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
2605 2606 2607
  return numOfRows;
}

S
Shengliang Guan 已提交
2608
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
2609 2610
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan1121 已提交
2611
}
S
Shengliang Guan 已提交
2612 2613 2614 2615 2616 2617 2618 2619 2620 2621

const char *mndGetStbStr(const char *src) {
  char *posDb = strstr(src, TS_PATH_DELIMITER);
  if (posDb != NULL) ++posDb;
  if (posDb == NULL) return src;

  char *posStb = strstr(posDb, TS_PATH_DELIMITER);
  if (posStb != NULL) ++posStb;
  if (posStb == NULL) return posDb;
  return posStb;
D
dapan1121 已提交
2622
}