tdataformat.c 30.8 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * 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/>.
 */
S
common  
Shengliang Guan 已提交
15 16

#define _DEFAULT_SOURCE
S
slguan 已提交
17
#include "tdataformat.h"
S
Shengliang Guan 已提交
18
#include "tcoding.h"
L
Liu Jicong 已提交
19
#include "tdatablock.h"
S
log  
Shengliang Guan 已提交
20
#include "tlog.h"
H
more  
hzcheng 已提交
21

C
Cary Xu 已提交
22 23
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson);

H
Hongze Cheng 已提交
24 25 26
#pragma pack(push, 1)
typedef struct {
  int16_t nCols;
H
more  
Hongze Cheng 已提交
27
  uint8_t idx[];
H
Hongze Cheng 已提交
28 29 30
} STSKVRow;
#pragma pack(pop)

H
Hongze Cheng 已提交
31 32
#define TSROW_IS_KV_ROW(r) ((r)->flags & TSROW_KV_ROW)

H
Hongze Cheng 已提交
33
// SValue
H
Hongze Cheng 已提交
34
int32_t tPutValue(uint8_t *p, SValue *pValue, int8_t type) {
H
Hongze Cheng 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  int32_t n = 0;

  if (IS_VAR_DATA_TYPE(type)) {
    n += tPutBinary(p ? p + n : p, pValue->pData, pValue->nData);
  } else {
    switch (type) {
      case TSDB_DATA_TYPE_BOOL:
        n += tPutI8(p ? p + n : p, pValue->i8 ? 1 : 0);
        break;
      case TSDB_DATA_TYPE_TINYINT:
        n += tPutI8(p ? p + n : p, pValue->i8);
        break;
      case TSDB_DATA_TYPE_SMALLINT:
        n += tPutI16(p ? p + n : p, pValue->i16);
        break;
      case TSDB_DATA_TYPE_INT:
        n += tPutI32(p ? p + n : p, pValue->i32);
        break;
      case TSDB_DATA_TYPE_BIGINT:
        n += tPutI64(p ? p + n : p, pValue->i64);
        break;
      case TSDB_DATA_TYPE_FLOAT:
        n += tPutFloat(p ? p + n : p, pValue->f);
        break;
      case TSDB_DATA_TYPE_DOUBLE:
        n += tPutDouble(p ? p + n : p, pValue->d);
        break;
      case TSDB_DATA_TYPE_TIMESTAMP:
        n += tPutI64(p ? p + n : p, pValue->ts);
        break;
      case TSDB_DATA_TYPE_UTINYINT:
        n += tPutU8(p ? p + n : p, pValue->u8);
        break;
      case TSDB_DATA_TYPE_USMALLINT:
        n += tPutU16(p ? p + n : p, pValue->u16);
        break;
      case TSDB_DATA_TYPE_UINT:
        n += tPutU32(p ? p + n : p, pValue->u32);
        break;
      case TSDB_DATA_TYPE_UBIGINT:
        n += tPutU64(p ? p + n : p, pValue->u64);
        break;
      default:
        ASSERT(0);
    }
  }

  return n;
}

H
Hongze Cheng 已提交
85
int32_t tGetValue(uint8_t *p, SValue *pValue, int8_t type) {
H
Hongze Cheng 已提交
86 87 88
  int32_t n = 0;

  if (IS_VAR_DATA_TYPE(type)) {
H
Hongze Cheng 已提交
89
    n += tGetBinary(p, &pValue->pData, pValue ? &pValue->nData : NULL);
H
Hongze Cheng 已提交
90 91 92
  } else {
    switch (type) {
      case TSDB_DATA_TYPE_BOOL:
H
Hongze Cheng 已提交
93
        n += tGetI8(p, &pValue->i8);
H
Hongze Cheng 已提交
94 95
        break;
      case TSDB_DATA_TYPE_TINYINT:
H
Hongze Cheng 已提交
96
        n += tGetI8(p, &pValue->i8);
H
Hongze Cheng 已提交
97 98
        break;
      case TSDB_DATA_TYPE_SMALLINT:
H
Hongze Cheng 已提交
99
        n += tGetI16(p, &pValue->i16);
H
Hongze Cheng 已提交
100 101
        break;
      case TSDB_DATA_TYPE_INT:
H
Hongze Cheng 已提交
102
        n += tGetI32(p, &pValue->i32);
H
Hongze Cheng 已提交
103 104
        break;
      case TSDB_DATA_TYPE_BIGINT:
H
Haojun Liao 已提交
105 106
        pValue->i64 = *(int64_t*)p;
        n += sizeof(int64_t);
H
Hongze Cheng 已提交
107 108
        break;
      case TSDB_DATA_TYPE_FLOAT:
H
Hongze Cheng 已提交
109
        n += tGetFloat(p, &pValue->f);
H
Hongze Cheng 已提交
110 111
        break;
      case TSDB_DATA_TYPE_DOUBLE:
H
Hongze Cheng 已提交
112
        n += tGetDouble(p, &pValue->d);
H
Hongze Cheng 已提交
113 114
        break;
      case TSDB_DATA_TYPE_TIMESTAMP:
H
Hongze Cheng 已提交
115
        n += tGetI64(p, &pValue->ts);
H
Hongze Cheng 已提交
116 117
        break;
      case TSDB_DATA_TYPE_UTINYINT:
H
Hongze Cheng 已提交
118
        n += tGetU8(p, &pValue->u8);
H
Hongze Cheng 已提交
119 120
        break;
      case TSDB_DATA_TYPE_USMALLINT:
H
Hongze Cheng 已提交
121
        n += tGetU16(p, &pValue->u16);
H
Hongze Cheng 已提交
122 123
        break;
      case TSDB_DATA_TYPE_UINT:
H
Hongze Cheng 已提交
124
        n += tGetU32(p, &pValue->u32);
H
Hongze Cheng 已提交
125 126
        break;
      case TSDB_DATA_TYPE_UBIGINT:
H
Haojun Liao 已提交
127 128
        pValue->u64 = *(uint64_t*)p;
        n += sizeof(uint64_t);
H
Hongze Cheng 已提交
129 130 131 132 133 134 135 136 137
        break;
      default:
        ASSERT(0);
    }
  }

  return n;
}

H
more  
Hongze Cheng 已提交
138 139 140 141 142
int tValueCmprFn(const SValue *pValue1, const SValue *pValue2, int8_t type) {
  // TODO
  return 0;
}

