mndStb.c 46.4 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 "mndAuth.h"
S
Shengliang Guan 已提交
19
#include "mndDb.h"
S
Shengliang Guan 已提交
20 21 22 23 24
#include "mndDnode.h"
#include "mndMnode.h"
#include "mndShow.h"
#include "mndTrans.h"
#include "mndUser.h"
25
#include "mndVgroup.h"
S
Shengliang Guan 已提交
26
#include "tname.h"
S
Shengliang Guan 已提交
27

S
Shengliang Guan 已提交
28
#define TSDB_STB_VER_NUMBER 1
S
Shengliang Guan 已提交
29 30 31 32 33
#define TSDB_STB_RESERVE_SIZE 64

static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
static int32_t  mndStbActionInsert(SSdb *pSdb, SStbObj *pStb);
static int32_t  mndStbActionDelete(SSdb *pSdb, SStbObj *pStb);
S
Shengliang Guan 已提交
34 35
static int32_t  mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew);
static int32_t  mndProcessMCreateStbReq(SMnodeMsg *pReq);
S
Shengliang Guan 已提交
36
static int32_t  mndProcessMAlterStbReq(SMnodeMsg *pReq);
S
Shengliang Guan 已提交
37 38
static int32_t  mndProcessMDropStbReq(SMnodeMsg *pReq);
static int32_t  mndProcessVCreateStbRsp(SMnodeMsg *pRsp);
S
Shengliang Guan 已提交
39
static int32_t  mndProcessVAlterStbRsp(SMnodeMsg *pRsp);
S
Shengliang Guan 已提交
40 41 42 43
static int32_t  mndProcessVDropStbRsp(SMnodeMsg *pRsp);
static int32_t  mndProcessStbMetaReq(SMnodeMsg *pReq);
static int32_t  mndGetStbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta);
static int32_t  mndRetrieveStb(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows);
S
Shengliang Guan 已提交
44 45 46 47
static void     mndCancelGetNextStb(SMnode *pMnode, void *pIter);

int32_t mndInitStb(SMnode *pMnode) {
  SSdbTable table = {.sdbType = SDB_STB,
S
Shengliang Guan 已提交
48
                     .keyType = SDB_KEY_BINARY,
S
Shengliang Guan 已提交
49 50 51 52 53 54
                     .encodeFp = (SdbEncodeFp)mndStbActionEncode,
                     .decodeFp = (SdbDecodeFp)mndStbActionDecode,
                     .insertFp = (SdbInsertFp)mndStbActionInsert,
                     .updateFp = (SdbUpdateFp)mndStbActionUpdate,
                     .deleteFp = (SdbDeleteFp)mndStbActionDelete};

S
Shengliang Guan 已提交
55
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STB, mndProcessMCreateStbReq);
S
Shengliang Guan 已提交
56
  mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessMAlterStbReq);
S
Shengliang Guan 已提交
57 58
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessMDropStbReq);
  mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndProcessVCreateStbRsp);
S
Shengliang Guan 已提交
59
  mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndProcessVAlterStbRsp);
S
Shengliang Guan 已提交
60 61
  mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndProcessVDropStbRsp);
  mndSetMsgHandle(pMnode, TDMT_MND_STB_META, mndProcessStbMetaReq);
S
Shengliang Guan 已提交
62 63 64 65

  mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_STB, mndGetStbMeta);
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb);
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STB, mndCancelGetNextStb);
S
Shengliang Guan 已提交
66 67

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

S
Shengliang Guan 已提交
70
void mndCleanupStb(SMnode *pMnode) {}
S
Shengliang Guan 已提交
71

72
SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
73 74
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
75
  int32_t  size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + TSDB_STB_RESERVE_SIZE;
S
Shengliang Guan 已提交
76
  SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, TSDB_STB_VER_NUMBER, size);
77
  if (pRaw == NULL) goto STB_ENCODE_OVER;
S
Shengliang Guan 已提交
78 79

  int32_t dataPos = 0;
80 81 82 83 84 85 86
  SDB_SET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, STB_ENCODE_OVER)
  SDB_SET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, STB_ENCODE_OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->createdTime, STB_ENCODE_OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->updateTime, STB_ENCODE_OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->uid, STB_ENCODE_OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->dbUid, STB_ENCODE_OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->version, STB_ENCODE_OVER)
S
Shengliang Guan 已提交
87
  SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, STB_ENCODE_OVER)
88 89
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, STB_ENCODE_OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, STB_ENCODE_OVER)
S
Shengliang Guan 已提交
90

S
Shengliang Guan 已提交
91 92 93 94 95 96 97 98 99 100
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, STB_ENCODE_OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->colId, STB_ENCODE_OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, STB_ENCODE_OVER)
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, STB_ENCODE_OVER)
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
101 102 103 104
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, STB_ENCODE_OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->colId, STB_ENCODE_OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, STB_ENCODE_OVER)
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, STB_ENCODE_OVER)
S
Shengliang Guan 已提交
105 106
  }

S
Shengliang Guan 已提交
107
  SDB_SET_BINARY(pRaw, dataPos, pStb->comment, TSDB_STB_COMMENT_LEN, STB_ENCODE_OVER)
108 109 110 111 112 113 114 115 116 117 118
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_STB_RESERVE_SIZE, STB_ENCODE_OVER)
  SDB_SET_DATALEN(pRaw, dataPos, STB_ENCODE_OVER)

  terrno = 0;

STB_ENCODE_OVER:
  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 已提交
119

120
  mTrace("stb:%s, encode to raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
121 122 123
  return pRaw;
}

S
Shengliang Guan 已提交
124
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
125 126
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
127
  int8_t sver = 0;
128
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto STB_DECODE_OVER;
S
Shengliang Guan 已提交
129

S
Shengliang Guan 已提交
130
  if (sver != TSDB_STB_VER_NUMBER) {
S
Shengliang Guan 已提交
131
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
132
    goto STB_DECODE_OVER;
S
Shengliang Guan 已提交
133 134
  }

S
Shengliang 已提交
135
  SSdbRow *pRow = sdbAllocRow(sizeof(SStbObj));
136 137
  if (pRow == NULL) goto STB_DECODE_OVER;

S
Shengliang Guan 已提交
138
  SStbObj *pStb = sdbGetRowObj(pRow);
139
  if (pStb == NULL) goto STB_DECODE_OVER;
S
Shengliang Guan 已提交
140 141

  int32_t dataPos = 0;
142 143 144 145 146 147 148
  SDB_GET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, STB_DECODE_OVER)
  SDB_GET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, STB_DECODE_OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->createdTime, STB_DECODE_OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->updateTime, STB_DECODE_OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->uid, STB_DECODE_OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->dbUid, STB_DECODE_OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->version, STB_DECODE_OVER)
S
Shengliang Guan 已提交
149
  SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, STB_DECODE_OVER)
150 151
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, STB_DECODE_OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, STB_DECODE_OVER)
S
Shengliang Guan 已提交
152

