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

S
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "mndStb.h"
S
Shengliang Guan 已提交
18
#include "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"
D
dapan1121 已提交
26
#include "mndInfoSchema.h"
S
Shengliang Guan 已提交
27
#include "tname.h"
S
Shengliang Guan 已提交
28

S
Shengliang Guan 已提交
29
#define TSDB_STB_VER_NUMBER 1
S
Shengliang Guan 已提交
30 31 32 33 34
#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 已提交
35 36
static int32_t  mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew);
static int32_t  mndProcessMCreateStbReq(SMnodeMsg *pReq);
S
Shengliang Guan 已提交
37
static int32_t  mndProcessMAlterStbReq(SMnodeMsg *pReq);
S
Shengliang Guan 已提交
38 39
static int32_t  mndProcessMDropStbReq(SMnodeMsg *pReq);
static int32_t  mndProcessVCreateStbRsp(SMnodeMsg *pRsp);
S
Shengliang Guan 已提交
40
static int32_t  mndProcessVAlterStbRsp(SMnodeMsg *pRsp);
S
Shengliang Guan 已提交
41
static int32_t  mndProcessVDropStbRsp(SMnodeMsg *pRsp);
D
dapan1121 已提交
42
static int32_t  mndProcessTableMetaReq(SMnodeMsg *pReq);
S
Shengliang Guan 已提交
43 44
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 已提交
45 46 47 48
static void     mndCancelGetNextStb(SMnode *pMnode, void *pIter);

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

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

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

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

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

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

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

  int32_t dataPos = 0;
81 82 83 84 85 86 87
  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 已提交
88
  SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, STB_ENCODE_OVER)
89 90
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, STB_ENCODE_OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, STB_ENCODE_OVER)
S
Shengliang Guan 已提交
91

S
Shengliang Guan 已提交
92 93 94 95 96 97 98 99 100 101
  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];
102 103 104 105
    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 已提交
106 107
  }

S
Shengliang Guan 已提交
108
  SDB_SET_BINARY(pRaw, dataPos, pStb->comment, TSDB_STB_COMMENT_LEN, STB_ENCODE_OVER)
109 110 111 112 113 114 115 116 117 118 119
  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 已提交
120

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

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

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

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

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

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

  int32_t dataPos = 0;
143 144 145 146 147 148 149
  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 已提交
150
  SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, STB_DECODE_OVER)
151 152
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, STB_DECODE_OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, STB_DECODE_OVER)
S
Shengliang Guan 已提交
153

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

S
Shengliang Guan 已提交
160 161 162 163 164 165 166 167 168 169
  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];
170 171 172 173
    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 已提交
174 175
  }

S
Shengliang Guan 已提交
176
  SDB_GET_BINARY(pRaw, dataPos, pStb->comment, TSDB_STB_COMMENT_LEN, STB_DECODE_OVER)
177 178 179 180 181 182 183
  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());
184 185
    tfree(pStb->pColumns);
    tfree(pStb->pTags);
186 187 188
    tfree(pRow);
    return NULL;
  }
S
Shengliang Guan 已提交
189

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
304
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
S
Shengliang Guan 已提交
305 306 307 308 309 310 311 312
  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;
313

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

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
  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 已提交
372
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
373 374
      return -1;
    }
S
Shengliang Guan 已提交
375
    if (pField->bytes <= 0) {
S
Shengliang Guan 已提交
376
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
377 378
      return -1;
    }
S
Shengliang Guan 已提交
379
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
380
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
381 382 383
      return -1;
    }
  }
S
Shengliang Guan 已提交
384

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

388
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
389 390 391 392 393 394 395 396
  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;
}

397
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
398 399 400 401 402 403 404 405
  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;
}

406
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
407 408 409 410 411 412 413 414
  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;
}

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

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

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

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

  return 0;
}

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

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

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

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

  return 0;
}

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

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

S
Shengliang Guan 已提交
513
  for (int32_t i = 0; i < stbObj.numOfColumns; ++i) {
S
Shengliang Guan 已提交
514 515 516 517 518 519
    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 已提交
520 521 522 523
    stbObj.nextColId++;
  }

  for (int32_t i = 0; i < stbObj.numOfTags; ++i) {
S
Shengliang Guan 已提交
524 525 526 527 528 529
    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 已提交
530
    stbObj.nextColId++;
S
Shengliang Guan 已提交
531 532
  }

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

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

S
Shengliang Guan 已提交
540 541 542 543 544 545
  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 已提交
546

S
Shengliang Guan 已提交
547 548 549
  code = 0;

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

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

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

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

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

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

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

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

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

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

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

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

  return code;
S
Shengliang Guan 已提交
624 625
}

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

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

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

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

  return 0;
}