H
Hongze Cheng 已提交
143
// STSRow2 ========================================================================
H
Hongze Cheng 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
static void setBitMap(uint8_t *pb, uint8_t v, int32_t idx, uint8_t flags) {
  if (pb) {
    switch (flags & 0xf) {
      case TSROW_HAS_NULL | TSROW_HAS_NONE:
      case TSROW_HAS_VAL | TSROW_HAS_NONE:
        if (v) {
          SET_BIT1(pb, idx, (uint8_t)1);
        } else {
          SET_BIT1(pb, idx, (uint8_t)0);
        }
        break;
      case TSROW_HAS_VAL | TSROW_HAS_NULL:
        v = v - 1;
        SET_BIT1(pb, idx, v);
        break;
      case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
        SET_BIT2(pb, idx, v);
        break;
H
more  
Hongze Cheng 已提交
162

H
Hongze Cheng 已提交
163 164
      default:
        ASSERT(0);
H
more  
Hongze Cheng 已提交
165 166
    }
  }
H
Hongze Cheng 已提交
167 168 169 170 171 172 173 174 175 176 177
}
#define SET_IDX(p, i, n, f)        \
  do {                             \
    if ((f)&TSROW_KV_SMALL) {      \
      ((uint8_t *)(p))[i] = (n);   \
    } else if ((f)&TSROW_KV_MID) { \
      ((uint16_t *)(p))[i] = (n);  \
    } else {                       \
      ((uint32_t *)(p))[i] = (n);  \
    }                              \
  } while (0)
H
more  
Hongze Cheng 已提交
178

