• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3549

06 Dec 2024 09:44AM UTC coverage: 59.948% (+0.1%) from 59.846%
#3549

push

travis-ci

web-flow
Merge pull request #29057 from taosdata/docs/TD-33031-3.0

docs: description of user privileges

118833 of 254191 branches covered (46.75%)

Branch coverage included in aggregate %.

199893 of 277480 relevant lines covered (72.04%)

19006119.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

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

16
#define _DEFAULT_SOURCE
17
#include "tdataformat.h"
18
#include "tRealloc.h"
19
#include "tdatablock.h"
20
#include "tlog.h"
21

22
static int32_t (*tColDataAppendValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData);
23
static int32_t (*tColDataUpdateValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward);
24

25
// ================================
26
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson);
27

28
// SRow ========================================================================
29
#define KV_FLG_LIT ((uint8_t)0x10)
30
#define KV_FLG_MID ((uint8_t)0x20)
31
#define KV_FLG_BIG ((uint8_t)0x40)
32

33
#define BIT_FLG_NONE  ((uint8_t)0x0)
34
#define BIT_FLG_NULL  ((uint8_t)0x1)
35
#define BIT_FLG_VALUE ((uint8_t)0x2)
36

37
#pragma pack(push, 1)
38
typedef struct {
39
  int16_t nCol;
40
  uint8_t idx[];  // uint8_t * | uint16_t * | uint32_t *
41
} SKVIdx;
42
#pragma pack(pop)
43

44
#define ROW_SET_BITMAP(PB, FLAG, IDX, VAL)      \
45
  do {                                          \
46
    switch (FLAG) {                             \
47
      case (HAS_NULL | HAS_NONE):               \
48
        SET_BIT1(PB, IDX, VAL);                 \
49
        break;                                  \
50
      case (HAS_VALUE | HAS_NONE):              \
51
        SET_BIT1(PB, IDX, (VAL) ? (VAL)-1 : 0); \
52
        break;                                  \
53
      case (HAS_VALUE | HAS_NULL):              \
54
        SET_BIT1(PB, IDX, (VAL)-1);             \
55
        break;                                  \
56
      case (HAS_VALUE | HAS_NULL | HAS_NONE):   \
57
        SET_BIT2(PB, IDX, VAL);                 \
58
        break;                                  \
59
      default:                                  \
60
        break;                                  \
61
    }                                           \
62
  } while (0)
63

64
static int32_t tPutPrimaryKeyIndex(uint8_t *p, const SPrimaryKeyIndex *index) {
603,402,224✔
65
  int32_t n = 0;
603,402,224✔
66
  n += tPutI8(p ? p + n : p, index->type);
603,402,224✔
67
  n += tPutU32v(p ? p + n : p, index->offset);
603,402,224✔
68
  return n;
603,402,224✔
69
}
70

71
static int32_t tGetPrimaryKeyIndex(uint8_t *p, SPrimaryKeyIndex *index) {
2,147,483,647✔
72
  int32_t n = 0;
2,147,483,647✔
73
  n += tGetI8(p + n, &index->type);
2,147,483,647!
74
  n += tGetU32v(p + n, &index->offset);
2,147,483,647!
75
  return n;
2,147,483,647✔
76
}
77

78
typedef struct {
79
  int32_t numOfNone;
80
  int32_t numOfNull;
81
  int32_t numOfValue;
82
  int32_t numOfPKs;
83
  int8_t  flag;
84

85
  // tuple
86
  int8_t           tupleFlag;
87
  SPrimaryKeyIndex tupleIndices[TD_MAX_PK_COLS];
88
  int32_t          tuplePKSize;      // primary key size
89
  int32_t          tupleBitmapSize;  // bitmap size
90
  int32_t          tupleFixedSize;   // fixed part size
91
  int32_t          tupleVarSize;     // var part size
92
  int32_t          tupleRowSize;
93

94
  // key-value
95
  int8_t           kvFlag;
96
  SPrimaryKeyIndex kvIndices[TD_MAX_PK_COLS];
97
  int32_t          kvMaxOffset;
98
  int32_t          kvPKSize;       // primary key size
99
  int32_t          kvIndexSize;    // offset array size
100
  int32_t          kvPayloadSize;  // payload size
101
  int32_t          kvRowSize;
102
} SRowBuildScanInfo;
103

104
static FORCE_INLINE int32_t tRowBuildScanAddNone(SRowBuildScanInfo *sinfo, const STColumn *pTColumn) {
105
  if ((pTColumn->flags & COL_IS_KEY)) return TSDB_CODE_PAR_PRIMARY_KEY_IS_NONE;
×
106
  sinfo->numOfNone++;
2,147,483,647✔
107
  return 0;
2,147,483,647✔
108
}
109

110
static FORCE_INLINE int32_t tRowBuildScanAddNull(SRowBuildScanInfo *sinfo, const STColumn *pTColumn) {
111
  if ((pTColumn->flags & COL_IS_KEY)) return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
112
  sinfo->numOfNull++;
29,034,923✔
113
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
29,034,923✔
114
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
29,034,923✔
115
  return 0;
29,034,923✔
116
}
117

118
static FORCE_INLINE void tRowBuildScanAddValue(SRowBuildScanInfo *sinfo, SColVal *colVal, const STColumn *pTColumn) {
119
  bool isPK = ((pTColumn->flags & COL_IS_KEY) != 0);
2,147,483,647✔
120

121
  if (isPK) {
2,147,483,647✔
122
    sinfo->tupleIndices[sinfo->numOfPKs].type = colVal->value.type;
204,629,545✔
123
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
204,629,545✔
124
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
204,629,545!
125
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
204,629,545✔
126
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
204,629,545✔
127
    sinfo->numOfPKs++;
204,629,545✔
128
  }
129

130
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
2,147,483,647✔
131
  if (IS_VAR_DATA_TYPE(colVal->value.type)) {
2,147,483,647!
132
    sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)  // size
545,993,761✔
133
                           + colVal->value.nData;               // value
545,993,761✔
134

135
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
545,993,761✔
136
                            + tPutU32v(NULL, colVal->value.nData)  // size
545,993,761✔
137
                            + colVal->value.nData;                 // value
545,993,761✔
138
  } else {
139
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)              // colId
2,147,483,647✔
140
                            + tDataTypes[colVal->value.type].bytes;  // value
2,147,483,647✔
141
  }
142
  sinfo->numOfValue++;
2,147,483,647✔
143
}
2,147,483,647✔
144

145
static int32_t tRowBuildScan(SArray *colVals, const STSchema *schema, SRowBuildScanInfo *sinfo) {
1,069,072,206✔
146
  int32_t  code = 0;
1,069,072,206✔
147
  int32_t  colValIndex = 1;
1,069,072,206✔
148
  int32_t  numOfColVals = TARRAY_SIZE(colVals);
1,069,072,206✔
149
  SColVal *colValArray = (SColVal *)TARRAY_DATA(colVals);
1,069,072,206✔
150

151
  if (!(numOfColVals > 0)) {
1,069,072,206!
152
    return TSDB_CODE_INVALID_PARA;
×
153
  }
154
  if (!(colValArray[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
1,069,072,206!
155
    return TSDB_CODE_INVALID_PARA;
×
156
  }
157
  if (!(colValArray[0].value.type == TSDB_DATA_TYPE_TIMESTAMP)) {
1,069,072,206!
158
    return TSDB_CODE_INVALID_PARA;
×
159
  }
160

161
  *sinfo = (SRowBuildScanInfo){
1,069,072,206✔
162
      .tupleFixedSize = schema->flen,
1,069,072,206✔
163
  };
164

165
  // loop scan
166
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
167
    for (;;) {
168
      if (colValIndex >= numOfColVals) {
2,147,483,647✔
169
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
64!
170
        break;
32✔
171
      }
172

173
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
174
        if (!(colValArray[colValIndex].value.type == schema->columns[i].type)) {
2,147,483,647!
175
          code = TSDB_CODE_INVALID_PARA;
×
176
          goto _exit;
×
177
        }
178

179
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {
2,147,483,647✔
180
          tRowBuildScanAddValue(sinfo, &colValArray[colValIndex], schema->columns + i);
2,147,483,647✔
181
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {
2,147,483,647✔
182
          if ((code = tRowBuildScanAddNull(sinfo, schema->columns + i))) goto _exit;
58,069,846!
183
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {
2,147,483,647!
184
          if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
2,147,483,647!
185
        }
186

187
        colValIndex++;
2,147,483,647✔
188
        break;
2,147,483,647✔
189
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {
×
190
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
54!
191
        break;
27✔
192
      } else {  // skip useless value
193
        colValIndex++;
×
194
      }
195
    }
196
  }
197

198
  if (sinfo->numOfNone) {
1,069,072,206✔
199
    sinfo->flag |= HAS_NONE;
373,654,211✔
200
  }
201
  if (sinfo->numOfNull) {
1,069,072,206✔
202
    sinfo->flag |= HAS_NULL;
20,217,939✔
203
  }
204
  if (sinfo->numOfValue) {
1,069,072,206✔
205
    sinfo->flag |= HAS_VALUE;
1,012,347,159✔
206
  }
207

208
  // Tuple
209
  sinfo->tupleFlag = sinfo->flag;
1,069,072,206✔
210
  switch (sinfo->flag) {
1,069,072,206!
211
    case HAS_NONE:
64,190,929✔
212
    case HAS_NULL:
213
      sinfo->tupleBitmapSize = 0;
64,190,929✔
214
      sinfo->tupleFixedSize = 0;
64,190,929✔
215
      break;
64,190,929✔
216
    case HAS_VALUE:
684,873,826✔
217
      sinfo->tupleBitmapSize = 0;
684,873,826✔
218
      sinfo->tupleFixedSize = schema->flen;
684,873,826✔
219
      break;
684,873,826✔
220
    case (HAS_NONE | HAS_NULL):
24,674✔
221
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,674✔
222
      sinfo->tupleFixedSize = 0;
24,674✔
223
      break;
24,674✔
224
    case (HAS_NONE | HAS_VALUE):
328,775,799✔
225
    case (HAS_NULL | HAS_VALUE):
226
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
328,775,799✔
227
      sinfo->tupleFixedSize = schema->flen;
328,775,799✔
228
      break;
328,775,799✔
229
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
453,459✔
230
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
453,459✔
231
      sinfo->tupleFixedSize = schema->flen;
453,459✔
232
      break;
453,459✔
233
  }
234
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,272,725,587✔
235
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
204,575,422✔
236
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
204,575,422✔
237
  }
238
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,068,150,165✔
239
                        + sinfo->tuplePKSize      // primary keys
1,068,150,165✔
240
                        + sinfo->tupleBitmapSize  // bitmap
1,068,150,165✔
241
                        + sinfo->tupleFixedSize   // fixed part
1,068,150,165✔
242
                        + sinfo->tupleVarSize;    // var part
1,068,150,165✔
243

244
  // Key-Value
245
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,068,150,165!
246
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,072,613,933✔
247
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,072,613,933✔
248
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
249
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
4,305,360✔
250
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
4,305,360✔
251
  } else {
252
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
253
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
254
  }
255
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,271,751,624✔
256
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
204,273,244✔
257
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
204,273,244✔
258
  }
259
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,067,478,380✔
260
                     + sinfo->kvPKSize        // primary keys
1,067,478,380✔
261
                     + sinfo->kvIndexSize     // index array
1,067,478,380✔
262
                     + sinfo->kvPayloadSize;  // payload
1,067,478,380✔
263

264
_exit:
1,067,478,380✔
265
  return code;
1,067,478,380✔
266
}
267

268
static int32_t tRowBuildTupleRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
759,597,179✔
269
                                 SRow **ppRow) {
270
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
759,597,179✔
271

272
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
759,597,179✔
273
  if (*ppRow == NULL) {
767,807,976!
274
    return terrno;
×
275
  }
276
  (*ppRow)->flag = sinfo->tupleFlag;
768,650,926✔
277
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
768,650,926✔
278
  (*ppRow)->sver = schema->version;
768,650,926✔
279
  (*ppRow)->len = sinfo->tupleRowSize;
768,650,926✔
280
  (*ppRow)->ts = colValArray[0].value.val;
768,650,926✔
281

282
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
768,650,926!
283
    return 0;
66,005,491✔
284
  }
285

286
  uint8_t *primaryKeys = (*ppRow)->data;
702,645,435✔
287
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
702,645,435✔
288
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
702,645,435✔
289
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
702,645,435✔
290

291
  // primary keys
292
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
907,827,207✔
293
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
207,382,655✔
294
  }
295

296
  // bitmap + fixed + varlen
297
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
700,444,552✔
298
  int32_t colValIndex = 1;
700,444,552✔
299
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
300
    for (;;) {
301
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647!
302
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
303
        break;
×
304
      }
305

306
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
307
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
2,147,483,647✔
308
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_VALUE);
2,147,483,647!
309

310
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
311
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
136,486,172✔
312
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
136,486,172✔
313
            if (colValArray[colValIndex].value.nData) {
136,486,172✔
314
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
135,858,961✔
315
              varlen += colValArray[colValIndex].value.nData;
135,858,961✔
316
            }
317
          } else {
318
            (void)memcpy(fixed + schema->columns[i].offset, &colValArray[colValIndex].value.val,
2,147,483,647✔
319
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
320
          }
321
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
15,431,621!
322
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
15,564,550!
323
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
477,164!
325
        }
326

327
        colValIndex++;
2,147,483,647✔
328
        break;
2,147,483,647✔
329
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
330
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
5!
331
        break;
5✔
332
      } else {
333
        colValIndex++;
×
334
      }
335
    }
336
  }
337

338
  return 0;
700,444,552✔
339
}
340

341
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
342
  if (flag & KV_FLG_LIT) {
2,147,483,647✔
343
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
2,147,483,647✔
344
  } else if (flag & KV_FLG_MID) {
7,239,507!
345
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,738,133✔
346
  } else {
347
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
×
348
  }
349
  indices->nCol++;
2,147,483,647✔
350
}
2,147,483,647✔
351

352
static int32_t tRowBuildKVRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema, SRow **ppRow) {
316,031,245✔
353
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
316,031,245✔
354

355
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
316,031,245✔
356
  if (*ppRow == NULL) {
316,361,386!
357
    return terrno;
×
358
  }
359
  (*ppRow)->flag = sinfo->kvFlag;
316,452,236✔
360
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
316,452,236✔
361
  (*ppRow)->sver = schema->version;
316,452,236✔
362
  (*ppRow)->len = sinfo->kvRowSize;
316,452,236✔
363
  (*ppRow)->ts = colValArray[0].value.val;
316,452,236✔
364

365
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
316,452,236!
366
    return TSDB_CODE_INVALID_PARA;
×
367
  }
368

369
  uint8_t *primaryKeys = (*ppRow)->data;
316,452,236✔
370
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
316,452,236✔
371
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
316,452,236✔
372
  uint32_t payloadSize = 0;
316,452,236✔
373

374
  // primary keys
375
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
317,804,813✔
376
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
1,352,576✔
377
  }
378

379
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
316,452,237✔
380
  int32_t colValIndex = 1;
316,452,237✔
381
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
382
    for (;;) {
383
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647✔
384
        break;
32✔
385
      }
386

387
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
388
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
2,147,483,647✔
389
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
2,147,483,647✔
390
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
391
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
413,131,580✔
392
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
413,131,580✔
393
            if (colValArray[colValIndex].value.nData > 0) {
413,131,580!
394
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
421,990,141✔
395
                           colValArray[colValIndex].value.nData);
421,990,141✔
396
            }
397
            payloadSize += colValArray[colValIndex].value.nData;
413,131,580✔
398
          } else {
399
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
2,147,483,647✔
400
            (void)memcpy(payload + payloadSize, &colValArray[colValIndex].value.val,
2,147,483,647✔
401
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
402
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
2,147,483,647✔
403
          }
404
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
2,147,483,647✔
405
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
13,199,852✔
406
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
26,399,704✔
407
        }
408

409
        colValIndex++;
2,147,483,647✔
410
        break;
2,147,483,647✔
411
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
412
        break;
22✔
413
      } else {
414
        colValIndex++;
×
415
      }
416
    }
417
  }
418

419
  return 0;
316,452,237✔
420
}
421

422
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
1,068,665,633✔
423
  int32_t           code;
424
  SRowBuildScanInfo sinfo;
425

426
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,068,665,633✔
427
  if (code) return code;
1,075,993,946!
428

429
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,075,993,946✔
430
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
760,351,932✔
431
  } else {
432
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
315,642,014✔
433
  }
434
  return code;
1,076,730,286✔
435
}
436

437
static int32_t tBindInfoCompare(const void *p1, const void *p2, const void *param) {
×
438
  if (((SBindInfo *)p1)->columnId < ((SBindInfo *)p2)->columnId) {
×
439
    return -1;
×
440
  } else if (((SBindInfo *)p1)->columnId > ((SBindInfo *)p2)->columnId) {
×
441
    return 1;
×
442
  }
443
  return 0;
×
444
}
445

446
/* build rows to `rowArray` from bind
447
 * `infos` is the bind information array
448
 * `numOfInfos` is the number of bind information
449
 * `infoSorted` is whether the bind information is sorted by column id
450
 * `pTSchema` is the schema of the table
451
 * `rowArray` is the array to store the rows
452
 */
453
int32_t tRowBuildFromBind(SBindInfo *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
16✔
454
                          SArray *rowArray) {
455
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
16!
456
    return TSDB_CODE_INVALID_PARA;
×
457
  }
458

459
  if (!infoSorted) {
16!
460
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
461
  }
462

463
  int32_t code = 0;
16✔
464
  int32_t numOfRows = infos[0].bind->num;
16✔
465
  SArray *colValArray;
466
  SColVal colVal;
467

468
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
16!
469
    return terrno;
×
470
  }
471

472
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
168✔
473
    taosArrayClear(colValArray);
154✔
474

475
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
2,368✔
476
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
2,218!
477
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
478
      } else {
479
        SValue value = {
2,218✔
480
            .type = infos[iInfo].type,
2,218✔
481
        };
482
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
2,218!
483
          value.nData = infos[iInfo].bind->length[iRow];
314✔
484
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
314!
485
            code = TSDB_CODE_INVALID_PARA;
×
486
            goto _exit;
×
487
          }
488
          value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
314✔
489
        } else {
490
          (void)memcpy(&value.val, (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
1,904✔
491
                       infos[iInfo].bind->buffer_length);
1,904✔
492
        }
493
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
2,218✔
494
      }
495
      if (taosArrayPush(colValArray, &colVal) == NULL) {
2,215!
496
        code = terrno;
×
497
        goto _exit;
×
498
      }
499
    }
500

501
    SRow *row;
502
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
150!
503
      goto _exit;
×
504
    }
505

506
    if ((taosArrayPush(rowArray, &row)) == NULL) {
152!
507
      code = terrno;
×
508
      goto _exit;
×
509
    }
510
  }
511

512
_exit:
14✔
513
  taosArrayDestroy(colValArray);
14✔
514
  return code;
15✔
515
}
516

517
int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
2,147,483,647✔
518
  if (!(iCol < pTSchema->numOfCols)) return TSDB_CODE_INVALID_PARA;
2,147,483,647!
519
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
2,147,483,647!
520

521
  STColumn *pTColumn = pTSchema->columns + iCol;
2,147,483,647✔
522

523
  if (iCol == 0) {
2,147,483,647✔
524
    pColVal->cid = pTColumn->colId;
61,053,427✔
525
    pColVal->value.type = pTColumn->type;
61,053,427✔
526
    pColVal->flag = CV_FLAG_VALUE;
61,053,427✔
527
    (void)memcpy(&pColVal->value.val, &pRow->ts, sizeof(TSKEY));
61,053,427✔
528
    return 0;
61,053,427✔
529
  }
530

531
  if (pRow->flag == HAS_NONE) {
2,147,483,647✔
532
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1,638,650✔
533
    return 0;
1,638,650✔
534
  }
535

536
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
537
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
915,598✔
538
    return 0;
915,598✔
539
  }
540

541
  SPrimaryKeyIndex index;
542
  uint8_t         *data = pRow->data;
2,147,483,647✔
543
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
2,147,483,647✔
544
    data += tGetPrimaryKeyIndex(data, &index);
84,349,896✔
545
  }
546

547
  if (pRow->flag >> 4) {  // KV Row
2,147,483,647✔
548
    SKVIdx  *pIdx = (SKVIdx *)data;
2,147,483,647✔
549
    uint8_t *pv = NULL;
2,147,483,647✔
550

551
    if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
552
      pv = pIdx->idx + pIdx->nCol;
2,147,483,647✔
553
    } else if (pRow->flag & KV_FLG_MID) {
73,058,565!
554
      pv = pIdx->idx + (pIdx->nCol << 1);
103,344,517✔
555
    } else {
556
      pv = pIdx->idx + (pIdx->nCol << 2);
×
557
    }
558

559
    int16_t lidx = 0;
2,147,483,647✔
560
    int16_t ridx = pIdx->nCol - 1;
2,147,483,647✔
561
    while (lidx <= ridx) {
2,147,483,647✔
562
      int16_t  mid = (lidx + ridx) >> 1;
2,147,483,647✔
563
      uint8_t *pData = NULL;
2,147,483,647✔
564
      if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
565
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
2,147,483,647✔
566
      } else if (pRow->flag & KV_FLG_MID) {
436,009,459!
567
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
436,245,913✔
568
      } else {
569
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
570
      }