S
Shengliang Guan 已提交
153 154 155
  pStb->pColumns = calloc(pStb->numOfColumns, sizeof(SSchema));
  pStb->pTags = calloc(pStb->numOfTags, sizeof(SSchema));
  if (pStb->pColumns == NULL || pStb->pTags == NULL) {
S
Shengliang 已提交
156 157
    goto STB_DECODE_OVER;
  }
S
Shengliang Guan 已提交
158

S
Shengliang Guan 已提交
159 160 161 162 163 164 165 166 167 168
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, STB_DECODE_OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->colId, STB_DECODE_OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, STB_DECODE_OVER)
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, STB_DECODE_OVER)
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
169 170 171 172
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, STB_DECODE_OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->colId, STB_DECODE_OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, STB_DECODE_OVER)
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, STB_DECODE_OVER)
S
Shengliang Guan 已提交
173 174
  }

S
Shengliang Guan 已提交
175
  SDB_GET_BINARY(pRaw, dataPos, pStb->comment, TSDB_STB_COMMENT_LEN, STB_DECODE_OVER)
176 177 178 179 180 181 182
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_STB_RESERVE_SIZE, STB_DECODE_OVER)

  terrno = 0;

STB_DECODE_OVER:
  if (terrno != 0) {
    mError("stb:%s, failed to decode from raw:%p since %s", pStb->name, pRaw, terrstr());
183 184
    tfree(pStb->pColumns);
    tfree(pStb->pTags);
185 186 187
    tfree(pRow);
    return NULL;
  }
S
Shengliang Guan 已提交
188

189
  mTrace("stb:%s, decode from raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
190 191 192
  return pRow;
}

S
Shengliang Guan 已提交
193
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
194
  mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
S
Shengliang Guan 已提交
195 196 197
  return 0;
}

S
Shengliang Guan 已提交
198
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
199
  mTrace("stb:%s, perform delete action, row:%p", pStb->name, pStb);
S
Shengliang Guan 已提交
200 201
  tfree(pStb->pColumns);
  tfree(pStb->pTags);
S
Shengliang Guan 已提交
202 203 204
  return 0;
}

S
Shengliang Guan 已提交
205 206
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 已提交
207

S
Shengliang Guan 已提交
208
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
209 210

  if (pOld->numOfColumns < pNew->numOfColumns) {
S
Shengliang Guan 已提交
211 212
    void *pColumns = malloc(pNew->numOfColumns * sizeof(SSchema));
    if (pColumns != NULL) {
S
Shengliang Guan 已提交
213
      free(pOld->pColumns);
S
Shengliang Guan 已提交
214
      pOld->pColumns = pColumns;
S
Shengliang Guan 已提交
215 216 217 218 219 220 221 222
    } 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) {
S
Shengliang Guan 已提交
223 224
    void *pTags = malloc(pNew->numOfTags * sizeof(SSchema));
    if (pTags != NULL) {
S
Shengliang Guan 已提交
225
      free(pOld->pTags);
S
Shengliang Guan 已提交
226
      pOld->pTags = pTags;
S
Shengliang Guan 已提交
227 228 229 230
    } 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 已提交
231
    }
S
Shengliang Guan 已提交
232 233
  }

S
Shengliang Guan 已提交
234 235
  pOld->updateTime = pNew->updateTime;
  pOld->version = pNew->version;
S
Shengliang Guan 已提交
236
  pOld->nextColId = pNew->nextColId;
S
Shengliang Guan 已提交
237 238
  pOld->numOfColumns = pNew->numOfColumns;
  pOld->numOfTags = pNew->numOfTags;
S
Shengliang Guan 已提交
239 240
  memcpy(pOld->pColumns, pNew->pColumns, pOld->numOfColumns * sizeof(SSchema));
  memcpy(pOld->pTags, pNew->pTags, pOld->numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
241
  memcpy(pOld->comment, pNew->comment, TSDB_STB_COMMENT_LEN);
S
Shengliang Guan 已提交
242
  taosWUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
243 244 245
  return 0;
}

S
Shengliang Guan 已提交
246
SStbObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
247
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
248
  SStbObj *pStb = sdbAcquire(pSdb, SDB_STB, stbName);
S
Shengliang Guan 已提交
249
  if (pStb == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
S
Shengliang Guan 已提交
250 251 252
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
  }
  return pStb;
S
Shengliang Guan 已提交
253 254
}

S
Shengliang Guan 已提交
255
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
S
Shengliang Guan 已提交
256 257 258 259
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pStb);
}

S
Shengliang Guan 已提交
260
static SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
S
Shengliang Guan 已提交
261 262
  SName name = {0};
  tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
S
Shengliang Guan 已提交
263

S
Shengliang Guan 已提交
264 265
  char db[TSDB_TABLE_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, db);
S
Shengliang Guan 已提交
266

S
Shengliang Guan 已提交
267 268
  return mndAcquireDb(pMnode, db);
}
S
Shengliang Guan 已提交
269

S
Shengliang Guan 已提交
270
static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
271
  SName name = {0};
S
Shengliang Guan 已提交
272
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
273

S
Shengliang Guan 已提交
274 275
  SVCreateTbReq req = {0};
  req.ver = 0;
S
Shengliang Guan 已提交
276
  req.name = (char *)tNameGetTableName(&name);
H
more  
Hongze Cheng 已提交
277 278 279 280 281
  req.ttl = 0;
  req.keep = 0;
  req.type = TD_SUPER_TABLE;
  req.stbCfg.suid = pStb->uid;
  req.stbCfg.nCols = pStb->numOfColumns;
S
Shengliang Guan 已提交
282
  req.stbCfg.pSchema = pStb->pColumns;
H
more  
Hongze Cheng 已提交
283
  req.stbCfg.nTagCols = pStb->numOfTags;
S
Shengliang Guan 已提交
284
  req.stbCfg.pTagSchema = pStb->pTags;
H
more  
Hongze Cheng 已提交
285

S
Shengliang Guan 已提交
286 287 288
  int32_t   contLen = tSerializeSVCreateTbReq(NULL, &req) + sizeof(SMsgHead);
  SMsgHead *pHead = malloc(contLen);
  if (pHead == NULL) {
H
more  
Hongze Cheng 已提交
289 290 291 292
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
293 294
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);
H
more  
Hongze Cheng 已提交
295

S
Shengliang Guan 已提交
296
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
H
more  
Hongze Cheng 已提交
297 298
  tSerializeSVCreateTbReq(&pBuf, &req);

S
Shengliang Guan 已提交
299 300
  *pContLen = contLen;
  return pHead;
301 302
}

S
Shengliang Guan 已提交
303
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
S
Shengliang Guan 已提交
304 305 306 307 308 309 310 311
  SName name = {0};
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

  SVDropTbReq req = {0};
  req.ver = 0;
  req.name = (char *)tNameGetTableName(&name);
  req.type = TD_SUPER_TABLE;
  req.suid = pStb->uid;
312

