metaTable.c 29.2 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
static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
H
Hongze Cheng 已提交
19 20 21 22 23 24 25
static int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME);
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);
H
Hongze Cheng 已提交
26
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry);
H
Hongze Cheng 已提交
27
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type);
H
Hongze Cheng 已提交
28

dengyihao's avatar
dengyihao 已提交
29
static int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
D
dapan1121 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
  pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
  if (NULL == pMetaRsp->pSchemas) {
    terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
    return -1;
  }

  strcpy(pMetaRsp->tbName, tbName);
  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 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
#ifdef USE_INVERTED_INDEX
  if (pMeta->pTagIvtIdx == NULL || pCtbEntry == NULL) {
    return -1;
  }
  void *      data = pCtbEntry->ctbEntry.pTags;
  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;

    char *Key = pTagVal->pKey;
    char *key = taosMemoryCalloc(1, strlen(Key) + 2 + strlen(tagName));
    sprintf(key, "%s_%s", tagName, Key);

    int32_t     nKey = strlen(key);
    SIndexTerm *term = NULL;

    if (type == TSDB_DATA_TYPE_NULL) {
    } else if (type == TSDB_DATA_TYPE_NCHAR) {
      if (pTagVal->nData > 0) {
        char *  val = taosMemoryCalloc(1, pTagVal->nData);
        int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val);
        // printf("val: %s, len: %d", val, len);

        char *tval = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
        memcpy(tval, (uint16_t *)&len, VARSTR_HEADER_SIZE);
        memcpy(tval + VARSTR_HEADER_SIZE, val, len);
        type = TSDB_DATA_TYPE_VARCHAR;
        term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, tval, len + 2);
      } else if (pTagVal->nData == 0) {
        char *  val = NULL;
        int32_t len = 0;
        // handle NULL key
      }
    } else if (type == TSDB_DATA_TYPE_DOUBLE) {
      double val = *(double *)(&pTagVal->i64);
      int    len = 0;
      term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
    } else if (type == TSDB_DATA_TYPE_BOOL) {
      int val = *(int *)(&pTagVal->i64);
      int len = 0;
      term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
    }
    if (term == NULL) {
      // handle except later
    } else {
      indexMultiTermAdd(terms, term);
    }
    taosMemoryFree(key);
  }
  tIndexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
  indexMultiTermDestroy(terms);
#endif
  return -1;
}

H
Hongze Cheng 已提交
116
int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
H
Hongze Cheng 已提交
117
  SMetaEntry  me = {0};
H
Hongze Cheng 已提交
118 119 120 121
  int         kLen = 0;
  int         vLen = 0;
  const void *pKey = NULL;
  const void *pVal = NULL;
dengyihao's avatar
dengyihao 已提交
122
  void *      pBuf = NULL;
H
Hongze Cheng 已提交
123
  int32_t     szBuf = 0;
dengyihao's avatar
dengyihao 已提交
124
  void *      p = NULL;
H
Hongze Cheng 已提交
125 126 127
  SMetaReader mr = {0};

  // validate req
H
Hongze Cheng 已提交
128
  metaReaderInit(&mr, pMeta, 0);
H
Hongze Cheng 已提交
129
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
H
Hongze Cheng 已提交
130 131
// TODO: just for pass case
#if 0
H
Hongze Cheng 已提交
132 133 134
    terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
    metaReaderClear(&mr);
    return -1;
H
Hongze Cheng 已提交
135 136 137 138
#else
    metaReaderClear(&mr);
    return 0;
#endif
H
Hongze Cheng 已提交
139
  }
H
Hongze Cheng 已提交
140
  metaReaderClear(&mr);
H
Hongze Cheng 已提交
141 142

  // set structs
H
Hongze Cheng 已提交
143
  me.version = version;
H
Hongze Cheng 已提交
144 145 146
  me.type = TSDB_SUPER_TABLE;
  me.uid = pReq->suid;
  me.name = pReq->name;
147
  me.stbEntry.schemaRow = pReq->schemaRow;
H
Hongze Cheng 已提交
148
  me.stbEntry.schemaTag = pReq->schemaTag;
H
Hongze Cheng 已提交
149

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

S
Shengliang Guan 已提交
152
  metaDebug("vgId:%d, super table is created, name:%s uid: %" PRId64, TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
H
Hongze Cheng 已提交
153 154 155 156

  return 0;

_err:
S
Shengliang Guan 已提交
157
  metaError("vgId:%d, failed to create super table: %s uid: %" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
H
Hongze Cheng 已提交
158 159 160 161 162
            pReq->suid, tstrerror(terrno));
  return -1;
}

int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
H
Hongze Cheng 已提交
163 164 165 166 167 168 169 170 171 172 173 174
  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) {
    terrno = TSDB_CODE_VND_TABLE_NOT_EXIST;
    return -1;
H
Hongze Cheng 已提交
175 176
  }

