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

taosdata / TDengine / #3774

28 Mar 2025 06:51AM UTC coverage: 62.934% (+2.6%) from 60.312%
#3774

push

travis-ci

web-flow
fix(tdb): disable page recycling (#30529)

154142 of 313582 branches covered (49.16%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

2163 existing lines in 136 files now uncovered.

240434 of 313390 relevant lines covered (76.72%)

17901958.9 hits per line

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

62.21
/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
#include "decimal.h"
22

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

152
  if (!(numOfColVals > 0)) {
1,277,344,923!
153
    return TSDB_CODE_INVALID_PARA;
×
154
  }
155
  if (!(colValArray[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
1,277,344,923!
156
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
157
  }
158
  if (!(colValArray[0].value.type == TSDB_DATA_TYPE_TIMESTAMP)) {
1,277,344,923!
159
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;;
×
160
  }
161

162
  *sinfo = (SRowBuildScanInfo){
1,277,344,923✔
163
      .tupleFixedSize = schema->flen,
1,277,344,923✔
164
  };
165

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

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

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

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

199
  if (sinfo->numOfNone) {
1,277,344,923✔
200
    sinfo->flag |= HAS_NONE;
360,679,117✔
201
  }
202
  if (sinfo->numOfNull) {
1,277,344,923✔
203
    sinfo->flag |= HAS_NULL;
28,700,634✔
204
  }
205
  if (sinfo->numOfValue) {
1,277,344,923✔
206
    sinfo->flag |= HAS_VALUE;
1,253,965,916✔
207
  }
208

209
  // Tuple
210
  sinfo->tupleFlag = sinfo->flag;
1,277,344,923✔
211
  switch (sinfo->flag) {
1,277,344,923!
212
    case HAS_NONE:
42,673,671✔
213
    case HAS_NULL:
214
      sinfo->tupleBitmapSize = 0;
42,673,671✔
215
      sinfo->tupleFixedSize = 0;
42,673,671✔
216
      break;
42,673,671✔
217
    case HAS_VALUE:
911,998,738✔
218
      sinfo->tupleBitmapSize = 0;
911,998,738✔
219
      sinfo->tupleFixedSize = schema->flen;
911,998,738✔
220
      break;
911,998,738✔
221
    case (HAS_NONE | HAS_NULL):
24,519✔
222
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,519✔
223
      sinfo->tupleFixedSize = 0;
24,519✔
224
      break;
24,519✔
225
    case (HAS_NONE | HAS_VALUE):
345,836,395✔
226
    case (HAS_NULL | HAS_VALUE):
227
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
345,836,395✔
228
      sinfo->tupleFixedSize = schema->flen;
345,836,395✔
229
      break;
345,836,395✔
230
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
452,579✔
231
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
452,579✔
232
      sinfo->tupleFixedSize = schema->flen;
452,579✔
233
      break;
452,579✔
234
  }
235
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,609,689,140✔
236
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
334,384,734✔
237
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
334,384,734✔
238
  }
239
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,275,304,406✔
240
                        + sinfo->tuplePKSize      // primary keys
1,275,304,406✔
241
                        + sinfo->tupleBitmapSize  // bitmap
1,275,304,406✔
242
                        + sinfo->tupleFixedSize   // fixed part
1,275,304,406✔
243
                        + sinfo->tupleVarSize;    // var part
1,275,304,406✔
244

245
  // Key-Value
246
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,275,304,406!
247
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,293,170,650✔
248
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,293,170,650✔
249
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
250
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
4,802,881✔
251
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
4,802,881✔
252
  } else {
253
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
254
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
255
  }
256
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,608,798,706✔
257
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
334,343,865✔
258
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
334,343,865✔
259
  }
260
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,274,454,841✔
261
                     + sinfo->kvPKSize        // primary keys
1,274,454,841✔
262
                     + sinfo->kvIndexSize     // index array
1,274,454,841✔
263
                     + sinfo->kvPayloadSize;  // payload
1,274,454,841✔
264

265
_exit:
1,274,454,841✔
266
  return code;
1,274,454,841✔
267
}
268

269
static int32_t tRowBuildTupleRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
968,563,946✔
270
                                 SRow **ppRow) {
271
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
968,563,946✔
272

273
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
968,563,946!
274
  if (*ppRow == NULL) {
980,677,776!
275
    return terrno;
×
276
  }
277
  (*ppRow)->flag = sinfo->tupleFlag;
980,677,776✔
278
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
980,677,776✔
279
  (*ppRow)->sver = schema->version;
980,677,776✔
280
  (*ppRow)->len = sinfo->tupleRowSize;
980,677,776✔
281
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
980,677,776✔
282

283
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
980,677,776!
284
    return 0;
40,467,888✔
285
  }
286

287
  uint8_t *primaryKeys = (*ppRow)->data;
940,209,888✔
288
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
940,209,888✔
289
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
940,209,888✔
290
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
940,209,888✔
291

292
  // primary keys
293
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,278,073,012✔
294
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
341,647,481✔
295
  }
296

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

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

311
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
312
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
150,214,091✔
313
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
150,214,091✔
314
            if (colValArray[colValIndex].value.nData) {
150,214,091!
315
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
157,087,270✔
316
              varlen += colValArray[colValIndex].value.nData;
157,087,270✔
317
            }
318
          } else {
319
            (void)memcpy(fixed + schema->columns[i].offset,
2,147,483,647✔
320
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
2,147,483,647!
321
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
322
          }
323
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
21,053,575!
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
22,125,275!
325
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
326
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
464,400!
327
        }
328

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

340
  return 0;
936,425,531✔
341
}
342

343
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
344
  if (flag & KV_FLG_LIT) {
2,147,483,647✔
345
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
2,147,483,647✔
346
  } else if (flag & KV_FLG_MID) {
5,985,636!
347
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,550,723✔
348
  } else {
UNCOV
349
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
×
350
  }
351
  indices->nCol++;
2,147,483,647✔
352
}
2,147,483,647✔
353

354
static int32_t tRowBuildKVRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema, SRow **ppRow) {
324,920,926✔
355
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
324,920,926✔
356

357
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
324,920,926!
358
  if (*ppRow == NULL) {
325,291,131!
359
    return terrno;
×
360
  }
361
  (*ppRow)->flag = sinfo->kvFlag;
325,291,131✔
362
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
325,291,131✔
363
  (*ppRow)->sver = schema->version;
325,291,131✔
364
  (*ppRow)->len = sinfo->kvRowSize;
325,291,131✔
365
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
325,291,131✔
366

367
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
325,291,131!
368
    return TSDB_CODE_INVALID_PARA;
×
369
  }
370

371
  uint8_t *primaryKeys = (*ppRow)->data;
325,299,876✔
372
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
325,299,876✔
373
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
325,299,876✔
374
  uint32_t payloadSize = 0;
325,299,876✔
375

376
  // primary keys
377
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
326,819,978✔
378
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
1,520,181✔
379
  }
380

381
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
325,299,797✔
382
  int32_t colValIndex = 1;
325,299,797✔
383
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
384
    for (;;) {
385
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647✔
386
        break;
44✔
387
      }
388

389
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
390
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
2,147,483,647✔
391
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
2,147,483,647✔
392
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
393
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
454,453,320✔
394
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
454,453,320✔
395
            if (colValArray[colValIndex].value.nData > 0) {
454,453,320!
396
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
464,763,605✔
397
                           colValArray[colValIndex].value.nData);
464,763,605✔
398
            }
399
            payloadSize += colValArray[colValIndex].value.nData;
454,453,320✔
400
          } else {
401
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
2,147,483,647✔
402
            (void)memcpy(payload + payloadSize, VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
2,147,483,647!
403
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
404
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
2,147,483,647✔
405
          }
406
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
2,147,483,647✔
407
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
13,735,987✔
408
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
27,471,974✔
409
        }
410

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

421
  return 0;
325,299,797✔
422
}
423

424
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
1,278,276,312✔
425
  int32_t           code;
426
  SRowBuildScanInfo sinfo;
427

428
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,278,276,312✔
429
  if (code) return code;
1,296,156,126!
430

431
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,296,156,126✔
432
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
972,045,337✔
433
  } else {
434
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
324,110,789✔
435
  }
436
  return code;
1,298,126,497✔
437
}
438

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

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

463
  if (!infoSorted) {
39,264!
464
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
465
  }
466

467
  int32_t code = 0;
39,264✔
468
  int32_t numOfRows = infos[0].bind->num;
39,264✔
469
  SArray *colValArray;
470
  SColVal colVal;
471

472
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
39,264✔
473
    return terrno;
3✔
474
  }
475

476
  SRowKey rowKey, lastRowKey;
477
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
147,830✔
478
    taosArrayClear(colValArray);
111,683✔
479

480
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
848,184✔
481
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
754,443✔
482
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
32✔
483
      } else {
484
        SValue value = {
754,411✔
485
            .type = infos[iInfo].type,
754,411✔
486
        };
487
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
754,411!
488
          value.nData = infos[iInfo].bind->length[iRow];
174,445✔
489
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
174,445!
490
            code = TSDB_CODE_INVALID_PARA;
×
491
            goto _exit;
×
492
          }
493
          value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
174,445✔
494
        } else {
495
          valueSetDatum(&value, infos[iInfo].type,
579,966✔
496
                        (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
579,966✔
497
                        infos[iInfo].bind->buffer_length);
579,966✔
498
        }
499
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
771,413✔
500
      }
501
      if (taosArrayPush(colValArray, &colVal) == NULL) {
737,111!
502
        code = terrno;
×
503
        goto _exit;
×
504
      }
505
    }
506

507
    SRow *row;
508
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
93,741!
509
      goto _exit;
×
510
    }
511

512
    if ((taosArrayPush(rowArray, &row)) == NULL) {
108,593!
513
      code = terrno;
×
514
      goto _exit;
×
515
    }
516

517
    if (pOrdered && pDupTs) {
108,593!
518
      tRowGetKey(row, &rowKey);
217,270!
519
      if (iRow == 0) {
108,695✔
520
        *pOrdered = true;
38,618✔
521
        *pDupTs = false;
38,618✔
522
      } else {
523
        if (*pOrdered) {
70,077!
524
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
70,098✔
525
          *pOrdered = (res >= 0);
70,098✔
526
          if (!*pDupTs) {
70,098✔
527
            *pDupTs = (res == 0);
69,722✔
528
          }
529
        }
530
      }
531
      lastRowKey = rowKey;
108,695✔
532
    }
533
  }
534

535
_exit:
36,147✔
536
  taosArrayDestroy(colValArray);
36,147✔
537
  return code;
39,205✔
538
}
539

540
int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
2,147,483,647✔
541
  if (!(iCol < pTSchema->numOfCols)) return TSDB_CODE_INVALID_PARA;
2,147,483,647!
542
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
2,147,483,647✔
543

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

546
  if (iCol == 0) {
2,147,483,647✔
547
    pColVal->cid = pTColumn->colId;
73,824,129✔
548
    pColVal->value.type = pTColumn->type;
73,824,129✔
549
    pColVal->flag = CV_FLAG_VALUE;
73,824,129✔
550
    VALUE_SET_TRIVIAL_DATUM(&pColVal->value, pRow->ts);
73,824,129✔
551
    return 0;
73,824,129✔
552
  }
553

554
  if (pRow->flag == HAS_NONE) {
2,147,483,647✔
555
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
115,608✔
556
    return 0;
115,608✔
557
  }
558

559
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
560
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
915,444✔
561
    return 0;
915,444✔
562
  }
563

564
  SPrimaryKeyIndex index;
565
  uint8_t         *data = pRow->data;
2,147,483,647✔
566
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
2,147,483,647✔
567
    data += tGetPrimaryKeyIndex(data, &index);
94,767,222✔
568
  }
569

570
  if (pRow->flag >> 4) {  // KV Row
2,147,483,647✔
571
    SKVIdx  *pIdx = (SKVIdx *)data;
2,147,483,647✔
572
    uint8_t *pv = NULL;
2,147,483,647✔
573

574
    if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
575
      pv = pIdx->idx + pIdx->nCol;
2,147,483,647✔
576
    } else if (pRow->flag & KV_FLG_MID) {
84,197,419!
577
      pv = pIdx->idx + (pIdx->nCol << 1);
100,060,613✔
578
    } else {
UNCOV
579
      pv = pIdx->idx + (pIdx->nCol << 2);
×
580
    }
581

582
    int16_t lidx = 0;
2,147,483,647✔
583
    int16_t ridx = pIdx->nCol - 1;
2,147,483,647✔
584
    while (lidx <= ridx) {
2,147,483,647✔
585
      int16_t  mid = (lidx + ridx) >> 1;
2,147,483,647✔
586
      uint8_t *pData = NULL;
2,147,483,647✔
587
      if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
588
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
2,147,483,647✔
589
      } else if (pRow->flag & KV_FLG_MID) {
419,744,192!
590
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
420,034,573✔
591
      } else {
592
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
593
      }
594

595
      int16_t cid;
596
      pData += tGetI16v(pData, &cid);
2,147,483,647✔
597

598
      if (TABS(cid) == pTColumn->colId) {
2,147,483,647✔
599
        if (cid < 0) {
2,147,483,647✔
600
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
85,213,580✔
601
        } else {
602
          pColVal->cid = pTColumn->colId;
2,147,483,647✔
603
          pColVal->value.type = pTColumn->type;
2,147,483,647✔
604
          pColVal->flag = CV_FLAG_VALUE;
2,147,483,647✔
605

606
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
2,147,483,647!
607
            pData += tGetU32v(pData, &pColVal->value.nData);
777,235,205!
608
            if (pColVal->value.nData > 0) {
777,235,205!
609
              pColVal->value.pData = pData;
910,178,552✔
610
            } else {
611
              pColVal->value.pData = NULL;
×
612
            }
613
          } else {
614
            valueSetDatum(&pColVal->value, pTColumn->type, pData, pTColumn->bytes);
2,147,483,647✔
615
          }
616
        }
617
        return 0;
2,147,483,647✔
618
      } else if (TABS(cid) < pTColumn->colId) {
2,147,483,647✔
619
        lidx = mid + 1;
2,147,483,647✔
620
      } else {
621
        ridx = mid - 1;
2,147,483,647✔
622
      }
623
    }
624

625
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2,119,800,163✔
626
  } else {  // Tuple Row
627
    uint8_t *bitmap = data;
698,163,596✔
628
    uint8_t *fixed;
629
    uint8_t *varlen;
630
    uint8_t  bit;
631

632
    if (pRow->flag == HAS_VALUE) {
698,163,596!
633
      fixed = bitmap;
705,909,644✔
634
      bit = BIT_FLG_VALUE;
705,909,644✔
635
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
×
636
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
637
      bit = GET_BIT2(bitmap, iCol - 1);
×
638
    } else {
639
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
640
      bit = GET_BIT1(bitmap, iCol - 1);
×
641

642
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
×
643
        if (bit) bit++;
20,375✔
644
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
×
645
        bit++;
2,235,295✔
646
      }
647
    }
648
    varlen = fixed + pTSchema->flen;
698,163,596✔
649

650
    if (bit == BIT_FLG_NONE) {
698,163,596✔
651
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,239✔
652
      return 0;
7,239✔
653
    } else if (bit == BIT_FLG_NULL) {
698,156,357✔
654
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
341,177✔
655
      return 0;
341,177✔
656
    }
657

658
    pColVal->cid = pTColumn->colId;
697,815,180✔
659
    pColVal->value.type = pTColumn->type;
697,815,180✔
660
    pColVal->flag = CV_FLAG_VALUE;
697,815,180✔
661
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
697,815,180!
662
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
21,851,238✔
663
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
43,702,476!
664
    } else {
665
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
675,963,942✔
666
    }
667
  }
668

669
  return 0;
2,147,483,647✔
670
}
671

672
void tRowDestroy(SRow *pRow) {
938,282,064✔
673
  if (pRow) taosMemoryFree(pRow);
938,282,064!
674
}
938,715,074✔
675

676
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
237,822,634✔
677
  SRowKey key1, key2;
678
  tRowGetKey(*(SRow **)p1, &key1);
475,645,268✔
679
  tRowGetKey(*(SRow **)p2, &key2);
456,252,104✔
680
  return tRowKeyCompare(&key1, &key2);
240,598,795✔
681
}
682
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
1,040✔
683
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
256✔
684
  int32_t code = 0;
256✔
685

686
  int32_t    nRow = iEnd - iStart;
256✔
687
  SRowIter **aIter = NULL;
256✔
688
  SArray    *aColVal = NULL;
256✔
689
  SRow      *pRow = NULL;
256✔
690

691
  aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
256!
692
  if (aIter == NULL) {
256!
693
    code = terrno;
×
694
    goto _exit;
×
695
  }
696

697
  for (int32_t i = 0; i < nRow; i++) {
1,296✔
698
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
1,040✔
699

700
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
1,040✔
701
    if (code) goto _exit;
1,040!
702
  }
703

704
  // merge
705
  aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
256✔
706
  if (aColVal == NULL) {
256!
707
    code = terrno;
×
708
    goto _exit;
×
709
  }
710

711
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
986✔
712
    SColVal *pColVal = NULL;
730✔
713
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
872✔
714
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
828✔
715
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
926✔
716
        pColValT = tRowIterNext(aIter[iRow]);
98✔
717
      }
718

719
      // todo: take strategy according to the flag
720
      if (COL_VAL_IS_VALUE(pColValT)) {
828✔
721
        pColVal = pColValT;
686✔
722
        break;
686✔
723
      } else if (COL_VAL_IS_NULL(pColValT)) {
142✔
724
        if (pColVal == NULL) {
2✔
725
          pColVal = pColValT;
1✔
726
        }
727
      }
728
    }
729

730
    if (pColVal) {
730✔
731
      if (taosArrayPush(aColVal, pColVal) == NULL) {
687!
732
        code = terrno;
×
733
        goto _exit;
×
734
      }
735
    }
736
  }
737

738
  // build
739
  code = tRowBuild(aColVal, pTSchema, &pRow);
256✔
740
  if (code) goto _exit;
256!
741

742
  taosArrayRemoveBatch(aRowP, iStart, nRow, (FDelete)tRowPDestroy);
256✔
743
  if (taosArrayInsert(aRowP, iStart, &pRow) == NULL) {
256!
744
    code = terrno;
×
745
    goto _exit;
×
746
  }
747

748
_exit:
256✔
749
  if (aIter) {
256!
750
    for (int32_t i = 0; i < nRow; i++) {
1,296✔
751
      tRowIterClose(&aIter[i]);
1,040✔
752
    }
753
    taosMemoryFree(aIter);
256!
754
  }
755
  if (aColVal) taosArrayDestroy(aColVal);
256!
756
  if (code) tRowDestroy(pRow);
256!
757
  return code;
256✔
758
}
759

760
int32_t tRowSort(SArray *aRowP) {
74,132✔
761
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
74,132✔
762
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
41,958✔
763
  if (code != TSDB_CODE_SUCCESS) {
41,973!
764
    uError("taosArrayMSort failed caused by %d", code);
×
765
  }
766
  return code;
41,974✔
767
}
768

769
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, int8_t flag) {
74,184✔
770
  int32_t code = 0;
74,184✔
771

772
  int32_t iStart = 0;
74,184✔
773
  while (iStart < aRowP->size) {
35,727,168!
774
    SRowKey key1;
775
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
35,886,095✔
776

777
    tRowGetKey(row1, &key1);
71,786,252✔
778

779
    int32_t iEnd = iStart + 1;
35,647,828✔
780
    while (iEnd < aRowP->size) {
35,649,985✔
781
      SRowKey key2;
782
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
35,586,319✔
783
      tRowGetKey(row2, &key2);
71,464,818✔
784

785
      if (tRowKeyCompare(&key1, &key2) != 0) break;
35,591,475✔
786

787
      iEnd++;
2,157✔
788
    }
789

790
    if (iEnd - iStart > 1) {
35,652,984✔
791
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
256✔
792
      if (code) return code;
256!
793
    }
794

795
    // the array is also changing, so the iStart just ++ instead of iEnd
796
    iStart++;
35,652,984✔
797
  }
798

UNCOV
799
  return code;
×
800
}
801

802
// SRowIter ========================================
803
struct SRowIter {
804
  SRow     *pRow;
805
  STSchema *pTSchema;
806

807
  int32_t iTColumn;
808
  union {
809
    struct {  // kv
810
      int32_t iCol;
811
      SKVIdx *pIdx;
812
    };
813
    struct {  // tuple
814
      uint8_t *pb;
815
      uint8_t *pf;
816
    };
817
  };
818
  uint8_t *pv;
819
  SColVal  cv;
820
};
821

822
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) {
1,392,727✔
823
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,392,727!
824

825
  int32_t code = 0;
1,392,727✔
826

827
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
1,392,727!
828
  if (pIter == NULL) {
1,443,364!
829
    code = terrno;
×
830
    goto _exit;
×
831
  }
832

833
  pIter->pRow = pRow;
1,443,364✔
834
  pIter->pTSchema = pTSchema;
1,443,364✔
835
  pIter->iTColumn = 0;
1,443,364✔
836

837
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
1,443,364!
838

839
  uint8_t         *data = pRow->data;
1,445,265✔
840
  SPrimaryKeyIndex index;
841
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,445,306✔
842
    data += tGetPrimaryKeyIndex(data, &index);
41✔
843
  }
844