S
Shengliang Guan 已提交
313 314 315
  int32_t   contLen = tSerializeSVDropTbReq(NULL, &req) + sizeof(SMsgHead);
  SMsgHead *pHead = malloc(contLen);
  if (pHead == NULL) {
316 317 318 319
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
320 321 322 323 324
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);

  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
  tSerializeSVDropTbReq(&pBuf, &req);
325

S
Shengliang Guan 已提交
326 327
  *pContLen = contLen;
  return pHead;
328 329
}

S
Shengliang Guan 已提交
330
static int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
S
Shengliang Guan 已提交
331
  if (pCreate->igExists < 0 || pCreate->igExists > 1) {
S
Shengliang Guan 已提交
332
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
333 334
    return -1;
  }
S
Shengliang Guan 已提交
335

S
Shengliang Guan 已提交
336
  if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
S
Shengliang Guan 已提交
337
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
338 339
    return -1;
  }
S
Shengliang Guan 已提交
340

S
Shengliang Guan 已提交
341
  if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
S
Shengliang Guan 已提交
342
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
343 344
    return -1;
  }
S
Shengliang Guan 已提交
345

S
Shengliang Guan 已提交
346
  SField *pField = taosArrayGet(pCreate->pColumns, 0);
S
Shengliang Guan 已提交
347
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
S
Shengliang Guan 已提交
348 349 350 351
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }

S
Shengliang Guan 已提交
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
  for (int32_t i = 0; i < pCreate->numOfColumns; ++i) {
    SField *pField = taosArrayGet(pCreate->pColumns, i);
    if (pField->type < 0) {
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
    if (pField->bytes <= 0) {
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
    if (pField->name[0] == 0) {
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
  }

  for (int32_t i = 0; i < pCreate->numOfTags; ++i) {
    SField *pField = taosArrayGet(pCreate->pTags, i);
    if (pField->type < 0) {
S
Shengliang Guan 已提交
371
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
372 373
      return -1;
    }
S
Shengliang Guan 已提交
374
    if (pField->bytes <= 0) {
S
Shengliang Guan 已提交
375
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
376 377
      return -1;
    }
S
Shengliang Guan 已提交
378
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
379
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
380 381 382
      return -1;
    }
  }
S
Shengliang Guan 已提交
383

S
Shengliang Guan 已提交
384 385 386
  return 0;
}

387
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
388 389 390 391 392 393 394 395
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1;

  return 0;
}

396
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
397 398 399 400 401 402 403 404
  SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
  if (pUndoRaw == NULL) return -1;
  if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) return -1;
  if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

405
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
406 407 408 409 410 411 412 413
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

414
static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
415
  SSdb   *pSdb = pMnode->pSdb;
416
  SVgObj *pVgroup = NULL;
417
  void   *pIter = NULL;
S
Shengliang Guan 已提交
418
  int32_t contLen;
419 420 421 422

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
423 424 425 426
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
427

S
Shengliang Guan 已提交
428
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
429
    if (pReq == NULL) {
430 431 432 433 434
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
435

436 437
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
438
    action.pCont = pReq;
S
Shengliang Guan 已提交
439
    action.contLen = contLen;
H
Hongze Cheng 已提交
440
    action.msgType = TDMT_VND_CREATE_STB;
441
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
S
Shengliang Guan 已提交
442
      free(pReq);
443 444 445 446 447 448
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
449 450 451 452

  return 0;
}

453
static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
454
  SSdb   *pSdb = pMnode->pSdb;
455
  SVgObj *pVgroup = NULL;
456
  void   *pIter = NULL;
457 458 459 460

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
461 462 463 464
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
465

S
Shengliang Guan 已提交
466
    int32_t contLen = 0;