H
Hongze Cheng 已提交
179
int32_t tTSRowNew(STSRowBuilder *pBuilder, SArray *pArray, STSchema *pTSchema, STSRow2 **ppRow) {
H
Hongze Cheng 已提交
180 181
  int32_t code = 0;
#if 0
H
Hongze Cheng 已提交
182 183 184 185
  STColumn *pTColumn;
  SColVal  *pColVal;
  int32_t   nColVal = taosArrayGetSize(pArray);
  int32_t   iColVal;
H
more  
Hongze Cheng 已提交
186

H
Hongze Cheng 已提交
187
  ASSERT(nColVal > 0);
H
more  
Hongze Cheng 已提交
188

H
Hongze Cheng 已提交
189 190 191 192 193 194
  // try
  uint8_t  flags = 0;
  uint32_t ntv = 0;
  uint32_t nkv = 0;
  int16_t  nTag = 0;
  uint32_t maxIdx = 0;
H
more  
Hongze Cheng 已提交
195

H
Hongze Cheng 已提交
196 197
  iColVal = 0;
  for (int32_t iColumn = 0; iColumn < pTSchema->numOfCols; iColumn++) {
H
more  
Hongze Cheng 已提交
198 199 200 201 202 203 204
    pTColumn = &pTSchema->columns[iColumn];
    if (iColVal < nColVal) {
      pColVal = (SColVal *)taosArrayGet(pArray, iColVal);
    } else {
      pColVal = NULL;
    }

H
Hongze Cheng 已提交
205 206 207
    if (iColumn == 0) {
      ASSERT(pColVal->cid == pTColumn->colId);
      ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
C
Cary Xu 已提交
208
      ASSERT(pTColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID);
H
Hongze Cheng 已提交
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

      iColVal++;
    } else {
      if (pColVal) {
        if (pColVal->cid == pTColumn->colId) {
          iColVal++;

          if (pColVal->isNone) {
            flags |= TSROW_HAS_NONE;
          } else if (pColVal->isNull) {
            flags |= TSROW_HAS_NULL;
            maxIdx = nkv;
            nTag++;
            nkv += tPutI16v(NULL, -pTColumn->colId);
          } else {
            flags |= TSROW_HAS_VAL;
            maxIdx = nkv;
            nTag++;
            nkv += tPutI16v(NULL, pTColumn->colId);
            nkv += tPutValue(NULL, &pColVal->value, pTColumn->type);
            if (IS_VAR_DATA_TYPE(pTColumn->type)) {
              ntv += tPutValue(NULL, &pColVal->value, pTColumn->type);
            }
          }
        } else if (pColVal->cid > pTColumn->colId) {
          flags |= TSROW_HAS_NONE;
H
more  
Hongze Cheng 已提交
235
        } else {
H
Hongze Cheng 已提交
236
          ASSERT(0);
H
more  
Hongze Cheng 已提交
237 238
        }
      } else {
H
Hongze Cheng 已提交
239
        flags |= TSROW_HAS_NONE;
H
more  
Hongze Cheng 已提交
240 241
      }
    }
H
Hongze Cheng 已提交
242
  }
H
more  
Hongze Cheng 已提交
243

C
Cary Xu 已提交
244
  ASSERT(flags);
H
more  
Hongze Cheng 已提交
245

H
Hongze Cheng 已提交
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
  // decide
  uint32_t nData = 0;
  uint32_t nDataT = 0;
  uint32_t nDataK = 0;
  if (flags == TSROW_HAS_NONE || flags == TSROW_HAS_NULL) {
    nData = 0;
  } else {
    switch (flags) {
      case TSROW_HAS_VAL:
        nDataT = pTSchema->flen + ntv;
        break;
      case TSROW_HAS_NULL | TSROW_HAS_NONE:
        nDataT = BIT1_SIZE(pTSchema->numOfCols - 1);
        break;
      case TSROW_HAS_VAL | TSROW_HAS_NONE:
      case TSROW_HAS_VAL | TSROW_HAS_NULL:
        nDataT = BIT1_SIZE(pTSchema->numOfCols - 1) + pTSchema->flen + ntv;
        break;
      case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
        nDataT = BIT2_SIZE(pTSchema->numOfCols - 1) + pTSchema->flen + ntv;
        break;
      default:
C
Cary Xu 已提交
268 269
        break;
        ASSERT(0);
H
more  
Hongze Cheng 已提交
270 271
    }

H
Hongze Cheng 已提交
272 273 274 275 276 277 278 279 280 281
    uint8_t tflags = 0;
    if (maxIdx <= UINT8_MAX) {
      nDataK = sizeof(STSKVRow) + sizeof(uint8_t) * nTag + nkv;
      tflags |= TSROW_KV_SMALL;
    } else if (maxIdx <= UINT16_MAX) {
      nDataK = sizeof(STSKVRow) + sizeof(uint16_t) * nTag + nkv;
      tflags |= TSROW_KV_MID;
    } else {
      nDataK = sizeof(STSKVRow) + sizeof(uint32_t) * nTag + nkv;
      tflags |= TSROW_KV_BIG;
H
more  
Hongze Cheng 已提交
282 283
    }

C
Cary Xu 已提交
284
    if (nDataT <= nDataK) {
H
Hongze Cheng 已提交
285
      nData = nDataT;
H
more  
Hongze Cheng 已提交
286
    } else {
H
Hongze Cheng 已提交
287 288
      nData = nDataK;
      flags |= tflags;
H
more  
Hongze Cheng 已提交
289 290
    }
  }
H
more  
Hongze Cheng 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308

  // alloc
  if (pBuilder) {
    // create from a builder
    if (nData == 0) {
      pBuilder->tsRow.nData = 0;
      pBuilder->tsRow.pData = NULL;
    } else {
      if (pBuilder->szBuf < nData) {
        uint8_t *p = taosMemoryRealloc(pBuilder->pBuf, nData);
        if (p == NULL) {
          code = TSDB_CODE_OUT_OF_MEMORY;
          goto _exit;
        }
        pBuilder->pBuf = p;
        pBuilder->szBuf = nData;
      }

H
Hongze Cheng 已提交
309
      pBuilder->tsRow.nData = nData;
H
more  
Hongze Cheng 已提交
310 311 312 313 314 315 316 317
      pBuilder->tsRow.pData = pBuilder->pBuf;
    }

    *ppRow = &pBuilder->tsRow;
  } else {
    // create a new one
    *ppRow = (STSRow2 *)taosMemoryMalloc(sizeof(STSRow2));
    if (*ppRow == NULL) {
H
more  
Hongze Cheng 已提交
318 319 320
      code = TSDB_CODE_OUT_OF_MEMORY;
      goto _exit;
    }
H
Hongze Cheng 已提交
321 322 323 324 325
    if (nData == 0) {
      (*ppRow)->nData = 0;
      (*ppRow)->pData = NULL;
    } else {
      (*ppRow)->nData = nData;
H
more  
Hongze Cheng 已提交
326 327
      (*ppRow)->pData = taosMemoryMalloc(nData);
      if ((*ppRow)->pData == NULL) {
H
Hongze Cheng 已提交
328
        taosMemoryFree(*ppRow);
H
more  
Hongze Cheng 已提交
329 330 331 332
        code = TSDB_CODE_OUT_OF_MEMORY;
        goto _exit;
      }
    }
H
more  
Hongze Cheng 已提交
333
  }
H
more  
Hongze Cheng 已提交
334

H
Hongze Cheng 已提交
335 336 337
  // build
  (*ppRow)->flags = flags;
  (*ppRow)->sver = pTSchema->version;
H
more  
Hongze Cheng 已提交
338

H
Hongze Cheng 已提交
339 340 341 342 343 344 345 346 347 348 349 350 351 352
  pColVal = (SColVal *)taosArrayGet(pArray, 0);
  (*ppRow)->ts = pColVal->value.ts;

  if ((*ppRow)->pData) {
    STSKVRow *pTSKVRow = NULL;
    uint8_t  *pidx = NULL;
    uint8_t  *pkv = NULL;
    uint8_t  *pb = NULL;
    uint8_t  *pf = NULL;
    uint8_t  *ptv = NULL;
    nkv = 0;
    ntv = 0;
    iColVal = 1;

C
Cary Xu 已提交
353
    if ((flags & 0xf0) == 0) {
H
Hongze Cheng 已提交
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
      switch (flags & 0xf) {
        case TSROW_HAS_VAL:
          pf = (*ppRow)->pData;
          ptv = pf + pTSchema->flen;
          break;
        case TSROW_HAS_NULL | TSROW_HAS_NONE:
          pb = (*ppRow)->pData;
          break;
        case TSROW_HAS_VAL | TSROW_HAS_NONE:
        case TSROW_HAS_VAL | TSROW_HAS_NULL:
          pb = (*ppRow)->pData;
          pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
          ptv = pf + pTSchema->flen;
          break;
        case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
          pb = (*ppRow)->pData;
          pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
          ptv = pf + pTSchema->flen;
          break;
        default:
C
Cary Xu 已提交
374
          ASSERT(0);
C
Cary Xu 已提交
375
          break;
H
Hongze Cheng 已提交
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 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
      }
    } else {
      pTSKVRow = (STSKVRow *)(*ppRow)->pData;
      pTSKVRow->nCols = 0;
      pidx = pTSKVRow->idx;
      if (flags & TSROW_KV_SMALL) {
        pkv = pidx + sizeof(uint8_t) * nTag;
      } else if (flags & TSROW_KV_MID) {
        pkv = pidx + sizeof(uint16_t) * nTag;
      } else {
        pkv = pidx + sizeof(uint32_t) * nTag;
      }
    }

    for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) {
      pTColumn = &pTSchema->columns[iColumn];
      if (iColVal < nColVal) {
        pColVal = (SColVal *)taosArrayGet(pArray, iColVal);
      } else {
        pColVal = NULL;
      }

      if (pColVal) {
        if (pColVal->cid == pTColumn->colId) {
          iColVal++;

          if (pColVal->isNone) {
            goto _set_none;
          } else if (pColVal->isNull) {
            goto _set_null;
          } else {
            goto _set_value;
          }
        } else if (pColVal->cid > pTColumn->colId) {
          goto _set_none;
        } else {
          ASSERT(0);
        }
      } else {
        goto _set_none;
      }

    _set_none:
C
Cary Xu 已提交
419
      if ((flags & 0xf0) == 0) {
H
Hongze Cheng 已提交
420
        setBitMap(pb, 0, iColumn - 1, flags);
H
Hongze Cheng 已提交
421
        if (flags & TSROW_HAS_VAL) {  // set 0
C
Cary Xu 已提交
422 423 424 425 426 427
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
            *(VarDataOffsetT *)(pf + pTColumn->offset) = 0;
          } else {
            tPutValue(pf + pTColumn->offset, &((SValue){0}), pTColumn->type);
          }
        }
H
Hongze Cheng 已提交
428 429 430 431
      }
      continue;

    _set_null:
C
Cary Xu 已提交
432
      if ((flags & 0xf0) == 0) {
H
Hongze Cheng 已提交
433
        setBitMap(pb, 1, iColumn - 1, flags);
H
Hongze Cheng 已提交
434
        if (flags & TSROW_HAS_VAL) {  // set 0
C
Cary Xu 已提交
435 436 437 438 439 440
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
            *(VarDataOffsetT *)(pf + pTColumn->offset) = 0;
          } else {
            tPutValue(pf + pTColumn->offset, &((SValue){0}), pTColumn->type);
          }
        }
H
Hongze Cheng 已提交
441 442 443 444 445 446
      } else {
        SET_IDX(pidx, pTSKVRow->nCols, nkv, flags);
        pTSKVRow->nCols++;
        nkv += tPutI16v(pkv + nkv, -pTColumn->colId);
      }
      continue;