845
  if (pRow->flag >> 4) {
1,445,265✔
846
    pIter->iCol = 0;
1,440,474✔
847
    pIter->pIdx = (SKVIdx *)data;
1,440,474✔
848
    if (pRow->flag & KV_FLG_LIT) {
1,440,474✔
849
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
1,436,819✔
850
    } else if (pRow->flag & KV_FLG_MID) {
3,655✔
851
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1);  // * sizeof(uint16_t)
3,600✔
852
    } else {
853
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2);  // * sizeof(uint32_t)
55✔
854
    }
855
  } else {
856
    switch (pRow->flag) {
4,791!
857
      case (HAS_NULL | HAS_NONE):
1✔
858
        pIter->pb = data;
1✔
859
        break;
1✔
860
      case HAS_VALUE:
2,911✔
861
        pIter->pf = data;
2,911✔
862
        pIter->pv = pIter->pf + pTSchema->flen;
2,911✔
863
        break;
2,911✔
864
      case (HAS_VALUE | HAS_NONE):
750✔
865
      case (HAS_VALUE | HAS_NULL):
866
        pIter->pb = data;
750✔
867
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
750✔
868
        pIter->pv = pIter->pf + pTSchema->flen;
750✔
869
        break;
750✔
870
      case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
871
        pIter->pb = data;
×
872
        pIter->pf = data + BIT2_SIZE(pTSchema->numOfCols - 1);
×
873
        pIter->pv = pIter->pf + pTSchema->flen;
×
874
        break;
×
875
      default:
1,129✔
876
        break;
1,129✔
877
    }
878
  }
879

880
_exit:
1,443,364✔
881
  if (code) {
1,443,364!
882
    *ppIter = NULL;
×
883
  } else {
884
    *ppIter = pIter;
1,443,364✔
885
  }
886
  return code;
1,443,364✔
887
}
888

889
void tRowIterClose(SRowIter **ppIter) {
1,368,346✔
890
  SRowIter *pIter = *ppIter;
1,368,346✔
891
  if (pIter) {
1,368,346!
892
    taosMemoryFree(pIter);
1,368,944!
893
  }
894
  *ppIter = NULL;
1,456,383✔
895
}
1,456,383✔
896

897
SColVal *tRowIterNext(SRowIter *pIter) {
14,547,880✔
898
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
14,547,880✔
899
    return NULL;
1,368,712✔
900
  }
901

902
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
13,179,168✔
903

904
  // timestamp
905
  if (0 == pIter->iTColumn) {
13,179,168✔
906
    pIter->cv.cid = pTColumn->colId;
1,411,529✔
907
    pIter->cv.value.type = pTColumn->type;
1,411,529✔
908
    pIter->cv.flag = CV_FLAG_VALUE;
1,411,529✔
909
    VALUE_SET_TRIVIAL_DATUM(&pIter->cv.value, pIter->pRow->ts);
1,411,529✔
910
    goto _exit;
1,411,529✔
911
  }
912

913
  if (pIter->pRow->flag == HAS_NONE) {
11,767,639✔
914
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1✔
915
    goto _exit;
1✔
916
  }
917

918
  if (pIter->pRow->flag == HAS_NULL) {
11,767,638✔
919
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,841✔
920
    goto _exit;
1,841✔
921
  }
922

923
  if (pIter->pRow->flag >> 4) {  // KV
11,765,797!
924
    if (pIter->iCol < pIter->pIdx->nCol) {
12,850,641✔
925
      uint8_t *pData;
926

927
      if (pIter->pRow->flag & KV_FLG_LIT) {
11,306,263✔
928
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
11,205,282✔
929
      } else if (pIter->pRow->flag & KV_FLG_MID) {
100,981!
930
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
108,000✔
931
      } else {
932
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
933
      }
934

935
      int16_t cid;
936
      pData += tGetI16v(pData, &cid);
11,306,263✔
937

938
      if (TABS(cid) == pTColumn->colId) {
11,306,263!
939
        if (cid < 0) {
11,768,475✔
940
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
2,345,663✔
941
        } else {
942
          pIter->cv.cid = pTColumn->colId;
9,422,812✔
943
          pIter->cv.value.type = pTColumn->type;
9,422,812✔
944
          pIter->cv.flag = CV_FLAG_VALUE;
9,422,812✔
945

946
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
9,422,812!
947
            pData += tGetU32v(pData, &pIter->cv.value.nData);
1,103,683!
948
            if (pIter->cv.value.nData > 0) {
1,103,683!
949
              pIter->cv.value.pData = pData;
2,776,206✔
950
            } else {
951
              pIter->cv.value.pData = NULL;
×
952
            }
953
          } else {
954
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
8,319,129✔
955
          }
956
        }
957

958
        pIter->iCol++;
12,694,757✔
959
        goto _exit;
12,694,757✔
960
      } else if (TABS(cid) > pTColumn->colId) {
×
961
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
94✔
962
        goto _exit;
94✔
963
      } else {
964
        uError("unexpected column id %d, %d", cid, pTColumn->colId);
×
965
        goto _exit;
×
966
      }
967
    } else {
968
      pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1,544,378✔
969
      goto _exit;
1,544,378✔
970
    }
971
  } else {  // Tuple
972
    uint8_t bv = BIT_FLG_VALUE;
×
973
    if (pIter->pb) {
×
974
      switch (pIter->pRow->flag) {
3,243!
975
        case (HAS_NULL | HAS_NONE):
3✔
976
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
3✔
977
          break;
3✔
978
        case (HAS_VALUE | HAS_NONE):
37✔
979
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
37✔
980
          if (bv) bv++;
37✔
981
          break;
37✔
982
        case (HAS_VALUE | HAS_NULL):
3,203✔
983
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
3,203✔
984
          break;
3,203✔
985
        case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
986
          bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1);
×
987
          break;
×
988
        default:
×
989
          break;
×
990
      }
991

992
      if (bv == BIT_FLG_NONE) {
3,243✔
993
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
13✔
994
        goto _exit;
13✔
995
      } else if (bv == BIT_FLG_NULL) {
3,230✔
996
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
348✔
997
        goto _exit;
348✔
998
      }
999
    }
1000

1001
    pIter->cv.cid = pTColumn->colId;
×
1002
    pIter->cv.value.type = pTColumn->type;
×
1003
    pIter->cv.flag = CV_FLAG_VALUE;
×
1004
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
1005
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
×
1006
      pData += tGetU32v(pData, &pIter->cv.value.nData);
×
1007
      if (pIter->cv.value.nData > 0) {
×
1008
        pIter->cv.value.pData = pData;
2,678✔
1009
      } else {
1010
        pIter->cv.value.pData = NULL;
×
1011
      }
1012
    } else {
1013
      valueSetDatum(&pIter->cv.value, pTColumn->type, pIter->pf + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
30,665✔
1014
    }
1015
    goto _exit;
33,356✔
1016
  }
1017

1018
_exit:
15,686,317✔
1019
  pIter->iTColumn++;
15,686,317✔
1020
  return &pIter->cv;
15,686,317✔
1021
}
1022

1023
static int32_t tRowNoneUpsertColData(SColData *aColData, int32_t nColData, int32_t flag) {
1,128✔
1024
  int32_t code = 0;
1,128✔
1025

1026
  if (flag) return code;
1,128!
1027

1028
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
8,026✔
1029
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
6,903✔
1030
    if (code) return code;
6,898!
1031
  }
1032

1033
  return code;
1,123✔
1034
}
1035
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
185,433✔
1036
  int32_t code = 0;
185,433✔
1037

1038
  int32_t   iColData = 0;
185,433✔
1039
  SColData *pColData = &aColData[iColData];
185,433✔
1040
  int32_t   iTColumn = 1;
185,433✔
1041
  STColumn *pTColumn = &pSchema->columns[iTColumn];
185,433✔
1042

1043
  while (pColData) {
699,219✔
1044
    if (pTColumn) {
513,800!
1045
      if (pTColumn->colId == pColData->cid) {  // NULL
513,800!
1046
        if (flag == 0) {
513,800✔
1047
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
513,601✔
1048
        } else {
1049
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
199✔
1050
        }
1051
        if (code) goto _exit;
513,786!
1052

1053
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
513,786✔
1054
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
513,786✔
UNCOV
1055
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
1056
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1057
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1058
      } else {
UNCOV
1059
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
×
1060
      }
1061
    } else {  // NONE
1062
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1063
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1064
    }
1065
  }
1066

1067
_exit:
185,419✔
1068
  return code;
185,419✔
1069
}
1070
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
803,097,441✔
1071
                                      int32_t flag) {
1072
  int32_t code = 0;
803,097,441✔
1073

1074
  int32_t   iColData = 0;
803,097,441✔
1075
  SColData *pColData = &aColData[iColData];
803,097,441✔
1076
  int32_t   iTColumn = 1;
803,097,441✔
1077
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
803,097,441✔
1078

1079
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
803,097,441✔
1080
  SPrimaryKeyIndex index;
1081
  uint8_t         *data = pRow->data;
803,097,441✔
1082
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,062,952,272✔
1083
    data += tGetPrimaryKeyIndex(data, &index);
259,845,459✔
1084
  }
1085

1086
  switch (pRow->flag) {
803,106,813!
1087
    case HAS_VALUE:
793,770,107✔
1088
      pf = data;  // TODO: fix here
793,770,107✔
1089
      pv = pf + pTSchema->flen;
793,770,107✔
1090
      break;
793,770,107✔
1091
    case (HAS_NULL | HAS_NONE):
1,297✔
1092
      pb = data;
1,297✔
1093
      break;
1,297✔
1094
    case (HAS_VALUE | HAS_NONE):
9,421,416✔
1095
    case (HAS_VALUE | HAS_NULL):
1096
      pb = data;
9,421,416✔
1097
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
9,421,416✔
1098
      pv = pf + pTSchema->flen;
9,421,416✔
1099
      break;
9,421,416✔
1100
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1101
      pb = data;
×
1102
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1103
      pv = pf + pTSchema->flen;
×
1104
      break;
×
1105
    default:
×
1106
      return TSDB_CODE_INVALID_DATA_FMT;
×
1107
  }
1108

1109
  while (pColData) {
2,147,483,647✔
1110
    if (pTColumn) {
2,147,483,647✔
1111
      if (pTColumn->colId == pColData->cid) {
2,147,483,647!
1112
        if (!(pTColumn->type == pColData->type)) {
2,147,483,647!
1113
          return TSDB_CODE_INVALID_PARA;
×
1114
        }
1115
        if (pb) {
2,147,483,647✔
1116
          uint8_t bv;
1117
          switch (pRow->flag) {
28,118,430!
1118
            case (HAS_NULL | HAS_NONE):
25,933✔
1119
              bv = GET_BIT1(pb, iTColumn - 1);
25,933✔
1120
              break;
25,933✔
1121
            case (HAS_VALUE | HAS_NONE):
198,890✔
1122
              bv = GET_BIT1(pb, iTColumn - 1);
198,890✔
1123
              if (bv) bv++;
198,890✔
1124
              break;
198,890✔
1125
            case (HAS_VALUE | HAS_NULL):
27,892,789✔
1126
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
27,892,789✔
1127
              break;
27,892,789✔
1128
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1129
              bv = GET_BIT2(pb, iTColumn - 1);
×
1130
              break;
×
1131
            default:
818✔
1132
              return TSDB_CODE_INVALID_DATA_FMT;
818✔
1133
          }
1134

1135
          if (bv == BIT_FLG_NONE) {
28,117,612✔
1136
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,377!
1137
              goto _exit;
×
1138
            goto _continue;
43,375✔
1139
          } else if (bv == BIT_FLG_NULL) {
28,074,235✔
1140
            if (flag == 0) {
9,406,104✔
1141
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
9,403,948✔
1142
            } else {
1143
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
2,156✔
1144
            }
1145
            if (code) goto _exit;
9,406,273!
1146
            goto _continue;
9,406,273✔
1147
          }
1148
        }
1149

1150
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1151
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
43,133,507!
1152
          uint32_t nData;
1153
          pData += tGetU32v(pData, &nData);
43,133,507✔
1154
          if (flag == 0) {
43,133,507!
1155
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
46,600,786✔
1156
          } else {
1157
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1158
          }
1159
          if (code) goto _exit;
47,580,326!
1160
        } else {
1161
          if (flag == 0) {
2,147,483,647✔
1162
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,147,483,647✔
1163
                                                                          TYPE_BYTES[pColData->type]);
2,147,483,647✔
1164
          } else {
1165
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
1,799,419✔
1166
                                                                          TYPE_BYTES[pColData->type], flag > 0);
1,799,419✔
1167
          }
1168
          if (code) goto _exit;
2,147,483,647!
1169
        }
1170

1171
      _continue:
2,147,483,647✔
1172
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
2,147,483,647✔
1173
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
2,147,483,647✔
1174
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
1175
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1176
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1177
      } else {
1178
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
1179
      }
1180
    } else {
1181
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
420,154!
1182
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
420,151✔
1183
    }
1184
  }
1185

1186
_exit:
806,509,183✔
1187
  return code;
806,509,183✔
1188
}
1189
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
5,051,175✔
1190
  int32_t code = 0;
5,051,175✔
1191

1192
  uint8_t  *pv = NULL;
5,051,175✔
1193
  int32_t   iColData = 0;
5,051,175✔
1194
  SColData *pColData = &aColData[iColData];
5,051,175✔
1195
  int32_t   iTColumn = 1;
5,051,175✔
1196
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
5,051,175✔
1197
  int32_t   iCol = 0;
5,051,175✔
1198

1199
  // primary keys
1200
  uint8_t         *data = pRow->data;
5,051,175✔
1201
  SPrimaryKeyIndex index;
1202
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
5,254,360✔
1203
    data += tGetPrimaryKeyIndex(data, &index);
203,185✔
1204
  }
1205

1206
  SKVIdx *pKVIdx = (SKVIdx *)data;
5,051,175✔
1207
  if (pRow->flag & KV_FLG_LIT) {
5,051,175✔
1208
    pv = pKVIdx->idx + pKVIdx->nCol;
4,994,896✔
1209
  } else if (pRow->flag & KV_FLG_MID) {
56,279!
1210
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
62,861✔
1211
  } else if (pRow->flag & KV_FLG_BIG) {
×
1212
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1213
  } else {
1214
    return TSDB_CODE_INVALID_PARA;
×
1215
  }
1216

1217
  while (pColData) {
47,245,191✔
1218
    if (pTColumn) {
42,197,278✔
1219
      if (pTColumn->colId == pColData->cid) {
41,798,102✔
1220
        while (iCol < pKVIdx->nCol) {
41,750,877✔
1221
          uint8_t *pData;
1222
          if (pRow->flag & KV_FLG_LIT) {
36,555,785✔
1223
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
34,849,837✔
1224
          } else if (pRow->flag & KV_FLG_MID) {
1,705,948!
1225
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,705,987✔
1226
          } else if (pRow->flag & KV_FLG_BIG) {
×
1227
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1228
          } else {
1229
            return TSDB_CODE_INVALID_DATA_FMT;
×
1230
          }
1231

1232
          int16_t cid;
1233
          pData += tGetI16v(pData, &cid);
36,555,824✔
1234

1235
          if (TABS(cid) == pTColumn->colId) {
36,555,824✔
1236
            if (cid < 0) {
36,155,348✔
1237
              if (flag == 0) {
7,866,882✔
1238
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
7,863,220✔
1239
              } else {
1240
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
3,662✔
1241
              }
1242
              if (code) goto _exit;
7,207,702!
1243
            } else {
1244
              uint32_t nData;
1245
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
28,288,466!
1246
                pData += tGetU32v(pData, &nData);
6,673,065✔
1247
              } else {
1248
                nData = 0;
21,615,401✔
1249
              }
1250
              if (flag == 0) {
28,288,466!
1251
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
28,639,935✔
1252
              } else {
1253
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1254
              }
1255
              if (code) goto _exit;
28,938,192!
1256
            }
1257
            iCol++;
36,145,894✔
1258
            goto _continue;
36,145,894✔
1259
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
400,476✔
1260
            break;
39,365✔
1261
          } else {
1262
            iCol++;
361,111✔
1263
          }
1264
        }
1265

1266
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
5,234,457!
1267

1268
      _continue:
5,234,024✔
1269
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
41,379,918✔
1270
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
41,379,918✔
1271
      } else if (pTColumn->colId > pColData->cid) {
408,336!
1272
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1273
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1274
      } else {
1275
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
408,336!
1276
      }
1277
    } else {
1278
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,176!
1279
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,180✔
1280
    }
1281
  }
1282

1283
_exit:
5,047,913✔
1284
  return code;
5,047,913✔
1285
}
1286
/* flag > 0: forward update
1287
 * flag == 0: append
1288
 * flag < 0: backward update
1289
 */
1290
int32_t tRowUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
808,287,973✔
1291
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
808,287,973!
1292
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
808,287,973!
1293

1294
  if (pRow->flag == HAS_NONE) {
808,287,973✔
1295
    return tRowNoneUpsertColData(aColData, nColData, flag);
1,128✔
1296
  } else if (pRow->flag == HAS_NULL) {
808,286,845✔
1297
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
185,434✔
1298
  } else if (pRow->flag >> 4) {  // KV row
808,101,411✔
1299
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
5,054,168✔
1300
  } else {  // TUPLE row
1301
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
803,047,243✔
1302
  }
1303
}
1304

1305
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
2,147,483,647✔
1306
  key->numOfPKs = row->numOfPKs;
2,147,483,647✔
1307

1308
  if (key->numOfPKs == 0) {
2,147,483,647!
1309
    return;
×
1310
  }
1311

1312
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1313

1314
  uint8_t *data = row->data;
2,147,483,647✔
1315

1316
  for (int32_t i = 0; i < row->numOfPKs; i++) {
2,147,483,647✔
1317
    data += tGetPrimaryKeyIndex(data, &indices[i]);
2,147,483,647✔
1318
  }
1319

1320
  // primary keys
1321
  for (int32_t i = 0; i < row->numOfPKs; i++) {
2,147,483,647✔
1322
    key->pks[i].type = indices[i].type;
2,147,483,647✔
1323

1324
    uint8_t *tdata = data + indices[i].offset;
2,147,483,647✔
1325
    if (row->flag >> 4) {
2,147,483,647✔
1326
      tdata += tGetI16v(tdata, NULL);
3,660,789✔
1327
    }
1328

1329
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
1330
      key->pks[i].pData = tdata;
775✔
1331
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
1,550!
1332
    } else {
1333
      valueSetDatum(key->pks + i, indices[i].type, tdata, tDataTypes[indices[i].type].bytes);
2,147,483,647✔
1334
    }
1335
  }
1336
}
1337

1338
#define T_COMPARE_SCALAR_VALUE(TYPE, V1, V2)    \
1339
  do {                                          \
1340
    if (*(TYPE *)(V1) < *(TYPE *)(V2)) {        \
1341
      return -1;                                \
1342
    } else if (*(TYPE *)(V1) > *(TYPE *)(V2)) { \
1343
      return 1;                                 \
1344
    } else {                                    \
1345
      return 0;                                 \
1346
    }                                           \
1347
  } while (0)
1348

