metaTable.c 44.1 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 49 50 51 52
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 {
    ASSERT(0);
  }
}

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 210 211
    tb_uid_t uid = *(tb_uid_t *)pData;
    tdbFree(pData);
    SMetaInfo info;
    metaGetInfo(pMeta, uid, &info);
    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

H
Hongze Cheng 已提交
264
  tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, &pMeta->txn);
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 298
  tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = ((SUidIdxVal *)pData)[0].version, .uid = pReq->suid},
              sizeof(STbDbKey), &pMeta->txn);
H
Hongze Cheng 已提交
299 300
  tdbTbDelete(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pMeta->txn);
  tdbTbDelete(pMeta->pUidIdx, &pReq->suid, sizeof(tb_uid_t), &pMeta->txn);
C
Cary Xu 已提交
301
  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

H
Hongze Cheng 已提交
324 325
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  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

H
Hongze Cheng 已提交
343 344
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c);
H
Hongze Cheng 已提交
345 346
  ASSERT(ret == 0 && c == 0);

H
Hongze Cheng 已提交
347
  ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
348 349
  ASSERT(ret == 0);

H
Hongze Cheng 已提交
350 351 352
  oStbEntry.pBuf = taosMemoryMalloc(nData);
  memcpy(oStbEntry.pBuf, pData, nData);
  tDecoderInit(&dc, oStbEntry.pBuf, nData);
H
Hongze Cheng 已提交
353 354 355 356 357 358
  metaDecodeEntry(&dc, &oStbEntry);

  nStbEntry.version = version;
  nStbEntry.type = TSDB_SUPER_TABLE;
  nStbEntry.uid = pReq->suid;
  nStbEntry.name = pReq->name;
359
  nStbEntry.stbEntry.schemaRow = pReq->schemaRow;
H
Hongze Cheng 已提交
360 361 362 363
  nStbEntry.stbEntry.schemaTag = pReq->schemaTag;

  metaWLock(pMeta);
  // compare two entry
364 365
  if (oStbEntry.stbEntry.schemaRow.version != pReq->schemaRow.version) {
    metaSaveToSkmDb(pMeta, &nStbEntry);
H
Hongze Cheng 已提交
366 367 368 369 370 371
  }

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

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

374
  // metaStatsCacheDrop(pMeta, nStbEntry.uid);
375

H
Hongze Cheng 已提交
376
  metaULock(pMeta);
377 378

  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
H
Hongze Cheng 已提交
379
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
380 381
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
382 383 384
  return 0;
}

385
int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **pMetaRsp) {
H
Hongze Cheng 已提交
386 387
  SMetaEntry  me = {0};
  SMetaReader mr = {0};
H
Hongze Cheng 已提交
388 389 390 391 392

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

395
  if (pReq->type == TSDB_CHILD_TABLE) {
396
    tb_uid_t suid = metaGetTableEntryUidByName(pMeta, pReq->ctb.stbName);
397 398 399 400 401 402
    if (suid != pReq->ctb.suid) {
      terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
      return -1;
    }
  }

H
Hongze Cheng 已提交
403
  // validate req
H
Hongze Cheng 已提交
404
  metaReaderInit(&mr, pMeta, 0);
H
Hongze Cheng 已提交
405
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
H
Hongze Cheng 已提交
406 407 408 409
    pReq->uid = mr.me.uid;
    if (pReq->type == TSDB_CHILD_TABLE) {
      pReq->ctb.suid = mr.me.ctbEntry.suid;
    }
H
Hongze Cheng 已提交
410 411 412
    terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
    metaReaderClear(&mr);
    return -1;
C
Cary Xu 已提交
413 414
  } else if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
    terrno = TSDB_CODE_SUCCESS;
H
Hongze Cheng 已提交
415
  }
H
Hongze Cheng 已提交
416
  metaReaderClear(&mr);
H
Hongze Cheng 已提交
417 418

  // build SMetaEntry
H
Hongze Cheng 已提交
419
  me.version = version;
H
Hongze Cheng 已提交
420 421 422 423 424 425
  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 已提交
426
    me.ctbEntry.commentLen = pReq->commentLen;
wmmhello's avatar
wmmhello 已提交
427
    me.ctbEntry.comment = pReq->comment;
H
Hongze Cheng 已提交
428 429
    me.ctbEntry.suid = pReq->ctb.suid;
    me.ctbEntry.pTags = pReq->ctb.pTag;
430

wmmhello's avatar
wmmhello 已提交
431
#ifdef TAG_FILTER_DEBUG
dengyihao's avatar
dengyihao 已提交
432 433
    SArray *pTagVals = NULL;
    int32_t code = tTagToValArray((STag *)pReq->ctb.pTag, &pTagVals);
wmmhello's avatar
wmmhello 已提交
434
    for (int i = 0; i < taosArrayGetSize(pTagVals); i++) {
dengyihao's avatar
dengyihao 已提交
435
      STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
wmmhello's avatar
wmmhello 已提交
436 437

      if (IS_VAR_DATA_TYPE(pTagVal->type)) {
dengyihao's avatar
dengyihao 已提交
438
        char *buf = taosMemoryCalloc(pTagVal->nData + 1, 1);
wmmhello's avatar
wmmhello 已提交
439
        memcpy(buf, pTagVal->pData, pTagVal->nData);
dengyihao's avatar
dengyihao 已提交
440 441
        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 已提交
442 443 444 445
        taosMemoryFree(buf);
      } else {
        double val = 0;
        GET_TYPED_DATA(val, double, pTagVal->type, &pTagVal->i64);
dengyihao's avatar
dengyihao 已提交
446 447
        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 已提交
448 449
      }
    }
