metaQuery.c 20.1 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

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

H
Hongze Cheng 已提交
18
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
H
Hongze Cheng 已提交
19 20
  memset(pReader, 0, sizeof(*pReader));
  pReader->flags = flags;
H
Hongze Cheng 已提交
21
  pReader->pMeta = pMeta;
H
Hongze Cheng 已提交
22
  metaRLock(pMeta);
H
Hongze Cheng 已提交
23
}
H
Hongze Cheng 已提交
24

H
Hongze Cheng 已提交
25
void metaReaderClear(SMetaReader *pReader) {
H
Hongze Cheng 已提交
26 27 28
  if (pReader->pMeta) {
    metaULock(pReader->pMeta);
  }
H
Hongze Cheng 已提交
29
  tDecoderClear(&pReader->coder);
H
Hongze Cheng 已提交
30
  tdbFree(pReader->pBuf);
H
Hongze Cheng 已提交
31 32
}

H
Hongze Cheng 已提交
33
int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t uid) {
H
Hongze Cheng 已提交
34
  SMeta   *pMeta = pReader->pMeta;
H
Hongze Cheng 已提交
35 36
  STbDbKey tbDbKey = {.version = version, .uid = uid};

H
Hongze Cheng 已提交
37
  // query table.db
H
Hongze Cheng 已提交
38
  if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pReader->pBuf, &pReader->szBuf) < 0) {
H
Hongze Cheng 已提交
39
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
40 41 42 43
    goto _err;
  }

  // decode the entry
H
Hongze Cheng 已提交
44
  tDecoderInit(&pReader->coder, pReader->pBuf, pReader->szBuf);
H
Hongze Cheng 已提交
45 46 47 48 49 50 51 52 53 54 55

  if (metaDecodeEntry(&pReader->coder, &pReader->me) < 0) {
    goto _err;
  }

  return 0;

_err:
  return -1;
}

H
Hongze Cheng 已提交
56
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
H
Hongze Cheng 已提交
57
  SMeta  *pMeta = pReader->pMeta;
H
Hongze Cheng 已提交
58 59 60
  int64_t version;

  // query uid.idx
H
Hongze Cheng 已提交
61
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pReader->pBuf, &pReader->szBuf) < 0) {
H
Hongze Cheng 已提交
62
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
63 64 65 66
    return -1;
  }

  version = *(int64_t *)pReader->pBuf;
H
Hongze Cheng 已提交
67
  return metaGetTableEntryByVersion(pReader, version, uid);
H
Hongze Cheng 已提交
68 69
}

H
Hongze Cheng 已提交
70
int metaGetTableEntryByName(SMetaReader *pReader, const char *name) {
H
Hongze Cheng 已提交
71
  SMeta   *pMeta = pReader->pMeta;
H
Hongze Cheng 已提交
72 73 74
  tb_uid_t uid;

  // query name.idx
H
Hongze Cheng 已提交
75
  if (tdbTbGet(pMeta->pNameIdx, name, strlen(name) + 1, &pReader->pBuf, &pReader->szBuf) < 0) {
H
Hongze Cheng 已提交
76
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
77 78 79 80
    return -1;
  }

  uid = *(tb_uid_t *)pReader->pBuf;
H
Hongze Cheng 已提交
81
  return metaGetTableEntryByUid(pReader, uid);
H
Hongze Cheng 已提交
82 83
}

H
Hongze Cheng 已提交
84
tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) {
H
Hongze Cheng 已提交
85
  void    *pData = NULL;
H
Hongze Cheng 已提交
86 87 88
  int      nData = 0;
  tb_uid_t uid = 0;

wmmhello's avatar
wmmhello 已提交
89 90
  metaRLock(pMeta);

H
Hongze Cheng 已提交
91 92 93 94 95
  if (tdbTbGet(pMeta->pNameIdx, name, strlen(name) + 1, &pData, &nData) == 0) {
    uid = *(tb_uid_t *)pData;
    tdbFree(pData);
  }

wmmhello's avatar
wmmhello 已提交
96 97
  metaULock(pMeta);

98
  return uid;
H
Hongze Cheng 已提交
99 100
}

dengyihao's avatar
dengyihao 已提交
101
int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName) {
D
dapan1121 已提交
102
  SMetaReader mr = {0};
dengyihao's avatar
dengyihao 已提交
103
  metaReaderInit(&mr, (SMeta *)meta, 0);
D
dapan1121 已提交
104 105 106 107 108 109 110 111
  metaGetTableEntryByUid(&mr, uid);

  STR_TO_VARSTR(tbName, mr.me.name);
  metaReaderClear(&mr);

  return 0;
}

H
Hongze Cheng 已提交
112
int metaReadNext(SMetaReader *pReader) {
H
Hongze Cheng 已提交
113 114
  SMeta *pMeta = pReader->pMeta;

H
Hongze Cheng 已提交
115
  // TODO
H
Hongze Cheng 已提交
116

H
Hongze Cheng 已提交
117 118 119 120
  return 0;
}