1349
int32_t tValueCompare(const SValue *tv1, const SValue *tv2) {
235,233,083✔
1350
  switch (tv1->type) {
235,233,083!
1351
    case TSDB_DATA_TYPE_BOOL:
×
1352
    case TSDB_DATA_TYPE_TINYINT:
1353
      T_COMPARE_SCALAR_VALUE(int8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1354
    case TSDB_DATA_TYPE_SMALLINT:
×
1355
      T_COMPARE_SCALAR_VALUE(int16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1356
    case TSDB_DATA_TYPE_INT:
33,468✔
1357
      T_COMPARE_SCALAR_VALUE(int32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
33,468✔
1358
    case TSDB_DATA_TYPE_BIGINT:
235,197,003✔
1359
    case TSDB_DATA_TYPE_TIMESTAMP:
1360
      T_COMPARE_SCALAR_VALUE(int64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
235,197,003✔
1361
    case TSDB_DATA_TYPE_FLOAT:
×
1362
      T_COMPARE_SCALAR_VALUE(float, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1363
    case TSDB_DATA_TYPE_DOUBLE:
×
1364
      T_COMPARE_SCALAR_VALUE(double, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1365
    case TSDB_DATA_TYPE_UTINYINT:
×
1366
      T_COMPARE_SCALAR_VALUE(uint8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1367
    case TSDB_DATA_TYPE_USMALLINT:
×
1368
      T_COMPARE_SCALAR_VALUE(uint16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
UNCOV
1369
    case TSDB_DATA_TYPE_UINT:
×
UNCOV
1370
      T_COMPARE_SCALAR_VALUE(uint32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
UNCOV
1371
    case TSDB_DATA_TYPE_UBIGINT:
×
UNCOV
1372
      T_COMPARE_SCALAR_VALUE(uint64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1373
    case TSDB_DATA_TYPE_GEOMETRY:
218✔
1374
    case TSDB_DATA_TYPE_BINARY: {
1375
      int32_t ret = strncmp((const char *)tv1->pData, (const char *)tv2->pData, TMIN(tv1->nData, tv2->nData));
218✔
1376
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
218✔
1377
    }
1378
    case TSDB_DATA_TYPE_NCHAR: {
×
1379
      int32_t ret = taosUcs4Compare((TdUcs4 *)tv1->pData, (TdUcs4 *)tv2->pData,
×
1380
                                    tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1381
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1382
    }
1383
    case TSDB_DATA_TYPE_VARBINARY: {
×
1384
      int32_t ret = memcmp(tv1->pData, tv2->pData, tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1385
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1386
    }
1387
    default:
2,394✔
1388
      break;
2,394✔
1389
  }
1390

1391
  return 0;
2,394✔
1392
}
1393

1394
// NOTE:
1395
// set key->numOfPKs to 0 as the smallest key with ts
1396
// set key->numOfPKs to (TD_MAX_PK_COLS + 1) as the largest key with ts
1397
FORCE_INLINE int32_t tRowKeyCompare(const SRowKey *key1, const SRowKey *key2) {
2,147,483,647✔
1398
  if (key1->ts < key2->ts) {
2,147,483,647!
1399
    return -1;
2,147,483,647✔
1400
  } else if (key1->ts > key2->ts) {
2,147,483,647!
1401
    return 1;
2,147,483,647✔
1402
  }
1403

1404
  if (key1->numOfPKs == key2->numOfPKs) {
222,303,051!
1405
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
300,443,479!
1406
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
235,227,488✔
1407
      if (ret) return ret;
235,214,787!
1408
    }
1409
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1410
    return -1;
×
1411
  } else {
1412
    return 1;
×
1413
  }
1414

1415
  return 0;
65,215,991✔
1416
}
1417

1418
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
707,839,821✔
1419
  pDst->ts = pSrc->ts;
707,839,821✔
1420
  pDst->numOfPKs = pSrc->numOfPKs;
707,839,821✔
1421

1422
  if (pSrc->numOfPKs > 0) {
707,839,821✔
1423
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
40,409,219✔
1424
      SValue *pVal = &pDst->pks[i];
20,016,829✔
1425
      pVal->type = pSrc->pks[i].type;
20,016,829✔
1426

1427
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
20,016,829✔
1428
    }
1429
  }
1430
}
708,217,007✔
1431

1432
// STag ========================================
1433
static int tTagValCmprFn(const void *p1, const void *p2) {
130,887,351✔
1434
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
130,887,351✔
1435
    return -1;
44,511,334✔
1436
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
86,376,017✔
1437
    return 1;
47,879,572✔
1438
  }
1439

1440
  return 0;
38,496,445✔
1441
}
1442
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
14,383✔
1443
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
14,383✔
1444
}
1445

1446
#ifdef TD_DEBUG_PRINT_TAG
1447
static void debugPrintTagVal(int8_t type, const void *val, int32_t vlen, const char *tag, int32_t ln) {
1448
  switch (type) {
1449
    case TSDB_DATA_TYPE_VARBINARY:
1450
    case TSDB_DATA_TYPE_JSON:
1451
    case TSDB_DATA_TYPE_VARCHAR:
1452
    case TSDB_DATA_TYPE_NCHAR:
1453
    case TSDB_DATA_TYPE_GEOMETRY: {
1454
      char tmpVal[32] = {0};
1455
      tstrncpy(tmpVal, val, vlen > 31 ? 31 : vlen);
1456
      printf("%s:%d type:%d vlen:%d, val:\"%s\"\n", tag, ln, (int32_t)type, vlen, tmpVal);
1457
    } break;
1458
    case TSDB_DATA_TYPE_FLOAT:
1459
      printf("%s:%d type:%d vlen:%d, val:%f\n", tag, ln, (int32_t)type, vlen, *(float *)val);
1460
      break;
1461
    case TSDB_DATA_TYPE_DOUBLE:
1462
      printf("%s:%d type:%d vlen:%d, val:%lf\n", tag, ln, (int32_t)type, vlen, *(double *)val);
1463
      break;
1464
    case TSDB_DATA_TYPE_BOOL:
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_TINYINT:
1468
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
1469
      break;
1470
    case TSDB_DATA_TYPE_SMALLINT:
1471
      printf("%s:%d type:%d vlen:%d, val:%" PRIi16 "\n", tag, ln, (int32_t)type, vlen, *(int16_t *)val);
1472
      break;
1473
    case TSDB_DATA_TYPE_INT:
1474
      printf("%s:%d type:%d vlen:%d, val:%" PRIi32 "\n", tag, ln, (int32_t)type, vlen, *(int32_t *)val);
1475
      break;
1476
    case TSDB_DATA_TYPE_BIGINT:
1477
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
1478
      break;
1479
    case TSDB_DATA_TYPE_TIMESTAMP:
1480
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
1481
      break;
1482
    case TSDB_DATA_TYPE_UTINYINT:
1483
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
1484
      break;
1485
    case TSDB_DATA_TYPE_USMALLINT:
1486
      printf("%s:%d type:%d vlen:%d, val:%" PRIu16 "\n", tag, ln, (int32_t)type, vlen, *(uint16_t *)val);
1487
      break;
1488
    case TSDB_DATA_TYPE_UINT:
1489
      printf("%s:%d type:%d vlen:%d, val:%" PRIu32 "\n", tag, ln, (int32_t)type, vlen, *(uint32_t *)val);
1490
      break;
1491
    case TSDB_DATA_TYPE_UBIGINT:
1492
      printf("%s:%d type:%d vlen:%d, val:%" PRIu64 "\n", tag, ln, (int32_t)type, vlen, *(uint64_t *)val);
1493
      break;
1494
    case TSDB_DATA_TYPE_NULL:
1495
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
1496
      break;
1497
    default:
1498
      break;
1499
  }
1500
}
1501

1502
void debugPrintSTag(STag *pTag, const char *tag, int32_t ln) {
1503
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
1504
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
1505
  uint8_t *p = NULL;
1506
  int16_t  offset = 0;
1507

1508
  if (isLarge) {
1509
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
1510
  } else {
1511
    p = (uint8_t *)&pTag->idx[pTag->nTag];
1512
  }
1513
  printf("%s:%d >>> STAG === %s:%s, len: %d, nTag: %d, sver:%d\n", tag, ln, isJson ? "json" : "normal",
1514
         isLarge ? "large" : "small", (int32_t)pTag->len, (int32_t)pTag->nTag, pTag->ver);
1515
  for (uint16_t n = 0; n < pTag->nTag; ++n) {
1516
    if (isLarge) {
1517
      offset = ((int16_t *)pTag->idx)[n];
1518
    } else {
1519
      offset = pTag->idx[n];
1520
    }
1521
    STagVal tagVal = {0};
1522
    if (isJson) {
1523
      tagVal.pKey = (char *)POINTER_SHIFT(p, offset);
1524
    } else {
1525
      tagVal.cid = *(int16_t *)POINTER_SHIFT(p, offset);
1526
    }
1527
    printf("%s:%d loop[%d-%d] offset=%d\n", __func__, __LINE__, (int32_t)pTag->nTag, (int32_t)n, (int32_t)offset);
1528
    tGetTagVal(p + offset, &tagVal, isJson);
1529
    if (IS_VAR_DATA_TYPE(tagVal.type)) {
1530
      debugPrintTagVal(tagVal.type, tagVal.pData, tagVal.nData, __func__, __LINE__);
1531
    } else {
1532
      debugPrintTagVal(tagVal.type, &tagVal.i64, tDataTypes[tagVal.type].bytes, __func__, __LINE__);
1533
    }
1534
  }
1535
  printf("\n");
1536
}
1537
#endif
1538

1539
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
918,845✔
1540
  int32_t n = 0;
918,845✔
1541

1542
  // key
1543
  if (isJson) {
918,845✔
1544
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
1,620✔
1545
  } else {
1546
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
1,836,070✔
1547
  }
1548

1549
  // type
1550
  n += tPutI8(p ? p + n : p, pTagVal->type);
918,845✔
1551

1552
  // value
1553
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
918,845✔
1554
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
666,696✔
1555
  } else {
1556
    p = p ? p + n : p;
585,497✔
1557
    n += tDataTypes[pTagVal->type].bytes;
585,497✔
1558
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
585,497✔
1559
  }
1560

1561
  return n;
918,845✔
1562
}
1563
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
130,326,334✔
1564
  int32_t n = 0;
130,326,334✔
1565

1566
  // key
1567
  if (isJson) {
130,326,334✔
1568
    n += tGetCStr(p + n, &pTagVal->pKey);
34,026!
1569
  } else {
1570
    n += tGetI16v(p + n, &pTagVal->cid);
260,618,642✔
1571
  }
1572

1573
  // type
1574
  n += tGetI8(p + n, &pTagVal->type);
130,326,334!
1575

1576
  // value
1577
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
130,326,334!
1578
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
42,855,226!
1579
  } else {
1580
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
108,898,721✔
1581
    n += tDataTypes[pTagVal->type].bytes;
108,898,721✔
1582
  }
1583

1584
  return n;
130,326,334✔
1585
}
1586

1587
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
49,787✔
1588

1589
bool tTagIsJsonNull(void *data) {
8,946✔
1590
  STag  *pTag = (STag *)data;
8,946✔
1591
  int8_t isJson = tTagIsJson(pTag);
8,946✔
1592
  if (!isJson) return false;
8,946✔
1593
  return ((STag *)data)->nTag == 0;
3,812✔
1594
}
1595

1596
int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
178,498✔
1597
  int32_t  code = 0;
178,498✔
1598
  uint8_t *p = NULL;
178,498✔
1599
  int16_t  n = 0;
178,498✔
1600
  int16_t  nTag = taosArrayGetSize(pArray);
178,498✔
1601
  int32_t  szTag = 0;
178,515✔
1602
  int8_t   isLarge = 0;
178,515✔
1603

1604
  // sort
1605
  if (isJson) {
178,515✔
1606
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
324✔
1607
  } else {
1608
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
178,191✔
1609
  }
1610

1611
  // get size
1612
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
637,966✔
1613
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
459,453✔
1614
  }
1615
  if (szTag <= INT8_MAX) {
178,513✔
1616
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
161,606✔
1617
  } else {
1618
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
16,907✔
1619
    isLarge = 1;
16,907✔
1620
  }
1621

1622
  // build tag
1623
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
178,513!
1624
  if ((*ppTag) == NULL) {
178,572!
1625
    code = terrno;
×
1626
    goto _err;
×
1627
  }
1628
  (*ppTag)->flags = 0;
178,572✔
1629
  if (isJson) {
178,572✔
1630
    (*ppTag)->flags |= TD_TAG_JSON;
324✔
1631
  }
1632
  if (isLarge) {
178,572✔
1633
    (*ppTag)->flags |= TD_TAG_LARGE;
16,932✔
1634
  }
1635
  (*ppTag)->len = szTag;
178,572✔
1636
  (*ppTag)->nTag = nTag;
178,572✔
1637
  (*ppTag)->ver = version;
178,572✔
1638

1639
  if (isLarge) {
178,572✔
1640
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
16,933✔
1641
  } else {
1642
    p = (uint8_t *)&(*ppTag)->idx[nTag];
161,639✔
1643
  }
1644
  n = 0;
178,572✔
1645
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
638,106✔
1646
    if (isLarge) {
459,540✔
1647
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
120,434✔
1648
    } else {
1649
      (*ppTag)->idx[iTag] = n;
339,106✔
1650
    }
1651
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
459,540✔
1652
  }
1653
#ifdef TD_DEBUG_PRINT_TAG
1654
  debugPrintSTag(*ppTag, __func__, __LINE__);
1655
#endif
1656

1657
  return code;
178,566✔
1658

1659
_err:
×
1660
  return code;
×
1661
}
1662

1663
void tTagFree(STag *pTag) {
78,697✔
1664
  if (pTag) taosMemoryFree(pTag);
78,697!
1665
}
78,700✔
1666

1667
char *tTagValToData(const STagVal *value, bool isJson) {
12,356,351✔
1668
  if (!value) {
12,356,351!
1669
    return NULL;
×
1670
  }
1671

1672
  char  *data = NULL;
12,356,351✔
1673
  int8_t typeBytes = 0;
12,356,351✔
1674
  if (isJson) {
12,356,351✔
1675
    typeBytes = CHAR_BYTES;
7,826✔
1676
  }
1677

1678
  if (IS_VAR_DATA_TYPE(value->type)) {
12,356,351✔
1679
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
2,996,671!
1680
    if (data == NULL) {
2,998,302!
1681
      return NULL;
×
1682
    }
1683

1684
    if (isJson) {
2,998,302✔
1685
      *data = value->type;
3,107✔
1686
    }
1687

1688
    varDataLen(data + typeBytes) = value->nData;
2,998,302✔
1689
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
2,998,302✔
1690
  } else {
1691
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
9,359,680✔
1692
  }
1693

1694
  return data;
12,357,982✔
1695
}
1696

1697
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
40,217,774✔
1698
  if (!pTag || !pTagVal) {
40,217,774!
1699
    return false;
×
1700
  }
1701

1702
  int16_t  lidx = 0;
40,370,338✔
1703
  int16_t  ridx = pTag->nTag - 1;
40,370,338✔
1704
  int16_t  midx;
1705
  uint8_t *p;
1706
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
40,370,338✔
1707
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
40,370,338✔
1708
  int16_t  offset;
1709
  STagVal  tv;
1710
  int      c;
1711

1712
  if (isLarge) {
40,370,338✔
1713
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
33,056,428✔
1714
  } else {
1715
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,313,910✔
1716
  }
1717

1718
  pTagVal->type = TSDB_DATA_TYPE_NULL;
40,370,338✔
1719
  pTagVal->pData = NULL;
40,370,338✔
1720
  pTagVal->nData = 0;
40,370,338✔
1721
  while (lidx <= ridx) {
132,210,693✔
1722
    midx = (lidx + ridx) / 2;
130,353,811✔
1723
    if (isLarge) {
130,353,811✔
1724
      offset = ((int16_t *)pTag->idx)[midx];
107,535,049✔
1725
    } else {
1726
      offset = pTag->idx[midx];
22,818,762✔
1727
    }
1728

1729
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
130,353,811✔
1730
    if (isJson) {
130,831,177✔
1731
      c = tTagValJsonCmprFn(pTagVal, &tv);
14,174✔
1732
    } else {
1733
      c = tTagValCmprFn(pTagVal, &tv);
130,817,003✔
1734
    }
1735

1736
    if (c < 0) {
132,052,748✔
1737
      ridx = midx - 1;
44,002,504✔
1738
    } else if (c > 0) {
88,050,244✔
1739
      lidx = midx + 1;
47,837,851✔
1740
    } else {
1741
      (void)memcpy(pTagVal, &tv, sizeof(tv));
40,212,393✔
1742
      return true;
40,212,393✔
1743
    }
1744
  }
1745
  return false;
1,856,882✔
1746
}
1747

1748
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
678,415✔
1749
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,356,830✔
1750
}
1751

1752
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
19,883,712✔
1753

1754
int32_t tTagToValArray(const STag *pTag, SArray **ppArray) {
1,885✔
1755
  int32_t  code = 0;
1,885✔
1756
  uint8_t *p = NULL;
1,885✔
1757
  STagVal  tv = {0};
1,885✔
1758
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
1,885✔
1759
  int16_t  offset = 0;
1,885✔
1760

1761
  if (isLarge) {
1,885✔
1762
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
17✔
1763
  } else {
1764
    p = (uint8_t *)&pTag->idx[pTag->nTag];
1,868✔
1765
  }
1766

1767
  (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
1,885✔
1768
  if (*ppArray == NULL) {
1,885!
1769
    code = terrno;
×
1770
    goto _err;
×
1771
  }
1772

1773
  for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
5,527✔
1774
    if (isLarge) {
3,642✔
1775
      offset = ((int16_t *)pTag->idx)[iTag];
27✔
1776
    } else {
1777
      offset = pTag->idx[iTag];
3,615✔
1778
    }
1779
    int32_t nt = tGetTagVal(p + offset, &tv, pTag->flags & TD_TAG_JSON);
3,642✔
1780
    if (taosArrayPush(*ppArray, &tv) == NULL) {
7,284!
1781
      code = terrno;
×
1782
      goto _err;
×
1783
    }
1784
  }
1785

1786
  return code;
1,885✔
1787

1788
_err:
×
1789
  return code;
×
1790
}
1791

1792
// STSchema ========================================
1793
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
16,845,515✔
1794
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
16,845,515!
1795
  if (pTSchema == NULL) {
16,882,416!
1796
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1797
    return NULL;
×
1798
  }
1799

1800
  pTSchema->numOfCols = numOfCols;
16,882,416✔
1801
  pTSchema->version = version;
16,882,416✔
1802

1803
  // timestamp column
1804
  if (!(aSchema[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
16,882,416!
1805
    terrno = TSDB_CODE_INVALID_PARA;
×
1806
    return NULL;
×
1807
  }
1808
  if (!(aSchema[0].colId == PRIMARYKEY_TIMESTAMP_COL_ID)) {
16,882,416!
1809
    terrno = TSDB_CODE_INVALID_PARA;
×
1810
    return NULL;
×
1811
  }
1812
  pTSchema->columns[0].colId = aSchema[0].colId;
16,882,416✔
1813
  pTSchema->columns[0].type = aSchema[0].type;
16,882,416✔
1814
  pTSchema->columns[0].flags = aSchema[0].flags;
16,882,416✔
1815
  pTSchema->columns[0].bytes = TYPE_BYTES[aSchema[0].type];
16,882,416✔
1816
  pTSchema->columns[0].offset = -1;
16,882,416✔
1817

1818
  // other columns
1819
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
195,458,596✔
1820
    SSchema  *pSchema = &aSchema[iCol];
178,576,180✔
1821
    STColumn *pTColumn = &pTSchema->columns[iCol];
178,576,180✔
1822

1823
    pTColumn->colId = pSchema->colId;
178,576,180✔
1824
    pTColumn->type = pSchema->type;
178,576,180✔
1825
    pTColumn->flags = pSchema->flags;
178,576,180✔
1826
    pTColumn->offset = pTSchema->flen;
178,576,180✔
1827

1828
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
178,576,180!
1829
      pTColumn->bytes = pSchema->bytes;
35,344,926✔
1830
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
35,344,926✔
1831
    } else {
1832
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
143,231,254✔
1833
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
143,231,254✔
1834
    }
1835

1836
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
178,576,180✔
1837
  }
1838

1839
#if 1  // todo : remove this
1840
  pTSchema->tlen += (int32_t)TD_BITMAP_BYTES(numOfCols);
16,882,416✔
1841
#endif
1842

1843
  return pTSchema;
16,882,416✔
1844
}
1845

1846
static int32_t tTColumnCompare(const void *p1, const void *p2) {
9,896,065✔
1847
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
9,896,065✔
1848
    return -1;
1,487,931✔
1849
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
8,408,134✔
1850
    return 1;
5,935,401✔
1851
  }
1852

1853
  return 0;
2,472,733✔
1854
}
1855

1856
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid) {
2,473,348✔
1857
  STColumn tcol = {
2,473,348✔
1858
      .colId = cid,
1859
  };
1860

1861
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
2,473,348✔
1862
}
1863

1864
// SColData ========================================
1865
void tColDataDestroy(void *ph) {
24,363,170✔
1866
  if (ph) {
24,363,170!
1867
    SColData *pColData = (SColData *)ph;
24,363,321✔
1868

1869
    tFree(pColData->pBitMap);
24,363,321!
1870
    tFree(pColData->aOffset);
24,363,347!
1871
    tFree(pColData->pData);
24,363,370!
1872
  }
1873
}
24,364,213✔
1874

1875
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
26,396,029✔
1876
  pColData->cid = cid;
26,396,029✔
1877
  pColData->type = type;
26,396,029✔
1878
  pColData->cflag = cflag;
26,396,029✔
1879
  tColDataClear(pColData);
26,396,029✔
1880
}
26,398,342✔
1881

1882
void tColDataClear(SColData *pColData) {
54,246,896✔
1883
  pColData->numOfNone = 0;
54,246,896✔
1884
  pColData->numOfNull = 0;
54,246,896✔
1885
  pColData->numOfValue = 0;
54,246,896✔
1886
  pColData->nVal = 0;
54,246,896✔
1887
  pColData->flag = 0;
54,246,896✔
1888
  pColData->nData = 0;
54,246,896✔
1889
}
54,246,896✔
1890

1891
void tColDataDeepClear(SColData *pColData) {
184,683✔
1892
  pColData->pBitMap = NULL;
184,683✔
1893
  pColData->aOffset = NULL;
184,683✔
1894
  pColData->pData = NULL;
184,683✔
1895

1896
  tColDataClear(pColData);
184,683✔
1897
}
184,708✔
1898

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

1902
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1903
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
76,490,494!
1904
    if (code) goto _exit;
87,350,242!
1905
    pColData->aOffset[pColData->nVal] = pColData->nData;
87,350,242✔
1906

1907
    if (nData) {
87,350,242!
1908
      code = tRealloc(&pColData->pData, pColData->nData + nData);
86,119,689!
1909
      if (code) goto _exit;
86,822,474!
1910
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
86,822,474✔
1911
      pColData->nData += nData;
86,822,474✔
1912
    }
1913
  } else {
1914
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
1915
      return TSDB_CODE_INVALID_PARA;
×
1916
    }
1917
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
1918
    if (code) goto _exit;
2,147,483,647!
1919
    if (pData) {
2,147,483,647!
1920
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
1921
    } else {
1922
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
33,215,022✔
1923
    }
1924
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
1925
  }
1926
  pColData->nVal++;
2,147,483,647✔
1927

1928
_exit:
2,147,483,647✔
1929
  return code;
2,147,483,647✔
1930
}
1931
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
6,420,559✔
1932
  pColData->flag = HAS_VALUE;
6,421,635✔
1933
  pColData->numOfValue++;
6,420,559✔
1934
  return tColDataPutValue(pColData, pData, nData);
6,422,396✔
1935
}
1936
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
174,751✔
1937
  pColData->flag = HAS_NONE;
174,751✔
1938
  pColData->numOfNone++;
