mndStb.c 80.2 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
  terrno = TSDB_CODE_OUT_OF_MEMORY;
165 166
  SSdbRow *pRow = NULL;
  SStbObj *pStb = NULL;
167

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

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

176
  pRow = sdbAllocRow(sizeof(SStbObj));
177
  if (pRow == NULL) goto _OVER;
178

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

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

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

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

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

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

242 243 244 245 246
  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 已提交
247

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

  terrno = 0;

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

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

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

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

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

S
Shengliang Guan 已提交
293 294
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 已提交
295

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

  if (pOld->numOfColumns < pNew->numOfColumns) {
wafwerar's avatar
wafwerar 已提交
299
    void *pColumns = taosMemoryMalloc(pNew->numOfColumns * sizeof(SSchema));
S
Shengliang Guan 已提交
300
    if (pColumns != NULL) {
wafwerar's avatar
wafwerar 已提交
301
      taosMemoryFree(pOld->pColumns);
S
Shengliang Guan 已提交
302
      pOld->pColumns = pColumns;
S
Shengliang Guan 已提交
303 304 305 306 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);
    }
  }

  if (pOld->numOfTags < pNew->numOfTags) {
wafwerar's avatar
wafwerar 已提交
311
    void *pTags = taosMemoryMalloc(pNew->numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
312
    if (pTags != NULL) {
wafwerar's avatar
wafwerar 已提交
313
      taosMemoryFree(pOld->pTags);
S
Shengliang Guan 已提交
314
      pOld->pTags = pTags;
S
Shengliang Guan 已提交
315 316 317 318
    } 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 已提交
319
    }
S
Shengliang Guan 已提交
320 321
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
593 594 595
  return 0;
}

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

  return 0;
}

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

  return 0;
}

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

  return 0;
}

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

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

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

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

  return 0;
}

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

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

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

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

  return 0;
}

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

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

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

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

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

775 776 777
  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 已提交
778 779 780
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
781

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

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

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

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

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

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

824
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
825
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
826
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) return -1;
827 828 829 830 831 832 833
  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 已提交
834

S
Shengliang Guan 已提交
835
static int32_t mndProcessTtlTimer(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
836 837 838 839 840 841 842
  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 已提交
843

844 845
  mInfo("start to process ttl timer");

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

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

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

wmmhello's avatar
wmmhello 已提交
871 872 873
  return 0;
}

wmmhello's avatar
wmmhello 已提交
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
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);
917
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
918
      pSchema->colId = pStb->pColumns[cIndex].colId;
919
    } else {
wmmhello's avatar
wmmhello 已提交
920 921 922 923 924 925 926 927 928 929 930
      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);
931
    if (cIndex >= 0) {
wmmhello's avatar
wmmhello 已提交
932
      pSchema->colId = pStb->pTags[cIndex].colId;
933
    } else {
wmmhello's avatar
wmmhello 已提交
934 935 936 937 938 939 940 941
      pSchema->colId = pDst->nextColId++;
    }
  }
  pDst->tagVer = createReq->tagVer;
  pDst->colVer = createReq->colVer;
  return TSDB_CODE_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  return code;
S
Shengliang Guan 已提交
1061 1062
}

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

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

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

  return 0;
}

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

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

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

S
Shengliang Guan 已提交
1121
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
  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 已提交
1132 1133 1134 1135 1136
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

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

S
Shengliang Guan 已提交
1149 1150 1151 1152
    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 已提交
1153 1154
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1155

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

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

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

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

    SNode *pAst = NULL;
    if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
1180
      ASSERT(0);
1181 1182 1183 1184 1185 1186 1187 1188
      return -1;
    }

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

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

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

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

    SNode *pAst = NULL;
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
1225
      ASSERT(0);
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
      return -1;
    }

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

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

  NEXT:
    sdbRelease(pSdb, pStream);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1253
    nodesDestroyList(pNodeList);
1254 1255 1256
  }
  return 0;
}
1257

1258 1259 1260
static int32_t mndCheckAlterColForTSma(SMnode *pMnode, const char *stbFullName, int64_t suid, col_id_t colId) {
  SSdb *pSdb = pMnode->pSdb;
  void *pIter = NULL;
1261 1262 1263 1264 1265
  while (1) {
    SSmaObj *pSma = NULL;
    pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pSma);
    if (pIter == NULL) break;

H
Hongze Cheng 已提交
1266 1267
    mInfo("tsma:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, sql:%s", pSma->name, stbFullName,
          suid, colId, pSma->sql);
1268 1269 1270 1271 1272

    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",
1273
             pSma->name, stbFullName, suid, colId);
