mndStb.c 55.0 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
#include "mndDnode.h"
S
Shengliang Guan 已提交
21
#include "mndInfoSchema.h"
S
Shengliang Guan 已提交
22
#include "mndMnode.h"
H
Hongze Cheng 已提交
23
#include "mndPerfSchema.h"
C
Cary Xu 已提交
24
#include "mndScheduler.h"
S
Shengliang Guan 已提交
25
#include "mndShow.h"
26
#include "mndTopic.h"
S
Shengliang Guan 已提交
27 28
#include "mndTrans.h"
#include "mndUser.h"
29
#include "mndVgroup.h"
S
Shengliang Guan 已提交
30
#include "tname.h"
S
Shengliang Guan 已提交
31

S
Shengliang Guan 已提交
32 33
#define STB_VER_NUMBER   1
#define STB_RESERVE_SIZE 64
S
Shengliang Guan 已提交
34 35 36 37

static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
static int32_t  mndStbActionInsert(SSdb *pSdb, SStbObj *pStb);
static int32_t  mndStbActionDelete(SSdb *pSdb, SStbObj *pStb);
S
Shengliang Guan 已提交
38
static int32_t  mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew);
S
Shengliang Guan 已提交
39 40 41 42 43
static int32_t  mndProcessMCreateStbReq(SRpcMsg *pReq);
static int32_t  mndProcessMAlterStbReq(SRpcMsg *pReq);
static int32_t  mndProcessMDropStbReq(SRpcMsg *pReq);
static int32_t  mndProcessTableMetaReq(SRpcMsg *pReq);
static int32_t  mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
S
Shengliang Guan 已提交
44 45 46
static void     mndCancelGetNextStb(SMnode *pMnode, void *pIter);

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

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

  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;

76
  int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + +pStb->commentLen +
S
Shengliang Guan 已提交
77 78
                 pStb->ast1Len + pStb->ast2Len + STB_RESERVE_SIZE;
  SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, STB_VER_NUMBER, size);
79
  if (pRaw == NULL) goto _OVER;
S
Shengliang Guan 已提交
80 81

  int32_t dataPos = 0;
82 83 84 85 86 87
  SDB_SET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, _OVER)
  SDB_SET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->createdTime, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->updateTime, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->uid, _OVER)
  SDB_SET_INT64(pRaw, dataPos, pStb->dbUid, _OVER)
88 89
  SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
90 91 92 93 94 95 96
  SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
  SDB_SET_INT32(pRaw, dataPos, (int32_t)(pStb->xFilesFactor * 10000), _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->delay, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->ttl, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->commentLen, _OVER)
97 98
  SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER)
  SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER)
S
Shengliang Guan 已提交
99

S
Shengliang Guan 已提交
100 101
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
102
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
S
Shengliang Guan 已提交
103
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
104 105 106
    SDB_SET_INT16(pRaw, dataPos, pSchema->colId, _OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
107 108 109 110
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
111
    SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
S
Shengliang Guan 已提交
112
    SDB_SET_INT8(pRaw, dataPos, pSchema->flags, _OVER)
113 114 115
    SDB_SET_INT16(pRaw, dataPos, pSchema->colId, _OVER)
    SDB_SET_INT32(pRaw, dataPos, pSchema->bytes, _OVER)
    SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
116 117
  }

S
sma  
Shengliang Guan 已提交
118
  if (pStb->commentLen > 0) {
119
    SDB_SET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen, _OVER)
S
sma  
Shengliang Guan 已提交
120
  }
121 122 123 124 125 126
  if (pStb->ast1Len > 0) {
    SDB_SET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
  }
  if (pStb->ast2Len > 0) {
    SDB_SET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
  }
S
Shengliang Guan 已提交
127
  SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
128
  SDB_SET_DATALEN(pRaw, dataPos, _OVER)
129 130 131

  terrno = 0;

132
_OVER:
133 134 135 136 137
  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 已提交
138

139
  mTrace("stb:%s, encode to raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
140 141 142
  return pRaw;
}

S
Shengliang Guan 已提交
143
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
144 145
  terrno = TSDB_CODE_OUT_OF_MEMORY;

S
Shengliang Guan 已提交
146
  int8_t sver = 0;
147
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
S
Shengliang Guan 已提交
148

S
Shengliang Guan 已提交
149
  if (sver != STB_VER_NUMBER) {
S
Shengliang Guan 已提交
150
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
151
    goto _OVER;
S
Shengliang Guan 已提交
152 153
  }

S
Shengliang 已提交
154
  SSdbRow *pRow = sdbAllocRow(sizeof(SStbObj));
155
  if (pRow == NULL) goto _OVER;
156

S
Shengliang Guan 已提交
157
  SStbObj *pStb = sdbGetRowObj(pRow);
158
  if (pStb == NULL) goto _OVER;
S
Shengliang Guan 已提交
159 160

  int32_t dataPos = 0;
161 162 163 164 165 166
  SDB_GET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_FNAME_LEN, _OVER)
  SDB_GET_BINARY(pRaw, dataPos, pStb->db, TSDB_DB_FNAME_LEN, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->createdTime, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->updateTime, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->uid, _OVER)
  SDB_GET_INT64(pRaw, dataPos, &pStb->dbUid, _OVER)
167 168
  SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
169
  SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
S
sma  
Shengliang Guan 已提交
170
  int32_t xFilesFactor = 0;
171
  SDB_GET_INT32(pRaw, dataPos, &xFilesFactor, _OVER)
S
sma  
Shengliang Guan 已提交
172
  pStb->xFilesFactor = xFilesFactor / 10000.0f;
173 174 175 176 177
  SDB_GET_INT32(pRaw, dataPos, &pStb->delay, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->ttl, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->commentLen, _OVER)
178 179
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER)
  SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER)
S
Shengliang Guan 已提交
180

wafwerar's avatar
wafwerar 已提交
181 182
  pStb->pColumns = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchema));
  pStb->pTags = taosMemoryCalloc(pStb->numOfTags, sizeof(SSchema));
183
  if (pStb->pColumns == NULL || pStb->pTags == NULL) {
184
    goto _OVER;
S
Shengliang 已提交
185
  }
S
Shengliang Guan 已提交
186

S
Shengliang Guan 已提交
187 188
  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pStb->pColumns[i];
189
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
S
Shengliang Guan 已提交
190
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
191 192 193
    SDB_GET_INT16(pRaw, dataPos, &pSchema->colId, _OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, _OVER)
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
194 195 196 197
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pStb->pTags[i];
198
    SDB_GET_INT8(pRaw, dataPos, &pSchema->type, _OVER)
S
Shengliang Guan 已提交
199
    SDB_GET_INT8(pRaw, dataPos, &pSchema->flags, _OVER)
200 201 202
    SDB_GET_INT16(pRaw, dataPos, &pSchema->colId, _OVER)
    SDB_GET_INT32(pRaw, dataPos, &pSchema->bytes, _OVER)
    SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
S
Shengliang Guan 已提交
203 204
  }

S
sma  
Shengliang Guan 已提交
205
  if (pStb->commentLen > 0) {
wafwerar's avatar
wafwerar 已提交
206
    pStb->comment = taosMemoryCalloc(pStb->commentLen, 1);
207 208
    if (pStb->comment == NULL) goto _OVER;
    SDB_GET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen, _OVER)
S
sma  
Shengliang Guan 已提交
209
  }
210 211 212 213 214 215 216 217 218 219
  if (pStb->ast1Len > 0) {
    pStb->pAst1 = taosMemoryCalloc(pStb->ast1Len, 1);
    if (pStb->pAst1 == NULL) goto _OVER;
    SDB_GET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
  }
  if (pStb->ast2Len > 0) {
    pStb->pAst2 = taosMemoryCalloc(pStb->ast2Len, 1);
    if (pStb->pAst2 == NULL) goto _OVER;
    SDB_GET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
  }
S
Shengliang Guan 已提交
220
  SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
221 222 223

  terrno = 0;

224
_OVER:
225 226
  if (terrno != 0) {
    mError("stb:%s, failed to decode from raw:%p since %s", pStb->name, pRaw, terrstr());
wafwerar's avatar
wafwerar 已提交
227 228 229 230
    taosMemoryFreeClear(pStb->pColumns);
    taosMemoryFreeClear(pStb->pTags);
    taosMemoryFreeClear(pStb->comment);
    taosMemoryFreeClear(pRow);
231 232
    return NULL;
  }
S
Shengliang Guan 已提交
233

234
  mTrace("stb:%s, decode from raw:%p, row:%p", pStb->name, pRaw, pStb);