S
Shengliang Guan 已提交
467
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
468
    if (pReq == NULL) {
469 470 471 472 473
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
474

475 476
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
477
    action.pCont = pReq;
S
Shengliang Guan 已提交
478
    action.contLen = contLen;
H
Hongze Cheng 已提交
479
    action.msgType = TDMT_VND_DROP_STB;
480
    if (mndTransAppendUndoAction(pTrans, &action) != 0) {
S
Shengliang Guan 已提交
481
      free(pReq);
482 483 484 485 486 487
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
488 489 490 491

  return 0;
}

S
Shengliang Guan 已提交
492
static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
S
Shengliang Guan 已提交
493
  SStbObj stbObj = {0};
S
Shengliang Guan 已提交
494 495
  memcpy(stbObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN);
  memcpy(stbObj.db, pDb->name, TSDB_DB_FNAME_LEN);
S
Shengliang Guan 已提交
496 497
  stbObj.createdTime = taosGetTimestampMs();
  stbObj.updateTime = stbObj.createdTime;
S
Shengliang Guan 已提交
498
  stbObj.uid = mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
S
Shengliang Guan 已提交
499
  stbObj.dbUid = pDb->uid;
S
Shengliang Guan 已提交
500
  stbObj.version = 1;
S
Shengliang Guan 已提交
501
  stbObj.nextColId = 1;
S
Shengliang Guan 已提交
502 503 504
  stbObj.numOfColumns = pCreate->numOfColumns;
  stbObj.numOfTags = pCreate->numOfTags;

S
Shengliang Guan 已提交
505 506
  stbObj.pColumns = malloc(stbObj.numOfColumns * sizeof(SSchema));
  stbObj.pTags = malloc(stbObj.numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
507
  if (stbObj.pColumns == NULL || stbObj.pTags == NULL) {
S
Shengliang Guan 已提交
508 509 510
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
511

S
Shengliang Guan 已提交
512
  for (int32_t i = 0; i < stbObj.numOfColumns; ++i) {
S
Shengliang Guan 已提交
513 514 515 516 517 518
    SField  *pField = taosArrayGet(pCreate->pColumns, i);
    SSchema *pSchema = &stbObj.pColumns[i];
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
    pSchema->colId = stbObj.nextColId;
S
Shengliang Guan 已提交
519 520 521 522
    stbObj.nextColId++;
  }

  for (int32_t i = 0; i < stbObj.numOfTags; ++i) {
S
Shengliang Guan 已提交
523 524 525 526 527 528
    SField  *pField = taosArrayGet(pCreate->pTags, i);
    SSchema *pSchema = &stbObj.pTags[i];
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
    pSchema->colId = stbObj.nextColId;
S
Shengliang Guan 已提交
529
    stbObj.nextColId++;
S
Shengliang Guan 已提交
530 531
  }

S
Shengliang 已提交
532
  int32_t code = -1;
S
Shengliang Guan 已提交
533
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_STB, &pReq->rpcMsg);
S
Shengliang Guan 已提交
534
  if (pTrans == NULL) goto CREATE_STB_OVER;
S
Shengliang Guan 已提交
535

S
Shengliang Guan 已提交
536
  mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
S
Shengliang Guan 已提交
537

S
Shengliang Guan 已提交
538 539 540 541 542 543
  if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
  if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
  if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
  if (mndSetCreateStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
  if (mndSetCreateStbUndoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto CREATE_STB_OVER;
  if (mndTransPrepare(pMnode, pTrans) != 0) goto CREATE_STB_OVER;
S
Shengliang Guan 已提交
544

S
Shengliang Guan 已提交
545 546 547
  code = 0;

CREATE_STB_OVER:
S
Shengliang Guan 已提交
548
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
549
  return code;
S
Shengliang Guan 已提交
550 551
}

S
Shengliang Guan 已提交
552
static int32_t mndProcessMCreateStbReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
553 554 555 556 557
  SMnode        *pMnode = pReq->pMnode;
  int32_t        code = -1;
  SStbObj       *pTopicStb = NULL;
  SStbObj       *pStb = NULL;
  SDbObj        *pDb = NULL;
S
Shengliang Guan 已提交
558
  SUserObj      *pUser = NULL;
S
Shengliang Guan 已提交
559
  SMCreateStbReq createReq = {0};
S
Shengliang Guan 已提交
560

S
Shengliang Guan 已提交
561 562 563 564
  if (tDeserializeSMCreateStbReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto CREATE_STB_OVER;
  }
S
Shengliang Guan 已提交
565

S
Shengliang Guan 已提交
566
  mDebug("stb:%s, start to create", createReq.name);
S
Shengliang Guan 已提交
567 568 569 570
  if (mndCheckCreateStbReq(&createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto CREATE_STB_OVER;
  }
S
Shengliang Guan 已提交
571

S
Shengliang Guan 已提交
572
  pStb = mndAcquireStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
573
  if (pStb != NULL) {
S
Shengliang Guan 已提交
574 575 576 577
    if (createReq.igExists) {
      mDebug("stb:%s, already exist, ignore exist is set", createReq.name);
      code = 0;
      goto CREATE_STB_OVER;
S
Shengliang Guan 已提交
578 579
    } else {
      terrno = TSDB_CODE_MND_STB_ALREADY_EXIST;
S
Shengliang Guan 已提交
580
      goto CREATE_STB_OVER;
S
Shengliang Guan 已提交
581
    }
S
Shengliang Guan 已提交
582
  } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) {
S
Shengliang Guan 已提交
583
    goto CREATE_STB_OVER;
S
Shengliang Guan 已提交
584 585
  }

S
Shengliang Guan 已提交
586
  pTopicStb = mndAcquireStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
587
  if (pTopicStb != NULL) {
L
Liu Jicong 已提交
588
    terrno = TSDB_CODE_MND_NAME_CONFLICT_WITH_TOPIC;
S
Shengliang Guan 已提交
589
    goto CREATE_STB_OVER;
L
Liu Jicong 已提交
590 591
  }

S
Shengliang Guan 已提交
592
  pDb = mndAcquireDbByStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
593 594
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
S
Shengliang Guan 已提交
595
    goto CREATE_STB_OVER;
S
Shengliang Guan 已提交
596 597
  }

S
Shengliang Guan 已提交
598 599 600 601 602 603 604 605 606
  pUser = mndAcquireUser(pMnode, pReq->user);
  if (pUser == NULL) {
    goto CREATE_STB_OVER;
  }

  if (mndCheckWriteAuth(pUser, pDb) != 0) {
    goto CREATE_STB_OVER;
  }

S
Shengliang Guan 已提交
607
  code = mndCreateStb(pMnode, pReq, &createReq, pDb);
608
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
609

S
Shengliang Guan 已提交
610
CREATE_STB_OVER:
611
  if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
612
    mError("stb:%s, failed to create since %s", createReq.name, terrstr());
S
Shengliang Guan 已提交
613 614
  }

S
Shengliang Guan 已提交
615 616 617
  mndReleaseStb(pMnode, pStb);
  mndReleaseStb(pMnode, pTopicStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
618 619
  mndReleaseUser(pMnode, pUser);
  tFreeSMCreateStbReq(&createReq);
S
Shengliang Guan 已提交
620 621

  return code;
S
Shengliang Guan 已提交
622 623
}

S
Shengliang Guan 已提交
624 625
static int32_t mndProcessVCreateStbRsp(SMnodeMsg *pRsp) {
  mndTransProcessRsp(pRsp);
626 627
  return 0;
}
S
Shengliang Guan 已提交
628

S
Shengliang Guan 已提交
629
static int32_t mndCheckAlterStbReq(SMAltertbReq *pAlter) {
S
Shengliang Guan 已提交
630 631 632 633
  if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }
S
Shengliang Guan 已提交
634

S
Shengliang Guan 已提交
635 636
  for (int32_t i = 0; i < pAlter->numOfFields; ++i) {
    SField *pField = taosArrayGet(pAlter->pFields, i);
S
Shengliang Guan 已提交
637

S
Shengliang Guan 已提交
638
    if (pField->type <= 0) {
S
Shengliang Guan 已提交
639 640 641
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
642
    if (pField->bytes <= 0) {
S
Shengliang Guan 已提交
643 644 645
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
646
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
647 648 649
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
650 651 652 653 654
  }

  return 0;
}

S
Shengliang Guan 已提交
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
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 mndAllocStbSchemas(const SStbObj *pOld, SStbObj *pNew) {
  pNew->pTags = calloc(pNew->numOfTags, sizeof(SSchema));
  pNew->pColumns = calloc(pNew->numOfColumns, sizeof(SSchema));
  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 Guan 已提交
688
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
689 690 691 692 693 694 695 696 697 698
  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 已提交
699 700 701 702 703
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
704
  for (int32_t i = 0; i < ntags; i++) {
S
Shengliang Guan 已提交
705 706
    SField *pField = taosArrayGet(pFields, i);
    if (mndFindSuperTableColumnIndex(pOld, pField->name) > 0) {
S
Shengliang Guan 已提交
707
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
708 709 710
      return -1;
    }

S
Shengliang Guan 已提交
711
    if (mndFindSuperTableTagIndex(pOld, pField->name) > 0) {
S
Shengliang Guan 已提交
712
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
713 714 715
      return -1;
    }

S
Shengliang Guan 已提交
716 717 718 719
    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 已提交
720 721
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
722 723

    mDebug("stb:%s, start to add tag %s", pNew->name, pSchema->name);
S
Shengliang Guan 已提交
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
  }

  pNew->version++;
  return 0;
}

static int32_t mndDropSuperTableTag(const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

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

  memmove(pNew->pTags + tag, pNew->pTags + tag + 1, sizeof(SSchema) * (pNew->numOfTags - tag - 1));
S
Shengliang Guan 已提交
742
  pNew->numOfTags--;
S
Shengliang Guan 已提交
743 744 745 746 747 748

  pNew->version++;
  mDebug("stb:%s, start to drop tag %s", pNew->name, tagName);
  return 0;
}

S
Shengliang Guan 已提交
749 750 751 752 753 754 755 756 757 758 759 760
static int32_t mndAlterStbTagName(const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
  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 已提交
761 762 763 764 765 766 767
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
S
Shengliang Guan 已提交
768
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
769 770 771
    return -1;
  }

S
Shengliang Guan 已提交
772 773
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
    return -1;
  }

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

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

  pNew->version++;
  mDebug("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
  return 0;
}

S
Shengliang Guan 已提交
789 790
static int32_t mndAlterStbTagBytes(const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
791 792 793 794 795 796 797 798 799 800 801
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

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

  SSchema *pTag = pNew->pTags + tag;

S
Shengliang Guan 已提交
802 803 804 805 806
  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 已提交
807
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
808 809 810 811
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

S
Shengliang Guan 已提交
812
  pTag->bytes = pField->bytes;
S
Shengliang Guan 已提交
813 814
  pNew->version++;

S
Shengliang Guan 已提交
815
  mDebug("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
816 817 818
  return 0;
}

S
Shengliang Guan 已提交
819
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ncols) {
S
Shengliang Guan 已提交
820 821 822 823 824
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
825 826 827 828 829
  pNew->numOfColumns = pNew->numOfColumns + ncols;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
830
  for (int32_t i = 0; i < ncols; i++) {
S
Shengliang Guan 已提交
831 832
    SField *pField = taosArrayGet(pFields, i);
    if (mndFindSuperTableColumnIndex(pOld, pField->name) > 0) {
S
Shengliang Guan 已提交
833
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
834 835 836
      return -1;
    }

S
Shengliang Guan 已提交
837
    if (mndFindSuperTableTagIndex(pOld, pField->name) > 0) {
S
Shengliang Guan 已提交
838
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
839 840 841
      return -1;
    }

S
Shengliang Guan 已提交
842 843 844 845
    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 已提交
846 847
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
848 849

    mDebug("stb:%s, start to add column %s", pNew->name, pSchema->name);
S
Shengliang Guan 已提交
850 851 852 853 854 855 856 857
  }

  pNew->version++;
  return 0;
}

static int32_t mndDropSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, const char *colName) {
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
S
Shengliang Guan 已提交
858
  if (col < 0) {
S
Shengliang Guan 已提交
859 860 861 862
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
863 864 865 866 867 868 869 870 871 872
  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;
  }

S
Shengliang Guan 已提交
873 874 875 876 877
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  memmove(pNew->pColumns + col, pNew->pColumns + col + 1, sizeof(SSchema) * (pNew->numOfColumns - col - 1));
S
Shengliang Guan 已提交
878
  pNew->numOfColumns--;
S
Shengliang Guan 已提交
879 880 881 882 883 884

  pNew->version++;
  mDebug("stb:%s, start to drop col %s", pNew->name, colName);
  return 0;
}

