mndStb.c 79.8 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);
S
Shengliang Guan 已提交
44 45
static int32_t  mndProcessTableMetaReq(SRpcMsg *pReq);
static int32_t  mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
S
Shengliang Guan 已提交
46
static void     mndCancelGetNextStb(SMnode *pMnode, void *pIter);
D
dapan1121 已提交
47
static int32_t  mndProcessTableCfgReq(SRpcMsg *pReq);
48 49 50
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 已提交
51 52

int32_t mndInitStb(SMnode *pMnode) {
S
Shengliang Guan 已提交
53 54 55 56 57 58 59 60 61
  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 已提交
62

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

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

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

S
Shengliang Guan 已提交
79
void mndCleanupStb(SMnode *pMnode) {}
S
Shengliang Guan 已提交
80

81
SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
82 83
  terrno = TSDB_CODE_OUT_OF_MEMORY;

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

  int32_t dataPos = 0;
90 91 92 93 94 95
  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)
96 97
  SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
S
Shengliang Guan 已提交
98
  SDB_SET_INT32(pRaw, dataPos, pStb->smaVer, _OVER)
99
  SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
100 101 102 103
  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)
104 105 106
  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 已提交
107
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfFuncs, _OVER)
108
  SDB_SET_INT32(pRaw, dataPos, pStb->commentLen, _OVER)
109 110
  SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER)
S
Shengliang Guan 已提交
111

S
Shengliang Guan 已提交
112 113
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
114
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
S
Shengliang Guan 已提交
115
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
116 117 118
    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 已提交
119 120 121 122
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
123
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
S
Shengliang Guan 已提交
124
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
125 126 127
    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 已提交
128 129
  }

S
Shengliang Guan 已提交
130 131 132 133 134
  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 已提交
135
  if (pStb->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
136
    SDB_SET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
S
sma  
Shengliang Guan 已提交
137
  }
S
Shengliang Guan 已提交
138

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

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

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

  terrno = 0;

152
_OVER:
153 154 155 156 157
  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 已提交
158

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

S
Shengliang Guan 已提交
163
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
164 165
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
166
  int8_t sver = 0;
167
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
168

S
Shengliang Guan 已提交
169
  if (sver != STB_VER_NUMBER) {
S
Shengliang Guan 已提交
170
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
171
    goto _OVER;
S
Shengliang Guan 已提交
172 173
  }

S
Shengliang 已提交
174
  SSdbRow *pRow = sdbAllocRow(sizeof(SStbObj));
175
  if (pRow == NULL) goto _OVER;
176

S
Shengliang Guan 已提交
177
  SStbObj *pStb = sdbGetRowObj(pRow);
178
  if (pStb == NULL) goto _OVER;
S
Shengliang Guan 已提交
179 180

  int32_t dataPos = 0;
181 182 183 184 185 186
  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)
187 188
  SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
S
Shengliang Guan 已提交
189
  SDB_GET_INT32(pRaw, dataPos, &pStb->smaVer, _OVER)
190
  SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
191 192 193 194
  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)
195 196 197
  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 已提交
198
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfFuncs, _OVER)
199
  SDB_GET_INT32(pRaw, dataPos, &pStb->commentLen, _OVER)
200 201
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER)
S
Shengliang Guan 已提交
202

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

S
Shengliang Guan 已提交
210 211
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
212
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
S
Shengliang Guan 已提交
213
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
214 215 216
    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 已提交
217 218 219 220
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
221
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
S
Shengliang Guan 已提交
222
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
223 224 225
    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 已提交
226 227
  }

S
Shengliang Guan 已提交
228 229 230 231 232 233
  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 已提交
234
  if (pStb->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
235
    pStb->comment = taosMemoryCalloc(pStb->commentLen + 1, 1);
236
    if (pStb->comment == NULL) goto _OVER;
wmmhello's avatar
wmmhello 已提交
237
    SDB_GET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
S
sma  
Shengliang Guan 已提交
238
  }
S
Shengliang Guan 已提交
239

240 241 242 243 244
  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 已提交
245

246 247 248 249 250
  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 已提交
251
  SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
252 253 254

  terrno = 0;

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

265
  mTrace("stb:%s, decode from raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
266 267 268
  return pRow;
}

L
Liu Jicong 已提交
269 270 271 272 273 274 275 276 277
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 已提交
278
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
279
  mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
S
Shengliang Guan 已提交
280 281 282
  return 0;
}

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

S
Shengliang Guan 已提交
289 290
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 已提交
291

S
Shengliang Guan 已提交
292
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
293 294

  if (pOld->numOfColumns < pNew->numOfColumns) {
wafwerar's avatar
wafwerar 已提交
295
    void *pColumns = taosMemoryMalloc(pNew->numOfColumns * sizeof(SSchema));
S
Shengliang Guan 已提交
296
    if (pColumns != NULL) {
wafwerar's avatar
wafwerar 已提交
297
      taosMemoryFree(pOld->pColumns);
S
Shengliang Guan 已提交
298
      pOld->pColumns = pColumns;
S
Shengliang Guan 已提交
299 300 301 302 303 304 305 306
    } 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 已提交
307
    void *pTags = taosMemoryMalloc(pNew->numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
308
    if (pTags != NULL) {
wafwerar's avatar
wafwerar 已提交
309
      taosMemoryFree(pOld->pTags);
S
Shengliang Guan 已提交
310
      pOld->pTags = pTags;
S
Shengliang Guan 已提交
311 312 313 314
    } 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 已提交
315
    }
S
Shengliang Guan 已提交
316 317
  }

318
  if (pOld->commentLen < pNew->commentLen && pNew->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
319
    void *comment = taosMemoryMalloc(pNew->commentLen + 1);
S
Shengliang Guan 已提交
320
    if (comment != NULL) {
wafwerar's avatar
wafwerar 已提交
321
      taosMemoryFree(pOld->comment);
S
Shengliang Guan 已提交
322 323 324 325 326 327 328
      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 已提交
329
  pOld->commentLen = pNew->commentLen;
S
Shengliang Guan 已提交
330

331
  if (pOld->ast1Len < pNew->ast1Len) {
S
Shengliang Guan 已提交
332
    void *pAst1 = taosMemoryMalloc(pNew->ast1Len + 1);
333 334 335 336 337 338 339 340 341 342 343
    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 已提交
344
    void *pAst2 = taosMemoryMalloc(pNew->ast2Len + 1);
345 346 347 348 349 350 351 352 353 354
    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 已提交
355
  pOld->updateTime = pNew->updateTime;
356 357
  pOld->tagVer = pNew->tagVer;
  pOld->colVer = pNew->colVer;
358
  pOld->smaVer = pNew->smaVer;
359
  pOld->nextColId = pNew->nextColId;
S
Shengliang 已提交
360
  pOld->ttl = pNew->ttl;
361 362 363 364 365 366 367 368
  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));
  }
369
  if (pNew->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
370
    memcpy(pOld->comment, pNew->comment, pNew->commentLen + 1);
S
Shengliang Guan 已提交
371
    pOld->commentLen = pNew->commentLen;
S
Shengliang Guan 已提交
372
  }
373 374
  if (pNew->ast1Len != 0) {
    memcpy(pOld->pAst1, pNew->pAst1, pNew->ast1Len);
S
Shengliang Guan 已提交
375
    pOld->ast1Len = pNew->ast1Len;
376 377 378
  }
  if (pNew->ast2Len != 0) {
    memcpy(pOld->pAst2, pNew->pAst2, pNew->ast2Len);
S
Shengliang Guan 已提交
379
    pOld->ast2Len = pNew->ast2Len;
380
  }
S
Shengliang Guan 已提交
381
  taosWUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
382 383 384
  return 0;
}

S
Shengliang Guan 已提交
385
SStbObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
386
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
387
  SStbObj *pStb = sdbAcquire(pSdb, SDB_STB, stbName);
S
Shengliang Guan 已提交
388
  if (pStb == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
S
Shengliang Guan 已提交
389 390 391
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
  }
  return pStb;
S
Shengliang Guan 已提交
392 393
}

S
Shengliang Guan 已提交
394
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
S
Shengliang Guan 已提交
395 396 397 398
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pStb);
}

399
SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
S
Shengliang Guan 已提交
400 401
  SName name = {0};
  tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
S
Shengliang Guan 已提交
402

S
Shengliang Guan 已提交
403 404
  char db[TSDB_TABLE_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, db);