S
Shengliang Guan 已提交
235 236 237
  return pRow;
}

S
Shengliang Guan 已提交
238
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
239
  mTrace("stb:%s, perform insert action, row:%p", pStb->name, pStb);
S
Shengliang Guan 已提交
240 241 242
  return 0;
}

S
Shengliang Guan 已提交
243
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
244
  mTrace("stb:%s, perform delete action, row:%p", pStb->name, pStb);
wafwerar's avatar
wafwerar 已提交
245 246 247
  taosMemoryFreeClear(pStb->pColumns);
  taosMemoryFreeClear(pStb->pTags);
  taosMemoryFreeClear(pStb->comment);
248 249
  taosMemoryFreeClear(pStb->pAst1);
  taosMemoryFreeClear(pStb->pAst2);
S
Shengliang Guan 已提交
250 251 252
  return 0;
}

S
Shengliang Guan 已提交
253 254
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 已提交
255

S
Shengliang Guan 已提交
256
  taosWLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
257 258

  if (pOld->numOfColumns < pNew->numOfColumns) {
wafwerar's avatar
wafwerar 已提交
259
    void *pColumns = taosMemoryMalloc(pNew->numOfColumns * sizeof(SSchema));
S
Shengliang Guan 已提交
260
    if (pColumns != NULL) {
wafwerar's avatar
wafwerar 已提交
261
      taosMemoryFree(pOld->pColumns);
S
Shengliang Guan 已提交
262
      pOld->pColumns = pColumns;
S
Shengliang Guan 已提交
263 264 265 266 267 268 269 270
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

  if (pOld->numOfTags < pNew->numOfTags) {
wafwerar's avatar
wafwerar 已提交
271
    void *pTags = taosMemoryMalloc(pNew->numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
272
    if (pTags != NULL) {
wafwerar's avatar
wafwerar 已提交
273
      taosMemoryFree(pOld->pTags);
S
Shengliang Guan 已提交
274
      pOld->pTags = pTags;
S
Shengliang Guan 已提交
275 276 277 278
    } 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 已提交
279
    }
S
Shengliang Guan 已提交
280 281
  }

S
Shengliang Guan 已提交
282
  if (pOld->commentLen < pNew->commentLen) {
wafwerar's avatar
wafwerar 已提交
283
    void *comment = taosMemoryMalloc(pNew->commentLen);
S
Shengliang Guan 已提交
284
    if (comment != NULL) {
wafwerar's avatar
wafwerar 已提交
285
      taosMemoryFree(pOld->comment);
S
Shengliang Guan 已提交
286 287 288 289 290 291 292 293
      pOld->comment = comment;
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
  if (pOld->ast1Len < pNew->ast1Len) {
    void *pAst1 = taosMemoryMalloc(pNew->ast1Len);
    if (pAst1 != NULL) {
      taosMemoryFree(pOld->pAst1);
      pOld->pAst1 = pAst1;
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

  if (pOld->ast2Len < pNew->ast2Len) {
    void *pAst2 = taosMemoryMalloc(pNew->ast2Len);
    if (pAst2 != NULL) {
      taosMemoryFree(pOld->pAst2);
      pOld->pAst2 = pAst2;
    } else {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      mTrace("stb:%s, failed to perform update action since %s", pOld->name, terrstr());
      taosWUnLockLatch(&pOld->lock);
    }
  }

S
Shengliang Guan 已提交
318
  pOld->updateTime = pNew->updateTime;
319 320
  pOld->tagVer = pNew->tagVer;
  pOld->colVer = pNew->colVer;
321
  pOld->nextColId = pNew->nextColId;
S
Shengliang 已提交
322
  pOld->ttl = pNew->ttl;
S
Shengliang Guan 已提交
323 324
  pOld->numOfColumns = pNew->numOfColumns;
  pOld->numOfTags = pNew->numOfTags;
S
Shengliang Guan 已提交
325 326
  memcpy(pOld->pColumns, pNew->pColumns, pOld->numOfColumns * sizeof(SSchema));
  memcpy(pOld->pTags, pNew->pTags, pOld->numOfTags * sizeof(SSchema));
S
Shengliang Guan 已提交
327
  if (pNew->commentLen != 0) {
S
Shengliang Guan 已提交
328
    memcpy(pOld->comment, pNew->comment, pNew->commentLen);
S
Shengliang Guan 已提交
329
  }
330 331 332 333 334 335
  if (pNew->ast1Len != 0) {
    memcpy(pOld->pAst1, pNew->pAst1, pNew->ast1Len);
  }
  if (pNew->ast2Len != 0) {
    memcpy(pOld->pAst2, pNew->pAst2, pNew->ast2Len);
  }
S
Shengliang Guan 已提交
336
  taosWUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
337 338 339
  return 0;
}

S
Shengliang Guan 已提交
340
SStbObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
341
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
342
  SStbObj *pStb = sdbAcquire(pSdb, SDB_STB, stbName);
S
Shengliang Guan 已提交
343
  if (pStb == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
S
Shengliang Guan 已提交
344 345 346
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
  }
  return pStb;
S
Shengliang Guan 已提交
347 348
}

S
Shengliang Guan 已提交
349
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
S
Shengliang Guan 已提交
350 351 352 353
  SSdb *pSdb = pMnode->pSdb;
  sdbRelease(pSdb, pStb);
}

354
SDbObj *mndAcquireDbByStb(SMnode *pMnode, const char *stbName) {
S
Shengliang Guan 已提交
355 356
  SName name = {0};
  tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
S
Shengliang Guan 已提交
357

S
Shengliang Guan 已提交
358 359
  char db[TSDB_TABLE_FNAME_LEN] = {0};
  tNameGetFullDbName(&name, db);
S
Shengliang Guan 已提交
360

S
Shengliang Guan 已提交
361 362
  return mndAcquireDb(pMnode, db);
}
S
Shengliang Guan 已提交
363

C
Cary Xu 已提交
364
static FORCE_INLINE int schemaExColIdCompare(const void *colId, const void *pSchema) {
H
Hongze Cheng 已提交
365
  if (*(col_id_t *)colId < ((SSchema *)pSchema)->colId) {
C
Cary Xu 已提交
366
    return -1;
H
Hongze Cheng 已提交
367
  } else if (*(col_id_t *)colId > ((SSchema *)pSchema)->colId) {
C
Cary Xu 已提交
368 369 370 371 372
    return 1;
  }
  return 0;
}

S
Shengliang Guan 已提交
373
static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
H
Hongze Cheng 已提交
374
  SEncoder       encoder = {0};
H
Hongze Cheng 已提交
375 376 377
  int32_t        contLen;
  SName          name = {0};
  SVCreateStbReq req = {0};
H
Hongze Cheng 已提交
378

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

S
Shengliang Guan 已提交
383
  req.name = (char *)tNameGetTableName(&name);
H
Hongze Cheng 已提交
384
  req.suid = pStb->uid;
385
  req.rollup = pStb->ast1Len > 0 ? 1 : 0;
386 387
  // todo
  req.schemaRow.nCols = pStb->numOfColumns;
388
  req.schemaRow.version = pStb->colVer;
389
  req.schemaRow.pSchema = pStb->pColumns;
H
Hongze Cheng 已提交
390
  req.schemaTag.nCols = pStb->numOfTags;
391
  req.schemaTag.version = pStb->tagVer;
H
Hongze Cheng 已提交
392
  req.schemaTag.pSchema = pStb->pTags;
H
more  
Hongze Cheng 已提交
393

C
Cary Xu 已提交
394
  if (req.rollup) {
H
Hongze Cheng 已提交
395 396
    req.pRSmaParam.xFilesFactor = pStb->xFilesFactor;
    req.pRSmaParam.delay = pStb->delay;
C
Cary Xu 已提交
397
    if (pStb->ast1Len > 0) {
398 399
      if (mndConvertRSmaTask(pStb->pAst1, pStb->uid, 0, 0, &req.pRSmaParam.qmsg1, &req.pRSmaParam.qmsg1Len,
                             req.pRSmaParam.xFilesFactor) != TSDB_CODE_SUCCESS) {
C
Cary Xu 已提交
400 401
        return NULL;
      }
C
Cary Xu 已提交
402 403
    }
    if (pStb->ast2Len > 0) {
404 405
      if (mndConvertRSmaTask(pStb->pAst2, pStb->uid, 0, 0, &req.pRSmaParam.qmsg2, &req.pRSmaParam.qmsg2Len,
                             req.pRSmaParam.xFilesFactor) != TSDB_CODE_SUCCESS) {
C
Cary Xu 已提交
406 407
        return NULL;
      }
C
Cary Xu 已提交
408
    }
H
Hongze Cheng 已提交
409
  }
H
Hongze Cheng 已提交
410
  // get length
wafwerar's avatar
wafwerar 已提交
411 412 413
  int32_t ret = 0;
  tEncodeSize(tEncodeSVCreateStbReq, &req, contLen, ret);
  if (ret < 0) {
H
Hongze Cheng 已提交
414 415 416
    return NULL;
  }

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

wafwerar's avatar
wafwerar 已提交
419
  SMsgHead *pHead = taosMemoryMalloc(contLen);
S
Shengliang Guan 已提交
420
  if (pHead == NULL) {
421 422
    taosMemoryFreeClear(req.pRSmaParam.qmsg1);
    taosMemoryFreeClear(req.pRSmaParam.qmsg2);
H
more  
Hongze Cheng 已提交
423 424 425 426
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
427 428
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);
H
more  
Hongze Cheng 已提交
429

S
Shengliang Guan 已提交
430
  void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
H
Hongze Cheng 已提交
431 432
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  if (tEncodeSVCreateStbReq(&encoder, &req) < 0) {
433 434 435 436
    taosMemoryFreeClear(pHead);
    taosMemoryFreeClear(req.pRSmaParam.qmsg1);
    taosMemoryFreeClear(req.pRSmaParam.qmsg2);
    tEncoderClear(&encoder);
H
Hongze Cheng 已提交
437 438
    return NULL;
  }
H
Hongze Cheng 已提交
439
  tEncoderClear(&encoder);
H
more  
Hongze Cheng 已提交
440

S
Shengliang Guan 已提交
441
  *pContLen = contLen;
442 443
  taosMemoryFreeClear(req.pRSmaParam.qmsg1);
  taosMemoryFreeClear(req.pRSmaParam.qmsg2);
S
Shengliang Guan 已提交
444
  return pHead;
445 446
}

S
Shengliang Guan 已提交
447
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
H
Hongze Cheng 已提交
448 449 450 451 452
  SName        name = {0};
  SVDropStbReq req = {0};
  int32_t      contLen = 0;
  int32_t      ret = 0;
  SMsgHead    *pHead = NULL;
H
Hongze Cheng 已提交
453
  SEncoder     encoder = {0};
H
Hongze Cheng 已提交
454

S
Shengliang Guan 已提交
455 456 457 458
  tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

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

H
Hongze Cheng 已提交
460 461 462 463 464
  tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
  if (ret < 0) return NULL;

  contLen += sizeof(SMsgHead);
  pHead = taosMemoryMalloc(contLen);
S
Shengliang Guan 已提交
465
  if (pHead == NULL) {
466 467 468 469
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
470 471 472 473
  pHead->contLen = htonl(contLen);
  pHead->vgId = htonl(pVgroup->vgId);

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

H
Hongze Cheng 已提交
475 476 477
  tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
  tEncodeSVDropStbReq(&encoder, &req);
  tEncoderClear(&encoder);
478

S
Shengliang Guan 已提交
479 480
  *pContLen = contLen;
  return pHead;
481 482
}

483
int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
S
Shengliang Guan 已提交
484
  if (pCreate->igExists < 0 || pCreate->igExists > 1) {
S
Shengliang Guan 已提交
485
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
486 487
    return -1;
  }
S
Shengliang Guan 已提交
488

S
Shengliang Guan 已提交
489
  if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
S
Shengliang Guan 已提交
490
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
491 492
    return -1;
  }
S
Shengliang Guan 已提交
493

S
Shengliang Guan 已提交
494
  if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
S
Shengliang Guan 已提交
495
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
496 497
    return -1;
  }