S
Shengliang Guan 已提交
885 886
static int32_t mndAlterStbColumnBytes(const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
  int32_t col = mndFindSuperTableColumnIndex(pOld, pField->name);
S
Shengliang Guan 已提交
887 888 889 890 891 892 893
  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 已提交
894
    nLen += (pOld->pColumns[i].colId == col) ? pField->bytes : pOld->pColumns[i].bytes;
S
Shengliang Guan 已提交
895 896 897 898 899 900 901 902 903 904 905 906
  }

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

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

  SSchema *pCol = pNew->pColumns + col;
S
Shengliang Guan 已提交
907 908
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
909 910 911
    return -1;
  }

S
Shengliang Guan 已提交
912
  if (pField->bytes <= pCol->bytes) {
S
Shengliang Guan 已提交
913
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
S
Shengliang Guan 已提交
914 915 916
    return -1;
  }

S
Shengliang Guan 已提交
917
  pCol->bytes = pField->bytes;
S
Shengliang Guan 已提交
918 919
  pNew->version++;

S
Shengliang Guan 已提交
920
  mDebug("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
921 922 923
  return 0;
}

S
Shengliang Guan 已提交
924
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
925 926 927
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
S
Shengliang Guan 已提交
928
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_UPDATING) != 0) return -1;
S
Shengliang Guan 已提交
929 930 931 932

  return 0;
}

S
Shengliang Guan 已提交
933
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
934 935 936 937 938 939 940 941
  SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
  if (pCommitRaw == NULL) return -1;
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;

  return 0;
}

S
Shengliang Guan 已提交
942
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
943 944 945 946 947 948 949 950
  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 已提交
951 952 953 954
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
S
Shengliang Guan 已提交
955

S
Shengliang Guan 已提交
956
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
957 958 959 960 961 962 963 964 965 966 967
    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;
S
Shengliang Guan 已提交
968
    action.msgType = TDMT_VND_ALTER_STB;
S
Shengliang Guan 已提交
969 970 971 972 973 974 975 976 977 978 979 980
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
      free(pReq);
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