wmmhello's avatar
wmmhello 已提交
450
#endif
wmmhello's avatar
wmmhello 已提交
451

452
    ++pMeta->pVnode->config.vndStats.numOfCTables;
453 454 455 456

    metaWLock(pMeta);
    metaUpdateStbStats(pMeta, me.ctbEntry.suid, 1);
    metaULock(pMeta);
H
Hongze Cheng 已提交
457 458 459
  } else {
    me.ntbEntry.ctime = pReq->ctime;
    me.ntbEntry.ttlDays = pReq->ttl;
wmmhello's avatar
wmmhello 已提交
460
    me.ntbEntry.commentLen = pReq->commentLen;
wmmhello's avatar
wmmhello 已提交
461
    me.ntbEntry.comment = pReq->comment;
462 463
    me.ntbEntry.schemaRow = pReq->ntb.schemaRow;
    me.ntbEntry.ncid = me.ntbEntry.schemaRow.pSchema[me.ntbEntry.schemaRow.nCols - 1].colId + 1;
464 465

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

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

471 472 473 474 475 476 477 478 479 480
  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 {
481
        metaUpdateMetaRsp(pReq->uid, pReq->name, &pReq->ntb.schemaRow, *pMetaRsp);
482 483 484 485
      }
    }
  }

S
Shengliang Guan 已提交
486
  metaDebug("vgId:%d, table:%s uid %" PRId64 " is created, type:%" PRId8, TD_VID(pMeta->pVnode), pReq->name, pReq->uid,
H
Hongze Cheng 已提交
487
            pReq->type);
H
refact  
Hongze Cheng 已提交
488
  return 0;
H
Hongze Cheng 已提交
489 490

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

496
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids, tb_uid_t *tbUid) {
H
Hongze Cheng 已提交
497
  void    *pData = NULL;
H
Hongze Cheng 已提交
498 499 500 501
  int      nData = 0;
  int      rc = 0;
  tb_uid_t uid;
  int      type;
H
more  
Hongze Cheng 已提交
502

H
Hongze Cheng 已提交
503 504
  rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
  if (rc < 0) {
505
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
H
more  
Hongze Cheng 已提交
506 507
    return -1;
  }
H
Hongze Cheng 已提交
508 509
  uid = *(tb_uid_t *)pData;

H
Hongze Cheng 已提交
510 511 512
  metaWLock(pMeta);
  metaDropTableByUid(pMeta, uid, &type);
  metaULock(pMeta);
H
Hongze Cheng 已提交
513

514
  if ((type == TSDB_CHILD_TABLE || type == TSDB_NORMAL_TABLE) && tbUids) {
H
Hongze Cheng 已提交
515
    taosArrayPush(tbUids, &uid);
H
Hongze Cheng 已提交
516
  }
H
Hongze Cheng 已提交
517

518 519 520 521
  if ((type == TSDB_CHILD_TABLE) && tbUid) {
    *tbUid = uid;
  }

H
Hongze Cheng 已提交
522 523 524
  tdbFree(pData);
  return 0;
}
H
Hongze Cheng 已提交
525

526 527
int metaTtlDropTable(SMeta *pMeta, int64_t ttl, SArray *tbUids) {
  int ret = metaTtlSmaller(pMeta, ttl, tbUids);
H
Hongze Cheng 已提交
528
  if (ret != 0) {
529 530
    return ret;
  }
531
  if (taosArrayGetSize(tbUids) == 0) {
532 533 534 535
    return 0;
  }

  metaWLock(pMeta);
536 537 538
  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 已提交
539
    metaDebug("ttl drop table:%" PRId64, *uid);
540 541 542 543 544
  }
  metaULock(pMeta);
  return 0;
}

H
Hongze Cheng 已提交
545 546 547
static void metaBuildTtlIdxKey(STtlIdxKey *ttlKey, const SMetaEntry *pME) {
  int64_t ttlDays;
  int64_t ctime;
548 549 550 551 552 553 554 555 556 557 558 559
  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 {
    ASSERT(0);
  }

  if (ttlDays <= 0) return;

wmmhello's avatar
wmmhello 已提交
560
  ttlKey->dtime = ctime / 1000 + ttlDays * tsTtlUnit;
561 562
  ttlKey->uid = pME->uid;
}
dengyihao's avatar
dengyihao 已提交
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
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 已提交
579 580 581 582 583 584
  if (pME->type == TSDB_NORMAL_TABLE) {
    ncolKey->ncol = pME->ntbEntry.schemaRow.nCols;
    ncolKey->uid = pME->uid;
  } else {
    return -1;
  }
dengyihao's avatar
dengyihao 已提交
585 586
  return 0;
}
587 588 589 590

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

H
Hongze Cheng 已提交
595
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
H
Hongze Cheng 已提交
596
  void      *pData = NULL;
H
Hongze Cheng 已提交
597 598 599 600 601 602
  int        nData = 0;
  int        rc = 0;
  SMetaEntry e = {0};
  SDecoder   dc = {0};

  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