571

572
      int16_t cid;
573
      pData += tGetI16v(pData, &cid);
2,147,483,647✔
574

575
      if (TABS(cid) == pTColumn->colId) {
2,147,483,647✔
576
        if (cid < 0) {
2,147,483,647✔
577
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
86,920,857✔
578
        } else {
579
          pColVal->cid = pTColumn->colId;
2,147,483,647✔
580
          pColVal->value.type = pTColumn->type;
2,147,483,647✔
581
          pColVal->flag = CV_FLAG_VALUE;
2,147,483,647✔
582

583
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
2,147,483,647!
584
            pData += tGetU32v(pData, &pColVal->value.nData);
721,815,403!
585
            if (pColVal->value.nData > 0) {
721,815,403!
586
              pColVal->value.pData = pData;
826,871,223✔
587
            } else {
588
              pColVal->value.pData = NULL;
×
589
            }
590
          } else {
591
            (void)memcpy(&pColVal->value.val, pData, pTColumn->bytes);
2,147,483,647✔
592
          }
593
        }
594
        return 0;
2,147,483,647✔
595
      } else if (TABS(cid) < pTColumn->colId) {
2,147,483,647✔
596
        lidx = mid + 1;
2,147,483,647✔
597
      } else {
598
        ridx = mid - 1;
2,147,483,647✔
599
      }
600
    }
601

602
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1,974,097,844✔
603
  } else {  // Tuple Row
604
    uint8_t *bitmap = data;
827,073,510✔
605
    uint8_t *fixed;
606
    uint8_t *varlen;
607
    uint8_t  bit;
608

609
    if (pRow->flag == HAS_VALUE) {
827,073,510✔
610
      fixed = bitmap;
717,995,111✔
611
      bit = BIT_FLG_VALUE;
717,995,111✔
612
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
109,078,399!
613
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
614
      bit = GET_BIT2(bitmap, iCol - 1);
×
615
    } else {
616
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
109,078,399✔
617
      bit = GET_BIT1(bitmap, iCol - 1);
109,078,399✔
618

619
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
109,078,399✔
620
        if (bit) bit++;
20,363✔
621
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
109,058,036✔
622
        bit++;
94,346,244✔
623
      }
624
    }
625
    varlen = fixed + pTSchema->flen;
827,073,510✔
626

627
    if (bit == BIT_FLG_NONE) {
827,073,510✔
628
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,229✔
629
      return 0;
7,229✔
630
    } else if (bit == BIT_FLG_NULL) {
827,066,281✔
631
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
9,997,269✔
632
      return 0;
9,997,269✔
633
    }
634

635
    pColVal->cid = pTColumn->colId;
817,069,012✔
636
    pColVal->value.type = pTColumn->type;
817,069,012✔
637
    pColVal->flag = CV_FLAG_VALUE;
817,069,012✔
638
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
817,069,012!
639
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
77,393,719✔
640
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
154,787,438✔
641
    } else {
642
      (void)memcpy(&pColVal->value.val, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
739,675,293✔
643
    }
644
  }
645

646
  return 0;
2,147,483,647✔
647
}
648

649
void tRowDestroy(SRow *pRow) {
699,620,985✔
650
  if (pRow) taosMemoryFree(pRow);
699,620,985!
651
}
699,485,102✔
652

653
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
261,153,384✔
654
  SRowKey key1, key2;
655
  tRowGetKey(*(SRow **)p1, &key1);
261,153,384✔
656
  tRowGetKey(*(SRow **)p2, &key2);
252,741,756✔
657
  return tRowKeyCompare(&key1, &key2);
262,245,683✔
658
}
659
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
1,010✔
660
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
241✔
661
  int32_t code = 0;
241✔
662

663
  int32_t    nRow = iEnd - iStart;
241✔
664
  SRowIter **aIter = NULL;
241✔
665
  SArray    *aColVal = NULL;
241✔
666
  SRow      *pRow = NULL;
241✔
667

668
  aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
241✔
669
  if (aIter == NULL) {
241!
670
    code = terrno;
×
671
    goto _exit;
×
672
  }
673

674
  for (int32_t i = 0; i < nRow; i++) {
1,251✔
675
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
1,010✔
676

677
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
1,010✔
678
    if (code) goto _exit;
1,010!
679
  }
680

681
  // merge
682
  aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
241✔
683
  if (aColVal == NULL) {
241!
684
    code = terrno;
×
685
    goto _exit;
×
686
  }
687

688
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
917✔
689
    SColVal *pColVal = NULL;
676✔
690
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
808✔
691
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
769✔
692
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
856✔
693
        pColValT = tRowIterNext(aIter[iRow]);
87✔
694
      }
695

696
      // todo: take strategy according to the flag
697
      if (COL_VAL_IS_VALUE(pColValT)) {
769✔
698
        pColVal = pColValT;
637✔
699
        break;
637✔
700
      } else if (COL_VAL_IS_NULL(pColValT)) {
132!
701
        if (pColVal == NULL) {
×
702
          pColVal = pColValT;
×
703
        }
704
      }
705
    }
706

707
    if (pColVal) {
676✔
708
      if (taosArrayPush(aColVal, pColVal) == NULL) {
637!
709
        code = terrno;
×
710
        goto _exit;
×
711
      }
712
    }
713
  }
714

715
  // build
716
  code = tRowBuild(aColVal, pTSchema, &pRow);
241✔
717
  if (code) goto _exit;
241!
718

719
  taosArrayRemoveBatch(aRowP, iStart, nRow, (FDelete)tRowPDestroy);
241✔
720
  if (taosArrayInsert(aRowP, iStart, &pRow) == NULL) {
241!
721
    code = terrno;
×
722
    goto _exit;
×
723
  }
724

725
_exit:
241✔
726
  if (aIter) {
241!
727
    for (int32_t i = 0; i < nRow; i++) {
1,251✔
728
      tRowIterClose(&aIter[i]);
1,010✔
729
    }
730
    taosMemoryFree(aIter);
241✔
731
  }
732
  if (aColVal) taosArrayDestroy(aColVal);
241!
733
  if (code) tRowDestroy(pRow);
241!
734
  return code;
241✔
735
}
736

737
int32_t tRowSort(SArray *aRowP) {
49,509✔
738
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
49,509✔
739
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
49,506✔
740
  if (code != TSDB_CODE_SUCCESS) {
49,505!
741
    uError("taosArrayMSort failed caused by %d", code);
×
742
  }
743
  return code;
49,505✔
744
}
745

746
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, int8_t flag) {
49,558✔
747
  int32_t code = 0;
49,558✔
748

749
  int32_t iStart = 0;
49,558✔
750
  while (iStart < aRowP->size) {
37,514,174✔
751
    SRowKey key1;
752
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
37,492,446✔
753

754
    tRowGetKey(row1, &key1);
37,746,138✔
755

756
    int32_t iEnd = iStart + 1;
37,456,378✔
757
    while (iEnd < aRowP->size) {
37,437,874✔
758
      SRowKey key2;
759
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
37,382,125✔
760
      tRowGetKey(row2, &key2);
37,619,752✔
761

762
      if (tRowKeyCompare(&key1, &key2) != 0) break;
37,390,363!
763

764
      iEnd++;
×
765
    }
766

767
    if (iEnd - iStart > 1) {
37,464,616✔
768
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
241✔
769
      if (code) return code;
241!
770
    }
771

772
    // the array is also changing, so the iStart just ++ instead of iEnd
773
    iStart++;
37,464,616✔
774
  }
775

776
  return code;
21,728✔
777
}
778

779
// SRowIter ========================================
780
struct SRowIter {
781
  SRow     *pRow;
782
  STSchema *pTSchema;
783

784
  int32_t iTColumn;
785
  union {
786
    struct {  // kv
787
      int32_t iCol;
788
      SKVIdx *pIdx;
789
    };
790
    struct {  // tuple
791
      uint8_t *pb;
792
      uint8_t *pf;
793
    };
794
  };
795
  uint8_t *pv;
796
  SColVal  cv;
797
};
798

799
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) {
248,400✔
800
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
248,400!
801

802
  int32_t code = 0;
248,400✔
803

804
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
248,400✔
805
  if (pIter == NULL) {
248,409✔
806
    code = terrno;
2✔
807
    goto _exit;
×
808
  }
809

810
  pIter->pRow = pRow;
248,407✔
811
  pIter->pTSchema = pTSchema;
248,407✔
812
  pIter->iTColumn = 0;
248,407✔
813

814
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
248,407✔
815

816
  uint8_t         *data = pRow->data;
248,252✔
817
  SPrimaryKeyIndex index;
818
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
248,257✔
819
    data += tGetPrimaryKeyIndex(data, &index);
5✔
820
  }
821

822
  if (pRow->flag >> 4) {
248,252✔
823
    pIter->iCol = 0;
227,691✔
824
    pIter->pIdx = (SKVIdx *)data;
227,691✔
825
    if (pRow->flag & KV_FLG_LIT) {
227,691!
826
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
227,694✔
827
    } else if (pRow->flag & KV_FLG_MID) {
×
828
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1);  // * sizeof(uint16_t)
×
829
    } else {
830
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2);  // * sizeof(uint32_t)
×
831
    }
832
  } else {
833
    switch (pRow->flag) {
20,561!
834
      case (HAS_NULL | HAS_NONE):
1✔
835
        pIter->pb = data;
1✔
836
        break;
1✔
837
      case HAS_VALUE:
20,475✔
838
        pIter->pf = data;
20,475✔
839
        pIter->pv = pIter->pf + pTSchema->flen;
20,475✔
840
        break;
20,475✔
841
      case (HAS_VALUE | HAS_NONE):
86✔
842
      case (HAS_VALUE | HAS_NULL):
843
        pIter->pb = data;
86✔
844
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
86✔
845
        pIter->pv = pIter->pf + pTSchema->flen;
86✔
846
        break;
86✔
847
      case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
848
        pIter->pb = data;
×
849
        pIter->pf = data + BIT2_SIZE(pTSchema->numOfCols - 1);
×
850
        pIter->pv = pIter->pf + pTSchema->flen;
×
851
        break;
×
852
      default:
×
853
        break;
×
854
    }
855
  }
856

857
_exit:
248,407✔
858
  if (code) {
248,407!
859
    *ppIter = NULL;
×
860
  } else {
861
    *ppIter = pIter;
248,407✔
862
  }
863
  return code;
248,407✔
864
}
865

866
void tRowIterClose(SRowIter **ppIter) {
248,408✔
867
  SRowIter *pIter = *ppIter;
248,408✔
868
  if (pIter) {
248,408!
869
    taosMemoryFree(pIter);
248,408✔
870
  }
871
  *ppIter = NULL;
248,408✔
872
}
248,408✔
873

874
SColVal *tRowIterNext(SRowIter *pIter) {
6,004,996✔
875
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
6,004,996✔
876
    return NULL;
247,398✔
877
  }
878

879
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
5,757,598✔
880

881
  // timestamp
882
  if (0 == pIter->iTColumn) {
5,757,598✔
883
    pIter->cv.cid = pTColumn->colId;
247,686✔
884
    pIter->cv.value.type = pTColumn->type;
247,686✔
885
    pIter->cv.flag = CV_FLAG_VALUE;
247,686✔
886
    (void)memcpy(&pIter->cv.value.val, &pIter->pRow->ts, sizeof(TSKEY));
247,686✔
887
    goto _exit;
247,686✔
888
  }
889

890
  if (pIter->pRow->flag == HAS_NONE) {
5,509,912✔
891
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
31✔
892
    goto _exit;
31✔
893
  }
894

895
  if (pIter->pRow->flag == HAS_NULL) {
5,509,881✔
896
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,396✔
897
    goto _exit;
1,396✔
898
  }
899

900
  if (pIter->pRow->flag >> 4) {  // KV
5,508,485✔
901
    if (pIter->iCol < pIter->pIdx->nCol) {
5,446,961✔
902
      uint8_t *pData;
903

904
      if (pIter->pRow->flag & KV_FLG_LIT) {
3,180,427!
905
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
3,180,452✔
906
      } else if (pIter->pRow->flag & KV_FLG_MID) {
×
907
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
×
908
      } else {
909
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
910
      }
911

912
      int16_t cid;
913
      pData += tGetI16v(pData, &cid);
3,180,427✔
914

915
      if (TABS(cid) == pTColumn->colId) {
3,180,427!
916
        if (cid < 0) {
3,180,505✔
917
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
2,255✔
918
        } else {
919
          pIter->cv.cid = pTColumn->colId;
3,178,250✔
920
          pIter->cv.value.type = pTColumn->type;
3,178,250✔
921
          pIter->cv.flag = CV_FLAG_VALUE;
3,178,250✔
922

923
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
3,178,250!
924
            pData += tGetU32v(pData, &pIter->cv.value.nData);
454,107!
925
            if (pIter->cv.value.nData > 0) {
454,107!
926
              pIter->cv.value.pData = pData;
454,238✔
927
            } else {
928
              pIter->cv.value.pData = NULL;
×
929
            }
930
          } else {
931
            (void)memcpy(&pIter->cv.value.val, pData, pTColumn->bytes);
2,724,143✔
932
          }
933
        }
934

935
        pIter->iCol++;
3,180,505✔
936
        goto _exit;
3,180,505✔
937
      } else if (TABS(cid) > pTColumn->colId) {
×
938
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
94✔
939
        goto _exit;
94✔
940
      } else {
941
        uError("unexpected column id %d, %d", cid, pTColumn->colId);
×
942
        goto _exit;
×
943
      }
944
    } else {
945
      pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2,266,534✔
946
      goto _exit;
2,266,534✔
947
    }
948
  } else {  // Tuple
949
    uint8_t bv = BIT_FLG_VALUE;
61,524✔
950
    if (pIter->pb) {
61,524✔
951
      switch (pIter->pRow->flag) {
800!
952
        case (HAS_NULL | HAS_NONE):
3✔
953
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
3✔
954
          break;
3✔
955
        case (HAS_VALUE | HAS_NONE):
37✔
956
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
37✔
957
          if (bv) bv++;
37✔
958
          break;
37✔
959
        case (HAS_VALUE | HAS_NULL):
760✔
960
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
760✔
961
          break;
760✔
962
        case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
963
          bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1);
×
964
          break;
×
965
        default:
×
966
          break;
×
967
      }
968

969
      if (bv == BIT_FLG_NONE) {
800✔
970
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
13✔
971
        goto _exit;
13✔
972
      } else if (bv == BIT_FLG_NULL) {
787✔
973
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
70✔
974
        goto _exit;
70✔
975
      }
976
    }
977

978
    pIter->cv.cid = pTColumn->colId;
61,441✔
979
    pIter->cv.value.type = pTColumn->type;
61,441✔
980
    pIter->cv.flag = CV_FLAG_VALUE;
61,441✔
981
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
68,783!
982
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
7,342✔
983
      pData += tGetU32v(pData, &pIter->cv.value.nData);
7,342!
984
      if (pIter->cv.value.nData > 0) {
7,342!
985
        pIter->cv.value.pData = pData;
7,747✔
986
      } else {
987
        pIter->cv.value.pData = NULL;
×
988
      }
989
    } else {
990
      (void)memcpy(&pIter->cv.value.val, pIter->pf + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
54,099✔
991
    }
992
    goto _exit;
61,441✔
993
  }
994

995
_exit:
5,757,770✔
996
  pIter->iTColumn++;
5,757,770✔
997
  return &pIter->cv;
5,757,770✔
998
}
999

1000
static int32_t tRowNoneUpsertColData(SColData *aColData, int32_t nColData, int32_t flag) {
9,426✔
1001
  int32_t code = 0;
9,426✔
1002

1003
  if (flag) return code;
9,426✔
1004

1005
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
90,607✔
1006
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
86,119✔
1007
    if (code) return code;
86,118!
1008
  }
1009

1010
  return code;
4,488✔
1011
}
1012
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
165,498✔
1013
  int32_t code = 0;
165,498✔
1014

1015
  int32_t   iColData = 0;
165,498✔
1016
  SColData *pColData = &aColData[iColData];
165,498✔
1017
  int32_t   iTColumn = 1;
165,498✔
1018
  STColumn *pTColumn = &pSchema->columns[iTColumn];
165,498✔
1019

1020
  while (pColData) {
601,494✔
1021
    if (pTColumn) {
436,034!
1022
      if (pTColumn->colId == pColData->cid) {  // NULL
436,034✔
1023
        if (flag == 0) {
436,028✔
1024
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
435,976✔
1025
        } else {
1026
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
52✔
1027
        }
1028
        if (code) goto _exit;
435,990!
1029

1030
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
435,990✔
1031
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
435,990✔
1032
      } else if (pTColumn->colId > pColData->cid) {  // NONE
6!
1033
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1034
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1035
      } else {
1036
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
6!
1037
      }
1038
    } else {  // NONE
1039
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1040
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1041
    }
1042
  }
1043

1044
_exit:
165,460✔
1045
  return code;
165,460✔
1046
}
1047
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
687,465,783✔
1048
                                      int32_t flag) {
1049
  int32_t code = 0;
687,465,783✔
1050

1051
  int32_t   iColData = 0;
687,465,783✔
1052
  SColData *pColData = &aColData[iColData];
687,465,783✔
1053
  int32_t   iTColumn = 1;
687,465,783✔
1054
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
687,465,783✔
1055

1056
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
687,465,783✔
1057
  SPrimaryKeyIndex index;
1058
  uint8_t         *data = pRow->data;
687,465,783✔
1059
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
911,962,448✔
1060
    data += tGetPrimaryKeyIndex(data, &index);
224,595,190✔
1061
  }
1062

1063
  switch (pRow->flag) {
687,367,258!
1064
    case HAS_VALUE:
676,856,753✔
1065
      pf = data;  // TODO: fix here
676,856,753✔
1066
      pv = pf + pTSchema->flen;
676,856,753✔
1067
      break;
676,856,753✔
1068
    case (HAS_NULL | HAS_NONE):
1,296✔
1069
      pb = data;
1,296✔
1070
      break;
1,296✔
1071
    case (HAS_VALUE | HAS_NONE):
10,682,407✔
1072
    case (HAS_VALUE | HAS_NULL):
1073
      pb = data;
10,682,407✔
1074
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
10,682,407✔
1075
      pv = pf + pTSchema->flen;
10,682,407✔
1076
      break;
10,682,407✔
1077
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1078
      pb = data;
×
1079
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1080
      pv = pf + pTSchema->flen;
×
1081
      break;
×
1082
    default:
×
1083
      return TSDB_CODE_INVALID_DATA_FMT;
×
1084
  }
1085

1086
  while (pColData) {
2,147,483,647✔
1087
    if (pTColumn) {
2,147,483,647✔
1088
      if (pTColumn->colId == pColData->cid) {
2,147,483,647!
1089
        if (!(pTColumn->type == pColData->type)) {
2,147,483,647!
1090
          return TSDB_CODE_INVALID_PARA;
×
1091
        }
1092
        if (pb) {
2,147,483,647✔
1093
          uint8_t bv;
1094
          switch (pRow->flag) {
65,508,114!
1095
            case (HAS_NULL | HAS_NONE):
25,920✔
1096
              bv = GET_BIT1(pb, iTColumn - 1);
25,920✔
1097
              break;
25,920✔
1098
            case (HAS_VALUE | HAS_NONE):
199,411✔
1099
              bv = GET_BIT1(pb, iTColumn - 1);
199,411✔
1100
              if (bv) bv++;
199,411✔
1101
              break;
199,411✔
1102
            case (HAS_VALUE | HAS_NULL):
65,282,498✔
1103
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
65,282,498✔
1104
              break;
65,282,498✔
1105
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1106
              bv = GET_BIT2(pb, iTColumn - 1);
×
1107
              break;
×
1108
            default:
285✔
1109
              return TSDB_CODE_INVALID_DATA_FMT;
285✔
1110
          }
1111

1112
          if (bv == BIT_FLG_NONE) {
65,507,829✔
1113
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,359!
1114
              goto _exit;
×
1115
            goto _continue;
43,361✔
1116
          } else if (bv == BIT_FLG_NULL) {
65,464,470✔
1117
            if (flag == 0) {
11,779,394✔
1118
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
11,607,780✔
1119
            } else {
1120
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
171,614✔
1121
            }
1122
            if (code) goto _exit;
11,779,559!
1123
            goto _continue;
11,779,559✔
1124
          }
1125
        }
1126

1127
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1128
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
51,166,973!
1129
          uint32_t nData;
1130
          pData += tGetU32v(pData, &nData);
51,166,973✔
1131
          if (flag == 0) {
51,166,973!
1132
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
54,459,418✔
1133
          } else {
1134
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1135
          }
1136
          if (code) goto _exit;
55,993,762!
1137
        } else {
1138
          if (flag == 0) {
2,147,483,647✔
1139
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,144,378,994✔
1140
                                                                          TYPE_BYTES[pColData->type]);
2,144,378,994✔
1141
          } else {
1142
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
5,064,410✔
1143
                                                                          TYPE_BYTES[pColData->type], flag > 0);
5,064,410✔
1144
          }
1145
          if (code) goto _exit;
2,147,479,909!
1146
        }
1147

1148
      _continue:
2,147,479,909✔
1149
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
2,147,483,647✔
1150
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
2,147,483,647✔
1151
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
1152
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1153
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1154
      } else {
1155
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
1156
      }
1157
    } else {
1158
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
420,081!
1159
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
420,079✔
1160
    }