H
more  
Hongze Cheng 已提交
447

H
Hongze Cheng 已提交
448
    _set_value:
C
Cary Xu 已提交
449
      if ((flags & 0xf0) == 0) {
H
Hongze Cheng 已提交
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
        setBitMap(pb, 2, iColumn - 1, flags);

        if (IS_VAR_DATA_TYPE(pTColumn->type)) {
          *(VarDataOffsetT *)(pf + pTColumn->offset) = ntv;
          ntv += tPutValue(ptv + ntv, &pColVal->value, pTColumn->type);
        } else {
          tPutValue(pf + pTColumn->offset, &pColVal->value, pTColumn->type);
        }
      } else {
        SET_IDX(pidx, pTSKVRow->nCols, nkv, flags);
        pTSKVRow->nCols++;
        nkv += tPutI16v(pkv + nkv, pColVal->cid);
        nkv += tPutValue(pkv + nkv, &pColVal->value, pTColumn->type);
      }
      continue;
    }
H
more  
Hongze Cheng 已提交
466 467
  }

H
Hongze Cheng 已提交
468
#endif
H
more  
Hongze Cheng 已提交
469
_exit:
H
Hongze Cheng 已提交
470 471 472
  return code;
}

H
Hongze Cheng 已提交
473 474
int32_t tTSRowClone(const STSRow2 *pRow, STSRow2 **ppRow) {
  int32_t code = 0;
H
Hongze Cheng 已提交
475
  int32_t rLen;
H
Hongze Cheng 已提交
476

H
Hongze Cheng 已提交
477 478
  TSROW_LEN(pRow, rLen);
  (*ppRow) = (STSRow2 *)taosMemoryMalloc(rLen);
H
Hongze Cheng 已提交
479
  if (*ppRow == NULL) {
H
Hongze Cheng 已提交
480 481
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
H
Hongze Cheng 已提交
482
  }
H
Hongze Cheng 已提交
483
  memcpy(*ppRow, pRow, rLen);
H
Hongze Cheng 已提交
484

H
Hongze Cheng 已提交
485 486
_exit:
  return code;
H
Hongze Cheng 已提交
487 488 489
}

void tTSRowFree(STSRow2 *pRow) {
H
Hongze Cheng 已提交
490 491 492
  if (pRow) {
    taosMemoryFree(pRow);
  }
H
Hongze Cheng 已提交
493 494
}

H
Hongze Cheng 已提交
495
void tTSRowGet(STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
H
Hongze Cheng 已提交
496
#if 0
C
Cary Xu 已提交
497
  uint8_t   isTuple = ((pRow->flags & 0xf0) == 0) ? 1 : 0;
H
Hongze Cheng 已提交
498
  STColumn *pTColumn = &pTSchema->columns[iCol];
H
Hongze Cheng 已提交
499 500
  uint8_t   flags = pRow->flags & (uint8_t)0xf;
  SValue    value;
H
Hongze Cheng 已提交
501

H
Hongze Cheng 已提交
502
  ASSERT(iCol < pTSchema->numOfCols);
C
Cary Xu 已提交
503
  ASSERT(flags);
H
Hongze Cheng 已提交
504
  ASSERT(pRow->sver == pTSchema->version);
H
Hongze Cheng 已提交
505

H
Hongze Cheng 已提交
506 507 508
  if (iCol == 0) {
    value.ts = pRow->ts;
    goto _return_value;
H
Hongze Cheng 已提交
509 510
  }

H
Hongze Cheng 已提交
511
  if (flags == TSROW_HAS_NONE) {
H
more  
Hongze Cheng 已提交
512
    goto _return_none;
C
Cary Xu 已提交
513
  } else if (flags == TSROW_HAS_NULL) {
H
more  
Hongze Cheng 已提交
514
    goto _return_null;
H
Hongze Cheng 已提交
515
  }
H
Hongze Cheng 已提交
516

H
Hongze Cheng 已提交
517 518 519 520 521 522 523 524 525 526 527 528 529 530
  ASSERT(pRow->nData && pRow->pData);

  if (isTuple) {
    uint8_t *pb = pRow->pData;
    uint8_t *pf = NULL;
    uint8_t *pv = NULL;
    uint8_t *p;
    uint8_t  b;

    // bit
    switch (flags) {
      case TSROW_HAS_VAL:
        pf = pb;
        break;
H
Hongze Cheng 已提交
531
      case TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
532 533 534
        b = GET_BIT1(pb, iCol - 1);
        if (b == 0) {
          goto _return_none;
H
Hongze Cheng 已提交
535
        } else {
H
Hongze Cheng 已提交
536
          goto _return_null;
H
Hongze Cheng 已提交
537
        }
H
Hongze Cheng 已提交
538
      case TSROW_HAS_VAL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
539 540 541
        b = GET_BIT1(pb, iCol - 1);
        if (b == 0) {
          goto _return_none;
H
Hongze Cheng 已提交
542
        } else {
H
Hongze Cheng 已提交
543 544
          pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
          break;
H
Hongze Cheng 已提交
545
        }
H
Hongze Cheng 已提交
546
      case TSROW_HAS_VAL | TSROW_HAS_NULL:
H
Hongze Cheng 已提交
547 548 549
        b = GET_BIT1(pb, iCol - 1);
        if (b == 0) {
          goto _return_null;
H
Hongze Cheng 已提交
550
        } else {
H
Hongze Cheng 已提交
551 552
          pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
          break;
H
Hongze Cheng 已提交
553
        }
H
Hongze Cheng 已提交
554
      case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
555 556 557 558 559
        b = GET_BIT2(pb, iCol - 1);
        if (b == 0) {
          goto _return_none;
        } else if (b == 1) {
          goto _return_null;
H
Hongze Cheng 已提交
560
        } else {
H
Hongze Cheng 已提交
561 562
          pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
          break;
H
Hongze Cheng 已提交
563
        }
H
Hongze Cheng 已提交
564
      default:
H
Hongze Cheng 已提交
565
        ASSERT(0);
H
Hongze Cheng 已提交
566
    }
H
Hongze Cheng 已提交
567

H
Hongze Cheng 已提交
568 569 570
    ASSERT(pf);

    p = pf + pTColumn->offset;
H
Hongze Cheng 已提交
571
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
H
Hongze Cheng 已提交
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
      pv = pf + pTSchema->flen;
      p = pv + *(VarDataOffsetT *)p;
    }
    tGetValue(p, &value, pTColumn->type);
    goto _return_value;
  } else {
    STSKVRow *pRowK = (STSKVRow *)pRow->pData;
    int16_t   lidx = 0;
    int16_t   ridx = pRowK->nCols - 1;
    uint8_t  *p;
    int16_t   midx;
    uint32_t  n;
    int16_t   cid;

    ASSERT(pRowK->nCols > 0);

    if (pRow->flags & TSROW_KV_SMALL) {
      p = pRow->pData + sizeof(STSKVRow) + sizeof(uint8_t) * pRowK->nCols;
    } else if (pRow->flags & TSROW_KV_MID) {
      p = pRow->pData + sizeof(STSKVRow) + sizeof(uint16_t) * pRowK->nCols;
    } else if (pRow->flags & TSROW_KV_BIG) {
      p = pRow->pData + sizeof(STSKVRow) + sizeof(uint32_t) * pRowK->nCols;
H
Hongze Cheng 已提交
594
    } else {
H
Hongze Cheng 已提交
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
      ASSERT(0);
    }
    while (lidx <= ridx) {
      midx = (lidx + ridx) / 2;

      if (pRow->flags & TSROW_KV_SMALL) {
        n = ((uint8_t *)pRowK->idx)[midx];
      } else if (pRow->flags & TSROW_KV_MID) {
        n = ((uint16_t *)pRowK->idx)[midx];
      } else {
        n = ((uint32_t *)pRowK->idx)[midx];
      }

      n += tGetI16v(p + n, &cid);

      if (TABS(cid) == pTColumn->colId) {
        if (cid < 0) {
          goto _return_null;
        } else {
          n += tGetValue(p + n, &value, pTColumn->type);
          goto _return_value;
        }

        return;
      } else if (TABS(cid) > pTColumn->colId) {
        ridx = midx - 1;
      } else {
        lidx = midx + 1;
      }
H
Hongze Cheng 已提交
624
    }
H
Hongze Cheng 已提交
625 626 627

    // not found, return NONE
    goto _return_none;
H
Hongze Cheng 已提交
628
  }