603 604 605
  if (rc < 0) {
    return -1;
  }
H
Hongze Cheng 已提交
606
  int64_t version = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
607 608 609 610

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

  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
611 612 613 614 615
  rc = metaDecodeEntry(&dc, &e);
  if (rc < 0) {
    tDecoderClear(&dc);
    return -1;
  }
H
Hongze Cheng 已提交
616 617 618

  if (type) *type = e.type;

619 620 621 622 623
  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 已提交
624
      version = ((SUidIdxVal *)tData)[0].version;
625 626 627 628 629 630 631 632 633 634
      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 已提交
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
        } 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) {
            tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, &pMeta->txn);
          }
          metaDestroyTagIdxKey(pTagIdxKey);
657 658 659 660 661 662 663
        }
        tDecoderClear(&tdc);
      }
      tdbFree(tData);
    }
  }

H
Hongze Cheng 已提交
664 665 666
  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);
667

dengyihao's avatar
dengyihao 已提交
668 669 670
  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 已提交
671
  if (e.type != TSDB_SUPER_TABLE) metaDeleteTtlIdx(pMeta, &e);
C
Cary Xu 已提交
672

H
Hongze Cheng 已提交
673 674
  if (e.type == TSDB_CHILD_TABLE) {
    tdbTbDelete(pMeta->pCtbIdx, &(SCtbIdxKey){.suid = e.ctbEntry.suid, .uid = uid}, sizeof(SCtbIdxKey), &pMeta->txn);
675 676

    --pMeta->pVnode->config.vndStats.numOfCTables;
677 678

    metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1);
H
Hongze Cheng 已提交
679 680
  } else if (e.type == TSDB_NORMAL_TABLE) {
    // drop schema.db (todo)
681 682

    --pMeta->pVnode->config.vndStats.numOfNTables;
683
    pMeta->pVnode->config.vndStats.numOfNTimeSeries -= e.ntbEntry.schemaRow.nCols - 1;
H
Hongze Cheng 已提交
684
  } else if (e.type == TSDB_SUPER_TABLE) {
C
Cary Xu 已提交
685
    tdbTbDelete(pMeta->pSuidIdx, &e.uid, sizeof(tb_uid_t), &pMeta->txn);
H
Hongze Cheng 已提交
686
    // drop schema.db (todo)
687

688
    metaStatsCacheDrop(pMeta, uid);
689
    --pMeta->pVnode->config.vndStats.numOfSTables;
H
Hongze Cheng 已提交
690 691
  }

H
Hongze Cheng 已提交
692 693
  metaCacheDrop(pMeta, uid);

H
Hongze Cheng 已提交
694 695
  tDecoderClear(&dc);
  tdbFree(pData);
H
Hongze Cheng 已提交
696

H
refact  
Hongze Cheng 已提交
697 698
  return 0;
}
dengyihao's avatar
dengyihao 已提交
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
// opt ins_tables
int metaUpdateCtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtimeIdxKey ctimeKey = {0};
  if (metaBuildCtimeIdxKey(&ctimeKey, pME) < 0) {
    return 0;
  }
  return tdbTbInsert(pMeta->pCtimeIdx, &ctimeKey, sizeof(ctimeKey), NULL, 0, &pMeta->txn);
}

int metaDeleteCtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtimeIdxKey ctimeKey = {0};
  if (metaBuildCtimeIdxKey(&ctimeKey, pME) < 0) {
    return 0;
  }
  return tdbTbDelete(pMeta->pCtimeIdx, &ctimeKey, sizeof(ctimeKey), &pMeta->txn);
}
int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SNcolIdxKey ncolKey = {0};
  if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
    return 0;
  }
  return tdbTbInsert(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), NULL, 0, &pMeta->txn);
}

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

