mndStb.c 72.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;
}

S
Shengliang Guan 已提交
269
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
270
  mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
S
Shengliang Guan 已提交
271 272 273
  return 0;
}

S
Shengliang Guan 已提交
274
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
275
  mTrace("stb:%s, perform delete action, row:%p", pStb->name, pStb);
276
  taosArrayDestroy(pStb->pFuncs);
wafwerar's avatar
wafwerar 已提交
277 278 279
  taosMemoryFreeClear(pStb->pColumns);
  taosMemoryFreeClear(pStb->pTags);
  taosMemoryFreeClear(pStb->comment);
280 281
  taosMemoryFreeClear(pStb->pAst1);
  taosMemoryFreeClear(pStb->pAst2);
S
Shengliang Guan 已提交
282 283 284
  return 0;
}

S
Shengliang Guan 已提交
285 286
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 已提交
287

S
Shengliang Guan 已提交
288
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
289 290

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

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

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

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

S
Shengliang Guan 已提交
390
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
S
Shengliang Guan 已提交
391 392 393 394
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pStb);
}

395
SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
S
Shengliang Guan 已提交
396 397
  SName name = {0};
  tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
S
Shengliang Guan 已提交
398

S
Shengliang Guan 已提交
399 400
  char db[TSDB_TABLE_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, db);
S
Shengliang Guan 已提交
401

S
Shengliang Guan 已提交
402 403
  return mndAcquireDb(pMnode, db);
}
S
Shengliang Guan 已提交
404

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

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

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

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

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

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

wafwerar's avatar
wafwerar 已提交
463
  SMsgHead *pHead = taosMemoryMalloc(contLen);
S
Shengliang Guan 已提交
464
  if (pHead == NULL) {
H
more  
Hongze Cheng 已提交
465
    terrno = TSDB_CODE_OUT_OF_MEMORY;
466
    goto _err;
H
more  
Hongze Cheng 已提交
467 468
  }

S
Shengliang Guan 已提交
469 470
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);
H
more  
Hongze Cheng 已提交
471

S
Shengliang Guan 已提交
472
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
H
Hongze Cheng 已提交
473 474
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  if (tEncodeSVCreateStbReq(&encoder, &req) < 0) {
475 476
    taosMemoryFreeClear(pHead);
    tEncoderClear(&encoder);
477
    goto _err;
H
Hongze Cheng 已提交
478
  }
H
Hongze Cheng 已提交
479
  tEncoderClear(&encoder);
H
more  
Hongze Cheng 已提交
480

S
Shengliang Guan 已提交
481
  *pContLen = contLen;
C
Cary Xu 已提交
482 483
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
S
Shengliang Guan 已提交
484
  return pHead;
485
_err:
C
Cary Xu 已提交
486 487
  taosMemoryFreeClear(req.rsmaParam.qmsg[0]);
  taosMemoryFreeClear(req.rsmaParam.qmsg[1]);
488
  return NULL;
489 490
}

S
Shengliang Guan 已提交
491
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
H
Hongze Cheng 已提交
492 493 494 495 496
  SName        name = {0};
  SVDropStbReq req = {0};
  int32_t      contLen = 0;
  int32_t      ret = 0;
  SMsgHead    *pHead = NULL;
H
Hongze Cheng 已提交
497
  SEncoder     encoder = {0};
H
Hongze Cheng 已提交
498

S
Shengliang Guan 已提交
499 500 501 502
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

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

H
Hongze Cheng 已提交
504 505 506 507 508
  tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
  if (ret < 0) return NULL;

  contLen += sizeof(SMsgHead);
  pHead = taosMemoryMalloc(contLen);
S
Shengliang Guan 已提交
509
  if (pHead == NULL) {
510 511 512 513
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
514 515 516 517
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);

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

H
Hongze Cheng 已提交
519 520 521
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  tEncodeSVDropStbReq(&encoder, &req);
  tEncoderClear(&encoder);
522

S
Shengliang Guan 已提交
523 524
  *pContLen = contLen;
  return pHead;
525 526
}

527
int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
S
Shengliang Guan 已提交
528
  if (pCreate->igExists < 0 || pCreate->igExists > 1) {
S
Shengliang Guan 已提交
529
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
530 531
    return -1;
  }
S
Shengliang Guan 已提交
532

S
Shengliang Guan 已提交
533
  if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
S
Shengliang Guan 已提交
534
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
535 536
    return -1;
  }
S
Shengliang Guan 已提交
537

S
Shengliang Guan 已提交
538
  if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
S
Shengliang Guan 已提交
539
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
540 541
    return -1;
  }
S
Shengliang Guan 已提交
542

S
Shengliang Guan 已提交
543
  SField *pField = taosArrayGet(pCreate->pColumns, 0);
S
Shengliang Guan 已提交
544
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
S
Shengliang Guan 已提交
545 546 547 548
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }

S
Shengliang Guan 已提交
549
  for (int32_t i = 0; i < pCreate->numOfColumns; ++i) {
550
    SField *pField1 = taosArrayGet(pCreate->pColumns, i);
S
Shengliang Guan 已提交
551
    if (pField1->type < 0) {
S
Shengliang Guan 已提交
552 553 554
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
555
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
556 557 558
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
559
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
560 561 562 563 564 565
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
  }

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

S
Shengliang Guan 已提交
581 582 583
  return 0;
}

584
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
585 586
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
587 588 589 590
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
591 592 593 594 595
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1;

  return 0;
}

596
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
597 598
  SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
  if (pUndoRaw == NULL) return -1;
S
Shengliang Guan 已提交
599 600 601 602
  if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) {
    sdbFreeRaw(pUndoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
603 604 605 606 607
  if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

608
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
609 610
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
611 612 613 614
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
615 616 617 618 619
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

620
static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
621
  SSdb   *pSdb = pMnode->pSdb;
622
  SVgObj *pVgroup = NULL;
623
  void   *pIter = NULL;
S
Shengliang Guan 已提交
624
  int32_t contLen;
625 626 627 628

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
629
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
630 631 632 633
      sdbRelease(pSdb, pVgroup);
      continue;
    }

wmmhello's avatar
wmmhello 已提交
634
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, NULL, 0);
S
Shengliang Guan 已提交
635
    if (pReq == NULL) {
636 637 638 639
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
S
Shengliang Guan 已提交
640

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

  return 0;
}