1161
  }
1162

1163
_exit:
690,403,630✔
1164
  return code;
690,403,630✔
1165
}
1166
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
4,673,990✔
1167
  int32_t code = 0;
4,673,990✔
1168

1169
  uint8_t  *pv = NULL;
4,673,990✔
1170
  int32_t   iColData = 0;
4,673,990✔
1171
  SColData *pColData = &aColData[iColData];
4,673,990✔
1172
  int32_t   iTColumn = 1;
4,673,990✔
1173
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
4,673,990✔
1174
  int32_t   iCol = 0;
4,673,990✔
1175

1176
  // primary keys
1177
  uint8_t         *data = pRow->data;
4,673,990✔
1178
  SPrimaryKeyIndex index;
1179
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
4,921,361✔
1180
    data += tGetPrimaryKeyIndex(data, &index);
247,448✔
1181
  }
1182

1183
  SKVIdx *pKVIdx = (SKVIdx *)data;
4,673,913✔
1184
  if (pRow->flag & KV_FLG_LIT) {
4,673,913✔
1185
    pv = pKVIdx->idx + pKVIdx->nCol;
4,607,720✔
1186
  } else if (pRow->flag & KV_FLG_MID) {
66,193!
1187
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
70,029✔
1188
  } else if (pRow->flag & KV_FLG_BIG) {
×
1189
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1190
  } else {
1191
    return TSDB_CODE_INVALID_PARA;
×
1192
  }
1193

1194
  while (pColData) {
45,817,476✔
1195
    if (pTColumn) {
41,189,133✔
1196
      if (pTColumn->colId == pColData->cid) {
40,790,081✔
1197
        while (iCol < pKVIdx->nCol) {
40,746,325✔
1198
          uint8_t *pData;
1199
          if (pRow->flag & KV_FLG_LIT) {
33,832,113✔
1200
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
31,951,978✔
1201
          } else if (pRow->flag & KV_FLG_MID) {
1,880,135!
1202
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,880,203✔
1203
          } else if (pRow->flag & KV_FLG_BIG) {
×
1204
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1205
          } else {
1206
            return TSDB_CODE_INVALID_DATA_FMT;
×
1207
          }
1208

1209
          int16_t cid;
1210
          pData += tGetI16v(pData, &cid);
33,832,181✔
1211

1212
          if (TABS(cid) == pTColumn->colId) {
33,832,181✔
1213
            if (cid < 0) {
33,420,359✔
1214
              if (flag == 0) {
6,866,976✔
1215
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
6,858,477✔
1216
              } else {
1217
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
8,499✔
1218
              }
1219
              if (code) goto _exit;
6,322,655!
1220
            } else {
1221
              uint32_t nData;
1222
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
26,553,383!
1223
                pData += tGetU32v(pData, &nData);
6,355,560✔
1224
              } else {
1225
                nData = 0;
20,197,823✔
1226
              }
1227
              if (flag == 0) {
26,553,383!
1228
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
26,759,151✔
1229
              } else {
1230
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1231
              }
1232
              if (code) goto _exit;
27,049,360!
1233
            }
1234
            iCol++;
33,372,015✔
1235
            goto _continue;
33,372,015✔
1236
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
411,822✔
1237
            break;
39,346✔
1238
          } else {
1239
            iCol++;
372,476✔
1240
          }
1241
        }
1242

1243
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
6,953,558!
1244

1245
      _continue:
6,952,440✔
1246
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
40,324,455✔
1247
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
40,324,455✔
1248
      } else if (pTColumn->colId > pColData->cid) {
416,232!
1249
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1250
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1251
      } else {
1252
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
416,232!
1253
      }
1254
    } else {
1255
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,052!
1256
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,040✔
1257
    }
1258
  }
1259

1260
_exit:
4,628,343✔
1261
  return code;
4,628,343✔
1262
}
1263
/* flag > 0: forward update
1264
 * flag == 0: append
1265
 * flag < 0: backward update
1266
 */
1267
int32_t tRowUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
692,297,074✔
1268
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
692,297,074!
1269
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
692,297,074!
1270

1271
  if (pRow->flag == HAS_NONE) {
692,297,074✔
1272
    return tRowNoneUpsertColData(aColData, nColData, flag);
9,426✔
1273
  } else if (pRow->flag == HAS_NULL) {
692,287,648✔
1274
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
165,510✔
1275
  } else if (pRow->flag >> 4) {  // KV row
692,122,138✔
1276
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
4,674,774✔
1277
  } else {  // TUPLE row
1278
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
687,447,364✔
1279
  }
1280
}
1281

1282
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
2,147,483,647✔
1283
  key->numOfPKs = row->numOfPKs;
2,147,483,647✔
1284

1285
  if (key->numOfPKs == 0) {
2,147,483,647!
1286
    return;
×
1287
  }
1288

1289
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1290

1291
  uint8_t *data = row->data;
2,147,483,647✔
1292

1293
  for (int32_t i = 0; i < row->numOfPKs; i++) {
2,147,483,647✔
1294
    data += tGetPrimaryKeyIndex(data, &indices[i]);
2,147,483,647✔
1295
  }
1296

1297
  // primary keys
1298
  for (int32_t i = 0; i < row->numOfPKs; i++) {
2,147,483,647✔
1299
    key->pks[i].type = indices[i].type;
2,147,483,647✔
1300

1301
    uint8_t *tdata = data + indices[i].offset;
2,147,483,647✔
1302
    if (row->flag >> 4) {
2,147,483,647✔
1303
      tdata += tGetI16v(tdata, NULL);
10,257,781✔
1304
    }
1305

1306
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
1307
      key->pks[i].pData = tdata;
2,290,631✔
1308
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
4,581,262✔
1309
    } else {
1310
      (void)memcpy(&key->pks[i].val, tdata, tDataTypes[indices[i].type].bytes);
2,147,483,647✔
1311
    }
1312
  }
1313
}
1314

1315
#define T_COMPARE_SCALAR_VALUE(TYPE, V1, V2)    \
1316
  do {                                          \
1317
    if (*(TYPE *)(V1) < *(TYPE *)(V2)) {        \
1318
      return -1;                                \
1319
    } else if (*(TYPE *)(V1) > *(TYPE *)(V2)) { \
1320
      return 1;                                 \
1321
    } else {                                    \
1322
      return 0;                                 \
1323
    }                                           \
1324
  } while (0)
1325

1326
int32_t tValueCompare(const SValue *tv1, const SValue *tv2) {
49,755,827✔
1327
  switch (tv1->type) {
49,755,827!
1328
    case TSDB_DATA_TYPE_BOOL:
×
1329
    case TSDB_DATA_TYPE_TINYINT:
1330
      T_COMPARE_SCALAR_VALUE(int8_t, &tv1->val, &tv2->val);
×
1331
    case TSDB_DATA_TYPE_SMALLINT:
×
1332
      T_COMPARE_SCALAR_VALUE(int16_t, &tv1->val, &tv2->val);
×
1333
    case TSDB_DATA_TYPE_INT:
2,090,406✔
1334
      T_COMPARE_SCALAR_VALUE(int32_t, &tv1->val, &tv2->val);
2,090,406✔
1335
    case TSDB_DATA_TYPE_BIGINT:
43,423,814✔
1336
    case TSDB_DATA_TYPE_TIMESTAMP:
1337
      T_COMPARE_SCALAR_VALUE(int64_t, &tv1->val, &tv2->val);
43,423,814✔
1338
    case TSDB_DATA_TYPE_FLOAT:
×
1339
      T_COMPARE_SCALAR_VALUE(float, &tv1->val, &tv2->val);
×
1340
    case TSDB_DATA_TYPE_DOUBLE:
×
1341
      T_COMPARE_SCALAR_VALUE(double, &tv1->val, &tv2->val);
×
1342
    case TSDB_DATA_TYPE_UTINYINT:
×
1343
      T_COMPARE_SCALAR_VALUE(uint8_t, &tv1->val, &tv2->val);
×
1344
    case TSDB_DATA_TYPE_USMALLINT:
×
1345
      T_COMPARE_SCALAR_VALUE(uint16_t, &tv1->val, &tv2->val);
×
1346
    case TSDB_DATA_TYPE_UINT:
1,121,857✔
1347
      T_COMPARE_SCALAR_VALUE(uint32_t, &tv1->val, &tv2->val);
1,121,857✔
1348
    case TSDB_DATA_TYPE_UBIGINT:
1,151,835✔
1349
      T_COMPARE_SCALAR_VALUE(uint64_t, &tv1->val, &tv2->val);
1,151,835✔
1350
    case TSDB_DATA_TYPE_GEOMETRY:
1,978,477✔
1351
    case TSDB_DATA_TYPE_BINARY: {
1352
      int32_t ret = strncmp((const char *)tv1->pData, (const char *)tv2->pData, TMIN(tv1->nData, tv2->nData));
1,978,477✔
1353
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
1,978,477✔
1354
    }
1355
    case TSDB_DATA_TYPE_NCHAR: {
×
1356
      int32_t ret = tasoUcs4Compare((TdUcs4 *)tv1->pData, (TdUcs4 *)tv2->pData,
×
1357
                                    tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1358
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1359
    }
1360
    case TSDB_DATA_TYPE_VARBINARY: {
×
1361
      int32_t ret = memcmp(tv1->pData, tv2->pData, tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1362
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1363
    }
1364
    default:
×
1365
      break;
×
1366
  }
1367

1368
  return 0;
×
1369
}
1370

1371
// NOTE:
1372
// set key->numOfPKs to 0 as the smallest key with ts
1373
// set key->numOfPKs to (TD_MAX_PK_COLS + 1) as the largest key with ts
1374
FORCE_INLINE int32_t tRowKeyCompare(const SRowKey *key1, const SRowKey *key2) {
2,147,483,647✔
1375
  if (key1->ts < key2->ts) {
2,147,483,647!
1376
    return -1;
2,147,483,647✔
1377
  } else if (key1->ts > key2->ts) {
2,147,483,647!
1378
    return 1;
2,147,483,647✔
1379
  }
1380

1381
  if (key1->numOfPKs == key2->numOfPKs) {
53,855,438!
1382
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
76,303,091!
1383
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
49,751,757✔
1384
      if (ret) return ret;
49,737,474!
1385
    }
1386
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1387
    return -1;
×
1388
  } else {
1389
    return 1;
×
1390
  }
1391

1392
  return 0;
26,551,334✔
1393
}
1394

1395
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
739,960,333✔
1396
  pDst->ts = pSrc->ts;
739,960,333✔
1397
  pDst->numOfPKs = pSrc->numOfPKs;
739,960,333✔
1398

1399
  if (pSrc->numOfPKs > 0) {
739,960,333✔
1400
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
67,234,571✔
1401
      SValue *pVal = &pDst->pks[i];
33,725,938✔
1402
      pVal->type = pSrc->pks[i].type;
33,725,938✔
1403

1404
      if (IS_NUMERIC_TYPE(pVal->type)) {
33,725,938!
1405
        pVal->val = pSrc->pks[i].val;
31,559,343✔
1406
      } else {
1407
        pVal->nData = pSrc->pks[i].nData;
2,166,595✔
1408
        (void)memcpy(pVal->pData, pSrc->pks[i].pData, pVal->nData);
2,166,595✔
1409
      }
1410
    }
1411
  }
1412
}
739,960,333✔
1413

1414
// STag ========================================
1415
static int tTagValCmprFn(const void *p1, const void *p2) {
146,458,581✔
1416
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
146,458,581✔
1417
    return -1;
49,996,357✔
1418
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
96,462,224✔
1419
    return 1;
53,052,298✔
1420
  }
1421

1422
  return 0;
43,409,926✔
1423
}
1424
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
10,542✔
1425
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
10,542✔
1426
}
1427

1428
#ifdef TD_DEBUG_PRINT_TAG
1429
static void debugPrintTagVal(int8_t type, const void *val, int32_t vlen, const char *tag, int32_t ln) {
1430
  switch (type) {
1431
    case TSDB_DATA_TYPE_VARBINARY:
1432
    case TSDB_DATA_TYPE_JSON:
1433
    case TSDB_DATA_TYPE_VARCHAR:
1434
    case TSDB_DATA_TYPE_NCHAR:
1435
    case TSDB_DATA_TYPE_GEOMETRY: {
1436
      char tmpVal[32] = {0};
1437
      strncpy(tmpVal, val, vlen > 31 ? 31 : vlen);
1438
      printf("%s:%d type:%d vlen:%d, val:\"%s\"\n", tag, ln, (int32_t)type, vlen, tmpVal);
1439
    } break;
1440
    case TSDB_DATA_TYPE_FLOAT:
1441
      printf("%s:%d type:%d vlen:%d, val:%f\n", tag, ln, (int32_t)type, vlen, *(float *)val);
1442
      break;
1443
    case TSDB_DATA_TYPE_DOUBLE:
1444
      printf("%s:%d type:%d vlen:%d, val:%lf\n", tag, ln, (int32_t)type, vlen, *(double *)val);
1445
      break;
1446
    case TSDB_DATA_TYPE_BOOL:
1447
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
1448
      break;
1449
    case TSDB_DATA_TYPE_TINYINT:
1450
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
1451
      break;
1452
    case TSDB_DATA_TYPE_SMALLINT:
1453
      printf("%s:%d type:%d vlen:%d, val:%" PRIi16 "\n", tag, ln, (int32_t)type, vlen, *(int16_t *)val);
1454
      break;
1455
    case TSDB_DATA_TYPE_INT:
1456
      printf("%s:%d type:%d vlen:%d, val:%" PRIi32 "\n", tag, ln, (int32_t)type, vlen, *(int32_t *)val);
1457
      break;
1458
    case TSDB_DATA_TYPE_BIGINT:
1459
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
1460
      break;
1461
    case TSDB_DATA_TYPE_TIMESTAMP:
1462
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
1463
      break;
1464
    case TSDB_DATA_TYPE_UTINYINT:
1465
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
1466
      break;
1467
    case TSDB_DATA_TYPE_USMALLINT:
1468
      printf("%s:%d type:%d vlen:%d, val:%" PRIu16 "\n", tag, ln, (int32_t)type, vlen, *(uint16_t *)val);
1469
      break;
1470
    case TSDB_DATA_TYPE_UINT:
1471
      printf("%s:%d type:%d vlen:%d, val:%" PRIu32 "\n", tag, ln, (int32_t)type, vlen, *(uint32_t *)val);
1472
      break;
1473
    case TSDB_DATA_TYPE_UBIGINT:
1474
      printf("%s:%d type:%d vlen:%d, val:%" PRIu64 "\n", tag, ln, (int32_t)type, vlen, *(uint64_t *)val);
1475
      break;
1476
    case TSDB_DATA_TYPE_NULL:
1477
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
1478
      break;
1479
    default:
1480
      break;
1481
  }
1482
}
1483

1484
void debugPrintSTag(STag *pTag, const char *tag, int32_t ln) {
1485
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
1486
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
1487
  uint8_t *p = NULL;
1488
  int16_t  offset = 0;
1489

1490
  if (isLarge) {
1491
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
1492
  } else {
1493
    p = (uint8_t *)&pTag->idx[pTag->nTag];
1494
  }
1495
  printf("%s:%d >>> STAG === %s:%s, len: %d, nTag: %d, sver:%d\n", tag, ln, isJson ? "json" : "normal",
1496
         isLarge ? "large" : "small", (int32_t)pTag->len, (int32_t)pTag->nTag, pTag->ver);
1497
  for (uint16_t n = 0; n < pTag->nTag; ++n) {
1498
    if (isLarge) {
1499
      offset = ((int16_t *)pTag->idx)[n];
1500
    } else {
1501
      offset = pTag->idx[n];
1502
    }
1503
    STagVal tagVal = {0};
1504
    if (isJson) {
1505
      tagVal.pKey = (char *)POINTER_SHIFT(p, offset);
1506
    } else {
1507
      tagVal.cid = *(int16_t *)POINTER_SHIFT(p, offset);
1508
    }
1509
    printf("%s:%d loop[%d-%d] offset=%d\n", __func__, __LINE__, (int32_t)pTag->nTag, (int32_t)n, (int32_t)offset);
1510
    tGetTagVal(p + offset, &tagVal, isJson);
1511
    if (IS_VAR_DATA_TYPE(tagVal.type)) {
1512
      debugPrintTagVal(tagVal.type, tagVal.pData, tagVal.nData, __func__, __LINE__);
1513
    } else {
1514
      debugPrintTagVal(tagVal.type, &tagVal.i64, tDataTypes[tagVal.type].bytes, __func__, __LINE__);
1515
    }
1516
  }
1517
  printf("\n");
1518
}
1519
#endif
1520

1521
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
765,548✔
1522
  int32_t n = 0;
765,548✔
1523

1524
  // key
1525
  if (isJson) {
765,548✔
1526
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
952✔
1527
  } else {
1528
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
1,530,144✔
1529
  }
1530

1531
  // type
1532
  n += tPutI8(p ? p + n : p, pTagVal->type);
765,548✔
1533

1534
  // value
1535
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
765,548!
1536
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
472,554✔
1537
  } else {
1538
    p = p ? p + n : p;
529,271✔
1539
    n += tDataTypes[pTagVal->type].bytes;
529,271✔
1540
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
529,271✔
1541
  }
1542

1543
  return n;
765,548✔
1544
}
1545
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
144,945,113✔
1546
  int32_t n = 0;
144,945,113✔
1547

1548
  // key
1549
  if (isJson) {
144,945,113✔
1550
    n += tGetCStr(p + n, &pTagVal->pKey);
24,594!
1551
  } else {
1552
    n += tGetI16v(p + n, &pTagVal->cid);
289,865,632!
1553
  }
1554

1555
  // type
1556
  n += tGetI8(p + n, &pTagVal->type);
144,945,113!
1557

1558
  // value
1559
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
144,945,113!
1560
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
49,157,118!
1561
  } else {
1562
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
120,366,554✔
1563
    n += tDataTypes[pTagVal->type].bytes;
120,366,554✔
1564
  }
1565

1566
  return n;
144,945,113✔
1567
}
1568

1569
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
38,090✔
1570

1571
bool tTagIsJsonNull(void *data) {
6,594✔
1572
  STag  *pTag = (STag *)data;
6,594✔
1573
  int8_t isJson = tTagIsJson(pTag);
6,594✔
1574
  if (!isJson) return false;
6,594✔
1575
  return ((STag *)data)->nTag == 0;
2,894✔
1576
}
1577

1578
int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
138,690✔
1579
  int32_t  code = 0;
138,690✔
1580
  uint8_t *p = NULL;
138,690✔
1581
  int16_t  n = 0;
138,690✔
1582
  int16_t  nTag = taosArrayGetSize(pArray);
138,690✔
1583
  int32_t  szTag = 0;
138,689✔
1584
  int8_t   isLarge = 0;
138,689✔
1585

1586
  // sort
1587
  if (isJson) {
138,689✔
1588
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
206✔
1589
  } else {
1590
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
138,483✔
1591
  }
1592

1593
  // get size
1594
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
521,555✔
1595
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
382,875✔
1596
  }
1597
  if (szTag <= INT8_MAX) {
138,680✔
1598
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
122,728✔
1599
  } else {
1600
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
15,952✔
1601
    isLarge = 1;
15,952✔
1602
  }
1603

1604
  // build tag
1605
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
138,680✔
1606
  if ((*ppTag) == NULL) {
138,750✔
1607
    code = terrno;
11✔
1608
    goto _err;
×
1609
  }
1610
  (*ppTag)->flags = 0;
138,739✔
1611
  if (isJson) {
138,739✔
1612
    (*ppTag)->flags |= TD_TAG_JSON;
206✔
1613
  }
1614
  if (isLarge) {
138,739✔
1615
    (*ppTag)->flags |= TD_TAG_LARGE;
15,958✔
1616
  }
1617
  (*ppTag)->len = szTag;
138,739✔
1618
  (*ppTag)->nTag = nTag;
138,739✔
1619
  (*ppTag)->ver = version;
138,739✔
1620

1621
  if (isLarge) {
138,739✔
1622
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
15,958✔
1623
  } else {
1624
    p = (uint8_t *)&(*ppTag)->idx[nTag];
122,781✔
1625
  }
1626
  n = 0;
138,739✔
1627
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
521,665✔
1628
    if (isLarge) {
382,950✔
1629
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
100,831✔
1630
    } else {
1631
      (*ppTag)->idx[iTag] = n;
282,119✔
1632
    }
1633
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
382,950✔
1634
  }
1635
#ifdef TD_DEBUG_PRINT_TAG
1636
  debugPrintSTag(*ppTag, __func__, __LINE__);
1637
#endif
1638

1639
  return code;
138,715✔
1640

1641
_err:
×
1642
  return code;
×
1643
}
1644

1645
void tTagFree(STag *pTag) {
54,703✔
1646
  if (pTag) taosMemoryFree(pTag);
54,703✔
1647
}
54,703✔
1648

1649
char *tTagValToData(const STagVal *value, bool isJson) {
16,746,985✔
1650
  if (!value) {
16,746,985!
1651
    return NULL;
×
1652
  }
1653

1654
  char  *data = NULL;
16,746,985✔
1655
  int8_t typeBytes = 0;
16,746,985✔
1656
  if (isJson) {
16,746,985✔
1657
    typeBytes = CHAR_BYTES;
5,946✔
1658
  }
1659

1660
  if (IS_VAR_DATA_TYPE(value->type)) {
16,746,985✔
1661
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
4,889,477✔
1662
    if (data == NULL) {
4,894,346!
1663
      return NULL;
×
1664
    }
1665

1666
    if (isJson) {
4,894,346✔
1667
      *data = value->type;
2,378✔
1668
    }
1669

1670
    varDataLen(data + typeBytes) = value->nData;
4,894,346✔
1671
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
4,894,346✔
1672
  } else {
1673
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
11,857,508✔
1674
  }
1675

1676
  return data;
16,751,854✔
1677
}
1678