S
Shengliang Guan 已提交
498

S
Shengliang Guan 已提交
499
  SField *pField = taosArrayGet(pCreate->pColumns, 0);
S
Shengliang Guan 已提交
500
  if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) {
S
Shengliang Guan 已提交
501 502 503 504
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }

S
Shengliang Guan 已提交
505
  for (int32_t i = 0; i < pCreate->numOfColumns; ++i) {
506
    SField *pField1 = taosArrayGet(pCreate->pColumns, i);
S
Shengliang Guan 已提交
507
    if (pField1->type < 0) {
S
Shengliang Guan 已提交
508 509 510
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
511
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
512 513 514
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
515
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
516 517 518 519 520 521
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
  }

  for (int32_t i = 0; i < pCreate->numOfTags; ++i) {
522 523
    SField *pField1 = taosArrayGet(pCreate->pTags, i);
    if (pField1->type < 0) {
S
Shengliang Guan 已提交
524
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
525 526
      return -1;
    }
527
    if (pField1->bytes <= 0) {
S
Shengliang Guan 已提交
528
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
529 530
      return -1;
    }
531
    if (pField1->name[0] == 0) {
S
Shengliang Guan 已提交
532
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
533 534 535
      return -1;
    }
  }
S
Shengliang Guan 已提交
536

S
Shengliang Guan 已提交
537 538 539
  return 0;
}

540
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
541 542 543 544 545 546 547 548
  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;
}

549
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
550 551 552 553 554 555 556 557
  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;
}

558
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
559 560 561 562 563 564 565 566
  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;
}

567
static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
568
  SSdb   *pSdb = pMnode->pSdb;
569
  SVgObj *pVgroup = NULL;
570
  void   *pIter = NULL;
S
Shengliang Guan 已提交
571
  int32_t contLen;
572 573 574 575

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
576 577 578 579
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
580

S
Shengliang Guan 已提交
581
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
582
    if (pReq == NULL) {
583 584 585 586
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
S
Shengliang Guan 已提交
587

588 589
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
590
    action.pCont = pReq;
S
Shengliang Guan 已提交
591
    action.contLen = contLen;
H
Hongze Cheng 已提交
592
    action.msgType = TDMT_VND_CREATE_STB;
S
Shengliang Guan 已提交
593
    action.acceptableCode = TSDB_CODE_TDB_STB_ALREADY_EXIST;
594
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
595
      taosMemoryFree(pReq);
596 597 598 599 600 601
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
602 603 604 605

  return 0;
}

606
static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
607
  SSdb   *pSdb = pMnode->pSdb;
608
  SVgObj *pVgroup = NULL;
609
  void   *pIter = NULL;
610 611 612 613

  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
614 615 616 617
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
618

S
Shengliang Guan 已提交
619
    int32_t contLen = 0;
S
Shengliang Guan 已提交
620
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
621
    if (pReq == NULL) {
622 623 624 625 626
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
S
Shengliang Guan 已提交
627

628 629
    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
S
Shengliang Guan 已提交
630
    action.pCont = pReq;
S
Shengliang Guan 已提交
631
    action.contLen = contLen;
H
Hongze Cheng 已提交
632
    action.msgType = TDMT_VND_DROP_STB;
S
Shengliang Guan 已提交
633
    action.acceptableCode = TSDB_CODE_TDB_STB_NOT_EXIST;
634
    if (mndTransAppendUndoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
635
      taosMemoryFree(pReq);
636 637 638 639 640 641
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }
S
Shengliang Guan 已提交
642 643 644 645

  return 0;
}

S
sma  
Shengliang Guan 已提交
646
static SSchema *mndFindStbColumns(const SStbObj *pStb, const char *colName) {
C
Cary Xu 已提交
647
  for (int32_t col = 0; col < pStb->numOfColumns; ++col) {
S
sma  
Shengliang Guan 已提交
648
    SSchema *pSchema = &pStb->pColumns[col];
C
Cary Xu 已提交
649
    if (strncasecmp(pSchema->name, colName, TSDB_COL_NAME_LEN) == 0) {
S
sma  
Shengliang Guan 已提交
650 651 652 653 654 655
      return pSchema;
    }
  }
  return NULL;
}

