mnodeTable.c 76.7 KB
Newer Older
H
hzcheng 已提交
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
slguan 已提交
16
#define _DEFAULT_SOURCE
H
hjxilinx 已提交
17
#include "os.h"
S
slguan 已提交
18 19 20 21 22 23
#include "taosmsg.h"
#include "ttime.h"
#include "tutil.h"
#include "taoserror.h"
#include "taosmsg.h"
#include "tscompression.h"
S
slguan 已提交
24
#include "tname.h"
S
slguan 已提交
25
#include "tidpool.h"
S
slguan 已提交
26
#include "tglobal.h"
27 28 29
#include "tcompare.h"
#include "tdataformat.h"
#include "tgrant.h"
30
#include "hash.h"
31
#include "mnode.h"
J
jtao1735 已提交
32
#include "dnode.h"
S
Shengliang Guan 已提交
33 34 35 36 37 38 39 40
#include "mnodeDef.h"
#include "mnodeInt.h"
#include "mnodeAcct.h"
#include "mnodeDb.h"
#include "mnodeDnode.h"
#include "mnodeMnode.h"
#include "mnodeProfile.h"
#include "mnodeSdb.h"
41
#include "mnodeShow.h"
S
Shengliang Guan 已提交
42 43 44
#include "mnodeTable.h"
#include "mnodeUser.h"
#include "mnodeVgroup.h"
45 46 47
#include "mnodeWrite.h"
#include "mnodeRead.h"
#include "mnodePeer.h"
S
slguan 已提交
48

49 50
static void *  tsChildTableSdb;
static void *  tsSuperTableSdb;
S
slguan 已提交
51 52
static int32_t tsChildTableUpdateSize;
static int32_t tsSuperTableUpdateSize;
53 54 55 56 57 58 59 60 61 62
static void *  mnodeGetChildTable(char *tableId);
static void *  mnodeGetSuperTable(char *tableId);
static void *  mnodeGetSuperTableByUid(uint64_t uid);
static void    mnodeDropAllChildTablesInStable(SSuperTableObj *pStable);
static void    mnodeAddTableIntoStable(SSuperTableObj *pStable, SChildTableObj *pCtable);
static void    mnodeRemoveTableFromStable(SSuperTableObj *pStable, SChildTableObj *pCtable);

static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn);
static int32_t mnodeGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
63 64 65 66
static int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn);
static int32_t mnodeGetStreamMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
static int32_t mnodeRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, void *pConn);
 
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *mnodeMsg);
static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg);
static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg);
static void    mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg);

static int32_t mnodeProcessDropTableMsg(SMnodeMsg *mnodeMsg);
static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg);
static void    mnodeProcessDropSuperTableRsp(SRpcMsg *rpcMsg);
static int32_t mnodeProcessDropChildTableMsg(SMnodeMsg *pMsg);
static void    mnodeProcessDropChildTableRsp(SRpcMsg *rpcMsg);

static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *mnodeMsg);
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *mnodeMsg);
static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *mnodeMsg);

static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *mnodeMsg);
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg);
static int32_t mnodeGetChildTableMeta(SMnodeMsg *pMsg);
S
Shengliang Guan 已提交
85
static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg);
86 87 88 89 90

static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *mnodeMsg);
static void    mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg);

static int32_t mnodeFindSuperTableColumnIndex(SSuperTableObj *pStable, char *colName);
S
slguan 已提交
91

S
Shengliang Guan 已提交
92
static void mnodeDestroyChildTable(SChildTableObj *pTable) {
93
  tfree(pTable->info.tableId);
S
slguan 已提交
94 95 96 97 98
  tfree(pTable->schema);
  tfree(pTable->sql);
  tfree(pTable);
}

99
static int32_t mnodeChildTableActionDestroy(SSdbOper *pOper) {
S
Shengliang Guan 已提交
100
  mnodeDestroyChildTable(pOper->pObj);
S
slguan 已提交
101 102 103
  return TSDB_CODE_SUCCESS;
}

104
static int32_t mnodeChildTableActionInsert(SSdbOper *pOper) {
S
slguan 已提交
105 106
  SChildTableObj *pTable = pOper->pObj;

107
  SVgObj *pVgroup = mnodeGetVgroup(pTable->vgId);
S
slguan 已提交
108
  if (pVgroup == NULL) {
S
slguan 已提交
109
    mError("ctable:%s, not in vgId:%d", pTable->info.tableId, pTable->vgId);
S
slguan 已提交
110 111
    return TSDB_CODE_INVALID_VGROUP_ID;
  }
112
  mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
113

114
  SDbObj *pDb = mnodeGetDb(pVgroup->dbName);
S
slguan 已提交
115
  if (pDb == NULL) {
S
slguan 已提交
116
    mError("ctable:%s, vgId:%d not in db:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName);
S
slguan 已提交
117 118
    return TSDB_CODE_INVALID_DB;
  }
119
  mnodeDecDbRef(pDb);
S
slguan 已提交
120

121
  SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
S
slguan 已提交
122
  if (pAcct == NULL) {
S
slguan 已提交
123
    mError("ctable:%s, acct:%s not exists", pTable->info.tableId, pDb->acct);
S
slguan 已提交
124 125
    return TSDB_CODE_INVALID_ACCT;
  }
126
  mnodeDecAcctRef(pAcct);
S
slguan 已提交
127 128

  if (pTable->info.type == TSDB_CHILD_TABLE) {
129
    // add ref
130 131
    pTable->superTable = mnodeGetSuperTableByUid(pTable->suid);
    mnodeAddTableIntoStable(pTable->superTable, pTable);
S
slguan 已提交
132 133 134 135 136 137
    grantAdd(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1);
    pAcct->acctInfo.numOfTimeSeries += (pTable->superTable->numOfColumns - 1);
  } else {
    grantAdd(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1);
    pAcct->acctInfo.numOfTimeSeries += (pTable->numOfColumns - 1);
  }
S
slguan 已提交
138

139 140
  mnodeAddTableIntoDb(pDb);
  mnodeAddTableIntoVgroup(pVgroup, pTable);
S
slguan 已提交
141 142 143 144

  return TSDB_CODE_SUCCESS;
}

145
static int32_t mnodeChildTableActionDelete(SSdbOper *pOper) {
S
slguan 已提交
146 147 148 149 150
  SChildTableObj *pTable = pOper->pObj;
  if (pTable->vgId == 0) {
    return TSDB_CODE_INVALID_VGROUP_ID;
  }

151
  SVgObj *pVgroup = mnodeGetVgroup(pTable->vgId);
S
slguan 已提交
152 153 154
  if (pVgroup == NULL) {
    return TSDB_CODE_INVALID_VGROUP_ID;
  }
155
  mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
156

157
  SDbObj *pDb = mnodeGetDb(pVgroup->dbName);
S
slguan 已提交
158
  if (pDb == NULL) {
S
slguan 已提交
159
    mError("ctable:%s, vgId:%d not in DB:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName);
S
slguan 已提交
160 161
    return TSDB_CODE_INVALID_DB;
  }
162
  mnodeDecDbRef(pDb);
S
slguan 已提交
163

164
  SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
S
slguan 已提交
165
  if (pAcct == NULL) {
S
slguan 已提交
166
    mError("ctable:%s, acct:%s not exists", pTable->info.tableId, pDb->acct);
S
slguan 已提交
167 168
    return TSDB_CODE_INVALID_ACCT;
  }
169
  mnodeDecAcctRef(pAcct);
S
slguan 已提交
170 171 172 173

  if (pTable->info.type == TSDB_CHILD_TABLE) {
    grantRestore(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1);
    pAcct->acctInfo.numOfTimeSeries -= (pTable->superTable->numOfColumns - 1);
174 175
    mnodeRemoveTableFromStable(pTable->superTable, pTable);
    mnodeDecTableRef(pTable->superTable);
S
slguan 已提交
176 177 178 179
  } else {
    grantRestore(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1);
    pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1);
  }
180 181
  mnodeRemoveTableFromDb(pDb);
  mnodeRemoveTableFromVgroup(pVgroup, pTable);
S
slguan 已提交
182 183 184 185
 
  return TSDB_CODE_SUCCESS;
}

186
static int32_t mnodeChildTableActionUpdate(SSdbOper *pOper) {
S
slguan 已提交
187
  SChildTableObj *pNew = pOper->pObj;
188
  SChildTableObj *pTable = mnodeGetChildTable(pNew->info.tableId);
S
slguan 已提交
189
  if (pTable != pNew) {
190
    void *oldTableId = pTable->info.tableId;
S
slguan 已提交
191 192 193 194 195 196 197 198
    void *oldSql = pTable->sql;
    void *oldSchema = pTable->schema;
    memcpy(pTable, pNew, pOper->rowSize);
    pTable->sql = pNew->sql;
    pTable->schema = pNew->schema;
    free(pNew);
    free(oldSql);
    free(oldSchema);
199
    free(oldTableId);
S
slguan 已提交
200
  }
201
  mnodeDecTableRef(pTable);
S
slguan 已提交
202

S
slguan 已提交
203 204 205
  return TSDB_CODE_SUCCESS;
}

206
static int32_t mnodeChildTableActionEncode(SSdbOper *pOper) {
S
slguan 已提交
207 208 209
  SChildTableObj *pTable = pOper->pObj;
  assert(pTable != NULL && pOper->rowData != NULL);

210 211 212 213 214 215 216 217 218 219 220
  int32_t len = strlen(pTable->info.tableId);
  if (len > TSDB_TABLE_ID_LEN) return TSDB_CODE_INVALID_TABLE_ID;

  memcpy(pOper->rowData, pTable->info.tableId, len);
  memset(pOper->rowData + len, 0, 1);
  len++;

  memcpy(pOper->rowData + len, (char*)pTable + sizeof(char *), tsChildTableUpdateSize);
  len += tsChildTableUpdateSize;

  if (pTable->info.type != TSDB_CHILD_TABLE) {
S
slguan 已提交
221
    int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema);
222 223 224 225 226 227
    memcpy(pOper->rowData + len, pTable->schema, schemaSize);
    len += schemaSize;

    if (pTable->sqlLen != 0) {
      memcpy(pOper->rowData + len, pTable->sql, pTable->sqlLen);
      len += pTable->sqlLen;
S
slguan 已提交
228 229 230
    }
  }

231 232
  pOper->rowSize = len;

S
slguan 已提交
233 234 235
  return TSDB_CODE_SUCCESS;
}

236
static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) {
S
slguan 已提交
237 238
  assert(pOper->rowData != NULL);
  SChildTableObj *pTable = calloc(1, sizeof(SChildTableObj));
239
  if (pTable == NULL) return TSDB_CODE_SERV_OUT_OF_MEMORY;
S
slguan 已提交
240

241
  int32_t len = strlen(pOper->rowData);
S
Shuduo Sang 已提交
242 243 244 245
  if (len > TSDB_TABLE_ID_LEN) {
    free(pTable);
    return TSDB_CODE_INVALID_TABLE_ID;
  }
246 247 248 249 250
  pTable->info.tableId = strdup(pOper->rowData);
  len++;

  memcpy((char*)pTable + sizeof(char *), pOper->rowData + len, tsChildTableUpdateSize);
  len += tsChildTableUpdateSize;
S
slguan 已提交
251 252 253 254 255

  if (pTable->info.type != TSDB_CHILD_TABLE) {
    int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema);
    pTable->schema = (SSchema *)malloc(schemaSize);
    if (pTable->schema == NULL) {
S
Shengliang Guan 已提交
256
      mnodeDestroyChildTable(pTable);
257
      return TSDB_CODE_INVALID_TABLE_TYPE;
S
slguan 已提交
258
    }
259 260 261 262 263 264
    memcpy(pTable->schema, pOper->rowData + len, schemaSize);
    len += schemaSize;

    if (pTable->sqlLen != 0) {
      pTable->sql = malloc(pTable->sqlLen);
      if (pTable->sql == NULL) {
S
Shengliang Guan 已提交
265
        mnodeDestroyChildTable(pTable);
266 267 268
        return TSDB_CODE_SERV_OUT_OF_MEMORY;
      }
      memcpy(pTable->sql, pOper->rowData + len, pTable->sqlLen);
S
slguan 已提交
269 270 271 272 273 274 275
    }
  }

  pOper->pObj = pTable;
  return TSDB_CODE_SUCCESS;
}

276
static int32_t mnodeChildTableActionRestored() {
S
Shengliang Guan 已提交
277
  void *pIter = NULL;
S
slguan 已提交
278 279 280
  SChildTableObj *pTable = NULL;

  while (1) {
281
    pIter = mnodeGetNextChildTable(pIter, &pTable);
S
slguan 已提交
282 283
    if (pTable == NULL) break;

284
    SDbObj *pDb = mnodeGetDbByTableId(pTable->info.tableId);
S
slguan 已提交
285 286
    if (pDb == NULL) {
      mError("ctable:%s, failed to get db, discard it", pTable->info.tableId);
S
Shengliang Guan 已提交
287
      SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb};
S
slguan 已提交
288
      sdbDeleteRow(&desc);
289
      mnodeDecTableRef(pTable);
S
slguan 已提交
290 291
      continue;
    }
292
    mnodeDecDbRef(pDb);
S
slguan 已提交
293

294
    SVgObj *pVgroup = mnodeGetVgroup(pTable->vgId);
S
slguan 已提交
295
    if (pVgroup == NULL) {
S
slguan 已提交
296
      mError("ctable:%s, failed to get vgId:%d sid:%d, discard it", pTable->info.tableId, pTable->vgId, pTable->sid);
S
slguan 已提交
297
      pTable->vgId = 0;
S
Shengliang Guan 已提交
298
      SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb};
S
slguan 已提交
299
      sdbDeleteRow(&desc);
300
      mnodeDecTableRef(pTable);
S
slguan 已提交
301 302
      continue;
    }
303
    mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
304 305

    if (strcmp(pVgroup->dbName, pDb->name) != 0) {
S
slguan 已提交
306
      mError("ctable:%s, db:%s not match with vgId:%d db:%s sid:%d, discard it",
S
slguan 已提交
307 308
             pTable->info.tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->sid);
      pTable->vgId = 0;
S
Shengliang Guan 已提交
309
      SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb};
S
slguan 已提交
310
      sdbDeleteRow(&desc);
311
      mnodeDecTableRef(pTable);
S
slguan 已提交
312 313 314 315
      continue;
    }

    if (pVgroup->tableList == NULL) {
S
slguan 已提交
316
      mError("ctable:%s, vgId:%d tableList is null", pTable->info.tableId, pTable->vgId);
S
slguan 已提交
317
      pTable->vgId = 0;
S
Shengliang Guan 已提交
318
      SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb};