H
Hongze Cheng 已提交
177
  // drop all child tables
dengyihao's avatar
dengyihao 已提交
178
  TBC *   pCtbIdxc = NULL;
H
Hongze Cheng 已提交
179
  SArray *pArray = taosArrayInit(8, sizeof(tb_uid_t));
H
Hongze Cheng 已提交
180

H
Hongze Cheng 已提交
181
  tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, &pMeta->txn);
H
Hongze Cheng 已提交
182 183
  rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = pReq->suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
  if (rc < 0) {
H
Hongze Cheng 已提交
184
    tdbTbcClose(pCtbIdxc);
H
Hongze Cheng 已提交
185 186
    metaWLock(pMeta);
    goto _drop_super_table;
H
Hongze Cheng 已提交
187 188 189
  }

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

H
Hongze Cheng 已提交
193 194 195 196 197
    if (((SCtbIdxKey *)pKey)->suid < pReq->suid) {
      continue;
    } else if (((SCtbIdxKey *)pKey)->suid > pReq->suid) {
      break;
    }
H
Hongze Cheng 已提交
198

H
Hongze Cheng 已提交
199 200 201 202 203 204
    taosArrayPush(pArray, &(((SCtbIdxKey *)pKey)->uid));
  }

  tdbTbcClose(pCtbIdxc);

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

H
Hongze Cheng 已提交
206 207
  for (int32_t iChild = 0; iChild < taosArrayGetSize(pArray); iChild++) {
    tb_uid_t uid = *(tb_uid_t *)taosArrayGet(pArray, iChild);
H
Hongze Cheng 已提交
208
    metaDropTableByUid(pMeta, uid, NULL);
H
Hongze Cheng 已提交
209 210
  }

H
Hongze Cheng 已提交
211 212 213 214 215 216 217 218 219 220 221 222
  taosArrayDestroy(pArray);

  // drop super table
_drop_super_table:
  tdbTbGet(pMeta->pUidIdx, &pReq->suid, sizeof(tb_uid_t), &pData, &nData);
  tdbTbDelete(pMeta->pTbDb, &(STbDbKey){.version = *(int64_t *)pData, .uid = pReq->suid}, 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);

  metaULock(pMeta);

H
Hongze Cheng 已提交
223
_exit:
H
Hongze Cheng 已提交
224 225
  tdbFree(pKey);
  tdbFree(pData);
S
Shengliang Guan 已提交
226
  metaDebug("vgId:%d,  super table %s uid:%" PRId64 " is dropped", TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
H
Hongze Cheng 已提交
227 228 229
  return 0;
}

H
Hongze Cheng 已提交
230 231 232
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
  SMetaEntry  oStbEntry = {0};
  SMetaEntry  nStbEntry = {0};
dengyihao's avatar
dengyihao 已提交
233 234
  TBC *       pUidIdxc = NULL;
  TBC *       pTbDbc = NULL;
H
Hongze Cheng 已提交
235 236 237 238 239 240 241
  const void *pData;
  int         nData;
  int64_t     oversion;
  SDecoder    dc = {0};
  int32_t     ret;
  int32_t     c;

H
Hongze Cheng 已提交
242 243
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  ret = tdbTbcMoveTo(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &c);
H
Hongze Cheng 已提交
244 245 246 247 248
  if (ret < 0 || c) {
    ASSERT(0);
    return -1;
  }

H
Hongze Cheng 已提交
249
  ret = tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
250 251 252 253 254 255 256
  if (ret < 0) {
    ASSERT(0);
    return -1;
  }

  oversion = *(int64_t *)pData;

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

H
Hongze Cheng 已提交
261
  ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
262 263
  ASSERT(ret == 0);

H
Hongze Cheng 已提交
264 265 266
  oStbEntry.pBuf = taosMemoryMalloc(nData);
  memcpy(oStbEntry.pBuf, pData, nData);
  tDecoderInit(&dc, oStbEntry.pBuf, nData);
H
Hongze Cheng 已提交
267 268 269 270 271 272
  metaDecodeEntry(&dc, &oStbEntry);

  nStbEntry.version = version;
  nStbEntry.type = TSDB_SUPER_TABLE;
  nStbEntry.uid = pReq->suid;
  nStbEntry.name = pReq->name;
273
  nStbEntry.stbEntry.schemaRow = pReq->schemaRow;
H
Hongze Cheng 已提交
274 275 276 277
  nStbEntry.stbEntry.schemaTag = pReq->schemaTag;

  metaWLock(pMeta);
  // compare two entry
278 279
  if (oStbEntry.stbEntry.schemaRow.version != pReq->schemaRow.version) {
    metaSaveToSkmDb(pMeta, &nStbEntry);
H
Hongze Cheng 已提交
280 281 282 283 284 285 286 287 288 289
  }

  // if (oStbEntry.stbEntry.schemaTag.sver != pReq->schemaTag.sver) {
  //   // change tag schema
  // }

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

  // update uid index