660
static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
661
  SSdb   *pSdb = pMnode->pSdb;
662
  SVgObj *pVgroup = NULL;
663
  void   *pIter = NULL;
664 665 666 667

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
668
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
669 670 671 672
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
673
    int32_t contLen = 0;
S
Shengliang Guan 已提交
674
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
675
    if (pReq == NULL) {
676 677 678 679 680
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
681

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

  return 0;
}

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

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

734
  if (pDst->commentLen > 0) {
wmmhello's avatar
wmmhello 已提交
735
    pDst->comment = taosMemoryCalloc(pDst->commentLen + 1, 1);
736
    if (pDst->comment == NULL) {
S
sma  
Shengliang Guan 已提交
737 738 739
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
740
    memcpy(pDst->comment, pCreate->pComment, pDst->commentLen + 1);
S
sma  
Shengliang Guan 已提交
741
  }
S
Shengliang Guan 已提交
742

743 744 745 746
  pDst->ast1Len = pCreate->ast1Len;
  if (pDst->ast1Len > 0) {
    pDst->pAst1 = taosMemoryCalloc(pDst->ast1Len, 1);
    if (pDst->pAst1 == NULL) {
747 748 749
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
750
    memcpy(pDst->pAst1, pCreate->pAst1, pDst->ast1Len);
751 752
  }

753 754 755 756
  pDst->ast2Len = pCreate->ast2Len;
  if (pDst->ast2Len > 0) {
    pDst->pAst2 = taosMemoryCalloc(pDst->ast2Len, 1);
    if (pDst->pAst2 == NULL) {
757 758 759
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
760
    memcpy(pDst->pAst2, pCreate->pAst2, pDst->ast2Len);
761 762
  }

763 764 765
  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 已提交
766 767 768
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
769

770
  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
S
Shengliang Guan 已提交
771
    SField  *pField = taosArrayGet(pCreate->pColumns, i);
772
    SSchema *pSchema = &pDst->pColumns[i];
S
Shengliang Guan 已提交
773 774
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
775
    pSchema->flags = pField->flags;
S
Shengliang Guan 已提交
776
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
777 778
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
779 780
  }

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

S
Shengliang Guan 已提交
793
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
794
  SStbObj stbObj = {0};
S
Shengliang 已提交
795
  int32_t code = -1;
796

797
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
798
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
799

S
Shengliang Guan 已提交
800
  mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
801
  if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
802
  if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
803
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
804 805
  code = 0;

806
_OVER:
S
Shengliang Guan 已提交
807
  mndTransDrop(pTrans);
808
  mndStbActionDelete(pMnode->pSdb, &stbObj);
S
Shengliang Guan 已提交
809
  return code;
S
Shengliang Guan 已提交
810
}
S
Shengliang Guan 已提交
811

812
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
813
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
814 815 816 817 818 819 820
  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 已提交
821

S
Shengliang Guan 已提交
822
static int32_t mndProcessTtlTimer(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
823 824 825 826 827 828 829
  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 已提交
830 831 832 833 834

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
835
    SMsgHead *pHead = rpcMallocCont(contLen);
wmmhello's avatar
wmmhello 已提交
836
    if (pHead == NULL) {
S
Shengliang Guan 已提交
837
      sdbCancelFetch(pSdb, pVgroup);
wmmhello's avatar
wmmhello 已提交
838 839 840 841 842
      sdbRelease(pSdb, pVgroup);
      continue;
    }
    pHead->contLen = htonl(contLen);
    pHead->vgId = htonl(pVgroup->vgId);
S
Shengliang Guan 已提交
843
    tSerializeSVDropTtlTableReq((char *)pHead + sizeof(SMsgHead), contLen, &ttlReq);
wmmhello's avatar
wmmhello 已提交
844 845

    SRpcMsg rpcMsg = {.msgType = TDMT_VND_DROP_TTL_TABLE, .pCont = pHead, .contLen = contLen};
S
Shengliang Guan 已提交
846
    SEpSet  epSet = mndGetVgroupEpset(pMnode, pVgroup);
wmmhello's avatar
wmmhello 已提交
847
    int32_t code = tmsgSendReq(&epSet, &rpcMsg);
S
Shengliang Guan 已提交
848
    if (code != 0) {
S
Shengliang Guan 已提交
849
      mError("vgId:%d, failed to send drop ttl table request to vnode since 0x%x", pVgroup->vgId, code);
S
Shengliang Guan 已提交
850
    } else {
S
Shengliang Guan 已提交
851
      mDebug("vgId:%d, send drop ttl table request to vnode, time:%d", pVgroup->vgId, ttlReq.timestamp);
wmmhello's avatar
wmmhello 已提交
852 853 854
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
855

wmmhello's avatar
wmmhello 已提交
856 857 858
  return 0;
}

wmmhello's avatar
wmmhello 已提交
859 860 861 862 863 864 865 866 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
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);
902
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
903
      pSchema->colId = pStb->pColumns[cIndex].colId;
904
    } else {
wmmhello's avatar
wmmhello 已提交
905 906 907 908 909 910 911 912 913 914 915
      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);
916
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
917
      pSchema->colId = pStb->pTags[cIndex].colId;
918
    } else {
wmmhello's avatar
wmmhello 已提交
919 920 921 922 923 924 925 926
      pSchema->colId = pDst->nextColId++;
    }
  }
  pDst->tagVer = createReq->tagVer;
  pDst->colVer = createReq->colVer;
  return TSDB_CODE_SUCCESS;
}

927
static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
928
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
929 930 931 932
  int32_t        code = -1;
  SStbObj       *pStb = NULL;
  SDbObj        *pDb = NULL;
  SMCreateStbReq createReq = {0};
933
  bool           isAlter = false;
S
Shengliang Guan 已提交
934