S
slguan 已提交
319
      sdbDeleteRow(&desc);
320
      mnodeDecTableRef(pTable);
S
slguan 已提交
321 322 323 324
      continue;
    }

    if (pTable->info.type == TSDB_CHILD_TABLE) {
325
      SSuperTableObj *pSuperTable = mnodeGetSuperTableByUid(pTable->suid);
S
slguan 已提交
326
      if (pSuperTable == NULL) {
327
        mError("ctable:%s, stable:%" PRIu64 " not exist", pTable->info.tableId, pTable->suid);
S
slguan 已提交
328
        pTable->vgId = 0;
S
Shengliang Guan 已提交
329
        SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb};
S
slguan 已提交
330
        sdbDeleteRow(&desc);
331
        mnodeDecTableRef(pTable);
S
slguan 已提交
332 333
        continue;
      }
334
      mnodeDecTableRef(pSuperTable);
S
slguan 已提交
335
    }
S
Shengliang Guan 已提交
336

337
    mnodeDecTableRef(pTable);
S
slguan 已提交
338 339
  }

S
Shengliang Guan 已提交
340 341
  sdbFreeIter(pIter);

S
slguan 已提交
342 343 344
  return 0;
}

345
static int32_t mnodeInitChildTables() {
S
slguan 已提交
346
  SChildTableObj tObj;
347
  tsChildTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj.info.type;
S
slguan 已提交
348 349 350 351

  SSdbTableDesc tableDesc = {
    .tableId      = SDB_TABLE_CTABLE,
    .tableName    = "ctables",
S
Shengliang Guan 已提交
352
    .hashSessions = TSDB_DEFAULT_CTABLES_HASH_SIZE,
353
    .maxRowSize   = sizeof(SChildTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_ID_LEN + TSDB_CQ_SQL_SIZE,
S
slguan 已提交
354
    .refCountPos  = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
355
    .keyType      = SDB_KEY_VAR_STRING,
356 357 358 359 360 361 362
    .insertFp     = mnodeChildTableActionInsert,
    .deleteFp     = mnodeChildTableActionDelete,
    .updateFp     = mnodeChildTableActionUpdate,
    .encodeFp     = mnodeChildTableActionEncode,
    .decodeFp     = mnodeChildTableActionDecode,
    .destroyFp    = mnodeChildTableActionDestroy,
    .restoredFp   = mnodeChildTableActionRestored
S
slguan 已提交
363 364 365 366 367 368 369 370
  };

  tsChildTableSdb = sdbOpenTable(&tableDesc);
  if (tsChildTableSdb == NULL) {
    mError("failed to init child table data");
    return -1;
  }

S
slguan 已提交
371
  mTrace("table:ctables is created");
S
slguan 已提交
372 373 374
  return 0;
}

375
static void mnodeCleanupChildTables() {
S
slguan 已提交
376 377 378
  sdbCloseTable(tsChildTableSdb);
}

379
static void mnodeAddTableIntoStable(SSuperTableObj *pStable, SChildTableObj *pCtable) {
380
  pStable->numOfTables++;
S
slguan 已提交
381

382 383
  if (pStable->vgHash == NULL) {
    pStable->vgHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false);
S
slguan 已提交
384 385
  }

386 387 388
  if (pStable->vgHash != NULL) {
    taosHashPut(pStable->vgHash, (char *)&pCtable->vgId, sizeof(pCtable->vgId), &pCtable->vgId, sizeof(pCtable->vgId));
  }
S
slguan 已提交
389 390
}

391
static void mnodeRemoveTableFromStable(SSuperTableObj *pStable, SChildTableObj *pCtable) {
S
slguan 已提交
392
  pStable->numOfTables--;
393 394 395

  if (pStable->vgHash == NULL) return;

396
  SVgObj *pVgroup = mnodeGetVgroup(pCtable->vgId);
397
  if (pVgroup == NULL) {
398 399
    taosHashRemove(pStable->vgHash, (char *)&pCtable->vgId, sizeof(pCtable->vgId));
  }
400
  mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
401 402
}

S
Shengliang Guan 已提交
403
static void mnodeDestroySuperTable(SSuperTableObj *pStable) {
404 405 406 407
  if (pStable->vgHash != NULL) {
    taosHashCleanup(pStable->vgHash);
    pStable->vgHash = NULL;
  }
408
  tfree(pStable->info.tableId);
S
slguan 已提交
409 410 411 412
  tfree(pStable->schema);
  tfree(pStable);
}

413
static int32_t mnodeSuperTableActionDestroy(SSdbOper *pOper) {
S
Shengliang Guan 已提交
414
  mnodeDestroySuperTable(pOper->pObj);
S
slguan 已提交
415 416 417
  return TSDB_CODE_SUCCESS;
}

418
static int32_t mnodeSuperTableActionInsert(SSdbOper *pOper) {
S
slguan 已提交
419
  SSuperTableObj *pStable = pOper->pObj;
420
  SDbObj *pDb = mnodeGetDbByTableId(pStable->info.tableId);
S
slguan 已提交
421
  if (pDb != NULL) {
422
    mnodeAddSuperTableIntoDb(pDb);
S
slguan 已提交
423
  }
424
  mnodeDecDbRef(pDb);
S
slguan 已提交
425 426 427 428

  return TSDB_CODE_SUCCESS;
}

429
static int32_t mnodeSuperTableActionDelete(SSdbOper *pOper) {
S
slguan 已提交
430
  SSuperTableObj *pStable = pOper->pObj;
431
  SDbObj *pDb = mnodeGetDbByTableId(pStable->info.tableId);
S
slguan 已提交
432
  if (pDb != NULL) {
433 434
    mnodeRemoveSuperTableFromDb(pDb);
    mnodeDropAllChildTablesInStable((SSuperTableObj *)pStable);
S
slguan 已提交
435
  }
436
  mnodeDecDbRef(pDb);
S
slguan 已提交
437

S
slguan 已提交
438 439 440
  return TSDB_CODE_SUCCESS;
}

441
static int32_t mnodeSuperTableActionUpdate(SSdbOper *pOper) {
S
slguan 已提交
442
  SSuperTableObj *pNew = pOper->pObj;
443
  SSuperTableObj *pTable = mnodeGetSuperTable(pNew->info.tableId);
S
slguan 已提交
444
  if (pTable != pNew) {
445
    void *oldTableId = pTable->info.tableId;
S
slguan 已提交
446 447 448
    void *oldSchema = pTable->schema;
    memcpy(pTable, pNew, pOper->rowSize);
    pTable->schema = pNew->schema;
449
    free(pNew->vgHash);
450
    free(pNew);
451
    free(oldTableId);
S
slguan 已提交
452 453
    free(oldSchema);
  }
454
  mnodeDecTableRef(pTable);
S
slguan 已提交
455 456 457
  return TSDB_CODE_SUCCESS;
}

458
static int32_t mnodeSuperTableActionEncode(SSdbOper *pOper) {
S
slguan 已提交
459 460 461
  SSuperTableObj *pStable = pOper->pObj;
  assert(pOper->pObj != NULL && pOper->rowData != NULL);

462 463
  int32_t len = strlen(pStable->info.tableId);
  if (len > TSDB_TABLE_ID_LEN) len = TSDB_CODE_INVALID_TABLE_ID;
S
slguan 已提交
464

465 466 467 468 469 470 471 472 473 474
  memcpy(pOper->rowData, pStable->info.tableId, len);
  memset(pOper->rowData + len, 0, 1);
  len++;

  memcpy(pOper->rowData + len, (char*)pStable + sizeof(char *), tsSuperTableUpdateSize);
  len += tsSuperTableUpdateSize;

  int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags);
  memcpy(pOper->rowData + len, pStable->schema, schemaSize);
  len += schemaSize;
S
slguan 已提交
475

476
  pOper->rowSize = len;
S
slguan 已提交
477 478 479 480

  return TSDB_CODE_SUCCESS;
}

481
static int32_t mnodeSuperTableActionDecode(SSdbOper *pOper) {
S
slguan 已提交
482 483 484 485
  assert(pOper->rowData != NULL);
  SSuperTableObj *pStable = (SSuperTableObj *) calloc(1, sizeof(SSuperTableObj));
  if (pStable == NULL) return TSDB_CODE_SERV_OUT_OF_MEMORY;

486 487 488 489 490 491 492
  int32_t len = strlen(pOper->rowData);
  if (len > TSDB_TABLE_ID_LEN) return TSDB_CODE_INVALID_TABLE_ID;
  pStable->info.tableId = strdup(pOper->rowData);
  len++;

  memcpy((char*)pStable + sizeof(char *), pOper->rowData + len, tsSuperTableUpdateSize);
  len += tsSuperTableUpdateSize;
S
slguan 已提交
493 494 495 496

  int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags);
  pStable->schema = malloc(schemaSize);
  if (pStable->schema == NULL) {
S
Shengliang Guan 已提交
497
    mnodeDestroySuperTable(pStable);
498
    return TSDB_CODE_NOT_SUPER_TABLE;
S
slguan 已提交
499 500
  }

501 502
  memcpy(pStable->schema, pOper->rowData + len, schemaSize);
  
S
slguan 已提交
503 504 505 506 507
  pOper->pObj = pStable;

  return TSDB_CODE_SUCCESS;
}

508
static int32_t mnodeSuperTableActionRestored() {
S
slguan 已提交
509 510 511
  return 0;
}

512
static int32_t mnodeInitSuperTables() {
S
slguan 已提交
513
  SSuperTableObj tObj;
514
  tsSuperTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj.info.type;
S
slguan 已提交
515 516

  SSdbTableDesc tableDesc = {
S
slguan 已提交
517
    .tableId      = SDB_TABLE_STABLE,
S
slguan 已提交
518
    .tableName    = "stables",
S
Shengliang Guan 已提交
519
    .hashSessions = TSDB_DEFAULT_STABLES_HASH_SIZE,
520
    .maxRowSize   = sizeof(SSuperTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_ID_LEN,
S
slguan 已提交
521
    .refCountPos  = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
522
    .keyType      = SDB_KEY_VAR_STRING,
523 524 525 526 527 528 529
    .insertFp     = mnodeSuperTableActionInsert,
    .deleteFp     = mnodeSuperTableActionDelete,
    .updateFp     = mnodeSuperTableActionUpdate,
    .encodeFp     = mnodeSuperTableActionEncode,
    .decodeFp     = mnodeSuperTableActionDecode,
    .destroyFp    = mnodeSuperTableActionDestroy,
    .restoredFp   = mnodeSuperTableActionRestored
S
slguan 已提交
530 531 532 533 534 535 536 537
  };

  tsSuperTableSdb = sdbOpenTable(&tableDesc);
  if (tsSuperTableSdb == NULL) {
    mError("failed to init stables data");
    return -1;
  }

S
slguan 已提交
538
  mTrace("table:stables is created");
S
slguan 已提交
539 540 541
  return 0;
}

542
static void mnodeCleanupSuperTables() {
S
slguan 已提交
543 544 545
  sdbCloseTable(tsSuperTableSdb);
}

546 547
int32_t mnodeInitTables() {
  int32_t code = mnodeInitSuperTables();
S
slguan 已提交
548 549
  if (code != TSDB_CODE_SUCCESS) {
    return code;
H
hzcheng 已提交
550 551
  }

552
  code = mnodeInitChildTables();
S
slguan 已提交
553 554 555
  if (code != TSDB_CODE_SUCCESS) {
    return code;
  }
H
hzcheng 已提交
556

557 558 559 560 561 562
  mnodeAddReadMsgHandle(TSDB_MSG_TYPE_CM_TABLES_META, mnodeProcessMultiTableMetaMsg);
  mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_CREATE_TABLE, mnodeProcessCreateTableMsg);
  mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_DROP_TABLE, mnodeProcessDropTableMsg);
  mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_ALTER_TABLE, mnodeProcessAlterTableMsg);
  mnodeAddReadMsgHandle(TSDB_MSG_TYPE_CM_TABLE_META, mnodeProcessTableMetaMsg);
  mnodeAddReadMsgHandle(TSDB_MSG_TYPE_CM_STABLE_VGROUP, mnodeProcessSuperTableVgroupMsg);
S
slguan 已提交
563
  
564 565 566 567
  mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_CREATE_TABLE_RSP, mnodeProcessCreateChildTableRsp);
  mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_DROP_TABLE_RSP, mnodeProcessDropChildTableRsp);
  mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_DROP_STABLE_RSP, mnodeProcessDropSuperTableRsp);
  mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_ALTER_TABLE_RSP, mnodeProcessAlterTableRsp);
S
slguan 已提交
568

569
  mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_CONFIG_TABLE, mnodeProcessTableCfgMsg);
S
slguan 已提交
570

571 572 573 574
  mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_TABLE, mnodeGetShowTableMeta);
  mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_TABLE, mnodeRetrieveShowTables);
  mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_METRIC, mnodeGetShowSuperTableMeta);
  mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_METRIC, mnodeRetrieveShowSuperTables);
575 576 577
  mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_STREAMS, mnodeGetStreamMeta);
  mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_STREAMS, mnodeRetrieveStreams);

S
slguan 已提交
578
  return TSDB_CODE_SUCCESS;
H
hzcheng 已提交
579 580
}

581
static void *mnodeGetChildTable(char *tableId) {
S
slguan 已提交
582 583 584
  return sdbGetRow(tsChildTableSdb, tableId);
}

585
static void *mnodeGetSuperTable(char *tableId) {
S
slguan 已提交
586 587 588
  return sdbGetRow(tsSuperTableSdb, tableId);
}

589
static void *mnodeGetSuperTableByUid(uint64_t uid) {
590
  SSuperTableObj *pStable = NULL;
S
Shengliang Guan 已提交
591
  void *pIter = NULL;
592 593

  while (1) {
594
    pIter = mnodeGetNextSuperTable(pIter, &pStable);
595 596
    if (pStable == NULL) break;
    if (pStable->uid == uid) {
597
      sdbFreeIter(pIter);
598 599
      return pStable;
    }
600
    mnodeDecTableRef(pStable);
601 602
  }

S
Shengliang Guan 已提交
603 604
  sdbFreeIter(pIter);

605 606 607
  return NULL;
}