174,751✔
1939
  pColData->nVal++;
174,751✔
1940
  return 0;
174,751✔
1941
}
1942
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
363,141✔
1943
  pColData->flag = HAS_NULL;
364,151✔
1944
  pColData->numOfNull++;
364,151✔
1945
  pColData->nVal++;
364,151✔
1946
  return 0;
363,141✔
1947
}
1948
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,366✔
1949
  int32_t code = 0;
1,366✔
1950

1951
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
1,366✔
1952
  code = tRealloc(&pColData->pBitMap, nBit);
1,366!
1953
  if (code) return code;
1,367!
1954

1955
  memset(pColData->pBitMap, 0, nBit);
1,367✔
1956
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,367!
1957

1958
  pColData->flag |= HAS_VALUE;
1,367✔
1959
  pColData->numOfValue++;
1,367✔
1960

1961
  if (pColData->nVal) {
1,367!
1962
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,367!
1963
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
244✔
1964
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
244!
1965
      if (code) return code;
244!
1966
      memset(pColData->aOffset, 0, nOffset);
244✔
1967
    } else {
1968
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
1,123✔
1969
      code = tRealloc(&pColData->pData, pColData->nData);
1,123!
1970
      if (code) return code;
1,123!
1971
      memset(pColData->pData, 0, pColData->nData);
1,123✔
1972
    }
1973
  }
1974

1975
  return tColDataPutValue(pColData, pData, nData);
1,366✔
1976
}
1977
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
11,541,616✔
1978
  pColData->nVal++;
11,541,616✔
1979
  pColData->numOfNone++;
11,541,616✔
1980
  return 0;
11,541,616✔
1981
}
1982
static FORCE_INLINE int32_t tColDataAppendValue12(SColData *pColData, uint8_t *pData, uint32_t nData) {
601✔
1983
  int32_t code = 0;
601✔
1984

1985
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
601✔
1986
  code = tRealloc(&pColData->pBitMap, nBit);
601!
1987
  if (code) return code;
601!
1988

1989
  memset(pColData->pBitMap, 0, nBit);
601✔
1990
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
601!
1991

1992
  pColData->flag |= HAS_NULL;
601✔
1993
  pColData->numOfNull++;
601✔
1994
  pColData->nVal++;
601✔
1995

1996
  return code;
601✔
1997
}
1998
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
118,982✔
1999
  int32_t code = 0;
119,057✔
2000

2001
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
119,057✔
2002
  code = tRealloc(&pColData->pBitMap, nBit);
119,025!
2003
  if (code) return code;
119,057!
2004

2005
  memset(pColData->pBitMap, 0, nBit);
119,057✔
2006
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
119,057!
2007

2008
  pColData->flag |= HAS_VALUE;
119,057✔
2009
  pColData->numOfValue++;
119,057✔
2010

2011
  if (pColData->nVal) {
119,057!
2012
    if (IS_VAR_DATA_TYPE(pColData->type)) {
119,057!
2013
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
7,497✔
2014
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
7,497!
2015
      if (code) return code;
7,497!
2016
      memset(pColData->aOffset, 0, nOffset);
7,497✔
2017
    } else {
2018
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
111,560✔
2019
      code = tRealloc(&pColData->pData, pColData->nData);
111,560!
2020
      if (code) return code;
111,560!
2021
      memset(pColData->pData, 0, pColData->nData);
111,560✔
2022
    }
2023
  }
2024

2025
  return tColDataPutValue(pColData, pData, nData);
119,057✔
2026
}
2027
static FORCE_INLINE int32_t tColDataAppendValue21(SColData *pColData, uint8_t *pData, uint32_t nData) {
80✔
2028
  int32_t code = 0;
80✔
2029

2030
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
80✔
2031
  code = tRealloc(&pColData->pBitMap, nBit);
80✔
2032
  if (code) return code;
80!
2033

2034
  memset(pColData->pBitMap, 255, nBit);
80✔
2035
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
80!
2036

2037
  pColData->flag |= HAS_NONE;
80✔
2038
  pColData->numOfNone++;
80✔
2039
  pColData->nVal++;
80✔
2040

2041
  return code;
80✔
2042
}
2043
static FORCE_INLINE int32_t tColDataAppendValue22(SColData *pColData, uint8_t *pData, uint32_t nData) {
4,638,274✔
2044
  pColData->nVal++;
4,638,274✔
2045
  pColData->numOfNull++;
4,638,274✔
2046
  return 0;
4,638,274✔
2047
}
2048
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2049
  int32_t code = 0;
×
2050

2051
  pColData->flag |= HAS_VALUE;
×
2052
  pColData->numOfValue++;
×
2053

2054
  uint8_t *pBitMap = NULL;
×
2055
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
2056
  if (code) return code;
×
2057

2058
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
2059
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal));
×
2060
  }
2061
  SET_BIT2_EX(pBitMap, pColData->nVal, 2);
×
2062

2063
  tFree(pColData->pBitMap);
×
2064
  pColData->pBitMap = pBitMap;
×
2065

2066
  if (pColData->nVal) {
×
2067
    if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2068
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
2069
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
2070
      if (code) return code;
×
2071
      memset(pColData->aOffset, 0, nOffset);
×
2072
    } else {
2073
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
×
2074
      code = tRealloc(&pColData->pData, pColData->nData);
×
2075
      if (code) return code;
×
2076
      memset(pColData->pData, 0, pColData->nData);
×
2077
    }
2078
  }
2079

2080
  return tColDataPutValue(pColData, pData, nData);
×
2081
}
2082
static FORCE_INLINE int32_t tColDataAppendValue31(SColData *pColData, uint8_t *pData, uint32_t nData) {
400✔
2083
  int32_t code = 0;
400✔
2084

2085
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
400!
2086
  if (code) return code;
400!
2087

2088
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
400!
2089
  pColData->numOfNone++;
400✔
2090
  pColData->nVal++;
400✔
2091

2092
  return code;
400✔
2093
}
2094
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
9,381✔
2095
  int32_t code = 0;
9,381✔
2096

2097
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
9,381!
2098
  if (code) return code;
9,387!
2099

2100
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
9,387!
2101
  pColData->numOfNull++;
9,387✔
2102
  pColData->nVal++;
9,387✔
2103

2104
  return code;
9,387✔
2105
}
2106
static FORCE_INLINE int32_t tColDataAppendValue40(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,147,483,647✔
2107
  pColData->numOfValue++;
2,147,483,647✔
2108
  return tColDataPutValue(pColData, pData, nData);
2,147,483,647✔
2109
}
2110
static FORCE_INLINE int32_t tColDataAppendValue41(SColData *pColData, uint8_t *pData, uint32_t nData) {
6,111✔
2111
  int32_t code = 0;
6,111✔
2112

2113
  pColData->flag |= HAS_NONE;
6,111✔
2114
  pColData->numOfNone++;
6,111✔
2115

2116
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
6,111✔
2117
  code = tRealloc(&pColData->pBitMap, nBit);
6,111✔
2118
  if (code) return code;
6,104!
2119

2120
  memset(pColData->pBitMap, 255, nBit);
6,104✔
2121
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
6,104✔
2122

2123
  return tColDataPutValue(pColData, NULL, 0);
6,108✔
2124
}
2125
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
689,687✔
2126
  int32_t code = 0;
706,905✔
2127

2128
  pColData->flag |= HAS_NULL;
706,905✔
2129
  pColData->numOfNull++;
706,905✔
2130

2131
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
706,905✔
2132
  code = tRealloc(&pColData->pBitMap, nBit);
706,601✔
2133
  if (code) return code;
706,916!
2134

2135
  memset(pColData->pBitMap, 255, nBit);
706,916✔
2136
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
706,916!
2137

2138
  return tColDataPutValue(pColData, NULL, 0);
706,915✔
2139
}
2140
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
57,676✔
2141
  int32_t code = 0;
59,676✔
2142

2143
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
59,675!
2144
  if (code) return code;
59,822!
2145

2146
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
59,822!
2147
  pColData->numOfValue++;
59,822!
2148

2149
  return tColDataPutValue(pColData, pData, nData);
60,807✔
2150
}
2151
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
102,497✔
2152
  int32_t code = 0;
102,497✔
2153

2154
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
102,497!
2155
  if (code) return code;
102,566!
2156

2157
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
102,566✔
2158
  pColData->numOfNone++;
102,566✔
2159

2160
  return tColDataPutValue(pColData, NULL, 0);
102,687✔
2161
}
2162
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
1✔
2163
  int32_t code = 0;
1✔
2164

2165
  pColData->flag |= HAS_NULL;
1✔
2166
  pColData->numOfNull++;
1✔
2167

2168
  uint8_t *pBitMap = NULL;
1✔
2169
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
1!
2170
  if (code) return code;
1!
2171

2172
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3!
2173
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
2!
2174
  }
2175
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
1!
2176

2177
  tFree(pColData->pBitMap);
1!
2178
  pColData->pBitMap = pBitMap;
1!
2179

2180
  return tColDataPutValue(pColData, NULL, 0);
1✔
2181
}
2182
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
473,768,123✔
2183
  int32_t code = 0;
475,732,367✔
2184

2185
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
475,731,967!
2186
  if (code) return code;
476,660,395!
2187
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
476,660,395!
2188
  pColData->numOfValue++;
476,660,395!
2189

2190
  return tColDataPutValue(pColData, pData, nData);
478,609,852✔
2191
}
2192
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
3,996✔
2193
  int32_t code = 0;
3,996✔
2194

2195
  pColData->flag |= HAS_NONE;
3,996✔
2196
  pColData->numOfNone++;
3,996✔
2197

2198
  uint8_t *pBitMap = NULL;
3,996✔
2199
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
3,996!
2200
  if (code) return code;
3,994!
2201

2202
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
135,423✔
2203
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
131,429✔
2204
  }
2205
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
3,994✔
2206

2207
  tFree(pColData->pBitMap);
3,994!
2208
  pColData->pBitMap = pBitMap;
3,994✔
2209

2210
  return tColDataPutValue(pColData, NULL, 0);
3,997✔
2211
}
2212
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
28,698,877✔
2213
  int32_t code = 0;
30,673,804✔
2214

2215
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
30,670,208!
2216
  if (code) return code;
30,683,325!
2217
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
30,683,325✔
2218
  pColData->numOfNull++;
30,683,325✔
2219

2220
  return tColDataPutValue(pColData, NULL, 0);
30,694,750✔
2221
}
2222
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2223
  int32_t code = 0;
×
2224

2225
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
2226
  if (code) return code;
×
2227
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 2);
×
2228
  pColData->numOfValue++;
×
2229

2230
  return tColDataPutValue(pColData, pData, nData);
×
2231
}
2232
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
4✔
2233
  int32_t code = 0;
4✔
2234

2235
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
4!
2236
  if (code) return code;
4!
2237
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 0);
4✔
2238
  pColData->numOfNone++;
4!
2239

2240
  return tColDataPutValue(pColData, NULL, 0);
4✔
2241
}
2242
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2243
  int32_t code = 0;
×
2244

2245
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
2246
  if (code) return code;
×
2247
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 1);
×
2248
  pColData->numOfNull++;
×
2249

2250
  return tColDataPutValue(pColData, NULL, 0);
×
2251
}
2252
static int32_t (*tColDataAppendValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData) = {
2253
    {tColDataAppendValue00, tColDataAppendValue01, tColDataAppendValue02},  // 0
2254
    {tColDataAppendValue10, tColDataAppendValue11, tColDataAppendValue12},  // HAS_NONE
2255
    {tColDataAppendValue20, tColDataAppendValue21, tColDataAppendValue22},  // HAS_NULL
2256
    {tColDataAppendValue30, tColDataAppendValue31, tColDataAppendValue32},  // HAS_NULL|HAS_NONE
2257
    {tColDataAppendValue40, tColDataAppendValue41, tColDataAppendValue42},  // HAS_VALUE
2258
    {tColDataAppendValue50, tColDataAppendValue51, tColDataAppendValue52},  // HAS_VALUE|HAS_NONE
2259
    {tColDataAppendValue60, tColDataAppendValue61, tColDataAppendValue62},  // HAS_VALUE|HAS_NULL
2260
    {tColDataAppendValue70, tColDataAppendValue71, tColDataAppendValue72},  // HAS_VALUE|HAS_NULL|HAS_NONE
2261

2262
    //       VALUE                  NONE                     NULL
2263
};
2264
int32_t tColDataAppendValue(SColData *pColData, SColVal *pColVal) {
2,147,483,647✔
2265
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) {
2,147,483,647!
2266
    return TSDB_CODE_INVALID_PARA;
×
2267
  }
2268
  return tColDataAppendValueImpl[pColData->flag][pColVal->flag](
2,147,483,647✔
2269
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData);
2,147,483,647!
2270
}
2271

2272
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
9✔
2273
  pColData->numOfNone--;
9✔
2274
  pColData->nVal--;
9✔
2275
  if (pColData->numOfNone) {
9!
2276
    return tColDataAppendValue10(pColData, pData, nData);
×
2277
  } else {
2278
    pColData->flag = 0;
9✔
2279
    return tColDataAppendValue00(pColData, pData, nData);
9✔
2280
  }
2281
}
2282
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
2283
  pColData->numOfNone--;
24✔
2284
  pColData->nVal--;
24✔
2285
  if (pColData->numOfNone) {
24!
2286
    return tColDataAppendValue12(pColData, pData, nData);
×
2287
  } else {
2288
    pColData->flag = 0;
24✔
2289
    return tColDataAppendValue02(pColData, pData, nData);
24✔
2290
  }
2291
  return 0;
2292
}
2293
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
1,110✔
2294
  if (forward) {
1,110!
2295
    pColData->numOfNull--;
1,110✔
2296
    pColData->nVal--;
1,110✔
2297
    if (pColData->numOfNull) {
1,110✔
2298
      return tColDataAppendValue20(pColData, pData, nData);
43✔
2299
    } else {
2300
      pColData->flag = 0;
1,067✔
2301
      return tColDataAppendValue00(pColData, pData, nData);
1,067✔
2302
    }
2303
  }
2304
  return 0;
×
2305
}
2306
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2307
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2308
    pColData->numOfNone--;
×
2309
    pColData->nVal--;
×
2310
    if (pColData->numOfNone) {
×
2311
      return tColDataAppendValue30(pColData, pData, nData);
×
2312
    } else {
2313
      pColData->flag = HAS_NULL;
×
2314
      return tColDataAppendValue20(pColData, pData, nData);
×
2315
    }
2316
  } else if (forward) {  // NULL ==> VALUE
×
2317
    pColData->numOfNull--;
×
2318
    pColData->nVal--;
×
2319
    if (pColData->numOfNull) {
×
2320
      return tColDataAppendValue30(pColData, pData, nData);
×
2321
    } else {
2322
      pColData->flag = HAS_NONE;
×
2323
      return tColDataAppendValue10(pColData, pData, nData);
×
2324
    }
2325
  }
2326
  return 0;
×
2327
}
2328
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
2329
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
2330
    pColData->numOfNone--;
80✔
2331
    pColData->numOfNull++;
80✔
2332
    if (pColData->numOfNone) {
80!
2333
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2334
    } else {
2335
      pColData->flag = HAS_NULL;
80✔
2336
    }
2337
  }
2338
  return 0;
80✔
2339
}
2340
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
23,646,161✔
2341
  if (forward) {  // VALUE ==> VALUE
23,646,161!
2342
    pColData->nVal--;
23,646,254✔
2343
    if (IS_VAR_DATA_TYPE(pColData->type)) {
23,646,254!
2344
      pColData->nData = pColData->aOffset[pColData->nVal];
743,614✔
2345
    } else {
2346
      pColData->nData -= TYPE_BYTES[pColData->type];
22,902,640✔
2347
    }
2348
    return tColDataPutValue(pColData, pData, nData);
23,664,059✔
2349
  }
2350
  return 0;
×
2351
}
2352
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
17,899✔
2353
  if (forward) {  // VALUE ==> NULL
17,899!
2354
    pColData->numOfValue--;
17,900✔
2355
    pColData->nVal--;
17,900✔
2356
    if (pColData->numOfValue) {
17,900✔
2357
      if (IS_VAR_DATA_TYPE(pColData->type)) {
16,914!
2358
        pColData->nData = pColData->aOffset[pColData->nVal];
1,044✔
2359
      } else {
2360
        pColData->nData -= TYPE_BYTES[pColData->type];
15,870✔
2361
      }
2362
      return tColDataAppendValue42(pColData, pData, nData);
16,912✔
2363
    } else {
2364
      pColData->flag = 0;
986✔
2365
      pColData->nData = 0;
986✔
2366
      return tColDataAppendValue02(pColData, pData, nData);
986✔
2367
    }
2368
  }
2369
  return 0;
×
2370
}
2371
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,685✔
2372
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
5,685✔
2373
    pColData->numOfNone--;
5,592✔
2374
    pColData->nVal--;
5,592✔
2375
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,592!
2376
      pColData->nData -= TYPE_BYTES[pColData->type];
4,472✔
2377
    }
2378
    if (pColData->numOfNone) {
5,592✔
2379
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2380
    } else {
2381
      pColData->flag = HAS_VALUE;
3,593✔
2382
      return tColDataAppendValue40(pColData, pData, nData);
3,594✔
2383
    }
2384
  } else if (forward) {  // VALUE ==> VALUE
93!
2385
    pColData->nVal--;
93✔
2386
    if (IS_VAR_DATA_TYPE(pColData->type)) {
93!
2387
      pColData->nData = pColData->aOffset[pColData->nVal];
22✔
2388
    } else {
2389
      pColData->nData -= TYPE_BYTES[pColData->type];
71✔
2390
    }
2391
    return tColDataPutValue(pColData, pData, nData);
93✔
2392
  }
2393
  return 0;
×
2394
}
2395
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
304✔
2396
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
304!
2397
    pColData->numOfNone--;
304✔
2398
    pColData->nVal--;
304✔
2399
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
304!
2400
      pColData->nData -= TYPE_BYTES[pColData->type];
244✔
2401
    }
2402
    if (pColData->numOfNone) {
304!
2403
      return tColDataAppendValue52(pColData, pData, nData);
×
2404
    } else {
2405
      pColData->flag = HAS_VALUE;
304!
2406
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2407
    }
2408
  } else if (forward) {  // VALUE ==> NULL
×
2409
    pColData->numOfValue--;
×
2410
    pColData->nVal--;
×
2411
    if (pColData->numOfValue) {
×
2412
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2413
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2414
      } else {
2415
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2416
      }
2417
      return tColDataAppendValue52(pColData, pData, nData);
×
2418
    } else {
2419
      pColData->flag = HAS_NONE;
×
2420
      pColData->nData = 0;
×
2421
      return tColDataAppendValue12(pColData, pData, nData);
×
2422
    }
2423
  }
2424
  return 0;
×
2425
}
2426
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
39,271,978✔
2427
  if (forward) {
39,271,978!
2428
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
39,271,983✔
2429
      pColData->numOfNull--;
1,994,333✔
2430
      pColData->nVal--;
1,994,333✔
2431
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
1,994,333!
2432
        pColData->nData -= TYPE_BYTES[pColData->type];
1,989,478✔
2433
      }
2434
      if (pColData->numOfNull) {
1,994,333✔
2435
        return tColDataAppendValue60(pColData, pData, nData);
1,963,844✔
2436
      } else {
2437
        pColData->flag = HAS_VALUE;
30,489✔
2438
        return tColDataAppendValue40(pColData, pData, nData);
30,488✔
2439
      }
2440
    } else {  // VALUE ==> VALUE
2441
      pColData->nVal--;
37,277,650✔
2442
      if (IS_VAR_DATA_TYPE(pColData->type)) {
37,277,650!
2443
        pColData->nData = pColData->aOffset[pColData->nVal];
2,682✔
2444
      } else {
2445
        pColData->nData -= TYPE_BYTES[pColData->type];
37,274,968✔
2446
      }
2447
      return tColDataPutValue(pColData, pData, nData);
37,277,650✔
2448
    }
2449
  }
2450
  return 0;
×
2451
}
2452
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
2,090,015✔
2453
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
2,090,015!
2454
    pColData->numOfValue--;
1,971,363✔
2455
    pColData->nVal--;
1,971,363✔
2456
    if (pColData->numOfValue) {
1,971,363✔
2457
      if (IS_VAR_DATA_TYPE(pColData->type)) {
1,971,331!
2458
        pColData->nData = pColData->aOffset[pColData->nVal];
2,514✔
2459
      } else {
2460
        pColData->nData -= TYPE_BYTES[pColData->type];
1,968,817✔
2461
      }
2462
      return tColDataAppendValue62(pColData, pData, nData);
1,971,334✔
2463
    } else {
2464
      pColData->flag = HAS_NULL;
32✔
2465
      pColData->nData = 0;
32!
2466
      return tColDataAppendValue20(pColData, pData, nData);
32✔
2467
    }
2468
  }
2469
  return 0;
118,652✔
2470
}
2471
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
401✔
2472
  int32_t code = 0;
401✔
2473

2474
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
401✔
2475
  if (bv == 0) {  // NONE ==> VALUE
401✔
2476
    pColData->numOfNone--;
400✔
2477
    pColData->nVal--;
400✔
2478
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
400!
2479
      pColData->nData -= TYPE_BYTES[pColData->type];
320✔
2480
    }
2481
    if (pColData->numOfNone) {
400!
2482
      return tColDataAppendValue70(pColData, pData, nData);
×
2483
    } else {
2484
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
21,200✔
2485
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
20,800✔
2486
      }