S
Shengliang Guan 已提交
935
  if (tDeserializeSMCreateStbReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
936
    terrno = TSDB_CODE_INVALID_MSG;
937
    goto _OVER;
S
Shengliang Guan 已提交
938
  }
S
Shengliang Guan 已提交
939

S
Shengliang Guan 已提交
940
  mDebug("stb:%s, start to create", createReq.name);
S
Shengliang Guan 已提交
941 942
  if (mndCheckCreateStbReq(&createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
943
    goto _OVER;
S
Shengliang Guan 已提交
944
  }
S
Shengliang Guan 已提交
945

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

S
Shengliang Guan 已提交
994
  pDb = mndAcquireDbByStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
995 996
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
997
    goto _OVER;
S
Shengliang Guan 已提交
998 999
  }

1000
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1001
    goto _OVER;
S
Shengliang Guan 已提交
1002 1003
  }

1004
  int32_t numOfStbs = -1;
S
Shengliang Guan 已提交
1005 1006 1007 1008
  if (mndGetNumOfStbs(pMnode, pDb->name, &numOfStbs) != 0) {
    goto _OVER;
  }

L
Liu Jicong 已提交
1009
  if (pDb->cfg.numOfStables == 1 && numOfStbs != 0) {
1010 1011 1012 1013
    terrno = TSDB_CODE_MND_SINGLE_STB_MODE_DB;
    goto _OVER;
  }

wafwerar's avatar
wafwerar 已提交
1014 1015 1016 1017 1018
  if ((terrno = grantCheck(TSDB_GRANT_STABLE)) < 0) {
    code = -1;
    goto _OVER;
  }

1019
  if (isAlter) {
1020
    bool    needRsp = false;
wmmhello's avatar
wmmhello 已提交
1021
    SStbObj pDst = {0};
wmmhello's avatar
wmmhello 已提交
1022 1023 1024
    if (mndBuildStbFromAlter(pStb, &pDst, &createReq) != 0) {
      taosMemoryFreeClear(pDst.pTags);
      taosMemoryFreeClear(pDst.pColumns);
wmmhello's avatar
wmmhello 已提交
1025 1026 1027 1028 1029 1030
      goto _OVER;
    }

    code = mndAlterStbImp(pMnode, pReq, pDb, &pDst, needRsp, NULL, 0);
    taosMemoryFreeClear(pDst.pTags);
    taosMemoryFreeClear(pDst.pColumns);
1031 1032 1033
  } else {
    code = mndCreateStb(pMnode, pReq, &createReq, pDb);
  }
S
Shengliang Guan 已提交
1034
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1035

1036
_OVER:
S
Shengliang Guan 已提交
1037
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1038
    mError("stb:%s, failed to create since %s", createReq.name, terrstr());
S
Shengliang Guan 已提交
1039 1040
  }

S
Shengliang Guan 已提交
1041 1042
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1043
  tFreeSMCreateStbReq(&createReq);
S
Shengliang Guan 已提交
1044 1045

  return code;
S
Shengliang Guan 已提交
1046 1047
}

S
Shengliang Guan 已提交
1048
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
S
Shengliang Guan 已提交
1049 1050
  if (pAlter->commentLen >= 0) return 0;
  if (pAlter->ttl != 0) return 0;
S
Shengliang 已提交
1051

S
Shengliang Guan 已提交
1052 1053 1054 1055
  if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }
S
Shengliang Guan 已提交
1056

S
Shengliang Guan 已提交
1057 1058 1059
  for (int32_t i = 0; i < pAlter->numOfFields; ++i) {
    SField *pField = taosArrayGet(pAlter->pFields, i);
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
1060 1061 1062
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
1063 1064 1065 1066 1067
  }

  return 0;
}

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

S
Shengliang 已提交
1096 1097 1098
  if (ttl >= 0) {
    pNew->ttl = ttl;
  }
S
Shengliang 已提交
1099 1100 1101 1102 1103 1104 1105

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

S
Shengliang Guan 已提交
1106
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
  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 已提交
1117 1118 1119 1120 1121
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1122
  for (int32_t i = 0; i < ntags; i++) {
S
Shengliang Guan 已提交
1123
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1124
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1125
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1126 1127 1128
      return -1;
    }

S
Shengliang 已提交
1129
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1130
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1131 1132 1133
      return -1;
    }

S
Shengliang Guan 已提交
1134 1135 1136 1137
    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 已提交
1138 1139
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1140 1141

    mDebug("stb:%s, start to add tag %s", pNew->name, pSchema->name);
S
Shengliang Guan 已提交
1142 1143
  }

1144
  pNew->tagVer++;
S
Shengliang Guan 已提交
1145 1146 1147
  return 0;
}

1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 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 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
int32_t mndCheckColAndTagModifiable(SMnode *pMnode, const char *stbname, int64_t suid, col_id_t colId) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
  while (1) {
    SMqTopicObj *pTopic = NULL;
    pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
    if (pIter == NULL) break;

    mDebug("topic:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, subType:%d sql:%s",
           pTopic->name, stbname, suid, colId, pTopic->subType, pTopic->sql);
    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;
      mDebug("topic:%s, check colId:%d tableId:%" PRId64 " ctbStbUid:%" PRId64, pTopic->name, pCol->colId,
             pCol->tableId, pTopic->ctbStbUid);

      if (pCol->tableId != suid && pTopic->ctbStbUid != suid) {
        mDebug("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
        goto NEXT;
      }
      if (pCol->colId > 0 && pCol->colId == colId) {
        sdbRelease(pSdb, pTopic);
        nodesDestroyNode(pAst);
        terrno = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TOPIC;
        mError("topic:%s, check colId:%d conflicted", pTopic->name, pCol->colId);
        return -1;
      }
      mDebug("topic:%s, check colId:%d passed", pTopic->name, pCol->colId);
    }

  NEXT:
    sdbRelease(pSdb, pTopic);
    nodesDestroyNode(pAst);
  }

  while (1) {
    SSmaObj *pSma = NULL;
    pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
    if (pIter == NULL) break;

    mDebug("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, sql:%s", pSma->name, stbname,
           suid, colId, pSma->sql);

    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",
             pSma->name, stbname, suid, colId);
      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;
      mDebug("tsma:%s, check colId:%d tableId:%" PRId64, pSma->name, pCol->colId, pCol->tableId);

      if ((pCol->tableId != suid) && (pSma->stbUid != suid)) {
        mDebug("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
        goto NEXT2;
      }
      if ((pCol->colId) > 0 && (pCol->colId == colId)) {
        sdbRelease(pSdb, pSma);
        nodesDestroyNode(pAst);
        terrno = TSDB_CODE_MND_FIELD_CONFLICT_WITH_TSMA;
        mError("tsma:%s, check colId:%d conflicted", pSma->name, pCol->colId);
        return -1;
      }
      mDebug("tsma:%s, check colId:%d passed", pSma->name, pCol->colId);
    }

  NEXT2:
    sdbRelease(pSdb, pSma);
    nodesDestroyNode(pAst);
  }

  return 0;
}