D
dapan1121 已提交
731
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq, STableMetaRsp *pMetaRsp) {
H
Hongze Cheng 已提交
732
  void           *pVal = NULL;
H
Hongze Cheng 已提交
733
  int             nVal = 0;
H
Hongze Cheng 已提交
734
  const void     *pData = NULL;
H
Hongze Cheng 已提交
735 736 737 738
  int             nData = 0;
  int             ret = 0;
  tb_uid_t        uid;
  int64_t         oversion;
H
Hongze Cheng 已提交
739
  SSchema        *pColumn = NULL;
H
Hongze Cheng 已提交
740 741 742 743
  SMetaEntry      entry = {0};
  SSchemaWrapper *pSchema;
  int             c;

H
Hongze Cheng 已提交
744
  if (pAlterTbReq->colName == NULL) {
H
Hongze Cheng 已提交
745 746 747 748
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
  }

H
Hongze Cheng 已提交
749
  // search name index
H
Hongze Cheng 已提交
750
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
H
Hongze Cheng 已提交
751
  if (ret < 0) {
752
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
753 754 755 756 757 758 759 760
    return -1;
  }

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

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

H
Hongze Cheng 已提交
763 764
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
H
Hongze Cheng 已提交
765 766
  ASSERT(c == 0);

H
Hongze Cheng 已提交
767
  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
768
  oversion = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
769 770

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

H
Hongze Cheng 已提交
773 774
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
H
Hongze Cheng 已提交
775
  ASSERT(c == 0);
H
Hongze Cheng 已提交
776
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
777 778 779

  // get table entry
  SDecoder dc = {0};
H
Hongze Cheng 已提交
780 781 782
  entry.pBuf = taosMemoryMalloc(nData);
  memcpy(entry.pBuf, pData, nData);
  tDecoderInit(&dc, entry.pBuf, nData);
H
Hongze Cheng 已提交
783 784
  ret = metaDecodeEntry(&dc, &entry);
  ASSERT(ret == 0);
H
Hongze Cheng 已提交
785 786 787 788 789 790

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

dengyihao's avatar
dengyihao 已提交
793 794 795 796
  // save old entry
  SMetaEntry oldEntry = {.type = TSDB_NORMAL_TABLE, .uid = entry.uid};
  oldEntry.ntbEntry.schemaRow.nCols = pSchema->nCols;

H
Hongze Cheng 已提交
797 798 799 800 801 802 803
  int32_t iCol = 0;
  for (;;) {
    pColumn = NULL;

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

H
Hongze Cheng 已提交
804
    ASSERT(pAlterTbReq->colName);
H
Hongze Cheng 已提交
805 806 807 808 809
    if (strcmp(pColumn->name, pAlterTbReq->colName) == 0) break;
    iCol++;
  }

  entry.version = version;
H
Hongze Cheng 已提交
810 811
  int      tlen;
  SSchema *pNewSchema = NULL;
H
Hongze Cheng 已提交
812 813 814 815 816 817
  switch (pAlterTbReq->action) {
    case TSDB_ALTER_TABLE_ADD_COLUMN:
      if (pColumn) {
        terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
        goto _err;
      }
818
      pSchema->version++;
H
Hongze Cheng 已提交
819
      pSchema->nCols++;
H
Hongze Cheng 已提交
820 821 822
      pNewSchema = taosMemoryMalloc(sizeof(SSchema) * pSchema->nCols);
      memcpy(pNewSchema, pSchema->pSchema, sizeof(SSchema) * (pSchema->nCols - 1));
      pSchema->pSchema = pNewSchema;
823 824 825 826 827
      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);
828 829

      ++pMeta->pVnode->config.vndStats.numOfNTimeSeries;
H
Hongze Cheng 已提交
830 831 832
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
      if (pColumn == NULL) {
833
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
834 835 836 837 838 839
        goto _err;
      }
      if (pColumn->colId == 0) {
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
        goto _err;
      }
L
Liu Jicong 已提交
840 841 842 843
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
        goto _err;
      }
844
      pSchema->version++;
H
Hongze Cheng 已提交
845 846 847 848
      tlen = (pSchema->nCols - iCol - 1) * sizeof(SSchema);
      if (tlen) {
        memmove(pColumn, pColumn + 1, tlen);
      }
H
Hongze Cheng 已提交
849
      pSchema->nCols--;
850 851

      --pMeta->pVnode->config.vndStats.numOfNTimeSeries;
H
Hongze Cheng 已提交
852 853 854
      break;
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
      if (pColumn == NULL) {
855
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
856 857
        goto _err;
      }
H
Hongze Cheng 已提交
858
      if (!IS_VAR_DATA_TYPE(pColumn->type) || pColumn->bytes > pAlterTbReq->colModBytes) {
H
Hongze Cheng 已提交
859 860 861
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
        goto _err;
      }
L
Liu Jicong 已提交
862 863 864 865
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
        goto _err;
      }
866
      pSchema->version++;
H
Hongze Cheng 已提交
867
      pColumn->bytes = pAlterTbReq->colModBytes;
H
Hongze Cheng 已提交
868 869
      break;
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
H
Hongze Cheng 已提交
870 871 872 873
      if (pAlterTbReq->colNewName == NULL) {
        terrno = TSDB_CODE_INVALID_MSG;
        goto _err;
      }
H
Hongze Cheng 已提交
874
      if (pColumn == NULL) {
875
        terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
876 877
        goto _err;
      }
L
Liu Jicong 已提交
878 879 880 881
      if (tqCheckColModifiable(pMeta->pVnode->pTq, uid, pColumn->colId) != 0) {
        terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
        goto _err;
      }
882
      pSchema->version++;
H
Hongze Cheng 已提交
883 884 885 886 887 888
      strcpy(pColumn->name, pAlterTbReq->colNewName);
      break;
  }

  entry.version = version;

dengyihao's avatar
dengyihao 已提交
889 890 891
  metaDeleteNcolIdx(pMeta, &oldEntry);
  metaUpdateNcolIdx(pMeta, &entry);

H
Hongze Cheng 已提交
892 893 894 895 896 897
  // do actual write
  metaWLock(pMeta);

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

H
Hongze Cheng 已提交
898
  metaUpdateUidIdx(pMeta, &entry);
H
Hongze Cheng 已提交
899 900 901 902 903

  metaSaveToSkmDb(pMeta, &entry);

  metaULock(pMeta);

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

wmmhello's avatar
wmmhello 已提交
906
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
H
Hongze Cheng 已提交
907
  if (pNewSchema) taosMemoryFree(pNewSchema);
H
Hongze Cheng 已提交
908 909
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
910 911
  tDecoderClear(&dc);

H
Hongze Cheng 已提交
912
  return 0;
H
Hongze Cheng 已提交
913 914