2487
      pColData->flag = (HAS_VALUE | HAS_NULL);
400!
2488
      return tColDataAppendValue60(pColData, pData, nData);
400✔
2489
    }
2490
  } else if (bv == 1) {  // NULL ==> VALUE
1!
2491
    if (forward) {
1!
2492
      pColData->numOfNull--;
1✔
2493
      pColData->nVal--;
1✔
2494
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
1!
2495
        pColData->nData -= TYPE_BYTES[pColData->type];
1✔
2496
      }
2497
      if (pColData->numOfNull) {
1!
2498
        return tColDataAppendValue70(pColData, pData, nData);
×
2499
      } else {
2500
        for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
3✔
2501
          SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) ? 1 : 0);
2✔
2502
        }
2503
        pColData->flag = (HAS_VALUE | HAS_NONE);
1!
2504
        return tColDataAppendValue50(pColData, pData, nData);
1✔
2505
      }
2506
    }
2507
  } else if (bv == 2) {  // VALUE ==> VALUE
×
2508
    if (forward) {
×
2509
      pColData->nVal--;
×
2510
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2511
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2512
      } else {
2513
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2514
      }
2515
      return tColDataPutValue(pColData, pData, nData);
×
2516
    }
2517
  } else {
2518
    return TSDB_CODE_INVALID_PARA;
×
2519
  }
2520
  return 0;
×
2521
}
2522
static int32_t tColDataUpdateValue72(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,596✔
2523
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
3,596✔
2524
  if (bv == 0) {  // NONE ==> NULL
3,596!
2525
    pColData->numOfNone--;
3,596✔
2526
    pColData->nVal--;
3,596✔
2527
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,596!
2528
      pColData->nData -= TYPE_BYTES[pColData->type];
2,544✔
2529
    }
2530
    if (pColData->numOfNone) {
3,596!
2531
      return tColDataAppendValue72(pColData, pData, nData);
×
2532
    } else {
2533
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
114,128✔
2534
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
110,532✔
2535
      }
2536
      pColData->flag = (HAS_VALUE | HAS_NULL);
3,596✔
2537
      return tColDataAppendValue62(pColData, pData, nData);
3,596✔
2538
    }
2539
  } else if (bv == 2 && forward) {  // VALUE ==> NULL
×
2540
    pColData->numOfValue--;
×
2541
    pColData->nVal--;
×
2542
    if (pColData->numOfValue) {
×
2543
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2544
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2545
      } else {
2546
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2547
      }
2548
      return tColDataAppendValue72(pColData, pData, nData);
×
2549
    } else {
2550
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
×
2551
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal));
×
2552
      }
2553
      pColData->flag = (HAS_NULL | HAS_NONE);
×
2554
      pColData->nData = 0;
×
2555
      return tColDataAppendValue32(pColData, pData, nData);
×
2556
    }
2557
  }
2558
  return 0;
×
2559
}
2560
static FORCE_INLINE int32_t tColDataUpdateNothing(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
13,636✔
2561
  return 0;
13,636✔
2562
}
2563
static int32_t (*tColDataUpdateValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) = {
2564
    {NULL, NULL, NULL},                                                     // 0
2565
    {tColDataUpdateValue10, tColDataUpdateNothing, tColDataUpdateValue12},  // HAS_NONE
2566
    {tColDataUpdateValue20, tColDataUpdateNothing, tColDataUpdateNothing},  // HAS_NULL
2567
    {tColDataUpdateValue30, tColDataUpdateNothing, tColDataUpdateValue32},  // HAS_NULL|HAS_NONE
2568
    {tColDataUpdateValue40, tColDataUpdateNothing, tColDataUpdateValue42},  // HAS_VALUE
2569
    {tColDataUpdateValue50, tColDataUpdateNothing, tColDataUpdateValue52},  // HAS_VALUE|HAS_NONE
2570
    {tColDataUpdateValue60, tColDataUpdateNothing, tColDataUpdateValue62},  // HAS_VALUE|HAS_NULL
2571
    {tColDataUpdateValue70, tColDataUpdateNothing, tColDataUpdateValue72},  // HAS_VALUE|HAS_NULL|HAS_NONE
2572

2573
    //    VALUE             NONE        NULL
2574
};
2575
int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward) {
63,896,706✔
2576
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
63,896,706!
2577
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
63,896,813!
2578

2579
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
63,896,813!
2580

2581
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
63,896,813✔
2582
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData, forward);
63,896,813!
2583
}
2584

2585
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
93,798,447✔
2586
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
93,798,447✔
2587
}
93,798,447✔
2588
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
1,566,003✔
2589
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
1,566,003✔
2590
}
1,566,003✔
2591
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
11,647✔
2592
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2593
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,647!
2594
    case 0:
1,058✔
2595
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,058✔
2596
      break;
1,058✔
2597
    case 1:
10,591✔
2598
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,591✔
2599
      break;
10,591✔
2600
    default:
×
2601
      break;
×
2602
  }
2603
}
11,647✔
2604
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
2605
  SValue value = {.type = pColData->type};
2,147,483,647✔
2606
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2607
    if (iVal + 1 < pColData->nVal) {
200,169,662!
2608
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
206,473,714✔
2609
    } else {
2610
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2611
    }
2612
    value.pData = pColData->pData + pColData->aOffset[iVal];
200,169,662✔
2613
  } else {
2614
    valueSetDatum(&value, pColData->type, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
2615
                  tDataTypes[pColData->type].bytes);
2,147,483,647✔
2616
  }
2617
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
2618
}
338,705,906✔
2619
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
254,801✔
2620
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2621
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
254,801!
2622
    case 0:
106,424✔
2623
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
106,424✔
2624
      break;
106,424✔
2625
    case 1:
148,677✔
2626
      tColDataGetValue4(pColData, iVal, pColVal);
2627
      break;
148,889✔
2628
    default:
×
2629
      break;
×
2630
  }
2631
}
255,013✔
2632
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
356,743,362✔
2633
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2634
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
356,743,362!
2635
    case 0:
18,877,011✔
2636
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
18,877,011✔
2637
      break;
18,877,011✔
2638
    case 1:
338,013,521✔
2639
      tColDataGetValue4(pColData, iVal, pColVal);
2640
      break;
338,539,215✔
2641
    default:
×
2642
      break;
×
2643
  }
2644
}
357,269,056✔
2645
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
11✔
2646
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
2647
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
11!
2648
    case 0:
5✔
2649
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
5✔
2650
      break;
5✔
2651
    case 1:
5✔
2652
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
5✔
2653
      break;
5✔
2654
    case 2:
1!
2655
      tColDataGetValue4(pColData, iVal, pColVal);
2656
      break;
1✔
2657
    default:
×
2658
      break;
×
2659
  }
2660
}
11✔
2661
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2662
    NULL,               // 0
2663
    tColDataGetValue1,  // HAS_NONE
2664
    tColDataGetValue2,  // HAS_NULL
2665
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2666
    tColDataGetValue4,  // HAS_VALUE
2667
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2668
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2669
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2670
};
2671
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
2672
  if (iVal < 0 || iVal >= pColData->nVal ||
2,147,483,647!
2673
      (pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
2,147,483,647!
2674
    return TSDB_CODE_INVALID_PARA;
×
2675
  }
2676
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
2677
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
2678
}
2679

2680
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
817,050,033✔
2681
  switch (pColData->flag) {
817,050,033!
2682
    case HAS_NONE:
×
2683
      return 0;
×
2684
    case HAS_NULL:
×
2685
      return 1;
×
2686
    case (HAS_NULL | HAS_NONE):
11,658✔
2687
      return GET_BIT1(pColData->pBitMap, iVal);
11,658✔
2688
    case HAS_VALUE:
×
2689
      return 2;
×
2690
    case (HAS_VALUE | HAS_NONE):
743,486✔
2691
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
743,486✔
2692
    case (HAS_VALUE | HAS_NULL):
816,865,617✔
2693
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
816,865,617✔
2694
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2695
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
2696
    default:
×
2697
      return 0;
×
2698
  }
2699
}
2700

2701
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg) {
28,162✔
2702
  int32_t code = 0;
28,162✔
2703

2704
  *pColData = *pColDataFrom;
28,162✔
2705

2706
  // bitmap
2707
  switch (pColData->flag) {
28,162!
2708
    case (HAS_NULL | HAS_NONE):
196✔
2709
    case (HAS_VALUE | HAS_NONE):
2710
    case (HAS_VALUE | HAS_NULL):
2711
      pColData->pBitMap = xMalloc(arg, BIT1_SIZE(pColData->nVal));
196✔
2712
      if (pColData->pBitMap == NULL) {
196!
2713
        code = TSDB_CODE_OUT_OF_MEMORY;
×
2714
        goto _exit;
×
2715
      }
2716
      (void)memcpy(pColData->pBitMap, pColDataFrom->pBitMap, BIT1_SIZE(pColData->nVal));
196✔
2717
      break;
196✔
2718
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2719
      pColData->pBitMap = xMalloc(arg, BIT2_SIZE(pColData->nVal));
×
2720
      if (pColData->pBitMap == NULL) {
×
2721
        code = TSDB_CODE_OUT_OF_MEMORY;
×
2722
        goto _exit;
×
2723
      }
2724
      (void)memcpy(pColData->pBitMap, pColDataFrom->pBitMap, BIT2_SIZE(pColData->nVal));
×
2725
      break;
×
2726
    default:
27,966✔
2727
      pColData->pBitMap = NULL;
27,966✔
2728
      break;
27,966✔
2729
  }
2730

2731
  // offset
2732
  if (IS_VAR_DATA_TYPE(pColData->type) && (pColData->flag & HAS_VALUE)) {
28,162!
2733
    pColData->aOffset = xMalloc(arg, pColData->nVal << 2);
220✔
2734
    if (pColData->aOffset == NULL) {
220!
2735
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2736
      goto _exit;
×
2737
    }
2738
    (void)memcpy(pColData->aOffset, pColDataFrom->aOffset, pColData->nVal << 2);
220✔
2739
  } else {
2740
    pColData->aOffset = NULL;
27,942✔
2741
  }
2742

2743
  // value
2744
  if (pColData->nData) {
28,162✔
2745
    pColData->pData = xMalloc(arg, pColData->nData);
27,950✔
2746
    if (pColData->pData == NULL) {
27,951!
2747
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2748
      goto _exit;
×
2749
    }
2750

2751
    (void)memcpy(pColData->pData, pColDataFrom->pData, pColData->nData);
27,951✔
2752
  } else {
2753
    pColData->pData = NULL;
212✔
2754
  }
2755

2756
_exit:
28,163✔
2757
  return code;
28,163✔
2758
}
2759

2760
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
6,398,730✔
2761
  int32_t code;
2762
  SBuffer local;
2763

2764
  if (!(colData->nVal > 0)) {
6,398,730!
2765
    return TSDB_CODE_INVALID_PARA;
×
2766
  }
2767

2768
  (*info) = (SColDataCompressInfo){
6,398,730✔
2769
      .cmprAlg = info->cmprAlg,
6,398,730✔
2770
      .columnFlag = colData->cflag,
6,398,730✔
2771
      .flag = colData->flag,
6,398,730✔
2772
      .dataType = colData->type,
6,398,730✔
2773
      .columnId = colData->cid,
6,398,730✔
2774
      .numOfData = colData->nVal,
6,398,730✔
2775
  };
2776

2777
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
6,398,730!
2778
    return 0;
238,464✔
2779
  }
2780

2781
  tBufferInit(&local);
2782
  if (assist == NULL) {
6,160,266!
2783
    assist = &local;
×
2784
  }
2785

2786
  // bitmap
2787
  if (colData->flag != HAS_VALUE) {
6,160,266✔
2788
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
760,572✔
2789
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
1✔
2790
    } else {
2791
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
760,571✔
2792
    }
2793

2794
    SCompressInfo cinfo = {
760,572✔
2795
        .dataType = TSDB_DATA_TYPE_TINYINT,
2796
        .cmprAlg = info->cmprAlg,
760,572✔
2797
        .originalSize = info->bitmapOriginalSize,
760,572✔
2798
    };
2799

2800
    code = tCompressDataToBuffer(colData->pBitMap, &cinfo, output, assist);
760,572✔
2801
    if (code) {
760,595!
2802
      tBufferDestroy(&local);
2803
      return code;
×
2804
    }
2805

2806
    info->bitmapCompressedSize = cinfo.compressedSize;
760,595✔
2807
  }
2808

2809
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
6,160,289✔
2810
    tBufferDestroy(&local);
2811
    return 0;
601✔
2812
  }
2813

2814
  // offset
2815
  if (IS_VAR_DATA_TYPE(colData->type)) {
6,159,688!
2816
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
971,011✔
2817

2818
    SCompressInfo cinfo = {
971,011✔
2819
        .dataType = TSDB_DATA_TYPE_INT,
2820
        .cmprAlg = info->cmprAlg,
971,011✔
2821
        .originalSize = info->offsetOriginalSize,
971,011✔
2822
    };
2823

2824
    code = tCompressDataToBuffer(colData->aOffset, &cinfo, output, assist);
971,011✔
2825
    if (code) {
971,106!
2826
      tBufferDestroy(&local);
2827
      return code;
×
2828
    }
2829

2830
    info->offsetCompressedSize = cinfo.compressedSize;
971,106✔
2831
  }
2832

2833
  // data
2834
  if (colData->nData > 0) {
6,159,783!
2835
    info->dataOriginalSize = colData->nData;
6,159,835✔
2836

2837
    SCompressInfo cinfo = {
6,159,835✔
2838
        .dataType = colData->type,
6,159,835✔
2839
        .cmprAlg = info->cmprAlg,
6,159,835✔
2840
        .originalSize = info->dataOriginalSize,
6,159,835✔
2841
    };
2842

2843
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
6,159,835✔
2844
    if (code) {
6,160,012!
2845
      tBufferDestroy(&local);
2846
      return code;
×
2847
    }
2848

2849
    info->dataCompressedSize = cinfo.compressedSize;
6,160,012✔
2850
  }
2851

2852
  tBufferDestroy(&local);
2853
  return 0;
6,159,960✔
2854
}
2855

2856
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
20,165,788✔
2857
  int32_t  code;
2858
  SBuffer  local;
2859
  uint8_t *data = (uint8_t *)input;
20,165,788✔
2860

2861
  tBufferInit(&local);
2862
  if (assist == NULL) {
20,165,788!
2863
    assist = &local;
×
2864
  }
2865

2866
  tColDataClear(colData);
20,165,788✔
2867
  colData->cid = info->columnId;
20,165,110✔
2868
  colData->type = info->dataType;
20,165,110✔
2869
  colData->cflag = info->columnFlag;
20,165,110✔
2870
  colData->nVal = info->numOfData;
20,165,110✔
2871
  colData->flag = info->flag;
20,165,110✔
2872

2873
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
20,165,110✔
2874
    goto _exit;
2,734,591✔
2875
  }
2876

2877
  // bitmap
2878
  if (info->bitmapOriginalSize > 0) {
17,430,519✔
2879
    SCompressInfo cinfo = {
551,105✔
2880
        .dataType = TSDB_DATA_TYPE_TINYINT,
2881
        .cmprAlg = info->cmprAlg,
551,105✔
2882
        .originalSize = info->bitmapOriginalSize,
551,105✔
2883
        .compressedSize = info->bitmapCompressedSize,
551,105✔
2884
    };
2885

2886
    code = tRealloc(&colData->pBitMap, cinfo.originalSize);
551,105!
2887
    if (code) {
551,166!
2888
      tBufferDestroy(&local);
2889
      return code;
×
2890
    }
2891

2892
    code = tDecompressData(data, &cinfo, colData->pBitMap, cinfo.originalSize, assist);
551,166✔
2893
    if (code) {
551,057!
2894
      tBufferDestroy(&local);
2895
      return code;
×
2896
    }
2897

2898
    data += cinfo.compressedSize;
551,057✔
2899
  }
2900

2901
  if (info->flag == (HAS_NONE | HAS_NULL)) {
17,430,471✔
2902
    goto _exit;
612✔
2903
  }
2904

2905
  // offset
2906
  if (info->offsetOriginalSize > 0) {
17,429,859✔
2907
    SCompressInfo cinfo = {
3,250,925✔
2908
        .cmprAlg = info->cmprAlg,
3,250,925✔
2909
        .dataType = TSDB_DATA_TYPE_INT,
2910
        .originalSize = info->offsetOriginalSize,
3,250,925✔
2911
        .compressedSize = info->offsetCompressedSize,
3,250,925✔
2912
    };
2913

2914
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
3,250,925!
2915
    if (code) {
3,250,919!
2916
      tBufferDestroy(&local);
2917
      return code;
×
2918
    }
2919

2920
    code = tDecompressData(data, &cinfo, colData->aOffset, cinfo.originalSize, assist);
3,250,919✔
2921
    if (code) {
3,250,843!
2922
      tBufferDestroy(&local);
2923
      return code;
×
2924
    }
2925

2926
    data += cinfo.compressedSize;
3,250,843✔
2927
  }
2928

2929
  // data
2930
  if (info->dataOriginalSize > 0) {
17,429,777✔
2931
    colData->nData = info->dataOriginalSize;
17,428,703✔
2932

2933
    SCompressInfo cinfo = {
17,428,703✔
2934
        .cmprAlg = info->cmprAlg,
17,428,703✔
2935
        .dataType = colData->type,
17,428,703✔
2936
        .originalSize = info->dataOriginalSize,
17,428,703✔
2937
        .compressedSize = info->dataCompressedSize,
17,428,703✔
2938
    };
2939

2940
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
17,428,703!
2941
    if (code) {
17,429,562!
2942
      tBufferDestroy(&local);
2943
      return code;
×
2944
    }
2945

2946
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
17,429,562✔
2947
    if (code) {
17,428,655!
2948
      tBufferDestroy(&local);
2949
      return code;
×
2950
    }
2951

2952
    data += cinfo.compressedSize;
17,428,655✔
2953
  }
2954

2955
_exit:
1,074✔
2956
  switch (colData->flag) {
20,164,932✔
2957
    case HAS_NONE:
2,473,358✔
2958
      colData->numOfNone = colData->nVal;
2,473,358✔
2959
      break;
2,473,358✔
2960
    case HAS_NULL:
262,675✔
2961
      colData->numOfNull = colData->nVal;
262,675✔
2962
      break;
262,675✔
2963
    case HAS_VALUE:
16,877,737✔
2964
      colData->numOfValue = colData->nVal;
16,877,737✔
2965
      break;
16,877,737✔
2966
    default:
551,162✔
2967
      for (int32_t i = 0; i < colData->nVal; i++) {
430,388,007✔
2968
        uint8_t bitValue = tColDataGetBitValue(colData, i);
429,785,633✔
2969
        if (bitValue == 0) {
429,836,845✔
2970
          colData->numOfNone++;
213,061✔
2971
        } else if (bitValue == 1) {
429,623,784✔
2972
          colData->numOfNull++;
28,480,840✔
2973
        } else {
2974
          colData->numOfValue++;
401,142,944✔
2975
        }
2976
      }
2977
  }
2978
  tBufferDestroy(&local);
2979
  return 0;
20,216,144✔
2980
}
2981

2982
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
574✔
2983
                                    char *data) {
2984
  int32_t code = 0;
574✔
2985
  if (data == NULL) {
574✔
2986
    if (pColData->cflag & COL_IS_KEY) {
13!
2987
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
2988
    } else {
2989
      for (int32_t i = 0; i < nRows; ++i) {
28✔
2990
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
15✔
2991
      }
2992
    }
2993
    goto _exit;
13✔
2994
  }
2995

2996
  if (IS_VAR_DATA_TYPE(type)) {  // var-length data type
561!
2997
    for (int32_t i = 0; i < nRows; ++i) {
281✔
2998
      int32_t offset = *((int32_t *)lengthOrbitmap + i);
181✔
2999
      if (offset == -1) {
181!
3000
        if (pColData->cflag & COL_IS_KEY) {
×
3001
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3002
          goto _exit;
×
3003
        }
3004
        if ((code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0))) {
×
3005
          goto _exit;
×
3006
        }
3007
      } else {
3008
        if (varDataTLen(data + offset) > bytes) {
181!
3009
          uError("var data length invalid, varDataTLen(data + offset):%d > bytes:%d", (int)varDataTLen(data + offset),
×
3010
                 bytes);
3011
          code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3012
          goto _exit;
×
3013
        }
3014
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)varDataVal(data + offset),
181✔
3015
                                                                      varDataLen(data + offset));
181✔
3016
      }
3017
    }
3018
  } else {  // fixed-length data type
3019
    bool allValue = true;
461✔
3020
    bool allNull = true;
461✔
3021
    for (int32_t i = 0; i < nRows; ++i) {
1,296✔
3022
      if (!colDataIsNull_f(lengthOrbitmap, i)) {
835✔
3023
        allNull = false;
622✔
3024
      } else {
3025
        allValue = false;
213✔
3026
      }
3027
    }
3028
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
461!
3029
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3030
      goto _exit;
×
3031
    }
3032

3033
    if (allValue) {
461✔
3034
      // optimize (todo)
3035
      for (int32_t i = 0; i < nRows; ++i) {
975✔
3036
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
608✔
3037
      }
3038
    } else if (allNull) {
94✔
3039
      // optimize (todo)
3040
      for (int32_t i = 0; i < nRows; ++i) {
249✔
3041
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
165✔
3042
        if (code) goto _exit;
165!
3043
      }
3044
    } else {
3045
      for (int32_t i = 0; i < nRows; ++i) {
72✔
3046
        if (colDataIsNull_f(lengthOrbitmap, i)) {
62✔
3047
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
48✔
3048
          if (code) goto _exit;
48!
3049
        } else {
3050
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
14✔
3051
        }
3052
      }
3053
    }