608 609
void *mnodeGetTable(char *tableId) {
  void *pTable = mnodeGetSuperTable(tableId);
610 611
  if (pTable != NULL) {
    return pTable;
H
hzcheng 已提交
612 613
  }

614
  pTable = mnodeGetChildTable(tableId);
615 616
  if (pTable != NULL) {
    return pTable;
S
#1177  
slguan 已提交
617
  }
H
hzcheng 已提交
618

S
slguan 已提交
619
  return NULL;
S
#1177  
slguan 已提交
620
}
H
hzcheng 已提交
621

622
void *mnodeGetNextChildTable(void *pIter, SChildTableObj **pTable) {
S
Shengliang Guan 已提交
623
  return sdbFetchRow(tsChildTableSdb, pIter, (void **)pTable);
624 625
}

626
void *mnodeGetNextSuperTable(void *pIter, SSuperTableObj **pTable) {
S
Shengliang Guan 已提交
627
  return sdbFetchRow(tsSuperTableSdb, pIter, (void **)pTable);
628 629
}

630
void mnodeIncTableRef(void *p1) {
S
slguan 已提交
631
  STableObj *pTable = (STableObj *)p1;
S
slguan 已提交
632 633 634 635 636 637 638
  if (pTable->type == TSDB_SUPER_TABLE) {
    sdbIncRef(tsSuperTableSdb, pTable);
  } else {
    sdbIncRef(tsChildTableSdb, pTable);
  }
}

639
void mnodeDecTableRef(void *p1) {
S
slguan 已提交
640 641
  if (p1 == NULL) return;

S
slguan 已提交
642
  STableObj *pTable = (STableObj *)p1;
S
slguan 已提交
643 644 645 646 647 648 649
  if (pTable->type == TSDB_SUPER_TABLE) {
    sdbDecRef(tsSuperTableSdb, pTable);
  } else {
    sdbDecRef(tsChildTableSdb, pTable);
  }
}

650 651 652
void mnodeCleanupTables() {
  mnodeCleanupChildTables();
  mnodeCleanupSuperTables();
S
#1177  
slguan 已提交
653
}
H
hzcheng 已提交
654

655
// todo move to name.h, add length of table name
S
Shengliang Guan 已提交
656
static void mnodeExtractTableName(char* tableId, char* name) {
657 658 659 660 661
  int pos = -1;
  int num = 0;
  for (pos = 0; tableId[pos] != 0; ++pos) {
    if (tableId[pos] == '.') num++;
    if (num == 2) break;
S
slguan 已提交
662 663
  }

664 665
  if (num == 2) {
    strcpy(name, tableId + pos + 1);
S
slguan 已提交
666
  }
H
hzcheng 已提交
667 668
}

669
static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
670
  SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
S
slguan 已提交
671
  
672
  if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pCreate->db);
S
slguan 已提交
673 674
  if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
    mError("table:%s, failed to create, db not selected", pCreate->tableId);
675
    return TSDB_CODE_DB_NOT_SELECTED;
S
slguan 已提交
676 677
  }

678
  if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pCreate->tableId);
679
  if (pMsg->pTable != NULL && pMsg->retry == 0) {
S
slguan 已提交
680 681
    if (pCreate->getMeta) {
      mTrace("table:%s, continue to get meta", pCreate->tableId);
682
      return mnodeGetChildTableMeta(pMsg);
S
slguan 已提交
683
    } else if (pCreate->igExists) {
S
slguan 已提交
684
      mTrace("table:%s, is already exist", pCreate->tableId);
685
      return TSDB_CODE_SUCCESS;
S
slguan 已提交
686 687
    } else {
      mError("table:%s, failed to create, table already exist", pCreate->tableId);
688
      return TSDB_CODE_TABLE_ALREADY_EXIST;
S
slguan 已提交
689
    }
S
slguan 已提交
690 691
  }

692
  if (pCreate->numOfTags != 0) {
S
Shengliang Guan 已提交
693
    mTrace("table:%s, create msg is received from thandle:%p", pCreate->tableId, pMsg->rpcMsg.handle);
694
    return mnodeProcessCreateSuperTableMsg(pMsg);
695
  } else {
S
Shengliang Guan 已提交
696
    mTrace("table:%s, create msg is received from thandle:%p", pCreate->tableId, pMsg->rpcMsg.handle);
697
    return mnodeProcessCreateChildTableMsg(pMsg);
S
slguan 已提交
698 699 700
  }
}

701
static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
702
  SCMDropTableMsg *pDrop = pMsg->rpcMsg.pCont;
703
  if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(pDrop->tableId);
S
slguan 已提交
704
  if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
S
slguan 已提交
705
    mError("table:%s, failed to drop table, db not selected", pDrop->tableId);
706
    return TSDB_CODE_DB_NOT_SELECTED;
S
slguan 已提交
707 708
  }

709
  if (mnodeCheckIsMonitorDB(pMsg->pDb->name, tsMonitorDbName)) {
710
    mError("table:%s, failed to drop table, in monitor database", pDrop->tableId);
711
    return TSDB_CODE_MONITOR_DB_FORBIDDEN;
712 713
  }

714
  if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pDrop->tableId);
S
slguan 已提交
715
  if (pMsg->pTable == NULL) {
S
slguan 已提交
716 717
    if (pDrop->igNotExists) {
      mTrace("table:%s, table is not exist, think drop success", pDrop->tableId);
718
      return TSDB_CODE_SUCCESS;
S
slguan 已提交
719 720
    } else {
      mError("table:%s, failed to drop table, table not exist", pDrop->tableId);
721
      return TSDB_CODE_INVALID_TABLE;
S
slguan 已提交
722 723 724
    }
  }

S
slguan 已提交
725
  if (pMsg->pTable->type == TSDB_SUPER_TABLE) {
guanshengliang's avatar
guanshengliang 已提交
726
    mPrint("table:%s, start to drop stable", pDrop->tableId);
727
    return mnodeProcessDropSuperTableMsg(pMsg);
S
slguan 已提交
728
  } else {
guanshengliang's avatar
guanshengliang 已提交
729
    mPrint("table:%s, start to drop ctable", pDrop->tableId);
730
    return mnodeProcessDropChildTableMsg(pMsg);
S
slguan 已提交
731 732 733
  }
}

734
static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
735
  SCMTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
S
slguan 已提交
736
  pInfo->createFlag = htons(pInfo->createFlag);
S
Shengliang Guan 已提交
737
  mTrace("table:%s, table meta msg is received from thandle:%p, createFlag:%d", pInfo->tableId, pMsg->rpcMsg.handle, pInfo->createFlag);
S
slguan 已提交
738

739
  if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(pInfo->tableId);
S
slguan 已提交
740
  if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
S
slguan 已提交
741
    mError("table:%s, failed to get table meta, db not selected", pInfo->tableId);
742
    return TSDB_CODE_DB_NOT_SELECTED;
S
slguan 已提交
743 744
  }

745
  if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pInfo->tableId);
S
slguan 已提交
746
  if (pMsg->pTable == NULL) {
S
slguan 已提交
747
    if (!pInfo->createFlag) {
S
slguan 已提交
748
      mError("table:%s, failed to get table meta, table not exist", pInfo->tableId);
749
      return TSDB_CODE_INVALID_TABLE;
S
slguan 已提交
750
    } else {
751
      mTrace("table:%s, failed to get table meta, start auto create table ", pInfo->tableId);
S
Shengliang Guan 已提交
752
      return mnodeAutoCreateChildTable(pMsg);
S
slguan 已提交
753
    }
S
slguan 已提交
754
  } else {
S
slguan 已提交
755
    if (pMsg->pTable->type != TSDB_SUPER_TABLE) {
756
      return mnodeGetChildTableMeta(pMsg);
S
slguan 已提交
757
    } else {
758
      return mnodeGetSuperTableMeta(pMsg);
S
slguan 已提交
759 760 761 762
    }
  }
}

763
static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
764
  SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
765
  SSuperTableObj *pStable = calloc(1, sizeof(SSuperTableObj));
S
slguan 已提交
766
  if (pStable == NULL) {
S
slguan 已提交
767
    mError("table:%s, failed to create, no enough memory", pCreate->tableId);
768
    return TSDB_CODE_SERV_OUT_OF_MEMORY;
S
slguan 已提交
769 770
  }

771
  pStable->info.tableId = strdup(pCreate->tableId);
S
slguan 已提交
772 773 774 775
  pStable->info.type    = TSDB_SUPER_TABLE;
  pStable->createdTime  = taosGetTimestampMs();
  pStable->uid          = (((uint64_t) pStable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul));
  pStable->sversion     = 0;
S
TD-355  
Shengliang Guan 已提交
776
  pStable->tversion     = 0;
S
slguan 已提交
777 778 779
  pStable->numOfColumns = htons(pCreate->numOfColumns);
  pStable->numOfTags    = htons(pCreate->numOfTags);

S
slguan 已提交
780
  int32_t numOfCols = pStable->numOfColumns + pStable->numOfTags;
S
slguan 已提交
781 782 783 784
  int32_t schemaSize = numOfCols * sizeof(SSchema);
  pStable->schema = (SSchema *)calloc(1, schemaSize);
  if (pStable->schema == NULL) {
    free(pStable);
S
slguan 已提交
785
    mError("table:%s, failed to create, no schema input", pCreate->tableId);
786
    return TSDB_CODE_INVALID_TABLE;
S
slguan 已提交
787 788 789 790 791 792 793 794
  }
  memcpy(pStable->schema, pCreate->schema, numOfCols * sizeof(SSchema));

  pStable->nextColId = 0;
  for (int32_t col = 0; col < numOfCols; col++) {
    SSchema *tschema = pStable->schema;
    tschema[col].colId = pStable->nextColId++;
    tschema[col].bytes = htons(tschema[col].bytes);
H
hjxilinx 已提交
795 796 797
    
    // todo 1. check the length of each column; 2. check the total length of all columns
    assert(tschema[col].type >= TSDB_DATA_TYPE_BOOL && tschema[col].type <= TSDB_DATA_TYPE_NCHAR);
S
slguan 已提交
798 799
  }

S
slguan 已提交
800
  SSdbOper oper = {
S
slguan 已提交
801
    .type = SDB_OPER_GLOBAL,
S
slguan 已提交
802 803 804 805 806 807 808
    .table = tsSuperTableSdb,
    .pObj = pStable,
    .rowSize = sizeof(SSuperTableObj) + schemaSize
  };

  int32_t code = sdbInsertRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
809
    mnodeDestroySuperTable(pStable);
S
slguan 已提交
810
    mError("table:%s, failed to create, sdb error", pCreate->tableId);
811
    return TSDB_CODE_SDB_ERROR;
S
slguan 已提交
812
  } else {
S
slguan 已提交
813
    mLPrint("table:%s, is created, tags:%d fields:%d", pStable->info.tableId, pStable->numOfTags, pStable->numOfColumns);
814
    return TSDB_CODE_SUCCESS;
S
slguan 已提交
815 816 817
  }
}

818
static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) {
S
slguan 已提交
819
  SSuperTableObj *pStable = (SSuperTableObj *)pMsg->pTable;
S
slguan 已提交
820
  if (pStable->numOfTables != 0) {
821 822 823
    SHashMutableIterator *pIter = taosHashCreateIter(pStable->vgHash);
    while (taosHashIterNext(pIter)) {
      int32_t *pVgId = taosHashIterGet(pIter);
824
      SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
guanshengliang's avatar
guanshengliang 已提交
825
      if (pVgroup == NULL) break;
826

S
slguan 已提交
827
      SMDDropSTableMsg *pDrop = rpcMallocCont(sizeof(SMDDropSTableMsg));
guanshengliang's avatar
guanshengliang 已提交
828
      pDrop->contLen = htonl(sizeof(SMDDropSTableMsg));
829
      pDrop->vgId = htonl(pVgroup->vgId);
S
slguan 已提交
830
      pDrop->uid = htobe64(pStable->uid);
S
Shengliang Guan 已提交
831
      mnodeExtractTableName(pStable->info.tableId, pDrop->tableId);
guanshengliang's avatar
guanshengliang 已提交
832
        
833
      mPrint("stable:%s, send drop stable msg to vgId:%d", pStable->info.tableId, pVgroup->vgId);
834
      SRpcIpSet ipSet = mnodeGetIpSetFromVgroup(pVgroup);
guanshengliang's avatar
guanshengliang 已提交
835 836
      SRpcMsg rpcMsg = {.pCont = pDrop, .contLen = sizeof(SMDDropSTableMsg), .msgType = TSDB_MSG_TYPE_MD_DROP_STABLE};
      dnodeSendMsgToDnode(&ipSet, &rpcMsg);
837
      mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
838
    }
839
    taosHashDestroyIter(pIter);
840

841
    mnodeDropAllChildTablesInStable(pStable);
guanshengliang's avatar
guanshengliang 已提交
842 843 844 845 846 847 848 849 850 851
  } 
  
  SSdbOper oper = {
    .type = SDB_OPER_GLOBAL,
    .table = tsSuperTableSdb,
    .pObj = pStable
  };
  
  int32_t code = sdbDeleteRow(&oper);
  mLPrint("stable:%s, is dropped from sdb, result:%s", pStable->info.tableId, tstrerror(code));
852
  return code;
S
slguan 已提交
853 854
}

855
static int32_t mnodeFindSuperTableTagIndex(SSuperTableObj *pStable, const char *tagName) {
guanshengliang's avatar
guanshengliang 已提交
856 857 858 859
  SSchema *schema = (SSchema *) pStable->schema;
  for (int32_t tag = 0; tag < pStable->numOfTags; tag++) {
    if (strcasecmp(schema[pStable->numOfColumns + tag].name, tagName) == 0) {
      return tag;
S
slguan 已提交
860 861 862 863 864 865
    }
  }

  return -1;
}

866
static int32_t mnodeAddSuperTableTag(SSuperTableObj *pStable, SSchema schema[], int32_t ntags) {
S
slguan 已提交
867
  if (pStable->numOfTags + ntags > TSDB_MAX_TAGS) {
S
slguan 已提交
868 869
    mError("stable:%s, add tag, too many tags", pStable->info.tableId);
    return TSDB_CODE_TOO_MANY_TAGS;
S
slguan 已提交
870 871
  }

S
slguan 已提交
872
  for (int32_t i = 0; i < ntags; i++) {
873
    if (mnodeFindSuperTableColumnIndex(pStable, schema[i].name) > 0) {
S
slguan 已提交
874 875 876 877
      mError("stable:%s, add tag, column:%s already exist", pStable->info.tableId, schema[i].name);
      return TSDB_CODE_TAG_ALREAY_EXIST;
    }

878
    if (mnodeFindSuperTableTagIndex(pStable, schema[i].name) > 0) {
S
slguan 已提交
879 880
      mError("stable:%s, add tag, tag:%s already exist", pStable->info.tableId, schema[i].name);
      return TSDB_CODE_FIELD_ALREAY_EXIST;
S
slguan 已提交
881 882 883 884 885 886
    }
  }

  int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns);
  pStable->schema = realloc(pStable->schema, schemaSize + sizeof(SSchema) * ntags);