H
Hongze Cheng 已提交
290
  tdbTbcUpsert(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &version, sizeof(version), 0);
H
Hongze Cheng 已提交
291

H
Hongze Cheng 已提交
292
  if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
H
Hongze Cheng 已提交
293 294
  metaULock(pMeta);
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
295 296
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
297 298 299
  return 0;
}

H
Hongze Cheng 已提交
300
int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
H
Hongze Cheng 已提交
301 302
  SMetaEntry  me = {0};
  SMetaReader mr = {0};
H
Hongze Cheng 已提交
303 304 305 306 307

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

H
Hongze Cheng 已提交
310
  // validate req
H
Hongze Cheng 已提交
311
  metaReaderInit(&mr, pMeta, 0);
H
Hongze Cheng 已提交
312
  if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
H
Hongze Cheng 已提交
313 314 315 316
    pReq->uid = mr.me.uid;
    if (pReq->type == TSDB_CHILD_TABLE) {
      pReq->ctb.suid = mr.me.ctbEntry.suid;
    }
H
Hongze Cheng 已提交
317 318 319
    terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
    metaReaderClear(&mr);
    return -1;
H
Hongze Cheng 已提交
320
  }
H
Hongze Cheng 已提交
321
  metaReaderClear(&mr);
H
Hongze Cheng 已提交
322 323

  // build SMetaEntry
H
Hongze Cheng 已提交
324
  me.version = version;
H
Hongze Cheng 已提交
325 326 327 328 329 330 331 332 333 334 335
  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;
    me.ctbEntry.suid = pReq->ctb.suid;
    me.ctbEntry.pTags = pReq->ctb.pTag;
  } else {
    me.ntbEntry.ctime = pReq->ctime;
    me.ntbEntry.ttlDays = pReq->ttl;
336 337
    me.ntbEntry.schemaRow = pReq->ntb.schemaRow;
    me.ntbEntry.ncid = me.ntbEntry.schemaRow.pSchema[me.ntbEntry.schemaRow.nCols - 1].colId + 1;
H
more  
Hongze Cheng 已提交
338 339
  }

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

S
Shengliang Guan 已提交
342
  metaDebug("vgId:%d, table %s uid %" PRId64 " is created, type:%" PRId8, TD_VID(pMeta->pVnode), pReq->name, pReq->uid,
H
Hongze Cheng 已提交
343
            pReq->type);
H
refact  
Hongze Cheng 已提交
344
  return 0;
H
Hongze Cheng 已提交
345 346

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

352
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids) {
dengyihao's avatar
dengyihao 已提交
353
  void *   pData = NULL;
H
Hongze Cheng 已提交
354 355 356 357
  int      nData = 0;
  int      rc = 0;
  tb_uid_t uid;
  int      type;
H
more  
Hongze Cheng 已提交
358

H
Hongze Cheng 已提交
359 360 361
  rc = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &pData, &nData);
  if (rc < 0) {
    terrno = TSDB_CODE_VND_TABLE_NOT_EXIST;
H
more  
Hongze Cheng 已提交
362 363
    return -1;
  }
H
Hongze Cheng 已提交
364 365
  uid = *(tb_uid_t *)pData;

H
Hongze Cheng 已提交
366 367 368
  metaWLock(pMeta);
  metaDropTableByUid(pMeta, uid, &type);
  metaULock(pMeta);
H
Hongze Cheng 已提交
369

H
Hongze Cheng 已提交
370 371
  if (type == TSDB_CHILD_TABLE && tbUids) {
    taosArrayPush(tbUids, &uid);
H
Hongze Cheng 已提交
372
  }
H
Hongze Cheng 已提交
373

H
Hongze Cheng 已提交
374 375 376
  tdbFree(pData);
  return 0;
}
H
Hongze Cheng 已提交
377

H
Hongze Cheng 已提交
378
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
dengyihao's avatar
dengyihao 已提交
379
  void *     pData = NULL;
H
Hongze Cheng 已提交
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
  int        nData = 0;
  int        rc = 0;
  int64_t    version;
  SMetaEntry e = {0};
  SDecoder   dc = {0};

  rc = tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData);
  version = *(int64_t *)pData;

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

  tDecoderInit(&dc, pData, nData);
  metaDecodeEntry(&dc, &e);

  if (type) *type = e.type;

  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);
  if (e.type == TSDB_CHILD_TABLE) {
    tdbTbDelete(pMeta->pCtbIdx, &(SCtbIdxKey){.suid = e.ctbEntry.suid, .uid = uid}, sizeof(SCtbIdxKey), &pMeta->txn);
  } else if (e.type == TSDB_NORMAL_TABLE) {
    // drop schema.db (todo)
    // drop ttl.idx (todo)
  } else if (e.type == TSDB_SUPER_TABLE) {
    // drop schema.db (todo)
H
Hongze Cheng 已提交
406 407
  }