3054
  }
3055

3056
_exit:
10✔
3057
  return code;
574✔
3058
}
3059

3060
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
8,075,673✔
3061
                               checkWKBGeometryFn cgeos) {
3062
  int32_t code = 0;
8,075,673✔
3063

3064
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
8,075,673✔
3065
    if (!(pColData->type == pBind->buffer_type)) {
7,494,790!
3066
      return TSDB_CODE_INVALID_PARA;
×
3067
    }
3068
  }
3069

3070
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
8,075,673!
3071
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
672,271✔
3072
      code = igeos();
203✔
3073
      if (code) {
203!
3074
        return code;
×
3075
      }
3076
    }
3077
    for (int32_t i = 0; i < pBind->num; ++i) {
2,636,118✔
3078
      if (pBind->is_null && pBind->is_null[i]) {
1,861,355✔
3079
        if (pColData->cflag & COL_IS_KEY) {
103,890!
3080
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3081
          goto _exit;
×
3082
        }
3083
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
103,890✔
3084
        if (code) goto _exit;
104,317!
3085
      } else if (pBind->length[i] > buffMaxLen) {
1,757,465!
3086
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3087
      } else {
3088
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
1,757,465✔
3089
          code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]);
206✔
3090
          if (code) {
207✔
3091
            uError("stmt col[%d] bind geometry wrong format", i);
1!
3092
            goto _exit;
1✔
3093
          }
3094
        }
3095
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
1,757,465✔
3096
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
1,757,465✔
3097
      }
3098
    }
3099
  } else {  // fixed-length data type
3100
    bool allValue;
3101
    bool allNull;
3102
    if (pBind->is_null) {
7,403,402✔
3103
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
568,299✔
3104
      allNull = (same && pBind->is_null[0] != 0);
568,299✔
3105
      allValue = (same && pBind->is_null[0] == 0);
568,299✔
3106
    } else {
3107
      allNull = false;
6,835,103✔
3108
      allValue = true;
6,835,103✔
3109
    }
3110

3111
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
7,403,402!
UNCOV
3112
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
UNCOV
3113
      goto _exit;
×
3114
    }
3115

3116
    if (allValue) {
7,403,402✔
3117
      // optimize (todo)
3118
      for (int32_t i = 0; i < pBind->num; ++i) {
244,988,753✔
3119
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
236,481,603✔
3120
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
236,481,603✔
3121
      }
3122
    } else if (allNull) {
373,494!
3123
      // optimize (todo)
3124
      for (int32_t i = 0; i < pBind->num; ++i) {
984,971✔
3125
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
488,087✔
3126
        if (code) goto _exit;
496,707!
3127
      }
3128
    } else {
UNCOV
3129
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3130
        if (pBind->is_null[i]) {
50,012✔
3131
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
4,257✔
3132
          if (code) goto _exit;
4,257!
3133
        } else {
3134
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
45,755✔
3135
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
45,755✔
3136
        }
3137
      }
3138
    }
3139
  }
3140

UNCOV
3141
_exit:
×
3142
  return code;
9,664,028✔
3143
}
3144

3145
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
213✔
3146
                                checkWKBGeometryFn cgeos) {
3147
  int32_t code = 0;
213✔
3148

3149
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
213!
3150
    if (!(pColData->type == pBind->buffer_type)) {
213!
UNCOV
3151
      return TSDB_CODE_INVALID_PARA;
×
3152
    }
3153
  }
3154

3155
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
311!
3156
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
98✔
3157
      code = igeos();
3✔
3158
      if (code) {
3!
UNCOV
3159
        return code;
×
3160
      }
3161
    }
3162

3163
    uint8_t *buf = pBind->buffer;
98✔
3164
    for (int32_t i = 0; i < pBind->num; ++i) {
388✔
3165
      if (pBind->is_null && pBind->is_null[i]) {
290✔
3166
        if (pColData->cflag & COL_IS_KEY) {
2!
3167
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3168
          goto _exit;
×
3169
        }
3170
        if (pBind->is_null[i] == 1) {
2!
3171
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
2✔
3172
          if (code) goto _exit;
2!
3173
        } else {
3174
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3175
          if (code) goto _exit;
×
3176
        }
3177
      } else if (pBind->length[i] > buffMaxLen) {
288!
3178
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3179
      } else {
3180
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
288✔
3181
          code = cgeos(buf, pBind->length[i]);
7✔
3182
          if (code) {
7!
UNCOV
3183
            uError("stmt2 col[%d] bind geometry wrong format", i);
×
UNCOV
3184
            goto _exit;
×
3185
          }
3186
        }
3187
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);
288✔
3188
        buf += pBind->length[i];
288✔
3189
      }
3190
    }
3191
  } else {  // fixed-length data type
3192
    bool allValue;
3193
    bool allNull;
3194
    bool allNone;
3195
    if (pBind->is_null) {
115!
3196
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
×
3197
      allNull = (same && pBind->is_null[0] == 1);
×
UNCOV
3198
      allNone = (same && pBind->is_null[0] > 1);
×
UNCOV
3199
      allValue = (same && pBind->is_null[0] == 0);
×
3200
    } else {
3201
      allNull = false;
115✔
3202
      allNone = false;
115✔
3203
      allValue = true;
115✔
3204
    }
3205

3206
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
115!
3207
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3208
      goto _exit;
×
3209
    }
3210

3211
    if (allValue) {
115!
3212
      // optimize (todo)
3213
      for (int32_t i = 0; i < pBind->num; ++i) {
434✔
3214
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
319✔
3215
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
319!
3216
          *val = 1;
1✔
3217
        }
3218

3219
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
319✔
3220
      }
3221
    } else if (allNull) {
×
3222
      // optimize (todo)
3223
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3224
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3225
        if (code) goto _exit;
×
3226
      }
UNCOV
3227
    } else if (allNone) {
×
3228
      // optimize (todo)
3229
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3230
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3231
        if (code) goto _exit;
×
3232
      }
3233
    } else {
3234
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3235
        if (pBind->is_null[i]) {
×
UNCOV
3236
          if (pBind->is_null[i] == 1) {
×
UNCOV
3237
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3238
            if (code) goto _exit;
×
3239
          } else {
3240
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
UNCOV
3241
            if (code) goto _exit;
×
3242
          }
3243
        } else {
UNCOV
3244
          uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
UNCOV
3245
          if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
UNCOV
3246
            *val = 1;
×
3247
          }
3248

3249
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3250
        }
3251
      }
3252
    }
3253
  }
3254

UNCOV
3255
_exit:
×
3256
  return code;
213✔
3257
}
3258

3259
/* build rows to `rowArray` from bind
3260
 * `infos` is the bind information array
3261
 * `numOfInfos` is the number of bind information
3262
 * `infoSorted` is whether the bind information is sorted by column id
3263
 * `pTSchema` is the schema of the table
3264
 * `rowArray` is the array to store the rows
3265
 * `pOrdered` is the pointer to store ordered
3266
 * `pDupTs` is the pointer to store duplicateTs
3267
 */
3268
int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
5,717✔
3269
                           SArray *rowArray, bool *pOrdered, bool *pDupTs) {
3270
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
5,717!
UNCOV
3271
    return TSDB_CODE_INVALID_PARA;
×
3272
  }
3273

3274
  if (!infoSorted) {
5,735✔
3275
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo2), NULL, tBindInfoCompare);
1✔
3276
  }
3277

3278
  int32_t code = 0;
5,735✔
3279
  int32_t numOfRows = infos[0].bind->num;
5,735✔
3280
  SArray *colValArray, *bufArray;
3281
  SColVal colVal;
3282

3283
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
5,735!
UNCOV
3284
    return terrno;
×
3285
  }
3286
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
5,726✔
3287
    taosArrayDestroy(colValArray);
3✔
3288
    return terrno;
×
3289
  }
3290
  for (int i = 0; i < numOfInfos; ++i) {
28,468✔
3291
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
45,466!
UNCOV
3292
      taosArrayDestroy(colValArray);
×
UNCOV
3293
      taosArrayDestroy(bufArray);
×
UNCOV
3294
      return terrno;
×
3295
    }
3296
  }
3297

3298
  SRowKey rowKey, lastRowKey;
3299
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
228,456!
3300
    taosArrayClear(colValArray);
244,587✔
3301

3302
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
1,060,754✔
3303
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
792,213✔
3304
        if (infos[iInfo].bind->is_null[iRow] == 1) {
2!
3305
          if(iInfo == 0) {
2✔
3306
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
1✔
3307
            goto _exit;
1✔
3308
          }
3309
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
1✔
3310
        } else {
UNCOV
3311
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3312
        }
3313
      } else {
3314
        SValue value = {
792,211✔
3315
            .type = infos[iInfo].type,
792,211✔
3316
        };
3317
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
792,211!
3318
          int32_t   length = infos[iInfo].bind->length[iRow];
6,783✔
3319
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
6,783✔
3320
          value.nData = length;
6,783✔
3321
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
6,783!
UNCOV
3322
            code = TSDB_CODE_INVALID_PARA;
×
UNCOV
3323
            goto _exit;
×
3324
          }
3325
          value.pData = *data;
6,783✔
3326
          *data += length;
6,783✔
3327
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3328
        } else {
3329
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
785,428✔
3330
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
785,428✔
3331
            *val = 1;
1✔
3332
          }
3333
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
785,428✔
3334
        }
3335
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
851,192✔
3336
      }
3337
      if (taosArrayPush(colValArray, &colVal) == NULL) {
817,040!
UNCOV
3338
        code = terrno;
×
3339
        goto _exit;
×
3340
      }
3341
    }
3342

3343
    SRow *row;
3344
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
268,541!
UNCOV
3345
      goto _exit;
×
3346
    }
3347

3348
    if ((taosArrayPush(rowArray, &row)) == NULL) {
222,835!
UNCOV
3349
      code = terrno;
×
UNCOV
3350
      goto _exit;
×
3351
    }
3352

3353
    if (pOrdered && pDupTs) {
222,835!
3354
      tRowGetKey(row, &rowKey);
446,952✔
3355
      if (iRow == 0) {
223,364✔
3356
        *pOrdered = true;
5,718✔
3357
        *pDupTs = false;
5,718✔
3358
      } else {
3359
        if (*pOrdered) {
217,646✔
3360
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
217,621✔
3361
          *pOrdered = (res >= 0);
217,621✔
3362
          if (!*pDupTs) {
217,621!
3363
            *pDupTs = (res == 0);
217,844✔
3364
          }
3365
        }
3366
        lastRowKey = rowKey;
217,646✔
3367
      }
3368
    }
3369
  }
UNCOV
3370
_exit:
×
UNCOV
3371
  taosArrayDestroy(colValArray);
×
3372
  taosArrayDestroy(bufArray);
5,733✔
3373
  return code;
5,751✔
3374
}
3375

3376
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
346✔
3377
  int32_t code = TSDB_CODE_SUCCESS;
346✔
3378

3379
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
346!
3380
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
146✔
3381
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
51✔
3382
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
73✔
3383
    if (iToRow == 0) {
73✔
3384
      pToColData->aOffset[iToRow] = 0;
14✔
3385
    }
3386

3387
    if (iToRow < pToColData->nVal - 1) {
73✔
3388
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
64✔
3389
    }
3390

3391
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
73✔
3392
                 nData);
3393
  } else {
3394
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
273✔
3395
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
273✔
3396
  }
3397
  return code;
346✔
3398
}
3399

3400
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
354✔
3401
                                        int32_t iToRow) {
3402
  int32_t code = TSDB_CODE_SUCCESS;
354✔
3403

3404
  switch (pFromColData->flag) {
354!
3405
    case HAS_NONE:
8✔
3406
    case HAS_NULL:
3407
      break;
8✔
UNCOV
3408
    case (HAS_NULL | HAS_NONE): {
×
UNCOV
3409
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
UNCOV
3410
    } break;
×
3411
    case HAS_VALUE: {
298✔
3412
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
298!
3413
    } break;
298✔
3414
    case (HAS_VALUE | HAS_NONE):
48✔
3415
    case (HAS_VALUE | HAS_NULL): {
3416
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
48✔
3417
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
48!
3418
    } break;
48✔
UNCOV
3419
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
UNCOV
3420
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
UNCOV
3421
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
UNCOV
3422
    } break;
×
UNCOV
3423
    default:
×
UNCOV
3424
      return -1;
×
3425
  }
3426

3427
  return code;
354✔
3428
}
3429

3430
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
75✔
3431
                               int32_t nColData) {
3432
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3433

3434
  for (int32_t i = 0; i < nColData; i++) {
429✔
3435
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
354✔
3436
    if (code != TSDB_CODE_SUCCESS) {
354!
UNCOV
3437
      return code;
×
3438
    }
3439
  }
3440

3441
  return code;
75✔
3442
}
3443

3444
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
75✔
3445
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3446

3447
  for (int32_t i = 0; i < nColData; i++) {
429✔
3448
    SColVal cv = {0};
354✔
3449
    code = tColDataGetValue(&aFromColData[i], iFromRow, &cv);
354✔
3450
    if (code != TSDB_CODE_SUCCESS) {
354!
UNCOV
3451
      return code;
×
3452
    }
3453
    code = tColDataAppendValue(&aToColData[i], &cv);
354✔
3454
    if (code != TSDB_CODE_SUCCESS) {
354!
UNCOV
3455
      return code;
×
3456
    }
3457
  }
3458

3459
  return code;
75✔
3460
}
3461

3462
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
228,535,303✔
3463
  SColVal cv;
3464

3465
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
228,535,303✔
3466
  key->numOfPKs = 0;
228,535,303✔
3467

3468
  for (int i = 1; i < nColData; i++) {
228,553,104!
3469
    if (aColData[i].cflag & COL_IS_KEY) {
229,392,951✔
3470
      tColDataGetValue4(&aColData[i], iRow, &cv);
15,925!
3471
      key->pks[key->numOfPKs++] = cv.value;
17,801✔
3472
    } else {
3473
      break;
229,377,026✔
3474
    }
3475
  }
3476
}
228,537,179✔
3477

3478
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
23✔
3479
  SColData *aDstColData = NULL;
23✔
3480
  int32_t   i = start, j = mid + 1, k = 0;
23✔
3481
  SRowKey   keyi, keyj;
3482

3483
  if (end > start) {
23!
3484
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
23!
3485
    if (aDstColData == NULL) {
23!
UNCOV
3486
      return terrno;
×
3487
    }
3488
    for (int c = 0; c < nColData; ++c) {
129✔
3489
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
106✔
3490
    }
3491
  }
3492

3493
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
23✔
3494
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
23✔
3495
  while (i <= mid && j <= end) {
63✔
3496
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
40✔
3497
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
30!
3498
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
30✔
3499
    } else {
3500
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
10!
3501
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
10✔
3502
    }
3503
  }
3504

3505
  while (i <= mid) {
35✔
3506
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
12!
3507
  }
3508

3509
  while (j <= end) {
46✔
3510
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
23!
3511
  }
3512

3513
  for (i = start, k = 0; i <= end; ++i, ++k) {
98✔
3514
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
75!
3515
  }
3516

3517
  if (aDstColData) {
23!
3518
    for (int32_t i = 0; i < nColData; i++) {
129✔
3519
      tColDataDestroy(&aDstColData[i]);
106✔
3520
    }
3521
    taosMemoryFree(aDstColData);
23!
3522
  }
3523

3524
  return TSDB_CODE_SUCCESS;
23✔
3525
}
3526

3527
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
52✔
3528
  int32_t ret = TSDB_CODE_SUCCESS;
52✔
3529
  int32_t mid;
3530

3531
  if (start >= end) {
52✔
3532
    return TSDB_CODE_SUCCESS;
29✔
3533
  }
3534

3535
  mid = (start + end) / 2;
23✔
3536

3537
  ret = tColDataMergeSort(aColData, start, mid, nColData);
23✔
3538
  if (ret != TSDB_CODE_SUCCESS) {
23!
UNCOV
3539
    return ret;
×
3540
  }
3541

3542
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
23✔
3543
  if (ret != TSDB_CODE_SUCCESS) {
23!
UNCOV
3544
    return ret;
×
3545
  }
3546

3547
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
23✔
3548
}
3549

3550
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
6✔
3551
  int32_t nVal = aColData[0].nVal;
6✔
3552

3553
  if (nVal < 2) return TSDB_CODE_SUCCESS;
6!
3554

3555
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
6✔
3556
}
3557

3558
static int32_t tColDataMerge(SArray **colArr) {
3✔
3559
  int32_t code = 0;
3✔
3560
  SArray *src = *colArr;
3✔
3561
  SArray *dst = NULL;
3✔
3562

3563
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
3✔
3564
  if (dst == NULL) {
3!
UNCOV
3565
    return terrno;
×
3566
  }
3567

3568
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
12✔
3569
    SColData *srcCol = taosArrayGet(src, i);
9✔
3570

3571
    SColData *dstCol = taosArrayReserve(dst, 1);
9✔
3572
    if (dstCol == NULL) {
9!
UNCOV
3573
      code = terrno;
×
UNCOV
3574
      goto _exit;
×
3575
    }
3576
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
9✔
3577
  }
3578

3579
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
3✔
3580
  SRowKey lastKey;
3581
  for (int32_t i = 0; i < numRows; i++) {
9✔
3582
    SRowKey key;
3583
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
3584

3585
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
9!
3586
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3587
        SColData *srcCol = taosArrayGet(src, j);
9✔
3588
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3589

3590
        SColVal cv;
3591
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3592
        if (code != TSDB_CODE_SUCCESS) {
9!
UNCOV
3593
          goto _exit;
×
3594
        }
3595
        code = tColDataAppendValue(dstCol, &cv);
9✔
3596
        if (code) {
9!
UNCOV
3597
          goto _exit;
×
3598
        }
3599
      }
3600
      lastKey = key;
3✔
3601
    } else {  // update existing row
3602
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3603
        SColData *srcCol = taosArrayGet(src, j);
9✔
3604
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3605

3606
        SColVal cv;
3607
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3608
        if (code != TSDB_CODE_SUCCESS) {
9!
UNCOV
3609
          goto _exit;
×
3610
        }
3611
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3612
        if (code) {
9!
UNCOV
3613
          goto _exit;
×
3614
        }
3615
      }
3616
    }
3617
  }
3618

3619
_exit:
3✔
3620
  if (code) {
3!
UNCOV
3621
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3622
  } else {
3623
    taosArrayDestroyEx(src, tColDataDestroy);
3✔
3624
    *colArr = dst;
3✔
3625
  }
3626
  return code;
3✔
3627
}
3628

3629
int32_t tColDataSortMerge(SArray **arr) {
40,738✔
3630
  SArray   *colDataArr = *arr;
40,738✔
3631
  int32_t   nColData = TARRAY_SIZE(colDataArr);
40,738✔
3632
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
40,738✔
3633

3634
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
40,738!
3635
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3636
  }
3637
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
40,738!
UNCOV
3638
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3639
  }
3640
  if (!(aColData[0].flag == HAS_VALUE)) {
40,738!
UNCOV
3641
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3642
  }
3643

3644
  if (aColData[0].nVal <= 1) goto _exit;
40,738✔
3645

3646
  int8_t doSort = 0;
40,533✔
3647
  int8_t doMerge = 0;
40,533✔
3648
  // scan -------
3649
  SRowKey lastKey;
3650
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
40,533✔
3651
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
106,502,802!
3652
    SRowKey key;
3653
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
107,527,823✔
3654

3655
    int32_t c = tRowKeyCompare(&lastKey, &key);
106,462,275✔
3656
    if (c < 0) {
106,462,275✔
3657
      lastKey = key;
106,451,813✔
3658
      continue;
106,451,813✔
3659
    } else if (c > 0) {
10,462✔
3660
      doSort = 1;
6✔
3661
      break;
6✔
3662
    } else {
3663
      doMerge = 1;
10,456✔
3664
    }
3665
  }
3666

3667
  // sort -------
UNCOV
3668
  if (doSort) {
×
3669
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
6!
3670
  }
3671

3672
  if (doMerge != 1) {
1,744,682✔
3673
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
40,552✔
3674
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
106,454,796!
3675
      SRowKey key;
3676
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
108,118,374✔
3677

3678
      int32_t c = tRowKeyCompare(&lastKey, &key);
106,414,245✔
3679
      if (c == 0) {
106,414,245!
UNCOV
3680
        doMerge = 1;
×
UNCOV
3681
        break;
×
3682
      }
3683
      lastKey = key;
106,414,245✔
3684
    }
3685
  }
3686

3687
  // merge -------
3688
  if (doMerge) {
40,552✔
3689
    int32_t code = tColDataMerge(arr);
3✔
3690
    if (code) return code;
3!
3691
  }
3692

3693
_exit:
40,552✔
3694
  return 0;
40,757✔
3695
}
3696

3697
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
248,634✔
3698
  int32_t code = 0;
248,634✔
3699

3700
  if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
497,268!
3701
  if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
497,268!
3702
  if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
497,268!
3703
  if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
497,268!
3704

3705
  // bitmap
3706
  switch (pColData->flag) {
248,634!
3707
    case (HAS_NULL | HAS_NONE):
2,144✔
3708
    case (HAS_VALUE | HAS_NONE):
3709
    case (HAS_VALUE | HAS_NULL):
3710
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
2,144✔
3711
      if (code) return code;
2,144!
3712
      break;
2,144✔
UNCOV
3713
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
UNCOV
3714
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
UNCOV
3715
      if (code) return code;
×
UNCOV
3716
      break;
×
3717
    default:
246,490✔
3718
      break;
246,490✔
3719
  }