_err:
wmmhello's avatar
wmmhello 已提交
915
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
H
Hongze Cheng 已提交
916 917
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
918 919
  tDecoderClear(&dc);

H
Hongze Cheng 已提交
920
  return -1;
H
Hongze Cheng 已提交
921 922 923
}

static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
H
Hongze Cheng 已提交
924 925
  SMetaEntry  ctbEntry = {0};
  SMetaEntry  stbEntry = {0};
H
Hongze Cheng 已提交
926
  void       *pVal = NULL;
H
Hongze Cheng 已提交
927 928 929 930 931 932 933 934
  int         nVal = 0;
  int         ret;
  int         c;
  tb_uid_t    uid;
  int64_t     oversion;
  const void *pData = NULL;
  int         nData = 0;

H
Hongze Cheng 已提交
935 936 937 938 939
  if (pAlterTbReq->tagName == NULL) {
    terrno = TSDB_CODE_INVALID_MSG;
    return -1;
  }

H
Hongze Cheng 已提交
940
  // search name index
H
Hongze Cheng 已提交
941
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
H
Hongze Cheng 已提交
942
  if (ret < 0) {
943
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
944 945 946 947 948 949 950 951
    return -1;
  }

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

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

H
Hongze Cheng 已提交
954 955
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
H
Hongze Cheng 已提交
956 957
  ASSERT(c == 0);

H
Hongze Cheng 已提交
958
  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
959
  oversion = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
960 961

  // search table.db
H
Hongze Cheng 已提交
962
  TBC     *pTbDbc = NULL;
H
Hongze Cheng 已提交
963 964
  SDecoder dc1 = {0};
  SDecoder dc2 = {0};
H
Hongze Cheng 已提交
965

H
Hongze Cheng 已提交
966
  /* get ctbEntry */
H
Hongze Cheng 已提交
967 968
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
H
Hongze Cheng 已提交
969
  ASSERT(c == 0);
H
Hongze Cheng 已提交
970
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
971

H
Hongze Cheng 已提交
972 973
  ctbEntry.pBuf = taosMemoryMalloc(nData);
  memcpy(ctbEntry.pBuf, pData, nData);
H
Hongze Cheng 已提交
974 975
  tDecoderInit(&dc1, ctbEntry.pBuf, nData);
  metaDecodeEntry(&dc1, &ctbEntry);
H
Hongze Cheng 已提交
976

H
Hongze Cheng 已提交
977
  /* get stbEntry*/
H
Hongze Cheng 已提交
978
  tdbTbGet(pMeta->pUidIdx, &ctbEntry.ctbEntry.suid, sizeof(tb_uid_t), &pVal, &nVal);
H
Hongze Cheng 已提交
979 980
  tdbTbGet(pMeta->pTbDb, &((STbDbKey){.uid = ctbEntry.ctbEntry.suid, .version = ((SUidIdxVal *)pVal)[0].version}),
           sizeof(STbDbKey), (void **)&stbEntry.pBuf, &nVal);
H
Hongze Cheng 已提交
981
  tdbFree(pVal);
H
Hongze Cheng 已提交
982 983
  tDecoderInit(&dc2, stbEntry.pBuf, nVal);
  metaDecodeEntry(&dc2, &stbEntry);
H
Hongze Cheng 已提交
984 985

  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
H
Hongze Cheng 已提交
986
  SSchema        *pColumn = NULL;
H
Hongze Cheng 已提交
987 988 989 990 991 992 993 994 995 996 997 998
  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) {
999
    terrno = TSDB_CODE_VND_COL_NOT_EXISTS;
H
Hongze Cheng 已提交
1000 1001
    goto _err;
  }
H
Hongze Cheng 已提交
1002

H
Hongze Cheng 已提交
1003
  ctbEntry.version = version;
H
Hongze Cheng 已提交
1004
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
1005
    ctbEntry.ctbEntry.pTags = taosMemoryMalloc(pAlterTbReq->nTagVal);
H
Hongze Cheng 已提交
1006
    if (ctbEntry.ctbEntry.pTags == NULL) {
wmmhello's avatar
wmmhello 已提交
1007 1008 1009
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _err;
    }
H
Hongze Cheng 已提交
1010 1011
    memcpy((void *)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
  } else {
C
Cary Xu 已提交
1012
    const STag *pOldTag = (const STag *)ctbEntry.ctbEntry.pTags;
H
Hongze Cheng 已提交
1013 1014
    STag       *pNewTag = NULL;
    SArray     *pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
C
Cary Xu 已提交
1015
    if (!pTagArray) {
C
Cary Xu 已提交
1016 1017 1018
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _err;
    }
wmmhello's avatar
wmmhello 已提交
1019 1020 1021
    for (int32_t i = 0; i < pTagSchema->nCols; i++) {
      SSchema *pCol = &pTagSchema->pSchema[i];
      if (iCol == i) {
1022 1023 1024
        if (pAlterTbReq->isNull) {
          continue;
        }
wmmhello's avatar
wmmhello 已提交
1025 1026 1027 1028 1029 1030
        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;
1031
        } else {
wmmhello's avatar
wmmhello 已提交
1032 1033 1034
          memcpy(&val.i64, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
        }
        taosArrayPush(pTagArray, &val);
wmmhello's avatar
wmmhello 已提交
1035
      } else {
wmmhello's avatar
wmmhello 已提交
1036
        STagVal val = {.cid = pCol->colId};
wmmhello's avatar
wmmhello 已提交
1037 1038
        if (tTagGet(pOldTag, &val)) {
          taosArrayPush(pTagArray, &val);
H
Hongze Cheng 已提交
1039 1040 1041
        }
      }
    }
C
Cary Xu 已提交
1042 1043
    if ((terrno = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag)) < 0) {
      taosArrayDestroy(pTagArray);
C
Cary Xu 已提交
1044 1045 1046
      goto _err;
    }
    ctbEntry.ctbEntry.pTags = (uint8_t *)pNewTag;