656 657 658 659 660 661 662
int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreate, SDbObj *pDb) {
  memcpy(pDst->name, pCreate->name, TSDB_TABLE_FNAME_LEN);
  memcpy(pDst->db, pDb->name, TSDB_DB_FNAME_LEN);
  pDst->createdTime = taosGetTimestampMs();
  pDst->updateTime = pDst->createdTime;
  pDst->uid = mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
  pDst->dbUid = pDb->uid;
663 664
  pDst->tagVer = 1;
  pDst->colVer = 1;
665 666 667 668 669 670 671 672 673 674
  pDst->nextColId = 1;
  pDst->xFilesFactor = pCreate->xFilesFactor;
  pDst->delay = pCreate->delay;
  pDst->ttl = pCreate->ttl;
  pDst->numOfColumns = pCreate->numOfColumns;
  pDst->numOfTags = pCreate->numOfTags;
  pDst->commentLen = pCreate->commentLen;
  if (pDst->commentLen > 0) {
    pDst->comment = taosMemoryCalloc(pDst->commentLen, 1);
    if (pDst->comment == NULL) {
S
sma  
Shengliang Guan 已提交
675 676 677
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
678
    memcpy(pDst->comment, pCreate->comment, pDst->commentLen);
S
sma  
Shengliang Guan 已提交
679
  }
S
Shengliang Guan 已提交
680

681 682 683 684
  pDst->ast1Len = pCreate->ast1Len;
  if (pDst->ast1Len > 0) {
    pDst->pAst1 = taosMemoryCalloc(pDst->ast1Len, 1);
    if (pDst->pAst1 == NULL) {
685 686 687
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
688
    memcpy(pDst->pAst1, pCreate->pAst1, pDst->ast1Len);
689 690
  }

691 692 693 694
  pDst->ast2Len = pCreate->ast2Len;
  if (pDst->ast2Len > 0) {
    pDst->pAst2 = taosMemoryCalloc(pDst->ast2Len, 1);
    if (pDst->pAst2 == NULL) {
695 696 697
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
698
    memcpy(pDst->pAst2, pCreate->pAst2, pDst->ast2Len);
699 700
  }

701 702 703
  pDst->pColumns = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SSchema));
  pDst->pTags = taosMemoryCalloc(1, pDst->numOfTags * sizeof(SSchema));
  if (pDst->pColumns == NULL || pDst->pTags == NULL) {
S
Shengliang Guan 已提交
704 705 706
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
707

708
  for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
S
Shengliang Guan 已提交
709
    SField  *pField = taosArrayGet(pCreate->pColumns, i);
710
    SSchema *pSchema = &pDst->pColumns[i];
S
Shengliang Guan 已提交
711 712
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
713
    pSchema->flags = pField->flags;
S
Shengliang Guan 已提交
714
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
715 716
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
717 718
  }

719
  for (int32_t i = 0; i < pDst->numOfTags; ++i) {
S
Shengliang Guan 已提交
720
    SField  *pField = taosArrayGet(pCreate->pTags, i);
721
    SSchema *pSchema = &pDst->pTags[i];
S
Shengliang Guan 已提交
722 723 724
    pSchema->type = pField->type;
    pSchema->bytes = pField->bytes;
    memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN);
725 726
    pSchema->colId = pDst->nextColId;
    pDst->nextColId++;
S
Shengliang Guan 已提交
727
  }
728 729 730
  return 0;
}

S
Shengliang Guan 已提交
731
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
732
  SStbObj stbObj = {0};
S
Shengliang Guan 已提交
733

S
Shengliang 已提交
734
  int32_t code = -1;
735

736
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
737
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
738

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

741
  if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
742 743 744

  if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;

745
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
746

S
Shengliang Guan 已提交
747 748
  code = 0;

749
_OVER:
S
Shengliang Guan 已提交
750
  mndTransDrop(pTrans);
S
Shengliang Guan 已提交
751
  return code;
S
Shengliang Guan 已提交
752
}
S
Shengliang Guan 已提交
753

754
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
755
  mndTransSetDbName(pTrans, pDb->name);
756 757 758 759 760 761 762
  if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) return -1;
  if (mndSetCreateStbUndoActions(pMnode, pTrans, pDb, pStb) != 0) return -1;
  return 0;
}
S
Shengliang Guan 已提交
763

S
Shengliang Guan 已提交
764 765
static int32_t mndProcessMCreateStbReq(SRpcMsg *pReq) {
  SMnode        *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
766 767 768
  int32_t        code = -1;
  SStbObj       *pStb = NULL;
  SDbObj        *pDb = NULL;
S
Shengliang Guan 已提交
769
  SUserObj      *pUser = NULL;
S
Shengliang Guan 已提交
770
  SMCreateStbReq createReq = {0};
S
Shengliang Guan 已提交
771

S
Shengliang Guan 已提交
772
  if (tDeserializeSMCreateStbReq(pReq->pCont, pReq->contLen, &createReq) != 0) {
S
Shengliang Guan 已提交
773
    terrno = TSDB_CODE_INVALID_MSG;
774
    goto _OVER;
S
Shengliang Guan 已提交
775
  }
S
Shengliang Guan 已提交
776

S
Shengliang Guan 已提交
777
  mDebug("stb:%s, start to create", createReq.name);
S
Shengliang Guan 已提交
778 779
  if (mndCheckCreateStbReq(&createReq) != 0) {
    terrno = TSDB_CODE_INVALID_MSG;
780
    goto _OVER;
S
Shengliang Guan 已提交
781
  }
S
Shengliang Guan 已提交
782

S
Shengliang Guan 已提交
783
  pStb = mndAcquireStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
784
  if (pStb != NULL) {
S
Shengliang Guan 已提交
785 786 787
    if (createReq.igExists) {
      mDebug("stb:%s, already exist, ignore exist is set", createReq.name);
      code = 0;
788
      goto _OVER;
S
Shengliang Guan 已提交
789 790
    } else {
      terrno = TSDB_CODE_MND_STB_ALREADY_EXIST;
791
      goto _OVER;
S
Shengliang Guan 已提交
792
    }
S
Shengliang Guan 已提交
793
  } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) {
794
    goto _OVER;
S
Shengliang Guan 已提交
795 796
  }

S
Shengliang Guan 已提交
797
  pDb = mndAcquireDbByStb(pMnode, createReq.name);
S
Shengliang Guan 已提交
798 799
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
800
    goto _OVER;
S
Shengliang Guan 已提交
801 802
  }

S
Shengliang Guan 已提交
803
  pUser = mndAcquireUser(pMnode, pReq->conn.user);
S
Shengliang Guan 已提交
804
  if (pUser == NULL) {
805
    goto _OVER;
S
Shengliang Guan 已提交
806 807 808
  }

  if (mndCheckWriteAuth(pUser, pDb) != 0) {
809
    goto _OVER;
S
Shengliang Guan 已提交
810 811
  }

812
  int32_t numOfStbs = -1;
S
Shengliang Guan 已提交
813 814 815 816
  if (mndGetNumOfStbs(pMnode, pDb->name, &numOfStbs) != 0) {
    goto _OVER;
  }

L
Liu Jicong 已提交
817
  if (pDb->cfg.numOfStables == 1 && numOfStbs != 0) {
818 819 820 821
    terrno = TSDB_CODE_MND_SINGLE_STB_MODE_DB;
    goto _OVER;
  }

S
Shengliang Guan 已提交
822
  code = mndCreateStb(pMnode, pReq, &createReq, pDb);
S
Shengliang Guan 已提交
823
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
824

825
_OVER:
S
Shengliang Guan 已提交
826
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
827
    mError("stb:%s, failed to create since %s", createReq.name, terrstr());
S
Shengliang Guan 已提交
828 829
  }

S
Shengliang Guan 已提交
830 831
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
832 833
  mndReleaseUser(pMnode, pUser);
  tFreeSMCreateStbReq(&createReq);
S
Shengliang Guan 已提交
834 835

  return code;
S
Shengliang Guan 已提交
836 837
}

S
Shengliang Guan 已提交
838
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
S
Shengliang 已提交
839
  if (pAlter->commentLen != 0 || pAlter->ttl != 0) return 0;
S
Shengliang 已提交
840

S
Shengliang Guan 已提交
841 842 843 844
  if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
    return -1;
  }
S
Shengliang Guan 已提交
845

S
Shengliang Guan 已提交
846 847 848
  for (int32_t i = 0; i < pAlter->numOfFields; ++i) {
    SField *pField = taosArrayGet(pAlter->pFields, i);
    if (pField->name[0] == 0) {
S
Shengliang Guan 已提交
849 850 851
      terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
      return -1;
    }
S
Shengliang Guan 已提交
852 853 854 855 856
  }

  return 0;
}