1679
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
44,508,673✔
1680
  if (!pTag || !pTagVal) {
44,508,673!
1681
    return false;
×
1682
  }
1683

1684
  int16_t  lidx = 0;
44,665,393✔
1685
  int16_t  ridx = pTag->nTag - 1;
44,665,393✔
1686
  int16_t  midx;
1687
  uint8_t *p;
1688
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
44,665,393✔
1689
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
44,665,393✔
1690
  int16_t  offset;
1691
  STagVal  tv;
1692
  int      c;
1693

1694
  if (isLarge) {
44,665,393✔
1695
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
37,806,930✔
1696
  } else {
1697
    p = (uint8_t *)&pTag->idx[pTag->nTag];
6,858,463✔
1698
  }
1699

1700
  pTagVal->type = TSDB_DATA_TYPE_NULL;
44,665,393✔
1701
  pTagVal->pData = NULL;
44,665,393✔
1702
  pTagVal->nData = 0;
44,665,393✔
1703
  while (lidx <= ridx) {
147,209,131✔
1704
    midx = (lidx + ridx) / 2;
145,441,189✔
1705
    if (isLarge) {
145,441,189✔
1706
      offset = ((int16_t *)pTag->idx)[midx];
122,448,269✔
1707
    } else {
1708
      offset = pTag->idx[midx];
22,992,920✔
1709
    }
1710

1711
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
145,441,189✔
1712
    if (isJson) {
146,383,219✔
1713
      c = tTagValJsonCmprFn(pTagVal, &tv);
10,408✔
1714
    } else {
1715
      c = tTagValCmprFn(pTagVal, &tv);
146,372,811✔
1716
    }
1717

1718
    if (c < 0) {
147,605,859✔
1719
      ridx = midx - 1;
49,543,171✔
1720
    } else if (c > 0) {
98,062,688✔
1721
      lidx = midx + 1;
53,000,567✔
1722
    } else {
1723
      (void)memcpy(pTagVal, &tv, sizeof(tv));
45,062,121✔
1724
      return true;
45,062,121✔
1725
    }
1726
  }
1727
  return false;
1,767,942✔
1728
}
1729

1730
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
712,929✔
1731
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,425,858✔
1732
}
1733

1734
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
20,202,112✔
1735

1736
int32_t tTagToValArray(const STag *pTag, SArray **ppArray) {
1,445✔
1737
  int32_t  code = 0;
1,445✔
1738
  uint8_t *p = NULL;
1,445✔
1739
  STagVal  tv = {0};
1,445✔
1740
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
1,445✔
1741
  int16_t  offset = 0;
1,445✔
1742

1743
  if (isLarge) {
1,445✔
1744
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
16✔
1745
  } else {
1746
    p = (uint8_t *)&pTag->idx[pTag->nTag];
1,429✔
1747
  }
1748

1749
  (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
1,445✔
1750
  if (*ppArray == NULL) {
1,445!
1751
    code = terrno;
×
1752
    goto _err;
×
1753
  }
1754

1755
  for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
4,094✔
1756
    if (isLarge) {
2,649✔
1757
      offset = ((int16_t *)pTag->idx)[iTag];
16✔
1758
    } else {
1759
      offset = pTag->idx[iTag];
2,633✔
1760
    }
1761
    int32_t nt = tGetTagVal(p + offset, &tv, pTag->flags & TD_TAG_JSON);
2,649✔
1762
    if (taosArrayPush(*ppArray, &tv) == NULL) {
5,298!
1763
      code = terrno;
×
1764
      goto _err;
×
1765
    }
1766
  }
1767

1768
  return code;
1,445✔
1769

1770
_err:
×
1771
  return code;
×
1772
}
1773

1774
// STSchema ========================================
1775
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
16,132,835✔
1776
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
16,132,835✔
1777
  if (pTSchema == NULL) {
16,164,277!
1778
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1779
    return NULL;
×
1780
  }
1781

1782
  pTSchema->numOfCols = numOfCols;
16,164,991✔
1783
  pTSchema->version = version;
16,164,991✔
1784

1785
  // timestamp column
1786
  if (!(aSchema[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
16,164,991!
1787
    terrno = TSDB_CODE_INVALID_PARA;
×
1788
    return NULL;
×
1789
  }
1790
  if (!(aSchema[0].colId == PRIMARYKEY_TIMESTAMP_COL_ID)) {
16,164,991!
1791
    terrno = TSDB_CODE_INVALID_PARA;
×
1792
    return NULL;
×
1793
  }
1794
  pTSchema->columns[0].colId = aSchema[0].colId;
16,164,991✔
1795
  pTSchema->columns[0].type = aSchema[0].type;
16,164,991✔
1796
  pTSchema->columns[0].flags = aSchema[0].flags;
16,164,991✔
1797
  pTSchema->columns[0].bytes = TYPE_BYTES[aSchema[0].type];
16,164,991✔
1798
  pTSchema->columns[0].offset = -1;
16,164,991✔
1799

1800
  // other columns
1801
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
185,696,815✔
1802
    SSchema  *pSchema = &aSchema[iCol];
169,531,824✔
1803
    STColumn *pTColumn = &pTSchema->columns[iCol];
169,531,824✔
1804

1805
    pTColumn->colId = pSchema->colId;
169,531,824✔
1806
    pTColumn->type = pSchema->type;
169,531,824✔
1807
    pTColumn->flags = pSchema->flags;
169,531,824✔
1808
    pTColumn->offset = pTSchema->flen;
169,531,824✔
1809

1810
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
169,531,824!
1811
      pTColumn->bytes = pSchema->bytes;
35,368,905✔
1812
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
35,368,905✔
1813
    } else {
1814
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
134,162,919✔
1815
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
134,162,919✔
1816
    }
1817

1818
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
169,531,824✔
1819
  }
1820

1821
#if 1  // todo : remove this
1822
  pTSchema->tlen += (int32_t)TD_BITMAP_BYTES(numOfCols);
16,164,991✔
1823
#endif
1824

1825
  return pTSchema;
16,164,991✔
1826
}
1827

1828
static int32_t tTColumnCompare(const void *p1, const void *p2) {
9,919,980✔
1829
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
9,919,980✔
1830
    return -1;
1,492,974✔
1831
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
8,427,006✔
1832
    return 1;
5,920,178✔
1833
  }
1834

1835
  return 0;
2,506,828✔
1836
}
1837

1838
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid) {
2,508,332✔
1839
  STColumn tcol = {
2,508,332✔
1840
      .colId = cid,
1841
  };
1842

1843
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
2,508,332✔
1844
}
1845

1846
// SColData ========================================
1847
void tColDataDestroy(void *ph) {
21,379,784✔
1848
  if (ph) {
21,379,784!
1849
    SColData *pColData = (SColData *)ph;
21,379,978✔
1850

1851
    tFree(pColData->pBitMap);
21,379,978✔
1852
    tFree(pColData->aOffset);
21,380,148✔
1853
    tFree(pColData->pData);
21,380,230✔
1854
  }
1855
}
21,380,731✔
1856

1857
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
21,803,622✔
1858
  pColData->cid = cid;
21,803,622✔
1859
  pColData->type = type;
21,803,622✔
1860
  pColData->cflag = cflag;
21,803,622✔
1861
  tColDataClear(pColData);
21,803,622✔
1862
}
21,805,716✔
1863

1864
void tColDataClear(SColData *pColData) {
44,532,426✔
1865
  pColData->numOfNone = 0;
44,532,426✔
1866
  pColData->numOfNull = 0;
44,532,426✔
1867
  pColData->numOfValue = 0;
44,532,426✔
1868
  pColData->nVal = 0;
44,532,426✔
1869
  pColData->flag = 0;
44,532,426✔
1870
  pColData->nData = 0;
44,532,426✔
1871
}
44,532,426✔
1872

1873
void tColDataDeepClear(SColData *pColData) {
653✔
1874
  pColData->pBitMap = NULL;
653✔
1875
  pColData->aOffset = NULL;
653✔
1876
  pColData->pData = NULL;
653✔
1877

1878
  tColDataClear(pColData);
653✔
1879
}
652✔
1880

1881
static FORCE_INLINE int32_t tColDataPutValue(SColData *pColData, uint8_t *pData, uint32_t nData) {
1882
  int32_t code = 0;
2,147,483,647✔
1883

1884
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1885
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
95,632,520!
1886
    if (code) goto _exit;
102,633,299!
1887
    pColData->aOffset[pColData->nVal] = pColData->nData;
102,633,299✔
1888

1889
    if (nData) {
102,633,299!
1890
      code = tRealloc(&pColData->pData, pColData->nData + nData);
99,714,400!
1891
      if (code) goto _exit;
100,302,882!
1892
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
100,302,882✔
1893
      pColData->nData += nData;
100,302,882✔
1894
    }
1895
  } else {
1896
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
1897
      return TSDB_CODE_INVALID_PARA;
×
1898
    }
1899
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
1900
    if (code) goto _exit;
2,147,483,647!
1901
    if (pData) {
2,147,483,647!
1902
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
1903
    } else {
1904
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
24,264,259✔
1905
    }
1906
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
1907
  }
1908
  pColData->nVal++;
2,147,483,647✔
1909

1910
_exit:
2,147,483,647✔
1911
  return code;
2,147,483,647✔
1912
}
1913
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,728,825✔
1914
  pColData->flag = HAS_VALUE;
2,728,912✔
1915
  pColData->numOfValue++;
2,728,825✔
1916
  return tColDataPutValue(pColData, pData, nData);
2,729,759✔
1917
}
1918
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
236,149✔
1919
  pColData->flag = HAS_NONE;
236,149✔
1920
  pColData->numOfNone++;
236,149✔
1921
  pColData->nVal++;
236,149✔
1922
  return 0;
236,149✔
1923
}
1924
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
156,049✔
1925
  pColData->flag = HAS_NULL;
156,140✔
1926
  pColData->numOfNull++;
156,140✔
1927
  pColData->nVal++;
156,140✔
1928
  return 0;
156,049✔
1929
}
1930
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,416✔
1931
  int32_t code = 0;
1,416✔
1932

1933
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
1,416✔
1934
  code = tRealloc(&pColData->pBitMap, nBit);
1,416!
1935
  if (code) return code;
1,416!
1936

1937
  memset(pColData->pBitMap, 0, nBit);
1,416✔
1938
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,416!
1939

1940
  pColData->flag |= HAS_VALUE;
1,416✔
1941
  pColData->numOfValue++;
1,416✔
1942

1943
  if (pColData->nVal) {
1,416!
1944
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,417!
1945
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
253✔
1946
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
253!
1947
      if (code) return code;
255!
1948
      memset(pColData->aOffset, 0, nOffset);
255✔
1949
    } else {
1950
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
1,164✔
1951
      code = tRealloc(&pColData->pData, pColData->nData);
1,164!
1952
      if (code) return code;
1,162!
1953
      memset(pColData->pData, 0, pColData->nData);
1,162✔
1954
    }
1955
  }
1956

1957
  return tColDataPutValue(pColData, pData, nData);
1,417✔
1958
}
1959
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
12,332,715✔
1960
  pColData->nVal++;
12,332,715✔
1961
  pColData->numOfNone++;
12,332,715✔
1962
  return 0;
12,332,715✔
1963
}
1964
static FORCE_INLINE int32_t tColDataAppendValue12(SColData *pColData, uint8_t *pData, uint32_t nData) {
600✔
1965
  int32_t code = 0;
600✔
1966

1967
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
600✔
1968
  code = tRealloc(&pColData->pBitMap, nBit);
600!
1969
  if (code) return code;
600!
1970

1971
  memset(pColData->pBitMap, 0, nBit);
600✔
1972
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
600!
1973

1974
  pColData->flag |= HAS_NULL;
600✔
1975
  pColData->numOfNull++;
600✔
1976
  pColData->nVal++;
600✔
1977

1978
  return code;
600✔
1979
}
1980
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
15,939✔
1981
  int32_t code = 0;
15,941✔
1982

1983
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
15,941✔
1984
  code = tRealloc(&pColData->pBitMap, nBit);
15,939!
1985
  if (code) return code;
15,941!
1986

1987
  memset(pColData->pBitMap, 0, nBit);
15,941✔
1988
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
15,941!
1989

1990
  pColData->flag |= HAS_VALUE;
15,941✔
1991
  pColData->numOfValue++;
15,941✔
1992

1993
  if (pColData->nVal) {
15,941!
1994
    if (IS_VAR_DATA_TYPE(pColData->type)) {
15,941!
1995
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
7,571✔
1996
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
7,571!
1997
      if (code) return code;
7,571!
1998
      memset(pColData->aOffset, 0, nOffset);
7,571✔
1999
    } else {
2000
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
8,370✔
2001
      code = tRealloc(&pColData->pData, pColData->nData);
8,370!
2002
      if (code) return code;
8,370!
2003
      memset(pColData->pData, 0, pColData->nData);
8,370✔
2004
    }
2005
  }
2006

2007
  return tColDataPutValue(pColData, pData, nData);
15,941✔
2008
}
2009
static FORCE_INLINE int32_t tColDataAppendValue21(SColData *pColData, uint8_t *pData, uint32_t nData) {
80✔
2010
  int32_t code = 0;
80✔
2011

2012
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
80✔
2013
  code = tRealloc(&pColData->pBitMap, nBit);
80✔
2014
  if (code) return code;
80!
2015

2016
  memset(pColData->pBitMap, 255, nBit);
80✔
2017
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
80!
2018

2019
  pColData->flag |= HAS_NONE;
80✔
2020
  pColData->numOfNone++;
80✔
2021
  pColData->nVal++;
80✔
2022

2023
  return code;
80✔
2024
}
2025
static FORCE_INLINE int32_t tColDataAppendValue22(SColData *pColData, uint8_t *pData, uint32_t nData) {
4,505,766✔
2026
  pColData->nVal++;
4,505,766✔
2027
  pColData->numOfNull++;
4,505,766✔
2028
  return 0;
4,505,766✔
2029
}
2030
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2031
  int32_t code = 0;
×
2032

2033
  pColData->flag |= HAS_VALUE;
×
2034
  pColData->numOfValue++;
×
2035

2036
  uint8_t *pBitMap = NULL;
×
2037
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
2038
  if (code) return code;
×
2039

2040
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
2041
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal));
×
2042
  }
2043
  SET_BIT2_EX(pBitMap, pColData->nVal, 2);
×
2044

2045
  tFree(pColData->pBitMap);
×
2046
  pColData->pBitMap = pBitMap;
×
2047

2048
  if (pColData->nVal) {
×
2049
    if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2050
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
2051
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
2052
      if (code) return code;
×
2053
      memset(pColData->aOffset, 0, nOffset);
×
2054
    } else {
2055
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
×
2056
      code = tRealloc(&pColData->pData, pColData->nData);
×
2057
      if (code) return code;
×
2058
      memset(pColData->pData, 0, pColData->nData);
×
2059
    }
2060
  }
2061

2062
  return tColDataPutValue(pColData, pData, nData);
×
2063
}
2064
static FORCE_INLINE int32_t tColDataAppendValue31(SColData *pColData, uint8_t *pData, uint32_t nData) {
400✔
2065
  int32_t code = 0;
400✔
2066

2067
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
400!
2068
  if (code) return code;
400!
2069

2070
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
400!
2071
  pColData->numOfNone++;
400✔
2072
  pColData->nVal++;
400✔
2073

2074
  return code;
400✔
2075
}
2076
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
9,380✔
2077
  int32_t code = 0;
9,380✔
2078

2079
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
9,380✔
2080
  if (code) return code;
9,381!
2081

2082
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
9,381!
2083
  pColData->numOfNull++;
9,381✔
2084
  pColData->nVal++;
9,381✔
2085

2086
  return code;
9,381✔
2087
}
2088
static FORCE_INLINE int32_t tColDataAppendValue40(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,147,483,647✔
2089
  pColData->numOfValue++;
2,147,483,647✔
2090
  return tColDataPutValue(pColData, pData, nData);
2,147,483,647✔
2091
}
2092
static FORCE_INLINE int32_t tColDataAppendValue41(SColData *pColData, uint8_t *pData, uint32_t nData) {
86,575✔
2093
  int32_t code = 0;
86,575✔
2094

2095
  pColData->flag |= HAS_NONE;
86,575✔
2096
  pColData->numOfNone++;
86,575✔
2097

2098
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
86,575✔
2099
  code = tRealloc(&pColData->pBitMap, nBit);
86,575✔
2100
  if (code) return code;
86,620!
2101

2102
  memset(pColData->pBitMap, 255, nBit);
86,620✔
2103
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
86,620✔
2104

2105
  return tColDataPutValue(pColData, NULL, 0);
86,623✔
2106
}
2107
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
256,828✔
2108
  int32_t code = 0;
262,946✔
2109

2110
  pColData->flag |= HAS_NULL;
262,946✔
2111
  pColData->numOfNull++;
262,946✔
2112

2113
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
262,946✔
2114
  code = tRealloc(&pColData->pBitMap, nBit);
262,642✔
2115
  if (code) return code;
262,955!
2116

2117
  memset(pColData->pBitMap, 255, nBit);
262,955✔
2118
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
262,955!
2119

2120
  return tColDataPutValue(pColData, NULL, 0);
262,952✔
2121
}
2122
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
503,112✔
2123
  int32_t code = 0;
505,113✔
2124

2125
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
505,112!
2126
  if (code) return code;
505,350!
2127

2128
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
505,350!
2129
  pColData->numOfValue++;
505,350!
2130

2131
  return tColDataPutValue(pColData, pData, nData);
508,449✔
2132
}
2133
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
749,470✔
2134
  int32_t code = 0;
749,470✔
2135

2136
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
749,470!
2137
  if (code) return code;
749,476!
2138

2139
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
749,476✔
2140
  pColData->numOfNone++;
749,476✔
2141

2142
  return tColDataPutValue(pColData, NULL, 0);
752,304✔
2143
}
2144
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
1✔
2145
  int32_t code = 0;
1✔
2146

2147
  pColData->flag |= HAS_NULL;
1✔
2148
  pColData->numOfNull++;
1✔
2149

2150
  uint8_t *pBitMap = NULL;
1✔
2151
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
1!
2152
  if (code) return code;
1!
2153

2154
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3!
2155
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
2!
2156
  }
2157
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
1!
2158

2159
  tFree(pColData->pBitMap);
1!
2160
  pColData->pBitMap = pBitMap;
1!
2161

2162
  return tColDataPutValue(pColData, NULL, 0);
1✔
2163
}
2164
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
363,008,769✔
2165
  int32_t code = 0;
363,175,543✔
2166

2167
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
363,175,143!
2168
  if (code) return code;
363,443,602!
2169
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
363,443,602!
2170
  pColData->numOfValue++;
363,443,602✔
2171

2172
  return tColDataPutValue(pColData, pData, nData);
363,924,996✔
2173
}
2174
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
3,997✔
2175
  int32_t code = 0;
3,997✔
2176

2177
  pColData->flag |= HAS_NONE;
3,997✔
2178
  pColData->numOfNone++;
3,997✔
2179

2180
  uint8_t *pBitMap = NULL;
3,997✔
2181
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
3,997!
2182
  if (code) return code;
3,997!
2183

2184
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
135,408✔
2185
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
131,411✔
2186
  }
2187
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
3,997✔
2188

2189
  tFree(pColData->pBitMap);
3,997✔
2190
  pColData->pBitMap = pBitMap;
3,996✔
2191

2192
  return tColDataPutValue(pColData, NULL, 0);
3,995✔
2193
}
2194
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
22,607,303✔
2195
  int32_t code = 0;
22,784,648✔
2196

2197
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
22,781,054!
2198
  if (code) return code;
22,792,884!
2199
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
22,792,884✔
2200
  pColData->numOfNull++;
22,792,884✔
2201

2202
  return tColDataPutValue(pColData, NULL, 0);
22,801,650✔
2203
}
2204
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2205
  int32_t code = 0;
×
2206

2207
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
2208
  if (code) return code;
×
2209
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 2);
×
2210
  pColData->numOfValue++;
×
2211

2212
  return tColDataPutValue(pColData, pData, nData);
×
2213
}
2214
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
4✔
2215
  int32_t code = 0;
4✔
2216

2217
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
4!
2218
  if (code) return code;
4!
2219
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 0);
4✔
2220
  pColData->numOfNone++;
4!
2221

2222
  return tColDataPutValue(pColData, NULL, 0);
4✔
2223
}
2224
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2225
  int32_t code = 0;
×
2226

2227
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
2228
  if (code) return code;
×
2229
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 1);
×
2230
  pColData->numOfNull++;
×
2231

2232
  return tColDataPutValue(pColData, NULL, 0);