S
Shengliang Guan 已提交
981
static int32_t mndAlterStb(SMnode *pMnode, SMnodeMsg *pReq, const SMAltertbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
S
Shengliang Guan 已提交
982 983 984 985 986 987 988 989 990
  SStbObj stbObj = {0};
  taosRLockLatch(&pOld->lock);
  memcpy(&stbObj, pOld, sizeof(SStbObj));
  stbObj.pColumns = NULL;
  stbObj.pTags = NULL;
  stbObj.updateTime = taosGetTimestampMs();
  taosRUnLockLatch(&pOld->lock);

  int32_t code = -1;
S
Shengliang Guan 已提交
991
  STrans *pTrans = NULL;
S
Shengliang Guan 已提交
992
  SField *pField0 = taosArrayGet(pAlter->pFields, 0);
S
Shengliang Guan 已提交
993

S
Shengliang Guan 已提交
994
  switch (pAlter->alterType) {
S
Shengliang Guan 已提交
995
    case TSDB_ALTER_TABLE_ADD_TAG:
S
Shengliang Guan 已提交
996
      code = mndAddSuperTableTag(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
997
      break;
S
Shengliang Guan 已提交
998
    case TSDB_ALTER_TABLE_DROP_TAG:
S
Shengliang Guan 已提交
999
      code = mndDropSuperTableTag(pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1000
      break;
S
Shengliang Guan 已提交
1001
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
S
Shengliang Guan 已提交
1002
      code = mndAlterStbTagName(pOld, &stbObj, pAlter->pFields);
S
Shengliang Guan 已提交
1003
      break;
S
Shengliang Guan 已提交
1004
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
S
Shengliang Guan 已提交
1005
      code = mndAlterStbTagBytes(pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1006 1007
      break;
    case TSDB_ALTER_TABLE_ADD_COLUMN:
S
Shengliang Guan 已提交
1008
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1009 1010
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
S
Shengliang Guan 已提交
1011
      code = mndDropSuperTableColumn(pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1012
      break;
S
Shengliang Guan 已提交
1013
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
S
Shengliang Guan 已提交
1014
      code = mndAlterStbColumnBytes(pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1015 1016 1017 1018 1019 1020
      break;
    default:
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      break;
  }

S
Shengliang Guan 已提交
1021
  if (code != 0) goto ALTER_STB_OVER;
S
Shengliang Guan 已提交
1022 1023

  code = -1;
S
Shengliang Guan 已提交
1024
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_ALTER_STB, &pReq->rpcMsg);
S
Shengliang Guan 已提交
1025
  if (pTrans == NULL) goto ALTER_STB_OVER;
S
Shengliang Guan 已提交
1026

S
Shengliang Guan 已提交
1027
  mDebug("trans:%d, used to alter stb:%s", pTrans->id, pAlter->name);
S
Shengliang Guan 已提交
1028

S
Shengliang Guan 已提交
1029 1030 1031 1032
  if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto ALTER_STB_OVER;
  if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto ALTER_STB_OVER;
  if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto ALTER_STB_OVER;
  if (mndTransPrepare(pMnode, pTrans) != 0) goto ALTER_STB_OVER;
S
Shengliang Guan 已提交
1033 1034

  code = 0;
S
Shengliang Guan 已提交
1035

S
Shengliang Guan 已提交
1036
ALTER_STB_OVER:
S
Shengliang Guan 已提交
1037 1038 1039
  mndTransDrop(pTrans);
  tfree(stbObj.pTags);
  tfree(stbObj.pColumns);
S
Shengliang Guan 已提交
1040 1041
  return code;
}
S
Shengliang Guan 已提交
1042

S
Shengliang Guan 已提交
1043
static int32_t mndProcessMAlterStbReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
1044 1045 1046 1047
  SMnode      *pMnode = pReq->pMnode;
  int32_t      code = -1;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
1048
  SUserObj    *pUser = NULL;
S
Shengliang Guan 已提交
1049
  SMAltertbReq alterReq = {0};
S
Shengliang Guan 已提交
1050

S
Shengliang Guan 已提交
1051
  if (tDeserializeSMAlterStbReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
1052 1053 1054
    terrno = TSDB_CODE_INVALID_MSG;
    goto ALTER_STB_OVER;
  }
S
Shengliang Guan 已提交
1055

S
Shengliang Guan 已提交
1056 1057
  mDebug("stb:%s, start to alter", alterReq.name);
  if (mndCheckAlterStbReq(&alterReq) != 0) goto ALTER_STB_OVER;
S
Shengliang Guan 已提交
1058

S
Shengliang Guan 已提交
1059
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1060 1061
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_INVALID_DB;
S
Shengliang Guan 已提交
1062
    goto ALTER_STB_OVER;
S
Shengliang Guan 已提交
1063 1064
  }

S
Shengliang Guan 已提交
1065
  pStb = mndAcquireStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1066 1067
  if (pStb == NULL) {
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
S
Shengliang Guan 已提交
1068
    goto ALTER_STB_OVER;
S
Shengliang Guan 已提交
1069
  }
S
Shengliang Guan 已提交
1070

S
Shengliang Guan 已提交
1071 1072 1073 1074 1075 1076 1077 1078 1079
  pUser = mndAcquireUser(pMnode, pReq->user);
  if (pUser == NULL) {
    goto ALTER_STB_OVER;
  }

  if (mndCheckWriteAuth(pUser, pDb) != 0) {
    goto ALTER_STB_OVER;
  }

S
Shengliang Guan 已提交
1080
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
1081
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1082

S
Shengliang Guan 已提交
1083
ALTER_STB_OVER:
1084
  if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1085
    mError("stb:%s, failed to alter since %s", alterReq.name, terrstr());
S
Shengliang Guan 已提交
1086 1087
  }

S
Shengliang Guan 已提交
1088 1089
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1090
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
1091
  taosArrayDestroy(alterReq.pFields);
S
Shengliang Guan 已提交
1092 1093

  return code;
S
Shengliang Guan 已提交
1094
}
S
Shengliang Guan 已提交
1095

S
Shengliang Guan 已提交
1096
static int32_t mndProcessVAlterStbRsp(SMnodeMsg *pRsp) {
S
Shengliang Guan 已提交
1097
  mndTransProcessRsp(pRsp);
1098 1099
  return 0;
}
S
Shengliang Guan 已提交
1100

S
Shengliang Guan 已提交
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
  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;
  if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
  if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;

  return 0;
}

S
Shengliang Guan 已提交
1119 1120 1121 1122 1123
static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
  SSdb   *pSdb = pMnode->pSdb;
  SVgObj *pVgroup = NULL;
  void   *pIter = NULL;
  int32_t contLen;
S
Shengliang Guan 已提交
1124

S
Shengliang Guan 已提交
1125 1126 1127
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
1128 1129 1130 1131
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
S
Shengliang Guan 已提交
1132

S
Shengliang Guan 已提交
1133
    int32_t contLen = 0;
S
Shengliang Guan 已提交
1134
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
    if (pReq == NULL) {
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }

    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
    action.pCont = pReq;
    action.contLen = contLen;
    action.msgType = TDMT_VND_DROP_STB;
    action.acceptableCode = TSDB_CODE_VND_TB_NOT_EXIST;
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
      free(pReq);
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

static int32_t mndDropStb(SMnode *pMnode, SMnodeMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1161
  int32_t code = -1;
S
Shengliang Guan 已提交
1162
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK,TRN_TYPE_DROP_STB, &pReq->rpcMsg);
S
Shengliang Guan 已提交
1163
  if (pTrans == NULL) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1164

S
Shengliang Guan 已提交
1165
  mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
S
Shengliang Guan 已提交
1166

S
Shengliang Guan 已提交
1167 1168
  if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
  if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1169
  if (mndSetDropStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1170
  if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1171

S
Shengliang Guan 已提交
1172 1173 1174
  code = 0;

DROP_STB_OVER:
S
Shengliang Guan 已提交
1175
  mndTransDrop(pTrans);
S
Shengliang 已提交
1176
  return code;
S
Shengliang Guan 已提交
1177 1178
}

S
Shengliang Guan 已提交
1179
static int32_t mndProcessMDropStbReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
1180 1181 1182 1183 1184
  SMnode      *pMnode = pReq->pMnode;
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
1185
  SMDropStbReq dropReq = {0};
S
Shengliang Guan 已提交
1186

S
Shengliang Guan 已提交
1187
  if (tDeserializeSMDropStbReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
1188 1189 1190
    terrno = TSDB_CODE_INVALID_MSG;
    goto DROP_STB_OVER;
  }
S
Shengliang Guan 已提交
1191

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

S
Shengliang Guan 已提交
1194
  pStb = mndAcquireStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
1195
  if (pStb == NULL) {
S
Shengliang Guan 已提交
1196 1197
    if (dropReq.igNotExists) {
      mDebug("stb:%s, not exist, ignore not exist is set", dropReq.name);
S
Shengliang Guan 已提交
1198 1199
      code = 0;
      goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1200 1201
    } else {
      terrno = TSDB_CODE_MND_STB_NOT_EXIST;
S
Shengliang Guan 已提交
1202
      goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1203 1204 1205
    }
  }

S
Shengliang Guan 已提交
1206
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
1207 1208
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
S
Shengliang Guan 已提交
1209
    goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1210 1211
  }