S
Shengliang Guan 已提交
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
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) {
wafwerar's avatar
wafwerar 已提交
878 879
  pNew->pTags = taosMemoryCalloc(pNew->numOfTags, sizeof(SSchema));
  pNew->pColumns = taosMemoryCalloc(pNew->numOfColumns, sizeof(SSchema));
S
Shengliang Guan 已提交
880 881 882 883 884 885 886 887 888 889
  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 已提交
890 891
static int32_t mndUpdateStbCommentAndTTL(const SStbObj *pOld, SStbObj *pNew, char *pComment, int32_t commentLen,
                                         int32_t ttl) {
S
Shengliang 已提交
892 893 894 895 896 897 898 899 900
  if (commentLen > 0) {
    pNew->commentLen = commentLen;
    pNew->comment = taosMemoryCalloc(1, commentLen);
    if (pNew->comment == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
    memcpy(pNew->comment, pComment, commentLen);
  }
S
Shengliang 已提交
901 902 903
  if (ttl >= 0) {
    pNew->ttl = ttl;
  }
S
Shengliang 已提交
904 905 906 907 908 909 910

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

S
Shengliang Guan 已提交
911
static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ntags) {
S
Shengliang Guan 已提交
912 913 914 915 916 917 918 919 920 921
  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 已提交
922 923 924 925 926
  pNew->numOfTags = pNew->numOfTags + ntags;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
927
  for (int32_t i = 0; i < ntags; i++) {
S
Shengliang Guan 已提交
928
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
929
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
930
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
931 932 933
      return -1;
    }

S
Shengliang 已提交
934
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
935
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
936 937 938
      return -1;
    }

S
Shengliang Guan 已提交
939 940 941 942
    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 已提交
943 944
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
945 946

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

949
  pNew->tagVer++;
S
Shengliang Guan 已提交
950 951 952
  return 0;
}

953
static int32_t mndDropSuperTableTag(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *tagName) {
S
Shengliang Guan 已提交
954 955 956 957 958 959
  int32_t tag = mndFindSuperTableTagIndex(pOld, tagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

960 961 962 963 964
  col_id_t colId = pOld->pTags[tag].colId;
  if (mndCheckColAndTagModifiable(pMnode, pOld->uid, colId) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
965 966 967 968 969
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

972
  pNew->tagVer++;
S
Shengliang Guan 已提交
973 974 975 976
  mDebug("stb:%s, start to drop tag %s", pNew->name, tagName);
  return 0;
}

977
static int32_t mndAlterStbTagName(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, SArray *pFields) {
S
Shengliang Guan 已提交
978 979 980 981 982 983 984 985 986 987 988
  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 已提交
989 990 991 992 993 994
  int32_t tag = mndFindSuperTableTagIndex(pOld, oldTagName);
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

995 996 997 998 999
  col_id_t colId = pOld->pTags[tag].colId;
  if (mndCheckColAndTagModifiable(pMnode, pOld->uid, colId) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1000
  if (mndFindSuperTableTagIndex(pOld, newTagName) >= 0) {
S
Shengliang Guan 已提交
1001
    terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1002 1003 1004
    return -1;
  }

S
Shengliang Guan 已提交
1005 1006
  if (mndFindSuperTableColumnIndex(pOld, newTagName) >= 0) {
    terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
    return -1;
  }

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

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

1017
  pNew->tagVer++;
S
Shengliang Guan 已提交
1018 1019 1020 1021
  mDebug("stb:%s, start to modify tag %s to %s", pNew->name, oldTagName, newTagName);
  return 0;
}

1022
static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1023
  int32_t tag = mndFindSuperTableTagIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1024 1025 1026 1027 1028
  if (tag < 0) {
    terrno = TSDB_CODE_MND_TAG_NOT_EXIST;
    return -1;
  }

1029 1030 1031 1032 1033
  col_id_t colId = pOld->pTags[tag].colId;
  if (mndCheckColAndTagModifiable(pMnode, pOld->uid, colId) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1034 1035 1036 1037 1038 1039
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pTag = pNew->pTags + tag;

S
Shengliang Guan 已提交
1040 1041 1042 1043 1044
  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 已提交
1045
  if (pField->bytes <= pTag->bytes) {
S
Shengliang Guan 已提交
1046 1047 1048 1049
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
    return -1;
  }

S
Shengliang Guan 已提交
1050
  pTag->bytes = pField->bytes;
1051
  pNew->tagVer++;
S
Shengliang Guan 已提交
1052

S
Shengliang Guan 已提交
1053
  mDebug("stb:%s, start to modify tag len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1054 1055 1056
  return 0;
}

S
Shengliang Guan 已提交
1057
static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray *pFields, int32_t ncols) {
S
Shengliang Guan 已提交
1058 1059 1060 1061 1062
  if (pOld->numOfColumns + ncols + pOld->numOfTags > TSDB_MAX_COLUMNS) {
    terrno = TSDB_CODE_MND_TOO_MANY_COLUMNS;
    return -1;
  }

S
Shengliang Guan 已提交
1063 1064 1065 1066 1067
  pNew->numOfColumns = pNew->numOfColumns + ncols;
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1068
  for (int32_t i = 0; i < ncols; i++) {
S
Shengliang Guan 已提交
1069
    SField *pField = taosArrayGet(pFields, i);
S
Shengliang 已提交
1070
    if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1071
      terrno = TSDB_CODE_MND_COLUMN_ALREADY_EXIST;
S
Shengliang Guan 已提交
1072 1073 1074
      return -1;
    }

S
Shengliang 已提交
1075
    if (mndFindSuperTableTagIndex(pOld, pField->name) >= 0) {
S
Shengliang Guan 已提交
1076
      terrno = TSDB_CODE_MND_TAG_ALREADY_EXIST;
S
Shengliang Guan 已提交
1077 1078 1079
      return -1;
    }

S
Shengliang Guan 已提交
1080 1081 1082 1083
    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 已提交
1084 1085
    pSchema->colId = pNew->nextColId;
    pNew->nextColId++;
S
Shengliang Guan 已提交
1086 1087

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

1090
  pNew->colVer++;
S
Shengliang Guan 已提交
1091 1092 1093
  return 0;
}

1094
static int32_t mndDropSuperTableColumn(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const char *colName) {
S
Shengliang Guan 已提交
1095
  int32_t col = mndFindSuperTableColumnIndex(pOld, colName);
S
Shengliang Guan 已提交
1096
  if (col < 0) {
S
Shengliang Guan 已提交
1097 1098 1099 1100
    terrno = TSDB_CODE_MND_COLUMN_NOT_EXIST;
    return -1;
  }

S
Shengliang Guan 已提交
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
  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;
  }

1111 1112 1113 1114 1115
  col_id_t colId = pOld->pTags[col].colId;
  if (mndCheckColAndTagModifiable(pMnode, pOld->uid, colId) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1116 1117 1118 1119 1120
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

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

1123
  pNew->colVer++;
S
Shengliang Guan 已提交
1124 1125 1126 1127
  mDebug("stb:%s, start to drop col %s", pNew->name, colName);
  return 0;
}

1128
static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj *pNew, const SField *pField) {
S
Shengliang Guan 已提交
1129
  int32_t col = mndFindSuperTableColumnIndex(pOld, pField->name);
S
Shengliang Guan 已提交
1130 1131 1132 1133 1134 1135 1136
  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 已提交
1137
    nLen += (pOld->pColumns[i].colId == col) ? pField->bytes : pOld->pColumns[i].bytes;
S
Shengliang Guan 已提交
1138 1139 1140 1141 1142 1143 1144
  }

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

1145 1146 1147 1148 1149
  col_id_t colId = pOld->pTags[col].colId;
  if (mndCheckColAndTagModifiable(pMnode, pOld->uid, colId) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
1150 1151 1152 1153 1154
  if (mndAllocStbSchemas(pOld, pNew) != 0) {
    return -1;
  }

  SSchema *pCol = pNew->pColumns + col;
S
Shengliang Guan 已提交
1155 1156
  if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR)) {
    terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
S
Shengliang Guan 已提交
1157 1158 1159
    return -1;
  }

S
Shengliang Guan 已提交
1160
  if (pField->bytes <= pCol->bytes) {
S
Shengliang Guan 已提交
1161
    terrno = TSDB_CODE_MND_INVALID_ROW_BYTES;
S
Shengliang Guan 已提交
1162 1163 1164
    return -1;
  }

S
Shengliang Guan 已提交
1165
  pCol->bytes = pField->bytes;
1166
  pNew->colVer++;
S
Shengliang Guan 已提交
1167

S
Shengliang Guan 已提交
1168
  mDebug("stb:%s, start to modify col len %s to %d", pNew->name, pField->name, pField->bytes);
S
Shengliang Guan 已提交
1169 1170 1171
  return 0;
}

S
Shengliang Guan 已提交
1172
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1173 1174 1175
  SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
  if (pRedoRaw == NULL) return -1;
  if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
S
Shengliang Guan 已提交
1176
  if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
S
Shengliang Guan 已提交
1177 1178 1179 1180

  return 0;
}

S
Shengliang Guan 已提交
1181
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1182 1183 1184 1185 1186 1187 1188 1189
  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 已提交
1190
static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1191 1192 1193 1194 1195 1196 1197 1198
  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 已提交
1199 1200 1201 1202
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
S
Shengliang Guan 已提交
1203