×
2233
}
2234
static int32_t (*tColDataAppendValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData) = {
2235
    {tColDataAppendValue00, tColDataAppendValue01, tColDataAppendValue02},  // 0
2236
    {tColDataAppendValue10, tColDataAppendValue11, tColDataAppendValue12},  // HAS_NONE
2237
    {tColDataAppendValue20, tColDataAppendValue21, tColDataAppendValue22},  // HAS_NULL
2238
    {tColDataAppendValue30, tColDataAppendValue31, tColDataAppendValue32},  // HAS_NULL|HAS_NONE
2239
    {tColDataAppendValue40, tColDataAppendValue41, tColDataAppendValue42},  // HAS_VALUE
2240
    {tColDataAppendValue50, tColDataAppendValue51, tColDataAppendValue52},  // HAS_VALUE|HAS_NONE
2241
    {tColDataAppendValue60, tColDataAppendValue61, tColDataAppendValue62},  // HAS_VALUE|HAS_NULL
2242
    {tColDataAppendValue70, tColDataAppendValue71, tColDataAppendValue72},  // HAS_VALUE|HAS_NULL|HAS_NONE
2243

2244
    //       VALUE                  NONE                     NULL
2245
};
2246
int32_t tColDataAppendValue(SColData *pColData, SColVal *pColVal) {
2,147,483,647✔
2247
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) {
2,147,483,647!
2248
    return TSDB_CODE_INVALID_PARA;
×
2249
  }
2250
  return tColDataAppendValueImpl[pColData->flag][pColVal->flag](
2,147,483,647✔
2251
      pColData, IS_VAR_DATA_TYPE(pColData->type) ? pColVal->value.pData : (uint8_t *)&pColVal->value.val,
2,147,483,647!
2252
      pColVal->value.nData);
2253
}
2254

2255
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
9✔
2256
  pColData->numOfNone--;
9✔
2257
  pColData->nVal--;
9✔
2258
  if (pColData->numOfNone) {
9!
2259
    return tColDataAppendValue10(pColData, pData, nData);
×
2260
  } else {
2261
    pColData->flag = 0;
9✔
2262
    return tColDataAppendValue00(pColData, pData, nData);
9✔
2263
  }
2264
}
2265
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
2266
  pColData->numOfNone--;
24✔
2267
  pColData->nVal--;
24✔
2268
  if (pColData->numOfNone) {
24!
2269
    return tColDataAppendValue12(pColData, pData, nData);
×
2270
  } else {
2271
    pColData->flag = 0;
24✔
2272
    return tColDataAppendValue02(pColData, pData, nData);
24✔
2273
  }
2274
  return 0;
2275
}
2276
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
78✔
2277
  if (forward) {
78!
2278
    pColData->numOfNull--;
78✔
2279
    pColData->nVal--;
78✔
2280
    if (pColData->numOfNull) {
78!
2281
      return tColDataAppendValue20(pColData, pData, nData);
×
2282
    } else {
2283
      pColData->flag = 0;
78✔
2284
      return tColDataAppendValue00(pColData, pData, nData);
78✔
2285
    }
2286
  }
2287
  return 0;
×
2288
}
2289
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2290
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2291
    pColData->numOfNone--;
×
2292
    pColData->nVal--;
×
2293
    if (pColData->numOfNone) {
×
2294
      return tColDataAppendValue30(pColData, pData, nData);
×
2295
    } else {
2296
      pColData->flag = HAS_NULL;
×
2297
      return tColDataAppendValue20(pColData, pData, nData);
×
2298
    }
2299
  } else if (forward) {  // NULL ==> VALUE
×
2300
    pColData->numOfNull--;
×
2301
    pColData->nVal--;
×
2302
    if (pColData->numOfNull) {
×
2303
      return tColDataAppendValue30(pColData, pData, nData);
×
2304
    } else {
2305
      pColData->flag = HAS_NONE;
×
2306
      return tColDataAppendValue10(pColData, pData, nData);
×
2307
    }
2308
  }
2309
  return 0;
×
2310
}
2311
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
2312
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
2313
    pColData->numOfNone--;
80✔
2314
    pColData->numOfNull++;
80✔
2315
    if (pColData->numOfNone) {
80!
2316
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2317
    } else {
2318
      pColData->flag = HAS_NULL;
80✔
2319
    }
2320
  }
2321
  return 0;
80✔
2322
}
2323
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
7,854,896✔
2324
  if (forward) {  // VALUE ==> VALUE
7,854,896!
2325
    pColData->nVal--;
7,855,142✔
2326
    if (IS_VAR_DATA_TYPE(pColData->type)) {
7,855,142!
2327
      pColData->nData = pColData->aOffset[pColData->nVal];
718,277✔
2328
    } else {
2329
      pColData->nData -= TYPE_BYTES[pColData->type];
7,136,865✔
2330
    }
2331
    return tColDataPutValue(pColData, pData, nData);
7,873,322✔
2332
  }
2333
  return 0;
×
2334
}
2335
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,881✔
2336
  if (forward) {  // VALUE ==> NULL
5,881!
2337
    pColData->numOfValue--;
5,881✔
2338
    pColData->nVal--;
5,881✔
2339
    if (pColData->numOfValue) {
5,881✔
2340
      if (IS_VAR_DATA_TYPE(pColData->type)) {
5,814!
2341
        pColData->nData = pColData->aOffset[pColData->nVal];
1,117✔
2342
      } else {
2343
        pColData->nData -= TYPE_BYTES[pColData->type];
4,697✔
2344
      }
2345
      return tColDataAppendValue42(pColData, pData, nData);
5,813✔
2346
    } else {
2347
      pColData->flag = 0;
67✔
2348
      pColData->nData = 0;
67✔
2349
      return tColDataAppendValue02(pColData, pData, nData);
67✔
2350
    }
2351
  }
2352
  return 0;
×
2353
}
2354
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
41,821✔
2355
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
41,821✔
2356
    pColData->numOfNone--;
5,599✔
2357
    pColData->nVal--;
5,599✔
2358
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,599!
2359
      pColData->nData -= TYPE_BYTES[pColData->type];
4,479✔
2360
    }
2361
    if (pColData->numOfNone) {
5,599✔
2362
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2363
    } else {
2364
      pColData->flag = HAS_VALUE;
3,599✔
2365
      return tColDataAppendValue40(pColData, pData, nData);
3,599✔
2366
    }
2367
  } else if (forward) {  // VALUE ==> VALUE
36,222!
2368
    pColData->nVal--;
36,225✔
2369
    if (IS_VAR_DATA_TYPE(pColData->type)) {
36,225!
2370
      pColData->nData = pColData->aOffset[pColData->nVal];
5,171✔
2371
    } else {
2372
      pColData->nData -= TYPE_BYTES[pColData->type];
31,054✔
2373
    }
2374
    return tColDataPutValue(pColData, pData, nData);
36,256✔
2375
  }
2376
  return 0;
×
2377
}
2378
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
304✔
2379
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
304!
2380
    pColData->numOfNone--;
304✔
2381
    pColData->nVal--;
304✔
2382
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
304!
2383
      pColData->nData -= TYPE_BYTES[pColData->type];
244✔
2384
    }
2385
    if (pColData->numOfNone) {
304!
2386
      return tColDataAppendValue52(pColData, pData, nData);
×
2387
    } else {
2388
      pColData->flag = HAS_VALUE;
304!
2389
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2390
    }
2391
  } else if (forward) {  // VALUE ==> NULL
×
2392
    pColData->numOfValue--;
×
2393
    pColData->nVal--;
×
2394
    if (pColData->numOfValue) {
×
2395
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2396
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2397
      } else {
2398
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2399
      }
2400
      return tColDataAppendValue52(pColData, pData, nData);
×
2401
    } else {
2402
      pColData->flag = HAS_NONE;
×
2403
      pColData->nData = 0;
×
2404
      return tColDataAppendValue12(pColData, pData, nData);
×
2405
    }
2406
  }
2407
  return 0;
×
2408
}
2409
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,300,090✔
2410
  if (forward) {
3,300,090!
2411
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
3,300,090✔
2412
      pColData->numOfNull--;
186,002✔
2413
      pColData->nVal--;
186,002✔
2414
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
186,002!
2415
        pColData->nData -= TYPE_BYTES[pColData->type];
156,274✔
2416
      }
2417
      if (pColData->numOfNull) {
186,002✔
2418
        return tColDataAppendValue60(pColData, pData, nData);
166,374✔
2419
      } else {
2420
        pColData->flag = HAS_VALUE;
19,628✔
2421
        return tColDataAppendValue40(pColData, pData, nData);
19,627✔
2422
      }
2423
    } else {  // VALUE ==> VALUE
2424
      pColData->nVal--;
3,114,088✔
2425
      if (IS_VAR_DATA_TYPE(pColData->type)) {
3,114,088!
2426
        pColData->nData = pColData->aOffset[pColData->nVal];
480,798✔
2427
      } else {
2428
        pColData->nData -= TYPE_BYTES[pColData->type];
2,633,290✔
2429
      }
2430
      return tColDataPutValue(pColData, pData, nData);
3,114,087✔
2431
    }
2432
  }
2433
  return 0;
×
2434
}
2435
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
196,932✔
2436
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
196,932!
2437
    pColData->numOfValue--;
173,753✔
2438
    pColData->nVal--;
173,753✔
2439
    if (pColData->numOfValue) {
173,753✔
2440
      if (IS_VAR_DATA_TYPE(pColData->type)) {
173,751!
2441
        pColData->nData = pColData->aOffset[pColData->nVal];
27,664✔
2442
      } else {
2443
        pColData->nData -= TYPE_BYTES[pColData->type];
146,087✔
2444
      }
2445
      return tColDataAppendValue62(pColData, pData, nData);
173,753✔
2446
    } else {
2447
      pColData->flag = HAS_NULL;
2✔
2448
      pColData->nData = 0;
2!
2449
      return tColDataAppendValue20(pColData, pData, nData);
2✔
2450
    }
2451
  }
2452
  return 0;
23,179✔
2453
}
2454
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
401✔
2455
  int32_t code = 0;
401✔
2456

2457
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
401✔
2458
  if (bv == 0) {  // NONE ==> VALUE
401✔
2459
    pColData->numOfNone--;
400✔
2460
    pColData->nVal--;
400✔
2461
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
400!
2462
      pColData->nData -= TYPE_BYTES[pColData->type];
320✔
2463
    }
2464
    if (pColData->numOfNone) {
400!
2465
      return tColDataAppendValue70(pColData, pData, nData);
×
2466
    } else {
2467
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
21,157✔
2468
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
20,757✔
2469
      }
2470
      pColData->flag = (HAS_VALUE | HAS_NULL);
400!
2471
      return tColDataAppendValue60(pColData, pData, nData);
400✔
2472
    }
2473
  } else if (bv == 1) {  // NULL ==> VALUE
1!
2474
    if (forward) {
1!
2475
      pColData->numOfNull--;
1✔
2476
      pColData->nVal--;
1✔
2477
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
1!
2478
        pColData->nData -= TYPE_BYTES[pColData->type];
1✔
2479
      }
2480
      if (pColData->numOfNull) {
1!
2481
        return tColDataAppendValue70(pColData, pData, nData);
×
2482
      } else {
2483
        for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
3✔
2484
          SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) ? 1 : 0);
2✔
2485
        }
2486
        pColData->flag = (HAS_VALUE | HAS_NONE);
1!
2487
        return tColDataAppendValue50(pColData, pData, nData);
1✔
2488
      }
2489
    }
2490
  } else if (bv == 2) {  // VALUE ==> VALUE
×
2491
    if (forward) {
×
2492
      pColData->nVal--;
×
2493
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2494
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2495
      } else {
2496
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2497
      }
2498
      return tColDataPutValue(pColData, pData, nData);
×
2499
    }
2500
  } else {
2501
    return TSDB_CODE_INVALID_PARA;
×
2502
  }
2503
  return 0;
×
2504
}
2505
static int32_t tColDataUpdateValue72(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,594✔
2506
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
3,594✔
2507
  if (bv == 0) {  // NONE ==> NULL
3,594!
2508
    pColData->numOfNone--;
3,594✔
2509
    pColData->nVal--;
3,594✔
2510
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,594!
2511
      pColData->nData -= TYPE_BYTES[pColData->type];
2,544✔
2512
    }
2513
    if (pColData->numOfNone) {
3,594!
2514
      return tColDataAppendValue72(pColData, pData, nData);
×
2515
    } else {
2516
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
114,328✔
2517
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
110,734✔
2518
      }
2519
      pColData->flag = (HAS_VALUE | HAS_NULL);
3,594✔
2520
      return tColDataAppendValue62(pColData, pData, nData);
3,595✔
2521
    }
2522
  } else if (bv == 2 && forward) {  // VALUE ==> NULL
×
2523
    pColData->numOfValue--;
×
2524
    pColData->nVal--;
×
2525
    if (pColData->numOfValue) {
×
2526
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2527
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2528
      } else {
2529
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2530
      }
2531
      return tColDataAppendValue72(pColData, pData, nData);
×
2532
    } else {
2533
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
×
2534
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal));
×
2535
      }
2536
      pColData->flag = (HAS_NULL | HAS_NONE);
×
2537
      pColData->nData = 0;
×
2538
      return tColDataAppendValue32(pColData, pData, nData);
×
2539
    }
2540
  }
2541
  return 0;
×
2542
}
2543
static FORCE_INLINE int32_t tColDataUpdateNothing(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
15,515✔
2544
  return 0;
15,515✔
2545
}
2546
static int32_t (*tColDataUpdateValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) = {
2547
    {NULL, NULL, NULL},                                                     // 0
2548
    {tColDataUpdateValue10, tColDataUpdateNothing, tColDataUpdateValue12},  // HAS_NONE
2549
    {tColDataUpdateValue20, tColDataUpdateNothing, tColDataUpdateNothing},  // HAS_NULL
2550
    {tColDataUpdateValue30, tColDataUpdateNothing, tColDataUpdateValue32},  // HAS_NULL|HAS_NONE
2551
    {tColDataUpdateValue40, tColDataUpdateNothing, tColDataUpdateValue42},  // HAS_VALUE
2552
    {tColDataUpdateValue50, tColDataUpdateNothing, tColDataUpdateValue52},  // HAS_VALUE|HAS_NONE
2553
    {tColDataUpdateValue60, tColDataUpdateNothing, tColDataUpdateValue62},  // HAS_VALUE|HAS_NULL
2554
    {tColDataUpdateValue70, tColDataUpdateNothing, tColDataUpdateValue72},  // HAS_VALUE|HAS_NULL|HAS_NONE
2555

2556
    //    VALUE             NONE        NULL
2557
};
2558
int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward) {
6,325,242✔
2559
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
6,325,242!
2560
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
6,325,639!
2561

2562
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
6,325,639!
2563

2564
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
6,325,639✔
2565
      pColData, IS_VAR_DATA_TYPE(pColData->type) ? pColVal->value.pData : (uint8_t *)&pColVal->value.val,
6,325,639!
2566
      pColVal->value.nData, forward);
2567
}
2568

2569
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
87,295,954✔
2570
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
87,295,954✔
2571
}
87,295,954✔
2572
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
1,569,150✔
2573
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
1,569,150✔
2574
}
1,569,150✔
2575
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
10,994✔
2576
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2577
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
10,994!
2578
    case 0:
1,000✔
2579
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,000✔
2580
      break;
1,000✔
2581
    case 1:
9,996✔
2582
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
9,996✔
2583
      break;
9,996✔
2584
    default:
×
2585
      break;
×
2586
  }
2587
}
10,994✔
2588
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
2589
  SValue value = {.type = pColData->type};
2,147,483,647✔
2590
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2591
    if (iVal + 1 < pColData->nVal) {
197,690,517!
2592
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
204,347,693✔
2593
    } else {
2594
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2595
    }
2596
    value.pData = pColData->pData + pColData->aOffset[iVal];
197,690,517✔
2597
  } else {
2598
    (void)memcpy(&value.val, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
2599
                 tDataTypes[pColData->type].bytes);
2,147,483,647✔
2600
  }
2601
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
2602
}
203,571,589✔
2603
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
9,061,319✔
2604
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2605
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
9,061,319!
2606
    case 0:
4,561,510✔
2607
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
4,561,510✔
2608
      break;
4,561,510✔
2609
    case 1:
4,622,007✔
2610
      tColDataGetValue4(pColData, iVal, pColVal);
2611
      break;
4,622,007✔
2612
    default:
×
2613
      break;
×
2614
  }
2615
}
9,061,319✔
2616
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
210,361,250✔
2617
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2618
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
210,361,250!
2619
    case 0:
11,981,422✔
2620
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
11,981,422✔
2621
      break;
11,981,422✔
2622
    case 1:
198,949,581✔
2623
      tColDataGetValue4(pColData, iVal, pColVal);
2624
      break;
198,949,581✔
2625
    default:
×
2626
      break;
×
2627
  }
2628
}
210,361,250✔
2629
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
11✔
2630
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
2631
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
11!
2632
    case 0:
5✔
2633
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
5✔
2634
      break;
5✔
2635
    case 1:
5✔
2636
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
5✔
2637
      break;
5✔
2638
    case 2:
1!
2639
      tColDataGetValue4(pColData, iVal, pColVal);
2640
      break;
1✔
2641
    default:
×
2642
      break;
×
2643
  }
2644
}
11✔
2645
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2646
    NULL,               // 0
2647
    tColDataGetValue1,  // HAS_NONE
2648
    tColDataGetValue2,  // HAS_NULL
2649
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2650
    tColDataGetValue4,  // HAS_VALUE
2651
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2652
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2653
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2654
};
2655
void tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
2656
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
2657
}
2,147,483,647✔
2658

2659
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
596,140,275✔
2660
  switch (pColData->flag) {
596,140,275!
2661
    case HAS_NONE:
×
2662
      return 0;
×
2663
    case HAS_NULL:
×
2664
      return 1;
×
2665
    case (HAS_NULL | HAS_NONE):
11,000✔
2666
      return GET_BIT1(pColData->pBitMap, iVal);
11,000✔
2667
    case HAS_VALUE:
×
2668
      return 2;
×
2669
    case (HAS_VALUE | HAS_NONE):
10,027,273✔
2670
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
10,027,273✔
2671
    case (HAS_VALUE | HAS_NULL):
586,120,285✔
2672
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
586,120,285✔
2673
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2674
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
2675
    default:
×
2676
      return 0;
×
2677
  }
2678
}
2679

2680
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg) {
450✔
2681
  int32_t code = 0;
450✔
2682

2683
  *pColData = *pColDataFrom;
450✔
2684

2685
  // bitmap
2686
  switch (pColData->flag) {
450!
2687
    case (HAS_NULL | HAS_NONE):
14✔
2688
    case (HAS_VALUE | HAS_NONE):
2689
    case (HAS_VALUE | HAS_NULL):
2690
      pColData->pBitMap = xMalloc(arg, BIT1_SIZE(pColData->nVal));
14✔
2691
      if (pColData->pBitMap == NULL) {
14!
2692
        code = TSDB_CODE_OUT_OF_MEMORY;
×
2693
        goto _exit;
×
2694
      }
2695
      (void)memcpy(pColData->pBitMap, pColDataFrom->pBitMap, BIT1_SIZE(pColData->nVal));
14✔
2696
      break;
14✔
2697
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2698
      pColData->pBitMap = xMalloc(arg, BIT2_SIZE(pColData->nVal));
×
2699
      if (pColData->pBitMap == NULL) {
×
2700
        code = TSDB_CODE_OUT_OF_MEMORY;
×
2701
        goto _exit;
×
2702
      }
2703
      (void)memcpy(pColData->pBitMap, pColDataFrom->pBitMap, BIT2_SIZE(pColData->nVal));
×
2704
      break;
×
2705
    default:
436✔
2706
      pColData->pBitMap = NULL;
436✔
2707
      break;
436✔
2708
  }
2709

2710
  // offset
2711
  if (IS_VAR_DATA_TYPE(pColData->type) && (pColData->flag & HAS_VALUE)) {
450!
2712
    pColData->aOffset = xMalloc(arg, pColData->nVal << 2);
104✔
2713
    if (pColData->aOffset == NULL) {
104!
2714
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2715
      goto _exit;
×
2716
    }
2717
    (void)memcpy(pColData->aOffset, pColDataFrom->aOffset, pColData->nVal << 2);
104✔
2718
  } else {
2719
    pColData->aOffset = NULL;
346✔
2720
  }
2721

2722
  // value
2723
  if (pColData->nData) {
450✔
2724
    pColData->pData = xMalloc(arg, pColData->nData);
362✔
2725
    if (pColData->pData == NULL) {
362!
2726
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2727
      goto _exit;
×
2728
    }
2729

2730
    (void)memcpy(pColData->pData, pColDataFrom->pData, pColData->nData);
362✔
2731
  } else {
2732
    pColData->pData = NULL;
88✔
2733
  }
2734

2735
_exit:
450✔
2736
  return code;
450✔
2737
}
2738

2739
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
2,653,376✔
2740
  int32_t code;
2741
  SBuffer local;
2742

2743
  if (!(colData->nVal > 0)) {
2,653,376!
2744
    return TSDB_CODE_INVALID_PARA;
×
2745
  }
2746

2747
  (*info) = (SColDataCompressInfo){
2,653,376✔
2748
      .cmprAlg = info->cmprAlg,
2,653,376✔
2749
      .columnFlag = colData->cflag,
2,653,376✔
2750
      .flag = colData->flag,
2,653,376✔
2751
      .dataType = colData->type,
2,653,376✔
2752
      .columnId = colData->cid,
2,653,376✔
2753
      .numOfData = colData->nVal,
2,653,376✔
2754
  };