S
slguan 已提交
887
  memcpy(pStable->schema + pStable->numOfColumns + pStable->numOfTags, schema, sizeof(SSchema) * ntags);
S
slguan 已提交
888

S
slguan 已提交
889
  SSchema *tschema = (SSchema *)(pStable->schema + pStable->numOfColumns + pStable->numOfTags);
S
slguan 已提交
890 891 892 893
  for (int32_t i = 0; i < ntags; i++) {
    tschema[i].colId = pStable->nextColId++;
  }

S
slguan 已提交
894
  pStable->numOfTags += ntags;
S
TD-355  
Shengliang Guan 已提交
895
  pStable->tversion++;
S
slguan 已提交
896

S
slguan 已提交
897
  SSdbOper oper = {
S
slguan 已提交
898
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
899
    .table = tsSuperTableSdb,
900
    .pObj = pStable
S
[TD-17]  
slguan 已提交
901
  };
S
slguan 已提交
902

S
[TD-17]  
slguan 已提交
903 904 905 906 907
  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
  }

S
slguan 已提交
908
  mPrint("stable %s, succeed to add tag %s", pStable->info.tableId, schema[0].name);
S
slguan 已提交
909 910 911
  return TSDB_CODE_SUCCESS;
}

912 913
static int32_t mnodeDropSuperTableTag(SSuperTableObj *pStable, char *tagName) {
  int32_t col = mnodeFindSuperTableTagIndex(pStable, tagName);
S
slguan 已提交
914 915 916
  if (col < 0) {
    mError("stable:%s, drop tag, tag:%s not exist", pStable->info.tableId, tagName);
    return TSDB_CODE_TAG_NOT_EXIST;
S
slguan 已提交
917
  }
S
slguan 已提交
918

S
slguan 已提交
919 920
  memmove(pStable->schema + pStable->numOfColumns + col, pStable->schema + pStable->numOfColumns + col + 1,
          sizeof(SSchema) * (pStable->numOfTags - col - 1));
S
slguan 已提交
921
  pStable->numOfTags--;
S
TD-355  
Shengliang Guan 已提交
922
  pStable->tversion++;
S
slguan 已提交
923

S
slguan 已提交
924
  SSdbOper oper = {
S
slguan 已提交
925
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
926
    .table = tsSuperTableSdb,
927
    .pObj = pStable
S
[TD-17]  
slguan 已提交
928
  };
S
slguan 已提交
929

S
[TD-17]  
slguan 已提交
930 931 932 933 934
  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
  }
  
S
slguan 已提交
935
  mPrint("stable %s, succeed to drop tag %s", pStable->info.tableId, tagName);
S
slguan 已提交
936 937 938
  return TSDB_CODE_SUCCESS;
}

939 940
static int32_t mnodeModifySuperTableTagName(SSuperTableObj *pStable, char *oldTagName, char *newTagName) {
  int32_t col = mnodeFindSuperTableTagIndex(pStable, oldTagName);
S
slguan 已提交
941
  if (col < 0) {
S
slguan 已提交
942 943
    mError("stable:%s, failed to modify table tag, oldName: %s, newName: %s", pStable->info.tableId, oldTagName, newTagName);
    return TSDB_CODE_TAG_NOT_EXIST;
S
slguan 已提交
944 945 946 947
  }

  // int32_t  rowSize = 0;
  uint32_t len = strlen(newTagName);
S
slguan 已提交
948 949 950
  if (len >= TSDB_COL_NAME_LEN) {
    return TSDB_CODE_COL_NAME_TOO_LONG;
  }
S
slguan 已提交
951

952
  if (mnodeFindSuperTableTagIndex(pStable, newTagName) >= 0) {
S
slguan 已提交
953
    return TSDB_CODE_TAG_ALREAY_EXIST;
S
slguan 已提交
954 955 956
  }

  // update
S
slguan 已提交
957
  SSchema *schema = (SSchema *) (pStable->schema + pStable->numOfColumns + col);
S
slguan 已提交
958 959
  strncpy(schema->name, newTagName, TSDB_COL_NAME_LEN);

S
slguan 已提交
960
  SSdbOper oper = {
S
slguan 已提交
961
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
962
    .table = tsSuperTableSdb,
963
    .pObj = pStable
S
[TD-17]  
slguan 已提交
964
  };
S
slguan 已提交
965

S
[TD-17]  
slguan 已提交
966 967 968
  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
S
slguan 已提交
969
  }
S
[TD-17]  
slguan 已提交
970
  
S
slguan 已提交
971
  mPrint("stable %s, succeed to modify tag %s to %s", pStable->info.tableId, oldTagName, newTagName);
S
slguan 已提交
972 973 974
  return TSDB_CODE_SUCCESS;
}

975
static int32_t mnodeFindSuperTableColumnIndex(SSuperTableObj *pStable, char *colName) {
S
slguan 已提交
976
  SSchema *schema = (SSchema *) pStable->schema;
S
slguan 已提交
977 978 979
  for (int32_t col = 0; col < pStable->numOfColumns; col++) {
    if (strcasecmp(schema[col].name, colName) == 0) {
      return col;
S
slguan 已提交
980 981 982 983 984 985
    }
  }

  return -1;
}

986
static int32_t mnodeAddSuperTableColumn(SDbObj *pDb, SSuperTableObj *pStable, SSchema schema[], int32_t ncols) {
S
slguan 已提交
987
  if (ncols <= 0) {
S
slguan 已提交
988
    mError("stable:%s, add column, ncols:%d <= 0", pStable->info.tableId);
S
slguan 已提交
989 990 991 992
    return TSDB_CODE_APP_ERROR;
  }

  for (int32_t i = 0; i < ncols; i++) {
993
    if (mnodeFindSuperTableColumnIndex(pStable, schema[i].name) > 0) {
S
slguan 已提交
994 995 996 997
      mError("stable:%s, add column, column:%s already exist", pStable->info.tableId, schema[i].name);
      return TSDB_CODE_FIELD_ALREAY_EXIST;
    }

998
    if (mnodeFindSuperTableTagIndex(pStable, schema[i].name) > 0) {
S
slguan 已提交
999 1000
      mError("stable:%s, add column, tag:%s already exist", pStable->info.tableId, schema[i].name);
      return TSDB_CODE_TAG_ALREAY_EXIST;
S
slguan 已提交
1001 1002 1003 1004 1005 1006
    }
  }

  int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns);
  pStable->schema = realloc(pStable->schema, schemaSize + sizeof(SSchema) * ncols);

S
slguan 已提交
1007 1008 1009
  memmove(pStable->schema + pStable->numOfColumns + ncols, pStable->schema + pStable->numOfColumns,
          sizeof(SSchema) * pStable->numOfTags);
  memcpy(pStable->schema + pStable->numOfColumns, schema, sizeof(SSchema) * ncols);
S
slguan 已提交
1010 1011 1012 1013 1014 1015 1016 1017 1018

  SSchema *tschema = (SSchema *) (pStable->schema + sizeof(SSchema) * pStable->numOfColumns);
  for (int32_t i = 0; i < ncols; i++) {
    tschema[i].colId = pStable->nextColId++;
  }

  pStable->numOfColumns += ncols;
  pStable->sversion++;

1019
  SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
S
[TD-17]  
slguan 已提交
1020 1021
  if (pAcct != NULL) {
    pAcct->acctInfo.numOfTimeSeries += (ncols * pStable->numOfTables);
1022
    mnodeDecAcctRef(pAcct);
S
[TD-17]  
slguan 已提交
1023
  }
S
slguan 已提交
1024

S
slguan 已提交
1025
  SSdbOper oper = {
S
slguan 已提交
1026
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
1027
    .table = tsSuperTableSdb,
1028
    .pObj = pStable
S
[TD-17]  
slguan 已提交
1029 1030 1031 1032 1033 1034 1035
  };

  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
  }
  
S
slguan 已提交
1036
  mPrint("stable %s, succeed to add column", pStable->info.tableId);
S
slguan 已提交
1037 1038 1039
  return TSDB_CODE_SUCCESS;
}

1040 1041
static int32_t mnodeDropSuperTableColumn(SDbObj *pDb, SSuperTableObj *pStable, char *colName) {
  int32_t col = mnodeFindSuperTableColumnIndex(pStable, colName);
S
slguan 已提交
1042 1043 1044
  if (col <= 0) {
    mError("stable:%s, drop column, column:%s not exist", pStable->info.tableId, colName);
    return TSDB_CODE_FIELD_NOT_EXIST;
S
slguan 已提交
1045 1046
  }

S
slguan 已提交
1047
  memmove(pStable->schema + col, pStable->schema + col + 1,
S
slguan 已提交
1048 1049 1050 1051 1052 1053 1054 1055
          sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags - col - 1));

  pStable->numOfColumns--;
  pStable->sversion++;

  int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns);
  pStable->schema = realloc(pStable->schema, schemaSize);

1056
  SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
S
[TD-17]  
slguan 已提交
1057 1058
  if (pAcct != NULL) {
    pAcct->acctInfo.numOfTimeSeries -= pStable->numOfTables;
1059
    mnodeDecAcctRef(pAcct);
S
[TD-17]  
slguan 已提交
1060
  }
S
slguan 已提交
1061

S
slguan 已提交
1062
  SSdbOper oper = {
S
slguan 已提交
1063
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
1064
    .table = tsSuperTableSdb,
1065
    .pObj = pStable
S
[TD-17]  
slguan 已提交
1066 1067 1068 1069 1070 1071 1072
  };

  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
  }
  
S
slguan 已提交
1073
  mPrint("stable %s, succeed to delete column", pStable->info.tableId);
S
slguan 已提交
1074 1075 1076
  return TSDB_CODE_SUCCESS;
}

S
slguan 已提交
1077
// show super tables
1078 1079
static int32_t mnodeGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
  SDbObj *pDb = mnodeGetDb(pShow->db);
S
[TD-17]  
slguan 已提交
1080
  if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED;
S
slguan 已提交
1081 1082 1083 1084

  int32_t cols = 0;
  SSchema *pSchema = pMeta->schema;

1085
  pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
S
slguan 已提交
1086 1087 1088 1089 1090 1091 1092
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "name");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
1093
  strcpy(pSchema[cols].name, "created_time");
S
slguan 已提交
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 2;
  pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
  strcpy(pSchema[cols].name, "columns");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 2;
  pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
  strcpy(pSchema[cols].name, "tags");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 4;
  pSchema[cols].type = TSDB_DATA_TYPE_INT;
  strcpy(pSchema[cols].name, "tables");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pMeta->numOfColumns = htons(cols);
  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];

  pShow->numOfRows = pDb->numOfSuperTables;
  pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];

1124
  mnodeDecDbRef(pDb);
S
slguan 已提交
1125 1126 1127
  return 0;
}

S
slguan 已提交
1128
// retrieve super tables
1129
int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
S
slguan 已提交
1130 1131 1132 1133 1134 1135 1136
  int32_t         numOfRows = 0;
  char *          pWrite;
  int32_t         cols = 0;
  SSuperTableObj *pTable = NULL;
  char            prefix[20] = {0};
  int32_t         prefixLen;

1137
  SDbObj *pDb = mnodeGetDb(pShow->db);
S
slguan 已提交
1138 1139 1140 1141 1142 1143 1144
  if (pDb == NULL) return 0;

  strcpy(prefix, pDb->name);
  strcat(prefix, TS_PATH_DELIMITER);
  prefixLen = strlen(prefix);

  SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;
1145
  char stableName[TSDB_TABLE_NAME_LEN + 1] = {0};
S
slguan 已提交
1146

S
slguan 已提交
1147
  while (numOfRows < rows) {    
1148
    pShow->pIter = mnodeGetNextSuperTable(pShow->pIter, &pTable);
S
slguan 已提交
1149 1150
    if (pTable == NULL) break;
    if (strncmp(pTable->info.tableId, prefix, prefixLen)) {
1151
      mnodeDecTableRef(pTable);
S
slguan 已提交
1152 1153 1154 1155
      continue;
    }

    memset(stableName, 0, tListLen(stableName));
S
Shengliang Guan 已提交
1156
    mnodeExtractTableName(pTable->info.tableId, stableName);
S
slguan 已提交
1157

S
Shengliang Guan 已提交
1158
    if (pShow->payloadLen > 0 && patternMatch(pShow->payload, stableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) {
1159
      mnodeDecTableRef(pTable);
S
slguan 已提交
1160
      continue;
S
Shengliang Guan 已提交
1161
    }
S
slguan 已提交
1162 1163 1164 1165

    cols = 0;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
H
hjxilinx 已提交
1166 1167 1168 1169 1170 1171
  
    int16_t len = strnlen(stableName, TSDB_DB_NAME_LEN);
    *(int16_t*) pWrite = len;
    pWrite += sizeof(int16_t); // todo refactor
  
    strncpy(pWrite, stableName, len);
S
slguan 已提交
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int64_t *)pWrite = pTable->createdTime;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int16_t *)pWrite = pTable->numOfColumns;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int16_t *)pWrite = pTable->numOfTags;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int32_t *)pWrite = pTable->numOfTables;
    cols++;

    numOfRows++;
1191
    mnodeDecTableRef(pTable);
S
slguan 已提交
1192 1193 1194
  }

  pShow->numOfReads += numOfRows;
1195
  mnodeDecDbRef(pDb);
S
slguan 已提交
1196

S
slguan 已提交
1197 1198 1199
  return numOfRows;
}

1200
void mnodeDropAllSuperTables(SDbObj *pDropDb) {
S
Shengliang Guan 已提交
1201
  void *  pIter= NULL;
S
slguan 已提交
1202 1203 1204 1205
  int32_t numOfTables = 0;
  int32_t dbNameLen = strlen(pDropDb->name);
  SSuperTableObj *pTable = NULL;

S
slguan 已提交
1206 1207
  mPrint("db:%s, all super tables will be dropped from sdb", pDropDb->name);

S
slguan 已提交
1208
  while (1) {
1209
    pIter = mnodeGetNextSuperTable(pIter, &pTable);
S
slguan 已提交
1210
    if (pTable == NULL) break;
S
slguan 已提交
1211 1212

    if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) {
S
slguan 已提交
1213
      SSdbOper oper = {
S
slguan 已提交
1214
        .type = SDB_OPER_LOCAL,
S
slguan 已提交
1215 1216 1217 1218 1219 1220
        .table = tsSuperTableSdb,
        .pObj = pTable,
      };
      sdbDeleteRow(&oper);
      numOfTables ++;
    }
S
slguan 已提交
1221

1222
    mnodeDecTableRef(pTable);
S
slguan 已提交
1223
  }