S
Shengliang Guan 已提交
405

S
Shengliang Guan 已提交
406 407
  return mndAcquireDb(pMnode, db);
}
S
Shengliang Guan 已提交
408

409
static FORCE_INLINE int32_t schemaExColIdCompare(const void *colId, const void *pSchema) {
H
Hongze Cheng 已提交
410
  if (*(col_id_t *)colId < ((SSchema *)pSchema)->colId) {
C
Cary Xu 已提交
411
    return -1;
H
Hongze Cheng 已提交
412
  } else if (*(col_id_t *)colId > ((SSchema *)pSchema)->colId) {
C
Cary Xu 已提交
413 414 415 416 417
    return 1;
  }
  return 0;
}

418 419
static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen,
                                   void *alterOriData, int32_t alterOriDataLen) {
H
Hongze Cheng 已提交
420
  SEncoder       encoder = {0};
H
Hongze Cheng 已提交
421 422 423
  int32_t        contLen;
  SName          name = {0};
  SVCreateStbReq req = {0};
H
Hongze Cheng 已提交
424

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

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

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

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

D
dapan1121 已提交
469
  SMsgHead *pHead = taosMemoryCalloc(1, contLen);
S
Shengliang Guan 已提交
470
  if (pHead == NULL) {
H
more  
Hongze Cheng 已提交
471
    terrno = TSDB_CODE_OUT_OF_MEMORY;
472
    goto _err;
H
more  
Hongze Cheng 已提交
473 474
  }

S
Shengliang Guan 已提交
475 476
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);
H
more  
Hongze Cheng 已提交
477

S
Shengliang Guan 已提交
478
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
H
Hongze Cheng 已提交
479 480
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  if (tEncodeSVCreateStbReq(&encoder, &req) < 0) {
481 482
    taosMemoryFreeClear(pHead);
    tEncoderClear(&encoder);
483
    goto _err;
H
Hongze Cheng 已提交
484
  }
H
Hongze Cheng 已提交
485
  tEncoderClear(&encoder);
H
more  
Hongze Cheng 已提交
486

S
Shengliang Guan 已提交
487
  *pContLen = contLen;
C
Cary Xu 已提交
488 489
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
S
Shengliang Guan 已提交
490
  return pHead;
491
_err:
C
Cary Xu 已提交
492 493
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
494
  return NULL;
495 496
}

S
Shengliang Guan 已提交
497
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
H
Hongze Cheng 已提交
498 499 500 501 502
  SName        name = {0};
  SVDropStbReq req = {0};
  int32_t      contLen = 0;
  int32_t      ret = 0;
  SMsgHead    *pHead = NULL;
H
Hongze Cheng 已提交
503
  SEncoder     encoder = {0};
H
Hongze Cheng 已提交
504

S
Shengliang Guan 已提交
505 506 507 508
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

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

H
Hongze Cheng 已提交
510 511 512 513 514
  tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
  if (ret < 0) return NULL;

  contLen += sizeof(SMsgHead);
  pHead = taosMemoryMalloc(contLen);
S
Shengliang Guan 已提交
515
  if (pHead == NULL) {
516 517 518 519
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
520 521 522 523
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);

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

H
Hongze Cheng 已提交
525 526 527
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  tEncodeSVDropStbReq(&encoder, &req);
  tEncoderClear(&encoder);
528

S
Shengliang Guan 已提交
529 530
  *pContLen = contLen;
  return pHead;
531 532
}

533
int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
S
Shengliang Guan 已提交
534
  if (pCreate->igExists < 0 || pCreate->igExists > 1) {
S
Shengliang Guan 已提交
535
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
536 537
    return -1;
  }
S
Shengliang Guan 已提交
538

539
  if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfTags + pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
5
54liuyao 已提交
540
    terrno = TSDB_CODE_PAR_INVALID_COLUMNS_NUM;
S
Shengliang Guan 已提交
541 542
    return -1;
  }
S
Shengliang Guan 已提交
543

S
Shengliang Guan 已提交
544
  if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
S
Shengliang Guan 已提交
545
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
546 547
    return -1;
  }
S
Shengliang Guan 已提交
548

S
Shengliang Guan 已提交
549
  SField *pField = taosArrayGet(pCreate->pColumns, 0);
S
Shengliang Guan 已提交
550
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
5
54liuyao 已提交
551
    terrno = TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
S
Shengliang Guan 已提交
552 553 554
    return -1;
  }

S
Shengliang Guan 已提交
555
  for (int32_t i = 0; i < pCreate->numOfColumns; ++i) {
556
    SField *pField1 = taosArrayGet(pCreate->pColumns, i);
S
Shengliang Guan 已提交
557
    if (pField1->type >= TSDB_DATA_TYPE_MAX) {
S
Shengliang Guan 已提交
558 559 560
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
561
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
562 563 564
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
565
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
566 567 568 569 570 571
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
  }

  for (int32_t i = 0; i < pCreate->numOfTags; ++i) {
572
    SField *pField1 = taosArrayGet(pCreate->pTags, i);
S
Shengliang Guan 已提交
573
    if (pField1->type >= TSDB_DATA_TYPE_MAX) {
S
Shengliang Guan 已提交
574
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
575 576
      return -1;
    }
577
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
578
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
579 580
      return -1;
    }
581
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
582
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
583 584 585
      return -1;
    }
  }
S
Shengliang Guan 已提交
586

S
Shengliang Guan 已提交
587 588 589
  return 0;
}

590
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
591 592
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
593 594 595 596
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
597 598 599 600 601
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1;

  return 0;
}

602
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
603 604
  SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
  if (pUndoRaw == NULL) return -1;
S
Shengliang Guan 已提交
605 606 607 608
  if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) {
    sdbFreeRaw(pUndoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
609 610 611 612 613
  if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

614
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
615 616
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
617 618 619 620
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
621 622 623 624 625
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

626
static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
627
  SSdb   *pSdb = pMnode->pSdb;
628
  SVgObj *pVgroup = NULL;
629
  void   *pIter = NULL;
S
Shengliang Guan 已提交
630
  int32_t contLen;
631 632 633 634

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
635
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
636 637 638 639
      sdbRelease(pSdb, pVgroup);
      continue;
    }

wmmhello's avatar
wmmhello 已提交
640
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, NULL, 0);
S
Shengliang Guan 已提交
641
    if (pReq == NULL) {
642 643 644 645
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
S
Shengliang Guan 已提交
646

647 648
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
649
    action.pCont = pReq;
S
Shengliang Guan 已提交
650
    action.contLen = contLen;
H
Hongze Cheng 已提交
651
    action.msgType = TDMT_VND_CREATE_STB;
S
Shengliang Guan 已提交
652
    action.acceptableCode = TSDB_CODE_TDB_STB_ALREADY_EXIST;
653
    action.retryCode = TSDB_CODE_TDB_STB_NOT_EXIST;
654
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
655
      taosMemoryFree(pReq);
656 657 658 659 660 661
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
662 663 664 665

  return 0;
}

666
static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
667
  SSdb   *pSdb = pMnode->pSdb;
668
  SVgObj *pVgroup = NULL;
669
  void   *pIter = NULL;
670 671 672 673

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
674
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
675 676 677 678
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
679
    int32_t contLen = 0;
