metaTable.c 46.9 KB
Newer Older
H
more  
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * 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/>.
H
refact  
Hongze Cheng 已提交
14 15
 */

H
Hongze Cheng 已提交
16
#include "meta.h"
H
refact  
Hongze Cheng 已提交
17

dengyihao's avatar
dengyihao 已提交
18 19 20 21 22 23 24 25 26 27 28 29
static int  metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
static int  metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
static int  metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME);
static int  metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME);
static int  metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME);
static int  metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME);
static int  metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME);
static int  metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME);
static int  metaUpdateSuidIdx(SMeta *pMeta, const SMetaEntry *pME);
static int  metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry);
static int  metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type);
static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey);
dengyihao's avatar
dengyihao 已提交
30 31 32 33 34
// opt ins_tables query
static int metaUpdateCtimeIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaDeleteCtimeIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
H
Hongze Cheng 已提交
35

H
Hongze Cheng 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48
static void metaGetEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) {
  pInfo->uid = pEntry->uid;
  pInfo->version = pEntry->version;
  if (pEntry->type == TSDB_SUPER_TABLE) {
    pInfo->suid = pEntry->uid;
    pInfo->skmVer = pEntry->stbEntry.schemaRow.version;
  } else if (pEntry->type == TSDB_CHILD_TABLE) {
    pInfo->suid = pEntry->ctbEntry.suid;
    pInfo->skmVer = 0;
  } else if (pEntry->type == TSDB_NORMAL_TABLE) {
    pInfo->suid = 0;
    pInfo->skmVer = pEntry->ntbEntry.schemaRow.version;
  } else {
49
    metaError("meta/table: invalide table type: %" PRId8 " get entry info failed.", pEntry->type);
H
Hongze Cheng 已提交
50 51 52
  }
}

dengyihao's avatar
dengyihao 已提交
53
static int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
D
dapan1121 已提交
54 55
  pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
  if (NULL == pMetaRsp->pSchemas) {
56
    terrno = TSDB_CODE_OUT_OF_MEMORY;
D
dapan1121 已提交
57 58 59
    return -1;
  }

M
Minglei Jin 已提交
60
  tstrncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
D
dapan1121 已提交
61 62 63 64 65 66 67 68 69 70
  pMetaRsp->numOfColumns = pSchema->nCols;
  pMetaRsp->tableType = TSDB_NORMAL_TABLE;
  pMetaRsp->sversion = pSchema->version;
  pMetaRsp->tuid = uid;

  memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));

  return 0;
}

dengyihao's avatar
dengyihao 已提交
71 72 73 74 75
static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
#ifdef USE_INVERTED_INDEX
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
    return -1;
  }
H
Hongze Cheng 已提交
76
  void       *data = pCtbEntry->ctbEntry.pTags;
dengyihao's avatar
dengyihao 已提交
77 78 79 80 81 82 83 84 85 86 87
  const char *tagName = pSchema->name;

  tb_uid_t    suid = pCtbEntry->ctbEntry.suid;
  tb_uid_t    tuid = pCtbEntry->uid;
  const void *pTagData = pCtbEntry->ctbEntry.pTags;
  int32_t     nTagData = 0;

  SArray *pTagVals = NULL;
  if (tTagToValArray((const STag *)data, &pTagVals) != 0) {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
88

dengyihao's avatar
dengyihao 已提交
89 90 91 92 93
  SIndexMultiTerm *terms = indexMultiTermCreate();
  int16_t          nCols = taosArrayGetSize(pTagVals);
  for (int i = 0; i < nCols; i++) {
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
    char     type = pTagVal->type;
dengyihao's avatar
dengyihao 已提交
94

H
Hongze Cheng 已提交
95
    char   *key = pTagVal->pKey;
dengyihao's avatar
dengyihao 已提交
96
    int32_t nKey = strlen(key);
dengyihao's avatar
dengyihao 已提交
97 98 99

    SIndexTerm *term = NULL;
    if (type == TSDB_DATA_TYPE_NULL) {
dengyihao's avatar
dengyihao 已提交
100
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
dengyihao's avatar
dengyihao 已提交
101 102
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
      if (pTagVal->nData > 0) {
H
Hongze Cheng 已提交
103
        char   *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
dengyihao's avatar
dengyihao 已提交
104 105
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE);
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
dengyihao's avatar
dengyihao 已提交
106
        type = TSDB_DATA_TYPE_VARCHAR;
dengyihao's avatar
dengyihao 已提交
107
        term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, val, len);
wmmhello's avatar
wmmhello 已提交
108
        taosMemoryFree(val);
dengyihao's avatar
dengyihao 已提交
109
      } else if (pTagVal->nData == 0) {
dengyihao's avatar
dengyihao 已提交
110
        term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, pTagVal->pData, 0);
dengyihao's avatar
dengyihao 已提交
111 112 113
      }
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
      double val = *(double *)(&pTagVal->i64);
dengyihao's avatar
dengyihao 已提交
114
      int    len = sizeof(val);
dengyihao's avatar
dengyihao 已提交
115 116 117
      term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
    } else if (type == TSDB_DATA_TYPE_BOOL) {
      int val = *(int *)(&pTagVal->i64);
dengyihao's avatar
dengyihao 已提交
118
      int len = sizeof(val);
dengyihao's avatar
dengyihao 已提交
119
      term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_BOOL, key, nKey, (const char *)&val, len);
dengyihao's avatar
dengyihao 已提交
120
    }
dengyihao's avatar
dengyihao 已提交
121
    if (term != NULL) {
dengyihao's avatar
dengyihao 已提交
122 123 124
      indexMultiTermAdd(terms, term);
    }
  }
dengyihao's avatar
dengyihao 已提交
125
  indexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
dengyihao's avatar
dengyihao 已提交
126
  indexMultiTermDestroy(terms);
dengyihao's avatar
dengyihao 已提交
127 128

  taosArrayDestroy(pTagVals);
dengyihao's avatar
dengyihao 已提交
129
#endif
dengyihao's avatar
dengyihao 已提交
130
  return 0;
dengyihao's avatar
dengyihao 已提交
131
}
132 133 134 135 136
int metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
#ifdef USE_INVERTED_INDEX
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
    return -1;
  }
137
  void       *data = pCtbEntry->ctbEntry.pTags;
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
  const char *tagName = pSchema->name;

  tb_uid_t    suid = pCtbEntry->ctbEntry.suid;
  tb_uid_t    tuid = pCtbEntry->uid;
  const void *pTagData = pCtbEntry->ctbEntry.pTags;
  int32_t     nTagData = 0;

  SArray *pTagVals = NULL;
  if (tTagToValArray((const STag *)data, &pTagVals) != 0) {
    return -1;
  }

  SIndexMultiTerm *terms = indexMultiTermCreate();
  int16_t          nCols = taosArrayGetSize(pTagVals);
  for (int i = 0; i < nCols; i++) {
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
    char     type = pTagVal->type;

156
    char   *key = pTagVal->pKey;
157 158 159 160 161 162 163
    int32_t nKey = strlen(key);

    SIndexTerm *term = NULL;
    if (type == TSDB_DATA_TYPE_NULL) {
      term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, NULL, 0);
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
      if (pTagVal->nData > 0) {
164
        char   *val = taosMemoryCalloc(1, pTagVal->nData + VARSTR_HEADER_SIZE);
165 166 167 168
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE);
        memcpy(val, (uint16_t *)&len, VARSTR_HEADER_SIZE);
        type = TSDB_DATA_TYPE_VARCHAR;
        term = indexTermCreate(suid, DEL_VALUE, type, key, nKey, val, len);
dengyihao's avatar
dengyihao 已提交
169
        taosMemoryFree(val);
170 171 172 173 174 175 176 177 178 179 180
      } else if (pTagVal->nData == 0) {
        term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_VARCHAR, key, nKey, pTagVal->pData, 0);
      }
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
      double val = *(double *)(&pTagVal->i64);
      int    len = sizeof(val);
      term = indexTermCreate(suid, DEL_VALUE, type, key, nKey, (const char *)&val, len);
    } else if (type == TSDB_DATA_TYPE_BOOL) {
      int val = *(int *)(&pTagVal->i64);
      int len = sizeof(val);
      term = indexTermCreate(suid, DEL_VALUE, TSDB_DATA_TYPE_BOOL, key, nKey, (const char *)&val, len);
dengyihao's avatar
dengyihao 已提交
181
    }
dengyihao's avatar
dengyihao 已提交
182
    if (term != NULL) {
dengyihao's avatar
dengyihao 已提交
183 184 185
      indexMultiTermAdd(terms, term);
    }
  }
dengyihao's avatar
dengyihao 已提交
186
  indexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
dengyihao's avatar
dengyihao 已提交
187
  indexMultiTermDestroy(terms);
dengyihao's avatar
dengyihao 已提交
188
  taosArrayDestroy(pTagVals);
dengyihao's avatar
dengyihao 已提交
189
#endif
dengyihao's avatar
dengyihao 已提交
190
  return 0;
dengyihao's avatar
dengyihao 已提交
191 192
}

H
Hongze Cheng 已提交
193
int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
H
Hongze Cheng 已提交
194
  SMetaEntry  me = {0};
H
Hongze Cheng 已提交
195 196 197 198
  int         kLen = 0;
  int         vLen = 0;
  const void *pKey = NULL;
  const void *pVal = NULL;