S
slguan 已提交
1224

S
Shengliang Guan 已提交
1225 1226
  sdbFreeIter(pIter);

S
slguan 已提交
1227
  mPrint("db:%s, all super tables:%d is dropped from sdb", pDropDb->name, numOfTables);
S
slguan 已提交
1228 1229
}

1230
static int32_t mnodeSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable) {
S
slguan 已提交
1231
  int32_t numOfCols = pTable->numOfColumns + pTable->numOfTags;
1232 1233
  assert(numOfCols <= TSDB_MAX_COLUMNS);
  
S
slguan 已提交
1234
  for (int32_t i = 0; i < numOfCols; ++i) {
1235
    strncpy(pSchema->name, pTable->schema[i].name, TSDB_COL_NAME_LEN);
S
slguan 已提交
1236 1237 1238 1239 1240 1241 1242 1243 1244
    pSchema->type  = pTable->schema[i].type;
    pSchema->bytes = htons(pTable->schema[i].bytes);
    pSchema->colId = htons(pTable->schema[i].colId);
    pSchema++;
  }

  return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema);
}

1245
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
S
slguan 已提交
1246
  SSuperTableObj *pTable = (SSuperTableObj *)pMsg->pTable;
1247
  STableMetaMsg *pMeta   = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
S
slguan 已提交
1248 1249
  pMeta->uid          = htobe64(pTable->uid);
  pMeta->sversion     = htons(pTable->sversion);
1250
  pMeta->tversion     = htons(pTable->tversion);
S
slguan 已提交
1251
  pMeta->precision    = pMsg->pDb->cfg.precision;
S
slguan 已提交
1252 1253 1254
  pMeta->numOfTags    = (uint8_t)pTable->numOfTags;
  pMeta->numOfColumns = htons((int16_t)pTable->numOfColumns);
  pMeta->tableType    = pTable->info.type;
1255
  pMeta->contLen      = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable);
H
hjxilinx 已提交
1256
  strncpy(pMeta->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN);
S
slguan 已提交
1257 1258 1259

  pMeta->contLen = htons(pMeta->contLen);

1260 1261 1262
  pMsg->rpcRsp.rsp = pMeta;
  pMsg->rpcRsp.len = pMeta->contLen;
  
S
Shengliang Guan 已提交
1263
  mTrace("stable:%s, uid:%" PRIu64 " table meta is retrieved", pTable->info.tableId, pTable->uid);
1264
  return TSDB_CODE_SUCCESS;
S
slguan 已提交
1265 1266
}

1267
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
1268
  SCMSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
H
hjxilinx 已提交
1269
  int32_t numOfTable = htonl(pInfo->numOfTables);
1270

S
scripts  
Shengliang Guan 已提交
1271
  // reserve space
S
Shengliang Guan 已提交
1272
  int32_t contLen = sizeof(SCMSTableVgroupRspMsg) + 32 * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo); 
1273 1274
  for (int32_t i = 0; i < numOfTable; ++i) {
    char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_ID_LEN) * i;
1275
    SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
1276 1277 1278
    if (pTable->vgHash != NULL) {
      contLen += (taosHashGetSize(pTable->vgHash) * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo));
    }
1279
    mnodeDecTableRef(pTable);
1280 1281
  }

S
scripts  
Shengliang Guan 已提交
1282
  SCMSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
S
slguan 已提交
1283
  if (pRsp == NULL) {
1284
    return TSDB_CODE_SERV_OUT_OF_MEMORY;
1285
  }
1286

H
hjxilinx 已提交
1287
  pRsp->numOfTables = htonl(numOfTable);
S
Shengliang Guan 已提交
1288
  char* msg = (char*) pRsp + sizeof(SCMSTableVgroupRspMsg);
1289 1290

  for (int32_t i = 0; i < numOfTable; ++i) {
S
Shengliang Guan 已提交
1291
    char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_ID_LEN) * i;
1292
    SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
S
scripts  
Shengliang Guan 已提交
1293
    SVgroupsInfo *pVgroupInfo = (SVgroupsInfo *)msg;
1294 1295 1296 1297 1298

    SHashMutableIterator *pIter = taosHashCreateIter(pTable->vgHash);
    int32_t vgSize = 0;
    while (taosHashIterNext(pIter)) {
      int32_t *pVgId = taosHashIterGet(pIter);
1299
      SVgObj * pVgroup = mnodeGetVgroup(*pVgId);
S
scripts  
Shengliang Guan 已提交
1300
      if (pVgroup == NULL) continue;
1301

S
scripts  
Shengliang Guan 已提交
1302 1303 1304
      pVgroupInfo->vgroups[vgSize].vgId = htonl(pVgroup->vgId);
      for (int32_t vn = 0; vn < pVgroup->numOfVnodes; ++vn) {
        SDnodeObj *pDnode = pVgroup->vnodeGid[vn].pDnode;
H
hjxilinx 已提交
1305
        if (pDnode == NULL) break;
1306

S
scripts  
Shengliang Guan 已提交
1307
        strncpy(pVgroupInfo->vgroups[vgSize].ipAddr[vn].fqdn, pDnode->dnodeFqdn, tListLen(pDnode->dnodeFqdn));
1308
        pVgroupInfo->vgroups[vgSize].ipAddr[vn].port = htons(pDnode->dnodePort);
1309

S
scripts  
Shengliang Guan 已提交
1310
        pVgroupInfo->vgroups[vgSize].numOfIps++;
H
hjxilinx 已提交
1311
      }
1312 1313

      vgSize++;
1314
      mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
1315
    }
1316

1317 1318
    taosHashDestroyIter(pIter);

S
scripts  
Shengliang Guan 已提交
1319
    pVgroupInfo->numOfVgroups = htonl(vgSize);
1320

H
hjxilinx 已提交
1321
    // one table is done, try the next table
1322
    msg += sizeof(SVgroupsInfo) + vgSize * sizeof(SCMVgroupInfo);
1323
  }
S
slguan 已提交
1324

1325 1326 1327 1328
  pMsg->rpcRsp.rsp = pRsp;
  pMsg->rpcRsp.len = msg - (char *)pRsp;

  return TSDB_CODE_SUCCESS;
S
slguan 已提交
1329 1330
}

1331
static void mnodeProcessDropSuperTableRsp(SRpcMsg *rpcMsg) {
guanshengliang's avatar
guanshengliang 已提交
1332
  mPrint("drop stable rsp received, result:%s", tstrerror(rpcMsg->code));
S
slguan 已提交
1333 1334
}

S
Shengliang Guan 已提交
1335
static void *mnodeBuildCreateChildTableMsg(SCMCreateTableMsg *pMsg, SChildTableObj *pTable) {
1336
  STagData *  pTagData = NULL;
S
slguan 已提交
1337 1338 1339 1340
  int32_t tagDataLen = 0;
  int32_t totalCols = 0;
  int32_t contLen = 0;
  if (pTable->info.type == TSDB_CHILD_TABLE && pMsg != NULL) {
1341 1342
    pTagData = (STagData*)pMsg->schema;
    tagDataLen = ntohl(pTagData->dataLen);
S
slguan 已提交
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
    totalCols = pTable->superTable->numOfColumns + pTable->superTable->numOfTags;
    contLen = sizeof(SMDCreateTableMsg) + totalCols * sizeof(SSchema) + tagDataLen + pTable->sqlLen;
  } else {
    totalCols = pTable->numOfColumns;
    contLen = sizeof(SMDCreateTableMsg) + totalCols * sizeof(SSchema) + pTable->sqlLen;
  }

  SMDCreateTableMsg *pCreate = rpcMallocCont(contLen);
  if (pCreate == NULL) {
    terrno = TSDB_CODE_SERV_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
1356
  mnodeExtractTableName(pTable->info.tableId, pCreate->tableId);
S
slguan 已提交
1357 1358 1359 1360 1361 1362 1363 1364 1365
  pCreate->contLen       = htonl(contLen);
  pCreate->vgId          = htonl(pTable->vgId);
  pCreate->tableType     = pTable->info.type;
  pCreate->createdTime   = htobe64(pTable->createdTime);
  pCreate->sid           = htonl(pTable->sid);
  pCreate->sqlDataLen    = htonl(pTable->sqlLen);
  pCreate->uid           = htobe64(pTable->uid);
  
  if (pTable->info.type == TSDB_CHILD_TABLE) {
S
Shengliang Guan 已提交
1366
    mnodeExtractTableName(pTable->superTable->info.tableId, pCreate->superTableId);
S
slguan 已提交
1367 1368 1369
    pCreate->numOfColumns  = htons(pTable->superTable->numOfColumns);
    pCreate->numOfTags     = htons(pTable->superTable->numOfTags);
    pCreate->sversion      = htonl(pTable->superTable->sversion);
1370
    pCreate->tversion      = htonl(pTable->superTable->tversion);
S
slguan 已提交
1371 1372 1373 1374 1375 1376
    pCreate->tagDataLen    = htonl(tagDataLen);
    pCreate->superTableUid = htobe64(pTable->superTable->uid);
  } else {
    pCreate->numOfColumns  = htons(pTable->numOfColumns);
    pCreate->numOfTags     = 0;
    pCreate->sversion      = htonl(pTable->sversion);
1377
    pCreate->tversion      = 0;
S
slguan 已提交
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
    pCreate->tagDataLen    = 0;
    pCreate->superTableUid = 0;
  }
 
  SSchema *pSchema = (SSchema *) pCreate->data;
  if (pTable->info.type == TSDB_CHILD_TABLE) {
    memcpy(pSchema, pTable->superTable->schema, totalCols * sizeof(SSchema));
  } else {
    memcpy(pSchema, pTable->schema, totalCols * sizeof(SSchema));
  }
  for (int32_t col = 0; col < totalCols; ++col) {
    pSchema->bytes = htons(pSchema->bytes);
    pSchema->colId = htons(pSchema->colId);
    pSchema++;
  }

  if (pTable->info.type == TSDB_CHILD_TABLE && pMsg != NULL) {
1395
    memcpy(pCreate->data + totalCols * sizeof(SSchema), pTagData->data, tagDataLen);
1396 1397 1398 1399
  }

  if (pTable->info.type == TSDB_STREAM_TABLE && pMsg != NULL) {
    memcpy(pCreate->data + totalCols * sizeof(SSchema), pTable->sql, pTable->sqlLen);
S
slguan 已提交
1400 1401 1402 1403 1404
  }

  return pCreate;
}

1405
static SChildTableObj* mnodeDoCreateChildTable(SCMCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t tid) {
1406
  SChildTableObj *pTable = calloc(1, sizeof(SChildTableObj));
S
slguan 已提交
1407
  if (pTable == NULL) {
S
slguan 已提交
1408
    mError("table:%s, failed to alloc memory", pCreate->tableId);
S
slguan 已提交
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
    terrno = TSDB_CODE_SERV_OUT_OF_MEMORY;
    return NULL;
  }

  if (pCreate->numOfColumns == 0) {
    pTable->info.type = TSDB_CHILD_TABLE;
  } else {
    pTable->info.type = TSDB_NORMAL_TABLE;
  }

1419 1420 1421 1422
  pTable->info.tableId = strdup(pCreate->tableId);  
  pTable->createdTime  = taosGetTimestampMs();
  pTable->sid          = tid;
  pTable->vgId         = pVgroup->vgId;
S
slguan 已提交
1423 1424
    
  if (pTable->info.type == TSDB_CHILD_TABLE) {
1425
    STagData *pTagData = (STagData *) pCreate->schema;  // it is a tag key
1426
    SSuperTableObj *pSuperTable = mnodeGetSuperTable(pTagData->name);
S
slguan 已提交
1427
    if (pSuperTable == NULL) {
1428
      mError("table:%s, corresponding super table:%s does not exist", pCreate->tableId, pTagData->name);
S
slguan 已提交
1429 1430 1431 1432
      free(pTable);
      terrno = TSDB_CODE_INVALID_TABLE;
      return NULL;
    }
1433
    mnodeDecTableRef(pSuperTable);
S
slguan 已提交
1434

1435 1436 1437 1438
    pTable->suid = pSuperTable->uid;
    pTable->uid  = (((uint64_t)pTable->vgId) << 40) + ((((uint64_t)pTable->sid) & ((1ul << 24) - 1ul)) << 16) +
                  (sdbGetVersion() & ((1ul << 16) - 1ul));
    pTable->superTable = pSuperTable;
S
slguan 已提交
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
  } else {
    pTable->uid          = (((uint64_t) pTable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul));
    pTable->sversion     = 0;
    pTable->numOfColumns = htons(pCreate->numOfColumns);
    pTable->sqlLen       = htons(pCreate->sqlLen);

    int32_t numOfCols  = pTable->numOfColumns;
    int32_t schemaSize = numOfCols * sizeof(SSchema);
    pTable->schema     = (SSchema *) calloc(1, schemaSize);
    if (pTable->schema == NULL) {
      free(pTable);
      terrno = TSDB_CODE_SERV_OUT_OF_MEMORY;
      return NULL;
    }
    memcpy(pTable->schema, pCreate->schema, numOfCols * sizeof(SSchema));

    pTable->nextColId = 0;
    for (int32_t col = 0; col < numOfCols; col++) {
      SSchema *tschema   = pTable->schema;
      tschema[col].colId = pTable->nextColId++;
      tschema[col].bytes = htons(tschema[col].bytes);
    }

    if (pTable->sqlLen != 0) {
      pTable->info.type = TSDB_STREAM_TABLE;
      pTable->sql = calloc(1, pTable->sqlLen);
      if (pTable->sql == NULL) {
        free(pTable);
        terrno = TSDB_CODE_SERV_OUT_OF_MEMORY;
        return NULL;
      }
      memcpy(pTable->sql, (char *) (pCreate->schema) + numOfCols * sizeof(SSchema), pTable->sqlLen);
      pTable->sql[pTable->sqlLen - 1] = 0;
      mTrace("table:%s, stream sql len:%d sql:%s", pTable->info.tableId, pTable->sqlLen, pTable->sql);
    }
  }
  
S
slguan 已提交
1476
  SSdbOper desc = {0};
S
slguan 已提交
1477
  desc.type = SDB_OPER_GLOBAL;
S
slguan 已提交
1478 1479 1480 1481 1482
  desc.pObj = pTable;
  desc.table = tsChildTableSdb;
  
  if (sdbInsertRow(&desc) != TSDB_CODE_SUCCESS) {
    free(pTable);
S
slguan 已提交
1483
    mError("table:%s, update sdb error", pCreate->tableId);
S
slguan 已提交
1484 1485 1486 1487
    terrno = TSDB_CODE_SDB_ERROR;
    return NULL;
  }

S
Shengliang Guan 已提交
1488
  mTrace("table:%s, create table in vgroup:%d, id:%d, uid:%" PRIu64 , pTable->info.tableId, pVgroup->vgId, pTable->sid, pTable->uid);
S
slguan 已提交
1489 1490 1491
  return pTable;
}

1492
static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
1493
  SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
S
slguan 已提交
1494 1495
  int32_t code = grantCheck(TSDB_GRANT_TIMESERIES);
  if (code != TSDB_CODE_SUCCESS) {
S
slguan 已提交
1496
    mError("table:%s, failed to create, grant timeseries failed", pCreate->tableId);
1497
    return code;
S
slguan 已提交
1498 1499
  }

1500
  SVgObj *pVgroup = mnodeGetAvailableVgroup(pMsg->pDb);
S
slguan 已提交
1501
  if (pVgroup == NULL) {
S
slguan 已提交
1502
    mTrace("table:%s, start to create a new vgroup", pCreate->tableId);
1503
    return mnodeCreateVgroup(pMsg, pMsg->pDb);
S
slguan 已提交
1504 1505
  }

1506
  if (pMsg->retry == 0) {
1507
    if (pMsg->pTable == NULL) {
1508 1509 1510
      int32_t sid = taosAllocateId(pVgroup->idPool);
      if (sid <= 0) {
        mTrace("tables:%s, no enough sid in vgId:%d", pCreate->tableId, pVgroup->vgId);
1511
        return mnodeCreateVgroup(pMsg, pMsg->pDb);
1512 1513
      }

1514
      pMsg->pTable = (STableObj *)mnodeDoCreateChildTable(pCreate, pVgroup, sid);
1515
      if (pMsg->pTable == NULL) {
1516
        return terrno;
1517 1518
      }

1519
      mnodeIncTableRef(pMsg->pTable);
1520
    }
1521
  } else {
1522
    if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pCreate->tableId);
1523
  }