1241
static int32_t mndDropSuperTableTag(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
S
Shengliang Guan 已提交
1242 1243 1244 1245 1246 1247
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1248
  col_id_t colId = pOld->pTags[tag].colId;
1249
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1250 1251 1252
    return -1;
  }

S
Shengliang Guan 已提交
1253 1254 1255 1256 1257
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1260
  pNew->tagVer++;
S
Shengliang Guan 已提交
1261 1262 1263 1264
  mDebug("stb:%s, start to drop tag %s", pNew->name, tagName);
  return 0;
}

1265
static int32_t mndAlterStbTagName(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
S
Shengliang Guan 已提交
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
  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 已提交
1277 1278 1279 1280 1281 1282
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1283
  col_id_t colId = pOld->pTags[tag].colId;
1284
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1285 1286 1287
    return -1;
  }

S
Shengliang Guan 已提交
1288
  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
S
Shengliang Guan 已提交
1289
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1290 1291 1292
    return -1;
  }

S
Shengliang Guan 已提交
1293 1294
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
    return -1;
  }

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

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

1305
  pNew->tagVer++;
S
Shengliang Guan 已提交
1306 1307 1308 1309
  mDebug("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
  return 0;
}

1310
static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1311
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1312 1313 1314 1315 1316
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1317
  col_id_t colId = pOld->pTags[tag].colId;
1318
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1319 1320 1321
    return -1;
  }

S
Shengliang Guan 已提交
1322 1323 1324 1325 1326 1327
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pTag = pNew->pTags + tag;

S
Shengliang Guan 已提交
1328 1329 1330 1331 1332
  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 已提交
1333
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
1334 1335 1336 1337
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

S
Shengliang Guan 已提交
1338
  pTag->bytes = pField->bytes;
1339
  pNew->tagVer++;
S
Shengliang Guan 已提交
1340

S
Shengliang Guan 已提交
1341
  mDebug("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1342 1343 1344
  return 0;
}

S
Shengliang Guan 已提交
1345
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ncols) {
S
Shengliang Guan 已提交
1346 1347 1348 1349 1350
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
1351 1352 1353 1354 1355
  pNew->numOfColumns = pNew->numOfColumns + ncols;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1356
  for (int32_t i = 0; i < ncols; i++) {
S
Shengliang Guan 已提交
1357
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1358
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1359
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1360 1361 1362
      return -1;
    }

S
Shengliang 已提交
1363
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1364
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1365 1366 1367
      return -1;
    }

S
Shengliang Guan 已提交
1368 1369 1370 1371
    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 已提交
1372 1373
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1374 1375

    mDebug("stb:%s, start to add column %s", pNew->name, pSchema->name);
S
Shengliang Guan 已提交
1376 1377
  }

1378
  pNew->colVer++;
S
Shengliang Guan 已提交
1379 1380 1381
  return 0;
}

1382
static int32_t mndDropSuperTableColumn(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *colName) {
S
Shengliang Guan 已提交
1383
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
S
Shengliang Guan 已提交
1384
  if (col < 0) {
S
Shengliang Guan 已提交
1385 1386 1387 1388
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398
  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;
  }

1399
  col_id_t colId = pOld->pColumns[col].colId;
1400
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1401 1402 1403
    return -1;
  }

S
Shengliang Guan 已提交
1404 1405 1406 1407 1408
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1411
  pNew->colVer++;
S
Shengliang Guan 已提交
1412 1413 1414 1415
  mDebug("stb:%s, start to drop col %s", pNew->name, colName);
  return 0;
}

1416
static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1417
  int32_t col = mndFindSuperTableColumnIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1418 1419 1420 1421 1422 1423 1424
  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 已提交
1425
    nLen += (pOld->pColumns[i].colId == col) ? pField->bytes : pOld->pColumns[i].bytes;
S
Shengliang Guan 已提交
1426 1427 1428 1429 1430 1431 1432
  }

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

1433
  col_id_t colId = pOld->pColumns[col].colId;
1434
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1435 1436 1437
    return -1;
  }

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

  SSchema *pCol = pNew->pColumns + col;
S
Shengliang Guan 已提交
1443 1444
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
1445 1446 1447
    return -1;
  }

S
Shengliang Guan 已提交
1448
  if (pField->bytes <= pCol->bytes) {
S
Shengliang Guan 已提交
1449
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
S
Shengliang Guan 已提交
1450 1451 1452
    return -1;
  }

S
Shengliang Guan 已提交
1453
  pCol->bytes = pField->bytes;
1454
  pNew->colVer++;
S
Shengliang Guan 已提交
1455

S
Shengliang Guan 已提交
1456
  mDebug("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1457 1458 1459
  return 0;
}

S
Shengliang Guan 已提交
1460
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1461 1462
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1463 1464 1465 1466
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1467
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
S
Shengliang Guan 已提交
1468 1469 1470 1471

  return 0;
}

S
Shengliang Guan 已提交
1472
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1473 1474
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
1475 1476 1477 1478
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1479 1480 1481 1482 1483
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