H
Hongze Cheng 已提交
199
  void       *pBuf = NULL;
H
Hongze Cheng 已提交
200
  int32_t     szBuf = 0;
H
Hongze Cheng 已提交
201
  void       *p = NULL;
H
Hongze Cheng 已提交
202 203

  // validate req
204 205
  void *pData = NULL;
  int   nData = 0;
M
Minglei Jin 已提交
206
  if (tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData) == 0) {
207 208 209
    tb_uid_t uid = *(tb_uid_t *)pData;
    tdbFree(pData);
    SMetaInfo info;
210
    metaGetInfo(pMeta, uid, &info, NULL);
211
    if (info.uid == info.suid) {
212 213
      return 0;
    } else {
214
      terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
215 216
      return -1;
    }
H
Hongze Cheng 已提交
217
  }
H
Hongze Cheng 已提交
218 219

  // set structs
H
Hongze Cheng 已提交
220
  me.version = version;
H
Hongze Cheng 已提交
221 222 223
  me.type = TSDB_SUPER_TABLE;
  me.uid = pReq->suid;
  me.name = pReq->name;
224
  me.stbEntry.schemaRow = pReq->schemaRow;
H
Hongze Cheng 已提交
225
  me.stbEntry.schemaTag = pReq->schemaTag;
C
Cary Xu 已提交
226 227 228 229
  if (pReq->rollup) {
    TABLE_SET_ROLLUP(me.flags);
    me.stbEntry.rsmaParam = pReq->rsmaParam;
  }
H
Hongze Cheng 已提交
230

H
Hongze Cheng 已提交
231
  if (metaHandleEntry(pMeta, &me) < 0) goto _err;
H
Hongze Cheng 已提交
232

233 234
  ++pMeta->pVnode->config.vndStats.numOfSTables;

S
Shengliang Guan 已提交
235
  metaDebug("vgId:%d, stb:%s is created, suid:%" PRId64, TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
H
Hongze Cheng 已提交
236 237 238 239

  return 0;

_err:
M
Minglei Jin 已提交
240 241
  metaError("vgId:%d, failed to create stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid,
            tstrerror(terrno));
H
Hongze Cheng 已提交
242 243 244
  return -1;
}

245
int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq, SArray *tbUidList) {
H
Hongze Cheng 已提交
246 247 248 249 250 251 252 253 254 255
  void *pKey = NULL;
  int   nKey = 0;
  void *pData = NULL;
  int   nData = 0;
  int   c = 0;
  int   rc = 0;

  // check if super table exists
  rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
  if (rc < 0 || *(tb_uid_t *)pData != pReq->suid) {
H
Hongze Cheng 已提交
256
    tdbFree(pData);
257
    terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
H
Hongze Cheng 已提交
258
    return -1;
H
Hongze Cheng 已提交
259 260
  }

H
Hongze Cheng 已提交
261
  // drop all child tables
262
  TBC *pCtbIdxc = NULL;
H
Hongze Cheng 已提交
263

264
  tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL);
H
Hongze Cheng 已提交
265 266
  rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = pReq->suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
  if (rc < 0) {
H
Hongze Cheng 已提交
267
    tdbTbcClose(pCtbIdxc);
H
Hongze Cheng 已提交
268 269
    metaWLock(pMeta);
    goto _drop_super_table;
H
Hongze Cheng 已提交
270 271 272
  }

  for (;;) {
H
Hongze Cheng 已提交
273 274
    rc = tdbTbcNext(pCtbIdxc, &pKey, &nKey, NULL, NULL);
    if (rc < 0) break;
H
Hongze Cheng 已提交
275

H
Hongze Cheng 已提交
276 277 278 279 280
    if (((SCtbIdxKey *)pKey)->suid < pReq->suid) {
      continue;
    } else if (((SCtbIdxKey *)pKey)->suid > pReq->suid) {
      break;
    }
H
Hongze Cheng 已提交
281

282
    taosArrayPush(tbUidList, &(((SCtbIdxKey *)pKey)->uid));
H
Hongze Cheng 已提交
283 284 285 286 287
  }

  tdbTbcClose(pCtbIdxc);

  metaWLock(pMeta);
H
Hongze Cheng 已提交
288

289 290
  for (int32_t iChild = 0; iChild < taosArrayGetSize(tbUidList); iChild++) {
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(tbUidList, iChild);
H
Hongze Cheng 已提交
291
    metaDropTableByUid(pMeta, uid, NULL);
H
Hongze Cheng 已提交
292 293
  }

H
Hongze Cheng 已提交
294 295 296
  // drop super table
_drop_super_table:
  tdbTbGet(pMeta->pUidIdx, &pReq->suid, sizeof(tb_uid_t), &pData, &nData);
H
Hongze Cheng 已提交
297
  tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = ((SUidIdxVal *)pData)[0].version, .uid = pReq->suid},
298 299 300 301
              sizeof(STbDbKey), pMeta->txn);
  tdbTbDelete(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, pMeta->txn);
  tdbTbDelete(pMeta->pUidIdx, &pReq->suid, sizeof(tb_uid_t), pMeta->txn);
  tdbTbDelete(pMeta->pSuidIdx, &pReq->suid, sizeof(tb_uid_t), pMeta->txn);
H
Hongze Cheng 已提交
302 303 304

  metaULock(pMeta);

H
Hongze Cheng 已提交
305
_exit:
H
Hongze Cheng 已提交
306 307
  tdbFree(pKey);
  tdbFree(pData);
C
Cary Xu 已提交
308
  metaDebug("vgId:%d, super table %s uid:%" PRId64 " is dropped", TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
H
Hongze Cheng 已提交
309 310 311
  return 0;
}

H
Hongze Cheng 已提交
312 313 314
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
  SMetaEntry  oStbEntry = {0};
  SMetaEntry  nStbEntry = {0};
H
Hongze Cheng 已提交
315 316
  TBC        *pUidIdxc = NULL;
  TBC        *pTbDbc = NULL;
H
Hongze Cheng 已提交
317 318 319 320 321
  const void *pData;
  int         nData;
  int64_t     oversion;
  SDecoder    dc = {0};
  int32_t     ret;
322
  int32_t     c = -2;
H
Hongze Cheng 已提交
323

324
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
H
Hongze Cheng 已提交
325
  ret = tdbTbcMoveTo(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &c);
H
Hongze Cheng 已提交
326
  if (ret < 0 || c) {
327 328 329
    tdbTbcClose(pUidIdxc);

    terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
H
Hongze Cheng 已提交
330 331 332
    return -1;
  }

H
Hongze Cheng 已提交
333
  ret = tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
334
  if (ret < 0) {
M
Minglei Jin 已提交
335 336
    tdbTbcClose(pUidIdxc);

M
Minglei Jin 已提交
337
    terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
H
Hongze Cheng 已提交
338 339 340
    return -1;
  }

H
Hongze Cheng 已提交
341
  oversion = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
342

343
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
H
Hongze Cheng 已提交
344
  ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c);
345
  if (!(ret == 0 && c == 0)) {
346 347 348 349
    tdbTbcClose(pUidIdxc);
    tdbTbcClose(pTbDbc);

    terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
350 351 352
    metaError("meta/table: invalide ret: %" PRId32 " or c: %" PRId32 "alter stb failed.", ret, c);
    return -1;
  }
H
Hongze Cheng 已提交
353

H
Hongze Cheng 已提交
354
  ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
355
  if (ret < 0) {
356
    tdbTbcClose(pUidIdxc);
357 358 359 360 361
    tdbTbcClose(pTbDbc);

    terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
    return -1;
  }
H
Hongze Cheng 已提交
362

H
Hongze Cheng 已提交
363 364 365
  oStbEntry.pBuf = taosMemoryMalloc(nData);
  memcpy(oStbEntry.pBuf, pData, nData);
  tDecoderInit(&dc, oStbEntry.pBuf, nData);
H
Hongze Cheng 已提交
366 367 368 369 370 371
  metaDecodeEntry(&dc, &oStbEntry);

  nStbEntry.version = version;
  nStbEntry.type = TSDB_SUPER_TABLE;
  nStbEntry.uid = pReq->suid;
  nStbEntry.name = pReq->name;
372
  nStbEntry.stbEntry.schemaRow = pReq->schemaRow;
H
Hongze Cheng 已提交
373 374 375 376
  nStbEntry.stbEntry.schemaTag = pReq->schemaTag;

  metaWLock(pMeta);
  // compare two entry
377 378
  if (oStbEntry.stbEntry.schemaRow.version != pReq->schemaRow.version) {
    metaSaveToSkmDb(pMeta, &nStbEntry);
H
Hongze Cheng 已提交
379 380 381 382 383 384
  }

  // update table.db
  metaSaveToTbDb(pMeta, &nStbEntry);

  // update uid index
H
Hongze Cheng 已提交
385
  metaUpdateUidIdx(pMeta, &nStbEntry);
H
Hongze Cheng 已提交
386

387
  // metaStatsCacheDrop(pMeta, nStbEntry.uid);
388

H
Hongze Cheng 已提交
389
  metaULock(pMeta);
390 391

  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
H
Hongze Cheng 已提交
392
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
393 394
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
395 396 397
  return 0;
}