1274 1275 1276 1277 1278 1279 1280 1281
      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;
1282
      mInfo("tsma:%s, check colId:%d tableId:%" PRId64, pSma->name, pCol->colId, pCol->tableId);
1283 1284

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

1299
  NEXT:
1300 1301
    sdbRelease(pSdb, pSma);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
1302
    nodesDestroyList(pNodeList);
1303
  }
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
  return 0;
}

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

1315 1316 1317
  if (mndCheckAlterColForTSma(pMnode, stbFullName, suid, colId) < 0) {
    return -1;
  }
1318 1319 1320
  return 0;
}

1321
static int32_t mndDropSuperTableTag(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
S
Shengliang Guan 已提交
1322 1323 1324 1325 1326 1327
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1328
  col_id_t colId = pOld->pTags[tag].colId;
1329
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1330 1331 1332
    return -1;
  }

S
Shengliang Guan 已提交
1333 1334 1335 1336 1337
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1340
  pNew->tagVer++;
1341
  mInfo("stb:%s, start to drop tag %s", pNew->name, tagName);
S
Shengliang Guan 已提交
1342 1343 1344
  return 0;
}

1345
static int32_t mndAlterStbTagName(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
S
Shengliang Guan 已提交
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
  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 已提交
1357 1358 1359 1360 1361 1362
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1363
  col_id_t colId = pOld->pTags[tag].colId;
1364
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1365 1366 1367
    return -1;
  }

S
Shengliang Guan 已提交
1368
  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
S
Shengliang Guan 已提交
1369
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1370 1371 1372
    return -1;
  }

S
Shengliang Guan 已提交
1373 1374
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
    return -1;
  }

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

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

1385
  pNew->tagVer++;
1386
  mInfo("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
S
Shengliang Guan 已提交
1387 1388 1389
  return 0;
}

1390
static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1391
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1392 1393 1394 1395 1396
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1397
  col_id_t colId = pOld->pTags[tag].colId;
1398
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1399 1400 1401
    return -1;
  }

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

  SSchema *pTag = pNew->pTags + tag;

S
Shengliang Guan 已提交
1408 1409 1410 1411 1412
  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 已提交
1413
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
1414 1415 1416 1417
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

S
Shengliang Guan 已提交
1418
  pTag->bytes = pField->bytes;
1419
  pNew->tagVer++;
S
Shengliang Guan 已提交
1420

1421
  mInfo("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1422 1423 1424
  return 0;
}

S
Shengliang Guan 已提交
1425
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ncols) {
S
Shengliang Guan 已提交
1426 1427 1428 1429 1430
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
1431 1432 1433 1434 1435
  pNew->numOfColumns = pNew->numOfColumns + ncols;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1436
  for (int32_t i = 0; i < ncols; i++) {
S
Shengliang Guan 已提交
1437
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1438
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1439
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1440 1441 1442
      return -1;
    }

S
Shengliang 已提交
1443
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1444
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1445 1446 1447
      return -1;
    }

S
Shengliang Guan 已提交
1448 1449 1450 1451
    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 已提交
1452 1453
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1454

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

1458
  pNew->colVer++;
S
Shengliang Guan 已提交
1459 1460 1461
  return 0;
}

1462
static int32_t mndDropSuperTableColumn(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *colName) {
S
Shengliang Guan 已提交
1463
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
S
Shengliang Guan 已提交
1464
  if (col < 0) {
S
Shengliang Guan 已提交
1465 1466 1467 1468
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
  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;
  }

1479
  col_id_t colId = pOld->pColumns[col].colId;
1480
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1481 1482 1483
    return -1;
  }

S
Shengliang Guan 已提交
1484 1485 1486 1487 1488
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1491
  pNew->colVer++;
1492
  mInfo("stb:%s, start to drop col %s", pNew->name, colName);
S
Shengliang Guan 已提交
1493 1494 1495
  return 0;
}

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

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

1513
  col_id_t colId = pOld->pColumns[col].colId;
1514
  if (mndCheckColAndTagModifiable(pMnode, pOld->name, pOld->uid, colId) != 0) {
1515 1516 1517
    return -1;
  }