H
Hongze Cheng 已提交
629

H
Hongze Cheng 已提交
630
_return_none:
H
Hongze Cheng 已提交
631
  *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
H
Hongze Cheng 已提交
632 633 634
  return;

_return_null:
H
Hongze Cheng 已提交
635
  *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
H
Hongze Cheng 已提交
636 637 638
  return;

_return_value:
H
Hongze Cheng 已提交
639
  *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, value);
H
Hongze Cheng 已提交
640
  return;
H
Hongze Cheng 已提交
641
#endif
H
Hongze Cheng 已提交
642 643 644 645
}

int32_t tTSRowToArray(STSRow2 *pRow, STSchema *pTSchema, SArray **ppArray) {
  int32_t code = 0;
H
Hongze Cheng 已提交
646
#if 0
H
Hongze Cheng 已提交
647 648 649 650 651 652 653 654 655 656 657 658 659
  SColVal cv;

  (*ppArray) = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
  if (*ppArray == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

  for (int32_t iColumn = 0; iColumn < pTSchema->numOfCols; iColumn++) {
    tTSRowGet(pRow, pTSchema, iColumn, &cv);
    taosArrayPush(*ppArray, &cv);
  }

H
Hongze Cheng 已提交
660
#endif
H
Hongze Cheng 已提交
661 662 663 664 665
_exit:
  return code;
}

int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow) {
H
Hongze Cheng 已提交
666
  int32_t n;
H
Hongze Cheng 已提交
667

H
Hongze Cheng 已提交
668 669 670
  TSROW_LEN(pRow, n);
  if (p) {
    memcpy(p, pRow, n);
H
Hongze Cheng 已提交
671 672 673 674 675
  }

  return n;
}

H
Hongze Cheng 已提交
676 677
int32_t tGetTSRow(uint8_t *p, STSRow2 **ppRow) {
  int32_t n;
H
Hongze Cheng 已提交
678

H
Hongze Cheng 已提交
679 680
  *ppRow = (STSRow2 *)p;
  TSROW_LEN(*ppRow, n);
H
Hongze Cheng 已提交
681 682

  return n;
H
Hongze Cheng 已提交
683 684 685
}

// STSchema
H
Hongze Cheng 已提交
686 687 688 689 690 691 692
int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t ncols, STSchema **ppTSchema) {
  *ppTSchema = (STSchema *)taosMemoryMalloc(sizeof(STSchema) + sizeof(STColumn) * ncols);
  if (*ppTSchema == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

H
Hongze Cheng 已提交
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717
  (*ppTSchema)->numOfCols = ncols;
  (*ppTSchema)->version = sver;
  (*ppTSchema)->flen = 0;
  (*ppTSchema)->vlen = 0;
  (*ppTSchema)->tlen = 0;

  for (int32_t iCol = 0; iCol < ncols; iCol++) {
    SSchema  *pColumn = &pSchema[iCol];
    STColumn *pTColumn = &((*ppTSchema)->columns[iCol]);

    pTColumn->colId = pColumn->colId;
    pTColumn->type = pColumn->type;
    pTColumn->flags = pColumn->flags;
    pTColumn->bytes = pColumn->bytes;
    pTColumn->offset = (*ppTSchema)->flen;

    // skip first column
    if (iCol) {
      (*ppTSchema)->flen += TYPE_BYTES[pColumn->type];
      if (IS_VAR_DATA_TYPE(pColumn->type)) {
        (*ppTSchema)->vlen += (pColumn->bytes + 5);
      }
    }
  }

H
Hongze Cheng 已提交
718 719 720
  return 0;
}

H
Hongze Cheng 已提交
721 722 723
void tTSchemaDestroy(STSchema *pTSchema) {
  if (pTSchema) taosMemoryFree(pTSchema);
}
H
Hongze Cheng 已提交
724

H
Hongze Cheng 已提交
725
// STSRowBuilder
H
Hongze Cheng 已提交
726

H
more  
Hongze Cheng 已提交
727
// STag
H
Hongze Cheng 已提交
728 729
static int tTagValCmprFn(const void *p1, const void *p2) {
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
H
Hongze Cheng 已提交
730
    return -1;
H
Hongze Cheng 已提交
731
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
H
Hongze Cheng 已提交
732 733
    return 1;
  }
H
Hongze Cheng 已提交
734

H
Hongze Cheng 已提交
735 736
  return 0;
}
H
Hongze Cheng 已提交
737 738 739
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
}
C
Cary Xu 已提交
740 741 742 743 744 745 746