C
Cary Xu 已提交
1047
    taosArrayDestroy(pTagArray);
wmmhello's avatar
wmmhello 已提交
1048
  }
H
Hongze Cheng 已提交
1049

1050 1051
  metaWLock(pMeta);

H
Hongze Cheng 已提交
1052 1053 1054 1055
  // save to table.db
  metaSaveToTbDb(pMeta, &ctbEntry);

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

dengyihao's avatar
dengyihao 已提交
1058 1059 1060 1061
  if (iCol == 0) {
    metaUpdateTagIdx(pMeta, &ctbEntry);
  }

M
Minglei Jin 已提交
1062
  ASSERT(ctbEntry.ctbEntry.pTags);
1063
  SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid};
H
Hongze Cheng 已提交
1064 1065
  tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags,
              ((STag *)(ctbEntry.ctbEntry.pTags))->len, &pMeta->txn);
1066

1067 1068
  metaULock(pMeta);

H
Hongze Cheng 已提交
1069 1070
  tDecoderClear(&dc1);
  tDecoderClear(&dc2);
M
Minglei Jin 已提交
1071
  taosMemoryFree((void *)ctbEntry.ctbEntry.pTags);
H
Hongze Cheng 已提交
1072 1073
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
H
Hongze Cheng 已提交
1074 1075
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
1076
  return 0;
H
Hongze Cheng 已提交
1077 1078

_err:
H
Hongze Cheng 已提交
1079 1080
  tDecoderClear(&dc1);
  tDecoderClear(&dc2);
H
Hongze Cheng 已提交
1081 1082
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
H
Hongze Cheng 已提交
1083 1084
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
1085
  return -1;
H
Hongze Cheng 已提交
1086 1087 1088
}

static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
H
Hongze Cheng 已提交
1089 1090 1091 1092 1093 1094 1095 1096 1097
  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 已提交
1098 1099 1100 1101

  // search name index
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
  if (ret < 0) {
1102
    terrno = TSDB_CODE_TDB_TABLE_NOT_EXIST;
wmmhello's avatar
wmmhello 已提交
1103
    return -1;
1104
  }
wmmhello's avatar
wmmhello 已提交
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117

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

  // search uid index
  TBC *pUidIdxc = NULL;

  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
  ASSERT(c == 0);

  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
1118
  oversion = ((SUidIdxVal *)pData)[0].version;
wmmhello's avatar
wmmhello 已提交
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139

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

  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
  ASSERT(c == 0);
  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);
  ASSERT(ret == 0);

  entry.version = version;
  metaWLock(pMeta);
  // build SMetaEntry
  if (entry.type == TSDB_CHILD_TABLE) {
H
Hongze Cheng 已提交
1140
    if (pAlterTbReq->updateTTL) {
wmmhello's avatar
wmmhello 已提交
1141 1142 1143 1144
      metaDeleteTtlIdx(pMeta, &entry);
      entry.ctbEntry.ttlDays = pAlterTbReq->newTTL;
      metaUpdateTtlIdx(pMeta, &entry);
    }
H
Hongze Cheng 已提交
1145
    if (pAlterTbReq->newCommentLen >= 0) {
wmmhello's avatar
wmmhello 已提交
1146 1147 1148
      entry.ctbEntry.commentLen = pAlterTbReq->newCommentLen;
      entry.ctbEntry.comment = pAlterTbReq->newComment;
    }
wmmhello's avatar
wmmhello 已提交
1149
  } else {
H
Hongze Cheng 已提交
1150
    if (pAlterTbReq->updateTTL) {
wmmhello's avatar
wmmhello 已提交
1151 1152 1153 1154
      metaDeleteTtlIdx(pMeta, &entry);
      entry.ntbEntry.ttlDays = pAlterTbReq->newTTL;
      metaUpdateTtlIdx(pMeta, &entry);
    }
H
Hongze Cheng 已提交
1155
    if (pAlterTbReq->newCommentLen >= 0) {
wmmhello's avatar
wmmhello 已提交
1156 1157 1158
      entry.ntbEntry.commentLen = pAlterTbReq->newCommentLen;
      entry.ntbEntry.comment = pAlterTbReq->newComment;
    }
1159
  }
wmmhello's avatar
wmmhello 已提交
1160 1161 1162

  // save to table db
  metaSaveToTbDb(pMeta, &entry);
H
Hongze Cheng 已提交
1163
  metaUpdateUidIdx(pMeta, &entry);
wmmhello's avatar
wmmhello 已提交
1164 1165 1166 1167
  metaULock(pMeta);

  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
1168
  tDecoderClear(&dc);