S
Shengliang Guan 已提交
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 688 689
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 已提交
690
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
691 692 693 694 695 696 697 698 699 700
  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 已提交
701 702 703 704 705
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

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

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

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

  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 已提交
744
  pNew->numOfTags--;
S
Shengliang Guan 已提交
745 746 747 748 749 750

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

S
Shengliang Guan 已提交
751 752 753 754 755 756 757 758 759 760 761 762
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 已提交
763 764 765 766 767 768 769
  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 已提交
770
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
771 772 773
    return -1;
  }

S
Shengliang Guan 已提交
774 775
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
    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 已提交
791 792
static int32_t mndAlterStbTagBytes(const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
793 794 795 796 797 798 799 800 801 802 803
  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 已提交
804 805 806 807 808
  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 已提交
809
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
810 811 812 813
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

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

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

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

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

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

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

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

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

  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 已提交
860
  if (col < 0) {
S
Shengliang Guan 已提交
861 862 863 864
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
865 866 867 868 869 870 871 872 873 874
  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 已提交
875 876 877 878 879
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

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

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

  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 已提交
909 910
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
911 912 913
    return -1;
  }

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

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

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

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

  return 0;
}

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

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

  return 0;
}

S
Shengliang Guan 已提交
983
static int32_t mndAlterStb(SMnode *pMnode, SMnodeMsg *pReq, const SMAltertbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
S
Shengliang Guan 已提交
984 985 986 987 988 989 990 991 992
  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 已提交
993
  STrans *pTrans = NULL;
S
Shengliang Guan 已提交
994
  SField *pField0 = taosArrayGet(pAlter->pFields, 0);
S
Shengliang Guan 已提交
995

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

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

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

S
Shengliang Guan 已提交
1029
  mDebug("trans:%d, used to alter stb:%s", pTrans->id, pAlter->name);
S
Shengliang Guan 已提交
1030
  mndTransSetDbInfo(pTrans, pDb);
S
Shengliang Guan 已提交
1031

S
Shengliang Guan 已提交
1032 1033 1034 1035
  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 已提交
1036 1037

  code = 0;
S
Shengliang Guan 已提交
1038

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

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
1083
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
1084
  if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1085

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

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

  return code;
S
Shengliang Guan 已提交
1097
}
S
Shengliang Guan 已提交
1098

S
Shengliang Guan 已提交
1099
static int32_t mndProcessVAlterStbRsp(SMnodeMsg *pRsp) {
S
Shengliang Guan 已提交
1100
  mndTransProcessRsp(pRsp);
1101 1102
  return 0;
}
S
Shengliang Guan 已提交
1103

S
Shengliang Guan 已提交
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
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 已提交
1122 1123 1124 1125 1126
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 已提交
1127

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

S
Shengliang Guan 已提交
1136
    int32_t contLen = 0;
S
Shengliang Guan 已提交
1137
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
    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 已提交
1164
  int32_t code = -1;
S
Shengliang Guan 已提交
1165
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK,TRN_TYPE_DROP_STB, &pReq->rpcMsg);
S
Shengliang Guan 已提交
1166
  if (pTrans == NULL) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1167

S
Shengliang Guan 已提交
1168
  mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
S
Shengliang Guan 已提交
1169
  mndTransSetDbInfo(pTrans, pDb);
S
Shengliang Guan 已提交
1170

S
Shengliang Guan 已提交
1171 1172
  if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
  if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1173
  if (mndSetDropStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1174
  if (mndTransPrepare(pMnode, pTrans) != 0) goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1175

S
Shengliang Guan 已提交
1176 1177 1178
  code = 0;

DROP_STB_OVER:
S
Shengliang Guan 已提交
1179
  mndTransDrop(pTrans);
S
Shengliang 已提交
1180
  return code;
S
Shengliang Guan 已提交
1181 1182
}

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

S
Shengliang Guan 已提交
1191
  if (tDeserializeSMDropStbReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
1192 1193 1194
    terrno = TSDB_CODE_INVALID_MSG;
    goto DROP_STB_OVER;
  }
S
Shengliang Guan 已提交
1195

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

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

S
Shengliang Guan 已提交
1210
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
1211 1212
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
S
Shengliang Guan 已提交
1213
    goto DROP_STB_OVER;
S
Shengliang Guan 已提交
1214 1215
  }

S
Shengliang Guan 已提交
1216 1217 1218 1219
  pUser = mndAcquireUser(pMnode, pReq->user);
  if (pUser == NULL) {
    goto DROP_STB_OVER;
  }
S
Shengliang Guan 已提交
1220

S
Shengliang Guan 已提交
1221 1222 1223 1224 1225 1226 1227 1228 1229
  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 已提交
1230
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
1231 1232
  }