3720

3721
  // value
3722
  if (pColData->flag & HAS_VALUE) {
248,634✔
3723
    if (IS_VAR_DATA_TYPE(pColData->type)) {
248,260!
3724
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
1,410✔
3725
      if (code) return code;
1,410!
3726

3727
      code = tEncodeI32v(pEncoder, pColData->nData);
1,410✔
3728
      if (code) return code;
1,410!
3729

3730
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
1,410✔
3731
      if (code) return code;
1,410!
3732
    } else {
3733
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
246,850✔
3734
      if (code) return code;
246,850!
3735
    }
3736
  }
3737

3738
  return code;
248,634✔
3739
}
3740

3741
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
74,417✔
3742
  int32_t code = 0;
74,417✔
3743

3744
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
148,830!
3745
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
148,819!
3746
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
148,804!
3747
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
148,793!
3748

3749
  if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
74,395!
UNCOV
3750
    return TSDB_CODE_INVALID_PARA;
×
3751
  }
3752

3753
  // bitmap
3754
  switch (pColData->flag) {
74,399!
3755
    case (HAS_NULL | HAS_NONE):
416✔
3756
    case (HAS_VALUE | HAS_NONE):
3757
    case (HAS_VALUE | HAS_NULL):
3758
      code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
416!
3759
      if (code) return code;
416!
3760
      break;
416✔
UNCOV
3761
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
UNCOV
3762
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
UNCOV
3763
      if (code) return code;
×
UNCOV
3764
      break;
×
3765
    default:
73,983✔
3766
      break;
73,983✔
3767
  }
3768

3769
  // value
3770
  if (pColData->flag & HAS_VALUE) {
74,399✔
3771
    if (IS_VAR_DATA_TYPE(pColData->type)) {
73,963!
3772
      code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
611!
3773
      if (code) return code;
611!
3774

3775
      code = tDecodeI32v(pDecoder, &pColData->nData);
611✔
3776
      if (code) return code;
610!
3777

3778
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
610!
3779
      if (code) return code;
610!
3780
    } else {
3781
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
73,352✔
3782
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
73,352!
3783
      if (code) return code;
73,352!
3784
    }
3785
  }
3786
  pColData->cflag = 0;
74,398✔
3787

3788
  return code;
74,398✔
3789
}
3790

3791
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
248,653✔
3792
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
248,653✔
3793
  if (code) return code;
248,695!
3794
  return tEncodeI8(pEncoder, pColData->cflag);
497,390✔
3795
}
3796

3797
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
74,417✔
3798
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
74,417✔
3799
  if (code) return code;
74,398!
3800

3801
  code = tDecodeI8(pDecoder, &pColData->cflag);
74,398✔
3802
  return code;
74,397✔
3803
}
3804

3805
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
248,639✔
3806
  if (version == 0) {
248,639!
UNCOV
3807
    return tEncodeColDataVersion0(pEncoder, pColData);
×
3808
  } else if (version == 1) {
248,639!
3809
    return tEncodeColDataVersion1(pEncoder, pColData);
248,657✔
3810
  } else {
3811
    return TSDB_CODE_INVALID_PARA;
×
3812
  }
3813
}
3814

3815
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
74,417✔
3816
  if (version == 0) {
74,417!
UNCOV
3817
    return tDecodeColDataVersion0(pDecoder, pColData);
×
3818
  } else if (version == 1) {
74,417!
3819
    return tDecodeColDataVersion1(pDecoder, pColData);
74,417✔
3820
  } else {
UNCOV
3821
    return TSDB_CODE_INVALID_PARA;
×
3822
  }
3823
}
3824

3825
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow) { return tEncodeFixed(pEncoder, pRow, pRow->len); }
2,147,483,647✔
3826

3827
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
929,986,831✔
3828
  if (ppRow == NULL) {
929,986,831!
UNCOV
3829
    return TSDB_CODE_INVALID_PARA;
×
3830
  }
3831

3832
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
929,986,831!
UNCOV
3833
    return TSDB_CODE_OUT_OF_RANGE;
×
3834
  }
3835

3836
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
929,986,831✔
3837
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
1,859,973,662!
3838
}
3839

3840
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3841
  do {                                       \
3842
    (SUM) += (VAL);                          \
3843
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3844
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3845
  } while (0)
3846

3847
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, SColumnDataAgg* pAggs) {
5,563✔
3848
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,563✔
3849
  int16_t*numOfNull = &pAggs->numOfNull;
5,563✔
3850
  *sum = 0;
5,563✔
3851
  *max = 0;
5,563✔
3852
  *min = 1;
5,563✔
3853
  *numOfNull = 0;
5,563✔
3854

3855
  int8_t val;
3856
  if (HAS_VALUE == pColData->flag) {
5,563!
3857
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,947,373✔
3858
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
3,941,810✔
3859
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
3,941,810✔
3860
    }
3861
  } else {
3862
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3863
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3864
        case 0:
×
3865
        case 1:
3866
          (*numOfNull)++;
×
3867
          break;
×
UNCOV
3868
        case 2:
×
UNCOV
3869
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
×
UNCOV
3870
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
UNCOV
3871
          break;
×
UNCOV
3872
        default:
×
UNCOV
3873
          break;
×
3874
      }
3875
    }
3876
  }
3877
}
5,563✔
3878

3879
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, SColumnDataAgg* pAggs) {
5,733✔
3880
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,733✔
3881
  int16_t *numOfNull = &pAggs->numOfNull;
5,733✔
3882
  *sum = 0;
5,733✔
3883
  *max = INT8_MIN;
5,733✔
3884
  *min = INT8_MAX;
5,733✔
3885
  *numOfNull = 0;
5,733✔
3886

3887
  int8_t val;
3888
  if (HAS_VALUE == pColData->flag) {
5,733!
3889
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,235,638✔
3890
      val = ((int8_t *)pColData->pData)[iVal];
4,229,905✔
3891
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,229,905✔
3892
    }
3893
  } else {
3894
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3895
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3896
        case 0:
×
3897
        case 1:
3898
          (*numOfNull)++;
×
3899
          break;
×
UNCOV
3900
        case 2:
×
UNCOV
3901
          val = ((int8_t *)pColData->pData)[iVal];
×
UNCOV
3902
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
UNCOV
3903
          break;
×
UNCOV
3904
        default:
×
UNCOV
3905
          break;
×
3906
      }
3907
    }
3908
  }
3909
}
5,733✔
3910

3911
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, SColumnDataAgg* pAggs) {
5,599✔
3912
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,599✔
3913
  int16_t *numOfNull = &pAggs->numOfNull;
5,599✔
3914
  *sum = 0;
5,599✔
3915
  *max = INT16_MIN;
5,599✔
3916
  *min = INT16_MAX;
5,599✔
3917
  *numOfNull = 0;
5,599✔
3918

3919
  int16_t val;
3920
  if (HAS_VALUE == pColData->flag) {
5,599!
3921
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,066,740✔
3922
      val = ((int16_t *)pColData->pData)[iVal];
4,061,141✔
3923
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,061,141✔
3924
    }
3925
  } else {
3926
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3927
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3928
        case 0:
×
3929
        case 1:
3930
          (*numOfNull)++;
×
3931
          break;
×
UNCOV
3932
        case 2:
×
UNCOV
3933
          val = ((int16_t *)pColData->pData)[iVal];
×
UNCOV
3934
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
UNCOV
3935
          break;
×
UNCOV
3936
        default:
×
UNCOV
3937
          break;
×
3938
      }
3939
    }
3940
  }
3941
}
5,599✔
3942

3943
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, SColumnDataAgg* pAggs) {
326,645✔
3944
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
326,645✔
3945
  int16_t *numOfNull = &pAggs->numOfNull;
326,645✔
3946
  *sum = 0;
326,645✔
3947
  *max = INT32_MIN;
326,645✔
3948
  *min = INT32_MAX;
326,645✔
3949
  *numOfNull = 0;
326,645✔
3950

3951
  int32_t val;
3952
  if (HAS_VALUE == pColData->flag) {
326,645✔
3953
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
875,956,749✔
3954
      val = ((int32_t *)pColData->pData)[iVal];
875,703,429✔
3955
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
875,703,429✔
3956
    }
3957
  } else {
3958
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
247,750,319✔
3959
      switch (tColDataGetBitValue(pColData, iVal)) {
247,676,603!
3960
        case 0:
13,135,532✔
3961
        case 1:
3962
          (*numOfNull)++;
13,135,532✔
3963
          break;
13,135,532✔
3964
        case 2:
234,563,852✔
3965
          val = ((int32_t *)pColData->pData)[iVal];
234,563,852✔
3966
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
234,563,852✔
3967
          break;
234,563,852✔
UNCOV
3968
        default:
×
UNCOV
3969
          break;
×
3970
      }
3971
    }
3972
  }
3973
}
327,036✔
3974

3975
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, SColumnDataAgg* pAggs) {
110,930✔
3976
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
110,930✔
3977
  int16_t *numOfNull = &pAggs->numOfNull;
110,930✔
3978
  *sum = 0;
110,930✔
3979
  *max = INT64_MIN;
110,930✔
3980
  *min = INT64_MAX;
110,930✔
3981
  *numOfNull = 0;
110,930✔
3982

3983
  int64_t val;
3984
  if (HAS_VALUE == pColData->flag) {
110,930✔
3985
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
336,150,863✔
3986
      val = ((int64_t *)pColData->pData)[iVal];
336,044,070✔
3987
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
336,044,070✔
3988
    }
3989
  } else {
3990
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
15,054,109✔
3991
      switch (tColDataGetBitValue(pColData, iVal)) {
15,051,114!
3992
        case 0:
1,572,009✔
3993
        case 1:
3994
          (*numOfNull)++;
1,572,009✔
3995
          break;
1,572,009✔
3996
        case 2:
13,480,936✔
3997
          val = ((int64_t *)pColData->pData)[iVal];
13,480,936✔
3998
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
13,480,936✔
3999
          break;
13,480,936✔
UNCOV
4000
        default:
×
UNCOV
4001
          break;
×
4002
      }
4003
    }
4004
  }
4005
}
109,788✔
4006

4007
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, SColumnDataAgg* pAggs) {
229,761✔
4008
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
229,761✔
4009
  int16_t *numOfNull = &pAggs->numOfNull;
229,761✔
4010
  *(double *)sum = 0;
229,761✔
4011
  *(double *)max = -FLT_MAX;
229,761✔
4012
  *(double *)min = FLT_MAX;
229,761✔
4013
  *numOfNull = 0;
229,761✔
4014

4015
  float val;
4016
  if (HAS_VALUE == pColData->flag) {
229,761✔
4017
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
920,662,452✔
4018
      val = ((float *)pColData->pData)[iVal];
920,432,692✔
4019
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
920,432,692✔
4020
    }
4021
  } else {
4022
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
106✔
4023
      switch (tColDataGetBitValue(pColData, iVal)) {
105!
4024
        case 0:
95✔
4025
        case 1:
4026
          (*numOfNull)++;
95✔
4027
          break;
95✔
4028
        case 2:
10✔
4029
          val = ((float *)pColData->pData)[iVal];
10✔
4030
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
10!
4031
          break;
10✔
UNCOV
4032
        default:
×
UNCOV
4033
          break;
×
4034
      }
4035
    }
4036
  }
4037
}
229,761✔
4038

4039
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, SColumnDataAgg* pAggs) {
20,316✔
4040
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
20,316✔
4041
  int16_t *numOfNull = &pAggs->numOfNull;
20,316✔
4042
  *(double *)sum = 0;
20,316✔
4043
  *(double *)max = -DBL_MAX;
20,316✔
4044
  *(double *)min = DBL_MAX;
20,316✔
4045
  *numOfNull = 0;
20,316✔
4046

4047
  double val;
4048
  if (HAS_VALUE == pColData->flag) {
20,316!
4049
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
32,369,295✔
4050
      val = ((double *)pColData->pData)[iVal];
32,348,979✔
4051
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
32,348,979✔
4052
    }
4053
  } else {
4054
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4055
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4056
        case 0:
×
4057
        case 1:
4058
          (*numOfNull)++;
×
4059
          break;
×
UNCOV
4060
        case 2:
×
UNCOV
4061
          val = ((double *)pColData->pData)[iVal];
×
UNCOV
4062
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
×
UNCOV
4063
          break;
×
UNCOV
4064
        default:
×
UNCOV
4065
          break;
×
4066
      }
4067
    }
4068
  }
4069
}
20,316✔
4070

4071
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,673✔
4072
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,673✔
4073
  int16_t *numOfNull = &pAggs->numOfNull;
2,673✔
4074
  *(uint64_t *)sum = 0;
2,673✔
4075
  *(uint64_t *)max = 0;
2,673✔
4076
  *(uint64_t *)min = UINT8_MAX;
2,673✔
4077
  *numOfNull = 0;
2,673✔
4078

4079
  uint8_t val;
4080
  if (HAS_VALUE == pColData->flag) {
2,673!
4081
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,181,609✔
4082
      val = ((uint8_t *)pColData->pData)[iVal];
3,178,936✔
4083
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,178,936✔
4084
    }
4085
  } else {
4086
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4087
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4088
        case 0:
×
4089
        case 1:
4090
          (*numOfNull)++;
×
4091
          break;
×
UNCOV
4092
        case 2:
×
UNCOV
4093
          val = ((uint8_t *)pColData->pData)[iVal];
×
UNCOV
4094
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
UNCOV
4095
          break;
×
UNCOV
4096
        default:
×
UNCOV
4097
          break;
×
4098
      }
4099
    }
4100
  }
4101
}
2,673✔
4102

4103
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,673✔
4104
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,673✔
4105
  int16_t *numOfNull = &pAggs->numOfNull;
2,673✔
4106
  *(uint64_t *)sum = 0;
2,673✔
4107
  *(uint64_t *)max = 0;
2,673✔
4108
  *(uint64_t *)min = UINT16_MAX;
2,673✔
4109
  *numOfNull = 0;
2,673✔
4110

4111
  uint16_t val;
4112
  if (HAS_VALUE == pColData->flag) {
2,673!
4113
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,181,632✔
4114
      val = ((uint16_t *)pColData->pData)[iVal];
3,178,959✔
4115
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,178,959✔
4116
    }
4117
  } else {
4118
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4119
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4120
        case 0:
×
4121
        case 1:
4122
          (*numOfNull)++;
×
4123
          break;
×
UNCOV
4124
        case 2:
×
UNCOV
4125
          val = ((uint16_t *)pColData->pData)[iVal];
×
UNCOV
4126
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
UNCOV
4127
          break;
×
UNCOV
4128
        default:
×
UNCOV
4129
          break;
×
4130
      }
4131
    }
4132
  }
4133
}
2,673✔
4134

4135
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,673✔
4136
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,673✔
4137
  int16_t *numOfNull = &pAggs->numOfNull;
2,673✔
4138
  *(uint64_t *)sum = 0;
2,673✔
4139
  *(uint64_t *)max = 0;
2,673✔
4140
  *(uint64_t *)min = UINT32_MAX;
2,673✔
4141
  *numOfNull = 0;
2,673✔
4142

4143
  uint32_t val;
4144
  if (HAS_VALUE == pColData->flag) {
2,673!
4145
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,181,610✔
4146
      val = ((uint32_t *)pColData->pData)[iVal];
3,178,937✔
4147
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,178,937✔
4148
    }
4149
  } else {
4150
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4151
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4152
        case 0:
×
4153
        case 1:
4154
          (*numOfNull)++;
×
4155
          break;
×
UNCOV
4156
        case 2:
×
UNCOV
4157
          val = ((uint32_t *)pColData->pData)[iVal];
×
UNCOV
4158
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
UNCOV
4159
          break;
×
UNCOV
4160
        default:
×
UNCOV
4161
          break;
×
4162
      }
4163
    }
4164
  }
4165
}
2,673✔
4166

4167
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,673✔
4168
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,673✔
4169
  int16_t *numOfNull = &pAggs->numOfNull;
2,673✔
4170
  *(uint64_t *)sum = 0;
2,673✔
4171
  *(uint64_t *)max = 0;
2,673✔
4172
  *(uint64_t *)min = UINT64_MAX;
2,673✔
4173
  *numOfNull = 0;
2,673✔
4174

4175
  uint64_t val;
4176
  if (HAS_VALUE == pColData->flag) {
2,673!
4177
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,181,632✔
4178
      val = ((uint64_t *)pColData->pData)[iVal];
3,178,959✔
4179
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,178,959✔
4180
    }
4181
  } else {
4182
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4183
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4184
        case 0:
×
4185
        case 1:
4186
          (*numOfNull)++;
×
4187
          break;
×
UNCOV
4188
        case 2:
×
UNCOV
4189
          val = ((uint64_t *)pColData->pData)[iVal];
×
UNCOV
4190
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
UNCOV
4191
          break;
×
UNCOV
4192
        default:
×
UNCOV
4193
          break;
×
4194
      }
4195
    }
4196
  }
4197
}
2,673✔
4198

4199
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, SColumnDataAgg* pAggs) {
17,533✔
4200
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
17,533✔
4201
  int16_t *numOfNull = &pAggs->numOfNull;
17,533✔
4202
  *(uint64_t *)sum = 0;
17,533✔
4203
  *(uint64_t *)max = 0;
17,533✔
4204
  *(uint64_t *)min = 0;
17,533✔
4205
  *numOfNull = 0;
17,533✔
4206

4207
  switch (pColData->flag) {
17,533!
UNCOV
4208
    case HAS_NONE:
×
4209
    case HAS_NULL:
4210
    case (HAS_NONE | HAS_NULL):
UNCOV
4211
      *numOfNull = pColData->nVal;
×
4212
      break;
×
4213
    case HAS_VALUE:
17,533✔
4214
      *numOfNull = 0;
17,533✔
4215
      break;
17,533✔
UNCOV
4216
    case (HAS_VALUE | HAS_NULL):
×
4217
    case (HAS_VALUE | HAS_NONE):
4218
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4219
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
×
4220
          (*numOfNull)++;
×
4221
        }
4222
      }
UNCOV
4223
      break;
×
4224
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4225
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4226
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
UNCOV
4227
          (*numOfNull)++;
×
4228
        }
4229
      }
UNCOV
4230
      break;
×
UNCOV
4231
    default:
×
UNCOV
4232
      break;
×
4233
  }
4234
}
17,533✔
4235

4236
#define CALC_DECIMAL_SUM_MAX_MIN(TYPE, pSumOp, pCompOp, pColData, pSum, pMax, pMin)           \
4237
  do {                                                                                        \
4238
    if (decimal128AddCheckOverflow((Decimal *)pSum, pVal, DECIMAL_WORD_NUM(TYPE))) *pOverflow = true; \
4239
    pSumOp->add(pSum, pVal, DECIMAL_WORD_NUM(TYPE));                                                  \
4240
    if (pCompOp->gt(pVal, pMax, DECIMAL_WORD_NUM(TYPE))) {                                            \
4241
      *(pMax) = *pVal;                                                                        \
4242
    }                                                                                         \
4243
    if (pCompOp->lt(pVal, pMin, DECIMAL_WORD_NUM(TYPE))) {                                            \
4244
      *(pMin) = *pVal;                                                                        \
4245
    }                                                                                         \
4246
  } while (0)
4247

4248
static FORCE_INLINE void tColDataCalcSMADecimal64Type(SColData* pColData, SColumnDataAgg* pAggs) {
159✔
4249
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum;
159✔
4250
  Decimal64  *pMax = (Decimal64 *)pAggs->decimal128Max, *pMin = (Decimal64 *)pAggs->decimal128Min;
159✔
4251
  uint8_t *pOverflow = &pAggs->overflow;
159✔
4252
  *pSum = DECIMAL128_ZERO;
159✔
4253
  *pMax = DECIMAL64_MIN;
159✔
4254
  *pMin = DECIMAL64_MAX;
159✔
4255
  pAggs->numOfNull = 0;
159✔
4256
  pAggs->colId |= DECIMAL_AGG_FLAG;
159✔
4257

4258
  Decimal64   *pVal = NULL;
159✔
4259
  const SDecimalOps *pSumOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
159✔
4260
  const SDecimalOps *pCompOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
159✔
4261
  if (HAS_VALUE == pColData->flag) {
159✔
4262
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
1,111✔
4263
      pVal = ((Decimal64*)pColData->pData) + iVal;
1,100✔
4264
      CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
1,100!
4265
    }
4266
  } else {
4267
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
122,048✔
4268
      switch (tColDataGetBitValue(pColData, iVal)) {
121,900!
4269
        case 0:
1,968✔
4270
        case 1:
4271
          pAggs->numOfNull++;
1,968✔
4272
          break;
1,968✔
4273
        case 2:
119,932✔
4274
          pVal = ((Decimal64 *)pColData->pData) + iVal;
119,932✔
4275
          CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
119,932!
4276
          break;
119,932✔
UNCOV
4277
        default:
×
UNCOV
4278
          break;
×
4279
      }
4280
    }
4281
  }
4282
}
159✔
4283