#if 1  // ===================================================
H
Hongze Cheng 已提交
121 122 123 124 125 126 127 128
SMTbCursor *metaOpenTbCursor(SMeta *pMeta) {
  SMTbCursor *pTbCur = NULL;

  pTbCur = (SMTbCursor *)taosMemoryCalloc(1, sizeof(*pTbCur));
  if (pTbCur == NULL) {
    return NULL;
  }

H
Hongze Cheng 已提交
129
  metaReaderInit(&pTbCur->mr, pMeta, 0);
H
Hongze Cheng 已提交
130

H
Hongze Cheng 已提交
131
  tdbTbcOpen(pMeta->pUidIdx, &pTbCur->pDbc, NULL);
H
Hongze Cheng 已提交
132

H
Hongze Cheng 已提交
133
  tdbTbcMoveToFirst(pTbCur->pDbc);
H
Hongze Cheng 已提交
134

H
Hongze Cheng 已提交
135 136 137 138 139
  return pTbCur;
}

void metaCloseTbCursor(SMTbCursor *pTbCur) {
  if (pTbCur) {
H
Hongze Cheng 已提交
140 141
    tdbFree(pTbCur->pKey);
    tdbFree(pTbCur->pVal);
H
Hongze Cheng 已提交
142
    metaReaderClear(&pTbCur->mr);
H
Hongze Cheng 已提交
143
    if (pTbCur->pDbc) {
H
Hongze Cheng 已提交
144
      tdbTbcClose(pTbCur->pDbc);
H
Hongze Cheng 已提交
145 146 147 148 149
    }
    taosMemoryFree(pTbCur);
  }
}

H
Hongze Cheng 已提交
150
int metaTbCursorNext(SMTbCursor *pTbCur) {
H
Hongze Cheng 已提交
151
  int    ret;
H
Hongze Cheng 已提交
152
  void  *pBuf;
H
Hongze Cheng 已提交
153 154 155
  STbCfg tbCfg;

  for (;;) {
H
Hongze Cheng 已提交
156
    ret = tdbTbcNext(pTbCur->pDbc, &pTbCur->pKey, &pTbCur->kLen, &pTbCur->pVal, &pTbCur->vLen);
H
Hongze Cheng 已提交
157 158
    if (ret < 0) {
      return -1;
H
Hongze Cheng 已提交
159 160
    }

M
Minglei Jin 已提交
161 162
    tDecoderClear(&pTbCur->mr.coder);

H
Hongze Cheng 已提交
163
    metaGetTableEntryByVersion(&pTbCur->mr, *(int64_t *)pTbCur->pVal, *(tb_uid_t *)pTbCur->pKey);
H
Hongze Cheng 已提交
164
    if (pTbCur->mr.me.type == TSDB_SUPER_TABLE) {
H
Hongze Cheng 已提交
165 166
      continue;
    }
H
Hongze Cheng 已提交
167 168

    break;
H
Hongze Cheng 已提交
169 170
  }

H
Hongze Cheng 已提交
171
  return 0;
H
Hongze Cheng 已提交
172 173
}

H
Hongze Cheng 已提交
174
SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, bool isinline) {
H
Hongze Cheng 已提交
175
  void           *pData = NULL;
H
Hongze Cheng 已提交
176 177 178 179 180 181
  int             nData = 0;
  int64_t         version;
  SSchemaWrapper  schema = {0};
  SSchemaWrapper *pSchema = NULL;
  SDecoder        dc = {0};

H
fix  
Hongze Cheng 已提交
182
  metaRLock(pMeta);
H
Hongze Cheng 已提交
183 184 185 186
_query:
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData) < 0) {
    goto _err;
  }
H
Hongze Cheng 已提交
187

H
Hongze Cheng 已提交
188
  version = *(int64_t *)pData;
H
Hongze Cheng 已提交
189

H
Hongze Cheng 已提交
190 191 192 193 194 195
  tdbTbGet(pMeta->pTbDb, &(STbDbKey){.uid = uid, .version = version}, sizeof(STbDbKey), &pData, &nData);
  SMetaEntry me = {0};
  tDecoderInit(&dc, pData, nData);
  metaDecodeEntry(&dc, &me);
  if (me.type == TSDB_SUPER_TABLE) {
    if (sver == -1 || sver == me.stbEntry.schemaRow.version) {
H
Hongze Cheng 已提交
196
      pSchema = tCloneSSchemaWrapper(&me.stbEntry.schemaRow);
H
Hongze Cheng 已提交
197 198
      tDecoderClear(&dc);
      goto _exit;
H
Hongze Cheng 已提交
199
    }
H
Hongze Cheng 已提交
200 201
  } else if (me.type == TSDB_CHILD_TABLE) {
    uid = me.ctbEntry.suid;
H
Hongze Cheng 已提交
202
    tDecoderClear(&dc);
H
Hongze Cheng 已提交
203
    goto _query;
H
Hongze Cheng 已提交
204
  } else {
H
Hongze Cheng 已提交
205 206 207 208
    if (sver == -1 || sver == me.ntbEntry.schemaRow.version) {
      pSchema = tCloneSSchemaWrapper(&me.ntbEntry.schemaRow);
      tDecoderClear(&dc);
      goto _exit;
H
Hongze Cheng 已提交
209
    }
H
Hongze Cheng 已提交
210 211
  }
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
212

H
Hongze Cheng 已提交
213 214 215
  // query from skm db
  if (tdbTbGet(pMeta->pSkmDb, &(SSkmDbKey){.uid = uid, .sver = sver}, sizeof(SSkmDbKey), &pData, &nData) < 0) {
    goto _err;
H
Hongze Cheng 已提交
216
  }