S
Shengliang Guan 已提交
1233 1234 1235 1236 1237
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  mndReleaseUser(pMnode, pUser);

  return code;
S
Shengliang Guan 已提交
1238
}
S
Shengliang Guan 已提交
1239

S
Shengliang Guan 已提交
1240 1241
static int32_t mndProcessVDropStbRsp(SMnodeMsg *pRsp) {
  mndTransProcessRsp(pRsp);
1242 1243
  return 0;
}
S
Shengliang Guan 已提交
1244

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

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

S
Shengliang Guan 已提交
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
  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 已提交
1268

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

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

S
Shengliang Guan 已提交
1287
  taosRUnLockLatch(&pStb->lock);
S
Shengliang Guan 已提交
1288
  return 0;
S
Shengliang Guan 已提交
1289
}
S
Shengliang Guan 已提交
1290

S
Shengliang Guan 已提交
1291 1292 1293
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 已提交
1294

S
Shengliang Guan 已提交
1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
  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 已提交
1312
}
S
Shengliang Guan 已提交
1313

D
dapan1121 已提交
1314
static int32_t mndProcessTableMetaReq(SMnodeMsg *pReq) {
S
Shengliang Guan 已提交
1315 1316 1317 1318
  SMnode       *pMnode = pReq->pMnode;
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
1319

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

D
dapan1121 已提交
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334
  if (0 == strcmp(infoReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) {
    mDebug("information_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
    if (mndBuildInsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
      goto RETRIEVE_META_OVER;
    }
  } else {
    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 已提交
1335
  }
S
Shengliang Guan 已提交
1336

S
Shengliang Guan 已提交
1337 1338 1339 1340 1341
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto RETRIEVE_META_OVER;
  }
S
Shengliang Guan 已提交
1342

S
Shengliang Guan 已提交
1343
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
1344 1345 1346 1347
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto RETRIEVE_META_OVER;
  }
D
dapan 已提交
1348

S
Shengliang Guan 已提交
1349 1350 1351 1352
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
  pReq->pCont = pRsp;
  pReq->contLen = rspLen;
  code = 0;
S
Shengliang Guan 已提交
1353

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

S
Shengliang Guan 已提交
1356 1357 1358 1359
RETRIEVE_META_OVER:
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
1360

S
Shengliang Guan 已提交
1361 1362 1363
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
1364

S
Shengliang Guan 已提交
1365 1366 1367 1368 1369 1370 1371 1372
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 已提交
1373

S
Shengliang Guan 已提交
1374 1375 1376 1377 1378
  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 已提交
1379

S
Shengliang Guan 已提交
1380 1381 1382 1383 1384
    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 已提交
1385
    }
S
Shengliang Guan 已提交
1386

S
Shengliang Guan 已提交
1387 1388
    if (pStbVersion->sversion != metaRsp.sversion) {
      taosArrayPush(batchMetaRsp.pArray, &metaRsp);
S
Shengliang Guan 已提交
1389
    }
S
Shengliang Guan 已提交
1390
  }
S
Shengliang Guan 已提交
1391

S
Shengliang Guan 已提交
1392 1393 1394 1395 1396
  int32_t rspLen = tSerializeSTableMetaBatchRsp(NULL, 0, &batchMetaRsp);
  if (rspLen < 0) {
    tFreeSTableMetaBatchRsp(&batchMetaRsp);
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
1397 1398
  }

S
Shengliang Guan 已提交
1399 1400 1401 1402 1403
  void *pRsp = malloc(rspLen);
  if (pRsp == NULL) {
    tFreeSTableMetaBatchRsp(&batchMetaRsp);
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
1404 1405
  }

S
Shengliang Guan 已提交
1406 1407 1408
  tSerializeSTableMetaBatchRsp(pRsp, rspLen, &batchMetaRsp);
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
1409 1410 1411
  return 0;
}

S
Shengliang Guan 已提交
1412
static int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
1413
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1414 1415 1416 1417 1418 1419
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
1420
  int32_t numOfStbs = 0;
1421
  void   *pIter = NULL;
S
Shengliang Guan 已提交
1422
  while (1) {
S
Shengliang Guan 已提交
1423
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
1424
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
1425 1426
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
1427
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
1428
      numOfStbs++;
S
Shengliang Guan 已提交
1429 1430
    }

S
Shengliang Guan 已提交
1431
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1432 1433
  }

S
Shengliang Guan 已提交
1434
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
1435
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1436 1437 1438
  return 0;
}