1484 1485
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb, void *alterOriData,
                                         int32_t alterOriDataLen) {
S
Shengliang Guan 已提交
1486 1487 1488 1489 1490 1491 1492 1493
  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 已提交
1494
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
1495 1496 1497 1498
      sdbRelease(pSdb, pVgroup);
      continue;
    }

wmmhello's avatar
wmmhello 已提交
1499
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, alterOriData, alterOriDataLen);
S
Shengliang Guan 已提交
1500 1501 1502 1503 1504 1505 1506 1507 1508
    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 已提交
1509
    action.msgType = TDMT_VND_ALTER_STB;
S
Shengliang Guan 已提交
1510
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
1511
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

D
dapan1121 已提交
1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567
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;
  }

  strcpy(pRsp->dbFName, pStb->db);
  strcpy(pRsp->tbName, tbName);
  strcpy(pRsp->stbName, tbName);
  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 已提交
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584
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;
  }

  strcpy(pRsp->dbFName, pStb->db);
  strcpy(pRsp->tbName, tbName);
  strcpy(pRsp->stbName, tbName);
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->tableType = TSDB_SUPER_TABLE;
D
dapan1121 已提交
1585 1586 1587 1588
  pRsp->delay1 = pStb->maxdelay[0];
  pRsp->delay2 = pStb->maxdelay[1];
  pRsp->watermark1 = pStb->watermark[0];
  pRsp->watermark2 = pStb->watermark[1];
D
dapan1121 已提交
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
  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 已提交
1613
  if (pStb->numOfFuncs > 0) {
D
dapan1121 已提交
1614 1615
    pRsp->pFuncs = taosArrayDup(pStb->pFuncs);
  }
1616

D
dapan1121 已提交
1617 1618 1619 1620
  taosRUnLockLatch(&pStb->lock);
  return 0;
}

L
Liu Jicong 已提交
1621 1622
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp,
                                 int32_t *smaVer) {
D
dapan1121 已提交
1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
  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 已提交
1635
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
D
dapan1121 已提交
1636 1637 1638
    return -1;
  }

D
dapan1121 已提交
1639 1640 1641 1642
  if (smaVer) {
    *smaVer = pStb->smaVer;
  }

D
dapan1121 已提交
1643 1644 1645 1646 1647 1648
  int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}

D
dapan1121 已提交
1649
static int32_t mndBuildStbCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) {
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
  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 已提交
1665

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

1668 1669 1670 1671
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}
D
dapan1121 已提交
1672

1673
static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, SStbObj *pObj, void **pCont, int32_t *pLen) {
1674
  int32_t       ret;
D
dapan1121 已提交
1675
  SEncoder      ec = {0};
1676
  uint32_t      contLen = 0;
D
dapan1121 已提交
1677
  SMAlterStbRsp alterRsp = {0};
1678
  SName         name = {0};
1679
  tNameFromString(&name, pObj->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
D
dapan1121 已提交
1680 1681 1682 1683 1684 1685

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

D
dapan1121 已提交
1687
  ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
D
dapan1121 已提交
1688 1689 1690 1691
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }
1692

D
dapan1121 已提交
1693 1694 1695 1696 1697 1698
  tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }

1699
  void *cont = taosMemoryMalloc(contLen);
D
dapan1121 已提交
1700 1701 1702 1703 1704 1705 1706 1707
  tEncoderInit(&ec, cont, contLen);
  tEncodeSMAlterStbRsp(&ec, &alterRsp);
  tEncoderClear(&ec);

  tFreeSMAlterStbRsp(&alterRsp);

  *pCont = cont;
  *pLen = contLen;
1708

D
dapan1121 已提交
1709 1710 1711
  return 0;
}

1712 1713
static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
                              void *alterOriData, int32_t alterOriDataLen) {
1714
  int32_t code = -1;
1715
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq);
1716 1717 1718
  if (pTrans == NULL) goto _OVER;

  mDebug("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
1719
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729

  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 已提交
1730
  if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen) != 0) goto _OVER;
1731 1732 1733 1734 1735 1736 1737 1738 1739
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;

  code = 0;

_OVER:
  mndTransDrop(pTrans);
  return code;
}

S
Shengliang Guan 已提交
1740
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
1741 1742 1743 1744
  bool    needRsp = true;
  int32_t code = -1;
  SField *pField0 = NULL;

S
Shengliang Guan 已提交
1745 1746 1747
  SStbObj stbObj = {0};
  taosRLockLatch(&pOld->lock);
  memcpy(&stbObj, pOld, sizeof(SStbObj));
1748
  taosRUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
1749 1750 1751
  stbObj.pColumns = NULL;
  stbObj.pTags = NULL;
  stbObj.updateTime = taosGetTimestampMs();
D
dapan1121 已提交
1752
  stbObj.lock = 0;
S
Shengliang Guan 已提交
1753