H
Hongze Cheng 已提交
408 409
  tDecoderClear(&dc);
  tdbFree(pData);
H
Hongze Cheng 已提交
410

H
refact  
Hongze Cheng 已提交
411 412
  return 0;
}
H
Hongze Cheng 已提交
413

D
dapan1121 已提交
414
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq, STableMetaRsp *pMetaRsp) {
dengyihao's avatar
dengyihao 已提交
415
  void *          pVal = NULL;
H
Hongze Cheng 已提交
416
  int             nVal = 0;
dengyihao's avatar
dengyihao 已提交
417
  const void *    pData = NULL;
H
Hongze Cheng 已提交
418 419 420 421
  int             nData = 0;
  int             ret = 0;
  tb_uid_t        uid;
  int64_t         oversion;
dengyihao's avatar
dengyihao 已提交
422
  SSchema *       pColumn = NULL;
H
Hongze Cheng 已提交
423 424 425 426 427
  SMetaEntry      entry = {0};
  SSchemaWrapper *pSchema;
  int             c;

  // search name index
H
Hongze Cheng 已提交
428
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
H
Hongze Cheng 已提交
429 430 431 432 433 434 435 436 437 438
  if (ret < 0) {
    terrno = TSDB_CODE_VND_TABLE_NOT_EXIST;
    return -1;
  }

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

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

H
Hongze Cheng 已提交
441 442
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
H
Hongze Cheng 已提交
443 444
  ASSERT(c == 0);

H
Hongze Cheng 已提交
445
  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
446 447 448
  oversion = *(int64_t *)pData;

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

H
Hongze Cheng 已提交
451 452
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
H
Hongze Cheng 已提交
453
  ASSERT(c == 0);
H
Hongze Cheng 已提交
454
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
455 456 457

  // get table entry
  SDecoder dc = {0};
H
Hongze Cheng 已提交
458 459 460
  entry.pBuf = taosMemoryMalloc(nData);
  memcpy(entry.pBuf, pData, nData);
  tDecoderInit(&dc, entry.pBuf, nData);
H
Hongze Cheng 已提交
461 462
  ret = metaDecodeEntry(&dc, &entry);
  ASSERT(ret == 0);
H
Hongze Cheng 已提交
463 464 465 466 467 468 469

  if (entry.type != TSDB_NORMAL_TABLE) {
    terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
    goto _err;
  }

  // search the column to add/drop/update
470
  pSchema = &entry.ntbEntry.schemaRow;
H
Hongze Cheng 已提交
471 472 473 474 475 476 477 478 479 480 481 482
  int32_t iCol = 0;
  for (;;) {
    pColumn = NULL;

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

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

  entry.version = version;
H
Hongze Cheng 已提交
483 484
  int      tlen;
  SSchema *pNewSchema = NULL;
H
Hongze Cheng 已提交
485 486 487 488 489 490
  switch (pAlterTbReq->action) {
    case TSDB_ALTER_TABLE_ADD_COLUMN:
      if (pColumn) {
        terrno = TSDB_CODE_VND_COL_ALREADY_EXISTS;
        goto _err;
      }
491
      pSchema->version++;
H
Hongze Cheng 已提交
492
      pSchema->nCols++;
H
Hongze Cheng 已提交
493 494 495
      pNewSchema = taosMemoryMalloc(sizeof(SSchema) * pSchema->nCols);
      memcpy(pNewSchema, pSchema->pSchema, sizeof(SSchema) * (pSchema->nCols - 1));
      pSchema->pSchema = pNewSchema;
496 497 498 499 500
      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);
H
Hongze Cheng 已提交
501 502 503 504 505 506 507 508 509 510
      break;
    case TSDB_ALTER_TABLE_DROP_COLUMN:
      if (pColumn == NULL) {
        terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS;
        goto _err;
      }
      if (pColumn->colId == 0) {
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
        goto _err;
      }
511
      pSchema->version++;
H
Hongze Cheng 已提交
512 513 514 515
      tlen = (pSchema->nCols - iCol - 1) * sizeof(SSchema);
      if (tlen) {
        memmove(pColumn, pColumn + 1, tlen);
      }
H
Hongze Cheng 已提交
516
      pSchema->nCols--;
H
Hongze Cheng 已提交
517 518 519 520 521 522
      break;
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
      if (pColumn == NULL) {
        terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS;
        goto _err;
      }
H
Hongze Cheng 已提交
523
      if (!IS_VAR_DATA_TYPE(pColumn->type) || pColumn->bytes > pAlterTbReq->colModBytes) {
H
Hongze Cheng 已提交
524 525 526
        terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
        goto _err;
      }
527
      pSchema->version++;
H
Hongze Cheng 已提交
528
      pColumn->bytes = pAlterTbReq->colModBytes;
H
Hongze Cheng 已提交
529 530 531 532 533 534
      break;
    case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
      if (pColumn == NULL) {
        terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS;
        goto _err;
      }
535
      pSchema->version++;
H
Hongze Cheng 已提交
536 537 538 539 540 541
      strcpy(pColumn->name, pAlterTbReq->colNewName);
      break;
  }

  entry.version = version;

H
Hongze Cheng 已提交
542 543 544 545 546 547
  // do actual write
  metaWLock(pMeta);

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

H
Hongze Cheng 已提交
548
  tdbTbcUpsert(pUidIdxc, &entry.uid, sizeof(tb_uid_t), &version, sizeof(version), 0);
H
Hongze Cheng 已提交
549 550 551 552 553

  metaSaveToSkmDb(pMeta, &entry);

  metaULock(pMeta);

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

H
Hongze Cheng 已提交
556
  if (pNewSchema) taosMemoryFree(pNewSchema);
H
Hongze Cheng 已提交
557
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
558 559
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
560
  return 0;
H
Hongze Cheng 已提交
561 562 563

_err:
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
564 565
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
566
  return -1;
H
Hongze Cheng 已提交
567 568 569
}