S
Shengliang Guan 已提交
1439 1440
static int32_t mndGetStbMeta(SMnodeMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta) {
  SMnode *pMnode = pReq->pMnode;
1441
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1442

S
Shengliang Guan 已提交
1443
  if (mndGetNumOfStbs(pMnode, pShow->db, &pShow->numOfRows) != 0) {
S
Shengliang Guan 已提交
1444 1445 1446 1447
    return -1;
  }

  int32_t  cols = 0;
S
Shengliang Guan 已提交
1448
  SSchema *pSchema = pMeta->pSchemas;
S
Shengliang Guan 已提交
1449 1450 1451 1452

  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 已提交
1453
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1454 1455 1456 1457
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
H
Haojun Liao 已提交
1458
  strcpy(pSchema[cols].name, "create_time");
S
Shengliang Guan 已提交
1459
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1460 1461
  cols++;

S
Shengliang Guan 已提交
1462 1463
  pShow->bytes[cols] = 4;
  pSchema[cols].type = TSDB_DATA_TYPE_INT;
S
Shengliang Guan 已提交
1464
  strcpy(pSchema[cols].name, "columns");
S
Shengliang Guan 已提交
1465
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1466 1467
  cols++;

S
Shengliang Guan 已提交
1468 1469
  pShow->bytes[cols] = 4;
  pSchema[cols].type = TSDB_DATA_TYPE_INT;
S
Shengliang Guan 已提交
1470
  strcpy(pSchema[cols].name, "tags");
S
Shengliang Guan 已提交
1471
  pSchema[cols].bytes = pShow->bytes[cols];
S
Shengliang Guan 已提交
1472 1473
  cols++;

S
Shengliang Guan 已提交
1474
  pMeta->numOfColumns = cols;
S
Shengliang Guan 已提交
1475 1476 1477 1478 1479 1480 1481
  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 已提交
1482
  pShow->numOfRows = sdbGetSize(pSdb, SDB_STB);
S
Shengliang Guan 已提交
1483
  pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
D
dapan1121 已提交
1484
  strcpy(pMeta->tbName, mndShowStr(pShow->type));
S
Shengliang Guan 已提交
1485 1486 1487 1488

  return 0;
}

S
Shengliang Guan 已提交
1489
static void mndExtractTableName(char *tableId, char *name) {
S
Shengliang Guan 已提交
1490 1491
  int32_t pos = -1;
  int32_t num = 0;
S
Shengliang Guan 已提交
1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
  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 已提交
1502 1503
static int32_t mndRetrieveStb(SMnodeMsg *pReq, SShowObj *pShow, char *data, int32_t rows) {
  SMnode  *pMnode = pReq->pMnode;
S
Shengliang Guan 已提交
1504
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1505 1506 1507
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
1508
  char    *pWrite;
S
Shengliang Guan 已提交
1509
  char     prefix[TSDB_DB_FNAME_LEN] = {0};
S
Shengliang Guan 已提交
1510

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

S
Shengliang Guan 已提交
1514
  tstrncpy(prefix, pShow->db, TSDB_DB_FNAME_LEN);
S
Shengliang Guan 已提交
1515 1516 1517 1518
  strcat(prefix, TS_PATH_DELIMITER);
  int32_t prefixLen = (int32_t)strlen(prefix);

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

S
Shengliang Guan 已提交
1522
    if (pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
1523
      if (strncmp(pStb->db, pDb->name, prefixLen) == 0) {
S
Shengliang Guan 已提交
1524
        mError("Inconsistent table data, name:%s, db:%s, dbUid:%" PRIu64, pStb->name, pDb->name, pDb->uid);
H
Haojun Liao 已提交
1525 1526
      }

S
Shengliang Guan 已提交
1527
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1528 1529 1530 1531 1532
      continue;
    }

    cols = 0;

S
Shengliang Guan 已提交
1533 1534
    char stbName[TSDB_TABLE_NAME_LEN] = {0};
    tstrncpy(stbName, pStb->name + prefixLen, TSDB_TABLE_NAME_LEN);
S
Shengliang Guan 已提交
1535
    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1536
    STR_TO_VARSTR(pWrite, stbName);
S
Shengliang Guan 已提交
1537 1538 1539
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1540
    *(int64_t *)pWrite = pStb->createdTime;
S
Shengliang Guan 已提交
1541 1542 1543
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1544
    *(int32_t *)pWrite = pStb->numOfColumns;
S
Shengliang Guan 已提交
1545 1546 1547
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
S
Shengliang Guan 已提交
1548
    *(int32_t *)pWrite = pStb->numOfTags;
S
Shengliang Guan 已提交
1549 1550 1551
    cols++;

    numOfRows++;
S
Shengliang Guan 已提交
1552
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1553 1554
  }

S
Shengliang Guan 已提交
1555
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1556
  pShow->numOfReads += numOfRows;
S
Shengliang Guan 已提交
1557
  mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
S
Shengliang Guan 已提交
1558 1559 1560
  return numOfRows;
}

S
Shengliang Guan 已提交
1561
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
1562 1563
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan1121 已提交
1564
}