2755

2756
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
2,653,376!
2757
    return 0;
139,118✔
2758
  }
2759

2760
  tBufferInit(&local);
2761
  if (assist == NULL) {
2,514,258!
2762
    assist = &local;
×
2763
  }
2764

2765
  // bitmap
2766
  if (colData->flag != HAS_VALUE) {
2,514,258✔
2767
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
330,899✔
2768
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
1✔
2769
    } else {
2770
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
330,898✔
2771
    }
2772

2773
    SCompressInfo cinfo = {
330,899✔
2774
        .dataType = TSDB_DATA_TYPE_TINYINT,
2775
        .cmprAlg = info->cmprAlg,
330,899✔
2776
        .originalSize = info->bitmapOriginalSize,
330,899✔
2777
    };
2778

2779
    code = tCompressDataToBuffer(colData->pBitMap, &cinfo, output, assist);
330,899✔
2780
    if (code) {
330,992!
2781
      tBufferDestroy(&local);
2782
      return code;
×
2783
    }
2784

2785
    info->bitmapCompressedSize = cinfo.compressedSize;
330,992✔
2786
  }
2787

2788
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
2,514,351✔
2789
    tBufferDestroy(&local);
2790
    return 0;
601✔
2791
  }
2792

2793
  // offset
2794
  if (IS_VAR_DATA_TYPE(colData->type)) {
2,513,750!
2795
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
341,505✔
2796

2797
    SCompressInfo cinfo = {
341,505✔
2798
        .dataType = TSDB_DATA_TYPE_INT,
2799
        .cmprAlg = info->cmprAlg,
341,505✔
2800
        .originalSize = info->offsetOriginalSize,
341,505✔
2801
    };
2802

2803
    code = tCompressDataToBuffer(colData->aOffset, &cinfo, output, assist);
341,505✔
2804
    if (code) {
341,502!
2805
      tBufferDestroy(&local);
2806
      return code;
×
2807
    }
2808

2809
    info->offsetCompressedSize = cinfo.compressedSize;
341,502✔
2810
  }
2811

2812
  // data
2813
  if (colData->nData > 0) {
2,513,747✔
2814
    info->dataOriginalSize = colData->nData;
2,513,665✔
2815

2816
    SCompressInfo cinfo = {
2,513,665✔
2817
        .dataType = colData->type,
2,513,665✔
2818
        .cmprAlg = info->cmprAlg,
2,513,665✔
2819
        .originalSize = info->dataOriginalSize,
2,513,665✔
2820
    };
2821

2822
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
2,513,665✔
2823
    if (code) {
2,513,902!
2824
      tBufferDestroy(&local);
2825
      return code;
×
2826
    }
2827

2828
    info->dataCompressedSize = cinfo.compressedSize;
2,513,902✔
2829
  }
2830

2831
  tBufferDestroy(&local);
2832
  return 0;
2,513,984✔
2833
}
2834

2835
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
19,148,203✔
2836
  int32_t  code;
2837
  SBuffer  local;
2838
  uint8_t *data = (uint8_t *)input;
19,148,203✔
2839

2840
  tBufferInit(&local);
2841
  if (assist == NULL) {
19,148,203!
2842
    assist = &local;
×
2843
  }
2844

2845
  tColDataClear(colData);
19,148,203✔
2846
  colData->cid = info->columnId;
19,147,001✔
2847
  colData->type = info->dataType;
19,147,001✔
2848
  colData->cflag = info->columnFlag;
19,147,001✔
2849
  colData->nVal = info->numOfData;
19,147,001✔
2850
  colData->flag = info->flag;
19,147,001✔
2851

2852
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
19,147,001✔
2853
    goto _exit;
2,773,207✔
2854
  }
2855

2856
  // bitmap
2857
  if (info->bitmapOriginalSize > 0) {
16,373,794✔
2858
    SCompressInfo cinfo = {
1,026,960✔
2859
        .dataType = TSDB_DATA_TYPE_TINYINT,
2860
        .cmprAlg = info->cmprAlg,
1,026,960✔
2861
        .originalSize = info->bitmapOriginalSize,
1,026,960✔
2862
        .compressedSize = info->bitmapCompressedSize,
1,026,960✔
2863
    };
2864

2865
    code = tRealloc(&colData->pBitMap, cinfo.originalSize);
1,026,960!
2866
    if (code) {
1,026,950!
2867
      tBufferDestroy(&local);
2868
      return code;
×
2869
    }
2870

2871
    code = tDecompressData(data, &cinfo, colData->pBitMap, cinfo.originalSize, assist);
1,026,950✔
2872
    if (code) {
1,026,763!
2873
      tBufferDestroy(&local);
2874
      return code;
×
2875
    }
2876

2877
    data += cinfo.compressedSize;
1,026,763✔
2878
  }
2879

2880
  if (info->flag == (HAS_NONE | HAS_NULL)) {
16,373,597✔
2881
    goto _exit;
600✔
2882
  }
2883

2884
  // offset
2885
  if (info->offsetOriginalSize > 0) {
16,372,997✔
2886
    SCompressInfo cinfo = {
2,597,761✔
2887
        .cmprAlg = info->cmprAlg,
2,597,761✔
2888
        .dataType = TSDB_DATA_TYPE_INT,
2889
        .originalSize = info->offsetOriginalSize,
2,597,761✔
2890
        .compressedSize = info->offsetCompressedSize,
2,597,761✔
2891
    };
2892

2893
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
2,597,761!
2894
    if (code) {
2,597,926!
2895
      tBufferDestroy(&local);
2896
      return code;
×
2897
    }
2898

2899
    code = tDecompressData(data, &cinfo, colData->aOffset, cinfo.originalSize, assist);
2,597,926✔
2900
    if (code) {
2,597,901!
2901
      tBufferDestroy(&local);
2902
      return code;
×
2903
    }
2904

2905
    data += cinfo.compressedSize;
2,597,901✔
2906
  }
2907

2908
  // data
2909
  if (info->dataOriginalSize > 0) {
16,373,137✔
2910
    colData->nData = info->dataOriginalSize;
16,371,857✔
2911

2912
    SCompressInfo cinfo = {
16,371,857✔
2913
        .cmprAlg = info->cmprAlg,
16,371,857✔
2914
        .dataType = colData->type,
16,371,857✔
2915
        .originalSize = info->dataOriginalSize,
16,371,857✔
2916
        .compressedSize = info->dataCompressedSize,
16,371,857✔
2917
    };
2918

2919
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
16,371,857!
2920
    if (code) {
16,373,262!
2921
      tBufferDestroy(&local);
2922
      return code;
×
2923
    }
2924

2925
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
16,373,262✔
2926
    if (code) {
16,372,835!
2927
      tBufferDestroy(&local);
2928
      return code;
×
2929
    }
2930

2931
    data += cinfo.compressedSize;
16,372,835✔
2932
  }
2933

2934
_exit:
1,280✔
2935
  switch (colData->flag) {
19,147,922✔
2936
    case HAS_NONE:
2,508,833✔
2937
      colData->numOfNone = colData->nVal;
2,508,833✔
2938
      break;
2,508,833✔
2939
    case HAS_NULL:
267,781✔
2940
      colData->numOfNull = colData->nVal;
267,781✔
2941
      break;
267,781✔
2942
    case HAS_VALUE:
15,346,081✔
2943
      colData->numOfValue = colData->nVal;
15,346,081✔
2944
      break;
15,346,081✔
2945
    default:
1,025,227✔
2946
      for (int32_t i = 0; i < colData->nVal; i++) {
328,491,151✔
2947
        uint8_t bitValue = tColDataGetBitValue(colData, i);
327,466,330✔
2948
        if (bitValue == 0) {
327,465,924✔
2949
          colData->numOfNone++;
4,855,733✔
2950
        } else if (bitValue == 1) {
322,610,191✔
2951
          colData->numOfNull++;
23,356,065✔
2952
        } else {
2953
          colData->numOfValue++;
299,254,126✔
2954
        }
2955
      }
2956
  }
2957
  tBufferDestroy(&local);
2958
  return 0;
19,147,516✔
2959
}
2960

2961
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
574✔
2962
                                    char *data) {
2963
  int32_t code = 0;
574✔
2964
  if (data == NULL) {
574✔
2965
    if (pColData->cflag & COL_IS_KEY) {
13!
2966
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
2967
    } else {
2968
      for (int32_t i = 0; i < nRows; ++i) {
28✔
2969
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
15✔
2970
      }
2971
    }
2972
    goto _exit;
13✔
2973
  }
2974

2975
  if (IS_VAR_DATA_TYPE(type)) {  // var-length data type
561!
2976
    for (int32_t i = 0; i < nRows; ++i) {
271✔
2977
      int32_t offset = *((int32_t *)lengthOrbitmap + i);
171✔
2978
      if (offset == -1) {
171!
2979
        if (pColData->cflag & COL_IS_KEY) {
×
2980
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
2981
          goto _exit;
×
2982
        }
2983
        if ((code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0))) {
×
2984
          goto _exit;
×
2985
        }
2986
      } else {
2987
        if (varDataTLen(data + offset) > bytes) {
171!
2988
          uError("var data length invalid, varDataTLen(data + offset):%d > bytes:%d", (int)varDataTLen(data + offset),
×
2989
                 bytes);
2990
          code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
2991
          goto _exit;
×
2992
        }
2993
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)varDataVal(data + offset),
171✔
2994
                                                                      varDataLen(data + offset));
171✔
2995
      }
2996
    }
2997
  } else {  // fixed-length data type
2998
    bool allValue = true;
461✔
2999
    bool allNull = true;
461✔
3000
    for (int32_t i = 0; i < nRows; ++i) {
1,266✔
3001
      if (!colDataIsNull_f(lengthOrbitmap, i)) {
805✔
3002
        allNull = false;
592✔
3003
      } else {
3004
        allValue = false;
213✔
3005
      }
3006
    }
3007
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
461!
3008
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3009
      goto _exit;
×
3010
    }
3011

3012
    if (allValue) {
461✔
3013
      // optimize (todo)
3014
      for (int32_t i = 0; i < nRows; ++i) {
945✔
3015
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
578✔
3016
      }
3017
    } else if (allNull) {
94✔
3018
      // optimize (todo)
3019
      for (int32_t i = 0; i < nRows; ++i) {
249✔
3020
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
165✔
3021
        if (code) goto _exit;
165!
3022
      }
3023
    } else {
3024
      for (int32_t i = 0; i < nRows; ++i) {
72✔
3025
        if (colDataIsNull_f(lengthOrbitmap, i)) {
62✔
3026
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
48✔
3027
          if (code) goto _exit;
48!
3028
        } else {
3029
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
14✔
3030
        }
3031
      }
3032
    }
3033
  }
3034

3035
_exit:
10✔
3036
  return code;
574✔
3037
}
3038

3039
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
491✔
3040
                               checkWKBGeometryFn cgeos) {
3041
  int32_t code = 0;
491✔
3042

3043
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
491✔
3044
    if (!(pColData->type == pBind->buffer_type)) {
488!
3045
      return TSDB_CODE_INVALID_PARA;
×
3046
    }
3047
  }
3048

3049
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
491!
3050
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
73!
3051
      code = igeos();
×
3052
      if (code) {
×
3053
        return code;
×
3054
      }
3055
    }
3056
    for (int32_t i = 0; i < pBind->num; ++i) {
697✔
3057
      if (pBind->is_null && pBind->is_null[i]) {
623✔
3058
        if (pColData->cflag & COL_IS_KEY) {
1!
3059
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3060
          goto _exit;
×
3061
        }
3062
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
1✔
3063
        if (code) goto _exit;
1!
3064
      } else if (pBind->length[i] > buffMaxLen) {
622!
3065
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3066
      } else {
3067
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
622!
3068
          code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]);
×
3069
          if (code) goto _exit;
×
3070
        }
3071
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
622✔
3072
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
622✔
3073
      }
3074
    }
3075
  } else {  // fixed-length data type
3076
    bool allValue;
3077
    bool allNull;
3078
    if (pBind->is_null) {
418✔
3079
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
367✔
3080
      allNull = (same && pBind->is_null[0] != 0);
367✔
3081
      allValue = (same && pBind->is_null[0] == 0);
367✔
3082
    } else {
3083
      allNull = false;
51✔
3084
      allValue = true;
51✔
3085
    }
3086

3087
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
418!
3088
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3089
      goto _exit;
×
3090
    }
3091

3092
    if (allValue) {
418✔
3093
      // optimize (todo)
3094
      for (int32_t i = 0; i < pBind->num; ++i) {
3,993✔
3095
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
3,565✔
3096
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
3,565✔
3097
      }
3098
    } else if (allNull) {
3✔
3099
      // optimize (todo)
3100
      for (int32_t i = 0; i < pBind->num; ++i) {
4✔
3101
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
2✔
3102
        if (code) goto _exit;
2!
3103
      }
3104
    } else {
3105
      for (int32_t i = 0; i < pBind->num; ++i) {
5✔
3106
        if (pBind->is_null[i]) {
4✔
3107
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
2✔
3108
          if (code) goto _exit;
2!
3109
        } else {
3110
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
2✔
3111
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
2✔
3112
        }
3113
      }
3114
    }
3115
  }
3116

3117
_exit:
1✔
3118
  return code;
505✔
3119
}
3120

3121
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
×
3122
                                checkWKBGeometryFn cgeos) {
3123
  int32_t code = 0;
×
3124

3125
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
×
3126
    if (!(pColData->type == pBind->buffer_type)) {
×
3127
      return TSDB_CODE_INVALID_PARA;
×
3128
    }
3129
  }
3130

3131
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
×
3132
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
3133
      code = igeos();
×
3134
      if (code) {
×
3135
        return code;
×
3136
      }
3137
    }
3138

3139
    uint8_t *buf = pBind->buffer;
×
3140
    for (int32_t i = 0; i < pBind->num; ++i) {
×
3141
      if (pBind->is_null && pBind->is_null[i]) {
×
3142
        if (pColData->cflag & COL_IS_KEY) {
×
3143
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3144
          goto _exit;
×
3145
        }
3146
        if (pBind->is_null[i] == 1) {
×
3147
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3148
          if (code) goto _exit;
×
3149
        } else {
3150
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3151
          if (code) goto _exit;
×
3152
        }
3153
      } else if (pBind->length[i] > buffMaxLen) {
×
3154
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3155
      } else {
3156
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
3157
          code = cgeos(buf, pBind->length[i]);
×
3158
          if (code) goto _exit;
×
3159
        }
3160
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);
×
3161
        buf += pBind->length[i];
×
3162
      }
3163
    }
3164
  } else {  // fixed-length data type
3165
    bool allValue;
3166
    bool allNull;
3167
    bool allNone;
3168
    if (pBind->is_null) {
×
3169
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
×
3170
      allNull = (same && pBind->is_null[0] == 1);
×
3171
      allNone = (same && pBind->is_null[0] > 1);
×
3172
      allValue = (same && pBind->is_null[0] == 0);
×
3173
    } else {
3174
      allNull = false;
×
3175
      allNone = false;
×
3176
      allValue = true;
×
3177
    }
3178

3179
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
×
3180
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3181
      goto _exit;
×
3182
    }
3183

3184
    if (allValue) {
×
3185
      // optimize (todo)
3186
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3187
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3188
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3189
          *val = 1;
×
3190
        }
3191

3192
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3193
      }
3194
    } else if (allNull) {
×
3195
      // optimize (todo)
3196
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3197
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3198
        if (code) goto _exit;
×
3199
      }
3200
    } else if (allNone) {
×
3201
      // optimize (todo)
3202
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3203
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3204
        if (code) goto _exit;
×
3205
      }
3206
    } else {
3207
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3208
        if (pBind->is_null[i]) {
×
3209
          if (pBind->is_null[i] == 1) {
×
3210
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3211
            if (code) goto _exit;
×
3212
          } else {
3213
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3214
            if (code) goto _exit;
×
3215
          }
3216
        } else {
3217
          uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3218
          if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3219
            *val = 1;
×
3220
          }
3221

3222
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3223
        }
3224
      }
3225
    }
3226
  }
3227

3228
_exit:
×
3229
  return code;
×
3230
}
3231

3232
/* build rows to `rowArray` from bind
3233
 * `infos` is the bind information array
3234
 * `numOfInfos` is the number of bind information
3235
 * `infoSorted` is whether the bind information is sorted by column id
3236
 * `pTSchema` is the schema of the table
3237
 * `rowArray` is the array to store the rows
3238
 */
3239
int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
×
3240
                           SArray *rowArray) {
3241
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
×
3242
    return TSDB_CODE_INVALID_PARA;
×
3243
  }
3244

3245
  if (!infoSorted) {
×
3246
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
3247
  }
3248

3249
  int32_t code = 0;
×
3250
  int32_t numOfRows = infos[0].bind->num;
×
3251
  SArray *colValArray, *bufArray;
3252
  SColVal colVal;
3253

3254
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
×
3255
    return terrno;
×
3256
  }
3257
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
×
3258
    taosArrayDestroy(colValArray);
×
3259
    return terrno;
×
3260
  }
3261
  for (int i = 0; i < numOfInfos; ++i) {
×
3262
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
×
3263
      taosArrayDestroy(colValArray);
×
3264
      taosArrayDestroy(bufArray);
×
3265
      return terrno;
×
3266
    }
3267
  }
3268

3269
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
3270
    taosArrayClear(colValArray);
×
3271

3272
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
×
3273
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
×
3274
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
3275
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
3276
        } else {
3277
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3278
        }
3279
      } else {
3280
        SValue value = {
×
3281
            .type = infos[iInfo].type,
×
3282
        };
3283
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
×
3284
          int32_t   length = infos[iInfo].bind->length[iRow];
×
3285
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
×
3286
          value.nData = length;
×
3287
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
×
3288
            code = TSDB_CODE_INVALID_PARA;
×
3289
            goto _exit;
×
3290
          }
3291
          value.pData = *data;
×
3292
          *data += length;
×
3293
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3294
        } else {
3295
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
×
3296
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
×
3297
            *val = 1;
×
3298
          }
3299
          (void)memcpy(&value.val, val,
×
3300
                       /*(uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,*/
3301
                       infos[iInfo].bytes /*bind->buffer_length*/);
×
3302
        }
3303
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
×
3304
      }
3305
      if (taosArrayPush(colValArray, &colVal) == NULL) {
×
3306
        code = terrno;
×
3307
        goto _exit;
×
3308
      }
3309
    }
3310

3311
    SRow *row;
3312
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
×
3313
      goto _exit;
×
3314
    }
3315

3316
    if ((taosArrayPush(rowArray, &row)) == NULL) {
×
3317
      code = terrno;
×
3318
      goto _exit;
×
3319
    }
3320
  }
3321

3322
_exit:
×
3323
  taosArrayDestroy(colValArray);
×
3324
  taosArrayDestroy(bufArray);
×
3325
  return code;
×
3326
}
3327

3328
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
286✔
3329
  int32_t code = TSDB_CODE_SUCCESS;
286✔
3330

3331
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
286!
3332
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
116✔
3333
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
42✔
3334
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
58✔
3335
    if (iToRow == 0) {
58✔
3336
      pToColData->aOffset[iToRow] = 0;
8✔
3337
    }
3338

3339
    if (iToRow < pToColData->nVal - 1) {
58✔
3340
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
52✔
3341
    }
3342

3343
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
58✔
3344
                 nData);
3345
  } else {
3346
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
228✔
3347
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
228✔
3348
  }
3349
  return code;
286✔
3350
}
3351

3352
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
294✔
3353
                                        int32_t iToRow) {
3354
  int32_t code = TSDB_CODE_SUCCESS;
294✔
3355

3356
  switch (pFromColData->flag) {
294!
3357
    case HAS_NONE:
8✔
3358
    case HAS_NULL:
3359
      break;
8✔
3360
    case (HAS_NULL | HAS_NONE): {
×
3361
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
3362
    } break;
×
3363
    case HAS_VALUE: {
238✔
3364
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
238!
3365
    } break;
238✔
3366
    case (HAS_VALUE | HAS_NONE):
48✔
3367
    case (HAS_VALUE | HAS_NULL): {
3368
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
48✔
3369
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
48!
3370
    } break;
48✔
3371
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
3372
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
3373
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3374
    } break;
×
3375
    default:
×
3376
      return -1;
×
3377
  }
3378

3379
  return code;
294✔
3380
}
3381

3382
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
60✔
3383
                               int32_t nColData) {
3384
  int32_t code = TSDB_CODE_SUCCESS;
60✔
3385

3386
  for (int32_t i = 0; i < nColData; i++) {
354✔
3387
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
294✔
3388
    if (code != TSDB_CODE_SUCCESS) {
294!
3389
      return code;
×
3390
    }
3391
  }
3392

3393
  return code;
60✔
3394
}
3395

3396
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
60✔
3397
  int32_t code = TSDB_CODE_SUCCESS;
60✔
3398

3399
  for (int32_t i = 0; i < nColData; i++) {
354✔
3400
    SColVal cv = {0};
294✔
3401
    tColDataGetValue(&aFromColData[i], iFromRow, &cv);
294✔
3402
    code = tColDataAppendValue(&aToColData[i], &cv);
294✔
3403
    if (code != TSDB_CODE_SUCCESS) {
294!
3404
      return code;
×
3405
    }
3406
  }
3407

3408
  return code;
60✔
3409
}
3410

3411
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
1,128✔
3412
  SColVal cv;
3413