S
Shengliang Guan 已提交
1212 1213 1214 1215
  pUser = mndAcquireUser(pMnode, pReq->user);
  if (pUser == NULL) {
    goto DROP_STB_OVER;
  }
S
Shengliang Guan 已提交
1216

S
Shengliang Guan 已提交
1217 1218 1219 1220 1221 1222 1223 1224 1225
  if (mndCheckWriteAuth(pUser, pDb) != 0) {
    goto DROP_STB_OVER;
  }

  code = mndDropStb(pMnode, pReq, pDb, pStb);
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;

DROP_STB_OVER:
  if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1226
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
1227 1228
  }

S
Shengliang Guan 已提交
1229 1230 1231 1232 1233
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  mndReleaseUser(pMnode, pUser);

  return code;
S
Shengliang Guan 已提交
1234
}
S
Shengliang Guan 已提交
1235

S
Shengliang Guan 已提交
1236 1237
static int32_t mndProcessVDropStbRsp(SMnodeMsg *pRsp) {
  mndTransProcessRsp(pRsp);
1238 1239
  return 0;
}
S
Shengliang Guan 已提交
1240

S
Shengliang Guan 已提交
1241
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
S
Shengliang Guan 已提交
1242 1243
  taosRLockLatch(&pStb->lock);

S
Shengliang Guan 已提交
1244
  int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
S
Shengliang Guan 已提交
1245
  pRsp->pSchemas = calloc(totalCols, sizeof(SSchema));
S
Shengliang Guan 已提交
1246
  if (pRsp->pSchemas == NULL) {
S
Shengliang Guan 已提交
1247
    taosRUnLockLatch(&pStb->lock);
S
Shengliang Guan 已提交
1248 1249 1250 1251
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

S
Shengliang Guan 已提交
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
  strcpy(pRsp->dbFName, pStb->db);
  strcpy(pRsp->tbName, tbName);
  strcpy(pRsp->stbName, tbName);
  pRsp->dbId = pDb->uid;
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->precision = pDb->cfg.precision;
  pRsp->tableType = TSDB_SUPER_TABLE;
  pRsp->update = pDb->cfg.update;
  pRsp->sversion = pStb->version;
  pRsp->suid = pStb->uid;
  pRsp->tuid = pStb->uid;
S
Shengliang Guan 已提交
1264

S
Shengliang Guan 已提交
1265
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
S
Shengliang Guan 已提交
1266
    SSchema *pSchema = &pRsp->pSchemas[i];
S
Shengliang Guan 已提交
1267 1268 1269
    SSchema *pSrcSchema = &pStb->pColumns[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
S
Shengliang Guan 已提交
1270 1271
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
S
Shengliang Guan 已提交
1272 1273 1274
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
S
Shengliang Guan 已提交
1275
    SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
S
Shengliang Guan 已提交
1276
    SSchema *pSrcSchema = &pStb->pTags[i];
S
Shengliang Guan 已提交
1277 1278
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
S
Shengliang Guan 已提交
1279 1280
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
S
Shengliang Guan 已提交
1281
  }
S
Shengliang Guan 已提交
1282

S
Shengliang Guan 已提交
1283
  taosRUnLockLatch(&pStb->lock);
S
Shengliang Guan 已提交
1284
  return 0;
S
Shengliang Guan 已提交
1285
}
S
Shengliang Guan 已提交
1286

S
Shengliang Guan 已提交
1287 1288 1289
static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp) {
  char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
  snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
S
Shengliang Guan 已提交
1290

S
Shengliang Guan 已提交
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
  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_MND_INVALID_STB;
    return -1;
  }

  int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  return code;
S
Shengliang Guan 已提交
1308
}
S
Shengliang Guan 已提交
1309

S
Shengliang Guan 已提交
1310 1311 1312 1313 1314
static int32_t mndProcessStbMetaReq(SMnodeMsg *pReq) {
  SMnode       *pMnode = pReq->pMnode;
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
1315

S
Shengliang Guan 已提交
1316
  if (tDeserializeSTableInfoReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &infoReq) != 0) {
S
Shengliang Guan 已提交
1317 1318 1319
    terrno = TSDB_CODE_INVALID_MSG;
    goto RETRIEVE_META_OVER;
  }
D
dapan 已提交
1320

S
Shengliang Guan 已提交
1321 1322 1323 1324
  mDebug("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
  if (mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
    goto RETRIEVE_META_OVER;
  }
S
Shengliang Guan 已提交
1325

S
Shengliang Guan 已提交
1326 1327 1328 1329 1330
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto RETRIEVE_META_OVER;
  }
S
Shengliang Guan 已提交
1331

S
Shengliang Guan 已提交
1332
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
1333 1334 1335 1336
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto RETRIEVE_META_OVER;
  }
D
dapan 已提交
1337

S
Shengliang Guan 已提交
1338 1339 1340 1341
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
  pReq->pCont = pRsp;
  pReq->contLen = rspLen;
  code = 0;
S
Shengliang Guan 已提交
1342

S
Shengliang Guan 已提交
1343
  mDebug("stb:%s.%s, meta is retrieved", infoReq.dbFName, infoReq.tbName);
D
dapan 已提交
1344

S
Shengliang Guan 已提交
1345 1346 1347 1348
RETRIEVE_META_OVER:
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
1349

S
Shengliang Guan 已提交
1350 1351 1352
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
1353

S
Shengliang Guan 已提交
1354 1355 1356 1357 1358 1359 1360 1361
int32_t mndValidateStbInfo(SMnode *pMnode, SSTableMetaVersion *pStbVersions, int32_t numOfStbs, void **ppRsp,
                           int32_t *pRspLen) {
  STableMetaBatchRsp batchMetaRsp = {0};
  batchMetaRsp.pArray = taosArrayInit(numOfStbs, sizeof(STableMetaRsp));
  if (batchMetaRsp.pArray == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
1362

S
Shengliang Guan 已提交
1363 1364 1365 1366 1367
  for (int32_t i = 0; i < numOfStbs; ++i) {
    SSTableMetaVersion *pStbVersion = &pStbVersions[i];
    pStbVersion->suid = be64toh(pStbVersion->suid);
    pStbVersion->sversion = ntohs(pStbVersion->sversion);
    pStbVersion->tversion = ntohs(pStbVersion->tversion);
S
Shengliang Guan 已提交
1368

S
Shengliang Guan 已提交
1369 1370 1371 1372 1373
    STableMetaRsp metaRsp = {0};
    mDebug("stb:%s.%s, start to retrieve meta", pStbVersion->dbFName, pStbVersion->stbName);
    if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp) != 0) {
      metaRsp.numOfColumns = -1;
      metaRsp.suid = pStbVersion->suid;
D
dapan 已提交
1374
    }
S
Shengliang Guan 已提交
1375

S
Shengliang Guan 已提交
1376 1377
    if (pStbVersion->sversion != metaRsp.sversion) {
      taosArrayPush(batchMetaRsp.pArray, &metaRsp);
S
Shengliang Guan 已提交
1378
    }
S
Shengliang Guan 已提交
1379
  }