S
Shengliang Guan 已提交
1204
    void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
    if (pReq == NULL) {
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }

    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
    action.pCont = pReq;
    action.contLen = contLen;
S
Shengliang Guan 已提交
1215
    action.msgType = TDMT_VND_ALTER_STB;
S
Shengliang Guan 已提交
1216
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
1217
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

D
dapan1121 已提交
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
  taosRLockLatch(&pStb->lock);

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

  strcpy(pRsp->dbFName, pStb->db);
  strcpy(pRsp->tbName, tbName);
  strcpy(pRsp->stbName, tbName);
  pRsp->dbId = pDb->uid;
  pRsp->numOfTags = pStb->numOfTags;
  pRsp->numOfColumns = pStb->numOfColumns;
  pRsp->precision = pDb->cfg.precision;
  pRsp->tableType = TSDB_SUPER_TABLE;
  pRsp->sversion = pStb->colVer;
  pRsp->tversion = pStb->tagVer;
  pRsp->suid = pStb->uid;
  pRsp->tuid = pStb->uid;

  for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
    SSchema *pSchema = &pRsp->pSchemas[i];
    SSchema *pSrcSchema = &pStb->pColumns[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
  }

  for (int32_t i = 0; i < pStb->numOfTags; ++i) {
    SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
    SSchema *pSrcSchema = &pStb->pTags[i];
    memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
    pSchema->type = pSrcSchema->type;
    pSchema->colId = pSrcSchema->colId;
    pSchema->bytes = pSrcSchema->bytes;
  }

  taosRUnLockLatch(&pStb->lock);
  return 0;
}

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);

  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;
}

1297 1298
static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, const SMAlterStbReq *pAlter, SStbObj *pObj, void **pCont,
                                     int32_t *pLen) {
D
dapan1121 已提交
1299 1300
  int           ret;
  SEncoder      ec = {0};
1301
  uint32_t      contLen = 0;
D
dapan1121 已提交
1302
  SMAlterStbRsp alterRsp = {0};
1303
  SName         name = {0};
D
dapan1121 已提交
1304 1305 1306 1307 1308 1309 1310
  tNameFromString(&name, pAlter->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);

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

D
dapan1121 已提交
1312
  ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
D
dapan1121 已提交
1313 1314 1315 1316
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }
1317

D
dapan1121 已提交
1318 1319 1320 1321 1322 1323
  tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
  if (ret) {
    tFreeSMAlterStbRsp(&alterRsp);
    return ret;
  }

1324
  void *cont = taosMemoryMalloc(contLen);
D
dapan1121 已提交
1325 1326 1327 1328 1329 1330 1331 1332
  tEncoderInit(&ec, cont, contLen);
  tEncodeSMAlterStbRsp(&ec, &alterRsp);
  tEncoderClear(&ec);

  tFreeSMAlterStbRsp(&alterRsp);

  *pCont = cont;
  *pLen = contLen;
1333

D
dapan1121 已提交
1334 1335 1336
  return 0;
}

S
Shengliang Guan 已提交
1337
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
1338 1339 1340 1341 1342
  bool    needRsp = true;
  int32_t code = -1;
  STrans *pTrans = NULL;
  SField *pField0 = NULL;

S
Shengliang Guan 已提交
1343 1344 1345
  SStbObj stbObj = {0};
  taosRLockLatch(&pOld->lock);
  memcpy(&stbObj, pOld, sizeof(SStbObj));
1346
  taosRUnLockLatch(&pOld->lock);
S
Shengliang Guan 已提交
1347 1348 1349
  stbObj.pColumns = NULL;
  stbObj.pTags = NULL;
  stbObj.updateTime = taosGetTimestampMs();
D
dapan1121 已提交
1350
  stbObj.lock = 0;
S
Shengliang Guan 已提交
1351

S
Shengliang Guan 已提交
1352
  switch (pAlter->alterType) {
S
Shengliang Guan 已提交
1353
    case TSDB_ALTER_TABLE_ADD_TAG:
S
Shengliang Guan 已提交
1354
      code = mndAddSuperTableTag(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1355
      break;
S
Shengliang Guan 已提交
1356
    case TSDB_ALTER_TABLE_DROP_TAG:
S
Shengliang 已提交
1357
      pField0 = taosArrayGet(pAlter->pFields, 0);
1358
      code = mndDropSuperTableTag(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1359
      break;
S
Shengliang Guan 已提交
1360
    case TSDB_ALTER_TABLE_UPDATE_TAG_NAME:
1361
      code = mndAlterStbTagName(pMnode, pOld, &stbObj, pAlter->pFields);
S
Shengliang Guan 已提交
1362
      break;
S
Shengliang Guan 已提交
1363
    case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
S
Shengliang 已提交
1364
      pField0 = taosArrayGet(pAlter->pFields, 0);
1365
      code = mndAlterStbTagBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1366 1367
      break;
    case TSDB_ALTER_TABLE_ADD_COLUMN:
S
Shengliang Guan 已提交
1368
      code = mndAddSuperTableColumn(pOld, &stbObj, pAlter->pFields, pAlter->numOfFields);
S
Shengliang Guan 已提交
1369 1370
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
S
Shengliang 已提交
1371
      pField0 = taosArrayGet(pAlter->pFields, 0);
1372
      code = mndDropSuperTableColumn(pMnode, pOld, &stbObj, pField0->name);
S
Shengliang Guan 已提交
1373
      break;
S
Shengliang Guan 已提交
1374
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
S
Shengliang 已提交
1375
      pField0 = taosArrayGet(pAlter->pFields, 0);
1376
      code = mndAlterStbColumnBytes(pMnode, pOld, &stbObj, pField0);
S
Shengliang Guan 已提交
1377
      break;
S
Shengliang 已提交
1378
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
D
dapan1121 已提交
1379
      needRsp = false;
S
Shengliang 已提交
1380
      code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
S
Shengliang 已提交
1381
      break;
S
Shengliang Guan 已提交
1382
    default:
D
dapan1121 已提交
1383
      needRsp = false;
S
Shengliang 已提交
1384
      terrno = TSDB_CODE_OPS_NOT_SUPPORT;
S
Shengliang Guan 已提交
1385 1386 1387
      break;
  }

1388
  if (code != 0) goto _OVER;
S
Shengliang Guan 已提交
1389 1390

  code = -1;
1391
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq);
1392
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
1393

S
Shengliang Guan 已提交
1394
  mDebug("trans:%d, used to alter stb:%s", pTrans->id, pAlter->name);
1395
  mndTransSetDbName(pTrans, pDb->name);
S
Shengliang Guan 已提交
1396

D
dapan1121 已提交
1397
  if (needRsp) {
1398
    void   *pCont = NULL;
D
dapan1121 已提交
1399
    int32_t contLen = 0;
1400
    if (mndBuildSMAlterStbRsp(pDb, pAlter, &stbObj, &pCont, &contLen) != 0) goto _OVER;
D
dapan1121 已提交
1401 1402
    mndTransSetRpcRsp(pTrans, pCont, contLen);
  }
1403

1404 1405 1406 1407
  if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
  if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
  if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
1408 1409

  code = 0;
S
Shengliang Guan 已提交
1410

1411
_OVER:
S
Shengliang Guan 已提交
1412
  mndTransDrop(pTrans);
wafwerar's avatar
wafwerar 已提交
1413 1414
  taosMemoryFreeClear(stbObj.pTags);
  taosMemoryFreeClear(stbObj.pColumns);
S
Shengliang Guan 已提交
1415 1416
  return code;
}
S
Shengliang Guan 已提交
1417

S
Shengliang Guan 已提交
1418 1419
static int32_t mndProcessMAlterStbReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1420 1421 1422 1423 1424
  int32_t       code = -1;
  SDbObj       *pDb = NULL;
  SStbObj      *pStb = NULL;
  SUserObj     *pUser = NULL;
  SMAlterStbReq alterReq = {0};
S
Shengliang Guan 已提交
1425

S
Shengliang Guan 已提交
1426
  if (tDeserializeSMAlterStbReq(pReq->pCont, pReq->contLen, &alterReq) != 0) {
S
Shengliang Guan 已提交
1427
    terrno = TSDB_CODE_INVALID_MSG;
1428
    goto _OVER;
S
Shengliang Guan 已提交
1429
  }
S
Shengliang Guan 已提交
1430

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

S
Shengliang Guan 已提交
1434
  pDb = mndAcquireDbByStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1435 1436
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_INVALID_DB;
1437
    goto _OVER;
S
Shengliang Guan 已提交
1438 1439
  }