S
Shengliang Guan 已提交
680
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
681
    if (pReq == NULL) {
682 683 684 685 686
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
687

688 689
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
690
    action.pCont = pReq;
S
Shengliang Guan 已提交
691
    action.contLen = contLen;
H
Hongze Cheng 已提交
692
    action.msgType = TDMT_VND_DROP_STB;
S
Shengliang Guan 已提交
693
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
694
    if (mndTransAppendUndoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
695
      taosMemoryFree(pReq);
696 697 698 699 700 701
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
702 703 704 705

  return 0;
}

S
sma  
Shengliang Guan 已提交
706
static SSchema *mndFindStbColumns(const SStbObj *pStb, const char *colName) {
C
Cary Xu 已提交
707
  for (int32_t col = 0; col < pStb->numOfColumns; ++col) {
S
sma  
Shengliang Guan 已提交
708
    SSchema *pSchema = &pStb->pColumns[col];
C
Cary Xu 已提交
709
    if (strncasecmp(pSchema->name, colName, TSDB_COL_NAME_LEN) == 0) {
S
sma  
Shengliang Guan 已提交
710 711 712 713 714 715
      return pSchema;
    }
  }
  return NULL;
}

716 717 718 719 720
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;
721 722
  pDst->uid =
      (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->suid : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
723
  pDst->dbUid = pDb->uid;
724 725
  pDst->tagVer = 1;
  pDst->colVer = 1;
S
Shengliang Guan 已提交
726
  pDst->smaVer = 1;
727
  pDst->nextColId = 1;
728 729 730 731
  pDst->maxdelay[0] = pCreate->delay1;
  pDst->maxdelay[1] = pCreate->delay2;
  pDst->watermark[0] = pCreate->watermark1;
  pDst->watermark[1] = pCreate->watermark2;
732 733 734
  pDst->ttl = pCreate->ttl;
  pDst->numOfColumns = pCreate->numOfColumns;
  pDst->numOfTags = pCreate->numOfTags;
S
Shengliang Guan 已提交
735
  pDst->numOfFuncs = pCreate->numOfFuncs;
736
  pDst->commentLen = pCreate->commentLen;
D
dapan1121 已提交
737 738
  pDst->pFuncs = pCreate->pFuncs;
  pCreate->pFuncs = NULL;
739

740
  if (pDst->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
741
    pDst->comment = taosMemoryCalloc(pDst->commentLen + 1, 1);
742
    if (pDst->comment == NULL) {
S
sma  
Shengliang Guan 已提交
743 744 745
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
746
    memcpy(pDst->comment, pCreate->pComment, pDst->commentLen + 1);
S
sma  
Shengliang Guan 已提交
747
  }
S
Shengliang Guan 已提交
748

749 750 751 752
  pDst->ast1Len = pCreate->ast1Len;
  if (pDst->ast1Len > 0) {
    pDst->pAst1 = taosMemoryCalloc(pDst->ast1Len, 1);
    if (pDst->pAst1 == NULL) {
753 754 755
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
756
    memcpy(pDst->pAst1, pCreate->pAst1, pDst->ast1Len);
757 758
  }

759 760 761 762
  pDst->ast2Len = pCreate->ast2Len;
  if (pDst->ast2Len > 0) {
    pDst->pAst2 = taosMemoryCalloc(pDst->ast2Len, 1);
    if (pDst->pAst2 == NULL) {
763 764 765
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
766
    memcpy(pDst->pAst2, pCreate->pAst2, pDst->ast2Len);
767 768
  }

769 770 771
  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 已提交
772 773 774
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
775

776
  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
S
Shengliang Guan 已提交
777
    SField  *pField = taosArrayGet(pCreate->pColumns, i);
778
    SSchema *pSchema = &pDst->pColumns[i];
S
Shengliang Guan 已提交
779 780
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
781
    pSchema->flags = pField->flags;
S
Shengliang Guan 已提交
782
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
783 784
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
785 786
  }

787
  for (int32_t i = 0; i < pDst->numOfTags; ++i) {
S
Shengliang Guan 已提交
788
    SField  *pField = taosArrayGet(pCreate->pTags, i);
789
    SSchema *pSchema = &pDst->pTags[i];
S
Shengliang Guan 已提交
790 791 792
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
793 794
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
795
  }
796 797 798
  return 0;
}

S
Shengliang Guan 已提交
799
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
800
  SStbObj stbObj = {0};
S
Shengliang 已提交
801
  int32_t code = -1;
802

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

806
  mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
807
  if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
808
  if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
809
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
810 811
  code = 0;

812
_OVER:
S
Shengliang Guan 已提交
813
  mndTransDrop(pTrans);
814
  mndStbActionDelete(pMnode->pSdb, &stbObj);
S
Shengliang Guan 已提交
815
  return code;
S
Shengliang Guan 已提交
816
}
S
Shengliang Guan 已提交
817

818
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
819
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
820 821 822 823 824 825 826
  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 已提交
827

S
Shengliang Guan 已提交
828
static int32_t mndProcessTtlTimer(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
829 830 831 832 833 834 835
  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 已提交
836

837 838
  mInfo("start to process ttl timer");

wmmhello's avatar
wmmhello 已提交
839 840 841 842
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
843
    SMsgHead *pHead = rpcMallocCont(contLen);
wmmhello's avatar
wmmhello 已提交
844
    if (pHead == NULL) {
S
Shengliang Guan 已提交
845
      sdbCancelFetch(pSdb, pVgroup);
wmmhello's avatar
wmmhello 已提交
846 847 848 849 850
      sdbRelease(pSdb, pVgroup);
      continue;
    }
    pHead->contLen = htonl(contLen);
    pHead->vgId = htonl(pVgroup->vgId);
S
Shengliang Guan 已提交
851
    tSerializeSVDropTtlTableReq((char *)pHead + sizeof(SMsgHead), contLen, &ttlReq);
wmmhello's avatar
wmmhello 已提交
852 853

    SRpcMsg rpcMsg = {.msgType = TDMT_VND_DROP_TTL_TABLE, .pCont = pHead, .contLen = contLen};
S
Shengliang Guan 已提交
854
    SEpSet  epSet = mndGetVgroupEpset(pMnode, pVgroup);
wmmhello's avatar
wmmhello 已提交
855
    int32_t code = tmsgSendReq(&epSet, &rpcMsg);
S
Shengliang Guan 已提交
856
    if (code != 0) {
S
Shengliang Guan 已提交
857
      mError("vgId:%d, failed to send drop ttl table request to vnode since 0x%x", pVgroup->vgId, code);
S
Shengliang Guan 已提交
858
    } else {
859
      mInfo("vgId:%d, send drop ttl table request to vnode, time:%d", pVgroup->vgId, ttlReq.timestamp);
wmmhello's avatar
wmmhello 已提交
860 861 862
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
863

wmmhello's avatar
wmmhello 已提交
864 865 866
  return 0;
}

wmmhello's avatar
wmmhello 已提交
867 868 869 870 871 872 873 874 875 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
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);
910
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
911
      pSchema->colId = pStb->pColumns[cIndex].colId;
912
    } else {
wmmhello's avatar
wmmhello 已提交
913 914 915 916 917 918 919 920 921 922 923
      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);
924
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
925
      pSchema->colId = pStb->pTags[cIndex].colId;
926
    } else {
wmmhello's avatar
wmmhello 已提交
927 928 929 930 931 932 933 934
      pSchema->colId = pDst->nextColId++;
    }
  }
  pDst->tagVer = createReq->tagVer;
  pDst->colVer = createReq->colVer;
  return TSDB_CODE_SUCCESS;
}

935
static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
936
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
937 938 939 940
  int32_t        code = -1;
  SStbObj       *pStb = NULL;
  SDbObj        *pDb = NULL;
  SMCreateStbReq createReq = {0};
941
  bool           isAlter = false;
S
Shengliang Guan 已提交
942

S
Shengliang Guan 已提交
943
  if (tDeserializeSMCreateStbReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
944
    terrno = TSDB_CODE_INVALID_MSG;
945
    goto _OVER;
S
Shengliang Guan 已提交
946
  }
S
Shengliang Guan 已提交
947

948
  mInfo("stb:%s, start to create", createReq.name);
S
Shengliang Guan 已提交
949 950
  if (mndCheckCreateStbReq(&createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
951
    goto _OVER;
S
Shengliang Guan 已提交
952
  }
S
Shengliang Guan 已提交
953

S
Shengliang Guan 已提交
954
  pStb = mndAcquireStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
955
  if (pStb != NULL) {
S
Shengliang Guan 已提交
956
    if (createReq.igExists) {
957
      if (createReq.source == TD_REQ_FROM_APP) {
958
        mInfo("stb:%s, already exist, ignore exist is set", createReq.name);
959 960 961 962 963 964 965 966
        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 已提交
967 968 969
        int32_t tagDelta = createReq.tagVer - pStb->tagVer;
        int32_t colDelta = createReq.colVer - pStb->colVer;
        int32_t verDelta = tagDelta + colDelta;
970 971 972 973 974 975 976
        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)) {
977
          isAlter = true;
978 979 980 981 982 983 984
          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 已提交
985 986
        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);
987 988 989
        terrno = TSDB_CODE_MND_INVALID_SCHEMA_VER;
        goto _OVER;
      }
S
Shengliang Guan 已提交
990 991
    } else {
      terrno = TSDB_CODE_MND_STB_ALREADY_EXIST;
992
      goto _OVER;
S
Shengliang Guan 已提交
993
    }