S
Shengliang Guan 已提交
1754
  switch (pAlter->alterType) {
S
Shengliang Guan 已提交
1755
    case TSDB_ALTER_TABLE_ADD_TAG:
S
Shengliang Guan 已提交
1756
      code = mndAddSuperTableTag(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1757
      break;
S
Shengliang Guan 已提交
1758
    case TSDB_ALTER_TABLE_DROP_TAG:
S
Shengliang 已提交
1759
      pField0 = taosArrayGet(pAlter->pFields, 0);
1760
      code = mndDropSuperTableTag(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1761
      break;
S
Shengliang Guan 已提交
1762
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
1763
      code = mndAlterStbTagName(pMnode, pOld, &stbObj, pAlter->pFields);
S
Shengliang Guan 已提交
1764
      break;
S
Shengliang Guan 已提交
1765
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
S
Shengliang 已提交
1766
      pField0 = taosArrayGet(pAlter->pFields, 0);
1767
      code = mndAlterStbTagBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1768 1769
      break;
    case TSDB_ALTER_TABLE_ADD_COLUMN:
S
Shengliang Guan 已提交
1770
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1771 1772
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
S
Shengliang 已提交
1773
      pField0 = taosArrayGet(pAlter->pFields, 0);
1774
      code = mndDropSuperTableColumn(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1775
      break;
S
Shengliang Guan 已提交
1776
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
S
Shengliang 已提交
1777
      pField0 = taosArrayGet(pAlter->pFields, 0);
1778
      code = mndAlterStbColumnBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1779
      break;
S
Shengliang 已提交
1780
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
D
dapan1121 已提交
1781
      needRsp = false;
S
Shengliang 已提交
1782
      code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
S
Shengliang 已提交
1783
      break;
S
Shengliang Guan 已提交
1784
    default:
D
dapan1121 已提交
1785
      needRsp = false;
S
Shengliang 已提交
1786
      terrno = TSDB_CODE_OPS_NOT_SUPPORT;
S
Shengliang Guan 已提交
1787 1788 1789
      break;
  }

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

1793
_OVER:
wafwerar's avatar
wafwerar 已提交
1794 1795
  taosMemoryFreeClear(stbObj.pTags);
  taosMemoryFreeClear(stbObj.pColumns);
1796 1797 1798
  if (pAlter->commentLen > 0) {
    taosMemoryFreeClear(stbObj.comment);
  }
S
Shengliang Guan 已提交
1799 1800
  return code;
}
S
Shengliang Guan 已提交
1801

1802
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
1803
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1804 1805 1806 1807
  int32_t       code = -1;
  SDbObj       *pDb = NULL;
  SStbObj      *pStb = NULL;
  SMAlterStbReq alterReq = {0};
S
Shengliang Guan 已提交
1808

S
Shengliang Guan 已提交
1809
  if (tDeserializeSMAlterStbReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
1810
    terrno = TSDB_CODE_INVALID_MSG;
1811
    goto _OVER;
S
Shengliang Guan 已提交
1812
  }
S
Shengliang Guan 已提交
1813

S
Shengliang Guan 已提交
1814
  mDebug("stb:%s, start to alter", alterReq.name);
1815
  if (mndCheckAlterStbReq(&alterReq) != 0) goto _OVER;
S
Shengliang Guan 已提交
1816

S
Shengliang Guan 已提交
1817
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1818 1819
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_INVALID_DB;
1820
    goto _OVER;
S
Shengliang Guan 已提交
1821 1822
  }

S
Shengliang Guan 已提交
1823
  pStb = mndAcquireStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1824 1825
  if (pStb == NULL) {
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
1826
    goto _OVER;
S
Shengliang Guan 已提交
1827
  }
S
Shengliang Guan 已提交
1828

1829
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1830
    goto _OVER;
S
Shengliang Guan 已提交
1831 1832
  }

S
Shengliang Guan 已提交
1833
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
S
Shengliang Guan 已提交
1834
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1835

1836
_OVER:
S
Shengliang Guan 已提交
1837
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1838
    mError("stb:%s, failed to alter since %s", alterReq.name, terrstr());
S
Shengliang Guan 已提交
1839 1840
  }

S
Shengliang Guan 已提交
1841 1842
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
1843
  tFreeSMAltertbReq(&alterReq);
S
Shengliang Guan 已提交
1844 1845

  return code;
S
Shengliang Guan 已提交
1846
}
S
Shengliang Guan 已提交
1847

S
Shengliang Guan 已提交
1848 1849 1850
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1851 1852 1853 1854
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1855 1856 1857 1858 1859 1860 1861 1862
  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 已提交
1863 1864 1865 1866
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1867 1868 1869 1870 1871
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

S
Shengliang Guan 已提交
1872 1873 1874 1875
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 已提交
1876

S
Shengliang Guan 已提交
1877 1878 1879
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
1880
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
1881 1882 1883 1884
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
1885
    int32_t contLen = 0;
S
Shengliang Guan 已提交
1886
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900
    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;
    action.acceptableCode = TSDB_CODE_VND_TB_NOT_EXIST;
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
1901
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
1902 1903 1904 1905 1906 1907 1908 1909 1910 1911
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

S
Shengliang Guan 已提交
1912
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1913
  int32_t code = -1;
1914
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq);
1915
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
1916

S
Shengliang Guan 已提交
1917
  mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
1918
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
S
Shengliang Guan 已提交
1919

1920 1921 1922
  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;
1923
  if (mndDropSmasByStb(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
1924
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
1925

S
Shengliang Guan 已提交
1926 1927
  code = 0;

1928
_OVER:
S
Shengliang Guan 已提交
1929
  mndTransDrop(pTrans);
S
Shengliang 已提交
1930
  return code;
S
Shengliang Guan 已提交
1931 1932
}

1933
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
1934
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1935 1936 1937
  int32_t      code = -1;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
1938
  SMDropStbReq dropReq = {0};
S
Shengliang Guan 已提交
1939

S
Shengliang Guan 已提交
1940
  if (tDeserializeSMDropStbReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
1941
    terrno = TSDB_CODE_INVALID_MSG;
1942
    goto _OVER;
S
Shengliang Guan 已提交
1943
  }
S
Shengliang Guan 已提交
1944

S
Shengliang Guan 已提交
1945
  mDebug("stb:%s, start to drop", dropReq.name);
S
Shengliang Guan 已提交
1946

S
Shengliang Guan 已提交
1947
  pStb = mndAcquireStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
1948
  if (pStb == NULL) {
S
Shengliang Guan 已提交
1949 1950
    if (dropReq.igNotExists) {
      mDebug("stb:%s, not exist, ignore not exist is set", dropReq.name);
S
Shengliang Guan 已提交
1951
      code = 0;
1952
      goto _OVER;
S
Shengliang Guan 已提交
1953 1954
    } else {
      terrno = TSDB_CODE_MND_STB_NOT_EXIST;
1955
      goto _OVER;
S
Shengliang Guan 已提交
1956 1957 1958
    }
  }

wmmhello's avatar
wmmhello 已提交
1959 1960
  if (dropReq.source == TD_REQ_FROM_TAOX && pStb->uid != dropReq.suid) {
    code = 0;
wmmhello's avatar
wmmhello 已提交
1961 1962 1963
    goto _OVER;
  }

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

1970
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
1971
    goto _OVER;
S
Shengliang Guan 已提交
1972 1973 1974
  }

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