S
Shengliang Guan 已提交
1518 1519 1520 1521 1522
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pCol = pNew->pColumns + col;
S
Shengliang Guan 已提交
1523 1524
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
1525 1526 1527
    return -1;
  }

S
Shengliang Guan 已提交
1528
  if (pField->bytes <= pCol->bytes) {
S
Shengliang Guan 已提交
1529
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
S
Shengliang Guan 已提交
1530 1531 1532
    return -1;
  }

S
Shengliang Guan 已提交
1533
  pCol->bytes = pField->bytes;
1534
  pNew->colVer++;
S
Shengliang Guan 已提交
1535

1536
  mInfo("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1537 1538 1539
  return 0;
}

S
Shengliang Guan 已提交
1540
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1541 1542
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1543 1544 1545 1546
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1547
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
S
Shengliang Guan 已提交
1548 1549 1550 1551

  return 0;
}

S
Shengliang Guan 已提交
1552
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1553 1554
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
S
Shengliang Guan 已提交
1555 1556 1557 1558
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1559 1560 1561 1562 1563
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

1564 1565
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb, void *alterOriData,
                                         int32_t alterOriDataLen) {
S
Shengliang Guan 已提交
1566 1567 1568 1569 1570 1571 1572 1573
  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 已提交
1574
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
1575 1576 1577 1578
      sdbRelease(pSdb, pVgroup);
      continue;
    }

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

  return 0;
}

D
dapan1121 已提交
1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
  taosRLockLatch(&pStb->lock);

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

S
Shengliang Guan 已提交
1613 1614 1615
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
D
dapan1121 已提交
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647
  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 已提交
1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658
static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableCfgRsp *pRsp) {
  taosRLockLatch(&pStb->lock);

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

S
Shengliang Guan 已提交
1659 1660 1661
  tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
  tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
  tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
D
dapan1121 已提交
1662 1663 1664
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->tableType = TSDB_SUPER_TABLE;
D
dapan1121 已提交
1665 1666 1667 1668
  pRsp->delay1 = pStb->maxdelay[0];
  pRsp->delay2 = pStb->maxdelay[1];
  pRsp->watermark1 = pStb->watermark[0];
  pRsp->watermark2 = pStb->watermark[1];
D
dapan1121 已提交
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692
  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 已提交
1693
  if (pStb->numOfFuncs > 0) {
H
Haojun Liao 已提交
1694
    pRsp->pFuncs = taosArrayDup(pStb->pFuncs, NULL);
D
dapan1121 已提交
1695
  }
1696

D
dapan1121 已提交
1697 1698 1699 1700
  taosRUnLockLatch(&pStb->lock);
  return 0;
}

L
Liu Jicong 已提交
1701 1702
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp,
                                 int32_t *smaVer) {
D
dapan1121 已提交
1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
  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 已提交
1715
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
D
dapan1121 已提交
1716 1717 1718
    return -1;
  }

D
dapan1121 已提交
1719 1720 1721 1722
  if (smaVer) {
    *smaVer = pStb->smaVer;
  }

D
dapan1121 已提交
1723 1724 1725 1726 1727 1728
  int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}

D
dapan1121 已提交
1729
static int32_t mndBuildStbCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) {
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744
  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 已提交
1745

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

1748 1749 1750 1751
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
}
D
dapan1121 已提交
1752

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

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

D
dapan1121 已提交
1767
  ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
D
dapan1121 已提交
1768 1769 1770 1771
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }
1772

D
dapan1121 已提交
1773 1774 1775 1776 1777 1778
  tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }

1779
  void *cont = taosMemoryMalloc(contLen);
D
dapan1121 已提交
1780 1781 1782 1783 1784 1785 1786 1787
  tEncoderInit(&ec, cont, contLen);
  tEncodeSMAlterStbRsp(&ec, &alterRsp);
  tEncoderClear(&ec);

  tFreeSMAlterStbRsp(&alterRsp);

  *pCont = cont;
  *pLen = contLen;
1788

D
dapan1121 已提交
1789 1790 1791
  return 0;
}