H
Hongze Cheng 已提交
217

H
Hongze Cheng 已提交
218
  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
219
  tDecodeSSchemaWrapperEx(&dc, &schema);
H
Hongze Cheng 已提交
220 221 222 223
  pSchema = tCloneSSchemaWrapper(&schema);
  tDecoderClear(&dc);

_exit:
H
Hongze Cheng 已提交
224 225 226
  metaULock(pMeta);
  tdbFree(pData);
  return pSchema;
H
Hongze Cheng 已提交
227

H
Hongze Cheng 已提交
228 229 230 231
_err:
  metaULock(pMeta);
  tdbFree(pData);
  return NULL;
H
Hongze Cheng 已提交
232 233
}

H
Hongze Cheng 已提交
234 235 236
int metaTtlSmaller(SMeta *pMeta, uint64_t ttl, SArray *uidList) {
  TBC *pCur;
  int  ret = tdbTbcOpen(pMeta->pTtlIdx, &pCur, NULL);
237 238 239 240 241 242 243 244 245 246 247 248 249 250
  if (ret < 0) {
    return ret;
  }

  STtlIdxKey ttlKey = {0};
  ttlKey.dtime = ttl;
  ttlKey.uid = INT64_MAX;
  int c = 0;
  tdbTbcMoveTo(pCur, &ttlKey, sizeof(ttlKey), &c);
  if (c < 0) {
    tdbTbcMoveToPrev(pCur);
  }

  void *pKey = NULL;
H
Hongze Cheng 已提交
251 252
  int   kLen = 0;
  while (1) {
253 254 255 256
    ret = tdbTbcPrev(pCur, &pKey, &kLen, NULL, NULL);
    if (ret < 0) {
      break;
    }
H
Hongze Cheng 已提交
257
    ttlKey = *(STtlIdxKey *)pKey;
258 259 260 261 262
    taosArrayPush(uidList, &ttlKey.uid);
  }
  tdbTbcClose(pCur);

  tdbFree(pKey);
wmmhello's avatar
wmmhello 已提交
263

264 265 266
  return 0;
}

H
Hongze Cheng 已提交
267
struct SMCtbCursor {
H
Hongze Cheng 已提交
268 269
  SMeta   *pMeta;
  TBC     *pCur;
H
Hongze Cheng 已提交
270
  tb_uid_t suid;
H
Hongze Cheng 已提交
271 272
  void    *pKey;
  void    *pVal;
H
Hongze Cheng 已提交
273 274 275 276
  int      kLen;
  int      vLen;
};

H
Hongze Cheng 已提交
277 278
SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
  SMCtbCursor *pCtbCur = NULL;
H
Hongze Cheng 已提交
279
  SCtbIdxKey   ctbIdxKey;
C
Cary Xu 已提交
280 281
  int          ret = 0;
  int          c = 0;
H
Hongze Cheng 已提交
282

H
Hongze Cheng 已提交
283 284 285 286
  pCtbCur = (SMCtbCursor *)taosMemoryCalloc(1, sizeof(*pCtbCur));
  if (pCtbCur == NULL) {
    return NULL;
  }
H
Hongze Cheng 已提交
287

H
fix  
Hongze Cheng 已提交
288
  pCtbCur->pMeta = pMeta;
H
Hongze Cheng 已提交
289
  pCtbCur->suid = uid;
H
fix  
Hongze Cheng 已提交
290 291
  metaRLock(pMeta);

H
Hongze Cheng 已提交
292
  ret = tdbTbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur, NULL);
H
Hongze Cheng 已提交
293
  if (ret < 0) {
H
fix  
Hongze Cheng 已提交
294
    metaULock(pMeta);
H
Hongze Cheng 已提交
295 296 297
    taosMemoryFree(pCtbCur);
    return NULL;
  }
H
Hongze Cheng 已提交
298

H
Hongze Cheng 已提交
299 300 301
  // move to the suid
  ctbIdxKey.suid = uid;
  ctbIdxKey.uid = INT64_MIN;
H
Hongze Cheng 已提交
302
  tdbTbcMoveTo(pCtbCur->pCur, &ctbIdxKey, sizeof(ctbIdxKey), &c);
H
Hongze Cheng 已提交
303
  if (c > 0) {
H
Hongze Cheng 已提交
304
    tdbTbcMoveToNext(pCtbCur->pCur);
H
Hongze Cheng 已提交
305 306
  }

H
Hongze Cheng 已提交
307 308 309
  return pCtbCur;
}

C
Cary Xu 已提交
310
void metaCloseCtbCursor(SMCtbCursor *pCtbCur) {
H
Hongze Cheng 已提交
311
  if (pCtbCur) {
H
fix  
Hongze Cheng 已提交
312
    if (pCtbCur->pMeta) metaULock(pCtbCur->pMeta);
H
Hongze Cheng 已提交
313
    if (pCtbCur->pCur) {
H
Hongze Cheng 已提交
314
      tdbTbcClose(pCtbCur->pCur);
H
Hongze Cheng 已提交
315

H
Hongze Cheng 已提交
316 317
      tdbFree(pCtbCur->pKey);
      tdbFree(pCtbCur->pVal);
H
Hongze Cheng 已提交
318
    }
H
Hongze Cheng 已提交
319

H
Hongze Cheng 已提交
320 321
    taosMemoryFree(pCtbCur);
  }
H
Hongze Cheng 已提交
322 323 324
}