1524

S
slguan 已提交
1525
  if (pMsg->pTable == NULL) {
1526
    return terrno;
S
slguan 已提交
1527 1528
  }

1529
  SMDCreateTableMsg *pMDCreate = mnodeBuildCreateChildTableMsg(pCreate, (SChildTableObj *)pMsg->pTable);
S
slguan 已提交
1530
  if (pMDCreate == NULL) {
1531
    return terrno;
S
slguan 已提交
1532 1533
  }

1534
  SRpcIpSet ipSet = mnodeGetIpSetFromVgroup(pVgroup);
S
slguan 已提交
1535
  SRpcMsg rpcMsg = {
1536
      .handle  = pMsg,
S
slguan 已提交
1537 1538 1539 1540 1541 1542
      .pCont   = pMDCreate,
      .contLen = htonl(pMDCreate->contLen),
      .code    = 0,
      .msgType = TSDB_MSG_TYPE_MD_CREATE_TABLE
  };

J
jtao1735 已提交
1543
  dnodeSendMsgToDnode(&ipSet, &rpcMsg);
1544 1545

  return TSDB_CODE_ACTION_IN_PROGRESS;
S
slguan 已提交
1546 1547
}

1548
static int32_t mnodeProcessDropChildTableMsg(SMnodeMsg *pMsg) {
S
slguan 已提交
1549
  SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable;
1550
  if (pMsg->pVgroup == NULL) pMsg->pVgroup = mnodeGetVgroup(pTable->vgId);
1551
  if (pMsg->pVgroup == NULL) {
S
slguan 已提交
1552
    mError("table:%s, failed to drop ctable, vgroup not exist", pTable->info.tableId);
1553
    return TSDB_CODE_OTHERS;
S
slguan 已提交
1554 1555 1556 1557
  }

  SMDDropTableMsg *pDrop = rpcMallocCont(sizeof(SMDDropTableMsg));
  if (pDrop == NULL) {
S
slguan 已提交
1558
    mError("table:%s, failed to drop ctable, no enough memory", pTable->info.tableId);
1559
    return TSDB_CODE_SERV_OUT_OF_MEMORY;
S
slguan 已提交
1560 1561 1562 1563 1564 1565 1566 1567
  }

  strcpy(pDrop->tableId, pTable->info.tableId);
  pDrop->vgId    = htonl(pTable->vgId);
  pDrop->contLen = htonl(sizeof(SMDDropTableMsg));
  pDrop->sid     = htonl(pTable->sid);
  pDrop->uid     = htobe64(pTable->uid);

1568
  SRpcIpSet ipSet = mnodeGetIpSetFromVgroup(pMsg->pVgroup);
S
slguan 已提交
1569

guanshengliang's avatar
guanshengliang 已提交
1570
  mPrint("table:%s, send drop ctable msg", pDrop->tableId);
S
slguan 已提交
1571
  SRpcMsg rpcMsg = {
1572
    .handle  = pMsg,
S
slguan 已提交
1573 1574 1575 1576 1577 1578
    .pCont   = pDrop,
    .contLen = sizeof(SMDDropTableMsg),
    .code    = 0,
    .msgType = TSDB_MSG_TYPE_MD_DROP_TABLE
  };

J
jtao1735 已提交
1579
  dnodeSendMsgToDnode(&ipSet, &rpcMsg);
1580 1581

  return TSDB_CODE_ACTION_IN_PROGRESS;
S
slguan 已提交
1582 1583
}

1584
static int32_t mnodeModifyChildTableTagValue(SChildTableObj *pTable, char *tagName, char *nContent) {
S
[TD-17]  
slguan 已提交
1585
  return TSDB_CODE_OPS_NOT_SUPPORT;
S
slguan 已提交
1586 1587
}

1588
static int32_t mnodeFindNormalTableColumnIndex(SChildTableObj *pTable, char *colName) {
S
slguan 已提交
1589
  SSchema *schema = (SSchema *) pTable->schema;
S
slguan 已提交
1590 1591 1592
  for (int32_t col = 0; col < pTable->numOfColumns; col++) {
    if (strcasecmp(schema[col].name, colName) == 0) {
      return col;
S
slguan 已提交
1593 1594 1595 1596 1597 1598
    }
  }

  return -1;
}

1599
static int32_t mnodeAddNormalTableColumn(SDbObj *pDb, SChildTableObj *pTable, SSchema schema[], int32_t ncols) {
S
slguan 已提交
1600
  if (ncols <= 0) {
S
slguan 已提交
1601
    mError("table:%s, add column, ncols:%d <= 0", pTable->info.tableId);
S
slguan 已提交
1602 1603 1604 1605
    return TSDB_CODE_APP_ERROR;
  }

  for (int32_t i = 0; i < ncols; i++) {
1606
    if (mnodeFindNormalTableColumnIndex(pTable, schema[i].name) > 0) {
S
slguan 已提交
1607 1608
      mError("table:%s, add column, column:%s already exist", pTable->info.tableId, schema[i].name);
      return TSDB_CODE_FIELD_ALREAY_EXIST;
S
slguan 已提交
1609 1610 1611 1612 1613 1614
    }
  }

  int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema);
  pTable->schema = realloc(pTable->schema, schemaSize + sizeof(SSchema) * ncols);

S
slguan 已提交
1615
  memcpy(pTable->schema + pTable->numOfColumns, schema, sizeof(SSchema) * ncols);
S
slguan 已提交
1616

S
slguan 已提交
1617
  SSchema *tschema = (SSchema *) (pTable->schema + pTable->numOfColumns);
S
slguan 已提交
1618 1619 1620 1621 1622 1623
  for (int32_t i = 0; i < ncols; i++) {
    tschema[i].colId = pTable->nextColId++;
  }

  pTable->numOfColumns += ncols;
  pTable->sversion++;
S
[TD-17]  
slguan 已提交
1624
  
1625
  SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
S
[TD-17]  
slguan 已提交
1626
  if (pAcct != NULL) {
S
slguan 已提交
1627
    pAcct->acctInfo.numOfTimeSeries += ncols;
1628
    mnodeDecAcctRef(pAcct);
S
[TD-17]  
slguan 已提交
1629 1630
  }
 
S
slguan 已提交
1631
  SSdbOper oper = {
S
slguan 已提交
1632
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
1633
    .table = tsChildTableSdb,
1634
    .pObj = pTable
S
[TD-17]  
slguan 已提交
1635
  };
S
slguan 已提交
1636

S
[TD-17]  
slguan 已提交
1637 1638 1639 1640 1641 1642
  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
  }
  
  mPrint("table %s, succeed to add column", pTable->info.tableId);
S
slguan 已提交
1643 1644 1645
  return TSDB_CODE_SUCCESS;
}

1646 1647
static int32_t mnodeDropNormalTableColumn(SDbObj *pDb, SChildTableObj *pTable, char *colName) {
  int32_t col = mnodeFindNormalTableColumnIndex(pTable, colName);
S
slguan 已提交
1648 1649 1650
  if (col <= 0) {
    mError("table:%s, drop column, column:%s not exist", pTable->info.tableId, colName);
    return TSDB_CODE_FIELD_NOT_EXIST;
S
slguan 已提交
1651 1652
  }

S
slguan 已提交
1653
  memmove(pTable->schema + col, pTable->schema + col + 1, sizeof(SSchema) * (pTable->numOfColumns - col - 1));
S
slguan 已提交
1654 1655 1656
  pTable->numOfColumns--;
  pTable->sversion++;

1657
  SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
S
[TD-17]  
slguan 已提交
1658 1659
  if (pAcct != NULL) {
    pAcct->acctInfo.numOfTimeSeries--;
1660
    mnodeDecAcctRef(pAcct);
S
[TD-17]  
slguan 已提交
1661 1662
  }
 
S
slguan 已提交
1663
  SSdbOper oper = {
S
slguan 已提交
1664
    .type = SDB_OPER_GLOBAL,
S
[TD-17]  
slguan 已提交
1665
    .table = tsChildTableSdb,
1666
    .pObj = pTable
S
[TD-17]  
slguan 已提交
1667
  };
S
slguan 已提交
1668

S
[TD-17]  
slguan 已提交
1669 1670 1671 1672 1673
  int32_t code = sdbUpdateRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    return TSDB_CODE_SDB_ERROR;
  }
  
S
slguan 已提交
1674
  mPrint("table %s, succeed to drop column %s", pTable->info.tableId, colName);
S
slguan 已提交
1675 1676 1677
  return TSDB_CODE_SUCCESS;
}

1678
static int32_t mnodeSetSchemaFromNormalTable(SSchema *pSchema, SChildTableObj *pTable) {
S
slguan 已提交
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
  int32_t numOfCols = pTable->numOfColumns;
  for (int32_t i = 0; i < numOfCols; ++i) {
    strcpy(pSchema->name, pTable->schema[i].name);
    pSchema->type  = pTable->schema[i].type;
    pSchema->bytes = htons(pTable->schema[i].bytes);
    pSchema->colId = htons(pTable->schema[i].colId);
    pSchema++;
  }

  return numOfCols * sizeof(SSchema);
}

1691
static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
S
slguan 已提交
1692 1693 1694
  SDbObj *pDb = pMsg->pDb;
  SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable;

S
slguan 已提交
1695 1696 1697 1698
  pMeta->uid       = htobe64(pTable->uid);
  pMeta->sid       = htonl(pTable->sid);
  pMeta->precision = pDb->cfg.precision;
  pMeta->tableType = pTable->info.type;
S
Shuduo Sang 已提交
1699
  strncpy(pMeta->tableId, pTable->info.tableId, strlen(pTable->info.tableId));
S
slguan 已提交
1700 1701 1702

  if (pTable->info.type == TSDB_CHILD_TABLE) {
    pMeta->sversion     = htons(pTable->superTable->sversion);
1703
    pMeta->tversion     = htons(pTable->superTable->tversion);
S
slguan 已提交
1704
    pMeta->numOfTags    = (int8_t)pTable->superTable->numOfTags;
S
slguan 已提交
1705
    pMeta->numOfColumns = htons((int16_t)pTable->superTable->numOfColumns);
1706
    pMeta->contLen      = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable->superTable);
S
slguan 已提交
1707 1708
  } else {
    pMeta->sversion     = htons(pTable->sversion);
1709
    pMeta->tversion     = 0;
S
slguan 已提交
1710 1711
    pMeta->numOfTags    = 0;
    pMeta->numOfColumns = htons((int16_t)pTable->numOfColumns);
1712
    pMeta->contLen      = sizeof(STableMetaMsg) + mnodeSetSchemaFromNormalTable(pMeta->schema, pTable); 
S
slguan 已提交
1713 1714
  }
  
1715
  if (pMsg->pVgroup == NULL) pMsg->pVgroup = mnodeGetVgroup(pTable->vgId);
1716
  if (pMsg->pVgroup == NULL) {
S
slguan 已提交
1717 1718 1719 1720
    mError("table:%s, failed to get table meta, db not selected", pTable->info.tableId);
    return TSDB_CODE_INVALID_VGROUP_ID;
  }

1721
  for (int32_t i = 0; i < pMsg->pVgroup->numOfVnodes; ++i) {
1722
    SDnodeObj *pDnode = mnodeGetDnode(pMsg->pVgroup->vnodeGid[i].dnodeId);
S
slguan 已提交
1723
    if (pDnode == NULL) break;
J
jtao1735 已提交
1724
    strcpy(pMeta->vgroup.ipAddr[i].fqdn, pDnode->dnodeFqdn);
J
jtao1735 已提交
1725
    pMeta->vgroup.ipAddr[i].port = htons(pDnode->dnodePort + TSDB_PORT_DNODESHELL);
S
slguan 已提交
1726
    pMeta->vgroup.numOfIps++;
1727
    mnodeDecDnodeRef(pDnode);
S
slguan 已提交
1728
  }
1729
  pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
S
slguan 已提交
1730 1731 1732 1733 1734 1735

  mTrace("table:%s, uid:%" PRIu64 " table meta is retrieved", pTable->info.tableId, pTable->uid);

  return TSDB_CODE_SUCCESS;
}

S
Shengliang Guan 已提交
1736
static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
1737
  SCMTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
1738 1739 1740
  STagData* pTag = (STagData*)pInfo->tags;

  int32_t contLen = sizeof(SCMCreateTableMsg) + offsetof(STagData, data) + ntohl(pTag->dataLen);