L
Liu Jicong 已提交
1792 1793
int32_t mndBuildSMCreateStbRsp(SMnode *pMnode, char *dbFName, char *stbFName, void **pCont, int32_t *pLen) {
  int32_t ret = -1;
1794 1795 1796 1797 1798 1799 1800 1801 1802
  SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
  if (NULL == pDb) {
    return -1;
  }

  SStbObj *pObj = mndAcquireStb(pMnode, stbFName);
  if (NULL == pObj) {
    goto _OVER;
  }
L
Liu Jicong 已提交
1803 1804 1805

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

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

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

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

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

  tFreeSMCreateStbRsp(&stbRsp);

  *pCont = cont;
  *pLen = contLen;

  ret = 0;
L
Liu Jicong 已提交
1839

1840 1841 1842 1843
_OVER:
  if (pObj) {
    mndReleaseStb(pMnode, pObj);
  }
L
Liu Jicong 已提交
1844

1845 1846 1847 1848 1849 1850 1851
  if (pDb) {
    mndReleaseDb(pMnode, pDb);
  }

  return ret;
}

1852 1853
static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
                              void *alterOriData, int32_t alterOriDataLen) {
1854
  int32_t code = -1;
1855
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "alter-stb");
1856 1857
  if (pTrans == NULL) goto _OVER;

1858
  mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
1859
  mndTransSetDbName(pTrans, pDb->name, pStb->name);
1860
  if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
1861 1862 1863 1864 1865 1866 1867 1868 1869 1870

  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 已提交
1871
  if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen) != 0) goto _OVER;
1872 1873 1874 1875 1876 1877 1878 1879 1880
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;

  code = 0;

_OVER:
  mndTransDrop(pTrans);
  return code;
}

S
Shengliang Guan 已提交
1881
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
1882 1883 1884 1885
  bool    needRsp = true;
  int32_t code = -1;
  SField *pField0 = NULL;

S
Shengliang Guan 已提交
1886 1887 1888
  SStbObj stbObj = {0};
  taosRLockLatch(&pOld->lock);
  memcpy(&stbObj, pOld, sizeof(SStbObj));
1889
  taosRUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
1890 1891 1892
  stbObj.pColumns = NULL;
  stbObj.pTags = NULL;
  stbObj.updateTime = taosGetTimestampMs();
D
dapan1121 已提交
1893
  stbObj.lock = 0;
S
Shengliang Guan 已提交
1894

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

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

1934
_OVER:
wafwerar's avatar
wafwerar 已提交
1935 1936
  taosMemoryFreeClear(stbObj.pTags);
  taosMemoryFreeClear(stbObj.pColumns);
1937 1938 1939
  if (pAlter->commentLen > 0) {
    taosMemoryFreeClear(stbObj.comment);
  }
S
Shengliang Guan 已提交
1940 1941
  return code;
}
S
Shengliang Guan 已提交
1942

1943
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
1944
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1945 1946 1947 1948
  int32_t       code = -1;
  SDbObj       *pDb = NULL;
  SStbObj      *pStb = NULL;
  SMAlterStbReq alterReq = {0};
S
Shengliang Guan 已提交
1949

S
Shengliang Guan 已提交
1950
  if (tDeserializeSMAlterStbReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
1951
    terrno = TSDB_CODE_INVALID_MSG;
1952
    goto _OVER;
S
Shengliang Guan 已提交
1953
  }
S
Shengliang Guan 已提交
1954

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

S
Shengliang Guan 已提交
1958
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1959 1960
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_INVALID_DB;
1961
    goto _OVER;
S
Shengliang Guan 已提交
1962 1963
  }

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

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

S
Shengliang Guan 已提交
1974
  code = mndAlterStb(pMnode, pReq, &alterReq, 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 alter since %s", alterReq.name, terrstr());
S
Shengliang Guan 已提交
1980 1981
  }

S
Shengliang Guan 已提交
1982 1983
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
1984
  tFreeSMAltertbReq(&alterReq);
S
Shengliang Guan 已提交
1985 1986

  return code;
S
Shengliang Guan 已提交
1987
}
S
Shengliang Guan 已提交
1988

S
Shengliang Guan 已提交
1989 1990 1991
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
S
Shengliang Guan 已提交
1992 1993 1994 1995
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
    sdbFreeRaw(pRedoRaw);
    return -1;
  }
S
Shengliang Guan 已提交
1996 1997 1998 1999 2000 2001 2002 2003
  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 已提交
2004 2005 2006 2007
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
    sdbFreeRaw(pCommitRaw);
    return -1;
  }
S
Shengliang Guan 已提交
2008 2009 2010 2011 2012
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

S
Shengliang Guan 已提交
2013 2014 2015 2016
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 已提交
2017