S
Shengliang Guan 已提交
994
  } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) {
995
    goto _OVER;
996
  } else if (createReq.source == TD_REQ_FROM_TAOX && (createReq.tagVer != 1 || createReq.colVer != 1)) {
997 998 999
    mInfo("stb:%s, alter table does not need to be done, because table is deleted", createReq.name);
    code = 0;
    goto _OVER;
S
Shengliang Guan 已提交
1000 1001
  }

S
Shengliang Guan 已提交
1002
  pDb = mndAcquireDbByStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
1003 1004
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
1005
    goto _OVER;
S
Shengliang Guan 已提交
1006 1007
  }

1008
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1009
    goto _OVER;
S
Shengliang Guan 已提交
1010 1011
  }

1012
  int32_t numOfStbs = -1;
S
Shengliang Guan 已提交
1013 1014 1015 1016
  if (mndGetNumOfStbs(pMnode, pDb->name, &numOfStbs) != 0) {
    goto _OVER;
  }

L
Liu Jicong 已提交
1017
  if (pDb->cfg.numOfStables == 1 && numOfStbs != 0) {
1018 1019 1020 1021
    terrno = TSDB_CODE_MND_SINGLE_STB_MODE_DB;
    goto _OVER;
  }

wafwerar's avatar
wafwerar 已提交
1022 1023 1024 1025 1026
  if ((terrno = grantCheck(TSDB_GRANT_STABLE)) < 0) {
    code = -1;
    goto _OVER;
  }

1027
  if (isAlter) {
1028
    bool    needRsp = false;
wmmhello's avatar
wmmhello 已提交
1029
    SStbObj pDst = {0};
wmmhello's avatar
wmmhello 已提交
1030 1031 1032
    if (mndBuildStbFromAlter(pStb, &pDst, &createReq) != 0) {
      taosMemoryFreeClear(pDst.pTags);
      taosMemoryFreeClear(pDst.pColumns);
wmmhello's avatar
wmmhello 已提交
1033 1034 1035 1036 1037 1038
      goto _OVER;
    }

    code = mndAlterStbImp(pMnode, pReq, pDb, &pDst, needRsp, NULL, 0);
    taosMemoryFreeClear(pDst.pTags);
    taosMemoryFreeClear(pDst.pColumns);
1039 1040 1041
  } else {
    code = mndCreateStb(pMnode, pReq, &createReq, pDb);
  }
S
Shengliang Guan 已提交
1042
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1043

1044
_OVER:
S
Shengliang Guan 已提交
1045
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1046
    mError("stb:%s, failed to create since %s", createReq.name, terrstr());
S
Shengliang Guan 已提交
1047 1048
  }

S
Shengliang Guan 已提交
1049 1050
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1051
  tFreeSMCreateStbReq(&createReq);
S
Shengliang Guan 已提交
1052 1053

  return code;
S
Shengliang Guan 已提交
1054 1055
}

S
Shengliang Guan 已提交
1056
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
S
Shengliang Guan 已提交
1057 1058
  if (pAlter->commentLen >= 0) return 0;
  if (pAlter->ttl != 0) return 0;
S
Shengliang 已提交
1059

S
Shengliang Guan 已提交
1060 1061 1062 1063
  if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }
S
Shengliang Guan 已提交
1064

S
Shengliang Guan 已提交
1065 1066 1067
  for (int32_t i = 0; i < pAlter->numOfFields; ++i) {
    SField *pField = taosArrayGet(pAlter->pFields, i);
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
1068 1069 1070
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
1071 1072 1073 1074 1075
  }

  return 0;
}

S
Shengliang Guan 已提交
1076
static int32_t mndAllocStbSchemas(const SStbObj *pOld, SStbObj *pNew) {
wafwerar's avatar
wafwerar 已提交
1077 1078
  pNew->pTags = taosMemoryCalloc(pNew->numOfTags, sizeof(SSchema));
  pNew->pColumns = taosMemoryCalloc(pNew->numOfColumns, sizeof(SSchema));
S
Shengliang Guan 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
  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 已提交
1089 1090
static int32_t mndUpdateStbCommentAndTTL(const SStbObj *pOld, SStbObj *pNew, char *pComment, int32_t commentLen,
                                         int32_t ttl) {
S
Shengliang 已提交
1091 1092
  if (commentLen > 0) {
    pNew->commentLen = commentLen;
wmmhello's avatar
wmmhello 已提交
1093
    pNew->comment = taosMemoryCalloc(1, commentLen + 1);
S
Shengliang 已提交
1094 1095 1096 1097
    if (pNew->comment == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
wmmhello's avatar
wmmhello 已提交
1098
    memcpy(pNew->comment, pComment, commentLen + 1);
1099
  } else if (commentLen == 0) {
wmmhello's avatar
wmmhello 已提交
1100
    pNew->commentLen = 0;
S
Shengliang Guan 已提交
1101
  } else {
S
Shengliang 已提交
1102
  }
wmmhello's avatar
wmmhello 已提交
1103

S
Shengliang 已提交
1104 1105 1106
  if (ttl >= 0) {
    pNew->ttl = ttl;
  }
S
Shengliang 已提交
1107 1108 1109 1110 1111 1112 1113

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

S
Shengliang Guan 已提交
1114
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
  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 已提交
1125 1126 1127 1128 1129
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1130
  for (int32_t i = 0; i < ntags; i++) {
S
Shengliang Guan 已提交
1131
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1132
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1133
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1134 1135 1136
      return -1;
    }

S
Shengliang 已提交
1137
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1138
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1139 1140 1141
      return -1;
    }

S
Shengliang Guan 已提交
1142 1143 1144 1145
    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 已提交
1146 1147
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1148

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

1152
  pNew->tagVer++;
S
Shengliang Guan 已提交
1153 1154 1155
  return 0;
}

1156
static int32_t mndCheckAlterColForTopic(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
1157 1158 1159 1160 1161 1162 1163
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SMqTopicObj *pTopic = NULL;
    pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
    if (pIter == NULL) break;

1164
    mInfo("topic:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, subType:%d sql:%s",
H
Hongze Cheng 已提交
1165
          pTopic->name, stbFullName, suid, colId, pTopic->subType, pTopic->sql);
1166 1167 1168 1169 1170 1171 1172 1173 1174 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) {
      ASSERT(0);
      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 已提交
1182 1183
      mInfo("topic:%s, check colId:%d tableId:%" PRId64 " ctbStbUid:%" PRId64, pTopic->name, pCol->colId, pCol->tableId,
            pTopic->ctbStbUid);
1184 1185

      if (pCol->tableId != suid && pTopic->ctbStbUid != suid) {
1186
        mInfo("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
1187 1188 1189 1190 1191
        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 已提交
1192 1193 1194
        nodesDestroyNode(pAst);
        nodesDestroyList(pNodeList);
        sdbRelease(pSdb, pTopic);
1195 1196
        return -1;
      }
1197
      mInfo("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
1198 1199 1200 1201 1202
    }

  NEXT:
    sdbRelease(pSdb, pTopic);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1203
    nodesDestroyList(pNodeList);
1204
  }
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 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) {
      ASSERT(0);
      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) {
1229
        mInfo("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
1230 1231 1232 1233 1234
        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 已提交
1235 1236 1237
        nodesDestroyNode(pAst);
        nodesDestroyList(pNodeList);
        sdbRelease(pSdb, pStream);
1238 1239
        return -1;
      }
1240
      mInfo("stream:%s, check colId:%d passed", pStream->name, pCol->colId);
1241 1242 1243 1244 1245
    }

  NEXT:
    sdbRelease(pSdb, pStream);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1246
    nodesDestroyList(pNodeList);
1247 1248 1249
  }
  return 0;
}
1250