static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
H
Hongze Cheng 已提交
570 571
  SMetaEntry  ctbEntry = {0};
  SMetaEntry  stbEntry = {0};
dengyihao's avatar
dengyihao 已提交
572
  void *      pVal = NULL;
H
Hongze Cheng 已提交
573 574 575 576 577 578 579 580 581
  int         nVal = 0;
  int         ret;
  int         c;
  tb_uid_t    uid;
  int64_t     oversion;
  const void *pData = NULL;
  int         nData = 0;

  // search name index
H
Hongze Cheng 已提交
582
  ret = tdbTbGet(pMeta->pNameIdx, pAlterTbReq->tbName, strlen(pAlterTbReq->tbName) + 1, &pVal, &nVal);
H
Hongze Cheng 已提交
583 584 585 586 587 588 589 590 591 592
  if (ret < 0) {
    terrno = TSDB_CODE_VND_TABLE_NOT_EXIST;
    return -1;
  }

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

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

H
Hongze Cheng 已提交
595 596
  tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, &pMeta->txn);
  tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
H
Hongze Cheng 已提交
597 598
  ASSERT(c == 0);

H
Hongze Cheng 已提交
599
  tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
600 601 602
  oversion = *(int64_t *)pData;

  // search table.db
dengyihao's avatar
dengyihao 已提交
603
  TBC *    pTbDbc = NULL;
H
Hongze Cheng 已提交
604 605
  SDecoder dc1 = {0};
  SDecoder dc2 = {0};
H
Hongze Cheng 已提交
606

H
Hongze Cheng 已提交
607
  /* get ctbEntry */
H
Hongze Cheng 已提交
608 609
  tdbTbcOpen(pMeta->pTbDb, &pTbDbc, &pMeta->txn);
  tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
H
Hongze Cheng 已提交
610
  ASSERT(c == 0);
H
Hongze Cheng 已提交
611
  tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
H
Hongze Cheng 已提交
612

H
Hongze Cheng 已提交
613 614
  ctbEntry.pBuf = taosMemoryMalloc(nData);
  memcpy(ctbEntry.pBuf, pData, nData);
H
Hongze Cheng 已提交
615 616
  tDecoderInit(&dc1, ctbEntry.pBuf, nData);
  metaDecodeEntry(&dc1, &ctbEntry);
H
Hongze Cheng 已提交
617

H
Hongze Cheng 已提交
618
  /* get stbEntry*/
H
Hongze Cheng 已提交
619 620 621
  tdbTbGet(pMeta->pUidIdx, &ctbEntry.ctbEntry.suid, sizeof(tb_uid_t), &pVal, &nVal);
  tdbTbGet(pMeta->pTbDb, &((STbDbKey){.uid = ctbEntry.ctbEntry.suid, .version = *(int64_t *)pVal}), sizeof(STbDbKey),
           (void **)&stbEntry.pBuf, &nVal);
H
Hongze Cheng 已提交
622
  tdbFree(pVal);
H
Hongze Cheng 已提交
623 624
  tDecoderInit(&dc2, stbEntry.pBuf, nVal);
  metaDecodeEntry(&dc2, &stbEntry);
H
Hongze Cheng 已提交
625 626

  SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
dengyihao's avatar
dengyihao 已提交
627
  SSchema *       pColumn = NULL;
H
Hongze Cheng 已提交
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
  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) {
    terrno = TSDB_CODE_VND_TABLE_COL_NOT_EXISTS;
    goto _err;
  }