S
Shengliang Guan 已提交
1440
  pStb = mndAcquireStb(pMnode, alterReq.name);
S
Shengliang Guan 已提交
1441 1442
  if (pStb == NULL) {
    terrno = TSDB_CODE_MND_STB_NOT_EXIST;
1443
    goto _OVER;
S
Shengliang Guan 已提交
1444
  }
S
Shengliang Guan 已提交
1445

1446 1447 1448 1449
  if ((alterReq.tagVer > 0 && alterReq.colVer > 0) &&
      (alterReq.tagVer <= pStb->tagVer || alterReq.colVer <= pStb->colVer)) {
    mDebug("stb:%s, already exist, tagVer:%d colVer:%d smaller than in mnode, tagVer:%d colVer:%d, alter success",
           alterReq.name, alterReq.tagVer, alterReq.colVer, pStb->tagVer, pStb->colVer);
1450 1451 1452 1453
    code = 0;
    goto _OVER;
  }

S
Shengliang Guan 已提交
1454
  pUser = mndAcquireUser(pMnode, pReq->conn.user);
S
Shengliang Guan 已提交
1455
  if (pUser == NULL) {
1456
    goto _OVER;
S
Shengliang Guan 已提交
1457 1458 1459
  }

  if (mndCheckWriteAuth(pUser, pDb) != 0) {
1460
    goto _OVER;
S
Shengliang Guan 已提交
1461 1462
  }

S
Shengliang Guan 已提交
1463
  code = mndAlterStb(pMnode, pReq, &alterReq, pDb, pStb);
S
Shengliang Guan 已提交
1464
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
S
Shengliang Guan 已提交
1465

1466
_OVER:
S
Shengliang Guan 已提交
1467
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1468
    mError("stb:%s, failed to alter since %s", alterReq.name, terrstr());
S
Shengliang Guan 已提交
1469 1470
  }

S
Shengliang Guan 已提交
1471 1472
  mndReleaseStb(pMnode, pStb);
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1473
  mndReleaseUser(pMnode, pUser);
S
Shengliang Guan 已提交
1474
  taosArrayDestroy(alterReq.pFields);
S
Shengliang Guan 已提交
1475 1476

  return code;
S
Shengliang Guan 已提交
1477
}
S
Shengliang Guan 已提交
1478

S
Shengliang Guan 已提交
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496
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 已提交
1497 1498 1499 1500
static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
  SSdb   *pSdb = pMnode->pSdb;
  SVgObj *pVgroup = NULL;
  void   *pIter = NULL;
S
Shengliang Guan 已提交
1501

S
Shengliang Guan 已提交
1502 1503 1504
  while (1) {
    pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
    if (pIter == NULL) break;
S
Shengliang Guan 已提交
1505 1506 1507 1508
    if (pVgroup->dbUid != pDb->uid) {
      sdbRelease(pSdb, pVgroup);
      continue;
    }
S
Shengliang Guan 已提交
1509

S
Shengliang Guan 已提交
1510
    int32_t contLen = 0;
S
Shengliang Guan 已提交
1511
    void   *pReq = mndBuildVDropStbReq(pMnode, pVgroup, pStb, &contLen);
S
Shengliang Guan 已提交
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525
    if (pReq == NULL) {
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }

    STransAction action = {0};
    action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
    action.pCont = pReq;
    action.contLen = contLen;
    action.msgType = TDMT_VND_DROP_STB;
    action.acceptableCode = TSDB_CODE_VND_TB_NOT_EXIST;
    if (mndTransAppendRedoAction(pTrans, &action) != 0) {
wafwerar's avatar
wafwerar 已提交
1526
      taosMemoryFree(pReq);
S
Shengliang Guan 已提交
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
      sdbCancelFetch(pSdb, pIter);
      sdbRelease(pSdb, pVgroup);
      return -1;
    }
    sdbRelease(pSdb, pVgroup);
  }

  return 0;
}

S
Shengliang Guan 已提交
1537
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
S
Shengliang Guan 已提交
1538
  int32_t code = -1;
1539
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
1540
  if (pTrans == NULL) goto _OVER;
S
Shengliang Guan 已提交
1541

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

1545 1546 1547 1548
  if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
  if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
  if (mndSetDropStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
  if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
S
Shengliang Guan 已提交
1549

S
Shengliang Guan 已提交
1550 1551
  code = 0;

1552
_OVER:
S
Shengliang Guan 已提交
1553
  mndTransDrop(pTrans);
S
Shengliang 已提交
1554
  return code;
S
Shengliang Guan 已提交
1555 1556
}

S
Shengliang Guan 已提交
1557 1558
static int32_t mndProcessMDropStbReq(SRpcMsg *pReq) {
  SMnode      *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1559 1560 1561 1562
  int32_t      code = -1;
  SUserObj    *pUser = NULL;
  SDbObj      *pDb = NULL;
  SStbObj     *pStb = NULL;
S
Shengliang Guan 已提交
1563
  SMDropStbReq dropReq = {0};
S
Shengliang Guan 已提交
1564

S
Shengliang Guan 已提交
1565
  if (tDeserializeSMDropStbReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
S
Shengliang Guan 已提交
1566
    terrno = TSDB_CODE_INVALID_MSG;
1567
    goto _OVER;
S
Shengliang Guan 已提交
1568
  }
S
Shengliang Guan 已提交
1569

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

S
Shengliang Guan 已提交
1572
  pStb = mndAcquireStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
1573
  if (pStb == NULL) {
S
Shengliang Guan 已提交
1574 1575
    if (dropReq.igNotExists) {
      mDebug("stb:%s, not exist, ignore not exist is set", dropReq.name);
S
Shengliang Guan 已提交
1576
      code = 0;
1577
      goto _OVER;
S
Shengliang Guan 已提交
1578 1579
    } else {
      terrno = TSDB_CODE_MND_STB_NOT_EXIST;
1580
      goto _OVER;
S
Shengliang Guan 已提交
1581 1582 1583
    }
  }

S
Shengliang Guan 已提交
1584
  pDb = mndAcquireDbByStb(pMnode, dropReq.name);
S
Shengliang Guan 已提交
1585 1586
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
1587
    goto _OVER;
S
Shengliang Guan 已提交
1588 1589
  }

S
Shengliang Guan 已提交
1590
  pUser = mndAcquireUser(pMnode, pReq->conn.user);
S
Shengliang Guan 已提交
1591
  if (pUser == NULL) {
1592
    goto _OVER;
S
Shengliang Guan 已提交
1593
  }
S
Shengliang Guan 已提交
1594

S
Shengliang Guan 已提交
1595
  if (mndCheckWriteAuth(pUser, pDb) != 0) {
1596
    goto _OVER;
S
Shengliang Guan 已提交
1597 1598 1599
  }

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

1602
_OVER:
S
Shengliang Guan 已提交
1603
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
S
Shengliang Guan 已提交
1604
    mError("stb:%s, failed to drop since %s", dropReq.name, terrstr());
S
Shengliang Guan 已提交
1605 1606
  }

S
Shengliang Guan 已提交
1607 1608 1609 1610 1611
  mndReleaseDb(pMnode, pDb);
  mndReleaseStb(pMnode, pStb);
  mndReleaseUser(pMnode, pUser);

  return code;
S
Shengliang Guan 已提交
1612
}
S
Shengliang Guan 已提交
1613

S
Shengliang Guan 已提交
1614 1615
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
  SMnode       *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1616 1617 1618
  int32_t       code = -1;
  STableInfoReq infoReq = {0};
  STableMetaRsp metaRsp = {0};
D
dapan 已提交
1619

S
Shengliang Guan 已提交
1620
  if (tDeserializeSTableInfoReq(pReq->pCont, pReq->contLen, &infoReq) != 0) {
S
Shengliang Guan 已提交
1621
    terrno = TSDB_CODE_INVALID_MSG;
1622
    goto _OVER;
S
Shengliang Guan 已提交
1623
  }
D
dapan 已提交
1624

D
dapan1121 已提交
1625 1626 1627
  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) {
1628
      goto _OVER;
D
dapan1121 已提交
1629
    }