S
Shengliang Guan 已提交
2018 2019 2020
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
2021
    if (!mndVgroupInDb(pVgroup, pDb->uid)) {
S
Shengliang Guan 已提交
2022 2023 2024 2025
      sdbRelease(pSdb, pVgroup);
      continue;
    }

S
Shengliang Guan 已提交
2026
    int32_t contLen = 0;
S
Shengliang Guan 已提交
2027
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039
    if (pReq == NULL) {
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }

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

  return 0;
}

S
Shengliang Guan 已提交
2053
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
2054
  int32_t code = -1;
2055
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "drop-stb");
2056
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
2057

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

2062 2063 2064
  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;
2065
  if (mndDropSmasByStb(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
2066
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
2067

S
Shengliang Guan 已提交
2068 2069
  code = 0;

2070
_OVER:
S
Shengliang Guan 已提交
2071
  mndTransDrop(pTrans);
S
Shengliang 已提交
2072
  return code;
S
Shengliang Guan 已提交
2073 2074
}

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

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

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

    SNode *pAst = NULL;
    if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
2097
      ASSERT(0);
2098 2099 2100 2101 2102 2103 2104 2105 2106
      return -1;
    }

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

L
Liu Jicong 已提交
2107
      if (pCol->tableId == suid) {
2108 2109
        sdbRelease(pSdb, pTopic);
        nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2110
        nodesDestroyList(pNodeList);
2111 2112 2113 2114 2115 2116 2117 2118
        return -1;
      } else {
        goto NEXT;
      }
    }
  NEXT:
    sdbRelease(pSdb, pTopic);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2119
    nodesDestroyList(pNodeList);
2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131
  }
  return 0;
}

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

L
Liu Jicong 已提交
2132 2133 2134 2135 2136 2137
    if (pStream->smaId != 0) {
      sdbRelease(pSdb, pStream);
      continue;
    }

    if (pStream->targetStbUid == suid) {
L
Liu Jicong 已提交
2138 2139 2140 2141
      sdbRelease(pSdb, pStream);
      return -1;
    }

2142 2143
    SNode *pAst = NULL;
    if (nodesStringToNode(pStream->ast, &pAst) != 0) {
2144
      ASSERT(0);
2145 2146 2147 2148 2149 2150 2151 2152 2153
      return -1;
    }

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

L
Liu Jicong 已提交
2154
      if (pCol->tableId == suid) {
2155 2156
        sdbRelease(pSdb, pStream);
        nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2157
        nodesDestroyList(pNodeList);
2158 2159 2160 2161 2162 2163 2164 2165
        return -1;
      } else {
        goto NEXT;
      }
    }
  NEXT:
    sdbRelease(pSdb, pStream);
    nodesDestroyNode(pAst);
L
Liu Jicong 已提交
2166
    nodesDestroyList(pNodeList);
2167 2168 2169 2170
  }
  return 0;
}

2171
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
S
Shengliang Guan 已提交
2172
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2173 2174 2175
  int32_t      code = -1;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
2176
  SMDropStbReq dropReq = {0};
S
Shengliang Guan 已提交
2177

S
Shengliang Guan 已提交
2178
  if (tDeserializeSMDropStbReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
2179
    terrno = TSDB_CODE_INVALID_MSG;
2180
    goto _OVER;
S
Shengliang Guan 已提交
2181
  }
S
Shengliang Guan 已提交
2182

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

S
Shengliang Guan 已提交
2185
  pStb = mndAcquireStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
2186
  if (pStb == NULL) {
S
Shengliang Guan 已提交
2187
    if (dropReq.igNotExists) {
2188
      mInfo("stb:%s, not exist, ignore not exist is set", dropReq.name);
S
Shengliang Guan 已提交
2189
      code = 0;
2190
      goto _OVER;
S
Shengliang Guan 已提交
2191 2192
    } else {
      terrno = TSDB_CODE_MND_STB_NOT_EXIST;
2193
      goto _OVER;
S
Shengliang Guan 已提交
2194 2195 2196
    }
  }

wmmhello's avatar
wmmhello 已提交
2197 2198
  if (dropReq.source == TD_REQ_FROM_TAOX && pStb->uid != dropReq.suid) {
    code = 0;
wmmhello's avatar
wmmhello 已提交
2199 2200 2201
    goto _OVER;
  }