S
slguan 已提交
1741 1742 1743
  SCMCreateTableMsg *pCreateMsg = rpcMallocCont(contLen);
  if (pCreateMsg == NULL) {
    mError("table:%s, failed to create table while get meta info, no enough memory", pInfo->tableId);
1744
    return TSDB_CODE_SERV_OUT_OF_MEMORY;
S
slguan 已提交
1745
  }
S
slguan 已提交
1746

S
slguan 已提交
1747 1748 1749 1750
  strncpy(pCreateMsg->tableId, pInfo->tableId, tListLen(pInfo->tableId));
  strcpy(pCreateMsg->db, pMsg->pDb->name);
  pCreateMsg->igExists = 1;
  pCreateMsg->getMeta = 1;
S
slguan 已提交
1751
  pCreateMsg->contLen = htonl(contLen);
B
Bomin Zhang 已提交
1752

1753
  memcpy(pCreateMsg->schema, pInfo->tags, contLen - sizeof(SCMCreateTableMsg));
S
slguan 已提交
1754

S
Shengliang Guan 已提交
1755 1756 1757 1758
  rpcFreeCont(pMsg->rpcMsg.pCont);
  pMsg->rpcMsg.msgType = TSDB_MSG_TYPE_CM_CREATE_TABLE;
  pMsg->rpcMsg.pCont = pCreateMsg;
  pMsg->rpcMsg.contLen = contLen;
S
slguan 已提交
1759

S
Shengliang Guan 已提交
1760
  mTrace("table:%s, start to create on demand, stable:%s", pInfo->tableId, pInfo->tags);
1761 1762

  return TSDB_CODE_ACTION_NEED_REPROCESSED;
S
slguan 已提交
1763
}
S
slguan 已提交
1764

1765
static int32_t mnodeGetChildTableMeta(SMnodeMsg *pMsg) {
1766
  STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
S
slguan 已提交
1767
  if (pMeta == NULL) {
S
slguan 已提交
1768
    mError("table:%s, failed to get table meta, no enough memory", pMsg->pTable->tableId);
1769
    return TSDB_CODE_SERV_OUT_OF_MEMORY;
S
slguan 已提交
1770 1771
  }

1772
  mnodeDoGetChildTableMeta(pMsg, pMeta);
S
slguan 已提交
1773

1774 1775
  pMsg->rpcRsp.len = pMeta->contLen;
  pMsg->rpcRsp.rsp = pMeta;
S
slguan 已提交
1776
  pMeta->contLen = htons(pMeta->contLen);
1777 1778

  return TSDB_CODE_SUCCESS;
S
slguan 已提交
1779 1780
}

1781
void mnodeDropAllChildTablesInVgroups(SVgObj *pVgroup) {
1782 1783 1784 1785 1786 1787 1788
  void *  pIter = NULL;
  int32_t numOfTables = 0;
  SChildTableObj *pTable = NULL;

  mPrint("vgId:%d, all child tables will be dropped from sdb", pVgroup->vgId);

  while (1) {
1789
    pIter = mnodeGetNextChildTable(pIter, &pTable);
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
    if (pTable == NULL) break;

    if (pTable->vgId == pVgroup->vgId) {
      SSdbOper oper = {
        .type = SDB_OPER_LOCAL,
        .table = tsChildTableSdb,
        .pObj = pTable,
      };
      sdbDeleteRow(&oper);
      numOfTables++;
    }
1801
    mnodeDecTableRef(pTable);
1802 1803 1804 1805 1806 1807 1808
  }

  sdbFreeIter(pIter);

  mPrint("vgId:%d, all child tables is dropped from sdb", pVgroup->vgId);
}

1809
void mnodeDropAllChildTables(SDbObj *pDropDb) {
S
Shengliang Guan 已提交
1810
  void *  pIter = NULL;
S
slguan 已提交
1811 1812 1813 1814
  int32_t numOfTables = 0;
  int32_t dbNameLen = strlen(pDropDb->name);
  SChildTableObj *pTable = NULL;

S
slguan 已提交
1815 1816
  mPrint("db:%s, all child tables will be dropped from sdb", pDropDb->name);

S
slguan 已提交
1817
  while (1) {
1818
    pIter = mnodeGetNextChildTable(pIter, &pTable);
S
slguan 已提交
1819
    if (pTable == NULL) break;
S
slguan 已提交
1820 1821

    if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) {
S
slguan 已提交
1822
      SSdbOper oper = {
S
slguan 已提交
1823
        .type = SDB_OPER_LOCAL,
S
slguan 已提交
1824 1825 1826 1827 1828 1829
        .table = tsChildTableSdb,
        .pObj = pTable,
      };
      sdbDeleteRow(&oper);
      numOfTables++;
    }
1830
    mnodeDecTableRef(pTable);
S
slguan 已提交
1831 1832
  }

S
Shengliang Guan 已提交
1833 1834
  sdbFreeIter(pIter);

S
slguan 已提交
1835
  mPrint("db:%s, all child tables:%d is dropped from sdb", pDropDb->name, numOfTables);
S
slguan 已提交
1836 1837
}

1838
static void mnodeDropAllChildTablesInStable(SSuperTableObj *pStable) {
S
Shengliang Guan 已提交
1839
  void *  pIter = NULL;
S
slguan 已提交
1840 1841 1842
  int32_t numOfTables = 0;
  SChildTableObj *pTable = NULL;

S
slguan 已提交
1843 1844
  mPrint("stable:%s, all child tables will dropped from sdb", pStable->info.tableId, numOfTables);

S
slguan 已提交
1845
  while (1) {
1846
    pIter = mnodeGetNextChildTable(pIter, &pTable);
S
slguan 已提交
1847
    if (pTable == NULL) break;
S
slguan 已提交
1848 1849

    if (pTable->superTable == pStable) {
S
slguan 已提交
1850
      SSdbOper oper = {
S
slguan 已提交
1851
        .type = SDB_OPER_LOCAL,
S
slguan 已提交
1852 1853 1854 1855 1856 1857
        .table = tsChildTableSdb,
        .pObj = pTable,
      };
      sdbDeleteRow(&oper);
      numOfTables++;
    }
S
slguan 已提交
1858

1859
    mnodeDecTableRef(pTable);
S
slguan 已提交
1860 1861
  }

S
Shengliang Guan 已提交
1862 1863
  sdbFreeIter(pIter);

S
slguan 已提交
1864
  mPrint("stable:%s, all child tables:%d is dropped from sdb", pStable->info.tableId, numOfTables);
S
slguan 已提交
1865 1866
}

1867 1868
static SChildTableObj* mnodeGetTableByPos(int32_t vnode, int32_t sid) {
  SVgObj *pVgroup = mnodeGetVgroup(vnode);
1869
  if (pVgroup == NULL) return NULL;
S
slguan 已提交
1870

S
slguan 已提交
1871
  SChildTableObj *pTable = pVgroup->tableList[sid - 1];
1872
  mnodeIncTableRef((STableObj *)pTable);
1873

1874
  mnodeDecVgroupRef(pVgroup);
S
slguan 已提交
1875 1876 1877
  return pTable;
}

1878
static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
1879
  SDMConfigTableMsg *pCfg = pMsg->rpcMsg.pCont;
S
slguan 已提交
1880 1881 1882 1883 1884
  pCfg->dnode = htonl(pCfg->dnode);
  pCfg->vnode = htonl(pCfg->vnode);
  pCfg->sid   = htonl(pCfg->sid);
  mTrace("dnode:%s, vnode:%d, sid:%d, receive table config msg", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid);

1885
  SChildTableObj *pTable = mnodeGetTableByPos(pCfg->vnode, pCfg->sid);
S
slguan 已提交
1886 1887
  if (pTable == NULL) {
    mError("dnode:%s, vnode:%d, sid:%d, table not found", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid);
1888
    return TSDB_CODE_NOT_ACTIVE_TABLE;
S
slguan 已提交
1889 1890 1891
  }

  SMDCreateTableMsg *pMDCreate = NULL;
1892
  pMDCreate = mnodeBuildCreateChildTableMsg(NULL, (SChildTableObj *)pTable);
S
slguan 已提交
1893
  if (pMDCreate == NULL) {
1894 1895
    mnodeDecTableRef(pTable);
    return terrno;
S
slguan 已提交
1896
  }
1897

1898 1899
  SDnodeObj *pDnode = mnodeGetDnode(pCfg->dnode);
  SRpcIpSet ipSet = mnodeGetIpSetFromIp(pDnode->dnodeEp);
S
slguan 已提交
1900 1901 1902 1903 1904 1905 1906
  SRpcMsg rpcRsp = {
      .handle  = NULL,
      .pCont   = pMDCreate,
      .contLen = htonl(pMDCreate->contLen),
      .code    = 0,
      .msgType = TSDB_MSG_TYPE_MD_CREATE_TABLE
  };
J
jtao1735 已提交
1907
  dnodeSendMsgToDnode(&ipSet, &rpcRsp);
1908

1909 1910 1911 1912
  mnodeDecTableRef(pTable);
  mnodeDecDnodeRef(pDnode);

  return TSDB_CODE_SUCCESS;
S
slguan 已提交
1913 1914
}

S
slguan 已提交
1915
// handle drop child response
1916
static void mnodeProcessDropChildTableRsp(SRpcMsg *rpcMsg) {
S
slguan 已提交
1917 1918
  if (rpcMsg->handle == NULL) return;

1919 1920
  SMnodeMsg *mnodeMsg = rpcMsg->handle;
  mnodeMsg->received++;
S
slguan 已提交
1921

S
Shengliang Guan 已提交
1922 1923 1924
  SChildTableObj *pTable = (SChildTableObj *)mnodeMsg->pTable;
  assert(pTable);
  mPrint("table:%s, drop table rsp received, thandle:%p result:%s", pTable->info.tableId, mnodeMsg->rpcMsg.handle, tstrerror(rpcMsg->code));
S
slguan 已提交
1925 1926 1927

  if (rpcMsg->code != TSDB_CODE_SUCCESS) {
    mError("table:%s, failed to drop in dnode, reason:%s", pTable->info.tableId, tstrerror(rpcMsg->code));
1928 1929
    dnodeSendRpcMnodeWriteRsp(mnodeMsg, rpcMsg->code);
    mnodeDecTableRef(pTable);
S
slguan 已提交
1930 1931 1932
    return;
  }

1933 1934
  if (mnodeMsg->pVgroup == NULL) mnodeMsg->pVgroup = mnodeGetVgroup(pTable->vgId);
  if (mnodeMsg->pVgroup == NULL) {
S
slguan 已提交
1935
    mError("table:%s, failed to get vgroup", pTable->info.tableId);
1936
    dnodeSendRpcMnodeWriteRsp(mnodeMsg, TSDB_CODE_INVALID_VGROUP_ID);
S
slguan 已提交
1937 1938 1939
    return;
  }
  
S
slguan 已提交
1940
  SSdbOper oper = {
S
slguan 已提交
1941
    .type = SDB_OPER_GLOBAL,
S
slguan 已提交
1942 1943 1944 1945 1946 1947 1948
    .table = tsChildTableSdb,
    .pObj = pTable
  };
  
  int32_t code = sdbDeleteRow(&oper);
  if (code != TSDB_CODE_SUCCESS) {
    mError("table:%s, update ctables sdb error", pTable->info.tableId);
1949
    dnodeSendRpcMnodeWriteRsp(mnodeMsg, TSDB_CODE_SDB_ERROR);
S
slguan 已提交
1950 1951 1952
    return;
  }

1953 1954 1955
  if (mnodeMsg->pVgroup->numOfTables <= 0) {
    mPrint("vgId:%d, all tables is dropped, drop vgroup", mnodeMsg->pVgroup->vgId);
    mnodeDropVgroup(mnodeMsg->pVgroup, NULL);
S
slguan 已提交
1956 1957
  }

1958
  dnodeSendRpcMnodeWriteRsp(mnodeMsg, TSDB_CODE_SUCCESS);
S
slguan 已提交
1959 1960
}

S
slguan 已提交
1961 1962
// handle create table response from dnode
// if failed, drop the table cached
1963
static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) {
S
slguan 已提交
1964 1965
  if (rpcMsg->handle == NULL) return;

1966 1967
  SMnodeMsg *mnodeMsg = rpcMsg->handle;
  mnodeMsg->received++;
S
slguan 已提交
1968

S
Shengliang Guan 已提交
1969 1970 1971
  SChildTableObj *pTable = (SChildTableObj *)mnodeMsg->pTable;
  assert(pTable);
  mTrace("table:%s, create table rsp received, thandle:%p result:%s", pTable->info.tableId, mnodeMsg->rpcMsg.handle,
1972
         tstrerror(rpcMsg->code));
S
slguan 已提交
1973 1974

  if (rpcMsg->code != TSDB_CODE_SUCCESS) {
S
Shengliang Guan 已提交
1975
    if (mnodeMsg->retry++ < 10) {
1976
      mTrace("table:%s, create table rsp received, retry:%d thandle:%p result:%s", pTable->info.tableId,
S
Shengliang Guan 已提交
1977
             mnodeMsg->retry, mnodeMsg->rpcMsg.handle, tstrerror(rpcMsg->code));
1978
      dnodeDelayReprocessMnodeWriteMsg(mnodeMsg);
1979 1980
    } else {
      mError("table:%s, failed to create in dnode, thandle:%p result:%s", pTable->info.tableId,
S
Shengliang Guan 已提交
1981
             mnodeMsg->rpcMsg.handle, tstrerror(rpcMsg->code));
1982
      
S
slguan 已提交
1983
      SSdbOper oper = {
S
slguan 已提交
1984
        .type = SDB_OPER_GLOBAL,
1985 1986 1987 1988
        .table = tsChildTableSdb,
        .pObj = pTable
      };
      sdbDeleteRow(&oper);
S
slguan 已提交
1989
    
1990
      dnodeSendRpcMnodeWriteRsp(mnodeMsg, rpcMsg->code);
1991
    }    
S
slguan 已提交
1992
  } else {
S
Shengliang Guan 已提交
1993
    mTrace("table:%s, created in dnode, thandle:%p result:%s", pTable->info.tableId, mnodeMsg->rpcMsg.handle,
1994
           tstrerror(rpcMsg->code));
S
Shengliang Guan 已提交
1995
    SCMCreateTableMsg *pCreate = mnodeMsg->rpcMsg.pCont;
S
slguan 已提交
1996 1997
    if (pCreate->getMeta) {
      mTrace("table:%s, continue to get meta", pTable->info.tableId);
1998 1999
      mnodeMsg->retry = 0;
      dnodeReprocessMnodeWriteMsg(mnodeMsg);
S
slguan 已提交
2000
    } else {
2001
      dnodeSendRpcMnodeWriteRsp(mnodeMsg, rpcMsg->code);
S
slguan 已提交
2002 2003 2004 2005
    }
  }
}

