metaQuery.c 20.5 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) {
479 480 481 482 483 484
  // num of child tables (excluding normal tables , stables and others)

  /* int64_t num = 0; */
  /* vnodeGetAllCtbNum(pMeta->pVnode, &num); */

  return pMeta->pVnode->config.vndStats.numOfCTables;
485 486 487
}

// N.B. Called by statusReq per second
M
Minglei Jin 已提交
488
int64_t metaGetTimeSeriesNum(SMeta *pMeta) {
489 490 491 492 493 494
  // sum of (number of columns of stable -  1) * number of ctables (excluding timestamp column)
  int64_t num = 0;
  vnodeGetTimeSeriesNum(pMeta->pVnode, &num);
  pMeta->pVnode->config.vndStats.numOfTimeSeries = num;

  return pMeta->pVnode->config.vndStats.numOfTimeSeries;
C
Cary Xu 已提交
495
}
H
Hongze Cheng 已提交
496

C
Cary Xu 已提交
497
typedef struct {
H
Hongze Cheng 已提交
498 499
  SMeta   *pMeta;
  TBC     *pCur;
C
Cary Xu 已提交
500
  tb_uid_t uid;
H
Hongze Cheng 已提交
501 502
  void    *pKey;
  void    *pVal;
C
Cary Xu 已提交
503 504 505 506 507 508 509 510 511 512 513 514 515
  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 已提交
516 517 518
    return NULL;
  }

C
Cary Xu 已提交
519 520 521 522
  pSmaCur->pMeta = pMeta;
  pSmaCur->uid = uid;
  metaRLock(pMeta);

H
Hongze Cheng 已提交
523
  ret = tdbTbcOpen(pMeta->pSmaIdx, &pSmaCur->pCur, NULL);
C
Cary Xu 已提交
524 525 526
  if (ret < 0) {
    metaULock(pMeta);
    taosMemoryFree(pSmaCur);
H
Hongze Cheng 已提交
527 528 529
    return NULL;
  }

C
Cary Xu 已提交
530 531 532
  // move to the suid
  smaIdxKey.uid = uid;
  smaIdxKey.smaUid = INT64_MIN;
H
Hongze Cheng 已提交
533
  tdbTbcMoveTo(pSmaCur->pCur, &smaIdxKey, sizeof(smaIdxKey), &c);
C
Cary Xu 已提交
534
  if (c > 0) {
H
Hongze Cheng 已提交
535
    tdbTbcMoveToNext(pSmaCur->pCur);
C
Cary Xu 已提交
536
  }
H
Hongze Cheng 已提交
537

C
Cary Xu 已提交
538 539
  return pSmaCur;
}
H
Hongze Cheng 已提交
540

C
Cary Xu 已提交
541 542 543 544
void metaCloseSmaCursor(SMSmaCursor *pSmaCur) {
  if (pSmaCur) {
    if (pSmaCur->pMeta) metaULock(pSmaCur->pMeta);
    if (pSmaCur->pCur) {
H
Hongze Cheng 已提交
545
      tdbTbcClose(pSmaCur->pCur);
H
Hongze Cheng 已提交
546

C
Cary Xu 已提交
547 548 549
      tdbFree(pSmaCur->pKey);
      tdbFree(pSmaCur->pVal);
    }
H
Hongze Cheng 已提交
550

C
Cary Xu 已提交
551 552 553 554 555 556 557 558
    taosMemoryFree(pSmaCur);
  }
}

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

H
Hongze Cheng 已提交
559
  ret = tdbTbcNext(pSmaCur->pCur, &pSmaCur->pKey, &pSmaCur->kLen, &pSmaCur->pVal, &pSmaCur->vLen);
C
Cary Xu 已提交
560 561 562 563 564 565 566 567 568 569 570 571 572 573
  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 已提交
574
  SArray       *pSmaIds = NULL;
C
Cary Xu 已提交
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597

  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 已提交
598
  STSma  *pTSma = NULL;
C
Cary Xu 已提交
599 600 601
  for (int i = 0; i < pSW->number; ++i) {
    smaId = *(tb_uid_t *)taosArrayGet(pSmaIds, i);
    if (metaGetTableEntryByUid(&mr, smaId) < 0) {
S
Shengliang Guan 已提交
602
      metaWarn("vgId:%d, no entry for tbId:%" PRIi64 ", smaId:%" PRIi64, TD_VID(pMeta->pVnode), uid, smaId);
C
Cary Xu 已提交
603 604 605 606 607 608 609 610 611 612
      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 已提交
613
        memcpy((void *)pTSma->expr, mr.me.smaEntry.tsma->expr, pTSma->exprLen);
H
Hongze Cheng 已提交
614
      }
C
Cary Xu 已提交
615 616 617 618 619
      if (pTSma->tagsFilterLen > 0) {
        if (!(pTSma->tagsFilter = taosMemoryCalloc(1, pTSma->tagsFilterLen))) {
          terrno = TSDB_CODE_OUT_OF_MEMORY;
          goto _err;
        }
H
Hongze Cheng 已提交
620
      }
H
Hongze Cheng 已提交
621
      memcpy((void *)pTSma->tagsFilter, mr.me.smaEntry.tsma->tagsFilter, pTSma->tagsFilterLen);
C
Cary Xu 已提交
622 623 624 625 626
    } else {
      pTSma->exprLen = 0;
      pTSma->expr = NULL;
      pTSma->tagsFilterLen = 0;
      pTSma->tagsFilter = NULL;
H
Hongze Cheng 已提交
627
    }
H
Hongze Cheng 已提交
628

C
Cary Xu 已提交
629
    ++smaIdx;
H
Hongze Cheng 已提交
630 631
  }

C
Cary Xu 已提交
632 633
  if (smaIdx <= 0) goto _err;
  pSW->number = smaIdx;
H
Hongze Cheng 已提交
634

C
Cary Xu 已提交
635 636
  metaReaderClear(&mr);
  taosArrayDestroy(pSmaIds);
H
Hongze Cheng 已提交
637
  return pSW;
C
Cary Xu 已提交
638 639 640
_err:
  metaReaderClear(&mr);
  taosArrayDestroy(pSmaIds);
C
Cary Xu 已提交
641
  tFreeTSmaWrapper(pSW, deepCopy);
H
Hongze Cheng 已提交
642 643 644
  return NULL;
}

C
Cary Xu 已提交
645
STSma *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid) {
H
Hongze Cheng 已提交
646
  STSma      *pTSma = NULL;
C
Cary Xu 已提交
647 648 649
  SMetaReader mr = {0};
  metaReaderInit(&mr, pMeta, 0);
  if (metaGetTableEntryByUid(&mr, indexUid) < 0) {
S
Shengliang Guan 已提交
650
    metaWarn("vgId:%d, failed to get table entry for smaId:%" PRIi64, TD_VID(pMeta->pVnode), indexUid);
C
Cary Xu 已提交
651 652 653 654 655 656 657 658 659 660 661 662 663 664
    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 已提交
665 666
}

C
Cary Xu 已提交
667
SArray *metaGetSmaIdsByTable(SMeta *pMeta, tb_uid_t uid) {
H
Hongze Cheng 已提交
668
  SArray     *pUids = NULL;
C
Cary Xu 已提交
669
  SSmaIdxKey *pSmaIdxKey = NULL;
H
Hongze Cheng 已提交
670

C
Cary Xu 已提交
671 672
  SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, uid);
  if (!pCur) {
H
Hongze Cheng 已提交
673 674 675
    return NULL;
  }

C
Cary Xu 已提交
676 677 678 679 680
  while (1) {
    tb_uid_t id = metaSmaCursorNext(pCur);
    if (id == 0) {
      break;
    }
H
Hongze Cheng 已提交
681

C
Cary Xu 已提交
682 683
    if (!pUids) {
      pUids = taosArrayInit(16, sizeof(tb_uid_t));
H
Hongze Cheng 已提交
684
      if (!pUids) {
C
Cary Xu 已提交
685 686 687
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        metaCloseSmaCursor(pCur);
        return NULL;
H
Hongze Cheng 已提交
688
      }
C
Cary Xu 已提交
689
    }
H
Hongze Cheng 已提交
690

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

C
Cary Xu 已提交
693 694 695 696 697
    if (taosArrayPush(pUids, &pSmaIdxKey->smaUid) < 0) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      metaCloseSmaCursor(pCur);
      taosArrayDestroy(pUids);
      return NULL;
H
Hongze Cheng 已提交
698 699 700 701 702 703 704
    }
  }

  metaCloseSmaCursor(pCur);
  return pUids;
}

C
Cary Xu 已提交
705
SArray *metaGetSmaTbUids(SMeta *pMeta) {
H
Hongze Cheng 已提交
706
  SArray     *pUids = NULL;
C
Cary Xu 已提交
707 708 709 710 711
  SSmaIdxKey *pSmaIdxKey = NULL;
  tb_uid_t    lastUid = 0;

  SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, 0);
  if (!pCur) {
H
Hongze Cheng 已提交
712 713 714
    return NULL;
  }

C
Cary Xu 已提交
715 716 717 718 719
  while (1) {
    tb_uid_t uid = metaSmaCursorNext(pCur);
    if (uid == 0) {
      break;
    }
H
Hongze Cheng 已提交
720

C
Cary Xu 已提交
721 722 723
    if (lastUid == uid) {
      continue;
    }
H
Hongze Cheng 已提交
724

C
Cary Xu 已提交
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
    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 已提交
742 743
  }

C
Cary Xu 已提交
744 745
  metaCloseSmaCursor(pCur);
  return pUids;
H
Hongze Cheng 已提交
746 747
}

L
Liu Jicong 已提交
748
#endif
H
Hongze Cheng 已提交
749

wmmhello's avatar
wmmhello 已提交
750
const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t type, STagVal *val) {
H
Hongze Cheng 已提交
751
  ASSERT(pEntry->type == TSDB_CHILD_TABLE);
wmmhello's avatar
wmmhello 已提交
752
  STag *tag = (STag *)pEntry->ctbEntry.pTags;
dengyihao's avatar
dengyihao 已提交
753
  if (type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
754 755
    return tag;
  }
wmmhello's avatar
wmmhello 已提交
756 757
  bool find = tTagGet(tag, val);

dengyihao's avatar
dengyihao 已提交
758
  if (!find) {
wmmhello's avatar
wmmhello 已提交
759 760 761
    return NULL;
  }
  return val;
dengyihao's avatar
dengyihao 已提交
762
}
wmmhello's avatar
wmmhello 已提交
763 764

typedef struct {
H
Hongze Cheng 已提交
765 766
  SMeta   *pMeta;
  TBC     *pCur;
wmmhello's avatar
wmmhello 已提交
767 768 769
  tb_uid_t suid;
  int16_t  cid;
  int16_t  type;
H
Hongze Cheng 已提交
770 771
  void    *pKey;
  void    *pVal;
wmmhello's avatar
wmmhello 已提交
772 773 774 775
  int32_t  kLen;
  int32_t  vLen;
} SIdxCursor;

dengyihao's avatar
dengyihao 已提交
776 777 778
int32_t metaFilterTableIds(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
  int32_t ret = 0;
  char   *buf = NULL;
wmmhello's avatar
wmmhello 已提交
779

dengyihao's avatar
dengyihao 已提交
780 781 782 783
  STagIdxKey *pKey = NULL;
  int32_t     nKey = 0;

  SIdxCursor *pCursor = NULL;
wmmhello's avatar
wmmhello 已提交
784 785 786 787 788 789 790 791 792 793 794 795
  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 已提交
796
  int32_t maxSize = 0;
wmmhello's avatar
wmmhello 已提交
797
  int32_t nTagData = 0;
H
Hongze Cheng 已提交
798
  void   *tagData = NULL;
dengyihao's avatar
dengyihao 已提交
799

dengyihao's avatar
dengyihao 已提交
800
  if (param->val == NULL) {
S
Shengliang Guan 已提交
801
    metaError("vgId:%d, failed to filter NULL data", TD_VID(pMeta->pVnode));
dengyihao's avatar
dengyihao 已提交
802
    return -1;
dengyihao's avatar
dengyihao 已提交
803
  } else {
dengyihao's avatar
dengyihao 已提交
804 805 806 807 808 809 810 811 812 813
    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 已提交
814

dengyihao's avatar
dengyihao 已提交
815 816 817 818 819 820
        tagData = buf;
        nTagData = maxSize;
      }
    } else {
      tagData = param->val;
      nTagData = tDataTypes[param->type].bytes;
dengyihao's avatar
dengyihao 已提交
821
    }
wmmhello's avatar
wmmhello 已提交
822
  }
dengyihao's avatar
dengyihao 已提交
823
  ret = metaCreateTagIdxKey(pCursor->suid, pCursor->cid, tagData, nTagData, pCursor->type,
wmmhello's avatar
wmmhello 已提交
824
                            param->reverse ? INT64_MAX : INT64_MIN, &pKey, &nKey);
dengyihao's avatar
dengyihao 已提交
825

wmmhello's avatar
wmmhello 已提交
826 827 828 829 830 831 832
  if (ret != 0) {
    goto END;
  }
  int cmp = 0;
  if (tdbTbcMoveTo(pCursor->pCur, pKey, nKey, &cmp) < 0) {
    goto END;
  }
dengyihao's avatar
dengyihao 已提交
833

dengyihao's avatar
dengyihao 已提交
834
  bool    first = true;
dengyihao's avatar
dengyihao 已提交
835
  int32_t valid = 0;
wmmhello's avatar
wmmhello 已提交
836
  while (1) {
dengyihao's avatar
dengyihao 已提交
837 838 839
    void   *entryKey = NULL, *entryVal = NULL;
    int32_t nEntryKey, nEntryVal;

wmmhello's avatar
wmmhello 已提交
840 841 842 843 844
    valid = tdbTbcGet(pCursor->pCur, (const void **)&entryKey, &nEntryKey, (const void **)&entryVal, &nEntryVal);
    if (valid < 0) {
      break;
    }
    STagIdxKey *p = entryKey;
dengyihao's avatar
dengyihao 已提交
845 846 847 848 849 850 851 852 853 854
    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 已提交
855 856 857 858
    if (p != NULL) {
      int32_t cmp = (*param->filterFunc)(p->data, pKey->data, pKey->type);
      if (cmp == 0) {
        // match
dengyihao's avatar
dengyihao 已提交
859 860 861 862 863 864
        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 已提交
865 866 867 868 869 870 871 872 873 874 875 876 877
        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 已提交
878

wmmhello's avatar
wmmhello 已提交
879 880 881
END:
  if (pCursor->pMeta) metaULock(pCursor->pMeta);
  if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
dengyihao's avatar
dengyihao 已提交
882
  taosMemoryFree(buf);
dengyihao's avatar
dengyihao 已提交
883
  taosMemoryFree(pKey);
wmmhello's avatar
wmmhello 已提交
884 885 886 887

  taosMemoryFree(pCursor);

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