S
Shengliang Guan 已提交
2202
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
2203 2204
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
2205
    goto _OVER;
S
Shengliang Guan 已提交
2206 2207
  }

2208
  if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
2209
    goto _OVER;
S
Shengliang Guan 已提交
2210 2211
  }

2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
  if (mndCheckDropStbForTopic(pMnode, dropReq.name, pStb->uid) < 0) {
    terrno = TSDB_CODE_MND_TOPIC_MUST_BE_DELETED;
    goto _OVER;
  }

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

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

2225
_OVER:
S
Shengliang Guan 已提交
2226
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
2227
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
2228 2229
  }

S
Shengliang Guan 已提交
2230 2231 2232
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
S
Shengliang Guan 已提交
2233
}
S
Shengliang Guan 已提交
2234

S
Shengliang Guan 已提交
2235 2236
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2237 2238 2239
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
2240

2241 2242 2243 2244
  SUserObj *pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
  if (pUser == NULL) return 0;
  bool sysinfo = pUser->sysInfo;

S
Shengliang Guan 已提交
2245
  if (tDeserializeSTableInfoReq(pReq->pCont, pReq->contLen, &infoReq) != 0) {
S
Shengliang Guan 已提交
2246
    terrno = TSDB_CODE_INVALID_MSG;
2247
    goto _OVER;
S
Shengliang Guan 已提交
2248
  }
D
dapan 已提交
2249