static void debugPrintTagVal(int8_t type, const void *val, int32_t vlen, const char *tag, int32_t ln) {
  switch (type) {
    case TSDB_DATA_TYPE_JSON:
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_NCHAR: {
      char tmpVal[32] = {0};
747
      strncpy(tmpVal, val, vlen > 31 ? 31 : vlen);
C
Cary Xu 已提交
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
      printf("%s:%d type:%d vlen:%d, val:\"%s\"\n", tag, ln, (int32_t)type, vlen, tmpVal);
    } break;
    case TSDB_DATA_TYPE_FLOAT:
      printf("%s:%d type:%d vlen:%d, val:%f\n", tag, ln, (int32_t)type, vlen, *(float *)val);
      break;
    case TSDB_DATA_TYPE_DOUBLE:
      printf("%s:%d type:%d vlen:%d, val:%lf\n", tag, ln, (int32_t)type, vlen, *(double *)val);
      break;
    case TSDB_DATA_TYPE_BOOL:
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
      break;
    case TSDB_DATA_TYPE_TINYINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
      break;
    case TSDB_DATA_TYPE_SMALLINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIi16 "\n", tag, ln, (int32_t)type, vlen, *(int16_t *)val);
      break;
    case TSDB_DATA_TYPE_INT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIi32 "\n", tag, ln, (int32_t)type, vlen, *(int32_t *)val);
      break;
    case TSDB_DATA_TYPE_BIGINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
      break;
    case TSDB_DATA_TYPE_TIMESTAMP:
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
      break;
    case TSDB_DATA_TYPE_UTINYINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
      break;
    case TSDB_DATA_TYPE_USMALLINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIu16 "\n", tag, ln, (int32_t)type, vlen, *(uint16_t *)val);
      break;
    case TSDB_DATA_TYPE_UINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIu32 "\n", tag, ln, (int32_t)type, vlen, *(uint32_t *)val);
      break;
    case TSDB_DATA_TYPE_UBIGINT:
      printf("%s:%d type:%d vlen:%d, val:%" PRIu64 "\n", tag, ln, (int32_t)type, vlen, *(uint64_t *)val);
      break;
wmmhello's avatar
wmmhello 已提交
786 787 788
    case TSDB_DATA_TYPE_NULL:
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
      break;
C
Cary Xu 已提交
789 790 791 792 793 794 795
    default:
      ASSERT(0);
      break;
  }
}

void debugPrintSTag(STag *pTag, const char *tag, int32_t ln) {
H
Hongze Cheng 已提交
796 797
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
798 799 800 801 802 803 804 805 806 807
  uint8_t *p = NULL;
  int16_t  offset = 0;

  if (isLarge) {
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
  } else {
    p = (uint8_t *)&pTag->idx[pTag->nTag];
  }
  printf("%s:%d >>> STAG === %s:%s, len: %d, nTag: %d, sver:%d\n", tag, ln, isJson ? "json" : "normal",
         isLarge ? "large" : "small", (int32_t)pTag->len, (int32_t)pTag->nTag, pTag->ver);
C
Cary Xu 已提交
808
  for (uint16_t n = 0; n < pTag->nTag; ++n) {
809 810 811 812 813 814 815 816
    if (isLarge) {
      offset = ((int16_t *)pTag->idx)[n];
    } else {
      offset = pTag->idx[n];
    }
    STagVal tagVal = {0};
    if (isJson) {
      tagVal.pKey = (char *)POINTER_SHIFT(p, offset);
C
Cary Xu 已提交
817
    } else {
818
      tagVal.cid = *(int16_t *)POINTER_SHIFT(p, offset);
C
Cary Xu 已提交
819
    }
820
    printf("%s:%d loop[%d-%d] offset=%d\n", __func__, __LINE__, (int32_t)pTag->nTag, (int32_t)n, (int32_t)offset);
C
Cary Xu 已提交
821
    tGetTagVal(p + offset, &tagVal, isJson);
822
    if (IS_VAR_DATA_TYPE(tagVal.type)) {
wmmhello's avatar
wmmhello 已提交
823
      debugPrintTagVal(tagVal.type, tagVal.pData, tagVal.nData, __func__, __LINE__);
824
    } else {
wmmhello's avatar
wmmhello 已提交
825 826
      debugPrintTagVal(tagVal.type, &tagVal.i64, tDataTypes[tagVal.type].bytes, __func__, __LINE__);
    }
C
Cary Xu 已提交
827 828 829 830
  }
  printf("\n");
}

H
Hongze Cheng 已提交
831 832
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
  int32_t n = 0;
H
Hongze Cheng 已提交
833

H
Hongze Cheng 已提交
834 835 836 837 838 839
  // key
  if (isJson) {
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
  } else {
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
  }
H
Hongze Cheng 已提交
840

H
Hongze Cheng 已提交
841 842 843 844 845 846 847
  // type
  n += tPutI8(p ? p + n : p, pTagVal->type);

  // value
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
  } else {
H
Hongze Cheng 已提交
848
    p = p ? p + n : p;
wmmhello's avatar
wmmhello 已提交
849
    n += tDataTypes[pTagVal->type].bytes;
850
    if (p) memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
H
Hongze Cheng 已提交
851 852
  }

H
Hongze Cheng 已提交
853 854 855 856 857 858 859 860 861 862
  return n;
}
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
  int32_t n = 0;

  // key
  if (isJson) {
    n += tGetCStr(p + n, &pTagVal->pKey);
  } else {
    n += tGetI16v(p + n, &pTagVal->cid);
H
Hongze Cheng 已提交
863 864
  }

H
Hongze Cheng 已提交
865 866
  // type
  n += tGetI8(p + n, &pTagVal->type);
H
Hongze Cheng 已提交
867

H
Hongze Cheng 已提交
868 869 870 871
  // value
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
  } else {
wmmhello's avatar
wmmhello 已提交
872
    memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
wmmhello's avatar
wmmhello 已提交
873
    n += tDataTypes[pTagVal->type].bytes;
H
Hongze Cheng 已提交
874 875 876 877
  }

  return n;
}
wmmhello's avatar
wmmhello 已提交
878