1251 1252 1253
static int32_t mndCheckAlterColForTSma(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
1254 1255 1256 1257 1258
  while (1) {
    SSmaObj *pSma = NULL;
    pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
    if (pIter == NULL) break;

H
Hongze Cheng 已提交
1259 1260
    mInfo("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, sql:%s", pSma->name, stbFullName,
          suid, colId, pSma->sql);
1261 1262 1263 1264 1265

    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",
1266
             pSma->name, stbFullName, suid, colId);
1267 1268 1269 1270 1271 1272 1273 1274
      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;
1275
      mInfo("tsma:%s, check colId:%d tableId:%" PRId64, pSma->name, pCol->colId, pCol->tableId);
1276 1277

      if ((pCol->tableId != suid) && (pSma->stbUid != suid)) {
1278
        mInfo("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
1279
        goto NEXT;
1280 1281 1282 1283
      }
      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 已提交
1284 1285 1286
        nodesDestroyNode(pAst);
        nodesDestroyList(pNodeList);
        sdbRelease(pSdb, pSma);
1287 1288
        return -1;
      }
1289
      mInfo("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
1290 1291
    }

1292
  NEXT:
1293 1294
    sdbRelease(pSdb, pSma);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1295
    nodesDestroyList(pNodeList);
1296
  }
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
  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;
  }
1307

1308 1309 1310
  if (mndCheckAlterColForTSma(pMnode, stbFullName, suid, colId) < 0) {
    return -1;
  }
1311 1312 1313
  return 0;
}

1314
static int32_t mndDropSuperTableTag(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
S
Shengliang Guan 已提交
1315 1316 1317 1318 1319 1320
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1321
  col_id_t colId = pOld->pTags[tag].colId;
1322
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1323 1324 1325
    return -1;
  }

S
Shengliang Guan 已提交
1326 1327 1328 1329 1330
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1333
  pNew->tagVer++;
1334
  mInfo("stb:%s, start to drop tag %s", pNew->name, tagName);
S
Shengliang Guan 已提交
1335 1336 1337
  return 0;
}

1338
static int32_t mndAlterStbTagName(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
S
Shengliang Guan 已提交
1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349
  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 已提交
1350 1351 1352 1353 1354 1355
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1356
  col_id_t colId = pOld->pTags[tag].colId;
1357
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1358 1359 1360
    return -1;
  }

S
Shengliang Guan 已提交
1361
  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
S
Shengliang Guan 已提交
1362
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1363 1364 1365
    return -1;
  }

S
Shengliang Guan 已提交
1366 1367
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377
    return -1;
  }

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

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

1378
  pNew->tagVer++;
1379
  mInfo("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
S
Shengliang Guan 已提交
1380 1381 1382
  return 0;
}

1383
static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1384
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1385 1386 1387 1388 1389
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1390
  col_id_t colId = pOld->pTags[tag].colId;
1391
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1392 1393 1394
    return -1;
  }

S
Shengliang Guan 已提交
1395 1396 1397 1398 1399 1400
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pTag = pNew->pTags + tag;

S
Shengliang Guan 已提交
1401 1402 1403 1404 1405
  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 已提交
1406
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
1407 1408 1409 1410
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

S
Shengliang Guan 已提交
1411
  pTag->bytes = pField->bytes;
1412
  pNew->tagVer++;
S
Shengliang Guan 已提交
1413

1414
  mInfo("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1415 1416 1417
  return 0;
}

S
Shengliang Guan 已提交
1418
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ncols) {
S
Shengliang Guan 已提交
1419 1420 1421 1422 1423
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
1424 1425 1426 1427 1428
  pNew->numOfColumns = pNew->numOfColumns + ncols;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1429
  for (int32_t i = 0; i < ncols; i++) {
S
Shengliang Guan 已提交
1430
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1431
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1432
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1433 1434 1435
      return -1;
    }

S
Shengliang 已提交
1436
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1437
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1438 1439 1440
      return -1;
    }

S
Shengliang Guan 已提交
1441 1442 1443 1444
    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 已提交
1445 1446
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1447

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

1451
  pNew->colVer++;
S
Shengliang Guan 已提交
1452 1453 1454
  return 0;
}

1455
static int32_t mndDropSuperTableColumn(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *colName) {
S
Shengliang Guan 已提交
1456
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
S
Shengliang Guan 已提交
1457
  if (col < 0) {
S
Shengliang Guan 已提交
1458 1459 1460 1461
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
  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;
  }

1472
  col_id_t colId = pOld->pColumns[col].colId;
1473
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1474 1475 1476
    return -1;
  }

S
Shengliang Guan 已提交
1477 1478 1479 1480 1481
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1484
  pNew->colVer++;
1485
  mInfo("stb:%s, start to drop col %s", pNew->name, colName);
S
Shengliang Guan 已提交
1486 1487 1488
  return 0;
}

1489
static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1490
  int32_t col = mndFindSuperTableColumnIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1491 1492 1493 1494 1495 1496 1497
  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 已提交
1498
    nLen += (pOld->pColumns[i].colId == col) ? pField->bytes : pOld->pColumns[i].bytes;
S
Shengliang Guan 已提交
1499 1500 1501 1502 1503 1504 1505
  }

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

1506
  col_id_t colId = pOld->pColumns[col].colId;
1507
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1508 1509 1510
    return -1;
  }

S
Shengliang Guan 已提交
1511 1512 1513 1514 1515
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pCol = pNew->pColumns + col;
S
Shengliang Guan 已提交
1516 1517
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
1518 1519 1520
    return -1;
  }

S
Shengliang Guan 已提交
1521
  if (pField->bytes <= pCol->bytes) {
S
Shengliang Guan 已提交
1522
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
S
Shengliang Guan 已提交
1523 1524 1525
    return -1;
  }

S
Shengliang Guan 已提交
1526
  pCol->bytes = pField->bytes;
1527
  pNew->colVer++;
S
Shengliang Guan 已提交
1528

1529
  mInfo("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1530 1531 1532
  return 0;
}

S
Shengliang Guan 已提交
1533
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1534 1535
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1536 1537 1538 1539
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1540
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
S
Shengliang Guan 已提交
1541 1542 1543 1544

  return 0;
}

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

  return 0;
}

1557 1558
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb, void *alterOriData,
                                         int32_t alterOriDataLen) {
S
Shengliang Guan 已提交
1559 1560 1561 1562 1563 1564 1565 1566
  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 已提交
1567
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
1568 1569 1570 1571
      sdbRelease(pSdb, pVgroup);
      continue;
    }

wmmhello's avatar
wmmhello 已提交
1572
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, alterOriData, alterOriDataLen);
S
Shengliang Guan 已提交
1573 1574 1575 1576 1577 1578 1579 1580 1581
    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 已提交
1582
    action.msgType = TDMT_VND_ALTER_STB;
S
Shengliang Guan 已提交
1583
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
1584
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

D
dapan1121 已提交
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
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 已提交
1606 1607 1608
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
D
dapan1121 已提交
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
  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 已提交
1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
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 已提交
1652 1653 1654
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
D
dapan1121 已提交
1655 1656 1657
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->tableType = TSDB_SUPER_TABLE;
D
dapan1121 已提交
1658 1659 1660 1661
  pRsp->delay1 = pStb->maxdelay[0];
  pRsp->delay2 = pStb->maxdelay[1];
  pRsp->watermark1 = pStb->watermark[0];
  pRsp->watermark2 = pStb->watermark[1];
D
dapan1121 已提交
1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685
  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 已提交
1686
  if (pStb->numOfFuncs > 0) {
D
dapan1121 已提交
1687 1688
    pRsp->pFuncs = taosArrayDup(pStb->pFuncs);
  }
1689

D
dapan1121 已提交
1690 1691 1692 1693
  taosRUnLockLatch(&pStb->lock);
  return 0;
}

L
Liu Jicong 已提交
1694 1695
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp,
                                 int32_t *smaVer) {
D
dapan1121 已提交
1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
  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 已提交
1708
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
D
dapan1121 已提交
1709 1710 1711
    return -1;
  }

D
dapan1121 已提交
1712 1713 1714 1715
  if (smaVer) {
    *smaVer = pStb->smaVer;
  }

D
dapan1121 已提交
1716 1717 1718 1719 1720 1721
  int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}

D
dapan1121 已提交
1722
static int32_t mndBuildStbCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) {
1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737
  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 已提交
1738

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

1741 1742 1743 1744
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}
D
dapan1121 已提交
1745

1746
static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, SStbObj *pObj, void **pCont, int32_t *pLen) {
1747
  int32_t       ret;
D
dapan1121 已提交
1748
  SEncoder      ec = {0};
1749
  uint32_t      contLen = 0;
D
dapan1121 已提交
1750
  SMAlterStbRsp alterRsp = {0};
1751
  SName         name = {0};
1752
  tNameFromString(&name, pObj->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
D
dapan1121 已提交
1753 1754 1755 1756 1757 1758

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

D
dapan1121 已提交
1760
  ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
D
dapan1121 已提交
1761 1762 1763 1764
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }
1765

D
dapan1121 已提交
1766 1767 1768 1769 1770 1771
  tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }

1772
  void *cont = taosMemoryMalloc(contLen);
D
dapan1121 已提交
1773 1774 1775 1776 1777 1778 1779 1780
  tEncoderInit(&ec, cont, contLen);
  tEncodeSMAlterStbRsp(&ec, &alterRsp);
  tEncoderClear(&ec);

  tFreeSMAlterStbRsp(&alterRsp);

  *pCont = cont;
  *pLen = contLen;
1781

D
dapan1121 已提交
1782 1783 1784
  return 0;
}

L
Liu Jicong 已提交
1785 1786
int32_t mndBuildSMCreateStbRsp(SMnode *pMnode, char *dbFName, char *stbFName, void **pCont, int32_t *pLen) {
  int32_t ret = -1;
1787 1788 1789 1790 1791 1792 1793 1794 1795
  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
  if (NULL == pDb) {
    return -1;
  }

  SStbObj *pObj = mndAcquireStb(pMnode, stbFName);
  if (NULL == pObj) {
    goto _OVER;
  }
L
Liu Jicong 已提交
1796 1797 1798

  SEncoder       ec = {0};
  uint32_t       contLen = 0;
1799
  SMCreateStbRsp stbRsp = {0};
L
Liu Jicong 已提交
1800
  SName          name = {0};
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
  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 已提交
1832

1833 1834 1835 1836
_OVER:
  if (pObj) {
    mndReleaseStb(pMnode, pObj);
  }
L
Liu Jicong 已提交
1837

1838 1839 1840 1841 1842 1843 1844
  if (pDb) {
    mndReleaseDb(pMnode, pDb);
  }

  return ret;
}

1845 1846
static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
                              void *alterOriData, int32_t alterOriDataLen) {
1847
  int32_t code = -1;
1848
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "alter-stb");
1849 1850
  if (pTrans == NULL) goto _OVER;

1851
  mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
1852
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862

  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 已提交
1863
  if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen) != 0) goto _OVER;
1864 1865 1866 1867 1868 1869 1870 1871 1872
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;

  code = 0;

_OVER:
  mndTransDrop(pTrans);
  return code;
}

S
Shengliang Guan 已提交
1873
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
1874 1875 1876 1877
  bool    needRsp = true;
  int32_t code = -1;
  SField *pField0 = NULL;

S
Shengliang Guan 已提交
1878 1879 1880
  SStbObj stbObj = {0};
  taosRLockLatch(&pOld->lock);
  memcpy(&stbObj, pOld, sizeof(SStbObj));
1881
  taosRUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
1882 1883 1884
  stbObj.pColumns = NULL;
  stbObj.pTags = NULL;
  stbObj.updateTime = taosGetTimestampMs();
D
dapan1121 已提交
1885
  stbObj.lock = 0;
S
Shengliang Guan 已提交
1886

S
Shengliang Guan 已提交
1887
  switch (pAlter->alterType) {
S
Shengliang Guan 已提交
1888
    case TSDB_ALTER_TABLE_ADD_TAG:
S
Shengliang Guan 已提交
1889
      code = mndAddSuperTableTag(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1890
      break;
S
Shengliang Guan 已提交
1891
    case TSDB_ALTER_TABLE_DROP_TAG:
S
Shengliang 已提交
1892
      pField0 = taosArrayGet(pAlter->pFields, 0);
1893
      code = mndDropSuperTableTag(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1894
      break;
S
Shengliang Guan 已提交
1895
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
1896
      code = mndAlterStbTagName(pMnode, pOld, &stbObj, pAlter->pFields);
S
Shengliang Guan 已提交
1897
      break;
S
Shengliang Guan 已提交
1898
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
S
Shengliang 已提交
1899
      pField0 = taosArrayGet(pAlter->pFields, 0);
1900
      code = mndAlterStbTagBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1901 1902
      break;
    case TSDB_ALTER_TABLE_ADD_COLUMN:
S
Shengliang Guan 已提交
1903
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1904 1905
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
S
Shengliang 已提交
1906
      pField0 = taosArrayGet(pAlter->pFields, 0);
1907
      code = mndDropSuperTableColumn(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1908
      break;
S
Shengliang Guan 已提交
1909
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
S
Shengliang 已提交
1910
      pField0 = taosArrayGet(pAlter->pFields, 0);
1911
      code = mndAlterStbColumnBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1912
      break;
S
Shengliang 已提交
1913
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
D
dapan1121 已提交
1914
      needRsp = false;
S
Shengliang 已提交
1915
      code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
S
Shengliang 已提交
1916
      break;
S
Shengliang Guan 已提交
1917
    default:
D
dapan1121 已提交
1918
      needRsp = false;
S
Shengliang 已提交
1919
      terrno = TSDB_CODE_OPS_NOT_SUPPORT;
S
Shengliang Guan 已提交
1920 1921 1922
      break;
  }

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

1926
_OVER:
wafwerar's avatar
wafwerar 已提交
1927 1928
  taosMemoryFreeClear(stbObj.pTags);
  taosMemoryFreeClear(stbObj.pColumns);
1929 1930 1931
  if (pAlter->commentLen > 0) {
    taosMemoryFreeClear(stbObj.comment);
  }
S
Shengliang Guan 已提交
1932 1933
  return code;
}
S
Shengliang Guan 已提交
1934

1935
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
1936
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1937 1938 1939 1940
  int32_t       code = -1;
  SDbObj       *pDb = NULL;
  SStbObj      *pStb = NULL;
  SMAlterStbReq alterReq = {0};
S
Shengliang Guan 已提交
1941

S
Shengliang Guan 已提交
1942
  if (tDeserializeSMAlterStbReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
1943
    terrno = TSDB_CODE_INVALID_MSG;
1944
    goto _OVER;
S
Shengliang Guan 已提交
1945
  }
S
Shengliang Guan 已提交
1946

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

S
Shengliang Guan 已提交
1950
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1951 1952
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_INVALID_DB;
1953
    goto _OVER;
S
Shengliang Guan 已提交
1954 1955
  }

S
Shengliang Guan 已提交
1956
  pStb = mndAcquireStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1957 1958
  if (pStb == NULL) {
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
1959
    goto _OVER;
S
Shengliang Guan 已提交
1960
  }
S
Shengliang Guan 已提交
1961

1962
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1963
    goto _OVER;
S
Shengliang Guan 已提交
1964 1965
  }

S
Shengliang Guan 已提交
1966
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
S
Shengliang Guan 已提交
1967
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1968

1969
_OVER:
S
Shengliang Guan 已提交
1970
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1971
    mError("stb:%s, failed to alter since %s", alterReq.name, terrstr());
S
Shengliang Guan 已提交
1972 1973
  }

S
Shengliang Guan 已提交
1974 1975
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
1976
  tFreeSMAltertbReq(&alterReq);
S
Shengliang Guan 已提交
1977 1978

  return code;
S
Shengliang Guan 已提交
1979
}
S
Shengliang Guan 已提交
1980

S
Shengliang Guan 已提交
1981 1982 1983
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1984 1985 1986 1987
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1988 1989 1990 1991 1992 1993 1994 1995
  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 已提交
1996 1997 1998 1999
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
2000 2001 2002 2003 2004
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

S
Shengliang Guan 已提交
2005 2006 2007 2008
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 已提交
2009

S
Shengliang Guan 已提交
2010 2011 2012
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
2013
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
2014 2015 2016 2017
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
2018
    int32_t contLen = 0;
S
Shengliang Guan 已提交
2019
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
    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 已提交
2032
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
S
Shengliang Guan 已提交
2033
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
2034
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

S
Shengliang Guan 已提交
2045
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
2046
  int32_t code = -1;
2047
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "drop-stb");
2048
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
2049

2050
  mInfo("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
2051
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
S
Shengliang Guan 已提交
2052

2053 2054 2055
  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;
2056
  if (mndDropSmasByStb(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
2057
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
2058

S
Shengliang Guan 已提交
2059 2060
  code = 0;

2061
_OVER:
S
Shengliang Guan 已提交
2062
  mndTransDrop(pTrans);
S
Shengliang 已提交
2063
  return code;
S
Shengliang Guan 已提交
2064 2065
}

2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097
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) {
      ASSERT(0);
      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 已提交
2098
      if (pCol->tableId == suid) {
2099 2100
        sdbRelease(pSdb, pTopic);
        nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2101
        nodesDestroyList(pNodeList);
2102 2103 2104 2105 2106 2107 2108 2109
        return -1;
      } else {
        goto NEXT;
      }
    }
  NEXT:
    sdbRelease(pSdb, pTopic);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2110
    nodesDestroyList(pNodeList);
2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122
  }
  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 已提交