D
dapan1121 已提交
2250
  if (0 == strcmp(infoReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
2251
    mInfo("information_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
2252
    if (mndBuildInsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, sysinfo, &metaRsp) != 0) {
2253
      goto _OVER;
D
dapan1121 已提交
2254
    }
D
dapan1121 已提交
2255
  } else if (0 == strcmp(infoReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
2256
    mInfo("performance_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2257
    if (mndBuildPerfsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
2258
      goto _OVER;
D
dapan1121 已提交
2259
    }
D
dapan1121 已提交
2260
  } else {
2261
    mInfo("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
D
dapan1121 已提交
2262
    if (mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp, NULL) != 0) {
2263
      goto _OVER;
D
dapan1121 已提交
2264
    }
S
Shengliang Guan 已提交
2265
  }
S
Shengliang Guan 已提交
2266

S
Shengliang Guan 已提交
2267 2268 2269
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
2270
    goto _OVER;
S
Shengliang Guan 已提交
2271
  }
S
Shengliang Guan 已提交
2272

S
Shengliang Guan 已提交
2273
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
2274 2275
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
2276
    goto _OVER;
S
Shengliang Guan 已提交
2277
  }
D
dapan 已提交
2278

S
Shengliang Guan 已提交
2279
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
S
Shengliang Guan 已提交
2280 2281
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = rspLen;
S
Shengliang Guan 已提交
2282
  code = 0;
S
Shengliang Guan 已提交
2283

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

2286
_OVER:
S
Shengliang Guan 已提交
2287 2288 2289
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
2290

2291
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
2292 2293 2294
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
2295

D
dapan1121 已提交
2296
static int32_t mndProcessTableCfgReq(SRpcMsg *pReq) {
2297 2298 2299 2300
  SMnode      *pMnode = pReq->info.node;
  int32_t      code = -1;
  STableCfgReq cfgReq = {0};
  STableCfgRsp cfgRsp = {0};
D
dapan1121 已提交
2301 2302 2303 2304 2305 2306 2307

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

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

D
dapan1121 已提交
2361
  hbRsp.pIndexRsp = taosArrayInit(numOfStbs, sizeof(STableIndexRsp));
D
dapan1121 已提交
2362
  if (NULL == hbRsp.pIndexRsp) {
D
dapan1121 已提交
2363
    taosArrayDestroy(hbRsp.pMetaRsp);
D
dapan1121 已提交
2364 2365 2366
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
L
Liu Jicong 已提交
2367

S
Shengliang Guan 已提交
2368
  for (int32_t i = 0; i < numOfStbs; ++i) {
D
dapan1121 已提交
2369
    SSTableVersion *pStbVersion = &pStbVersions[i];
S
Shengliang Guan 已提交
2370 2371 2372
    pStbVersion->suid = be64toh(pStbVersion->suid);
    pStbVersion->sversion = ntohs(pStbVersion->sversion);
    pStbVersion->tversion = ntohs(pStbVersion->tversion);
D
dapan1121 已提交
2373
    pStbVersion->smaVer = ntohl(pStbVersion->smaVer);
S
Shengliang Guan 已提交
2374

S
Shengliang Guan 已提交
2375
    STableMetaRsp metaRsp = {0};
L
Liu Jicong 已提交
2376
    int32_t       smaVer = 0;
2377
    mInfo("stb:%s.%s, start to retrieve meta", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2378
    if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
S
Shengliang Guan 已提交
2379 2380
      metaRsp.numOfColumns = -1;
      metaRsp.suid = pStbVersion->suid;
D
dapan1121 已提交
2381
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2382
      continue;
D
dapan 已提交
2383
    }
S
Shengliang Guan 已提交
2384

D
dapan1121 已提交
2385
    if (pStbVersion->sversion != metaRsp.sversion || pStbVersion->tversion != metaRsp.tversion) {
D
dapan1121 已提交
2386
      taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
D
dapan1121 已提交
2387 2388
    } else {
      tFreeSTableMetaRsp(&metaRsp);
S
Shengliang Guan 已提交
2389
    }
D
dapan1121 已提交
2390

D
dapan1121 已提交
2391
    if (pStbVersion->smaVer && pStbVersion->smaVer != smaVer) {
L
Liu Jicong 已提交
2392 2393
      bool           exist = false;
      char           tbFName[TSDB_TABLE_FNAME_LEN];
D
dapan1121 已提交
2394
      STableIndexRsp indexRsp = {0};
D
dapan1121 已提交
2395 2396 2397 2398 2399
      indexRsp.pIndex = taosArrayInit(10, sizeof(STableIndexInfo));
      if (NULL == indexRsp.pIndex) {
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        return -1;
      }
L
Liu Jicong 已提交
2400

D
dapan1121 已提交
2401
      sprintf(tbFName, "%s.%s", pStbVersion->dbFName, pStbVersion->stbName);
D
dapan1121 已提交
2402
      int32_t code = mndGetTableSma(pMnode, tbFName, &indexRsp, &exist);
D
dapan1121 已提交
2403
      if (code || !exist) {
D
dapan1121 已提交
2404 2405 2406
        indexRsp.suid = pStbVersion->suid;
        indexRsp.version = -1;
        indexRsp.pIndex = NULL;
D
dapan1121 已提交
2407
      }
D
dapan1121 已提交
2408

D
dapan1121 已提交
2409 2410
      strcpy(indexRsp.dbFName, pStbVersion->dbFName);
      strcpy(indexRsp.tbName, pStbVersion->stbName);
D
dapan1121 已提交
2411 2412

      taosArrayPush(hbRsp.pIndexRsp, &indexRsp);
D
dapan1121 已提交
2413
    }
S
Shengliang Guan 已提交
2414
  }
S
Shengliang Guan 已提交
2415

D
dapan1121 已提交
2416
  int32_t rspLen = tSerializeSSTbHbRsp(NULL, 0, &hbRsp);
S
Shengliang Guan 已提交
2417
  if (rspLen < 0) {
D
dapan1121 已提交
2418
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2419 2420
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
2421 2422
  }

wafwerar's avatar
wafwerar 已提交
2423
  void *pRsp = taosMemoryMalloc(rspLen);
S
Shengliang Guan 已提交
2424
  if (pRsp == NULL) {
D
dapan1121 已提交
2425
    tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2426 2427
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
2428 2429
  }

D
dapan1121 已提交
2430 2431
  tSerializeSSTbHbRsp(pRsp, rspLen, &hbRsp);
  tFreeSSTbHbRsp(&hbRsp);
S
Shengliang Guan 已提交
2432 2433
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
2434 2435 2436
  return 0;
}

2437
int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
2438
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2439 2440 2441 2442 2443 2444
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
2445
  int32_t numOfStbs = 0;
2446
  void   *pIter = NULL;
S
Shengliang Guan 已提交
2447
  while (1) {
S
Shengliang Guan 已提交
2448
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
2449
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2450 2451
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
2452
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
2453
      numOfStbs++;
S
Shengliang Guan 已提交
2454 2455
    }

S
Shengliang Guan 已提交
2456
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2457 2458
  }

S
Shengliang Guan 已提交
2459
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
2460
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
2461 2462 2463
  return 0;
}

L
Liu Jicong 已提交
2464 2465 2466 2467 2468 2469 2470 2471
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 已提交
2472 2473
  int32_t pos = -1;
  int32_t num = 0;