H
Hongze Cheng 已提交
879
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
wmmhello's avatar
wmmhello 已提交
880

H
Hongze Cheng 已提交
881 882 883 884 885
bool tTagIsJsonNull(void *data) {
  STag  *pTag = (STag *)data;
  int8_t isJson = tTagIsJson(pTag);
  if (!isJson) return false;
  return ((STag *)data)->nTag == 0;
wmmhello's avatar
wmmhello 已提交
886 887
}

H
Hongze Cheng 已提交
888
int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
H
Hongze Cheng 已提交
889 890 891
  int32_t  code = 0;
  uint8_t *p = NULL;
  int16_t  n = 0;
H
Hongze Cheng 已提交
892
  int16_t  nTag = taosArrayGetSize(pArray);
H
Hongze Cheng 已提交
893 894
  int32_t  szTag = 0;
  int8_t   isLarge = 0;
H
Hongze Cheng 已提交
895 896 897

  // sort
  if (isJson) {
wafwerar's avatar
wafwerar 已提交
898
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
H
Hongze Cheng 已提交
899
  } else {
wafwerar's avatar
wafwerar 已提交
900
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
H
Hongze Cheng 已提交
901 902 903
  }

  // get size
H
Hongze Cheng 已提交
904
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
H
Hongze Cheng 已提交
905
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
H
Hongze Cheng 已提交
906
  }
H
Hongze Cheng 已提交
907 908 909 910 911 912
  if (szTag <= INT8_MAX) {
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
  } else {
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
    isLarge = 1;
  }
H
Hongze Cheng 已提交
913

H
Hongze Cheng 已提交
914
  ASSERT(szTag <= INT16_MAX);
H
Hongze Cheng 已提交
915 916

  // build tag
C
Cary Xu 已提交
917
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
H
Hongze Cheng 已提交
918 919 920 921
  if ((*ppTag) == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }
H
Hongze Cheng 已提交
922 923 924 925 926 927 928
  (*ppTag)->flags = 0;
  if (isJson) {
    (*ppTag)->flags |= TD_TAG_JSON;
  }
  if (isLarge) {
    (*ppTag)->flags |= TD_TAG_LARGE;
  }
H
Hongze Cheng 已提交
929 930 931
  (*ppTag)->len = szTag;
  (*ppTag)->nTag = nTag;
  (*ppTag)->ver = version;
H
Hongze Cheng 已提交
932

H
Hongze Cheng 已提交
933 934 935 936 937
  if (isLarge) {
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
  } else {
    p = (uint8_t *)&(*ppTag)->idx[nTag];
  }
H
Hongze Cheng 已提交
938 939
  n = 0;
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
H
Hongze Cheng 已提交
940 941 942 943 944
    if (isLarge) {
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
    } else {
      (*ppTag)->idx[iTag] = n;
    }
H
Hongze Cheng 已提交
945
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
H
Hongze Cheng 已提交
946
  }
947
#ifdef TD_DEBUG_PRINT_TAG
C
Cary Xu 已提交
948
  debugPrintSTag(*ppTag, __func__, __LINE__);
949
#endif
C
Cary Xu 已提交
950

H
Hongze Cheng 已提交
951 952 953 954
  return code;

_err:
  return code;
H
Hongze Cheng 已提交
955 956 957 958 959 960
}

void tTagFree(STag *pTag) {
  if (pTag) taosMemoryFree(pTag);
}

961 962 963
char *tTagValToData(const STagVal *value, bool isJson) {
  if (!value) return NULL;
  char  *data = NULL;
wmmhello's avatar
wmmhello 已提交
964 965 966 967
  int8_t typeBytes = 0;
  if (isJson) {
    typeBytes = CHAR_BYTES;
  }
968
  if (IS_VAR_DATA_TYPE(value->type)) {
wmmhello's avatar
wmmhello 已提交
969
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
970 971
    if (data == NULL) return NULL;
    if (isJson) *data = value->type;
wmmhello's avatar
wmmhello 已提交
972 973
    varDataLen(data + typeBytes) = value->nData;
    memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
974 975
  } else {
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
wmmhello's avatar
wmmhello 已提交
976 977 978 979 980
  }

  return data;
}

C
Cary Xu 已提交
981
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
H
Hongze Cheng 已提交
982 983 984
  int16_t  lidx = 0;
  int16_t  ridx = pTag->nTag - 1;
  int16_t  midx;
H
Hongze Cheng 已提交
985 986 987 988
  uint8_t *p;
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
  int16_t  offset;
H
Hongze Cheng 已提交
989 990 991
  STagVal  tv;
  int      c;

H
Hongze Cheng 已提交
992 993 994 995 996 997
  if (isLarge) {
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
  } else {
    p = (uint8_t *)&pTag->idx[pTag->nTag];
  }

H
Hongze Cheng 已提交
998 999 1000 1001 1002
  pTagVal->type = TSDB_DATA_TYPE_NULL;
  pTagVal->pData = NULL;
  pTagVal->nData = 0;
  while (lidx <= ridx) {
    midx = (lidx + ridx) / 2;
H
Hongze Cheng 已提交
1003 1004 1005 1006 1007
    if (isLarge) {
      offset = ((int16_t *)pTag->idx)[midx];
    } else {
      offset = pTag->idx[midx];
    }
H
Hongze Cheng 已提交
1008

H
Hongze Cheng 已提交
1009 1010
    tGetTagVal(p + offset, &tv, isJson);
    if (isJson) {
H
Hongze Cheng 已提交
1011
      c = tTagValJsonCmprFn(pTagVal, &tv);
H
Hongze Cheng 已提交
1012
    } else {
H
Hongze Cheng 已提交
1013
      c = tTagValCmprFn(pTagVal, &tv);
H
Hongze Cheng 已提交
1014 1015
    }

H
Hongze Cheng 已提交
1016 1017 1018 1019
    if (c < 0) {
      ridx = midx - 1;
    } else if (c > 0) {
      lidx = midx + 1;
H
Hongze Cheng 已提交
1020
    } else {
H
Hongze Cheng 已提交
1021
      memcpy(pTagVal, &tv, sizeof(tv));
C
Cary Xu 已提交
1022
      return true;
H
Hongze Cheng 已提交
1023 1024
    }
  }
C
Cary Xu 已提交
1025
  return false;
H
Hongze Cheng 已提交
1026 1027
}

H
more  
Hongze Cheng 已提交
1028 1029
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
H
Hongze Cheng 已提交
1030 1031
}

H
more  
Hongze Cheng 已提交
1032
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
H
Hongze Cheng 已提交
1033