tb_uid_t metaCtbCursorNext(SMCtbCursor *pCtbCur) {
H
Hongze Cheng 已提交
325 326
  int         ret;
  SCtbIdxKey *pCtbIdxKey;
H
Hongze Cheng 已提交
327

H
Hongze Cheng 已提交
328
  ret = tdbTbcNext(pCtbCur->pCur, &pCtbCur->pKey, &pCtbCur->kLen, &pCtbCur->pVal, &pCtbCur->vLen);
H
Hongze Cheng 已提交
329 330 331
  if (ret < 0) {
    return 0;
  }
H
Hongze Cheng 已提交
332

H
Hongze Cheng 已提交
333
  pCtbIdxKey = pCtbCur->pKey;
H
Hongze Cheng 已提交
334 335 336
  if (pCtbIdxKey->suid > pCtbCur->suid) {
    return 0;
  }
H
Hongze Cheng 已提交
337

H
Hongze Cheng 已提交
338
  return pCtbIdxKey->uid;
H
Hongze Cheng 已提交
339 340
}

C
Cary Xu 已提交
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
struct SMStbCursor {
  SMeta   *pMeta;
  TBC     *pCur;
  tb_uid_t suid;
  void    *pKey;
  void    *pVal;
  int      kLen;
  int      vLen;
};

SMStbCursor *metaOpenStbCursor(SMeta *pMeta, tb_uid_t suid) {
  SMStbCursor *pStbCur = NULL;
  int          ret = 0;
  int          c = 0;

  pStbCur = (SMStbCursor *)taosMemoryCalloc(1, sizeof(*pStbCur));
  if (pStbCur == NULL) {
C
Cary Xu 已提交
358
    terrno = TSDB_CODE_OUT_OF_MEMORY;
C
Cary Xu 已提交
359 360 361 362 363 364 365 366 367
    return NULL;
  }

  pStbCur->pMeta = pMeta;
  pStbCur->suid = suid;
  metaRLock(pMeta);

  ret = tdbTbcOpen(pMeta->pSuidIdx, &pStbCur->pCur, NULL);
  if (ret < 0) {
C
Cary Xu 已提交
368
    terrno = TSDB_CODE_OUT_OF_MEMORY;
C
Cary Xu 已提交
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
    metaULock(pMeta);
    taosMemoryFree(pStbCur);
    return NULL;
  }

  // move to the suid
  tdbTbcMoveTo(pStbCur->pCur, &suid, sizeof(suid), &c);
  if (c > 0) {
    tdbTbcMoveToNext(pStbCur->pCur);
  }

  return pStbCur;
}

void metaCloseStbCursor(SMStbCursor *pStbCur) {
  if (pStbCur) {
    if (pStbCur->pMeta) metaULock(pStbCur->pMeta);
    if (pStbCur->pCur) {
      tdbTbcClose(pStbCur->pCur);

      tdbFree(pStbCur->pKey);
      tdbFree(pStbCur->pVal);
    }

    taosMemoryFree(pStbCur);
  }
}

tb_uid_t metaStbCursorNext(SMStbCursor *pStbCur) {
  int ret;

  ret = tdbTbcNext(pStbCur->pCur, &pStbCur->pKey, &pStbCur->kLen, &pStbCur->pVal, &pStbCur->vLen);
  if (ret < 0) {
    return 0;
  }
H
Hongze Cheng 已提交
404
  return *(tb_uid_t *)pStbCur->pKey;
C
Cary Xu 已提交
405 406
}

H
Hongze Cheng 已提交
407
STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) {
H
Hongze Cheng 已提交
408
  // SMetaReader     mr = {0};
H
Hongze Cheng 已提交
409
  STSchema       *pTSchema = NULL;
H
Hongze Cheng 已提交
410 411
  SSchemaWrapper *pSW = NULL;
  STSchemaBuilder sb = {0};
H
Hongze Cheng 已提交
412
  SSchema        *pSchema;
H
Hongze Cheng 已提交
413

H
Hongze Cheng 已提交
414
  pSW = metaGetTableSchema(pMeta, uid, sver, 0);
C
Cary Xu 已提交
415
  if (!pSW) return NULL;
H
fix  
Hongze Cheng 已提交
416

417
  tdInitTSchemaBuilder(&sb, pSW->version);
H
Hongze Cheng 已提交
418 419 420 421 422
  for (int i = 0; i < pSW->nCols; i++) {
    pSchema = pSW->pSchema + i;
    tdAddColToSchema(&sb, pSchema->type, pSchema->flags, pSchema->colId, pSchema->bytes);
  }
  pTSchema = tdGetSchemaFromBuilder(&sb);
C
Cary Xu 已提交
423

H
Hongze Cheng 已提交
424 425
  tdDestroyTSchemaBuilder(&sb);

H
Hongze Cheng 已提交
426 427
  taosMemoryFree(pSW->pSchema);
  taosMemoryFree(pSW);
H
Hongze Cheng 已提交
428 429 430
  return pTSchema;
}