2123 2124 2125 2126 2127 2128
    if (pStream->smaId != 0) {
      sdbRelease(pSdb, pStream);
      continue;
    }

    if (pStream->targetStbUid == suid) {
L
Liu Jicong 已提交
2129 2130 2131 2132
      sdbRelease(pSdb, pStream);
      return -1;
    }

2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144
    SNode *pAst = NULL;
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
      ASSERT(0);
      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 已提交
2145
      if (pCol->tableId == suid) {
2146 2147
        sdbRelease(pSdb, pStream);
        nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2148
        nodesDestroyList(pNodeList);
2149 2150 2151 2152 2153 2154 2155 2156
        return -1;
      } else {
        goto NEXT;
      }
    }
  NEXT:
    sdbRelease(pSdb, pStream);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2157
    nodesDestroyList(pNodeList);
2158 2159 2160 2161
  }
  return 0;
}

2162
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
2163
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2164 2165 2166
  int32_t      code = -1;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
2167
  SMDropStbReq dropReq = {0};
S
Shengliang Guan 已提交
2168

S
Shengliang Guan 已提交
2169
  if (tDeserializeSMDropStbReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
2170
    terrno = TSDB_CODE_INVALID_MSG;
2171
    goto _OVER;
S
Shengliang Guan 已提交
2172
  }
S
Shengliang Guan 已提交
2173

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

S
Shengliang Guan 已提交
2176
  pStb = mndAcquireStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
2177
  if (pStb == NULL) {
S
Shengliang Guan 已提交
2178
    if (dropReq.igNotExists) {
2179
      mInfo("stb:%s, not exist, ignore not exist is set", dropReq.name);
S
Shengliang Guan 已提交
2180
      code = 0;
2181
      goto _OVER;
S
Shengliang Guan 已提交
2182 2183
    } else {
      terrno = TSDB_CODE_MND_STB_NOT_EXIST;
2184
      goto _OVER;
S
Shengliang Guan 已提交
2185 2186 2187
    }
  }

wmmhello's avatar
wmmhello 已提交
2188 2189
  if (dropReq.source == TD_REQ_FROM_TAOX && pStb->uid != dropReq.suid) {
    code = 0;
wmmhello's avatar
wmmhello 已提交
2190 2191 2192
    goto _OVER;
  }

S
Shengliang Guan 已提交
2193
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
2194 2195
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
2196
    goto _OVER;
S
Shengliang Guan 已提交
2197 2198
  }

2199
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
2200
    goto _OVER;
S
Shengliang Guan 已提交
2201 2202
  }

2203 2204 2205 2206 2207 2208 2209 2210 2211 2212
  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 已提交
2213
  code = mndDropStb(pMnode, pReq, pDb, pStb);
S
Shengliang Guan 已提交
2214
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
2215

2216
_OVER:
S
Shengliang Guan 已提交
2217
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
2218
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
2219 2220
  }

S
Shengliang Guan 已提交
2221 2222 2223
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
S
Shengliang Guan 已提交
2224
}
S
Shengliang Guan 已提交
2225

S
Shengliang Guan 已提交
2226 2227
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2228 2229 2230
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
2231

2232 2233 2234 2235
  SUserObj *pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
  if (pUser == NULL) return 0;
  bool sysinfo = pUser->sysInfo;

S
Shengliang Guan 已提交
2236
  if (tDeserializeSTableInfoReq(pReq->pCont, pReq->contLen, &infoReq) != 0) {
S
Shengliang Guan 已提交
2237
    terrno = TSDB_CODE_INVALID_MSG;
2238
    goto _OVER;
S
Shengliang Guan 已提交
2239
  }
D
dapan 已提交
2240