3414
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
1,128✔
3415
  key->numOfPKs = 0;
1,128✔
3416

3417
  for (int i = 1; i < nColData; i++) {
1,128!
3418
    if (aColData[i].cflag & COL_IS_KEY) {
1,129!
3419
      tColDataGetValue4(&aColData[i], iRow, &cv);
×
3420
      key->pks[key->numOfPKs++] = cv.value;
×
3421
    } else {
3422
      break;
1,129✔
3423
    }
3424
  }
3425
}
1,128✔
3426

3427
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
17✔
3428
  SColData *aDstColData = NULL;
17✔
3429
  int32_t   i = start, j = mid + 1, k = 0;
17✔
3430
  SRowKey   keyi, keyj;
3431

3432
  if (end > start) {
17!
3433
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
17✔
3434
    if (aDstColData == NULL) {
17!
3435
      return terrno;
×
3436
    }
3437
    for (int c = 0; c < nColData; ++c) {
99✔
3438
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
82✔
3439
    }
3440
  }
3441

3442
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
17✔
3443
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
17✔
3444
  while (i <= mid && j <= end) {
48✔
3445
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
31✔
3446
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
24!
3447
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
24✔
3448
    } else {
3449
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
7!
3450
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
7✔
3451
    }
3452
  }
3453

3454
  while (i <= mid) {
26✔
3455
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
9!
3456
  }
3457

3458
  while (j <= end) {
37✔
3459
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
20!
3460
  }
3461

3462
  for (i = start, k = 0; i <= end; ++i, ++k) {
77✔
3463
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
60!
3464
  }
3465

3466
  if (aDstColData) {
17!
3467
    for (int32_t i = 0; i < nColData; i++) {
99✔
3468
      tColDataDestroy(&aDstColData[i]);
82✔
3469
    }
3470
    taosMemoryFree(aDstColData);
17✔
3471
  }
3472

3473
  return TSDB_CODE_SUCCESS;
17✔
3474
}
3475

3476
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
37✔
3477
  int32_t ret = TSDB_CODE_SUCCESS;
37✔
3478
  int32_t mid;
3479

3480
  if (start >= end) {
37✔
3481
    return TSDB_CODE_SUCCESS;
20✔
3482
  }
3483

3484
  mid = (start + end) / 2;
17✔
3485

3486
  ret = tColDataMergeSort(aColData, start, mid, nColData);
17✔
3487
  if (ret != TSDB_CODE_SUCCESS) {
17!
3488
    return ret;
×
3489
  }
3490

3491
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
17✔
3492
  if (ret != TSDB_CODE_SUCCESS) {
17!
3493
    return ret;
×
3494
  }
3495

3496
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
17✔
3497
}
3498

3499
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
3✔
3500
  int32_t nVal = aColData[0].nVal;
3✔
3501

3502
  if (nVal < 2) return TSDB_CODE_SUCCESS;
3!
3503

3504
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
3✔
3505
}
3506

3507
static int32_t tColDataMerge(SArray **colArr) {
3✔
3508
  int32_t code = 0;
3✔
3509
  SArray *src = *colArr;
3✔
3510
  SArray *dst = NULL;
3✔
3511

3512
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
3✔
3513
  if (dst == NULL) {
3!
3514
    return terrno;
×
3515
  }
3516

3517
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
12✔
3518
    SColData *srcCol = taosArrayGet(src, i);
9✔
3519

3520
    SColData *dstCol = taosArrayReserve(dst, 1);
9✔
3521
    if (dstCol == NULL) {
9!
3522
      code = terrno;
×
3523
      goto _exit;
×
3524
    }
3525
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
9✔
3526
  }
3527

3528
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
3✔
3529
  SRowKey lastKey;
3530
  for (int32_t i = 0; i < numRows; i++) {
9✔
3531
    SRowKey key;
3532
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
3533

3534
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
9!
3535
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3536
        SColData *srcCol = taosArrayGet(src, j);
9✔
3537
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3538

3539
        SColVal cv;
3540
        tColDataGetValue(srcCol, i, &cv);
9✔
3541
        code = tColDataAppendValue(dstCol, &cv);
9✔
3542
        if (code) {
9!
3543
          goto _exit;
×
3544
        }
3545
      }
3546
      lastKey = key;
3✔
3547
    } else {  // update existing row
3548
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3549
        SColData *srcCol = taosArrayGet(src, j);
9✔
3550
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3551

3552
        SColVal cv;
3553
        tColDataGetValue(srcCol, i, &cv);
9✔
3554
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3555
        if (code) {
9!
3556
          goto _exit;
×
3557
        }
3558
      }
3559
    }
3560
  }
3561

3562
_exit:
3✔
3563
  if (code) {
3!
3564
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3565
  } else {
3566
    taosArrayDestroyEx(src, tColDataDestroy);
3✔
3567
    *colArr = dst;
3✔
3568
  }
3569
  return code;
3✔
3570
}
3571

3572
int32_t tColDataSortMerge(SArray **arr) {
158✔
3573
  SArray   *colDataArr = *arr;
158✔
3574
  int32_t   nColData = TARRAY_SIZE(colDataArr);
158✔
3575
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
158✔
3576

3577
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
158!
3578
    return TSDB_CODE_INVALID_PARA;
×
3579
  }
3580
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
158!
3581
    return TSDB_CODE_INVALID_PARA;
×
3582
  }
3583
  if (!(aColData[0].flag == HAS_VALUE)) {
158!
3584
    return TSDB_CODE_INVALID_PARA;
×
3585
  }
3586

3587
  if (aColData[0].nVal <= 1) goto _exit;
158✔
3588

3589
  int8_t doSort = 0;
62✔
3590
  int8_t doMerge = 0;
62✔
3591
  // scan -------
3592
  SRowKey lastKey;
3593
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
62✔
3594
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
410✔
3595
    SRowKey key;
3596
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
353✔
3597

3598
    int32_t c = tRowKeyCompare(&lastKey, &key);
349✔
3599
    if (c < 0) {
349✔
3600
      lastKey = key;
339✔
3601
      continue;
339✔
3602
    } else if (c > 0) {
10✔
3603
      doSort = 1;
3✔
3604
      break;
3✔
3605
    } else {
3606
      doMerge = 1;
7✔
3607
    }
3608
  }
3609

3610
  // sort -------
3611
  if (doSort) {
60✔
3612
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
3!
3613
  }
3614

3615
  if (doMerge != 1) {
69✔
3616
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
62✔
3617
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
414✔
3618
      SRowKey key;
3619
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
357✔
3620

3621
      int32_t c = tRowKeyCompare(&lastKey, &key);
353✔
3622
      if (c == 0) {
353!
3623
        doMerge = 1;
×
3624
        break;
×
3625
      }
3626
      lastKey = key;
353✔
3627
    }
3628
  }
3629

3630
  // merge -------
3631
  if (doMerge) {
64✔
3632
    int32_t code = tColDataMerge(arr);
3✔
3633
    if (code) return code;
3!
3634
  }
3635

3636
_exit:
64✔
3637
  return 0;
160✔
3638
}
3639

3640
static int32_t tPutColDataVersion0(uint8_t *pBuf, SColData *pColData) {
1,964✔
3641
  int32_t n = 0;
1,964✔
3642

3643
  n += tPutI16v(pBuf ? pBuf + n : NULL, pColData->cid);
1,964✔
3644
  n += tPutI8(pBuf ? pBuf + n : NULL, pColData->type);
1,964✔
3645
  n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nVal);
1,964✔
3646
  n += tPutI8(pBuf ? pBuf + n : NULL, pColData->flag);
1,964✔
3647

3648
  // bitmap
3649
  switch (pColData->flag) {
1,964!
3650
    case (HAS_NULL | HAS_NONE):
28✔
3651
    case (HAS_VALUE | HAS_NONE):
3652
    case (HAS_VALUE | HAS_NULL):
3653
      if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
28✔
3654
      n += BIT1_SIZE(pColData->nVal);
28✔
3655
      break;
28✔
3656
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3657
      if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
3658
      n += BIT2_SIZE(pColData->nVal);
×
3659
      break;
×
3660
    default:
1,936✔
3661
      break;
1,936✔
3662
  }
3663

3664
  // value
3665
  if (pColData->flag & HAS_VALUE) {
1,964✔
3666
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,791!
3667
      if (pBuf) (void)memcpy(pBuf + n, pColData->aOffset, pColData->nVal << 2);
315✔
3668
      n += (pColData->nVal << 2);
315✔
3669

3670
      n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nData);
315✔
3671
      if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
315✔
3672
      n += pColData->nData;
315✔
3673
    } else {
3674
      if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
1,476✔
3675
      n += pColData->nData;
1,476✔
3676
    }
3677
  }
3678

3679
  return n;
1,964✔
3680
}
3681

3682
static int32_t tGetColDataVersion0(uint8_t *pBuf, SColData *pColData) {
2,016✔
3683
  int32_t n = 0;
2,016✔
3684

3685
  n += tGetI16v(pBuf + n, &pColData->cid);
2,016!
3686
  n += tGetI8(pBuf + n, &pColData->type);
2,016!
3687
  n += tGetI32v(pBuf + n, &pColData->nVal);
2,016!
3688
  n += tGetI8(pBuf + n, &pColData->flag);
2,016!
3689

3690
  // bitmap
3691
  switch (pColData->flag) {
2,016!
3692
    case (HAS_NULL | HAS_NONE):
52✔
3693
    case (HAS_VALUE | HAS_NONE):
3694
    case (HAS_VALUE | HAS_NULL):
3695
      pColData->pBitMap = pBuf + n;
52✔
3696
      n += BIT1_SIZE(pColData->nVal);
52✔
3697
      break;
52✔
3698
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3699
      pColData->pBitMap = pBuf + n;
×
3700
      n += BIT2_SIZE(pColData->nVal);
×
3701
      break;
×
3702
    default:
1,964✔
3703
      break;
1,964✔
3704
  }
3705

3706
  // value
3707
  if (pColData->flag & HAS_VALUE) {
2,016✔
3708
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,821!
3709
      pColData->aOffset = (int32_t *)(pBuf + n);
378✔
3710
      n += (pColData->nVal << 2);
378✔
3711

3712
      n += tGetI32v(pBuf + n, &pColData->nData);
378✔
3713
      pColData->pData = pBuf + n;
378✔
3714
      n += pColData->nData;
378✔
3715
    } else {
3716
      pColData->pData = pBuf + n;
1,443✔
3717
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
1,443✔
3718
      n += pColData->nData;
1,443✔
3719
    }
3720
  }
3721
  pColData->cflag = 0;
2,016✔
3722

3723
  return n;
2,016✔
3724
}
3725

3726
static int32_t tPutColDataVersion1(uint8_t *pBuf, SColData *pColData) {
1,966✔
3727
  int32_t n = tPutColDataVersion0(pBuf, pColData);
1,966✔
3728
  n += tPutI8(pBuf ? pBuf + n : NULL, pColData->cflag);
1,967✔
3729
  return n;
1,967✔
3730
}
3731

3732
static int32_t tGetColDataVersion1(uint8_t *pBuf, SColData *pColData) {
2,016✔
3733
  int32_t n = tGetColDataVersion0(pBuf, pColData);
2,016✔
3734
  n += tGetI8(pBuf ? pBuf + n : NULL, &pColData->cflag);
2,016!
3735
  return n;
2,016✔
3736
}
3737

3738
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
1,965✔
3739
  if (version == 0) {
1,965!
3740
    return tPutColDataVersion0(pBuf, pColData);
×
3741
  } else if (version == 1) {
1,965!
3742
    return tPutColDataVersion1(pBuf, pColData);
1,965✔
3743
  } else {
3744
    return TSDB_CODE_INVALID_PARA;
×
3745
  }
3746
}
3747

3748
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
2,015✔
3749
  if (version == 0) {
2,015!
3750
    return tGetColDataVersion0(pBuf, pColData);
×
3751
  } else if (version == 1) {
2,015!
3752
    return tGetColDataVersion1(pBuf, pColData);
2,016✔
3753
  } else {
3754
    return TSDB_CODE_INVALID_PARA;
×
3755
  }
3756
}
3757

3758
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3759
  do {                                       \
3760
    (SUM) += (VAL);                          \
3761
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3762
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3763
  } while (0)
3764

3765
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
7,136✔
3766
                                             int16_t *numOfNull) {
3767
  *sum = 0;
7,136✔
3768
  *max = 0;
7,136✔
3769
  *min = 1;
7,136✔
3770
  *numOfNull = 0;
7,136✔
3771

3772
  int8_t val;
3773
  if (HAS_VALUE == pColData->flag) {
7,136✔
3774
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,249,074✔
3775
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,243,403✔
3776
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,243,403✔
3777
    }
3778
  } else {
3779
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
3780
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
3781
        case 0:
235,846✔
3782
        case 1:
3783
          (*numOfNull)++;
235,846✔
3784
          break;
235,846✔
3785
        case 2:
4,491,425✔
3786
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,491,425✔
3787
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,491,425✔
3788
          break;
4,491,425✔
3789
        default:
×
3790
          break;
×
3791
      }
3792
    }
3793
  }
3794
}
7,136✔
3795

3796
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
7,171✔
3797
                                                int16_t *numOfNull) {
3798
  *sum = 0;
7,171✔
3799
  *max = INT8_MIN;
7,171✔
3800
  *min = INT8_MAX;
7,171✔
3801
  *numOfNull = 0;
7,171✔
3802

3803
  int8_t val;
3804
  if (HAS_VALUE == pColData->flag) {
7,171✔
3805
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,368,516✔
3806
      val = ((int8_t *)pColData->pData)[iVal];
4,362,810✔
3807
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,362,810✔
3808
    }
3809
  } else {
3810
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
3811
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
3812
        case 0:
235,236✔
3813
        case 1:
3814
          (*numOfNull)++;
235,236✔
3815
          break;
235,236✔
3816
        case 2:
4,492,035✔
3817
          val = ((int8_t *)pColData->pData)[iVal];
4,492,035✔
3818
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,492,035✔
3819
          break;
4,492,035✔
3820
        default:
×
3821
          break;
×
3822
      }
3823
    }
3824
  }
3825
}
7,171✔
3826

3827
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
7,172✔
3828
                                                     int16_t *numOfNull) {
3829
  *sum = 0;
7,172✔
3830
  *max = INT16_MIN;
7,172✔
3831
  *min = INT16_MAX;
7,172✔
3832
  *numOfNull = 0;
7,172✔
3833

3834
  int16_t val;
3835
  if (HAS_VALUE == pColData->flag) {
7,172✔
3836
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,368,466✔
3837
      val = ((int16_t *)pColData->pData)[iVal];
4,362,759✔
3838
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,362,759✔
3839
    }
3840
  } else {
3841
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
3842
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
3843
        case 0:
236,467✔
3844
        case 1:
3845
          (*numOfNull)++;
236,467✔
3846
          break;
236,467✔
3847
        case 2:
4,490,804✔
3848
          val = ((int16_t *)pColData->pData)[iVal];
4,490,804✔
3849
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,490,804✔
3850
          break;
4,490,804✔
3851
        default:
×
3852
          break;
×
3853
      }
3854
    }
3855
  }
3856
}
7,172✔
3857

3858
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
245,199✔
3859
                                            int16_t *numOfNull) {
3860
  *sum = 0;
245,199✔
3861
  *max = INT32_MIN;
245,199✔
3862
  *min = INT32_MAX;
245,199✔
3863
  *numOfNull = 0;
245,199✔
3864

3865
  int32_t val;
3866
  if (HAS_VALUE == pColData->flag) {
245,199✔
3867
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
742,100,164✔
3868
      val = ((int32_t *)pColData->pData)[iVal];
741,885,865✔
3869
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
741,885,865✔
3870
    }
3871
  } else {
3872
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
87,143,330✔
3873
      switch (tColDataGetBitValue(pColData, iVal)) {
87,128,158!
3874
        case 0:
5,122,442✔
3875
        case 1:
3876
          (*numOfNull)++;
5,122,442✔
3877
          break;
5,122,442✔
3878
        case 2:
82,019,692✔
3879
          val = ((int32_t *)pColData->pData)[iVal];
82,019,692✔
3880
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
82,019,692✔
3881
          break;
82,019,692✔
3882
        default:
×
3883
          break;
×
3884
      }
3885
    }
3886
  }
3887
}
229,471✔
3888

3889
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
78,861✔
3890
                                               int16_t *numOfNull) {
3891
  *sum = 0;
78,861✔
3892
  *max = INT64_MIN;
78,861✔
3893
  *min = INT64_MAX;
78,861✔
3894
  *numOfNull = 0;
78,861✔
3895

3896
  int64_t val;
3897
  if (HAS_VALUE == pColData->flag) {
78,861✔
3898
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
203,638,582✔
3899
      val = ((int64_t *)pColData->pData)[iVal];
203,565,323✔
3900
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
203,565,323✔
3901
    }
3902
  } else {
3903
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
19,787,043✔
3904
      switch (tColDataGetBitValue(pColData, iVal)) {
19,781,546!
3905
        case 0:
1,804,846✔
3906
        case 1:
3907
          (*numOfNull)++;
1,804,846✔
3908
          break;
1,804,846✔
3909
        case 2:
17,978,351✔
3910
          val = ((int64_t *)pColData->pData)[iVal];
17,978,351✔
3911
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
17,978,351✔
3912
          break;
17,978,351✔
3913
        default:
×
3914
          break;
×
3915
      }
3916
    }
3917
  }
3918
}
78,756✔
3919

3920
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
191,457✔
3921
                                              int16_t *numOfNull) {
3922
  *(double *)sum = 0;
191,457✔
3923
  *(double *)max = -FLT_MAX;
191,457✔
3924
  *(double *)min = FLT_MAX;
191,457✔
3925
  *numOfNull = 0;
191,457✔
3926

3927
  float val;
3928
  if (HAS_VALUE == pColData->flag) {
191,457✔
3929
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
758,294,886✔
3930
      val = ((float *)pColData->pData)[iVal];
758,104,895✔
3931
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
758,104,895✔
3932
    }
3933
  } else {
3934
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,842✔
3935
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,376!
3936
        case 0:
236,861✔
3937
        case 1:
3938
          (*numOfNull)++;
236,861✔
3939
          break;
236,861✔
3940
        case 2:
4,490,515✔
3941
          val = ((float *)pColData->pData)[iVal];
4,490,515✔
3942
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,490,515✔
3943
          break;
4,490,515✔
3944
        default:
×
3945
          break;
×
3946
      }
3947
    }
3948
  }
3949
}
191,457✔
3950

3951
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
7,827✔
3952
                                               int16_t *numOfNull) {
3953
  *(double *)sum = 0;
7,827✔
3954
  *(double *)max = -DBL_MAX;
7,827✔
3955
  *(double *)min = DBL_MAX;
7,827✔
3956
  *numOfNull = 0;
7,827✔
3957

3958
  double val;
3959
  if (HAS_VALUE == pColData->flag) {
7,827✔
3960
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,602,606✔
3961
      val = ((double *)pColData->pData)[iVal];
9,596,244✔
3962
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
9,596,244✔
3963
    }
3964
  } else {
3965
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
3966
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
3967
        case 0:
236,388✔
3968
        case 1:
3969
          (*numOfNull)++;
236,388✔
3970
          break;
236,388✔
3971
        case 2:
4,490,883✔
3972
          val = ((double *)pColData->pData)[iVal];
4,490,883✔
3973
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,490,883✔
3974
          break;
4,490,883✔
3975
        default:
×
3976
          break;
×
3977
      }
3978
    }
3979
  }
3980
}
7,827✔
3981

3982
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
4,257✔
3983
                                                 int16_t *numOfNull) {
3984
  *(uint64_t *)sum = 0;
4,257✔
3985
  *(uint64_t *)max = 0;
4,257✔
3986
  *(uint64_t *)min = UINT8_MAX;
4,257✔
3987
  *numOfNull = 0;
4,257✔
3988

3989
  uint8_t val;
3990
  if (HAS_VALUE == pColData->flag) {
4,257✔
3991
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,482,767✔
3992
      val = ((uint8_t *)pColData->pData)[iVal];
3,479,975✔
3993
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,479,975✔
3994
    }
3995
  } else {
3996
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
3997
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
3998
        case 0:
235,937✔
3999
        case 1:
4000
          (*numOfNull)++;
235,937✔
4001
          break;
235,937✔
4002
        case 2:
4,491,334✔
4003
          val = ((uint8_t *)pColData->pData)[iVal];
4,491,334✔
4004
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,491,334✔
4005
          break;
4,491,334✔
4006
        default:
×
4007
          break;
×
4008
      }
4009
    }
4010
  }
4011
}
4,257✔
4012

4013
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
4,257✔
4014
                                                      int16_t *numOfNull) {
4015
  *(uint64_t *)sum = 0;
4,257✔
4016
  *(uint64_t *)max = 0;
4,257✔
4017
  *(uint64_t *)min = UINT16_MAX;
4,257✔
4018
  *numOfNull = 0;
4,257✔
4019

4020
  uint16_t val;
4021
  if (HAS_VALUE == pColData->flag) {
4,257✔
4022
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,484,562✔
4023
      val = ((uint16_t *)pColData->pData)[iVal];
3,481,770✔
4024
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,481,770✔
4025
    }
4026
  } else {
4027
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
4028
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
4029
        case 0:
235,289✔
4030
        case 1:
4031
          (*numOfNull)++;
235,289✔
4032
          break;
235,289✔
4033
        case 2:
4,491,982✔
4034
          val = ((uint16_t *)pColData->pData)[iVal];
4,491,982✔
4035
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,491,982✔
4036
          break;
4,491,982✔
4037
        default:
×
4038
          break;
×
4039
      }