S
Shengliang Guan 已提交
1380

S
Shengliang Guan 已提交
1381 1382 1383 1384 1385
  int32_t rspLen = tSerializeSTableMetaBatchRsp(NULL, 0, &batchMetaRsp);
  if (rspLen < 0) {
    tFreeSTableMetaBatchRsp(&batchMetaRsp);
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
1386 1387
  }

S
Shengliang Guan 已提交
1388 1389 1390 1391 1392
  void *pRsp = malloc(rspLen);
  if (pRsp == NULL) {
    tFreeSTableMetaBatchRsp(&batchMetaRsp);
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
1393 1394
  }

S
Shengliang Guan 已提交
1395 1396 1397
  tSerializeSTableMetaBatchRsp(pRsp, rspLen, &batchMetaRsp);
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
1398 1399 1400
  return 0;
}

S
Shengliang Guan 已提交
1401
static int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
1402
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1403 1404 1405 1406 1407 1408
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
1409
  int32_t numOfStbs = 0;
1410
  void   *pIter = NULL;
S
Shengliang Guan 已提交
1411
  while (1) {
S
Shengliang Guan 已提交
1412
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
1413
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
1414 1415
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
1416
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
1417
      numOfStbs++;
S
Shengliang Guan 已提交
1418 1419
    }

S
Shengliang Guan 已提交
1420
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1421 1422
  }

S
Shengliang Guan 已提交
1423
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
1424
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1425 1426 1427
  return 0;
}

S
Shengliang Guan 已提交
1428 1429
static int32_t mndGetStbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) {
  SMnode *pMnode = pReq->pMnode;
1430
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1431

S
Shengliang Guan 已提交
1432
  if (mndGetNumOfStbs(pMnode, pShow->db, &pShow->numOfRows) != 0) {
S
Shengliang Guan 已提交
1433 1434 1435 1436
    return -1;
  }

  int32_t  cols = 0;
S
Shengliang Guan 已提交
1437
  SSchema *pSchema = pMeta->pSchemas;
S
Shengliang Guan 已提交
1438 1439 1440 1441

  pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "name");
S
Shengliang Guan 已提交
1442
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1443 1444 1445 1446
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
H
Haojun Liao 已提交
1447
  strcpy(pSchema[cols].name, "create_time");
S
Shengliang Guan 已提交
1448
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1449 1450
  cols++;

S
Shengliang Guan 已提交
1451 1452
  pShow->bytes[cols] = 4;
  pSchema[cols].type = TSDB_DATA_TYPE_INT;
S
Shengliang Guan 已提交
1453
  strcpy(pSchema[cols].name, "columns");
S
Shengliang Guan 已提交
1454
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1455 1456
  cols++;

S
Shengliang Guan 已提交
1457 1458
  pShow->bytes[cols] = 4;
  pSchema[cols].type = TSDB_DATA_TYPE_INT;
S
Shengliang Guan 已提交
1459
  strcpy(pSchema[cols].name, "tags");
S
Shengliang Guan 已提交
1460
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1461 1462
  cols++;

S
Shengliang Guan 已提交
1463
  pMeta->numOfColumns = cols;
S
Shengliang Guan 已提交
1464 1465 1466 1467 1468 1469 1470
  pShow->numOfColumns = cols;

  pShow->offset[0] = 0;
  for (int32_t i = 1; i < cols; ++i) {
    pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
  }

S
Shengliang Guan 已提交
1471
  pShow->numOfRows = sdbGetSize(pSdb, SDB_STB);
S
Shengliang Guan 已提交
1472
  pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
D
dapan1121 已提交
1473
  strcpy(pMeta->tbName, mndShowStr(pShow->type));
S
Shengliang Guan 已提交
1474 1475 1476 1477

  return 0;
}

S
Shengliang Guan 已提交
1478
static void mndExtractTableName(char *tableId, char *name) {
S
Shengliang Guan 已提交
1479 1480
  int32_t pos = -1;
  int32_t num = 0;
S
Shengliang Guan 已提交
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
  for (pos = 0; tableId[pos] != 0; ++pos) {
    if (tableId[pos] == '.') num++;
    if (num == 2) break;
  }

  if (num == 2) {
    strcpy(name, tableId + pos + 1);
  }
}

S
Shengliang Guan 已提交
1491 1492
static int32_t mndRetrieveStb(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) {
  SMnode  *pMnode = pReq->pMnode;
S
Shengliang Guan 已提交
1493
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1494 1495 1496
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
1497
  char    *pWrite;
S
Shengliang Guan 已提交
1498
  char     prefix[TSDB_DB_FNAME_LEN] = {0};
S
Shengliang Guan 已提交
1499

S
Shengliang Guan 已提交
1500
  SDbObj *pDb = mndAcquireDb(pMnode, pShow->db);
S
Shengliang Guan 已提交
1501
  if (pDb == NULL) return 0;
S
Shengliang Guan 已提交
1502

S
Shengliang Guan 已提交
1503
  tstrncpy(prefix, pShow->db, TSDB_DB_FNAME_LEN);
S
Shengliang Guan 已提交
1504 1505 1506 1507
  strcat(prefix, TS_PATH_DELIMITER);
  int32_t prefixLen = (int32_t)strlen(prefix);

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

S
Shengliang Guan 已提交
1511
    if (pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
1512
      if (strncmp(pStb->db, pDb->name, prefixLen) == 0) {
S
Shengliang Guan 已提交
1513
        mError("Inconsistent table data, name:%s, db:%s, dbUid:%" PRIu64, pStb->name, pDb->name, pDb->uid);
H
Haojun Liao 已提交
1514 1515
      }

S
Shengliang Guan 已提交
1516
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1517 1518 1519 1520 1521
      continue;
    }

    cols = 0;

S
Shengliang Guan 已提交
1522 1523
    char stbName[TSDB_TABLE_NAME_LEN] = {0};
    tstrncpy(stbName, pStb->name + prefixLen, TSDB_TABLE_NAME_LEN);
S
Shengliang Guan 已提交
1524
    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1525
    STR_TO_VARSTR(pWrite, stbName);
S
Shengliang Guan 已提交
1526 1527 1528
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1529
    *(int64_t *)pWrite = pStb->createdTime;
S
Shengliang Guan 已提交
1530 1531 1532
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1533
    *(int32_t *)pWrite = pStb->numOfColumns;
S
Shengliang Guan 已提交
1534 1535 1536
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1537
    *(int32_t *)pWrite = pStb->numOfTags;
S
Shengliang Guan 已提交
1538 1539 1540
    cols++;

    numOfRows++;
S
Shengliang Guan 已提交
1541
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1542 1543
  }

S
Shengliang Guan 已提交
1544
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1545
  pShow->numOfReads += numOfRows;
S
Shengliang Guan 已提交
1546
  mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
S
Shengliang Guan 已提交
1547 1548 1549
  return numOfRows;
}

S
Shengliang Guan 已提交
1550
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
1551 1552
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan 已提交
1553
}