S
slguan 已提交
2006
// not implemented yet
2007
static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) {
2008
  mTrace("alter table rsp received, handle:%p code:%s", rpcMsg->handle, tstrerror(rpcMsg->code));
S
slguan 已提交
2009 2010
}

2011
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
2012
  SCMMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
S
slguan 已提交
2013 2014
  pInfo->numOfTables = htonl(pInfo->numOfTables);

2015
  int32_t totalMallocLen = 4 * 1024 * 1024;  // first malloc 4 MB, subsequent reallocation as twice
S
slguan 已提交
2016 2017
  SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen);
  if (pMultiMeta == NULL) {
2018
    return TSDB_CODE_SERV_OUT_OF_MEMORY;
S
slguan 已提交
2019 2020 2021 2022 2023
  }

  pMultiMeta->contLen = sizeof(SMultiTableMeta);
  pMultiMeta->numOfTables = 0;

2024 2025
  for (int32_t t = 0; t < pInfo->numOfTables; ++t) {
    char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_ID_LEN + 1);
2026
    SChildTableObj *pTable = mnodeGetChildTable(tableId);
S
slguan 已提交
2027 2028
    if (pTable == NULL) continue;

2029
    if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(tableId);
2030
    if (pMsg->pDb == NULL) {
2031
      mnodeDecTableRef(pTable);
2032 2033
      continue;
    }
S
slguan 已提交
2034 2035

    int availLen = totalMallocLen - pMultiMeta->contLen;
2036
    if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
2037 2038 2039
      totalMallocLen *= 2;
      pMultiMeta = rpcReallocCont(pMultiMeta, totalMallocLen);
      if (pMultiMeta == NULL) {
2040 2041
        mnodeDecTableRef(pTable);
        return TSDB_CODE_SERV_OUT_OF_MEMORY;
2042 2043
      } else {
        t--;
2044
        mnodeDecTableRef(pTable);
2045 2046
        continue;
      }
S
slguan 已提交
2047 2048 2049
    }

    STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen);
2050
    int32_t code = mnodeDoGetChildTableMeta(pMsg, pMeta);
S
slguan 已提交
2051 2052 2053 2054
    if (code == TSDB_CODE_SUCCESS) {
      pMultiMeta->numOfTables ++;
      pMultiMeta->contLen += pMeta->contLen;
    }
2055

2056
    mnodeDecTableRef(pTable);
S
slguan 已提交
2057 2058
  }

2059 2060 2061 2062
  pMsg->rpcRsp.rsp = pMultiMeta;
  pMsg->rpcRsp.len = pMultiMeta->contLen;

  return TSDB_CODE_SUCCESS;
S
slguan 已提交
2063 2064
}

2065 2066
static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
  SDbObj *pDb = mnodeGetDb(pShow->db);
S
slguan 已提交
2067
  if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED;
S
slguan 已提交
2068 2069 2070 2071

  int32_t cols = 0;
  SSchema *pSchema = pMeta->schema;

2072
  pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
S
slguan 已提交
2073
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
2074
  strcpy(pSchema[cols].name, "table_name");
S
slguan 已提交
2075 2076 2077 2078 2079
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
2080
  strcpy(pSchema[cols].name, "created_time");
S
slguan 已提交
2081 2082 2083 2084 2085 2086 2087 2088 2089
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 2;
  pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
  strcpy(pSchema[cols].name, "columns");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

2090
  pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
S
slguan 已提交
2091
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
2092
  strcpy(pSchema[cols].name, "stable_name");
S
slguan 已提交
2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pMeta->numOfColumns = htons(cols);
  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];
  }

  pShow->numOfRows = pDb->numOfTables;
  pShow->rowSize   = pShow->offset[cols - 1] + pShow->bytes[cols - 1];

2107
  mnodeDecDbRef(pDb);
S
slguan 已提交
2108 2109 2110
  return 0;
}

S
Shengliang Guan 已提交
2111
static void mnodeVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow) {
S
slguan 已提交
2112 2113 2114 2115 2116 2117 2118
  if (rows < capacity) {
    for (int32_t i = 0; i < numOfCols; ++i) {
      memmove(data + pShow->offset[i] * rows, data + pShow->offset[i] * capacity, pShow->bytes[i] * rows);
    }
  }
}

2119 2120
static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
  SDbObj *pDb = mnodeGetDb(pShow->db);
S
slguan 已提交
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132
  if (pDb == NULL) return 0;

  int32_t numOfRows  = 0;
  SChildTableObj *pTable = NULL;
  SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;

  char prefix[64] = {0};
  strcpy(prefix, pDb->name);
  strcat(prefix, TS_PATH_DELIMITER);
  int32_t prefixLen = strlen(prefix);

  while (numOfRows < rows) {
2133
    pShow->pIter = mnodeGetNextChildTable(pShow->pIter, &pTable);
S
slguan 已提交
2134 2135 2136 2137
    if (pTable == NULL) break;

    // not belong to current db
    if (strncmp(pTable->info.tableId, prefix, prefixLen)) {
2138
      mnodeDecTableRef(pTable);
S
slguan 已提交
2139 2140 2141
      continue;
    }

2142
    char tableName[TSDB_TABLE_NAME_LEN + 1] = {0};
S
slguan 已提交
2143
    
2144
    // pattern compare for table name
S
Shengliang Guan 已提交
2145
    mnodeExtractTableName(pTable->info.tableId, tableName);
S
slguan 已提交
2146

S
Shengliang Guan 已提交
2147
    if (pShow->payloadLen > 0 && patternMatch(pShow->payload, tableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) {
2148
      mnodeDecTableRef(pTable);
S
slguan 已提交
2149 2150 2151 2152 2153 2154
      continue;
    }

    int32_t cols = 0;

    char *pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
H
hjxilinx 已提交
2155

2156
    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, tableName, TSDB_TABLE_NAME_LEN);
S
slguan 已提交
2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int64_t *) pWrite = pTable->createdTime;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    if (pTable->info.type == TSDB_CHILD_TABLE) {
      *(int16_t *)pWrite = pTable->superTable->numOfColumns;
    } else {
      *(int16_t *)pWrite = pTable->numOfColumns;
    }

    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
2173 2174
    
    memset(tableName, 0, tListLen(tableName));
S
slguan 已提交
2175
    if (pTable->info.type == TSDB_CHILD_TABLE) {
S
Shengliang Guan 已提交
2176
      mnodeExtractTableName(pTable->superTable->info.tableId, tableName);
2177
      STR_WITH_MAXSIZE_TO_VARSTR(pWrite, tableName, TSDB_TABLE_NAME_LEN);
S
slguan 已提交
2178
    }
2179
    
S
slguan 已提交
2180 2181 2182
    cols++;

    numOfRows++;
2183
    mnodeDecTableRef(pTable);
S
slguan 已提交
2184 2185 2186 2187 2188
  }

  pShow->numOfReads += numOfRows;
  const int32_t NUM_OF_COLUMNS = 4;

S
Shengliang Guan 已提交
2189
  mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
2190
  mnodeDecDbRef(pDb);
S
slguan 已提交
2191 2192 2193 2194

  return numOfRows;
}

2195
static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) {
S
Shengliang Guan 已提交
2196 2197
  SCMAlterTableMsg *pAlter = pMsg->rpcMsg.pCont;
  mTrace("table:%s, alter table msg is received from thandle:%p", pAlter->tableId, pMsg->rpcMsg.handle);
S
[TD-17]  
slguan 已提交
2198

2199
  if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(pAlter->tableId);
S
slguan 已提交
2200
  if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
S
[TD-17]  
slguan 已提交
2201
    mError("table:%s, failed to alter table, db not selected", pAlter->tableId);
2202
    return TSDB_CODE_DB_NOT_SELECTED;
S
[TD-17]  
slguan 已提交
2203 2204
  }

2205
  if (mnodeCheckIsMonitorDB(pMsg->pDb->name, tsMonitorDbName)) {
S
[TD-17]  
slguan 已提交
2206
    mError("table:%s, failed to alter table, its log db", pAlter->tableId);
2207
    return TSDB_CODE_MONITOR_DB_FORBIDDEN;
S
[TD-17]  
slguan 已提交
2208 2209
  }

2210
  if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pAlter->tableId);
S
[TD-17]  
slguan 已提交
2211 2212
  if (pMsg->pTable == NULL) {
    mError("table:%s, failed to alter table, table not exist", pMsg->pTable->tableId);
2213
    return TSDB_CODE_INVALID_TABLE;
S
[TD-17]  
slguan 已提交
2214 2215
  }

S
slguan 已提交
2216
  pAlter->type = htons(pAlter->type);
2217 2218
  pAlter->numOfCols = htons(pAlter->numOfCols);
  pAlter->tagValLen = htonl(pAlter->tagValLen);
S
slguan 已提交
2219

S
[TD-17]  
slguan 已提交
2220 2221
  if (pAlter->numOfCols > 2) {
    mError("table:%s, error numOfCols:%d in alter table", pAlter->tableId, pAlter->numOfCols);
2222
    return TSDB_CODE_APP_ERROR;
S
[TD-17]  
slguan 已提交
2223 2224 2225 2226 2227 2228
  }

  for (int32_t i = 0; i < pAlter->numOfCols; ++i) {
    pAlter->schema[i].bytes = htons(pAlter->schema[i].bytes);
  }

S
slguan 已提交
2229
  int32_t code = TSDB_CODE_OPS_NOT_SUPPORT;
S
[TD-17]  
slguan 已提交
2230 2231 2232 2233
  if (pMsg->pTable->type == TSDB_SUPER_TABLE) {
    SSuperTableObj *pTable = (SSuperTableObj *)pMsg->pTable;
    mTrace("table:%s, start to alter stable", pAlter->tableId);
    if (pAlter->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
2234
      code = mnodeAddSuperTableTag(pTable, pAlter->schema, 1);
S
[TD-17]  
slguan 已提交
2235
    } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) {
2236
      code = mnodeDropSuperTableTag(pTable, pAlter->schema[0].name);
S
[TD-17]  
slguan 已提交
2237
    } else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) {
2238
      code = mnodeModifySuperTableTagName(pTable, pAlter->schema[0].name, pAlter->schema[1].name);
S
[TD-17]  
slguan 已提交
2239
    } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
2240
      code = mnodeAddSuperTableColumn(pMsg->pDb, pTable, pAlter->schema, 1);
S
[TD-17]  
slguan 已提交
2241
    } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
2242
      code = mnodeDropSuperTableColumn(pMsg->pDb, pTable, pAlter->schema[0].name);
S
[TD-17]  
slguan 已提交
2243 2244
    } else {
    }
S
slguan 已提交
2245
  } else {
S
[TD-17]  
slguan 已提交
2246 2247 2248
    mTrace("table:%s, start to alter ctable", pAlter->tableId);
    SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable;
    if (pAlter->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) {
2249
      char *tagVal = (char*)(pAlter->schema + pAlter->numOfCols);
2250
      code = mnodeModifyChildTableTagValue(pTable, pAlter->schema[0].name, tagVal);
S
[TD-17]  
slguan 已提交
2251
    } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) {
2252
      code = mnodeAddNormalTableColumn(pMsg->pDb, pTable, pAlter->schema, 1);
S
[TD-17]  
slguan 已提交
2253
    } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
2254
      code = mnodeDropNormalTableColumn(pMsg->pDb, pTable, pAlter->schema[0].name);
S
[TD-17]  
slguan 已提交
2255 2256
    } else {
    }
S
slguan 已提交
2257 2258
  }

2259
  return code;
S
[TD-17]  
slguan 已提交
2260
}
2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372

static int32_t mnodeGetStreamMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
  SDbObj *pDb = mnodeGetDb(pShow->db);
  if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED;

  int32_t cols = 0;
  SSchema *pSchema = pMeta->schema;

  pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "table_name");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 8;
  pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
  strcpy(pSchema[cols].name, "created_time");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = 2;
  pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
  strcpy(pSchema[cols].name, "columns");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pShow->bytes[cols] = TSDB_MAX_SQL_SHOW_LEN + VARSTR_HEADER_SIZE;
  pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
  strcpy(pSchema[cols].name, "sql");
  pSchema[cols].bytes = htons(pShow->bytes[cols]);
  cols++;

  pMeta->numOfColumns = htons(cols);
  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];
  }

  pShow->numOfRows = pDb->numOfTables;
  pShow->rowSize   = pShow->offset[cols - 1] + pShow->bytes[cols - 1];

  mnodeDecDbRef(pDb);
  return 0;
}

static int32_t mnodeRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
  SDbObj *pDb = mnodeGetDb(pShow->db);
  if (pDb == NULL) return 0;

  
  int32_t numOfRows  = 0;
  SChildTableObj *pTable = NULL;
  SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;

  char prefix[64] = {0};
  strcpy(prefix, pDb->name);
  strcat(prefix, TS_PATH_DELIMITER);
  int32_t prefixLen = strlen(prefix);

  while (numOfRows < rows) {
    pShow->pIter = mnodeGetNextChildTable(pShow->pIter, &pTable);
    if (pTable == NULL) break;
    
    // not belong to current db
    if (strncmp(pTable->info.tableId, prefix, prefixLen) || pTable->info.type != TSDB_STREAM_TABLE) {
      mnodeDecTableRef(pTable);
      continue;
    }

    char tableName[TSDB_TABLE_NAME_LEN + 1] = {0};
    
    // pattern compare for table name
    mnodeExtractTableName(pTable->info.tableId, tableName);

    if (pShow->payloadLen > 0 && patternMatch(pShow->payload, tableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) {
      mnodeDecTableRef(pTable);
      continue;
    }

    int32_t cols = 0;

    char *pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;

    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, tableName, TSDB_TABLE_NAME_LEN);
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int64_t *) pWrite = pTable->createdTime;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    *(int16_t *)pWrite = pTable->numOfColumns;
    cols++;

    pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
    STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, TSDB_MAX_SQL_SHOW_LEN);    
    cols++;

    numOfRows++;
    mnodeDecTableRef(pTable);
  }

  pShow->numOfReads += numOfRows;
  const int32_t NUM_OF_COLUMNS = 4;

  mnodeVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
  mnodeDecDbRef(pDb);

  return numOfRows;
}