L
Liu Jicong 已提交
2474 2475
  for (pos = 0; stbFullName[pos] != 0; ++pos) {
    if (stbFullName[pos] == TS_PATH_DELIMITER[0]) num++;
S
Shengliang Guan 已提交
2476 2477 2478 2479
    if (num == 2) break;
  }

  if (num == 2) {
L
Liu Jicong 已提交
2480
    tstrncpy(dst, stbFullName + pos + 1, dstSize);
S
Shengliang Guan 已提交
2481 2482 2483
  }
}

S
Shengliang Guan 已提交
2484 2485
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode  *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
2486
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
2487 2488 2489
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
2490

H
Hongze Cheng 已提交
2491
  SDbObj *pDb = NULL;
H
Haojun Liao 已提交
2492 2493
  if (strlen(pShow->db) > 0) {
    pDb = mndAcquireDb(pMnode, pShow->db);
D
dapan1121 已提交
2494
    if (pDb == NULL) return terrno;
H
Haojun Liao 已提交
2495
  }
S
Shengliang Guan 已提交
2496

S
Shengliang Guan 已提交
2497
  while (numOfRows < rows) {
S
Shengliang Guan 已提交
2498
    pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
S
Shengliang Guan 已提交
2499 2500
    if (pShow->pIter == NULL) break;

H
Haojun Liao 已提交
2501
    if (pDb != NULL && pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
2502
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2503 2504 2505 2506 2507
      continue;
    }

    cols = 0;

H
Haojun Liao 已提交
2508
    SName name = {0};
H
Hongze Cheng 已提交
2509
    char  stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
L
Liu Jicong 已提交
2510
    mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
2511
    varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
S
Shengliang Guan 已提交
2512

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

H
Hongze Cheng 已提交
2516 2517
    char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
2518 2519 2520
    tNameGetDbName(&name, varDataVal(db));
    varDataSetLen(db, strlen(varDataVal(db)));

2521
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
H
Hongze Cheng 已提交
2522
    colDataAppend(pColInfo, numOfRows, (const char *)db, false);
2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535

    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

2536
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
wmmhello's avatar
wmmhello 已提交
2537 2538 2539 2540
    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);
2541
    } else if (pStb->commentLen == 0) {
wmmhello's avatar
wmmhello 已提交
2542 2543 2544 2545 2546
      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 已提交
2547
    }
H
Haojun Liao 已提交
2548

2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562
    char watermark[64 + VARSTR_HEADER_SIZE] = {0};
    sprintf(varDataVal(watermark), "%" PRId64 "a,%" PRId64 "a", pStb->watermark[0], pStb->watermark[1]);
    varDataSetLen(watermark, strlen(varDataVal(watermark)));

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

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

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

S
Shengliang Guan 已提交
2563
    char    rollup[160 + VARSTR_HEADER_SIZE] = {0};
2564
    int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
D
dapan1121 已提交
2565 2566
    char   *sep = ", ";
    int32_t sepLen = strlen(sep);
D
dapan1121 已提交
2567
    int32_t rollupLen = sizeof(rollup) - VARSTR_HEADER_SIZE - 2;
2568 2569 2570
    for (int32_t i = 0; i < rollupNum; ++i) {
      char *funcName = taosArrayGet(pStb->pFuncs, i);
      if (i) {
D
dapan1121 已提交
2571 2572
        strncat(varDataVal(rollup), sep, rollupLen);
        rollupLen -= sepLen;
2573
      }
D
dapan1121 已提交
2574 2575
      strncat(varDataVal(rollup), funcName, rollupLen);
      rollupLen -= strlen(funcName);
2576 2577 2578 2579 2580 2581
    }
    varDataSetLen(rollup, strlen(varDataVal(rollup)));

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

S
Shengliang Guan 已提交
2582
    numOfRows++;
S
Shengliang Guan 已提交
2583
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
2584 2585
  }

H
Haojun Liao 已提交
2586 2587 2588 2589
  if (pDb != NULL) {
    mndReleaseDb(pMnode, pDb);
  }

2590
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
2591 2592 2593
  return numOfRows;
}

S
Shengliang Guan 已提交
2594
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
2595 2596
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan1121 已提交
2597
}
S
Shengliang Guan 已提交
2598 2599 2600 2601 2602 2603 2604 2605 2606 2607

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

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