D
dapan1121 已提交
1630 1631 1632
  } else if (0 == strcmp(infoReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) {
    mDebug("performance_schema table:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
    if (mndBuildPerfsTableSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
1633
      goto _OVER;
D
dapan1121 已提交
1634
    }
D
dapan1121 已提交
1635 1636 1637
  } else {
    mDebug("stb:%s.%s, start to retrieve meta", infoReq.dbFName, infoReq.tbName);
    if (mndBuildStbSchema(pMnode, infoReq.dbFName, infoReq.tbName, &metaRsp) != 0) {
1638
      goto _OVER;
D
dapan1121 已提交
1639
    }
S
Shengliang Guan 已提交
1640
  }
S
Shengliang Guan 已提交
1641

S
Shengliang Guan 已提交
1642 1643 1644
  int32_t rspLen = tSerializeSTableMetaRsp(NULL, 0, &metaRsp);
  if (rspLen < 0) {
    terrno = TSDB_CODE_INVALID_MSG;
1645
    goto _OVER;
S
Shengliang Guan 已提交
1646
  }
S
Shengliang Guan 已提交
1647

S
Shengliang Guan 已提交
1648
  void *pRsp = rpcMallocCont(rspLen);
S
Shengliang Guan 已提交
1649 1650
  if (pRsp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
1651
    goto _OVER;
S
Shengliang Guan 已提交
1652
  }
D
dapan 已提交
1653

S
Shengliang Guan 已提交
1654
  tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
S
Shengliang Guan 已提交
1655 1656
  pReq->info.rsp = pRsp;
  pReq->info.rspLen = rspLen;
S
Shengliang Guan 已提交
1657
  code = 0;
S
Shengliang Guan 已提交
1658

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

1661
_OVER:
S
Shengliang Guan 已提交
1662 1663 1664
  if (code != 0) {
    mError("stb:%s.%s, failed to retrieve meta since %s", infoReq.dbFName, infoReq.tbName, terrstr());
  }
S
Shengliang Guan 已提交
1665

S
Shengliang Guan 已提交
1666 1667 1668
  tFreeSTableMetaRsp(&metaRsp);
  return code;
}
S
Shengliang Guan 已提交
1669

S
Shengliang Guan 已提交
1670 1671 1672 1673 1674 1675 1676 1677
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 已提交
1678

S
Shengliang Guan 已提交
1679 1680 1681 1682 1683
  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 已提交
1684

S
Shengliang Guan 已提交
1685 1686 1687 1688 1689
    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 已提交
1690
    }
S
Shengliang Guan 已提交
1691

D
dapan1121 已提交
1692
    if (pStbVersion->sversion != metaRsp.sversion || pStbVersion->tversion != metaRsp.tversion) {
S
Shengliang Guan 已提交
1693
      taosArrayPush(batchMetaRsp.pArray, &metaRsp);
D
dapan1121 已提交
1694 1695
    } else {
      tFreeSTableMetaRsp(&metaRsp);
S
Shengliang Guan 已提交
1696
    }
S
Shengliang Guan 已提交
1697
  }
S
Shengliang Guan 已提交
1698

S
Shengliang Guan 已提交
1699 1700 1701 1702 1703
  int32_t rspLen = tSerializeSTableMetaBatchRsp(NULL, 0, &batchMetaRsp);
  if (rspLen < 0) {
    tFreeSTableMetaBatchRsp(&batchMetaRsp);
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
D
dapan 已提交
1704 1705
  }

wafwerar's avatar
wafwerar 已提交
1706
  void *pRsp = taosMemoryMalloc(rspLen);
S
Shengliang Guan 已提交
1707 1708 1709 1710
  if (pRsp == NULL) {
    tFreeSTableMetaBatchRsp(&batchMetaRsp);
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
D
dapan 已提交
1711 1712
  }

S
Shengliang Guan 已提交
1713
  tSerializeSTableMetaBatchRsp(pRsp, rspLen, &batchMetaRsp);
D
dapan1121 已提交
1714
  tFreeSTableMetaBatchRsp(&batchMetaRsp);
S
Shengliang Guan 已提交
1715 1716
  *ppRsp = pRsp;
  *pRspLen = rspLen;
D
dapan 已提交
1717 1718 1719
  return 0;
}

1720
int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
S
Shengliang Guan 已提交
1721
  SSdb   *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1722 1723 1724 1725 1726 1727
  SDbObj *pDb = mndAcquireDb(pMnode, dbName);
  if (pDb == NULL) {
    terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
    return -1;
  }

S
Shengliang Guan 已提交
1728
  int32_t numOfStbs = 0;
1729
  void   *pIter = NULL;
S
Shengliang Guan 已提交
1730
  while (1) {
S
Shengliang Guan 已提交
1731
    SStbObj *pStb = NULL;
S
Shengliang Guan 已提交
1732
    pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
S
Shengliang Guan 已提交
1733 1734
    if (pIter == NULL) break;

S
Shengliang Guan 已提交
1735
    if (pStb->dbUid == pDb->uid) {
S
Shengliang Guan 已提交
1736
      numOfStbs++;
S
Shengliang Guan 已提交
1737 1738
    }

S
Shengliang Guan 已提交
1739
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1740 1741
  }

S
Shengliang Guan 已提交
1742
  *pNumOfStbs = numOfStbs;
S
Shengliang Guan 已提交
1743
  mndReleaseDb(pMnode, pDb);
S
Shengliang Guan 已提交
1744 1745 1746
  return 0;
}

S
Shengliang Guan 已提交
1747
static void mndExtractTableName(char *tableId, char *name) {
S
Shengliang Guan 已提交
1748 1749
  int32_t pos = -1;
  int32_t num = 0;
S
Shengliang Guan 已提交
1750
  for (pos = 0; tableId[pos] != 0; ++pos) {
H
Haojun Liao 已提交
1751
    if (tableId[pos] == TS_PATH_DELIMITER[0]) num++;
S
Shengliang Guan 已提交
1752 1753 1754 1755 1756 1757 1758 1759
    if (num == 2) break;
  }

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

S
Shengliang Guan 已提交
1760 1761
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
  SMnode  *pMnode = pReq->info.node;
S
Shengliang Guan 已提交
1762
  SSdb    *pSdb = pMnode->pSdb;
S
Shengliang Guan 已提交
1763 1764 1765
  int32_t  numOfRows = 0;
  SStbObj *pStb = NULL;
  int32_t  cols = 0;
S
Shengliang Guan 已提交
1766

H
Hongze Cheng 已提交
1767
  SDbObj *pDb = NULL;
H
Haojun Liao 已提交
1768 1769
  if (strlen(pShow->db) > 0) {
    pDb = mndAcquireDb(pMnode, pShow->db);
D
dapan1121 已提交
1770
    if (pDb == NULL) return terrno;
H
Haojun Liao 已提交
1771
  }
S
Shengliang Guan 已提交
1772

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

H
Haojun Liao 已提交
1777
    if (pDb != NULL && pStb->dbUid != pDb->uid) {
S
Shengliang Guan 已提交
1778
      sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1779 1780 1781 1782 1783
      continue;
    }

    cols = 0;

H
Haojun Liao 已提交
1784
    SName name = {0};
H
Hongze Cheng 已提交
1785
    char  stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
1786 1787
    mndExtractTableName(pStb->name, &stbName[VARSTR_HEADER_SIZE]);
    varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
S
Shengliang Guan 已提交
1788

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

H
Hongze Cheng 已提交
1792 1793
    char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
    tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
1794 1795 1796
    tNameGetDbName(&name, varDataVal(db));
    varDataSetLen(db, strlen(varDataVal(db)));

1797
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
H
Hongze Cheng 已提交
1798
    colDataAppend(pColInfo, numOfRows, (const char *)db, false);
1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811

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

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

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

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

S
Shengliang 已提交
1812
    char *p = taosMemoryCalloc(1, pStb->commentLen + 1 + VARSTR_HEADER_SIZE);  // check malloc failures
1813 1814 1815 1816 1817 1818 1819
    if (p != NULL) {
      if (pStb->commentLen != 0) {
        STR_TO_VARSTR(p, pStb->comment);
      } else {
        STR_TO_VARSTR(p, "");
      }

1820
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
1821 1822
      colDataAppend(pColInfo, numOfRows, (const char *)p, false);
      taosMemoryFree(p);
S
Shengliang Guan 已提交
1823
    }
H
Haojun Liao 已提交
1824

S
Shengliang Guan 已提交
1825
    numOfRows++;
S
Shengliang Guan 已提交
1826
    sdbRelease(pSdb, pStb);
S
Shengliang Guan 已提交
1827 1828
  }

H
Haojun Liao 已提交
1829 1830 1831 1832
  if (pDb != NULL) {
    mndReleaseDb(pMnode, pDb);
  }

1833
  pShow->numOfRows += numOfRows;
S
Shengliang Guan 已提交
1834 1835 1836
  return numOfRows;
}

S
Shengliang Guan 已提交
1837
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
S
Shengliang Guan 已提交
1838 1839
  SSdb *pSdb = pMnode->pSdb;
  sdbCancelFetch(pSdb, pIter);
D
dapan1121 已提交
1840
}