wmmhello's avatar
wmmhello 已提交
1169
  if (entry.pBuf) taosMemoryFree(entry.pBuf);
H
Hongze Cheng 已提交
1170 1171 1172
  return 0;
}

D
dapan1121 已提交
1173
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
H
Hongze Cheng 已提交
1174 1175 1176 1177 1178
  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 已提交
1179
      return metaAlterTableColumn(pMeta, version, pReq, pMetaRsp);
H
Hongze Cheng 已提交
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
    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 已提交
1191
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1192
  STbDbKey tbDbKey;
H
Hongze Cheng 已提交
1193 1194
  void    *pKey = NULL;
  void    *pVal = NULL;
H
Hongze Cheng 已提交
1195 1196
  int      kLen = 0;
  int      vLen = 0;
H
Hongze Cheng 已提交
1197
  SEncoder coder = {0};
H
Hongze Cheng 已提交
1198 1199

  // set key and value
H
Hongze Cheng 已提交
1200
  tbDbKey.version = pME->version;
H
Hongze Cheng 已提交
1201 1202
  tbDbKey.uid = pME->uid;

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

H
Hongze Cheng 已提交
1206 1207
  pKey = &tbDbKey;
  kLen = sizeof(tbDbKey);
H
Hongze Cheng 已提交
1208

wafwerar's avatar
wafwerar 已提交
1209 1210 1211
  int32_t ret = 0;
  tEncodeSize(metaEncodeEntry, pME, vLen, ret);
  if (ret < 0) {
H
Hongze Cheng 已提交
1212 1213 1214 1215 1216 1217 1218 1219 1220
    goto _err;
  }

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

H
Hongze Cheng 已提交
1221
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
1222 1223 1224 1225 1226

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

H
Hongze Cheng 已提交
1227
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
1228 1229

  // write to table.db
H
Hongze Cheng 已提交
1230
  if (tdbTbInsert(pMeta->pTbDb, pKey, kLen, pVal, vLen, &pMeta->txn) < 0) {
H
Hongze Cheng 已提交
1231 1232 1233 1234 1235 1236 1237
    goto _err;
  }

  taosMemoryFree(pVal);
  return 0;

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

H
Hongze Cheng 已提交
1241 1242 1243 1244
  taosMemoryFree(pVal);
  return -1;
}

H
Hongze Cheng 已提交
1245
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1246 1247 1248 1249 1250 1251 1252 1253
  // upsert cache
  SMetaInfo info;
  metaGetEntryInfo(pME, &info);
  metaCacheUpsert(pMeta, &info);

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

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

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

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

H
Hongze Cheng 已提交
1264
static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
1265 1266
  STtlIdxKey ttlKey = {0};
  metaBuildTtlIdxKey(&ttlKey, pME);
H
Hongze Cheng 已提交
1267
  if (ttlKey.dtime == 0) return 0;
H
Hongze Cheng 已提交
1268
  return tdbTbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
1269 1270
}

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

H
Hongze Cheng 已提交
1274 1275
  return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags,
                     ((STag *)(pME->ctbEntry.pTags))->len, &pMeta->txn);
H
Hongze Cheng 已提交
1276 1277
}

wmmhello's avatar
wmmhello 已提交
1278
int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
1279
                        STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
dengyihao's avatar
dengyihao 已提交
1280 1281 1282 1283 1284
  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 已提交
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295

  *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 已提交
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305

  // 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 已提交
1306 1307 1308 1309 1310 1311 1312 1313 1314

  return 0;
}

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

static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
H
Hongze Cheng 已提交
1315
  void          *pData = NULL;
H
Hongze Cheng 已提交
1316 1317 1318
  int            nData = 0;
  STbDbKey       tbDbKey = {0};
  SMetaEntry     stbEntry = {0};
H
Hongze Cheng 已提交
1319
  STagIdxKey    *pTagIdxKey = NULL;
H
Hongze Cheng 已提交
1320
  int32_t        nTagIdxKey;
M
Minglei Jin 已提交
1321 1322
  const SSchema *pTagColumn;
  const void    *pTagData = NULL;
C
Cary Xu 已提交
1323
  int32_t        nTagData = 0;
H
Hongze Cheng 已提交
1324
  SDecoder       dc = {0};
1325
  int32_t        ret = 0;
H
Hongze Cheng 已提交
1326
  // get super table
H
Hongze Cheng 已提交
1327
  if (tdbTbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData) != 0) {
1328 1329
    ret = -1;
    goto end;
wmmhello's avatar
wmmhello 已提交
1330
  }
H
Hongze Cheng 已提交
1331
  tbDbKey.uid = pCtbEntry->ctbEntry.suid;
H
Hongze Cheng 已提交
1332
  tbDbKey.version = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
1333
  tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData);
H
Hongze Cheng 已提交
1334 1335

  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
1336 1337 1338 1339
  ret = metaDecodeEntry(&dc, &stbEntry);
  if (ret < 0) {
    goto end;
  }
H
Hongze Cheng 已提交
1340 1341

  pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
C
Cary Xu 已提交
1342 1343

  STagVal tagVal = {.cid = pTagColumn->colId};
1344
  if (pTagColumn->type != TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
1345
    tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal);
1346
    if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
wmmhello's avatar
wmmhello 已提交
1347 1348
      pTagData = tagVal.pData;
      nTagData = (int32_t)tagVal.nData;
1349
    } else {
wmmhello's avatar
wmmhello 已提交
1350 1351 1352
      pTagData = &(tagVal.i64);
      nTagData = tDataTypes[pTagColumn->type].bytes;
    }
1353 1354 1355
  } else {
    // pTagData = pCtbEntry->ctbEntry.pTags;
    // nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
dengyihao's avatar
dengyihao 已提交
1356 1357
    pTagData = pCtbEntry->ctbEntry.pTags;
    nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
1358 1359
    ret = metaSaveJsonVarToIdx(pMeta, pCtbEntry, pTagColumn);
    goto end;
wmmhello's avatar
wmmhello 已提交
1360
  }
dengyihao's avatar
dengyihao 已提交
1361 1362 1363 1364 1365 1366 1367
  if (pTagData != NULL) {
    if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
                            pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
      ret = -1;
      goto end;
    }
    tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
1368
  }
1369
end:
H
Hongze Cheng 已提交
1370 1371 1372
  metaDestroyTagIdxKey(pTagIdxKey);
  tDecoderClear(&dc);
  tdbFree(pData);
1373
  return ret;
H
Hongze Cheng 已提交
1374 1375
}

H
Hongze Cheng 已提交
1376
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1377
  SEncoder              coder = {0};
H
Hongze Cheng 已提交
1378
  void                 *pVal = NULL;
H
Hongze Cheng 已提交
1379 1380 1381 1382 1383 1384
  int                   vLen = 0;
  int                   rcode = 0;
  SSkmDbKey             skmDbKey = {0};
  const SSchemaWrapper *pSW;

  if (pME->type == TSDB_SUPER_TABLE) {
1385
    pSW = &pME->stbEntry.schemaRow;
H
Hongze Cheng 已提交
1386
  } else if (pME->type == TSDB_NORMAL_TABLE) {
1387
    pSW = &pME->ntbEntry.schemaRow;
H
Hongze Cheng 已提交
1388 1389
  } else {
    ASSERT(0);
H
Hongze Cheng 已提交
1390 1391
  }

H
Hongze Cheng 已提交
1392
  skmDbKey.uid = pME->uid;
1393
  skmDbKey.sver = pSW->version;
H
Hongze Cheng 已提交
1394

1395 1396 1397 1398 1399
  // 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 已提交
1400
  // encode schema
wafwerar's avatar
wafwerar 已提交
1401 1402 1403
  int32_t ret = 0;
  tEncodeSize(tEncodeSSchemaWrapper, pSW, vLen, ret);
  if (ret < 0) return -1;
H
Hongze Cheng 已提交
1404
  pVal = taosMemoryMalloc(vLen);
H
Hongze Cheng 已提交
1405 1406 1407 1408 1409 1410
  if (pVal == NULL) {
    rcode = -1;
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

H
Hongze Cheng 已提交
1411
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
1412 1413
  tEncodeSSchemaWrapper(&coder, pSW);

H
Hongze Cheng 已提交
1414
  if (tdbTbInsert(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, &pMeta->txn) < 0) {
H
Hongze Cheng 已提交
1415 1416 1417 1418
    rcode = -1;
    goto _exit;
  }

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

H
Hongze Cheng 已提交
1422
_exit:
H
Hongze Cheng 已提交
1423
  taosMemoryFree(pVal);
H
Hongze Cheng 已提交
1424
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
1425 1426 1427
  return rcode;
}

H
Hongze Cheng 已提交
1428
int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
1429 1430
  metaWLock(pMeta);

H
Hongze Cheng 已提交
1431
  // save to table.db
H
Hongze Cheng 已提交
1432
  if (metaSaveToTbDb(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1433 1434

  // update uid.idx
H
Hongze Cheng 已提交
1435
  if (metaUpdateUidIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1436 1437

  // update name.idx
H
Hongze Cheng 已提交
1438
  if (metaUpdateNameIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1439 1440 1441

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

    // update tag.idx
H
Hongze Cheng 已提交
1445
    if (metaUpdateTagIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1446 1447
  } else {
    // update schema.db
H
Hongze Cheng 已提交
1448
    if (metaSaveToSkmDb(pMeta, pME) < 0) goto _err;
C
Cary Xu 已提交
1449 1450 1451

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

dengyihao's avatar
dengyihao 已提交
1455 1456 1457 1458 1459 1460
  if (metaUpdateCtimeIdx(pMeta, pME) < 0) goto _err;

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

H
Hongze Cheng 已提交
1461
  if (pME->type != TSDB_SUPER_TABLE) {
H
Hongze Cheng 已提交
1462
    if (metaUpdateTtlIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
1463 1464
  }

H
Hongze Cheng 已提交
1465
  metaULock(pMeta);
H
Hongze Cheng 已提交
1466
  return 0;
H
Hongze Cheng 已提交
1467 1468 1469 1470

_err:
  metaULock(pMeta);
  return -1;
1471
}
dengyihao's avatar
dengyihao 已提交
1472
// refactor later
dengyihao's avatar
dengyihao 已提交
1473 1474
void *metaGetIdx(SMeta *pMeta) { return pMeta->pTagIdx; }
void *metaGetIvtIdx(SMeta *pMeta) { return pMeta->pTagIvtIdx; }