H
Hongze Cheng 已提交
643

H
Hongze Cheng 已提交
644 645
  if (iCol == 0) {
    // TODO : need to update tag index
H
Hongze Cheng 已提交
646
  }
H
Hongze Cheng 已提交
647
  ctbEntry.version = version;
H
Hongze Cheng 已提交
648
  if (pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
649
    ctbEntry.ctbEntry.pTags = taosMemoryMalloc(pAlterTbReq->nTagVal);
H
Hongze Cheng 已提交
650
    if (ctbEntry.ctbEntry.pTags == NULL) {
wmmhello's avatar
wmmhello 已提交
651 652 653
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _err;
    }
H
Hongze Cheng 已提交
654 655
    memcpy((void *)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
  } else {
C
Cary Xu 已提交
656
    const STag *pOldTag = (const STag *)ctbEntry.ctbEntry.pTags;
dengyihao's avatar
dengyihao 已提交
657 658
    STag *      pNewTag = NULL;
    SArray *    pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
C
Cary Xu 已提交
659
    if (!pTagArray) {
C
Cary Xu 已提交
660 661 662
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _err;
    }
wmmhello's avatar
wmmhello 已提交
663 664 665
    for (int32_t i = 0; i < pTagSchema->nCols; i++) {
      SSchema *pCol = &pTagSchema->pSchema[i];
      if (iCol == i) {
wmmhello's avatar
wmmhello 已提交
666 667 668 669 670 671
        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;
672
        } else {
wmmhello's avatar
wmmhello 已提交
673 674 675
          memcpy(&val.i64, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
        }
        taosArrayPush(pTagArray, &val);
wmmhello's avatar
wmmhello 已提交
676
      } else {
wmmhello's avatar
wmmhello 已提交
677
        STagVal val = {.cid = pCol->colId};
wmmhello's avatar
wmmhello 已提交
678 679
        if (tTagGet(pOldTag, &val)) {
          taosArrayPush(pTagArray, &val);
H
Hongze Cheng 已提交
680 681 682
        }
      }
    }
C
Cary Xu 已提交
683 684
    if ((terrno = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag)) < 0) {
      taosArrayDestroy(pTagArray);
C
Cary Xu 已提交
685 686 687
      goto _err;
    }
    ctbEntry.ctbEntry.pTags = (uint8_t *)pNewTag;
C
Cary Xu 已提交
688
    taosArrayDestroy(pTagArray);
wmmhello's avatar
wmmhello 已提交
689
  }
H
Hongze Cheng 已提交
690 691 692 693 694

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

  // save to uid.idx
H
Hongze Cheng 已提交
695
  tdbTbUpsert(pMeta->pUidIdx, &ctbEntry.uid, sizeof(tb_uid_t), &version, sizeof(version), &pMeta->txn);
H
Hongze Cheng 已提交
696

H
Hongze Cheng 已提交
697 698
  tDecoderClear(&dc1);
  tDecoderClear(&dc2);
H
Hongze Cheng 已提交
699
  if (ctbEntry.ctbEntry.pTags) taosMemoryFree((void *)ctbEntry.ctbEntry.pTags);
H
Hongze Cheng 已提交
700 701
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
H
Hongze Cheng 已提交
702 703
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
704
  return 0;
H
Hongze Cheng 已提交
705 706

_err:
H
Hongze Cheng 已提交
707 708
  tDecoderClear(&dc1);
  tDecoderClear(&dc2);
H
Hongze Cheng 已提交
709 710
  if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
  if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
H
Hongze Cheng 已提交
711 712
  tdbTbcClose(pTbDbc);
  tdbTbcClose(pUidIdxc);
H
Hongze Cheng 已提交
713
  return -1;
H
Hongze Cheng 已提交
714 715 716 717 718 719 720 721
}

static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
  // TODO
  ASSERT(0);
  return 0;
}

D
dapan1121 已提交
722
int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
H
Hongze Cheng 已提交
723 724 725 726 727
  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 已提交
728
      return metaAlterTableColumn(pMeta, version, pReq, pMetaRsp);
H
Hongze Cheng 已提交
729 730 731 732 733 734 735 736 737 738 739
    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 已提交
740
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
741
  STbDbKey tbDbKey;
dengyihao's avatar
dengyihao 已提交
742 743
  void *   pKey = NULL;
  void *   pVal = NULL;
H
Hongze Cheng 已提交
744 745
  int      kLen = 0;
  int      vLen = 0;
H
Hongze Cheng 已提交
746
  SEncoder coder = {0};
H
Hongze Cheng 已提交
747 748

  // set key and value
H
Hongze Cheng 已提交
749
  tbDbKey.version = pME->version;