1977
_OVER:
S
Shengliang Guan 已提交
1978
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1979
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
1980 1981
  }

S
Shengliang Guan 已提交
1982 1983 1984
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
S
Shengliang Guan 已提交
1985
}
S
Shengliang Guan 已提交
1986

S
Shengliang Guan 已提交
1987 1988
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1989 1990 1991
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
1992

S
Shengliang Guan 已提交
1993
  if (tDeserializeSTableInfoReq(pReq->pCont, pReq->contLen, &infoReq) != 0) {
S
Shengliang Guan 已提交
1994
    terrno = TSDB_CODE_INVALID_MSG;
1995
    goto _OVER;
S
Shengliang Guan 已提交
1996
  }
D
dapan 已提交
1997

D
dapan1121 已提交
1998 1999 2000
  if (0 == strcmp(infoReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
    mDebug("information_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
    if (mndBuildInsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
2001
      goto _OVER;
D
dapan1121 已提交
2002
    }
D
dapan1121 已提交
2003 2004 2005
  } else if (0 == strcmp(infoReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
    mDebug("performance_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
    if (mndBuildPerfsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
2006
      goto _OVER;
D
dapan1121 已提交
2007
    }
D
dapan1121 已提交
2008 2009
  } else {
    mDebug("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2010
    if (mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp, NULL) != 0) {
2011
      goto _OVER;
D
dapan1121 已提交
2012
    }
S
Shengliang Guan 已提交
2013
  }
S
Shengliang Guan 已提交
2014

S
Shengliang Guan 已提交
2015 2016 2017
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
2018
    goto _OVER;
S
Shengliang Guan 已提交
2019
  }
S
Shengliang Guan 已提交
2020

S
Shengliang Guan 已提交
2021
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
2022 2023
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
2024
    goto _OVER;
S
Shengliang Guan 已提交
2025
  }
D
dapan 已提交
2026

S
Shengliang Guan 已提交
2027
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
S
Shengliang Guan 已提交
2028 2029
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = rspLen;
S
Shengliang Guan 已提交
2030
  code = 0;
S
Shengliang Guan 已提交
2031

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

2034
_OVER:
S
Shengliang Guan 已提交
2035 2036 2037
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
2038

S
Shengliang Guan 已提交
2039 2040 2041
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
2042

D
dapan1121 已提交
2043
static int32_t mndProcessTableCfgReq(SRpcMsg *pReq) {
2044 2045 2046 2047
  SMnode      *pMnode = pReq->info.node;
  int32_t      code = -1;
  STableCfgReq cfgReq = {0};
  STableCfgRsp cfgRsp = {0};
D
dapan1121 已提交
2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 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 2098

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

  if (0 == strcmp(cfgReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
    mDebug("information_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
    if (mndBuildInsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  } else if (0 == strcmp(cfgReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
    mDebug("performance_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
    if (mndBuildPerfsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) {
      goto _OVER;
    }
  } else {
    mDebug("stb:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName);
    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 已提交
2099
int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t numOfStbs, void **ppRsp,
S
Shengliang Guan 已提交
2100
                           int32_t *pRspLen) {
D
dapan1121 已提交
2101
  SSTbHbRsp hbRsp = {0};
D
dapan1121 已提交
2102 2103
  hbRsp.pMetaRsp = taosArrayInit(numOfStbs, sizeof(STableMetaRsp));
  if (hbRsp.pMetaRsp == NULL) {
S
Shengliang Guan 已提交
2104 2105 2106
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
2107

D
dapan1121 已提交
2108
  hbRsp.pIndexRsp = taosArrayInit(numOfStbs, sizeof(STableIndexRsp));
D
dapan1121 已提交
2109
  if (NULL == hbRsp.pIndexRsp) {
D
dapan1121 已提交
2110
    taosArrayDestroy(hbRsp.pMetaRsp);
D
dapan1121 已提交
2111 2112 2113
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
L
Liu Jicong 已提交
2114

S
Shengliang Guan 已提交
2115
  for (int32_t i = 0; i < numOfStbs; ++i) {
D
dapan1121 已提交
2116
    SSTableVersion *pStbVersion = &pStbVersions[i];
S
Shengliang Guan 已提交
2117 2118 2119
    pStbVersion->suid = be64toh(pStbVersion->suid);
    pStbVersion->sversion = ntohs(pStbVersion->sversion);
    pStbVersion->tversion = ntohs(pStbVersion->tversion);
D
dapan1121 已提交
2120
    pStbVersion->smaVer = ntohl(pStbVersion->smaVer);
S
Shengliang Guan 已提交
2121

S
Shengliang Guan 已提交
2122
    STableMetaRsp metaRsp = {0};
L
Liu Jicong 已提交
2123
    int32_t       smaVer = 0;
S
Shengliang Guan 已提交
2124
    mDebug("stb:%s.%s, start to retrieve meta", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2125
    if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
S
Shengliang Guan 已提交
2126 2127
      metaRsp.numOfColumns = -1;
      metaRsp.suid = pStbVersion->suid;
D
dapan1121 已提交
2128
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2129
      continue;
D
dapan 已提交
2130
    }
S
Shengliang Guan 已提交
2131

D
dapan1121 已提交
2132
    if (pStbVersion->sversion != metaRsp.sversion || pStbVersion->tversion != metaRsp.tversion) {
D
dapan1121 已提交
2133
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2134 2135
    } else {
      tFreeSTableMetaRsp(&metaRsp);
S
Shengliang Guan 已提交
2136
    }
D
dapan1121 已提交
2137

D
dapan1121 已提交
2138
    if (pStbVersion->smaVer && pStbVersion->smaVer != smaVer) {
L
Liu Jicong 已提交
2139 2140
      bool           exist = false;
      char           tbFName[TSDB_TABLE_FNAME_LEN];
D
dapan1121 已提交
2141
      STableIndexRsp indexRsp = {0};
D
dapan1121 已提交
2142 2143 2144 2145 2146
      indexRsp.pIndex = taosArrayInit(10, sizeof(STableIndexInfo));
      if (NULL == indexRsp.pIndex) {
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        return -1;
      }
L
Liu Jicong 已提交
2147

D
dapan1121 已提交
2148
      sprintf(tbFName, "%s.%s", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2149
      int32_t code = mndGetTableSma(pMnode, tbFName, &indexRsp, &exist);
D
dapan1121 已提交
2150
      if (code || !exist) {
D
dapan1121 已提交
2151 2152 2153
        indexRsp.suid = pStbVersion->suid;
        indexRsp.version = -1;
        indexRsp.pIndex = NULL;
D
dapan1121 已提交
2154
      }
D
dapan1121 已提交
2155

D
dapan1121 已提交
2156 2157
      strcpy(indexRsp.dbFName, pStbVersion->dbFName);
      strcpy(indexRsp.tbName, pStbVersion->stbName);
D
dapan1121 已提交
2158 2159

      taosArrayPush(hbRsp.pIndexRsp, &indexRsp);
D
dapan1121 已提交
2160
    }
S
Shengliang Guan 已提交
2161
  }
S
Shengliang Guan 已提交
2162

D
dapan1121 已提交
2163
  int32_t rspLen = tSerializeSSTbHbRsp(NULL, 0, &hbRsp);
S
Shengliang Guan 已提交
2164
  if (rspLen < 0) {
D
dapan1121 已提交
2165
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2166 2167
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
2168 2169
  }

wafwerar's avatar
wafwerar 已提交
2170
  void *pRsp = taosMemoryMalloc(rspLen);
S
Shengliang Guan 已提交
2171
  if (pRsp == NULL) {
D
dapan1121 已提交
2172
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2173 2174
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
2175 2176
  }

D
dapan1121 已提交
2177 2178
  tSerializeSSTbHbRsp(pRsp, rspLen, &hbRsp);
  tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2179 2180
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
2181 2182 2183
  return 0;
}

2184
int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
2185
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2186 2187 2188 2189 2190 2191
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
2192
  int32_t numOfStbs = 0;
2193
  void   *pIter = NULL;
S
Shengliang Guan 已提交
2194
  while (1) {
S
Shengliang Guan 已提交
2195
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
2196
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2197 2198
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
2199
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
2200
      numOfStbs++;
S
Shengliang Guan 已提交
2201 2202
    }

S
Shengliang Guan 已提交
2203
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2204 2205
  }

S
Shengliang Guan 已提交
2206
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
2207
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
2208 2209 2210
  return 0;
}

L
Liu Jicong 已提交
2211 2212 2213 2214 2215 2216 2217 2218
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 已提交
2219 2220
  int32_t pos = -1;
  int32_t num = 0;
L
Liu Jicong 已提交
2221 2222
  for (pos = 0; stbFullName[pos] != 0; ++pos) {
    if (stbFullName[pos] == TS_PATH_DELIMITER[0]) num++;
S
Shengliang Guan 已提交
2223 2224 2225 2226
    if (num == 2) break;
  }

  if (num == 2) {
L
Liu Jicong 已提交
2227
    tstrncpy(dst, stbFullName + pos + 1, dstSize);
S
Shengliang Guan 已提交
2228 2229 2230
  }
}

S
Shengliang Guan 已提交
2231 2232
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode  *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2233
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2234 2235 2236
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
2237

H
Hongze Cheng 已提交
2238
  SDbObj *pDb = NULL;
H
Haojun Liao 已提交
2239 2240
  if (strlen(pShow->db) > 0) {
    pDb = mndAcquireDb(pMnode, pShow->db);
D
dapan1121 已提交
2241
    if (pDb == NULL) return terrno;
H
Haojun Liao 已提交
2242
  }
S
Shengliang Guan 已提交
2243

S
Shengliang Guan 已提交
2244
  while (numOfRows < rows) {
S
Shengliang Guan 已提交
2245
    pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2246 2247
    if (pShow->pIter == NULL) break;

H
Haojun Liao 已提交
2248
    if (pDb != NULL && pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
2249
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2250 2251 2252 2253 2254
      continue;
    }

    cols = 0;

H
Haojun Liao 已提交
2255
    SName name = {0};
H
Hongze Cheng 已提交
2256
    char  stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
L
Liu Jicong 已提交
2257
    mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
2258
    varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
S
Shengliang Guan 已提交
2259

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

H
Hongze Cheng 已提交
2263 2264
    char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
2265 2266 2267
    tNameGetDbName(&name, varDataVal(db));
    varDataSetLen(db, strlen(varDataVal(db)));

2268
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
H
Hongze Cheng 已提交
2269
    colDataAppend(pColInfo, numOfRows, (const char *)db, false);
2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282

    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

2283
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
wmmhello's avatar
wmmhello 已提交
2284 2285 2286 2287
    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);
2288
    } else if (pStb->commentLen == 0) {
wmmhello's avatar
wmmhello 已提交
2289 2290 2291 2292 2293
      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 已提交
2294
    }
H
Haojun Liao 已提交
2295

2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309
    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);

2310
    char    rollup[128 + VARSTR_HEADER_SIZE] = {0};
2311 2312 2313 2314
    int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
    for (int32_t i = 0; i < rollupNum; ++i) {
      char *funcName = taosArrayGet(pStb->pFuncs, i);
      if (i) {
2315
        strcat(varDataVal(rollup), ", ");
2316 2317 2318 2319 2320 2321 2322 2323
      }
      strcat(varDataVal(rollup), funcName);
    }
    varDataSetLen(rollup, strlen(varDataVal(rollup)));

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

S
Shengliang Guan 已提交
2324
    numOfRows++;
S
Shengliang Guan 已提交
2325
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2326 2327
  }

H
Haojun Liao 已提交
2328 2329 2330 2331
  if (pDb != NULL) {
    mndReleaseDb(pMnode, pDb);
  }

2332
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
2333 2334 2335
  return numOfRows;
}

S
Shengliang Guan 已提交
2336
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
2337 2338
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan1121 已提交
2339
}