D
dapan1121 已提交
2241
  if (0 == strcmp(infoReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
2242
    mInfo("information_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
2243
    if (mndBuildInsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, sysinfo, &metaRsp) != 0) {
2244
      goto _OVER;
D
dapan1121 已提交
2245
    }
D
dapan1121 已提交
2246
  } else if (0 == strcmp(infoReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
2247
    mInfo("performance_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2248
    if (mndBuildPerfsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
2249
      goto _OVER;
D
dapan1121 已提交
2250
    }
D
dapan1121 已提交
2251
  } else {
2252
    mInfo("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2253
    if (mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp, NULL) != 0) {
2254
      goto _OVER;
D
dapan1121 已提交
2255
    }
S
Shengliang Guan 已提交
2256
  }
S
Shengliang Guan 已提交
2257

S
Shengliang Guan 已提交
2258 2259 2260
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
2261
    goto _OVER;
S
Shengliang Guan 已提交
2262
  }
S
Shengliang Guan 已提交
2263

S
Shengliang Guan 已提交
2264
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
2265 2266
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
2267
    goto _OVER;
S
Shengliang Guan 已提交
2268
  }
D
dapan 已提交
2269

S
Shengliang Guan 已提交
2270
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
S
Shengliang Guan 已提交
2271 2272
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = rspLen;
S
Shengliang Guan 已提交
2273
  code = 0;
S
Shengliang Guan 已提交
2274

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

2277
_OVER:
S
Shengliang Guan 已提交
2278 2279 2280
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
2281

2282
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
2283 2284 2285
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
2286

D
dapan1121 已提交
2287
static int32_t mndProcessTableCfgReq(SRpcMsg *pReq) {
2288 2289 2290 2291
  SMnode      *pMnode = pReq->info.node;
  int32_t      code = -1;
  STableCfgReq cfgReq = {0};
  STableCfgRsp cfgRsp = {0};
D
dapan1121 已提交
2292 2293 2294 2295 2296 2297 2298

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

  if (0 == strcmp(cfgReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
2299
    mInfo("information_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
D
dapan1121 已提交
2300 2301 2302 2303
    if (mndBuildInsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  } else if (0 == strcmp(cfgReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
2304
    mInfo("performance_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
D
dapan1121 已提交
2305 2306 2307 2308
    if (mndBuildPerfsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  } else {
2309
    mInfo("stb:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
D
dapan1121 已提交
2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342
    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 已提交
2343
int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t numOfStbs, void **ppRsp,
S
Shengliang Guan 已提交
2344
                           int32_t *pRspLen) {
D
dapan1121 已提交
2345
  SSTbHbRsp hbRsp = {0};
D
dapan1121 已提交
2346 2347
  hbRsp.pMetaRsp = taosArrayInit(numOfStbs, sizeof(STableMetaRsp));
  if (hbRsp.pMetaRsp == NULL) {
S
Shengliang Guan 已提交
2348 2349 2350
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
2351

D
dapan1121 已提交
2352
  hbRsp.pIndexRsp = taosArrayInit(numOfStbs, sizeof(STableIndexRsp));
D
dapan1121 已提交
2353
  if (NULL == hbRsp.pIndexRsp) {
D
dapan1121 已提交
2354
    taosArrayDestroy(hbRsp.pMetaRsp);
D
dapan1121 已提交
2355 2356 2357
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
L
Liu Jicong 已提交
2358

S
Shengliang Guan 已提交
2359
  for (int32_t i = 0; i < numOfStbs; ++i) {
D
dapan1121 已提交
2360
    SSTableVersion *pStbVersion = &pStbVersions[i];
S
Shengliang Guan 已提交
2361 2362 2363
    pStbVersion->suid = be64toh(pStbVersion->suid);
    pStbVersion->sversion = ntohs(pStbVersion->sversion);
    pStbVersion->tversion = ntohs(pStbVersion->tversion);
D
dapan1121 已提交
2364
    pStbVersion->smaVer = ntohl(pStbVersion->smaVer);
S
Shengliang Guan 已提交
2365

S
Shengliang Guan 已提交
2366
    STableMetaRsp metaRsp = {0};
L
Liu Jicong 已提交
2367
    int32_t       smaVer = 0;
2368
    mInfo("stb:%s.%s, start to retrieve meta", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2369
    if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
S
Shengliang Guan 已提交
2370 2371
      metaRsp.numOfColumns = -1;
      metaRsp.suid = pStbVersion->suid;
D
dapan1121 已提交
2372
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2373
      continue;
D
dapan 已提交
2374
    }
S
Shengliang Guan 已提交
2375

D
dapan1121 已提交
2376
    if (pStbVersion->sversion != metaRsp.sversion || pStbVersion->tversion != metaRsp.tversion) {
D
dapan1121 已提交
2377
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2378 2379
    } else {
      tFreeSTableMetaRsp(&metaRsp);
S
Shengliang Guan 已提交
2380
    }
D
dapan1121 已提交
2381

D
dapan1121 已提交
2382
    if (pStbVersion->smaVer && pStbVersion->smaVer != smaVer) {
L
Liu Jicong 已提交
2383 2384
      bool           exist = false;
      char           tbFName[TSDB_TABLE_FNAME_LEN];
D
dapan1121 已提交
2385
      STableIndexRsp indexRsp = {0};
D
dapan1121 已提交
2386 2387 2388 2389 2390
      indexRsp.pIndex = taosArrayInit(10, sizeof(STableIndexInfo));
      if (NULL == indexRsp.pIndex) {
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        return -1;
      }
L
Liu Jicong 已提交
2391

D
dapan1121 已提交
2392
      sprintf(tbFName, "%s.%s", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2393
      int32_t code = mndGetTableSma(pMnode, tbFName, &indexRsp, &exist);
D
dapan1121 已提交
2394
      if (code || !exist) {
D
dapan1121 已提交
2395 2396 2397
        indexRsp.suid = pStbVersion->suid;
        indexRsp.version = -1;
        indexRsp.pIndex = NULL;
D
dapan1121 已提交
2398
      }
D
dapan1121 已提交
2399

D
dapan1121 已提交
2400 2401
      strcpy(indexRsp.dbFName, pStbVersion->dbFName);
      strcpy(indexRsp.tbName, pStbVersion->stbName);
D
dapan1121 已提交
2402 2403

      taosArrayPush(hbRsp.pIndexRsp, &indexRsp);
D
dapan1121 已提交
2404
    }
S
Shengliang Guan 已提交
2405
  }
S
Shengliang Guan 已提交
2406

D
dapan1121 已提交
2407
  int32_t rspLen = tSerializeSSTbHbRsp(NULL, 0, &hbRsp);
S
Shengliang Guan 已提交
2408
  if (rspLen < 0) {
D
dapan1121 已提交
2409
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2410 2411
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
2412 2413
  }

wafwerar's avatar
wafwerar 已提交
2414
  void *pRsp = taosMemoryMalloc(rspLen);
S
Shengliang Guan 已提交
2415
  if (pRsp == NULL) {
D
dapan1121 已提交
2416
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2417 2418
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
2419 2420
  }

D
dapan1121 已提交
2421 2422
  tSerializeSSTbHbRsp(pRsp, rspLen, &hbRsp);
  tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2423 2424
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
2425 2426 2427
  return 0;
}

2428
int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
2429
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2430 2431 2432 2433 2434 2435
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
2436
  int32_t numOfStbs = 0;
2437
  void   *pIter = NULL;
S
Shengliang Guan 已提交
2438
  while (1) {
S
Shengliang Guan 已提交
2439
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
2440
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2441 2442
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
2443
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
2444
      numOfStbs++;
S
Shengliang Guan 已提交
2445 2446
    }

S
Shengliang Guan 已提交
2447
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2448 2449
  }

S
Shengliang Guan 已提交
2450
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
2451
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
2452 2453 2454
  return 0;
}

L
Liu Jicong 已提交
2455 2456 2457 2458 2459 2460 2461 2462
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 已提交
2463 2464
  int32_t pos = -1;
  int32_t num = 0;
L
Liu Jicong 已提交
2465 2466
  for (pos = 0; stbFullName[pos] != 0; ++pos) {
    if (stbFullName[pos] == TS_PATH_DELIMITER[0]) num++;
S
Shengliang Guan 已提交
2467 2468 2469 2470
    if (num == 2) break;
  }

  if (num == 2) {
L
Liu Jicong 已提交
2471
    tstrncpy(dst, stbFullName + pos + 1, dstSize);
S
Shengliang Guan 已提交
2472 2473 2474
  }
}

S
Shengliang Guan 已提交
2475 2476
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode  *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2477
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2478 2479 2480
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
2481

H
Hongze Cheng 已提交
2482
  SDbObj *pDb = NULL;
H
Haojun Liao 已提交
2483 2484
  if (strlen(pShow->db) > 0) {
    pDb = mndAcquireDb(pMnode, pShow->db);
D
dapan1121 已提交
2485
    if (pDb == NULL) return terrno;
H
Haojun Liao 已提交
2486
  }
S
Shengliang Guan 已提交
2487

S
Shengliang Guan 已提交
2488
  while (numOfRows < rows) {
S
Shengliang Guan 已提交
2489
    pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2490 2491
    if (pShow->pIter == NULL) break;

H
Haojun Liao 已提交
2492
    if (pDb != NULL && pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
2493
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2494 2495 2496 2497 2498
      continue;
    }

    cols = 0;

H
Haojun Liao 已提交
2499
    SName name = {0};
H
Hongze Cheng 已提交
2500
    char  stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
L
Liu Jicong 已提交
2501
    mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
2502
    varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
S
Shengliang Guan 已提交
2503

H
Hongze Cheng 已提交
2504 2505
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
    colDataAppend(pColInfo, numOfRows, (const char *)stbName, false);
2506

H
Hongze Cheng 已提交
2507 2508
    char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
2509 2510 2511
    tNameGetDbName(&name, varDataVal(db));
    varDataSetLen(db, strlen(varDataVal(db)));

2512
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
H
Hongze Cheng 已提交
2513
    colDataAppend(pColInfo, numOfRows, (const char *)db, false);
2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526

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

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

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

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

2527
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
wmmhello's avatar
wmmhello 已提交
2528 2529 2530 2531
    if (pStb->commentLen > 0) {
      char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
      STR_TO_VARSTR(comment, pStb->comment);
      colDataAppend(pColInfo, numOfRows, comment, false);
2532
    } else if (pStb->commentLen == 0) {
wmmhello's avatar
wmmhello 已提交
2533 2534 2535 2536 2537
      char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
      STR_TO_VARSTR(comment, "");
      colDataAppend(pColInfo, numOfRows, comment, false);
    } else {
      colDataAppendNULL(pColInfo, numOfRows);
S
Shengliang Guan 已提交
2538
    }
H
Haojun Liao 已提交
2539

2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553
    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++);
    colDataAppend(pColInfo, numOfRows, (const char *)watermark, false);

    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++);
    colDataAppend(pColInfo, numOfRows, (const char *)maxDelay, false);

S
Shengliang Guan 已提交
2554
    char    rollup[160 + VARSTR_HEADER_SIZE] = {0};
2555
    int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
D
dapan1121 已提交
2556 2557
    char   *sep = ", ";
    int32_t sepLen = strlen(sep);
D
dapan1121 已提交
2558
    int32_t rollupLen = sizeof(rollup) - VARSTR_HEADER_SIZE - 2;
2559 2560 2561
    for (int32_t i = 0; i < rollupNum; ++i) {
      char *funcName = taosArrayGet(pStb->pFuncs, i);
      if (i) {
D
dapan1121 已提交
2562 2563
        strncat(varDataVal(rollup), sep, rollupLen);
        rollupLen -= sepLen;
2564
      }
D
dapan1121 已提交
2565 2566
      strncat(varDataVal(rollup), funcName, rollupLen);
      rollupLen -= strlen(funcName);
2567 2568 2569 2570 2571 2572
    }
    varDataSetLen(rollup, strlen(varDataVal(rollup)));

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

S
Shengliang Guan 已提交
2573
    numOfRows++;
S
Shengliang Guan 已提交
2574
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2575 2576
  }

H
Haojun Liao 已提交
2577 2578 2579 2580
  if (pDb != NULL) {
    mndReleaseDb(pMnode, pDb);
  }

2581
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
2582 2583 2584
  return numOfRows;
}

S
Shengliang Guan 已提交
2585
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
2586 2587
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan1121 已提交
2588
}
S
Shengliang Guan 已提交
2589 2590 2591 2592 2593 2594 2595 2596 2597 2598

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 已提交
2599
}