398
int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **pMetaRsp) {
H
Hongze Cheng 已提交
399 400
  SMetaEntry  me = {0};
  SMetaReader mr = {0};
H
Hongze Cheng 已提交
401 402 403 404 405

  // validate message
  if (pReq->type != TSDB_CHILD_TABLE && pReq->type != TSDB_NORMAL_TABLE) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto _err;
H
more  
Hongze Cheng 已提交
406 407
  }

408
  if (pReq->type == TSDB_CHILD_TABLE) {
409
    tb_uid_t suid = metaGetTableEntryUidByName(pMeta, pReq->ctb.stbName);
410 411 412 413 414 415
    if (suid != pReq->ctb.suid) {
      terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
      return -1;
    }
  }

H
Hongze Cheng 已提交
416
  // validate req
H
Hongze Cheng 已提交
417
  metaReaderInit(&mr, pMeta, 0);
H
Hongze Cheng 已提交
418
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
419 420 421 422 423
    if (pReq->type == TSDB_CHILD_TABLE && pReq->ctb.suid != mr.me.ctbEntry.suid) {
      terrno = TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
      metaReaderClear(&mr);
      return -1;
    }
H
Hongze Cheng 已提交
424 425 426 427
    pReq->uid = mr.me.uid;
    if (pReq->type == TSDB_CHILD_TABLE) {
      pReq->ctb.suid = mr.me.ctbEntry.suid;
    }
H
Hongze Cheng 已提交
428 429 430
    terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
    metaReaderClear(&mr);
    return -1;
C
Cary Xu 已提交
431 432
  } else if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
    terrno = TSDB_CODE_SUCCESS;
H
Hongze Cheng 已提交
433
  }
H
Hongze Cheng 已提交
434
  metaReaderClear(&mr);
H
Hongze Cheng 已提交
435 436

  // build SMetaEntry
H
Hongze Cheng 已提交
437
  me.version = version;
H
Hongze Cheng 已提交
438 439 440 441 442 443
  me.type = pReq->type;
  me.uid = pReq->uid;
  me.name = pReq->name;
  if (me.type == TSDB_CHILD_TABLE) {
    me.ctbEntry.ctime = pReq->ctime;
    me.ctbEntry.ttlDays = pReq->ttl;
wmmhello's avatar
wmmhello 已提交
444
    me.ctbEntry.commentLen = pReq->commentLen;
wmmhello's avatar
wmmhello 已提交
445
    me.ctbEntry.comment = pReq->comment;
H
Hongze Cheng 已提交
446 447
    me.ctbEntry.suid = pReq->ctb.suid;
    me.ctbEntry.pTags = pReq->ctb.pTag;
448

wmmhello's avatar
wmmhello 已提交
449
#ifdef TAG_FILTER_DEBUG
dengyihao's avatar
dengyihao 已提交
450 451
    SArray *pTagVals = NULL;
    int32_t code = tTagToValArray((STag *)pReq->ctb.pTag, &pTagVals);
wmmhello's avatar
wmmhello 已提交
452
    for (int i = 0; i < taosArrayGetSize(pTagVals); i++) {
dengyihao's avatar
dengyihao 已提交
453
      STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
wmmhello's avatar
wmmhello 已提交
454 455

      if (IS_VAR_DATA_TYPE(pTagVal->type)) {
dengyihao's avatar
dengyihao 已提交
456
        char *buf = taosMemoryCalloc(pTagVal->nData + 1, 1);
wmmhello's avatar
wmmhello 已提交
457
        memcpy(buf, pTagVal->pData, pTagVal->nData);
dengyihao's avatar
dengyihao 已提交
458 459
        metaDebug("metaTag table:%s varchar index:%d cid:%d type:%d value:%s", pReq->name, i, pTagVal->cid,
                  pTagVal->type, buf);
wmmhello's avatar
wmmhello 已提交
460 461 462 463
        taosMemoryFree(buf);
      } else {
        double val = 0;
        GET_TYPED_DATA(val, double, pTagVal->type, &pTagVal->i64);
dengyihao's avatar
dengyihao 已提交
464 465
        metaDebug("metaTag table:%s number index:%d cid:%d type:%d value:%f", pReq->name, i, pTagVal->cid,
                  pTagVal->type, val);
wmmhello's avatar
wmmhello 已提交
466 467
      }
    }
wmmhello's avatar
wmmhello 已提交
468
#endif
wmmhello's avatar
wmmhello 已提交
469

470
    ++pMeta->pVnode->config.vndStats.numOfCTables;
471 472 473

    metaWLock(pMeta);
    metaUpdateStbStats(pMeta, me.ctbEntry.suid, 1);
474
    metaUidCacheClear(pMeta, me.ctbEntry.suid);
475
    metaULock(pMeta);
H
Hongze Cheng 已提交
476 477 478
  } else {
    me.ntbEntry.ctime = pReq->ctime;
    me.ntbEntry.ttlDays = pReq->ttl;
wmmhello's avatar
wmmhello 已提交
479
    me.ntbEntry.commentLen = pReq->commentLen;
wmmhello's avatar
wmmhello 已提交
480
    me.ntbEntry.comment = pReq->comment;
481 482
    me.ntbEntry.schemaRow = pReq->ntb.schemaRow;
    me.ntbEntry.ncid = me.ntbEntry.schemaRow.pSchema[me.ntbEntry.schemaRow.nCols - 1].colId + 1;
483 484

    ++pMeta->pVnode->config.vndStats.numOfNTables;
485
    pMeta->pVnode->config.vndStats.numOfNTimeSeries += me.ntbEntry.schemaRow.nCols - 1;
H
more  
Hongze Cheng 已提交
486 487
  }

H
Hongze Cheng 已提交
488
  if (metaHandleEntry(pMeta, &me) < 0) goto _err;
H
Hongze Cheng 已提交
489

490 491 492 493 494 495 496 497 498 499
  if (pMetaRsp) {
    *pMetaRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));

    if (*pMetaRsp) {
      if (me.type == TSDB_CHILD_TABLE) {
        (*pMetaRsp)->tableType = TSDB_CHILD_TABLE;
        (*pMetaRsp)->tuid = pReq->uid;
        (*pMetaRsp)->suid = pReq->ctb.suid;
        strcpy((*pMetaRsp)->tbName, pReq->name);
      } else {
500
        metaUpdateMetaRsp(pReq->uid, pReq->name, &pReq->ntb.schemaRow, *pMetaRsp);
501 502 503 504
      }
    }
  }

S
Shengliang Guan 已提交
505
  metaDebug("vgId:%d, table:%s uid %" PRId64 " is created, type:%" PRId8, TD_VID(pMeta->pVnode), pReq->name, pReq->uid,
H
Hongze Cheng 已提交
506
            pReq->type);
H
refact  
Hongze Cheng 已提交
507
  return 0;
H
Hongze Cheng 已提交
508 509

_err:
S
Shengliang Guan 已提交
510
  metaError("vgId:%d, failed to create table:%s type:%s since %s", TD_VID(pMeta->pVnode), pReq->name,
H
Hongze Cheng 已提交
511 512
            pReq->type == TSDB_CHILD_TABLE ? "child table" : "normal table", tstrerror(terrno));
  return -1;
H
refact  
Hongze Cheng 已提交
513 514
}

515
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids, tb_uid_t *tbUid) {
H
Hongze Cheng 已提交
516
  void    *pData = NULL;
H
Hongze Cheng 已提交
517 518 519 520
  int      nData = 0;
  int      rc = 0;
  tb_uid_t uid;
  int      type;
H
more  
Hongze Cheng 已提交
521

H
Hongze Cheng 已提交
522 523
  rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
  if (rc < 0) {
524
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
H
more  
Hongze Cheng 已提交
525 526
    return -1;
  }
H
Hongze Cheng 已提交
527 528
  uid = *(tb_uid_t *)pData;

H
Hongze Cheng 已提交
529 530 531
  metaWLock(pMeta);
  metaDropTableByUid(pMeta, uid, &type);
  metaULock(pMeta);
H
Hongze Cheng 已提交
532

533
  if ((type == TSDB_CHILD_TABLE || type == TSDB_NORMAL_TABLE) && tbUids) {
H
Hongze Cheng 已提交
534
    taosArrayPush(tbUids, &uid);
H
Hongze Cheng 已提交
535
  }
H
Hongze Cheng 已提交
536

537 538 539 540
  if ((type == TSDB_CHILD_TABLE) && tbUid) {
    *tbUid = uid;
  }

H
Hongze Cheng 已提交
541 542 543
  tdbFree(pData);
  return 0;
}
H
Hongze Cheng 已提交
544

545 546
int metaTtlDropTable(SMeta *pMeta, int64_t ttl, SArray *tbUids) {
  int ret = metaTtlSmaller(pMeta, ttl, tbUids);
H
Hongze Cheng 已提交
547
  if (ret != 0) {
548 549
    return ret;
  }
550
  if (taosArrayGetSize(tbUids) == 0) {
551 552 553 554
    return 0;
  }

  metaWLock(pMeta);
555 556 557
  for (int i = 0; i < taosArrayGetSize(tbUids); ++i) {
    tb_uid_t *uid = (tb_uid_t *)taosArrayGet(tbUids, i);
    metaDropTableByUid(pMeta, *uid, NULL);
H
Hongze Cheng 已提交
558
    metaDebug("ttl drop table:%" PRId64, *uid);
559 560 561 562 563
  }
  metaULock(pMeta);
  return 0;
}