C
Cary Xu 已提交
1034
int32_t tTagToValArray(const STag *pTag, SArray **ppArray) {
H
Hongze Cheng 已提交
1035
  int32_t  code = 0;
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
  uint8_t *p = NULL;
  STagVal  tv = {0};
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
  int16_t  offset = 0;

  if (isLarge) {
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
  } else {
    p = (uint8_t *)&pTag->idx[pTag->nTag];
  }
H
Hongze Cheng 已提交
1046

H
more  
Hongze Cheng 已提交
1047
  (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
H
Hongze Cheng 已提交
1048
  if (*ppArray == NULL) {
H
Hongze Cheng 已提交
1049 1050 1051 1052 1053
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

  for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
1054 1055 1056 1057 1058 1059
    if (isLarge) {
      offset = ((int16_t *)pTag->idx)[iTag];
    } else {
      offset = pTag->idx[iTag];
    }
    tGetTagVal(p + offset, &tv, pTag->flags & TD_TAG_JSON);
H
Hongze Cheng 已提交
1060
    taosArrayPush(*ppArray, &tv);
H
Hongze Cheng 已提交
1061 1062 1063 1064 1065 1066 1067 1068
  }

  return code;

_err:
  return code;
}

wmmhello's avatar
wmmhello 已提交
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
void tTagSetCid(const STag *pTag, int16_t iTag, int16_t cid) {
  uint8_t *p = NULL;
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
  int16_t  offset = 0;

  if (isLarge) {
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
  } else {
    p = (uint8_t *)&pTag->idx[pTag->nTag];
  }

  if (isLarge) {
    offset = ((int16_t *)pTag->idx)[iTag];
  } else {
    offset = pTag->idx[iTag];
  }

  tPutI16v(p + offset, cid);
}

H
Hongze Cheng 已提交
1089
#if 1  // ===================================================================================================================
C
Cary Xu 已提交
1090
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
1091 1092 1093
  if (pBuilder == NULL) return -1;

  pBuilder->tCols = 256;
wafwerar's avatar
wafwerar 已提交
1094
  pBuilder->columns = (STColumn *)taosMemoryMalloc(sizeof(STColumn) * pBuilder->tCols);
H
Hongze Cheng 已提交
1095 1096 1097 1098 1099 1100 1101 1102
  if (pBuilder->columns == NULL) return -1;

  tdResetTSchemaBuilder(pBuilder, version);
  return 0;
}

void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder) {
wafwerar's avatar
wafwerar 已提交
1103
    taosMemoryFreeClear(pBuilder->columns);
H
Hongze Cheng 已提交
1104 1105 1106
  }
}

C
Cary Xu 已提交
1107
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
1108 1109 1110
  pBuilder->nCols = 0;
  pBuilder->tlen = 0;
  pBuilder->flen = 0;
T
Tao Liu 已提交
1111
  pBuilder->vlen = 0;
H
Hongze Cheng 已提交
1112 1113 1114
  pBuilder->version = version;
}

C
Cary Xu 已提交
1115
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes) {
1116
  if (!isValidDataType(type)) return -1;
H
Hongze Cheng 已提交
1117 1118 1119

  if (pBuilder->nCols >= pBuilder->tCols) {
    pBuilder->tCols *= 2;
wafwerar's avatar
wafwerar 已提交
1120
    STColumn *columns = (STColumn *)taosMemoryRealloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
T
tickduan 已提交
1121 1122
    if (columns == NULL) return -1;
    pBuilder->columns = columns;
H
Hongze Cheng 已提交
1123 1124 1125
  }

  STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
H
Hongze Cheng 已提交
1126 1127 1128
  pCol->type = type;
  pCol->colId = colId;
  pCol->flags = flags;
H
Hongze Cheng 已提交
1129
  if (pBuilder->nCols == 0) {
H
Hongze Cheng 已提交
1130
    pCol->offset = 0;
H
Hongze Cheng 已提交
1131
  } else {
S
Shengliang Guan 已提交
1132
    STColumn *pTCol = &(pBuilder->columns[pBuilder->nCols - 1]);
H
Hongze Cheng 已提交
1133
    pCol->offset = pTCol->offset + TYPE_BYTES[pTCol->type];
H
Hongze Cheng 已提交
1134 1135 1136
  }

  if (IS_VAR_DATA_TYPE(type)) {
H
Hongze Cheng 已提交
1137
    pCol->bytes = bytes;
T
Tao Liu 已提交
1138 1139
    pBuilder->tlen += (TYPE_BYTES[type] + bytes);
    pBuilder->vlen += bytes - sizeof(VarDataLenT);
H
Hongze Cheng 已提交
1140
  } else {
H
Hongze Cheng 已提交
1141
    pCol->bytes = TYPE_BYTES[type];
H
Hongze Cheng 已提交
1142
    pBuilder->tlen += TYPE_BYTES[type];
T
Tao Liu 已提交
1143
    pBuilder->vlen += TYPE_BYTES[type];
H
Hongze Cheng 已提交
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
  }

  pBuilder->nCols++;
  pBuilder->flen += TYPE_BYTES[type];

  ASSERT(pCol->offset < pBuilder->flen);

  return 0;
}

STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder->nCols <= 0) return NULL;

  int tlen = sizeof(STSchema) + sizeof(STColumn) * pBuilder->nCols;

wafwerar's avatar
wafwerar 已提交
1159
  STSchema *pSchema = (STSchema *)taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
1160 1161
  if (pSchema == NULL) return NULL;

H
Hongze Cheng 已提交
1162 1163 1164 1165 1166
  pSchema->version = pBuilder->version;
  pSchema->numOfCols = pBuilder->nCols;
  pSchema->tlen = pBuilder->tlen;
  pSchema->flen = pBuilder->flen;
  pSchema->vlen = pBuilder->vlen;
H
Hongze Cheng 已提交
1167

C
Cary Xu 已提交
1168
#ifdef TD_SUPPORT_BITMAP
H
Hongze Cheng 已提交
1169
  pSchema->tlen += (int)TD_BITMAP_BYTES(pSchema->numOfCols);
C
Cary Xu 已提交
1170 1171
#endif

H
Hongze Cheng 已提交
1172
  memcpy(&pSchema->columns[0], pBuilder->columns, sizeof(STColumn) * pBuilder->nCols);
H
Hongze Cheng 已提交
1173

H
TD-27  
hzcheng 已提交
1174 1175 1176
  return pSchema;
}

H
Hongze Cheng 已提交
1177
#endif