4040
    }
4041
  }
4042
}
4,257✔
4043

4044
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
4,257✔
4045
                                             int16_t *numOfNull) {
4046
  *(uint64_t *)sum = 0;
4,257✔
4047
  *(uint64_t *)max = 0;
4,257✔
4048
  *(uint64_t *)min = UINT32_MAX;
4,257✔
4049
  *numOfNull = 0;
4,257✔
4050

4051
  uint32_t val;
4052
  if (HAS_VALUE == pColData->flag) {
4,257✔
4053
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,484,562✔
4054
      val = ((uint32_t *)pColData->pData)[iVal];
3,481,770✔
4055
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,481,770✔
4056
    }
4057
  } else {
4058
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
4059
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
4060
        case 0:
236,310✔
4061
        case 1:
4062
          (*numOfNull)++;
236,310✔
4063
          break;
236,310✔
4064
        case 2:
4,490,961✔
4065
          val = ((uint32_t *)pColData->pData)[iVal];
4,490,961✔
4066
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,490,961✔
4067
          break;
4,490,961✔
4068
        default:
×
4069
          break;
×
4070
      }
4071
    }
4072
  }
4073
}
4,257✔
4074

4075
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
4,257✔
4076
                                                int16_t *numOfNull) {
4077
  *(uint64_t *)sum = 0;
4,257✔
4078
  *(uint64_t *)max = 0;
4,257✔
4079
  *(uint64_t *)min = UINT64_MAX;
4,257✔
4080
  *numOfNull = 0;
4,257✔
4081

4082
  uint64_t val;
4083
  if (HAS_VALUE == pColData->flag) {
4,257✔
4084
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,483,412✔
4085
      val = ((uint64_t *)pColData->pData)[iVal];
3,480,620✔
4086
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,480,620✔
4087
    }
4088
  } else {
4089
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,728,736✔
4090
      switch (tColDataGetBitValue(pColData, iVal)) {
4,727,271!
4091
        case 0:
237,663✔
4092
        case 1:
4093
          (*numOfNull)++;
237,663✔
4094
          break;
237,663✔
4095
        case 2:
4,489,608✔
4096
          val = ((uint64_t *)pColData->pData)[iVal];
4,489,608✔
4097
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,489,608✔
4098
          break;
4,489,608✔
4099
        default:
×
4100
          break;
×
4101
      }
4102
    }
4103
  }
4104
}
4,257✔
4105

4106
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
19,180✔
4107
                                                int16_t *numOfNull) {
4108
  *(uint64_t *)sum = 0;
19,180✔
4109
  *(uint64_t *)max = 0;
19,180✔
4110
  *(uint64_t *)min = 0;
19,180✔
4111
  *numOfNull = 0;
19,180✔
4112

4113
  switch (pColData->flag) {
19,180!
4114
    case HAS_NONE:
×
4115
    case HAS_NULL:
4116
    case (HAS_NONE | HAS_NULL):
4117
      *numOfNull = pColData->nVal;
×
4118
      break;
×
4119
    case HAS_VALUE:
16,250✔
4120
      *numOfNull = 0;
16,250✔
4121
      break;
16,250✔
4122
    case (HAS_VALUE | HAS_NULL):
2,930✔
4123
    case (HAS_VALUE | HAS_NONE):
4124
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,457,472✔
4125
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
9,454,542✔
4126
          (*numOfNull)++;
471,165✔
4127
        }
4128
      }
4129
      break;
2,930✔
4130
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4131
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4132
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4133
          (*numOfNull)++;
×
4134
        }
4135
      }
4136
      break;
×
4137
    default:
×
4138
      break;
×
4139
  }
4140
}
19,180✔
4141

4142
void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull) = {
4143
    NULL,
4144
    tColDataCalcSMABool,           // TSDB_DATA_TYPE_BOOL
4145
    tColDataCalcSMATinyInt,        // TSDB_DATA_TYPE_TINYINT
4146
    tColDataCalcSMATinySmallInt,   // TSDB_DATA_TYPE_SMALLINT
4147
    tColDataCalcSMAInt,            // TSDB_DATA_TYPE_INT
4148
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_BIGINT
4149
    tColDataCalcSMAFloat,          // TSDB_DATA_TYPE_FLOAT
4150
    tColDataCalcSMADouble,         // TSDB_DATA_TYPE_DOUBLE
4151
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARCHAR
4152
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_TIMESTAMP
4153
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_NCHAR
4154
    tColDataCalcSMAUTinyInt,       // TSDB_DATA_TYPE_UTINYINT
4155
    tColDataCalcSMATinyUSmallInt,  // TSDB_DATA_TYPE_USMALLINT
4156
    tColDataCalcSMAUInt,           // TSDB_DATA_TYPE_UINT
4157
    tColDataCalcSMAUBigInt,        // TSDB_DATA_TYPE_UBIGINT
4158
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_JSON
4159
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARBINARY
4160
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_DECIMAL
4161
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_BLOB
4162
    NULL,                          // TSDB_DATA_TYPE_MEDIUMBLOB
4163
    tColDataCalcSMAVarType         // TSDB_DATA_TYPE_GEOMETRY
4164
};
4165

4166
// SValueColumn ================================
4167
int32_t tValueColumnInit(SValueColumn *valCol) {
20,462,593✔
4168
  valCol->type = TSDB_DATA_TYPE_NULL;
20,462,593✔
4169
  valCol->numOfValues = 0;
20,462,593✔
4170
  tBufferInit(&valCol->data);
20,462,593✔
4171
  tBufferInit(&valCol->offsets);
20,462,593✔
4172
  return 0;
20,462,593✔
4173
}
4174

4175
void tValueColumnDestroy(SValueColumn *valCol) {
50,495,668✔
4176
  valCol->type = TSDB_DATA_TYPE_NULL;
50,495,668✔
4177
  valCol->numOfValues = 0;
50,495,668✔
4178
  tBufferDestroy(&valCol->data);
50,495,668✔
4179
  tBufferDestroy(&valCol->offsets);
50,495,825✔
4180
  return;
50,495,816✔
4181
}
4182

4183
void tValueColumnClear(SValueColumn *valCol) {
23,690,992✔
4184
  valCol->type = TSDB_DATA_TYPE_NULL;
23,690,992✔
4185
  valCol->numOfValues = 0;
23,690,992✔
4186
  tBufferClear(&valCol->data);
23,690,992✔
4187
  tBufferClear(&valCol->offsets);
23,690,992✔
4188
  return;
23,690,992✔
4189
}
4190

4191
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
1,000,515✔
4192
  int32_t code;
4193

4194
  if (valCol->numOfValues == 0) {
1,000,515✔
4195
    valCol->type = value->type;
13,540✔
4196
  }
4197

4198
  if (!(value->type == valCol->type)) {
1,000,515!
4199
    return TSDB_CODE_INVALID_PARA;
×
4200
  }
4201

4202
  if (IS_VAR_DATA_TYPE(value->type)) {
1,000,515!
4203
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
18,722!
4204
      return code;
×
4205
    }
4206
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
18,723!
4207
      return code;
×
4208
    }
4209
  } else {
4210
    code = tBufferPut(&valCol->data, &value->val, tDataTypes[value->type].bytes);
991,154✔
4211
    if (code) return code;
991,154!
4212
  }
4213
  valCol->numOfValues++;
1,000,516✔
4214

4215
  return 0;
1,000,516✔
4216
}
4217

4218
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
236,707,557✔
4219
  int32_t code;
4220

4221
  if (idx < 0 || idx >= valCol->numOfValues) {
236,707,557!
4222
    return TSDB_CODE_OUT_OF_RANGE;
×
4223
  }
4224

4225
  if (IS_VAR_DATA_TYPE(valCol->type)) {
236,724,721!
4226
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
19,881✔
4227
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
19,881!
4228
    int32_t  oldDataSize = nextOffset - offsets[idx];
19,881✔
4229
    int32_t  bytesAdded = value->nData - oldDataSize;
19,881✔
4230

4231
    if (bytesAdded != 0) {
19,881✔
4232
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
24!
4233
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
12✔
4234
              tBufferGetSize(&valCol->data) - nextOffset);
12✔
4235
      valCol->data.size += bytesAdded;
12✔
4236

4237
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
12!
4238
        offsets[i] += bytesAdded;
×
4239
      }
4240
    }
4241
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
19,881✔
4242
  } else {
4243
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, &value->val,
236,752,637✔
4244
                        tDataTypes[valCol->type].bytes);
236,704,840✔
4245
  }
4246
  return 0;
4247
}
4248

4249
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
479,779,138✔
4250
  if (idx < 0 || idx >= valCol->numOfValues) {
479,779,138!
4251
    return TSDB_CODE_OUT_OF_RANGE;
×
4252
  }
4253

4254
  value->type = valCol->type;
479,832,524✔
4255
  if (IS_VAR_DATA_TYPE(value->type)) {
479,832,524!
4256
    int32_t       offset, nextOffset;
4257
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
816,123✔
4258

4259
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
816,123!
4260
    if (idx == valCol->numOfValues - 1) {
907,229✔
4261
      nextOffset = tBufferGetSize(&valCol->data);
299,974✔
4262
    } else {
4263
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
607,255✔
4264
    }
4265
    value->nData = nextOffset - offset;
906,533✔
4266
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
906,533✔
4267
  } else {
4268
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
479,016,401✔
4269
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, &value->val));
958,032,802!
4270
  }
4271
  return 0;
479,922,934✔
4272
}
4273

4274
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
13,538✔
4275
  int32_t code;
4276

4277
  if (!(valCol->numOfValues > 0)) {
13,538!
4278
    return TSDB_CODE_INVALID_PARA;
×
4279
  }
4280

4281
  (*info) = (SValueColumnCompressInfo){
13,538✔
4282
      .cmprAlg = info->cmprAlg,
13,538✔
4283
      .type = valCol->type,
13,538✔
4284
  };
4285

4286
  // offset
4287
  if (IS_VAR_DATA_TYPE(valCol->type)) {
13,538!
4288
    SCompressInfo cinfo = {
3,492✔
4289
        .cmprAlg = info->cmprAlg,
3,492✔
4290
        .dataType = TSDB_DATA_TYPE_INT,
4291
        .originalSize = valCol->offsets.size,
3,492✔
4292
    };
4293

4294
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
3,492✔
4295
    if (code) return code;
3,494!
4296

4297
    info->offsetOriginalSize = cinfo.originalSize;
3,494✔
4298
    info->offsetCompressedSize = cinfo.compressedSize;
3,494✔
4299
  }
4300

4301
  // data
4302
  SCompressInfo cinfo = {
13,540✔
4303
      .cmprAlg = info->cmprAlg,
13,540✔
4304
      .dataType = valCol->type,
13,540✔
4305
      .originalSize = valCol->data.size,
13,540✔
4306
  };
4307

4308
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
13,540✔
4309
  if (code) return code;
13,542!
4310

4311
  info->dataOriginalSize = cinfo.originalSize;
13,542✔
4312
  info->dataCompressedSize = cinfo.compressedSize;
13,542✔
4313

4314
  return 0;
13,542✔
4315
}
4316

4317
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
1,035,917✔
4318
                               SBuffer *assist) {
4319
  int32_t code;
4320

4321
  tValueColumnClear(valCol);
1,035,917✔
4322
  valCol->type = info->type;
1,035,899✔
4323
  // offset
4324
  if (IS_VAR_DATA_TYPE(valCol->type)) {
1,388,744!
4325
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
352,463✔
4326

4327
    SCompressInfo cinfo = {
352,463✔
4328
        .dataType = TSDB_DATA_TYPE_INT,
4329
        .cmprAlg = info->cmprAlg,
352,463✔
4330
        .originalSize = info->offsetOriginalSize,
352,463✔
4331
        .compressedSize = info->offsetCompressedSize,
352,463✔
4332
    };
4333

4334
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
352,463✔
4335
    if (code) {
352,845!
4336
      return code;
×
4337
    }
4338
  } else {
4339
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
683,436✔
4340
  }
4341

4342
  // data
4343
  SCompressInfo cinfo = {
1,036,281✔
4344
      .dataType = valCol->type,
1,036,281✔
4345
      .cmprAlg = info->cmprAlg,
1,036,281✔
4346
      .originalSize = info->dataOriginalSize,
1,036,281✔
4347
      .compressedSize = info->dataCompressedSize,
1,036,281✔
4348
  };
4349

4350
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
1,036,281✔
4351
  if (code) {
1,036,510!
4352
    return code;
×
4353
  }
4354

4355
  return 0;
1,036,510✔
4356
}
4357

4358
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
13,542✔
4359
  int32_t code;
4360
  uint8_t fmtVer = 0;
13,542✔
4361

4362
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
27,084!
4363
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
27,084!
4364
  if ((code = tBufferPutI8(buffer, info->type))) return code;
27,084!
4365
  if (IS_VAR_DATA_TYPE(info->type)) {
13,542!
4366
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
6,988!
4367
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
6,988!
4368
  }
4369
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
27,084!
4370
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
27,084!
4371

4372
  return 0;
13,542✔
4373
}
4374

4375
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
1,036,320✔
4376
  int32_t code;
4377
  uint8_t fmtVer;
4378

4379
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
1,036,320!
4380
  if (fmtVer == 0) {
1,036,235!
4381
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
1,036,240!
4382
    if ((code = tBufferGetI8(reader, &info->type))) return code;
1,036,014!
4383
    if (IS_VAR_DATA_TYPE(info->type)) {
1,035,820!
4384
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
352,448!
4385
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
352,544!
4386
    } else {
4387
      info->offsetOriginalSize = 0;
683,372✔
4388
      info->offsetCompressedSize = 0;
683,372✔
4389
    }
4390
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
1,035,870!
4391
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
1,035,692!
4392
  } else {
4393
    return TSDB_CODE_INVALID_PARA;
×
4394
  }
4395

4396
  return 0;
1,035,701✔
4397
}
4398

4399
int32_t tCompressData(void          *input,       // input
5,906,089✔
4400
                      SCompressInfo *info,        // compress info
4401
                      void          *output,      // output
4402
                      int32_t        outputSize,  // output size
4403
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4404
) {
4405
  int32_t extraSizeNeeded;
4406
  int32_t code;
4407

4408
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
5,906,089!
4409
  if (!(outputSize >= extraSizeNeeded)) {
5,906,089!
4410
    return TSDB_CODE_INVALID_PARA;
×
4411
  }
4412

4413
  if (info->cmprAlg == NO_COMPRESSION) {
5,906,089!
4414
    (void)memcpy(output, input, info->originalSize);
×
4415
    info->compressedSize = info->originalSize;
×
4416
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
7,262,252!
4417
    SBuffer local;
4418

4419
    tBufferInit(&local);
4420
    if (buffer == NULL) {
1,353,399!
4421
      buffer = &local;
×
4422
    }
4423

4424
    if (info->cmprAlg == TWO_STAGE_COMP) {
1,353,399!
4425
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
1,355,970✔
4426
      if (code) {
1,355,970!
4427
        tBufferDestroy(&local);
4428
        return code;
×
4429
      }
4430
    }
4431

4432
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
2,709,562✔
4433
        input,                                                   // input
4434
        info->originalSize,                                      // input size
4435
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
1,353,399✔
4436
        output,                                                  // output
4437
        outputSize,                                              // output size
4438
        info->cmprAlg,                                           // compression algorithm
1,353,399✔
4439
        buffer->data,                                            // buffer
4440
        buffer->capacity                                         // buffer size
1,353,399✔
4441
    );
4442
    if (info->compressedSize < 0) {
1,356,163!
4443
      tBufferDestroy(&local);
4444
      return TSDB_CODE_COMPRESS_ERROR;
×
4445
    }
4446

4447
    tBufferDestroy(&local);
4448
  } else {
4449
    DEFINE_VAR(info->cmprAlg)
4,552,690✔
4450
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
4,552,690!
4451
      (void)memcpy(output, input, info->originalSize);
×
4452
      info->compressedSize = info->originalSize;
×
4453
      return 0;
×
4454
    }
4455
    SBuffer local;
4456

4457
    tBufferInit(&local);
4458
    if (buffer == NULL) {
4,552,690!
4459
      buffer = &local;
×
4460
    }
4461
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
4,552,690✔
4462

4463
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
9,106,388✔
4464
        input,                                                      // input
4465
        info->originalSize,                                         // input size
4466
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
4,552,694✔
4467
        output,                                                     // output
4468
        outputSize,                                                 // output size
4469
        info->cmprAlg,                                              // compression algorithm
4470
        buffer->data,                                               // buffer
4471
        buffer->capacity                                            // buffer size
4,552,694✔
4472
    );
4473
    if (info->compressedSize < 0) {
4,553,694!
4474
      tBufferDestroy(&local);
4475
      return TSDB_CODE_COMPRESS_ERROR;
×
4476
    }
4477

4478
    tBufferDestroy(&local);
4479
    // new col compress
4480
  }
4481

4482
  return 0;
5,909,857✔
4483
}
4484

4485
int32_t tDecompressData(void                *input,       // input
70,030,199✔
4486
                        const SCompressInfo *info,        // compress info
4487
                        void                *output,      // output
4488
                        int32_t              outputSize,  // output size
4489
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4490
) {
4491
  int32_t code;
4492

4493
  if (!(outputSize >= info->originalSize)) {
70,030,199!
4494
    return TSDB_CODE_INVALID_PARA;
×
4495
  }
4496

4497
  if (info->cmprAlg == NO_COMPRESSION) {
70,030,199!
4498
    if (!(info->compressedSize == info->originalSize)) {
×
4499
      return TSDB_CODE_INVALID_PARA;
×
4500
    }
4501
    (void)memcpy(output, input, info->compressedSize);
×
4502
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
100,289,892!
4503
    SBuffer local;
4504

4505
    tBufferInit(&local);
4506
    if (buffer == NULL) {
30,229,672!
4507
      buffer = &local;
×
4508
    }
4509

4510
    if (info->cmprAlg == TWO_STAGE_COMP) {
30,229,672!
4511
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
30,259,400✔
4512
      if (code) {
30,260,162!
4513
        tBufferDestroy(&local);
4514
        return code;
×
4515
      }
4516
    }
4517

4518
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
30,230,434✔
4519
        input,                                                  // input
4520
        info->compressedSize,                                   // inputSize
30,230,434✔
4521
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
30,230,434✔
4522
        output,                                                 // output
4523
        outputSize,                                             // output size
4524
        info->cmprAlg,                                          // compression algorithm
30,230,434✔
4525
        buffer->data,                                           // helper buffer
4526
        buffer->capacity                                        // extra buffer size
30,230,434✔
4527
    );
4528
    if (decompressedSize < 0) {
30,259,693!
4529
      tBufferDestroy(&local);
4530
      return TSDB_CODE_COMPRESS_ERROR;
×
4531
    }
4532

4533
    if (!(decompressedSize == info->originalSize)) {
30,259,693!
4534
      return TSDB_CODE_COMPRESS_ERROR;
×
4535
    }
4536
    tBufferDestroy(&local);
4537
  } else {
4538
    DEFINE_VAR(info->cmprAlg);
39,800,527✔
4539
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
39,800,527!
4540
      (void)memcpy(output, input, info->compressedSize);
×
4541
      return 0;
×
4542
    }
4543
    SBuffer local;
4544

4545
    tBufferInit(&local);
4546
    if (buffer == NULL) {
39,800,527!
4547
      buffer = &local;
×
4548
    }
4549
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
39,800,527✔
4550
    if (code) {
39,801,051!
4551
      return code;
×
4552
    }
4553

4554
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
39,801,051✔
4555
        input,                                                  // input
4556
        info->compressedSize,                                   // inputSize
39,801,051✔
4557
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
39,801,051✔
4558
        output,                                                 // output
4559
        outputSize,                                             // output size
4560
        info->cmprAlg,                                          // compression algorithm
39,801,051✔
4561
        buffer->data,                                           // helper buffer
4562
        buffer->capacity                                        // extra buffer size
39,801,051✔
4563
    );
4564
    if (decompressedSize < 0) {
39,801,181!
4565
      tBufferDestroy(&local);
4566
      return TSDB_CODE_COMPRESS_ERROR;
×
4567
    }
4568

4569
    if (!(decompressedSize == info->originalSize)) {
39,801,181!
4570
      return TSDB_CODE_COMPRESS_ERROR;
×
4571
    }
4572
    tBufferDestroy(&local);
4573
  }
4574

4575
  return 0;
70,060,874✔
4576
}
4577

4578
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
5,906,382✔
4579
  int32_t code;
4580

4581
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
5,906,382✔
4582
  if (code) return code;
5,906,389!
4583

4584
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
5,906,389✔
4585
  if (code) return code;
5,907,477!
4586

4587
  output->size += info->compressedSize;
5,907,477✔
4588
  return 0;
5,907,477✔
4589
}
4590

4591
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
30,254,196✔
4592
  int32_t code;
4593

4594
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
30,254,196✔
4595
  if (code) return code;
30,255,103!
4596

4597
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
30,255,103✔
4598
  if (code) return code;
30,259,550!
4599

4600
  output->size += info->originalSize;
30,259,550✔
4601
  return 0;
30,259,550✔
4602
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc