metaQuery.c 20.6 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
  // num of child tables (excluding normal tables , stables and others)

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

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

C
Cary Xu 已提交
631
    ++smaIdx;
H
Hongze Cheng 已提交
632 633
  }

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

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

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

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

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

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

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

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

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

  metaCloseSmaCursor(pCur);
  return pUids;
}

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

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

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

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

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

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

L
Liu Jicong 已提交
750
#endif
H
Hongze Cheng 已提交
751

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

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

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

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

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

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

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

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

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

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

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

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

  taosMemoryFree(pCursor);

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