H
Hongze Cheng 已提交
564
static void metaBuildTtlIdxKey(STtlIdxKey *ttlKey, const SMetaEntry *pME) {
M
Minglei Jin 已提交
565 566
  int64_t ttlDays = 0;
  int64_t ctime = 0;
567 568 569 570 571 572 573
  if (pME->type == TSDB_CHILD_TABLE) {
    ctime = pME->ctbEntry.ctime;
    ttlDays = pME->ctbEntry.ttlDays;
  } else if (pME->type == TSDB_NORMAL_TABLE) {
    ctime = pME->ntbEntry.ctime;
    ttlDays = pME->ntbEntry.ttlDays;
  } else {
574 575
    metaError("meta/table: invalide table type: %" PRId8 " build ttl idx key failed.", pME->type);
    return;
576 577 578 579
  }

  if (ttlDays <= 0) return;

wmmhello's avatar
wmmhello 已提交
580
  ttlKey->dtime = ctime / 1000 + ttlDays * tsTtlUnit;
581 582
  ttlKey->uid = pME->uid;
}
dengyihao's avatar
dengyihao 已提交
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
static int metaBuildCtimeIdxKey(SCtimeIdxKey *ctimeKey, const SMetaEntry *pME) {
  int64_t ctime;
  if (pME->type == TSDB_CHILD_TABLE) {
    ctime = pME->ctbEntry.ctime;
  } else if (pME->type == TSDB_NORMAL_TABLE) {
    ctime = pME->ntbEntry.ctime;
  } else {
    return -1;
  }

  ctimeKey->ctime = ctime;
  ctimeKey->uid = pME->uid;
  return 0;
}

static int metaBuildNColIdxKey(SNcolIdxKey *ncolKey, const SMetaEntry *pME) {
dengyihao's avatar
dengyihao 已提交
599 600 601 602 603 604
  if (pME->type == TSDB_NORMAL_TABLE) {
    ncolKey->ncol = pME->ntbEntry.schemaRow.nCols;
    ncolKey->uid = pME->uid;
  } else {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
605 606
  return 0;
}
607 608 609 610

static int metaDeleteTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
  STtlIdxKey ttlKey = {0};
  metaBuildTtlIdxKey(&ttlKey, pME);
H
Hongze Cheng 已提交
611
  if (ttlKey.dtime == 0) return 0;
612
  return tdbTbDelete(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), pMeta->txn);
613 614
}

H
Hongze Cheng 已提交
615
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
H
Hongze Cheng 已提交
616
  void      *pData = NULL;
H
Hongze Cheng 已提交
617 618 619 620 621 622
  int        nData = 0;
  int        rc = 0;
  SMetaEntry e = {0};
  SDecoder   dc = {0};

  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
623 624 625
  if (rc < 0) {
    return -1;
  }
H
Hongze Cheng 已提交
626
  int64_t version = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
627 628 629 630

  tdbTbGet(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), &pData, &nData);

  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
631 632 633 634 635
  rc = metaDecodeEntry(&dc, &e);
  if (rc < 0) {
    tDecoderClear(&dc);
    return -1;
  }
H
Hongze Cheng 已提交
636 637 638

  if (type) *type = e.type;

639 640 641 642 643
  if (e.type == TSDB_CHILD_TABLE) {
    void *tData = NULL;
    int   tLen = 0;

    if (tdbTbGet(pMeta->pUidIdx, &e.ctbEntry.suid, sizeof(tb_uid_t), &tData, &tLen) == 0) {
H
Hongze Cheng 已提交
644
      version = ((SUidIdxVal *)tData)[0].version;
645 646 647 648 649 650 651 652 653 654
      STbDbKey tbDbKey = {.uid = e.ctbEntry.suid, .version = version};
      if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &tData, &tLen) == 0) {
        SDecoder   tdc = {0};
        SMetaEntry stbEntry = {0};

        tDecoderInit(&tdc, tData, tLen);
        metaDecodeEntry(&tdc, &stbEntry);
        const SSchema *pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
        if (pTagColumn->type == TSDB_DATA_TYPE_JSON) {
          metaDelJsonVarFromIdx(pMeta, &e, pTagColumn);
dengyihao's avatar
dengyihao 已提交
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673
        } else {
          STagIdxKey *pTagIdxKey = NULL;
          int32_t     nTagIdxKey;

          const void *pTagData = NULL;
          int32_t     nTagData = 0;

          STagVal tagVal = {.cid = pTagColumn->colId};
          tTagGet((const STag *)e.ctbEntry.pTags, &tagVal);
          if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
            pTagData = tagVal.pData;
            nTagData = (int32_t)tagVal.nData;
          } else {
            pTagData = &(tagVal.i64);
            nTagData = tDataTypes[pTagColumn->type].bytes;
          }

          if (metaCreateTagIdxKey(e.ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type, uid,
                                  &pTagIdxKey, &nTagIdxKey) == 0) {
674
            tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
dengyihao's avatar
dengyihao 已提交
675 676
          }
          metaDestroyTagIdxKey(pTagIdxKey);
677 678 679 680 681 682 683
        }
        tDecoderClear(&tdc);
      }
      tdbFree(tData);
    }
  }

684 685 686
  tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = version, .uid = uid}, sizeof(STbDbKey), pMeta->txn);
  tdbTbDelete(pMeta->pNameIdx, e.name, strlen(e.name) + 1, pMeta->txn);
  tdbTbDelete(pMeta->pUidIdx, &uid, sizeof(uid), pMeta->txn);
687

dengyihao's avatar
dengyihao 已提交
688 689 690
  if (e.type == TSDB_CHILD_TABLE || e.type == TSDB_NORMAL_TABLE) metaDeleteCtimeIdx(pMeta, &e);
  if (e.type == TSDB_NORMAL_TABLE) metaDeleteNcolIdx(pMeta, &e);

H
Hongze Cheng 已提交
691
  if (e.type != TSDB_SUPER_TABLE) metaDeleteTtlIdx(pMeta, &e);
C
Cary Xu 已提交
692

H
Hongze Cheng 已提交
693
  if (e.type == TSDB_CHILD_TABLE) {
694
    tdbTbDelete(pMeta->pCtbIdx, &(SCtbIdxKey){.suid = e.ctbEntry.suid, .uid = uid}, sizeof(SCtbIdxKey), pMeta->txn);
695 696

    --pMeta->pVnode->config.vndStats.numOfCTables;
697 698

    metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1);
699
    metaUidCacheClear(pMeta, e.ctbEntry.suid);
H
Hongze Cheng 已提交
700 701
  } else if (e.type == TSDB_NORMAL_TABLE) {
    // drop schema.db (todo)
702 703

    --pMeta->pVnode->config.vndStats.numOfNTables;
704
    pMeta->pVnode->config.vndStats.numOfNTimeSeries -= e.ntbEntry.schemaRow.nCols - 1;
H
Hongze Cheng 已提交
705
  } else if (e.type == TSDB_SUPER_TABLE) {
706
    tdbTbDelete(pMeta->pSuidIdx, &e.uid, sizeof(tb_uid_t), pMeta->txn);
H
Hongze Cheng 已提交
707
    // drop schema.db (todo)
708

709
    metaStatsCacheDrop(pMeta, uid);
710
    metaUidCacheClear(pMeta, uid);
711
    --pMeta->pVnode->config.vndStats.numOfSTables;
H
Hongze Cheng 已提交
712 713
  }

H
Hongze Cheng 已提交
714 715
  metaCacheDrop(pMeta, uid);

H
Hongze Cheng 已提交
716 717
  tDecoderClear(&dc);
  tdbFree(pData);
H
Hongze Cheng 已提交
718

H
refact  
Hongze Cheng 已提交
719 720
  return 0;
}
dengyihao's avatar
dengyihao 已提交
721 722 723 724 725 726
// opt ins_tables
int metaUpdateCtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtimeIdxKey ctimeKey = {0};
  if (metaBuildCtimeIdxKey(&ctimeKey, pME) < 0) {
    return 0;
  }
727 728
  metaTrace("vgId:%d, start to save version:%" PRId64 " uid:%" PRId64 " ctime:%" PRId64, TD_VID(pMeta->pVnode),
            pME->version, pME->uid, ctimeKey.ctime);
729

730
  return tdbTbInsert(pMeta->pCtimeIdx, &ctimeKey, sizeof(ctimeKey), NULL, 0, pMeta->txn);
dengyihao's avatar
dengyihao 已提交
731 732 733 734 735 736 737
}

int metaDeleteCtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtimeIdxKey ctimeKey = {0};
  if (metaBuildCtimeIdxKey(&ctimeKey, pME) < 0) {
    return 0;
  }
738
  return tdbTbDelete(pMeta->pCtimeIdx, &ctimeKey, sizeof(ctimeKey), pMeta->txn);
dengyihao's avatar
dengyihao 已提交
739 740 741 742 743 744
}
int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SNcolIdxKey ncolKey = {0};
  if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
    return 0;
  }
745
  return tdbTbInsert(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), NULL, 0, pMeta->txn);
dengyihao's avatar
dengyihao 已提交
746 747 748 749 750 751 752
}

int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SNcolIdxKey ncolKey = {0};
  if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
    return 0;
  }
753
  return tdbTbDelete(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), pMeta->txn);
dengyihao's avatar
dengyihao 已提交
754
}
H
Hongze Cheng 已提交
755

D
dapan1121 已提交
756
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq, STableMetaRsp *pMetaRsp) {
H
Hongze Cheng 已提交
757
  void           *pVal = NULL;
H
Hongze Cheng 已提交
758
  int             nVal = 0;
H
Hongze Cheng 已提交
759
  const void     *pData = NULL;
H
Hongze Cheng 已提交
760 761 762 763
  int             nData = 0;
  int             ret = 0;
  tb_uid_t        uid;
  int64_t         oversion;
H
Hongze Cheng 已提交
764
  SSchema        *pColumn = NULL;
H
Hongze Cheng 已提交
765 766 767 768
  SMetaEntry      entry = {0};
  SSchemaWrapper *pSchema;
  int             c;

H
Hongze Cheng 已提交
769
  if (pAlterTbReq->colName == NULL) {
H
Hongze Cheng 已提交
770 771 772 773
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
  }

H
Hongze Cheng 已提交
774
  // search name index
H
Hongze Cheng 已提交
775
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
H
Hongze Cheng 已提交
776
  if (ret < 0) {
777
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
778 779 780 781 782 783 784 785
    return -1;
  }

  uid = *(tb_uid_t *)pVal;
  tdbFree(pVal);
  pVal = NULL;

  // search uid index
H
Hongze Cheng 已提交
786
  TBC *pUidIdxc = NULL;
H
Hongze Cheng 已提交
787

788
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
H
Hongze Cheng 已提交
789
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
790
  if (c != 0) {
791
    tdbTbcClose(pUidIdxc);
792 793 794
    metaError("meta/table: invalide c: %" PRId32 " alt tb column failed.", c);
    return -1;
  }
H
Hongze Cheng 已提交
795

H
Hongze Cheng 已提交
796
  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
797
  oversion = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
798 799

  // search table.db
H
Hongze Cheng 已提交
800
  TBC *pTbDbc = NULL;
H
Hongze Cheng 已提交
801

802
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
H
Hongze Cheng 已提交
803
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
804
  if (c != 0) {
805 806
    tdbTbcClose(pUidIdxc);
    tdbTbcClose(pTbDbc);
807 808 809 810
    metaError("meta/table: invalide c: %" PRId32 " alt tb column failed.", c);
    return -1;
  }

H
Hongze Cheng 已提交
811
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
812 813 814

  // get table entry
  SDecoder dc = {0};
H
Hongze Cheng 已提交
815 816 817
  entry.pBuf = taosMemoryMalloc(nData);
  memcpy(entry.pBuf, pData, nData);
  tDecoderInit(&dc, entry.pBuf, nData);
H
Hongze Cheng 已提交
818
  ret = metaDecodeEntry(&dc, &entry);
819
  if (ret != 0) {
820 821
    tdbTbcClose(pUidIdxc);
    tdbTbcClose(pTbDbc);
822 823 824 825
    tDecoderClear(&dc);
    metaError("meta/table: invalide ret: %" PRId32 " alt tb column failed.", ret);
    return -1;
  }
H
Hongze Cheng 已提交
826 827 828 829 830 831

  if (entry.type != TSDB_NORMAL_TABLE) {
    terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
    goto _err;
  }
  // search the column to add/drop/update
832
  pSchema = &entry.ntbEntry.schemaRow;
H
Hongze Cheng 已提交
833

dengyihao's avatar
dengyihao 已提交
834 835 836 837
  // save old entry
  SMetaEntry oldEntry = {.type = TSDB_NORMAL_TABLE, .uid = entry.uid};
  oldEntry.ntbEntry.schemaRow.nCols = pSchema->nCols;

H
Hongze Cheng 已提交
838 839 840 841 842 843 844
  int32_t iCol = 0;
  for (;;) {
    pColumn = NULL;

    if (iCol >= pSchema->nCols) break;
    pColumn = &pSchema->pSchema[iCol];

845 846 847 848 849
    if (NULL == pAlterTbReq->colName) {
      metaError("meta/table: null pAlterTbReq->colName");
      return -1;
    }

H
Hongze Cheng 已提交
850 851 852 853 854
    if (strcmp(pColumn->name, pAlterTbReq->colName) == 0) break;
    iCol++;
  }

  entry.version = version;
H
Hongze Cheng 已提交
855 856
  int      tlen;
  SSchema *pNewSchema = NULL;
H
Hongze Cheng 已提交
857 858 859 860 861 862
  switch (pAlterTbReq->action) {
    case TSDB_ALTER_TABLE_ADD_COLUMN:
      if (pColumn) {
        terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
        goto _err;
      }
863
      pSchema->version++;
H
Hongze Cheng 已提交
864
      pSchema->nCols++;
H
Hongze Cheng 已提交
865 866 867
      pNewSchema = taosMemoryMalloc(sizeof(SSchema) * pSchema->nCols);
      memcpy(pNewSchema, pSchema->pSchema, sizeof(SSchema) * (pSchema->nCols - 1));
      pSchema->pSchema = pNewSchema;
868 869 870 871 872
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].bytes = pAlterTbReq->bytes;
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].type = pAlterTbReq->type;
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].flags = pAlterTbReq->flags;
      pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].colId = entry.ntbEntry.ncid++;
      strcpy(pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].name, pAlterTbReq->colName);
873 874

      ++pMeta->pVnode->config.vndStats.numOfNTimeSeries;
H
Hongze Cheng 已提交
875 876 877
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
      if (pColumn == NULL) {
878
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
879 880 881 882 883 884
        goto _err;
      }
      if (pColumn->colId == 0) {
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
        goto _err;
      }
L
Liu Jicong 已提交
885 886 887 888
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
        goto _err;
      }
889
      pSchema->version++;
H
Hongze Cheng 已提交
890 891 892 893
      tlen = (pSchema->nCols - iCol - 1) * sizeof(SSchema);
      if (tlen) {
        memmove(pColumn, pColumn + 1, tlen);
      }
H
Hongze Cheng 已提交
894
      pSchema->nCols--;
895 896

      --pMeta->pVnode->config.vndStats.numOfNTimeSeries;
H
Hongze Cheng 已提交
897 898 899
      break;
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
      if (pColumn == NULL) {
900
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
901 902
        goto _err;
      }
H
Hongze Cheng 已提交
903
      if (!IS_VAR_DATA_TYPE(pColumn->type) || pColumn->bytes > pAlterTbReq->colModBytes) {
H
Hongze Cheng 已提交
904 905 906
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
        goto _err;
      }
L
Liu Jicong 已提交
907 908 909 910
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
        goto _err;
      }
911
      pSchema->version++;
H
Hongze Cheng 已提交
912
      pColumn->bytes = pAlterTbReq->colModBytes;
H
Hongze Cheng 已提交
913 914
      break;
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
H
Hongze Cheng 已提交
915 916 917 918
      if (pAlterTbReq->colNewName == NULL) {
        terrno = TSDB_CODE_INVALID_MSG;
        goto _err;
      }
H
Hongze Cheng 已提交
919
      if (pColumn == NULL) {
920
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
921 922
        goto _err;
      }
L
Liu Jicong 已提交
923 924 925 926
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
        goto _err;
      }
927
      pSchema->version++;
H
Hongze Cheng 已提交
928 929 930 931 932 933
      strcpy(pColumn->name, pAlterTbReq->colNewName);
      break;
  }

  entry.version = version;

dengyihao's avatar
dengyihao 已提交
934 935 936
  metaDeleteNcolIdx(pMeta, &oldEntry);
  metaUpdateNcolIdx(pMeta, &entry);

H
Hongze Cheng 已提交
937 938 939 940 941 942
  // do actual write
  metaWLock(pMeta);

  // save to table db
  metaSaveToTbDb(pMeta, &entry);

H
Hongze Cheng 已提交
943
  metaUpdateUidIdx(pMeta, &entry);
H
Hongze Cheng 已提交
944 945 946 947 948

  metaSaveToSkmDb(pMeta, &entry);

  metaULock(pMeta);

D
dapan1121 已提交
949 950
  metaUpdateMetaRsp(uid, pAlterTbReq->tbName, pSchema, pMetaRsp);

wmmhello's avatar
wmmhello 已提交
951
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
H
Hongze Cheng 已提交
952
  if (pNewSchema) taosMemoryFree(pNewSchema);
H
Hongze Cheng 已提交
953 954
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
955 956
  tDecoderClear(&dc);

H
Hongze Cheng 已提交
957
  return 0;
H
Hongze Cheng 已提交
958 959

_err:
wmmhello's avatar
wmmhello 已提交
960
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
H
Hongze Cheng 已提交
961 962
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
963 964
  tDecoderClear(&dc);

H
Hongze Cheng 已提交
965
  return -1;
H
Hongze Cheng 已提交
966 967 968
}

static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
H
Hongze Cheng 已提交
969 970
  SMetaEntry  ctbEntry = {0};
  SMetaEntry  stbEntry = {0};
H
Hongze Cheng 已提交
971
  void       *pVal = NULL;
H
Hongze Cheng 已提交
972 973 974 975 976 977 978 979
  int         nVal = 0;
  int         ret;
  int         c;
  tb_uid_t    uid;
  int64_t     oversion;
  const void *pData = NULL;
  int         nData = 0;

H
Hongze Cheng 已提交
980 981 982 983 984
  if (pAlterTbReq->tagName == NULL) {
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
  }

H
Hongze Cheng 已提交
985
  // search name index
H
Hongze Cheng 已提交
986
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
H
Hongze Cheng 已提交
987
  if (ret < 0) {
988
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
989 990 991 992 993 994 995 996
    return -1;
  }

  uid = *(tb_uid_t *)pVal;
  tdbFree(pVal);
  pVal = NULL;

  // search uid index
H
Hongze Cheng 已提交
997
  TBC *pUidIdxc = NULL;
H
Hongze Cheng 已提交
998

999
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
H
Hongze Cheng 已提交
1000
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
1001
  if (c != 0) {
1002 1003
    tdbTbcClose(pUidIdxc);
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
1004 1005 1006
    metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
    return -1;
  }
H
Hongze Cheng 已提交
1007

H
Hongze Cheng 已提交
1008
  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
1009
  oversion = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
1010 1011

  // search table.db
H
Hongze Cheng 已提交
1012
  TBC     *pTbDbc = NULL;
H
Hongze Cheng 已提交
1013 1014
  SDecoder dc1 = {0};
  SDecoder dc2 = {0};
H
Hongze Cheng 已提交
1015

H
Hongze Cheng 已提交
1016
  /* get ctbEntry */
1017
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
H
Hongze Cheng 已提交
1018
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
1019
  if (c != 0) {
1020 1021 1022
    tdbTbcClose(pUidIdxc);
    tdbTbcClose(pTbDbc);
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
1023 1024 1025 1026
    metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
    return -1;
  }

H
Hongze Cheng 已提交
1027
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
1028

H
Hongze Cheng 已提交
1029 1030
  ctbEntry.pBuf = taosMemoryMalloc(nData);
  memcpy(ctbEntry.pBuf, pData, nData);
H
Hongze Cheng 已提交
1031 1032
  tDecoderInit(&dc1, ctbEntry.pBuf, nData);
  metaDecodeEntry(&dc1, &ctbEntry);
H
Hongze Cheng 已提交
1033

H
Hongze Cheng 已提交
1034
  /* get stbEntry*/
H
Hongze Cheng 已提交
1035
  tdbTbGet(pMeta->pUidIdx, &ctbEntry.ctbEntry.suid, sizeof(tb_uid_t), &pVal, &nVal);
1036 1037 1038 1039 1040
  if (!pVal) {
    terrno = TSDB_CODE_INVALID_MSG;
    goto _err;
  }

H
Hongze Cheng 已提交
1041 1042
  tdbTbGet(pMeta->pTbDb, &((STbDbKey){.uid = ctbEntry.ctbEntry.suid, .version = ((SUidIdxVal *)pVal)[0].version}),
           sizeof(STbDbKey), (void **)&stbEntry.pBuf, &nVal);
H
Hongze Cheng 已提交
1043
  tdbFree(pVal);
H
Hongze Cheng 已提交
1044 1045
  tDecoderInit(&dc2, stbEntry.pBuf, nVal);
  metaDecodeEntry(&dc2, &stbEntry);
H
Hongze Cheng 已提交
1046 1047

  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
H
Hongze Cheng 已提交
1048
  SSchema        *pColumn = NULL;
H
Hongze Cheng 已提交
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
  int32_t         iCol = 0;
  for (;;) {
    pColumn = NULL;

    if (iCol >= pTagSchema->nCols) break;
    pColumn = &pTagSchema->pSchema[iCol];

    if (strcmp(pColumn->name, pAlterTbReq->tagName) == 0) break;
    iCol++;
  }

  if (pColumn == NULL) {
1061
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
1062 1063
    goto _err;
  }
H
Hongze Cheng 已提交
1064

H
Hongze Cheng 已提交
1065
  ctbEntry.version = version;
H
Hongze Cheng 已提交
1066
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
1067
    ctbEntry.ctbEntry.pTags = taosMemoryMalloc(pAlterTbReq->nTagVal);
H
Hongze Cheng 已提交
1068
    if (ctbEntry.ctbEntry.pTags == NULL) {
wmmhello's avatar
wmmhello 已提交
1069 1070 1071
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _err;
    }
H
Hongze Cheng 已提交
1072 1073
    memcpy((void *)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
  } else {
C
Cary Xu 已提交
1074
    const STag *pOldTag = (const STag *)ctbEntry.ctbEntry.pTags;
H
Hongze Cheng 已提交
1075 1076
    STag       *pNewTag = NULL;
    SArray     *pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
C
Cary Xu 已提交
1077
    if (!pTagArray) {
C
Cary Xu 已提交
1078 1079 1080
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _err;
    }
wmmhello's avatar
wmmhello 已提交
1081 1082 1083
    for (int32_t i = 0; i < pTagSchema->nCols; i++) {
      SSchema *pCol = &pTagSchema->pSchema[i];
      if (iCol == i) {
1084 1085 1086
        if (pAlterTbReq->isNull) {
          continue;
        }
wmmhello's avatar
wmmhello 已提交
1087 1088 1089 1090 1091 1092
        STagVal val = {0};
        val.type = pCol->type;
        val.cid = pCol->colId;
        if (IS_VAR_DATA_TYPE(pCol->type)) {
          val.pData = pAlterTbReq->pTagVal;
          val.nData = pAlterTbReq->nTagVal;
1093
        } else {
wmmhello's avatar
wmmhello 已提交
1094 1095 1096
          memcpy(&val.i64, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
        }
        taosArrayPush(pTagArray, &val);
wmmhello's avatar
wmmhello 已提交
1097
      } else {
wmmhello's avatar
wmmhello 已提交
1098
        STagVal val = {.cid = pCol->colId};
wmmhello's avatar
wmmhello 已提交
1099 1100
        if (tTagGet(pOldTag, &val)) {
          taosArrayPush(pTagArray, &val);
H
Hongze Cheng 已提交
1101 1102 1103
        }
      }
    }
C
Cary Xu 已提交
1104 1105
    if ((terrno = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag)) < 0) {
      taosArrayDestroy(pTagArray);
C
Cary Xu 已提交
1106 1107 1108
      goto _err;
    }
    ctbEntry.ctbEntry.pTags = (uint8_t *)pNewTag;
C
Cary Xu 已提交
1109
    taosArrayDestroy(pTagArray);
wmmhello's avatar
wmmhello 已提交
1110
  }
H
Hongze Cheng 已提交
1111

1112 1113
  metaWLock(pMeta);

H
Hongze Cheng 已提交
1114 1115 1116 1117
  // save to table.db
  metaSaveToTbDb(pMeta, &ctbEntry);

  // save to uid.idx
H
Hongze Cheng 已提交
1118
  metaUpdateUidIdx(pMeta, &ctbEntry);
H
Hongze Cheng 已提交
1119

dengyihao's avatar
dengyihao 已提交
1120 1121 1122 1123
  if (iCol == 0) {
    metaUpdateTagIdx(pMeta, &ctbEntry);
  }

1124 1125 1126 1127 1128
  if (NULL == ctbEntry.ctbEntry.pTags) {
    metaError("meta/table: null tags, update tag val failed.");
    goto _err;
  }

1129
  SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid};
H
Hongze Cheng 已提交
1130
  tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags,
1131
              ((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn);
1132

1133 1134
  metaUidCacheClear(pMeta, ctbEntry.ctbEntry.suid);

1135 1136
  metaULock(pMeta);

H
Hongze Cheng 已提交
1137 1138
  tDecoderClear(&dc1);
  tDecoderClear(&dc2);
M
Minglei Jin 已提交
1139
  taosMemoryFree((void *)ctbEntry.ctbEntry.pTags);
H
Hongze Cheng 已提交
1140 1141
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
H
Hongze Cheng 已提交
1142 1143
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
1144
  return 0;
H
Hongze Cheng 已提交
1145 1146

_err:
H
Hongze Cheng 已提交
1147 1148
  tDecoderClear(&dc1);
  tDecoderClear(&dc2);
H
Hongze Cheng 已提交
1149 1150
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
H
Hongze Cheng 已提交
1151 1152
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
1153
  return -1;
H
Hongze Cheng 已提交
1154 1155 1156
}

static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
H
Hongze Cheng 已提交
1157 1158 1159 1160 1161 1162 1163 1164 1165
  void       *pVal = NULL;
  int         nVal = 0;
  const void *pData = NULL;
  int         nData = 0;
  int         ret = 0;
  tb_uid_t    uid;
  int64_t     oversion;
  SMetaEntry  entry = {0};
  int         c = 0;
wmmhello's avatar
wmmhello 已提交
1166 1167 1168 1169

  // search name index
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
  if (ret < 0) {
1170
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
wmmhello's avatar
wmmhello 已提交
1171
    return -1;
1172
  }
wmmhello's avatar
wmmhello 已提交
1173 1174 1175 1176 1177 1178 1179 1180

  uid = *(tb_uid_t *)pVal;
  tdbFree(pVal);
  pVal = NULL;

  // search uid index
  TBC *pUidIdxc = NULL;

1181
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
wmmhello's avatar
wmmhello 已提交
1182
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
1183
  if (c != 0) {
1184
    tdbTbcClose(pUidIdxc);
1185 1186 1187
    metaError("meta/table: invalide c: %" PRId32 " update tb options failed.", c);
    return -1;
  }
wmmhello's avatar
wmmhello 已提交
1188 1189

  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
1190
  oversion = ((SUidIdxVal *)pData)[0].version;
wmmhello's avatar
wmmhello 已提交
1191 1192 1193 1194

  // search table.db
  TBC *pTbDbc = NULL;

1195
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
wmmhello's avatar
wmmhello 已提交
1196
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
1197
  if (c != 0) {
1198 1199
    tdbTbcClose(pUidIdxc);
    tdbTbcClose(pTbDbc);
1200 1201 1202 1203
    metaError("meta/table: invalide c: %" PRId32 " update tb options failed.", c);
    return -1;
  }

wmmhello's avatar
wmmhello 已提交
1204 1205 1206 1207 1208 1209 1210 1211
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);

  // get table entry
  SDecoder dc = {0};
  entry.pBuf = taosMemoryMalloc(nData);
  memcpy(entry.pBuf, pData, nData);
  tDecoderInit(&dc, entry.pBuf, nData);
  ret = metaDecodeEntry(&dc, &entry);
1212 1213
  if (ret != 0) {
    tDecoderClear(&dc);
1214 1215
    tdbTbcClose(pUidIdxc);
    tdbTbcClose(pTbDbc);
1216 1217 1218
    metaError("meta/table: invalide ret: %" PRId32 " alt tb options failed.", ret);
    return -1;
  }
wmmhello's avatar
wmmhello 已提交
1219 1220 1221 1222 1223

  entry.version = version;
  metaWLock(pMeta);
  // build SMetaEntry
  if (entry.type == TSDB_CHILD_TABLE) {
H
Hongze Cheng 已提交
1224
    if (pAlterTbReq->updateTTL) {
wmmhello's avatar
wmmhello 已提交
1225 1226 1227 1228
      metaDeleteTtlIdx(pMeta, &entry);
      entry.ctbEntry.ttlDays = pAlterTbReq->newTTL;
      metaUpdateTtlIdx(pMeta, &entry);
    }
H
Hongze Cheng 已提交
1229
    if (pAlterTbReq->newCommentLen >= 0) {
wmmhello's avatar
wmmhello 已提交
1230 1231 1232
      entry.ctbEntry.commentLen = pAlterTbReq->newCommentLen;
      entry.ctbEntry.comment = pAlterTbReq->newComment;
    }
wmmhello's avatar
wmmhello 已提交
1233
  } else {
H
Hongze Cheng 已提交
1234
    if (pAlterTbReq->updateTTL) {
wmmhello's avatar
wmmhello 已提交
1235 1236 1237 1238
      metaDeleteTtlIdx(pMeta, &entry);
      entry.ntbEntry.ttlDays = pAlterTbReq->newTTL;
      metaUpdateTtlIdx(pMeta, &entry);
    }
H
Hongze Cheng 已提交
1239
    if (pAlterTbReq->newCommentLen >= 0) {
wmmhello's avatar
wmmhello 已提交
1240 1241 1242
      entry.ntbEntry.commentLen = pAlterTbReq->newCommentLen;
      entry.ntbEntry.comment = pAlterTbReq->newComment;
    }
1243
  }
wmmhello's avatar
wmmhello 已提交
1244 1245 1246

  // save to table db
  metaSaveToTbDb(pMeta, &entry);
H
Hongze Cheng 已提交
1247
  metaUpdateUidIdx(pMeta, &entry);
wmmhello's avatar
wmmhello 已提交
1248 1249 1250 1251
  metaULock(pMeta);

  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
1252
  tDecoderClear(&dc);
wmmhello's avatar
wmmhello 已提交
1253
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
H
Hongze Cheng 已提交
1254 1255 1256
  return 0;
}

D
dapan1121 已提交
1257
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
H
Hongze Cheng 已提交
1258 1259 1260 1261 1262
  switch (pReq->action) {
    case TSDB_ALTER_TABLE_ADD_COLUMN:
    case TSDB_ALTER_TABLE_DROP_COLUMN:
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
D
dapan1121 已提交
1263
      return metaAlterTableColumn(pMeta, version, pReq, pMetaRsp);
H
Hongze Cheng 已提交
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
    case TSDB_ALTER_TABLE_UPDATE_TAG_VAL:
      return metaUpdateTableTagVal(pMeta, version, pReq);
    case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
      return metaUpdateTableOptions(pMeta, version, pReq);
    default:
      terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
      return -1;
      break;
  }
}

H
Hongze Cheng 已提交
1275
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1276
  STbDbKey tbDbKey;
H
Hongze Cheng 已提交
1277 1278
  void    *pKey = NULL;
  void    *pVal = NULL;
H
Hongze Cheng 已提交
1279 1280
  int      kLen = 0;
  int      vLen = 0;
H
Hongze Cheng 已提交
1281
  SEncoder coder = {0};
H
Hongze Cheng 已提交
1282 1283

  // set key and value
H
Hongze Cheng 已提交
1284
  tbDbKey.version = pME->version;
H
Hongze Cheng 已提交
1285 1286
  tbDbKey.uid = pME->uid;

S
Shengliang Guan 已提交
1287
  metaDebug("vgId:%d, start to save table version:%" PRId64 " uid:%" PRId64, TD_VID(pMeta->pVnode), pME->version,
1288 1289
            pME->uid);

H
Hongze Cheng 已提交
1290 1291
  pKey = &tbDbKey;
  kLen = sizeof(tbDbKey);
H
Hongze Cheng 已提交
1292

wafwerar's avatar
wafwerar 已提交
1293 1294 1295
  int32_t ret = 0;
  tEncodeSize(metaEncodeEntry, pME, vLen, ret);
  if (ret < 0) {
H
Hongze Cheng 已提交
1296 1297 1298 1299 1300 1301 1302 1303 1304
    goto _err;
  }

  pVal = taosMemoryMalloc(vLen);
  if (pVal == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

H
Hongze Cheng 已提交
1305
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
1306 1307 1308 1309 1310

  if (metaEncodeEntry(&coder, pME) < 0) {
    goto _err;
  }

H
Hongze Cheng 已提交
1311
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
1312 1313

  // write to table.db
1314
  if (tdbTbInsert(pMeta->pTbDb, pKey, kLen, pVal, vLen, pMeta->txn) < 0) {
H
Hongze Cheng 已提交
1315 1316 1317 1318 1319 1320 1321
    goto _err;
  }

  taosMemoryFree(pVal);
  return 0;

_err:
S
Shengliang Guan 已提交
1322
  metaError("vgId:%d, failed to save table version:%" PRId64 "uid:%" PRId64 " %s", TD_VID(pMeta->pVnode), pME->version,
1323 1324
            pME->uid, tstrerror(terrno));

H
Hongze Cheng 已提交
1325 1326 1327 1328
  taosMemoryFree(pVal);
  return -1;
}

H
Hongze Cheng 已提交
1329
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1330 1331 1332 1333 1334 1335 1336
  // upsert cache
  SMetaInfo info;
  metaGetEntryInfo(pME, &info);
  metaCacheUpsert(pMeta, &info);

  SUidIdxVal uidIdxVal = {.suid = info.suid, .version = info.version, .skmVer = info.skmVer};

1337
  return tdbTbUpsert(pMeta->pUidIdx, &pME->uid, sizeof(tb_uid_t), &uidIdxVal, sizeof(uidIdxVal), pMeta->txn);
H
Hongze Cheng 已提交
1338 1339
}

C
Cary Xu 已提交
1340
static int metaUpdateSuidIdx(SMeta *pMeta, const SMetaEntry *pME) {
1341
  return tdbTbInsert(pMeta->pSuidIdx, &pME->uid, sizeof(tb_uid_t), NULL, 0, pMeta->txn);
C
Cary Xu 已提交
1342 1343
}

H
Hongze Cheng 已提交
1344
static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME) {
1345
  return tdbTbInsert(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), pMeta->txn);
H
Hongze Cheng 已提交
1346 1347
}

H
Hongze Cheng 已提交
1348
static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
1349 1350
  STtlIdxKey ttlKey = {0};
  metaBuildTtlIdxKey(&ttlKey, pME);
H
Hongze Cheng 已提交
1351
  if (ttlKey.dtime == 0) return 0;
1352
  return tdbTbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, pMeta->txn);
H
Hongze Cheng 已提交
1353 1354
}

H
Hongze Cheng 已提交
1355 1356
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
wmmhello's avatar
wmmhello 已提交
1357

H
Hongze Cheng 已提交
1358
  return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags,
1359
                     ((STag *)(pME->ctbEntry.pTags))->len, pMeta->txn);
H
Hongze Cheng 已提交
1360 1361
}

wmmhello's avatar
wmmhello 已提交
1362
int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
1363
                        STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
dengyihao's avatar
dengyihao 已提交
1364 1365 1366 1367 1368
  if (IS_VAR_DATA_TYPE(type)) {
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + VARSTR_HEADER_SIZE + sizeof(tb_uid_t);
  } else {
    *nTagIdxKey = sizeof(STagIdxKey) + nTagData + sizeof(tb_uid_t);
  }