H
Hongze Cheng 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema **ppTSchema) {
  int32_t   code = 0;
  STSchema *pTSchema = NULL;
  SSkmDbKey skmDbKey = {.uid = suid ? suid : uid, .sver = sver};
  void     *pData = NULL;
  int       nData = 0;

  // query
  metaRLock(pMeta);
  if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), &pData, &nData) < 0) {
    code = TSDB_CODE_NOT_FOUND;
    metaULock(pMeta);
    goto _err;
  }
  metaULock(pMeta);

  // decode
  SDecoder        dc = {0};
  SSchemaWrapper  schema;
  SSchemaWrapper *pSchemaWrapper = &schema;

  tDecoderInit(&dc, pData, nData);
  tDecodeSSchemaWrapper(&dc, pSchemaWrapper);
  tDecoderClear(&dc);
455
  tdbFree(pData);
H
Hongze Cheng 已提交
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476

  // convert
  STSchemaBuilder sb = {0};

  tdInitTSchemaBuilder(&sb, pSchemaWrapper->version);
  for (int i = 0; i < pSchemaWrapper->nCols; i++) {
    SSchema *pSchema = pSchemaWrapper->pSchema + i;
    tdAddColToSchema(&sb, pSchema->type, pSchema->flags, pSchema->colId, pSchema->bytes);
  }
  pTSchema = tdGetSchemaFromBuilder(&sb);
  tdDestroyTSchemaBuilder(&sb);

  *ppTSchema = pTSchema;
  taosMemoryFree(pSchemaWrapper->pSchema);
  return code;

_err:
  *ppTSchema = NULL;
  return code;
}

477 478
// N.B. Called by statusReq per second
int64_t metaGetTbNum(SMeta *pMeta) {
C
Cary Xu 已提交
479
  // TODO
C
Cary Xu 已提交
480
  return 0;
481 482 483
}

// N.B. Called by statusReq per second
M
Minglei Jin 已提交
484
int64_t metaGetTimeSeriesNum(SMeta *pMeta) {
485
  // TODO
M
Minglei Jin 已提交
486
  return 400;
C
Cary Xu 已提交
487
}
H
Hongze Cheng 已提交
488

C
Cary Xu 已提交
489
typedef struct {
H
Hongze Cheng 已提交
490 491
  SMeta   *pMeta;
  TBC     *pCur;
C
Cary Xu 已提交
492
  tb_uid_t uid;
H
Hongze Cheng 已提交
493 494
  void    *pKey;
  void    *pVal;
C
Cary Xu 已提交
495 496 497 498 499 500 501 502 503 504 505 506 507
  int      kLen;
  int      vLen;
} SMSmaCursor;

SMSmaCursor *metaOpenSmaCursor(SMeta *pMeta, tb_uid_t uid) {
  SMSmaCursor *pSmaCur = NULL;
  SSmaIdxKey   smaIdxKey;
  int          ret;
  int          c;

  pSmaCur = (SMSmaCursor *)taosMemoryCalloc(1, sizeof(*pSmaCur));
  if (pSmaCur == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
508 509 510
    return NULL;
  }

C
Cary Xu 已提交
511 512 513 514
  pSmaCur->pMeta = pMeta;
  pSmaCur->uid = uid;
  metaRLock(pMeta);

H
Hongze Cheng 已提交
515
  ret = tdbTbcOpen(pMeta->pSmaIdx, &pSmaCur->pCur, NULL);
C
Cary Xu 已提交
516 517 518
  if (ret < 0) {
    metaULock(pMeta);
    taosMemoryFree(pSmaCur);
H
Hongze Cheng 已提交
519 520 521
    return NULL;
  }

C
Cary Xu 已提交
522 523 524
  // move to the suid
  smaIdxKey.uid = uid;
  smaIdxKey.smaUid = INT64_MIN;
H
Hongze Cheng 已提交
525
  tdbTbcMoveTo(pSmaCur->pCur, &smaIdxKey, sizeof(smaIdxKey), &c);
C
Cary Xu 已提交
526
  if (c > 0) {
H
Hongze Cheng 已提交
527
    tdbTbcMoveToNext(pSmaCur->pCur);
C
Cary Xu 已提交
528
  }
H
Hongze Cheng 已提交
529

C
Cary Xu 已提交
530 531
  return pSmaCur;
}
H
Hongze Cheng 已提交
532

C
Cary Xu 已提交
533 534 535 536
void metaCloseSmaCursor(SMSmaCursor *pSmaCur) {
  if (pSmaCur) {
    if (pSmaCur->pMeta) metaULock(pSmaCur->pMeta);
    if (pSmaCur->pCur) {
H
Hongze Cheng 已提交
537
      tdbTbcClose(pSmaCur->pCur);
H
Hongze Cheng 已提交
538

C
Cary Xu 已提交
539 540 541
      tdbFree(pSmaCur->pKey);
      tdbFree(pSmaCur->pVal);
    }
H
Hongze Cheng 已提交
542

C
Cary Xu 已提交
543 544 545 546 547 548 549 550
    taosMemoryFree(pSmaCur);
  }
}

tb_uid_t metaSmaCursorNext(SMSmaCursor *pSmaCur) {
  int         ret;
  SSmaIdxKey *pSmaIdxKey;

H
Hongze Cheng 已提交
551
  ret = tdbTbcNext(pSmaCur->pCur, &pSmaCur->pKey, &pSmaCur->kLen, &pSmaCur->pVal, &pSmaCur->vLen);
C
Cary Xu 已提交
552 553 554 555 556 557 558 559 560 561 562 563 564 565
  if (ret < 0) {
    return 0;
  }

  pSmaIdxKey = pSmaCur->pKey;
  if (pSmaIdxKey->uid > pSmaCur->uid) {
    return 0;
  }

  return pSmaIdxKey->uid;
}

STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid, bool deepCopy) {
  STSmaWrapper *pSW = NULL;
H
Hongze Cheng 已提交
566
  SArray       *pSmaIds = NULL;
C
Cary Xu 已提交
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589

  if (!(pSmaIds = metaGetSmaIdsByTable(pMeta, uid))) {
    return NULL;
  }

  pSW = taosMemoryCalloc(1, sizeof(*pSW));
  if (!pSW) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

  pSW->number = taosArrayGetSize(pSmaIds);
  pSW->tSma = taosMemoryCalloc(pSW->number, sizeof(STSma));

  if (!pSW->tSma) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

  SMetaReader mr = {0};
  metaReaderInit(&mr, pMeta, 0);
  int64_t smaId;
  int     smaIdx = 0;
H
Hongze Cheng 已提交
590
  STSma  *pTSma = NULL;
C
Cary Xu 已提交
591 592 593
  for (int i = 0; i < pSW->number; ++i) {
    smaId = *(tb_uid_t *)taosArrayGet(pSmaIds, i);
    if (metaGetTableEntryByUid(&mr, smaId) < 0) {
S
Shengliang Guan 已提交
594
      metaWarn("vgId:%d, no entry for tbId: %" PRIi64 ", smaId: %" PRIi64, TD_VID(pMeta->pVnode), uid, smaId);
C
Cary Xu 已提交
595 596 597 598 599 600 601 602 603 604
      continue;
    }
    pTSma = pSW->tSma + smaIdx;
    memcpy(pTSma, mr.me.smaEntry.tsma, sizeof(STSma));
    if (deepCopy) {
      if (pTSma->exprLen > 0) {
        if (!(pTSma->expr = taosMemoryCalloc(1, pTSma->exprLen))) {
          terrno = TSDB_CODE_OUT_OF_MEMORY;
          goto _err;
        }
H
Hongze Cheng 已提交
605
        memcpy((void *)pTSma->expr, mr.me.smaEntry.tsma->expr, pTSma->exprLen);
H
Hongze Cheng 已提交
606
      }
C
Cary Xu 已提交
607 608 609 610 611
      if (pTSma->tagsFilterLen > 0) {
        if (!(pTSma->tagsFilter = taosMemoryCalloc(1, pTSma->tagsFilterLen))) {
          terrno = TSDB_CODE_OUT_OF_MEMORY;
          goto _err;
        }
H
Hongze Cheng 已提交
612
      }
H
Hongze Cheng 已提交
613
      memcpy((void *)pTSma->tagsFilter, mr.me.smaEntry.tsma->tagsFilter, pTSma->tagsFilterLen);
C
Cary Xu 已提交
614 615 616 617 618
    } else {
      pTSma->exprLen = 0;
      pTSma->expr = NULL;
      pTSma->tagsFilterLen = 0;
      pTSma->tagsFilter = NULL;
H
Hongze Cheng 已提交
619
    }
H
Hongze Cheng 已提交
620

C
Cary Xu 已提交
621
    ++smaIdx;
H
Hongze Cheng 已提交
622 623
  }

C
Cary Xu 已提交
624 625
  if (smaIdx <= 0) goto _err;
  pSW->number = smaIdx;
H
Hongze Cheng 已提交
626

C
Cary Xu 已提交
627 628
  metaReaderClear(&mr);
  taosArrayDestroy(pSmaIds);
H
Hongze Cheng 已提交
629
  return pSW;
C
Cary Xu 已提交
630 631 632
_err:
  metaReaderClear(&mr);
  taosArrayDestroy(pSmaIds);
C
Cary Xu 已提交
633
  tFreeTSmaWrapper(pSW, deepCopy);
H
Hongze Cheng 已提交
634 635 636
  return NULL;
}

C
Cary Xu 已提交
637
STSma *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid) {
H
Hongze Cheng 已提交
638
  STSma      *pTSma = NULL;
C
Cary Xu 已提交
639 640 641
  SMetaReader mr = {0};
  metaReaderInit(&mr, pMeta, 0);
  if (metaGetTableEntryByUid(&mr, indexUid) < 0) {
S
Shengliang Guan 已提交
642
    metaWarn("vgId:%d, failed to get table entry for smaId: %" PRIi64, TD_VID(pMeta->pVnode), indexUid);
C
Cary Xu 已提交
643 644 645 646 647 648 649 650 651 652 653 654 655 656
    metaReaderClear(&mr);
    return NULL;
  }
  pTSma = (STSma *)taosMemoryMalloc(sizeof(STSma));
  if (!pTSma) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    metaReaderClear(&mr);
    return NULL;
  }

  memcpy(pTSma, mr.me.smaEntry.tsma, sizeof(STSma));

  metaReaderClear(&mr);
  return pTSma;
H
Hongze Cheng 已提交
657 658
}

C
Cary Xu 已提交
659
SArray *metaGetSmaIdsByTable(SMeta *pMeta, tb_uid_t uid) {
H
Hongze Cheng 已提交
660
  SArray     *pUids = NULL;
C
Cary Xu 已提交
661
  SSmaIdxKey *pSmaIdxKey = NULL;
H
Hongze Cheng 已提交
662

C
Cary Xu 已提交
663 664
  SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, uid);
  if (!pCur) {
H
Hongze Cheng 已提交
665 666 667
    return NULL;
  }

C
Cary Xu 已提交
668 669 670 671 672
  while (1) {
    tb_uid_t id = metaSmaCursorNext(pCur);
    if (id == 0) {
      break;
    }
H
Hongze Cheng 已提交
673

C
Cary Xu 已提交
674 675
    if (!pUids) {
      pUids = taosArrayInit(16, sizeof(tb_uid_t));
H
Hongze Cheng 已提交
676
      if (!pUids) {
C
Cary Xu 已提交
677 678 679
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        metaCloseSmaCursor(pCur);
        return NULL;
H
Hongze Cheng 已提交
680
      }
C
Cary Xu 已提交
681
    }
H
Hongze Cheng 已提交
682

C
Cary Xu 已提交
683
    pSmaIdxKey = (SSmaIdxKey *)pCur->pKey;
H
Hongze Cheng 已提交
684

C
Cary Xu 已提交
685 686 687 688 689
    if (taosArrayPush(pUids, &pSmaIdxKey->smaUid) < 0) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      metaCloseSmaCursor(pCur);
      taosArrayDestroy(pUids);
      return NULL;
H
Hongze Cheng 已提交
690 691 692 693 694 695 696
    }
  }

  metaCloseSmaCursor(pCur);
  return pUids;
}

C
Cary Xu 已提交
697
SArray *metaGetSmaTbUids(SMeta *pMeta) {
H
Hongze Cheng 已提交
698
  SArray     *pUids = NULL;
C
Cary Xu 已提交
699 700 701 702 703
  SSmaIdxKey *pSmaIdxKey = NULL;
  tb_uid_t    lastUid = 0;

  SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, 0);
  if (!pCur) {
H
Hongze Cheng 已提交
704 705 706
    return NULL;
  }

C
Cary Xu 已提交
707 708 709 710 711
  while (1) {
    tb_uid_t uid = metaSmaCursorNext(pCur);
    if (uid == 0) {
      break;
    }
H
Hongze Cheng 已提交
712

C
Cary Xu 已提交
713 714 715
    if (lastUid == uid) {
      continue;
    }
H
Hongze Cheng 已提交
716

C
Cary Xu 已提交
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
    lastUid = uid;

    if (!pUids) {
      pUids = taosArrayInit(16, sizeof(tb_uid_t));
      if (!pUids) {
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        metaCloseSmaCursor(pCur);
        return NULL;
      }
    }

    if (taosArrayPush(pUids, &uid) < 0) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      metaCloseSmaCursor(pCur);
      taosArrayDestroy(pUids);
      return NULL;
    }
H
Hongze Cheng 已提交
734 735
  }

C
Cary Xu 已提交
736 737
  metaCloseSmaCursor(pCur);
  return pUids;
H
Hongze Cheng 已提交
738 739
}

L
Liu Jicong 已提交
740
#endif
H
Hongze Cheng 已提交
741

wmmhello's avatar
wmmhello 已提交
742
const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t type, STagVal *val) {
H
Hongze Cheng 已提交
743
  ASSERT(pEntry->type == TSDB_CHILD_TABLE);
wmmhello's avatar
wmmhello 已提交
744
  STag *tag = (STag *)pEntry->ctbEntry.pTags;
dengyihao's avatar
dengyihao 已提交
745
  if (type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
746 747
    return tag;
  }
wmmhello's avatar
wmmhello 已提交
748 749
  bool find = tTagGet(tag, val);

dengyihao's avatar
dengyihao 已提交
750
  if (!find) {
wmmhello's avatar
wmmhello 已提交
751 752 753
    return NULL;
  }
  return val;
dengyihao's avatar
dengyihao 已提交
754
}
wmmhello's avatar
wmmhello 已提交
755 756

typedef struct {
H
Hongze Cheng 已提交
757 758
  SMeta   *pMeta;
  TBC     *pCur;
wmmhello's avatar
wmmhello 已提交
759 760 761
  tb_uid_t suid;
  int16_t  cid;
  int16_t  type;
H
Hongze Cheng 已提交
762 763
  void    *pKey;
  void    *pVal;
wmmhello's avatar
wmmhello 已提交
764 765 766 767
  int32_t  kLen;
  int32_t  vLen;
} SIdxCursor;