H
Hongze Cheng 已提交
750 751 752 753
  tbDbKey.uid = pME->uid;

  pKey = &tbDbKey;
  kLen = sizeof(tbDbKey);
H
Hongze Cheng 已提交
754

wafwerar's avatar
wafwerar 已提交
755 756 757
  int32_t ret = 0;
  tEncodeSize(metaEncodeEntry, pME, vLen, ret);
  if (ret < 0) {
H
Hongze Cheng 已提交
758 759 760 761 762 763 764 765 766
    goto _err;
  }

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

H
Hongze Cheng 已提交
767
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
768 769 770 771 772

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

H
Hongze Cheng 已提交
773
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
774 775

  // write to table.db
H
Hongze Cheng 已提交
776
  if (tdbTbInsert(pMeta->pTbDb, pKey, kLen, pVal, vLen, &pMeta->txn) < 0) {
H
Hongze Cheng 已提交
777 778 779 780 781 782 783 784 785 786 787
    goto _err;
  }

  taosMemoryFree(pVal);
  return 0;

_err:
  taosMemoryFree(pVal);
  return -1;
}

H
Hongze Cheng 已提交
788
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
789
  return tdbTbInsert(pMeta->pUidIdx, &pME->uid, sizeof(tb_uid_t), &pME->version, sizeof(int64_t), &pMeta->txn);
H
Hongze Cheng 已提交
790 791
}

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

H
Hongze Cheng 已提交
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
  int32_t    ttlDays;
  int64_t    ctime;
  STtlIdxKey ttlKey;

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

  ttlKey.dtime = ctime + ttlDays * 24 * 60 * 60;
  ttlKey.uid = pME->uid;

H
Hongze Cheng 已提交
816
  return tdbTbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
817 818
}

H
Hongze Cheng 已提交
819 820
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
  SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
H
Hongze Cheng 已提交
821
  return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
822 823
}

wmmhello's avatar
wmmhello 已提交
824
int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
825
                        STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
dengyihao's avatar
dengyihao 已提交
826 827 828 829 830
  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 已提交
831 832 833 834 835 836 837 838 839 840 841

  *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 已提交
842 843 844 845 846 847 848 849 850 851

  // 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 已提交
852 853 854 855 856 857 858 859 860

  return 0;
}

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

static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
dengyihao's avatar
dengyihao 已提交
861
  void *         pData = NULL;
H
Hongze Cheng 已提交
862 863 864
  int            nData = 0;
  STbDbKey       tbDbKey = {0};
  SMetaEntry     stbEntry = {0};
dengyihao's avatar
dengyihao 已提交
865
  STagIdxKey *   pTagIdxKey = NULL;
H
Hongze Cheng 已提交
866 867
  int32_t        nTagIdxKey;
  const SSchema *pTagColumn;       // = &stbEntry.stbEntry.schema.pSchema[0];
dengyihao's avatar
dengyihao 已提交
868
  const void *   pTagData = NULL;  //
C
Cary Xu 已提交
869
  int32_t        nTagData = 0;
H
Hongze Cheng 已提交
870 871 872
  SDecoder       dc = {0};

  // get super table
H
Hongze Cheng 已提交
873
  tdbTbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData);
H
Hongze Cheng 已提交
874 875
  tbDbKey.uid = pCtbEntry->ctbEntry.suid;
  tbDbKey.version = *(int64_t *)pData;
H
Hongze Cheng 已提交
876
  tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData);
H
Hongze Cheng 已提交
877 878 879 880 881

  tDecoderInit(&dc, pData, nData);
  metaDecodeEntry(&dc, &stbEntry);

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

  STagVal tagVal = {.cid = pTagColumn->colId};
884
  if (pTagColumn->type != TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
885
    tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal);
886
    if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
wmmhello's avatar
wmmhello 已提交
887 888
      pTagData = tagVal.pData;
      nTagData = (int32_t)tagVal.nData;
889
    } else {
wmmhello's avatar
wmmhello 已提交
890 891 892
      pTagData = &(tagVal.i64);
      nTagData = tDataTypes[pTagColumn->type].bytes;
    }
893 894 895
  } else {
    // pTagData = pCtbEntry->ctbEntry.pTags;
    // nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
dengyihao's avatar
dengyihao 已提交
896 897 898
    pTagData = pCtbEntry->ctbEntry.pTags;
    nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
    return metaSaveJsonVarToIdx(pMeta, pCtbEntry, pTagColumn);
wmmhello's avatar
wmmhello 已提交
899
  }
H
Hongze Cheng 已提交
900 901

  // update tag index