H
Hongze Cheng 已提交
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379

  *ppTagIdxKey = (STagIdxKey *)taosMemoryMalloc(*nTagIdxKey);
  if (*ppTagIdxKey == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  (*ppTagIdxKey)->suid = suid;
  (*ppTagIdxKey)->cid = cid;
  (*ppTagIdxKey)->isNull = (pTagData == NULL) ? 1 : 0;
  (*ppTagIdxKey)->type = type;
dengyihao's avatar
dengyihao 已提交
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389

  // refactor
  if (IS_VAR_DATA_TYPE(type)) {
    memcpy((*ppTagIdxKey)->data, (uint16_t *)&nTagData, VARSTR_HEADER_SIZE);
    memcpy((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE, pTagData, nTagData);
    *(tb_uid_t *)((*ppTagIdxKey)->data + VARSTR_HEADER_SIZE + nTagData) = uid;
  } else {
    memcpy((*ppTagIdxKey)->data, pTagData, nTagData);
    *(tb_uid_t *)((*ppTagIdxKey)->data + nTagData) = uid;
  }
H
Hongze Cheng 已提交
1390 1391 1392 1393 1394 1395 1396 1397 1398

  return 0;
}

static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) {
  if (pTagIdxKey) taosMemoryFree(pTagIdxKey);
}

static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
H
Hongze Cheng 已提交
1399
  void          *pData = NULL;
H
Hongze Cheng 已提交
1400 1401 1402
  int            nData = 0;
  STbDbKey       tbDbKey = {0};
  SMetaEntry     stbEntry = {0};
H
Hongze Cheng 已提交
1403
  STagIdxKey    *pTagIdxKey = NULL;
H
Hongze Cheng 已提交
1404
  int32_t        nTagIdxKey;
M
Minglei Jin 已提交
1405 1406
  const SSchema *pTagColumn;
  const void    *pTagData = NULL;
C
Cary Xu 已提交
1407
  int32_t        nTagData = 0;
H
Hongze Cheng 已提交
1408
  SDecoder       dc = {0};
1409
  int32_t        ret = 0;
H
Hongze Cheng 已提交
1410
  // get super table
H
Hongze Cheng 已提交
1411
  if (tdbTbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData) != 0) {
1412 1413 1414
    metaError("vgId:%d, failed to get stable suid for update. version:%" PRId64, TD_VID(pMeta->pVnode),
              pCtbEntry->version);
    terrno = TSDB_CODE_TDB_INVALID_TABLE_ID;
1415 1416
    ret = -1;
    goto end;
wmmhello's avatar
wmmhello 已提交
1417
  }
H
Hongze Cheng 已提交
1418
  tbDbKey.uid = pCtbEntry->ctbEntry.suid;
H
Hongze Cheng 已提交
1419
  tbDbKey.version = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
1420
  tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData);
H
Hongze Cheng 已提交
1421 1422

  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
1423 1424 1425 1426
  ret = metaDecodeEntry(&dc, &stbEntry);
  if (ret < 0) {
    goto end;
  }
H
Hongze Cheng 已提交
1427

M
Minglei Jin 已提交
1428 1429 1430 1431
  if (stbEntry.stbEntry.schemaTag.pSchema == NULL) {
    goto end;
  }

H
Hongze Cheng 已提交
1432
  pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
C
Cary Xu 已提交
1433 1434

  STagVal tagVal = {.cid = pTagColumn->colId};
1435
  if (pTagColumn->type != TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
1436
    tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal);
1437
    if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
wmmhello's avatar
wmmhello 已提交
1438 1439
      pTagData = tagVal.pData;
      nTagData = (int32_t)tagVal.nData;
1440
    } else {
wmmhello's avatar
wmmhello 已提交
1441 1442 1443
      pTagData = &(tagVal.i64);
      nTagData = tDataTypes[pTagColumn->type].bytes;
    }
1444 1445 1446
  } else {
    // pTagData = pCtbEntry->ctbEntry.pTags;
    // nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
dengyihao's avatar
dengyihao 已提交
1447 1448
    pTagData = pCtbEntry->ctbEntry.pTags;
    nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
1449 1450
    ret = metaSaveJsonVarToIdx(pMeta, pCtbEntry, pTagColumn);
    goto end;
wmmhello's avatar
wmmhello 已提交
1451
  }
dengyihao's avatar
dengyihao 已提交
1452 1453 1454 1455 1456 1457
  if (pTagData != NULL) {
    if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
                            pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
      ret = -1;
      goto end;
    }
1458
    tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
H
Hongze Cheng 已提交
1459
  }
1460
end:
H
Hongze Cheng 已提交
1461 1462 1463
  metaDestroyTagIdxKey(pTagIdxKey);
  tDecoderClear(&dc);
  tdbFree(pData);
1464
  return ret;
H
Hongze Cheng 已提交
1465 1466
}

H
Hongze Cheng 已提交
1467
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1468
  SEncoder              coder = {0};
H
Hongze Cheng 已提交
1469
  void                 *pVal = NULL;
H
Hongze Cheng 已提交
1470 1471 1472 1473 1474 1475
  int                   vLen = 0;
  int                   rcode = 0;
  SSkmDbKey             skmDbKey = {0};
  const SSchemaWrapper *pSW;

  if (pME->type == TSDB_SUPER_TABLE) {
1476
    pSW = &pME->stbEntry.schemaRow;
H
Hongze Cheng 已提交
1477
  } else if (pME->type == TSDB_NORMAL_TABLE) {
1478
    pSW = &pME->ntbEntry.schemaRow;
H
Hongze Cheng 已提交
1479
  } else {
1480 1481
    metaError("meta/table: invalide table type: %" PRId8 " save skm db failed.", pME->type);
    return TSDB_CODE_FAILED;
H
Hongze Cheng 已提交
1482 1483
  }

H
Hongze Cheng 已提交
1484
  skmDbKey.uid = pME->uid;
1485
  skmDbKey.sver = pSW->version;
H
Hongze Cheng 已提交
1486

1487 1488 1489 1490 1491
  // if receive tmq meta message is: create stable1 then delete stable1 then create stable1 with multi vgroups
  if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), NULL, NULL) == 0) {
    return rcode;
  }

H
Hongze Cheng 已提交
1492
  // encode schema
wafwerar's avatar
wafwerar 已提交
1493 1494 1495
  int32_t ret = 0;
  tEncodeSize(tEncodeSSchemaWrapper, pSW, vLen, ret);
  if (ret < 0) return -1;
H
Hongze Cheng 已提交
1496
  pVal = taosMemoryMalloc(vLen);
H
Hongze Cheng 已提交
1497 1498 1499 1500 1501 1502
  if (pVal == NULL) {
    rcode = -1;
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

H
Hongze Cheng 已提交
1503
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
1504 1505
  tEncodeSSchemaWrapper(&coder, pSW);

1506
  if (tdbTbInsert(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, pMeta->txn) < 0) {
H
Hongze Cheng 已提交
1507 1508 1509 1510
    rcode = -1;
    goto _exit;
  }

M
Minglei Jin 已提交
1511 1512 1513
  metaDebug("vgId:%d, set schema:(%" PRId64 ") sver:%d since %s", TD_VID(pMeta->pVnode), pME->uid, pSW->version,
            tstrerror(terrno));

H
Hongze Cheng 已提交
1514
_exit:
H
Hongze Cheng 已提交
1515
  taosMemoryFree(pVal);
H
Hongze Cheng 已提交
1516
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
1517 1518 1519
  return rcode;
}

H
Hongze Cheng 已提交
1520
int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1521 1522
  metaWLock(pMeta);

H
Hongze Cheng 已提交
1523
  // save to table.db
H
Hongze Cheng 已提交
1524
  if (metaSaveToTbDb(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1525 1526

  // update uid.idx
H
Hongze Cheng 已提交
1527
  if (metaUpdateUidIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1528 1529

  // update name.idx
H
Hongze Cheng 已提交
1530
  if (metaUpdateNameIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1531 1532 1533

  if (pME->type == TSDB_CHILD_TABLE) {
    // update ctb.idx
H
Hongze Cheng 已提交
1534
    if (metaUpdateCtbIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1535 1536

    // update tag.idx
H
Hongze Cheng 已提交
1537
    if (metaUpdateTagIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1538 1539
  } else {
    // update schema.db
H
Hongze Cheng 已提交
1540
    if (metaSaveToSkmDb(pMeta, pME) < 0) goto _err;
C
Cary Xu 已提交
1541 1542 1543

    if (pME->type == TSDB_SUPER_TABLE) {
      if (metaUpdateSuidIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1544
    }
H
Hongze Cheng 已提交
1545 1546
  }

dengyihao's avatar
dengyihao 已提交
1547 1548 1549 1550 1551 1552
  if (metaUpdateCtimeIdx(pMeta, pME) < 0) goto _err;

  if (pME->type == TSDB_NORMAL_TABLE) {
    if (metaUpdateNcolIdx(pMeta, pME) < 0) goto _err;
  }

H
Hongze Cheng 已提交
1553
  if (pME->type != TSDB_SUPER_TABLE) {
H
Hongze Cheng 已提交
1554
    if (metaUpdateTtlIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1555 1556
  }

H
Hongze Cheng 已提交
1557
  metaULock(pMeta);
H
Hongze Cheng 已提交
1558
  return 0;
H
Hongze Cheng 已提交
1559 1560 1561 1562

_err:
  metaULock(pMeta);
  return -1;
1563
}
dengyihao's avatar
dengyihao 已提交
1564
// refactor later
dengyihao's avatar
dengyihao 已提交
1565 1566
void *metaGetIdx(SMeta *pMeta) { return pMeta->pTagIdx; }
void *metaGetIvtIdx(SMeta *pMeta) { return pMeta->pTagIvtIdx; }