dengyihao's avatar
dengyihao 已提交
768 769 770
int32_t metaFilterTableIds(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
  int32_t ret = 0;
  char   *buf = NULL;
wmmhello's avatar
wmmhello 已提交
771

dengyihao's avatar
dengyihao 已提交
772 773 774 775
  STagIdxKey *pKey = NULL;
  int32_t     nKey = 0;

  SIdxCursor *pCursor = NULL;
wmmhello's avatar
wmmhello 已提交
776 777 778 779 780 781 782 783 784 785 786 787
  pCursor = (SIdxCursor *)taosMemoryCalloc(1, sizeof(SIdxCursor));
  pCursor->pMeta = pMeta;
  pCursor->suid = param->suid;
  pCursor->cid = param->cid;
  pCursor->type = param->type;

  metaRLock(pMeta);
  ret = tdbTbcOpen(pMeta->pTagIdx, &pCursor->pCur, NULL);
  if (ret < 0) {
    goto END;
  }

dengyihao's avatar
dengyihao 已提交
788
  int32_t maxSize = 0;
wmmhello's avatar
wmmhello 已提交
789
  int32_t nTagData = 0;
H
Hongze Cheng 已提交
790
  void   *tagData = NULL;
dengyihao's avatar
dengyihao 已提交
791

dengyihao's avatar
dengyihao 已提交
792
  if (param->val == NULL) {
S
Shengliang Guan 已提交
793
    metaError("vgId:%d, failed to filter NULL data", TD_VID(pMeta->pVnode));
dengyihao's avatar
dengyihao 已提交
794
    return -1;
dengyihao's avatar
dengyihao 已提交
795
  } else {
dengyihao's avatar
dengyihao 已提交
796 797 798 799 800 801 802 803 804 805
    if (IS_VAR_DATA_TYPE(param->type)) {
      tagData = varDataVal(param->val);
      nTagData = varDataLen(param->val);

      if (param->type == TSDB_DATA_TYPE_NCHAR) {
        maxSize = 4 * nTagData + 1;
        buf = taosMemoryCalloc(1, maxSize);
        if (false == taosMbsToUcs4(tagData, nTagData, (TdUcs4 *)buf, maxSize, &maxSize)) {
          goto END;
        }
dengyihao's avatar
dengyihao 已提交
806

dengyihao's avatar
dengyihao 已提交
807 808 809 810 811 812
        tagData = buf;
        nTagData = maxSize;
      }
    } else {
      tagData = param->val;
      nTagData = tDataTypes[param->type].bytes;
dengyihao's avatar
dengyihao 已提交
813
    }
wmmhello's avatar
wmmhello 已提交
814
  }
dengyihao's avatar
dengyihao 已提交
815
  ret = metaCreateTagIdxKey(pCursor->suid, pCursor->cid, tagData, nTagData, pCursor->type,
wmmhello's avatar
wmmhello 已提交
816
                            param->reverse ? INT64_MAX : INT64_MIN, &pKey, &nKey);
dengyihao's avatar
dengyihao 已提交
817

wmmhello's avatar
wmmhello 已提交
818 819 820 821 822 823 824
  if (ret != 0) {
    goto END;
  }
  int cmp = 0;
  if (tdbTbcMoveTo(pCursor->pCur, pKey, nKey, &cmp) < 0) {
    goto END;
  }
dengyihao's avatar
dengyihao 已提交
825

dengyihao's avatar
dengyihao 已提交
826
  bool    first = true;
dengyihao's avatar
dengyihao 已提交
827
  int32_t valid = 0;
wmmhello's avatar
wmmhello 已提交
828
  while (1) {
dengyihao's avatar
dengyihao 已提交
829 830 831
    void   *entryKey = NULL, *entryVal = NULL;
    int32_t nEntryKey, nEntryVal;

wmmhello's avatar
wmmhello 已提交
832 833 834 835 836
    valid = tdbTbcGet(pCursor->pCur, (const void **)&entryKey, &nEntryKey, (const void **)&entryVal, &nEntryVal);
    if (valid < 0) {
      break;
    }
    STagIdxKey *p = entryKey;
dengyihao's avatar
dengyihao 已提交
837 838 839 840 841 842 843 844 845 846
    if (p->type != pCursor->type) {
      if (first) {
        valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
        if (valid < 0) break;
        continue;
      } else {
        break;
      }
    }
    first = false;
wmmhello's avatar
wmmhello 已提交
847 848 849 850
    if (p != NULL) {
      int32_t cmp = (*param->filterFunc)(p->data, pKey->data, pKey->type);
      if (cmp == 0) {
        // match
dengyihao's avatar
dengyihao 已提交
851 852 853 854 855 856
        tb_uid_t tuid = 0;
        if (IS_VAR_DATA_TYPE(pKey->type)) {
          tuid = *(tb_uid_t *)(p->data + varDataTLen(p->data));
        } else {
          tuid = *(tb_uid_t *)(p->data + tDataTypes[pCursor->type].bytes);
        }
wmmhello's avatar
wmmhello 已提交
857 858 859 860 861 862 863 864 865 866 867 868 869
        taosArrayPush(pUids, &tuid);
      } else if (cmp == 1) {
        // not match but should continue to iter
      } else {
        // not match and no more result
        break;
      }
    }
    valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
    if (valid < 0) {
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
870

wmmhello's avatar
wmmhello 已提交
871 872 873
END:
  if (pCursor->pMeta) metaULock(pCursor->pMeta);
  if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
dengyihao's avatar
dengyihao 已提交
874
  taosMemoryFree(buf);
dengyihao's avatar
dengyihao 已提交
875
  taosMemoryFree(pKey);
wmmhello's avatar
wmmhello 已提交
876 877 878 879

  taosMemoryFree(pCursor);

  return ret;
dengyihao's avatar
dengyihao 已提交
880
}