dengyihao's avatar
dengyihao 已提交
902 903 904 905 906 907 908 909 910 911 912 913
#ifdef USE_INVERTED_INDEX
  tb_uid_t suid = pCtbEntry->ctbEntry.suid;
  tb_uid_t tuid = pCtbEntry->uid;

  SIndexMultiTerm *tmGroup = indexMultiTermCreate();

  SIndexTerm *tm = indexTermCreate(suid, ADD_VALUE, pTagColumn->type, pTagColumn->name, sizeof(pTagColumn->name),
                                   pTagData, pTagData == NULL ? 0 : strlen(pTagData));
  indexMultiTermAdd(tmGroup, tm);
  int ret = indexPut((SIndex *)pMeta->pTagIvtIdx, tmGroup, tuid);
  indexMultiTermDestroy(tmGroup);
#else
914 915
  if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
                          pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
H
Hongze Cheng 已提交
916 917
    return -1;
  }
H
Hongze Cheng 已提交
918
  tdbTbInsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, &pMeta->txn);
H
Hongze Cheng 已提交
919
  metaDestroyTagIdxKey(pTagIdxKey);
dengyihao's avatar
dengyihao 已提交
920
#endif
H
Hongze Cheng 已提交
921 922
  tDecoderClear(&dc);
  tdbFree(pData);
H
Hongze Cheng 已提交
923 924 925
  return 0;
}

H
Hongze Cheng 已提交
926
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
927
  SEncoder              coder = {0};
dengyihao's avatar
dengyihao 已提交
928
  void *                pVal = NULL;
H
Hongze Cheng 已提交
929 930 931 932 933 934
  int                   vLen = 0;
  int                   rcode = 0;
  SSkmDbKey             skmDbKey = {0};
  const SSchemaWrapper *pSW;

  if (pME->type == TSDB_SUPER_TABLE) {
935
    pSW = &pME->stbEntry.schemaRow;
H
Hongze Cheng 已提交
936
  } else if (pME->type == TSDB_NORMAL_TABLE) {
937
    pSW = &pME->ntbEntry.schemaRow;
H
Hongze Cheng 已提交
938 939
  } else {
    ASSERT(0);
H
Hongze Cheng 已提交
940 941
  }

H
Hongze Cheng 已提交
942
  skmDbKey.uid = pME->uid;
943
  skmDbKey.sver = pSW->version;
H
Hongze Cheng 已提交
944 945

  // encode schema
wafwerar's avatar
wafwerar 已提交
946 947 948
  int32_t ret = 0;
  tEncodeSize(tEncodeSSchemaWrapper, pSW, vLen, ret);
  if (ret < 0) return -1;
H
Hongze Cheng 已提交
949
  pVal = taosMemoryMalloc(vLen);
H
Hongze Cheng 已提交
950 951 952 953 954 955
  if (pVal == NULL) {
    rcode = -1;
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

H
Hongze Cheng 已提交
956
  tEncoderInit(&coder, pVal, vLen);
H
Hongze Cheng 已提交
957 958
  tEncodeSSchemaWrapper(&coder, pSW);

H
Hongze Cheng 已提交
959
  if (tdbTbInsert(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, &pMeta->txn) < 0) {
H
Hongze Cheng 已提交
960 961 962 963 964
    rcode = -1;
    goto _exit;
  }

_exit:
H
Hongze Cheng 已提交
965
  taosMemoryFree(pVal);
H
Hongze Cheng 已提交
966
  tEncoderClear(&coder);
H
Hongze Cheng 已提交
967 968 969 970
  return rcode;
}

static int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
H
Hongze Cheng 已提交
971 972
  metaWLock(pMeta);

H
Hongze Cheng 已提交
973
  // save to table.db
H
Hongze Cheng 已提交
974
  if (metaSaveToTbDb(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
975 976

  // update uid.idx
H
Hongze Cheng 已提交
977
  if (metaUpdateUidIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
978 979

  // update name.idx
H
Hongze Cheng 已提交
980
  if (metaUpdateNameIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
981 982 983

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

    // update tag.idx
H
Hongze Cheng 已提交
987
    if (metaUpdateTagIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
988 989
  } else {
    // update schema.db
H
Hongze Cheng 已提交
990
    if (metaSaveToSkmDb(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
991 992 993
  }

  if (pME->type != TSDB_SUPER_TABLE) {
H
Hongze Cheng 已提交
994
    if (metaUpdateTtlIdx(pMeta, pME) < 0) goto _err;
H
Hongze Cheng 已提交
995 996
  }

H
Hongze Cheng 已提交
997
  metaULock(pMeta);
H
Hongze Cheng 已提交
998
  return 0;
H
Hongze Cheng 已提交
999 1000 1001 1002

_err:
  metaULock(pMeta);
  return -1;
1003
}
dengyihao's avatar
dengyihao 已提交
1004 1005 1006 1007 1008 1009 1010 1011
// refactor later
void *metaGetIdx(SMeta *pMeta) {
#ifdef USE_INVERTED_INDEX
  return pMeta->pTagIvtIdx;
#else
  return pMeta->pTagIdx;
#endif
}