4284
static FORCE_INLINE void tColDataCalcSMADecimal128Type(SColData* pColData, SColumnDataAgg* pAggs) {
423✔
4285
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum, *pMax = (Decimal128 *)pAggs->decimal128Max,
423✔
4286
             *pMin = (Decimal128 *)pAggs->decimal128Min;
423✔
4287
  uint8_t *pOverflow = &pAggs->overflow;
423✔
4288
  *pSum = DECIMAL128_ZERO;
423✔
4289
  *pMax = DECIMAL128_MIN;
423✔
4290
  *pMin = DECIMAL128_MAX;
423✔
4291
  pAggs->numOfNull = 0;
423✔
4292
  pAggs->colId |= DECIMAL_AGG_FLAG;
423✔
4293

4294
  Decimal128        *pVal = NULL;
423✔
4295
  const SDecimalOps *pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
423✔
4296
  if (HAS_VALUE == pColData->flag) {
423✔
4297
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
1,313✔
4298
      pVal = ((Decimal128*)pColData->pData) + iVal;
1,300✔
4299
      CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
1,300✔
4300
    }
4301
  } else {
4302
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
386,110✔
4303
      switch (tColDataGetBitValue(pColData, iVal)) {
385,700!
4304
        case 0:
6,185✔
4305
        case 1:
4306
          pAggs->numOfNull++;
6,185✔
4307
          break;
6,185✔
4308
        case 2:
379,515✔
4309
          pVal = ((Decimal128*)pColData->pData) + iVal;
379,515✔
4310
          CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
379,515✔
4311
          break;
379,515✔
UNCOV
4312
        default:
×
UNCOV
4313
          break;
×
4314
      }
4315
    }
4316
  }
4317
}
423✔
4318

4319
void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAgg* pAggs) = {
4320
    NULL,
4321
    tColDataCalcSMABool,           // TSDB_DATA_TYPE_BOOL
4322
    tColDataCalcSMATinyInt,        // TSDB_DATA_TYPE_TINYINT
4323
    tColDataCalcSMATinySmallInt,   // TSDB_DATA_TYPE_SMALLINT
4324
    tColDataCalcSMAInt,            // TSDB_DATA_TYPE_INT
4325
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_BIGINT
4326
    tColDataCalcSMAFloat,          // TSDB_DATA_TYPE_FLOAT
4327
    tColDataCalcSMADouble,         // TSDB_DATA_TYPE_DOUBLE
4328
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARCHAR
4329
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_TIMESTAMP
4330
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_NCHAR
4331
    tColDataCalcSMAUTinyInt,       // TSDB_DATA_TYPE_UTINYINT
4332
    tColDataCalcSMATinyUSmallInt,  // TSDB_DATA_TYPE_USMALLINT
4333
    tColDataCalcSMAUInt,           // TSDB_DATA_TYPE_UINT
4334
    tColDataCalcSMAUBigInt,        // TSDB_DATA_TYPE_UBIGINT
4335
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_JSON
4336
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARBINARY
4337
    tColDataCalcSMADecimal128Type, // TSDB_DATA_TYPE_DECIMAL
4338
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_BLOB
4339
    NULL,                          // TSDB_DATA_TYPE_MEDIUMBLOB
4340
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_GEOMETRY
4341
    tColDataCalcSMADecimal64Type,  // TSDB_DATA_TYPE_DECIMAL64
4342
};
4343

4344
// SValueColumn ================================
4345
int32_t tValueColumnInit(SValueColumn *valCol) {
18,101,508✔
4346
  valCol->type = TSDB_DATA_TYPE_NULL;
18,101,508✔
4347
  valCol->numOfValues = 0;
18,101,508✔
4348
  tBufferInit(&valCol->data);
18,101,508✔
4349
  tBufferInit(&valCol->offsets);
18,101,508✔
4350
  return 0;
18,101,508✔
4351
}
4352

4353
void tValueColumnDestroy(SValueColumn *valCol) {
42,311,809✔
4354
  valCol->type = TSDB_DATA_TYPE_NULL;
42,311,809✔
4355
  valCol->numOfValues = 0;
42,311,809✔
4356
  tBufferDestroy(&valCol->data);
42,311,809✔
4357
  tBufferDestroy(&valCol->offsets);
42,311,810✔
4358
  return;
42,311,810✔
4359
}
4360

4361
void tValueColumnClear(SValueColumn *valCol) {
21,409,359✔
4362
  valCol->type = TSDB_DATA_TYPE_NULL;
21,409,359✔
4363
  valCol->numOfValues = 0;
21,409,359✔
4364
  tBufferClear(&valCol->data);
21,409,359✔
4365
  tBufferClear(&valCol->offsets);
21,409,359✔
4366
  return;
21,409,359✔
4367
}
4368

4369
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
1,005,264✔
4370
  int32_t code;
4371

4372
  if (valCol->numOfValues == 0) {
1,005,264✔
4373
    valCol->type = value->type;
4,688✔
4374
  }
4375

4376
  if (!(value->type == valCol->type)) {
1,005,264!
UNCOV
4377
    return TSDB_CODE_INVALID_PARA;
×
4378
  }
4379

4380
  if (IS_VAR_DATA_TYPE(value->type)) {
1,005,264!
4381
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
20!
UNCOV
4382
      return code;
×
4383
    }
4384
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
20!
UNCOV
4385
      return code;
×
4386
    }
4387
  } else {
4388
    code = tBufferPut(&valCol->data, VALUE_GET_DATUM(value, value->type), tDataTypes[value->type].bytes);
1,005,254!
4389
    if (code) return code;
1,005,254!
4390
  }
4391
  valCol->numOfValues++;
1,005,264✔
4392

4393
  return 0;
1,005,264✔
4394
}
4395

4396
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
274,330,466✔
4397
  int32_t code;
4398

4399
  if (idx < 0 || idx >= valCol->numOfValues) {
274,330,466!
4400
    return TSDB_CODE_OUT_OF_RANGE;
×
4401
  }
4402

4403
  if (IS_VAR_DATA_TYPE(valCol->type)) {
274,344,249!
4404
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
×
4405
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
×
4406
    int32_t  oldDataSize = nextOffset - offsets[idx];
×
4407
    int32_t  bytesAdded = value->nData - oldDataSize;
×
4408

4409
    if (bytesAdded != 0) {
×
4410
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
×
UNCOV
4411
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
×
UNCOV
4412
              tBufferGetSize(&valCol->data) - nextOffset);
×
4413
      valCol->data.size += bytesAdded;
×
4414

UNCOV
4415
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
×
UNCOV
4416
        offsets[i] += bytesAdded;
×
4417
      }
4418
    }
UNCOV
4419
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
×
4420
  } else {
4421
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, VALUE_GET_DATUM(value, valCol->type),
274,375,555!
4422
                        tDataTypes[valCol->type].bytes);
274,375,555✔
4423
  }
4424
  return 0;
4425
}
4426

4427
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
561,734,557✔
4428
  if (idx < 0 || idx >= valCol->numOfValues) {
561,734,557!
UNCOV
4429
    return TSDB_CODE_OUT_OF_RANGE;
×
4430
  }
4431

4432
  value->type = valCol->type;
561,798,215✔
4433
  if (IS_VAR_DATA_TYPE(value->type)) {
561,798,215!
4434
    int32_t       offset, nextOffset;
UNCOV
4435
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
×
4436

UNCOV
4437
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
×
4438
    if (idx == valCol->numOfValues - 1) {
52✔
4439
      nextOffset = tBufferGetSize(&valCol->data);
48✔
4440
    } else {
4441
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
4!
4442
    }
4443
    value->nData = nextOffset - offset;
52✔
4444
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
52✔
4445
  } else {
4446
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
561,799,791✔
4447
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
1,123,599,582!
4448
  }
4449
  return 0;
561,799,843✔
4450
}
4451

4452
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
4,687✔
4453
  int32_t code;
4454

4455
  if (!(valCol->numOfValues > 0)) {
4,687!
UNCOV
4456
    return TSDB_CODE_INVALID_PARA;
×
4457
  }
4458

4459
  (*info) = (SValueColumnCompressInfo){
4,687✔
4460
      .cmprAlg = info->cmprAlg,
4,687✔
4461
      .type = valCol->type,
4,687✔
4462
  };
4463

4464
  // offset
4465
  if (IS_VAR_DATA_TYPE(valCol->type)) {
4,687!
4466
    SCompressInfo cinfo = {
6✔
4467
        .cmprAlg = info->cmprAlg,
6✔
4468
        .dataType = TSDB_DATA_TYPE_INT,
4469
        .originalSize = valCol->offsets.size,
6✔
4470
    };
4471

4472
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
6✔
4473
    if (code) return code;
6!
4474

4475
    info->offsetOriginalSize = cinfo.originalSize;
6✔
4476
    info->offsetCompressedSize = cinfo.compressedSize;
6✔
4477
  }
4478

4479
  // data
4480
  SCompressInfo cinfo = {
4,687✔
4481
      .cmprAlg = info->cmprAlg,
4,687✔
4482
      .dataType = valCol->type,
4,687✔
4483
      .originalSize = valCol->data.size,
4,687✔
4484
  };
4485

4486
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
4,687✔
4487
  if (code) return code;
4,688!
4488

4489
  info->dataOriginalSize = cinfo.originalSize;
4,688✔
4490
  info->dataCompressedSize = cinfo.compressedSize;
4,688✔
4491

4492
  return 0;
4,688✔
4493
}
4494

4495
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
95,817✔
4496
                               SBuffer *assist) {
4497
  int32_t code;
4498

4499
  tValueColumnClear(valCol);
95,817✔
4500
  valCol->type = info->type;
95,817✔
4501
  // offset
4502
  if (IS_VAR_DATA_TYPE(valCol->type)) {
95,817!
UNCOV
4503
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
×
4504

UNCOV
4505
    SCompressInfo cinfo = {
×
4506
        .dataType = TSDB_DATA_TYPE_INT,
UNCOV
4507
        .cmprAlg = info->cmprAlg,
×
4508
        .originalSize = info->offsetOriginalSize,
×
UNCOV
4509
        .compressedSize = info->offsetCompressedSize,
×
4510
    };
4511

UNCOV
4512
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
×
UNCOV
4513
    if (code) {
×
UNCOV
4514
      return code;
×
4515
    }
4516
  } else {
4517
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
95,817✔
4518
  }
4519

4520
  // data
4521
  SCompressInfo cinfo = {
95,817✔
4522
      .dataType = valCol->type,
95,817✔
4523
      .cmprAlg = info->cmprAlg,
95,817✔
4524
      .originalSize = info->dataOriginalSize,
95,817✔
4525
      .compressedSize = info->dataCompressedSize,
95,817✔
4526
  };
4527

4528
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
95,817✔
4529
  if (code) {
95,817!
UNCOV
4530
    return code;
×
4531
  }
4532

4533
  return 0;
95,817✔
4534
}
4535

4536
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
4,688✔
4537
  int32_t code;
4538
  uint8_t fmtVer = 0;
4,688✔
4539

4540
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
9,376!
4541
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
9,376!
4542
  if ((code = tBufferPutI8(buffer, info->type))) return code;
9,376!
4543
  if (IS_VAR_DATA_TYPE(info->type)) {
4,688!
4544
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
12!
4545
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
12!
4546
  }
4547
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
9,376!
4548
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
9,376!
4549

4550
  return 0;
4,688✔
4551
}
4552

4553
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
95,816✔
4554
  int32_t code;
4555
  uint8_t fmtVer;
4556

4557
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
95,816!
4558
  if (fmtVer == 0) {
95,815!
4559
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
95,815!
4560
    if ((code = tBufferGetI8(reader, &info->type))) return code;
95,816!
4561
    if (IS_VAR_DATA_TYPE(info->type)) {
95,816!
UNCOV
4562
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
×
UNCOV
4563
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
×
4564
    } else {
4565
      info->offsetOriginalSize = 0;
95,816✔
4566
      info->offsetCompressedSize = 0;
95,816✔
4567
    }
4568
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
95,816!
4569
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
95,817!
4570
  } else {
UNCOV
4571
    return TSDB_CODE_INVALID_PARA;
×
4572
  }
4573

4574
  return 0;
95,818✔
4575
}
4576

4577
int32_t tCompressData(void          *input,       // input
13,222,263✔
4578
                      SCompressInfo *info,        // compress info
4579
                      void          *output,      // output
4580
                      int32_t        outputSize,  // output size
4581
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4582
) {
4583
  int32_t extraSizeNeeded;
4584
  int32_t code;
4585

4586
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
13,222,263!
4587
  if (!(outputSize >= extraSizeNeeded)) {
13,222,263!
UNCOV
4588
    return TSDB_CODE_INVALID_PARA;
×
4589
  }
4590

4591
  if (info->cmprAlg == NO_COMPRESSION) {
13,222,263!
UNCOV
4592
    (void)memcpy(output, input, info->originalSize);
×
4593
    info->compressedSize = info->originalSize;
×
4594
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
15,745,084!
4595
    SBuffer local;
4596

4597
    tBufferInit(&local);
4598
    if (buffer == NULL) {
2,520,146!
UNCOV
4599
      buffer = &local;
×
4600
    }
4601

4602
    if (info->cmprAlg == TWO_STAGE_COMP) {
2,520,146!
4603
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
2,522,686✔
4604
      if (code) {
2,522,686!
4605
        tBufferDestroy(&local);
UNCOV
4606
        return code;
×
4607
      }
4608
    }
4609

4610
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
5,042,967✔
4611
        input,                                                   // input
4612
        info->originalSize,                                      // input size
4613
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
2,520,146✔
4614
        output,                                                  // output
4615
        outputSize,                                              // output size
4616
        info->cmprAlg,                                           // compression algorithm
2,520,146✔
4617
        buffer->data,                                            // buffer
4618
        buffer->capacity                                         // buffer size
2,520,146✔
4619
    );
4620
    if (info->compressedSize < 0) {
2,522,821!
4621
      tBufferDestroy(&local);
UNCOV
4622
      return TSDB_CODE_COMPRESS_ERROR;
×
4623
    }
4624

4625
    tBufferDestroy(&local);
4626
  } else {
4627
    DEFINE_VAR(info->cmprAlg)
10,702,117✔
4628
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
10,702,117!
UNCOV
4629
      (void)memcpy(output, input, info->originalSize);
×
UNCOV
4630
      info->compressedSize = info->originalSize;
×
4631
      return 0;
×
4632
    }
4633
    SBuffer local;
4634

4635
    tBufferInit(&local);
4636
    if (buffer == NULL) {
10,702,117!
UNCOV
4637
      buffer = &local;
×
4638
    }
4639
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
10,702,117✔
4640

4641
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
21,404,596✔
4642
        input,                                                      // input
4643
        info->originalSize,                                         // input size
4644
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
10,702,135✔
4645
        output,                                                     // output
4646
        outputSize,                                                 // output size
4647
        info->cmprAlg,                                              // compression algorithm
4648
        buffer->data,                                               // buffer
4649
        buffer->capacity                                            // buffer size
10,702,135✔
4650
    );
4651
    if (info->compressedSize < 0) {
10,702,461!
4652
      tBufferDestroy(&local);
UNCOV
4653
      return TSDB_CODE_COMPRESS_ERROR;
×
4654
    }
4655

4656
    tBufferDestroy(&local);
4657
    // new col compress
4658
  }
4659

4660
  return 0;
13,225,282✔
4661
}
4662

4663
int32_t tDecompressData(void                *input,       // input
67,442,799✔
4664
                        const SCompressInfo *info,        // compress info
4665
                        void                *output,      // output
4666
                        int32_t              outputSize,  // output size
4667
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4668
) {
4669
  int32_t code;
4670

4671
  if (!(outputSize >= info->originalSize)) {
67,442,799!
UNCOV
4672
    return TSDB_CODE_INVALID_PARA;
×
4673
  }
4674

4675
  if (info->cmprAlg == NO_COMPRESSION) {
67,442,799!
UNCOV
4676
    if (!(info->compressedSize == info->originalSize)) {
×
UNCOV
4677
      return TSDB_CODE_INVALID_PARA;
×
4678
    }
4679
    (void)memcpy(output, input, info->compressedSize);
×
4680
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
94,076,122!
4681
    SBuffer local;
4682

4683
    tBufferInit(&local);
4684
    if (buffer == NULL) {
26,608,752!
UNCOV
4685
      buffer = &local;
×
4686
    }
4687

4688
    if (info->cmprAlg == TWO_STAGE_COMP) {
26,608,752!
4689
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
26,634,700✔
4690
      if (code) {
26,635,644!
4691
        tBufferDestroy(&local);
UNCOV
4692
        return code;
×
4693
      }
4694
    }
4695

4696
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
26,609,696✔
4697
        input,                                                  // input
4698
        info->compressedSize,                                   // inputSize
26,609,696✔
4699
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
26,609,696✔
4700
        output,                                                 // output
4701
        outputSize,                                             // output size
4702
        info->cmprAlg,                                          // compression algorithm
26,609,696✔
4703
        buffer->data,                                           // helper buffer
4704
        buffer->capacity                                        // extra buffer size
26,609,696✔
4705
    );
4706
    if (decompressedSize < 0) {
26,633,323!
4707
      tBufferDestroy(&local);
UNCOV
4708
      return TSDB_CODE_COMPRESS_ERROR;
×
4709
    }
4710

4711
    if (!(decompressedSize == info->originalSize)) {
26,633,323!
4712
      return TSDB_CODE_COMPRESS_ERROR;
×
4713
    }
4714
    tBufferDestroy(&local);
4715
  } else {
4716
    DEFINE_VAR(info->cmprAlg);
40,834,047✔
4717
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
40,834,047!
UNCOV
4718
      (void)memcpy(output, input, info->compressedSize);
×
4719
      return 0;
×
4720
    }
4721
    SBuffer local;
4722

4723
    tBufferInit(&local);
4724
    if (buffer == NULL) {
40,834,047!
UNCOV
4725
      buffer = &local;
×
4726
    }
4727
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
40,834,047✔
4728
    if (code) {
40,835,004!
UNCOV
4729
      return code;
×
4730
    }
4731

4732
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
40,835,004✔
4733
        input,                                                  // input
4734
        info->compressedSize,                                   // inputSize
40,835,004✔
4735
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
40,835,004✔
4736
        output,                                                 // output
4737
        outputSize,                                             // output size
4738
        info->cmprAlg,                                          // compression algorithm
40,835,004✔
4739
        buffer->data,                                           // helper buffer
4740
        buffer->capacity                                        // extra buffer size
40,835,004✔
4741
    );
4742
    if (decompressedSize < 0) {
40,836,171!
4743
      tBufferDestroy(&local);
UNCOV
4744
      return TSDB_CODE_COMPRESS_ERROR;
×
4745
    }
4746

4747
    if (!(decompressedSize == info->originalSize)) {
40,836,171!
UNCOV
4748
      return TSDB_CODE_COMPRESS_ERROR;
×
4749
    }
4750
    tBufferDestroy(&local);
4751
  }
4752

4753
  return 0;
67,469,494✔
4754
}
4755

4756
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
13,222,670✔
4757
  int32_t code;
4758

4759
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
13,222,670✔
4760
  if (code) return code;
13,222,667!
4761

4762
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
13,222,667✔
4763
  if (code) return code;
13,223,200!
4764

4765
  output->size += info->compressedSize;
13,223,200✔
4766
  return 0;
13,223,200✔
4767
}
4768

4769
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
26,628,863✔
4770
  int32_t code;
4771

4772
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
26,628,863✔
4773
  if (code) return code;
26,628,858!
4774

4775
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
26,628,858✔
4776
  if (code) return code;
26,632,308!
4777

4778
  output->size += info->originalSize;
26,632,308✔
4779
  return 0;
26,632,308✔
4780
}
4781

4782
// handle all types, including var data
4783
void valueSetDatum(SValue *pVal, int8_t type, void *pDatum, uint32_t len) {
2,147,483,647✔
4784
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
2,147,483,647!
UNCOV
4785
    pVal->pData = pDatum;
×
UNCOV
4786
    pVal->nData = len;
×
4787
  } else {
4788
    switch (len) {
2,147,483,647!
4789
      case sizeof(uint8_t):
1,347,473,922✔
4790
        pVal->val = *(uint8_t *)pDatum;
1,347,473,922✔
4791
        break;
1,347,473,922✔
4792
      case sizeof(uint16_t):
722,442,450✔
4793
        pVal->val = *(uint16_t *)pDatum;
722,442,450✔
4794
        break;
722,442,450✔
4795
      case sizeof(uint32_t):
2,147,483,647✔
4796
        pVal->val = *(uint32_t *)pDatum;
2,147,483,647✔
4797
        break;
2,147,483,647✔
4798
      case sizeof(uint64_t):
2,147,483,647✔
4799
        pVal->val = *(uint64_t *)pDatum;
2,147,483,647✔
4800
        break;
2,147,483,647✔
UNCOV
4801
      default:
×
UNCOV
4802
        break;
×
4803
    }
4804
  }
4805
}
2,147,483,647✔
4806

4807
void valueCloneDatum(SValue *pDst, const SValue *pSrc, int8_t type) {
60,869,744✔
4808
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
60,869,744!
4809
    memcpy(pDst->pData, pSrc->pData, pSrc->nData);
×
4810
    pDst->nData = pSrc->nData;
×
4811
  } else {
4812
    pDst->val = pSrc->val;
61,149,948✔
4813
  }
4814
}
60,869,744✔
UNCOV
4815
void valueClearDatum(SValue *pVal, int8_t type) {
×
4816
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
UNCOV
4817
    taosMemoryFreeClear(pVal->pData);
×
UNCOV
4818
    pVal->nData = 0;
×
4819
  } else {
UNCOV
4820
    pVal->val = 0;
×
4821
  }
UNCOV
4822
}
×
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