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

taosdata / TDengine / #3661

17 Mar 2025 05:39AM UTC coverage: 62.007% (-0.03%) from 62.039%
#3661

push

travis-ci

web-flow
tests: add tdb ut (#30093)

* fix: compile warnings

* tests: add tdb ut

* test(tdb): fix return code

* test: recover ut

* fix: minor changes

* fix: enable test

* fix: ut errors

---------

Co-authored-by: Minglei Jin <mljin@taosdata.com>

153829 of 317582 branches covered (48.44%)

Branch coverage included in aggregate %.

240310 of 318051 relevant lines covered (75.56%)

19602636.8 hits per line

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

60.97
/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) {
753,424,927✔
66
  int32_t n = 0;
753,424,927✔
67
  n += tPutI8(p ? p + n : p, index->type);
753,424,927✔
68
  n += tPutU32v(p ? p + n : p, index->offset);
753,424,927✔
69
  return n;
753,424,927✔
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++;
26,341,311✔
114
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
26,341,311✔
115
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
26,341,311✔
116
  return 0;
26,341,311✔
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;
255,242,649✔
124
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
255,242,649✔
125
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
255,242,649!
126
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
255,242,649✔
127
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
255,242,649✔
128
    sinfo->numOfPKs++;
255,242,649✔
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
578,784,255✔
134
                           + colVal->value.nData;               // value
578,784,255✔
135

136
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
578,784,255✔
137
                            + tPutU32v(NULL, colVal->value.nData)  // size
578,784,255✔
138
                            + colVal->value.nData;                 // value
578,784,255✔
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,117,797,891✔
147
  int32_t  code = 0;
1,117,797,891✔
148
  int32_t  colValIndex = 1;
1,117,797,891✔
149
  int32_t  numOfColVals = TARRAY_SIZE(colVals);
1,117,797,891✔
150
  SColVal *colValArray = (SColVal *)TARRAY_DATA(colVals);
1,117,797,891✔
151

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

162
  *sinfo = (SRowBuildScanInfo){
1,117,797,891✔
163
      .tupleFixedSize = schema->flen,
1,117,797,891✔
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;
88!
171
        break;
44✔
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;
52,682,622!
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) {
3,568,912✔
191
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
62!
192
        break;
31✔
193
      } else {  // skip useless value
194
        colValIndex++;
3,568,881✔
195
      }
196
    }
197
  }
198

199
  if (sinfo->numOfNone) {
1,117,797,891✔
200
    sinfo->flag |= HAS_NONE;
354,179,626✔
201
  }
202
  if (sinfo->numOfNull) {
1,117,797,891✔
203
    sinfo->flag |= HAS_NULL;
19,108,582✔
204
  }
205
  if (sinfo->numOfValue) {
1,117,797,891✔
206
    sinfo->flag |= HAS_VALUE;
1,085,807,580✔
207
  }
208

209
  // Tuple
210
  sinfo->tupleFlag = sinfo->flag;
1,117,797,891✔
211
  switch (sinfo->flag) {
1,117,797,891!
212
    case HAS_NONE:
38,217,449✔
213
    case HAS_NULL:
214
      sinfo->tupleBitmapSize = 0;
38,217,449✔
215
      sinfo->tupleFixedSize = 0;
38,217,449✔
216
      break;
38,217,449✔
217
    case HAS_VALUE:
752,784,226✔
218
      sinfo->tupleBitmapSize = 0;
752,784,226✔
219
      sinfo->tupleFixedSize = schema->flen;
752,784,226✔
220
      break;
752,784,226✔
221
    case (HAS_NONE | HAS_NULL):
24,493✔
222
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,493✔
223
      sinfo->tupleFixedSize = 0;
24,493✔
224
      break;
24,493✔
225
    case (HAS_NONE | HAS_VALUE):
334,199,024✔
226
    case (HAS_NULL | HAS_VALUE):
227
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
334,199,024✔
228
      sinfo->tupleFixedSize = schema->flen;
334,199,024✔
229
      break;
334,199,024✔
230
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
451,840✔
231
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
451,840✔
232
      sinfo->tupleFixedSize = schema->flen;
451,840✔
233
      break;
451,840✔
234
  }
235
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,373,222,583✔
236
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
256,140,854✔
237
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
256,140,854✔
238
  }
239
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,117,081,729✔
240
                        + sinfo->tuplePKSize      // primary keys
1,117,081,729✔
241
                        + sinfo->tupleBitmapSize  // bitmap
1,117,081,729✔
242
                        + sinfo->tupleFixedSize   // fixed part
1,117,081,729✔
243
                        + sinfo->tupleVarSize;    // var part
1,117,081,729✔
244

245
  // Key-Value
246
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,117,081,729!
247
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,118,669,658✔
248
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,118,669,658✔
249
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
250
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
5,877,461✔
251
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
5,877,461✔
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,371,810,926✔
257
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
255,243,547✔
258
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
255,243,547✔
259
  }
260
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,116,567,379✔
261
                     + sinfo->kvPKSize        // primary keys
1,116,567,379✔
262
                     + sinfo->kvIndexSize     // index array
1,116,567,379✔
263
                     + sinfo->kvPayloadSize;  // payload
1,116,567,379✔
264

265
_exit:
1,116,567,379✔
266
  return code;
1,116,567,379✔
267
}
268

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

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

283
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
807,423,839✔
284
    return 0;
39,744,917✔
285
  }
286

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

292
  // primary keys
293
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,022,524,572✔
294
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
257,151,266✔
295
  }
296

297
  // bitmap + fixed + varlen
298
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
765,373,306✔
299
  int32_t colValIndex = 1;
765,373,306✔
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;
155,181,371✔
313
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
155,181,371✔
314
            if (colValArray[colValIndex].value.nData) {
155,181,371!
315
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
160,785,732✔
316
              varlen += colValArray[colValIndex].value.nData;
160,785,732✔
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
11,058,054!
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
13,262,336!
325
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
326
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
473,224!
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
2,368,416✔
332
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
9!
333
        break;
9✔
334
      } else {
335
        colValIndex++;
2,368,407✔
336
      }
337
    }
338
  }
339

340
  return 0;
765,373,306✔
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) {
6,252,249!
347
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,134,522✔
348
  } else {
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) {
322,146,411✔
355
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
322,146,411✔
356

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

367
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
322,450,065!
368
    return TSDB_CODE_INVALID_PARA;
×
369
  }
370

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

376
  // primary keys
377
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
323,537,327✔
378
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
1,063,411✔
379
  }
380

381
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
322,473,916✔
382
  int32_t colValIndex = 1;
322,473,916✔
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);
421,639,302✔
394
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
421,639,302✔
395
            if (colValArray[colValIndex].value.nData > 0) {
421,639,302!
396
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
432,274,679✔
397
                           colValArray[colValIndex].value.nData);
432,274,679✔
398
            }
399
            payloadSize += colValArray[colValIndex].value.nData;
421,639,302✔
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);
12,833,804✔
408
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
25,667,608✔
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;
322,473,916✔
422
}
423

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

428
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,117,633,925✔
429
  if (code) return code;
1,123,704,045!
430

431
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,123,704,045✔
432
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
801,839,020✔
433
  } else {
434
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
321,865,025✔
435
  }
436
  return code;
1,125,808,818✔
437
}
438

439
static int32_t tBindInfoCompare(const void *p1, const void *p2, const void *param) {
×
440
  if (((SBindInfo *)p1)->columnId < ((SBindInfo *)p2)->columnId) {
×
441
    return -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,
34,219✔
458
                          SArray *rowArray, bool *pOrdered, bool *pDupTs) {
459
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
34,219!
460
    return TSDB_CODE_INVALID_PARA;
×
461
  }
462

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

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

472
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
34,272!
473
    return terrno;
×
474
  }
475

476
  SRowKey rowKey, lastRowKey;
477
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
115,838✔
478
    taosArrayClear(colValArray);
82,170✔
479

480
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
747,611✔
481
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
679,644✔
482
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
32✔
483
      } else {
484
        SValue value = {
679,612✔
485
            .type = infos[iInfo].type,
679,612✔
486
        };
487
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
679,612!
488
          value.nData = infos[iInfo].bind->length[iRow];
176,173✔
489
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
176,173!
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;
176,173✔
494
        } else {
495
          valueSetDatum(&value, infos[iInfo].type,
503,439✔
496
                        (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
503,439✔
497
                        infos[iInfo].bind->buffer_length);
503,439✔
498
        }
499
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
689,505✔
500
      }
501
      if (taosArrayPush(colValArray, &colVal) == NULL) {
665,478!
502
        code = terrno;
×
503
        goto _exit;
×
504
      }
505
    }
506

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

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

517
    if (pOrdered && pDupTs) {
81,550!
518
      tRowGetKey(row, &rowKey);
163,164!
519
      if (iRow == 0) {
81,600✔
520
        *pOrdered = true;
34,059✔
521
        *pDupTs = false;
34,059✔
522
      } else {
523
        // no more compare if we already get disordered or duplicate rows
524
        if (*pOrdered && !*pDupTs) {
47,541!
525
          int32_t code = tRowKeyCompare(&rowKey, &lastRowKey);
47,534✔
526
          *pOrdered = (code >= 0);
47,534✔
527
          *pDupTs = (code == 0);
47,534✔
528
        }
529
      }
530
      lastRowKey = rowKey;
81,600✔
531
    }
532
  }
533

534
_exit:
33,668✔
535
  taosArrayDestroy(colValArray);
33,668✔
536
  return code;
34,215✔
537
}
538

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

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

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

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

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

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

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

573
    if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
574
      pv = pIdx->idx + pIdx->nCol;
2,147,483,647✔
575
    } else if (pRow->flag & KV_FLG_MID) {
75,357,982!
576
      pv = pIdx->idx + (pIdx->nCol << 1);
90,541,755✔
577
    } else {
578
      pv = pIdx->idx + (pIdx->nCol << 2);
×
579
    }
580

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

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

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

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

624
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2,028,559,284✔
625
  } else {  // Tuple Row
626
    uint8_t *bitmap = data;
583,423,322✔
627
    uint8_t *fixed;
628
    uint8_t *varlen;
629
    uint8_t  bit;
630

631
    if (pRow->flag == HAS_VALUE) {
583,423,322!
632
      fixed = bitmap;
598,981,168✔
633
      bit = BIT_FLG_VALUE;
598,981,168✔
634
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
×
635
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
636
      bit = GET_BIT2(bitmap, iCol - 1);
×
637
    } else {
638
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
639
      bit = GET_BIT1(bitmap, iCol - 1);
×
640

641
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
×
642
        if (bit) bit++;
20,213✔
643
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
×
644
        bit++;
2,167,414✔
645
      }
646
    }
647
    varlen = fixed + pTSchema->flen;
583,423,322✔
648

649
    if (bit == BIT_FLG_NONE) {
583,423,322✔
650
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,218✔
651
      return 0;
7,218✔
652
    } else if (bit == BIT_FLG_NULL) {
583,416,104✔
653
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
368,022✔
654
      return 0;
368,022✔
655
    }
656

657
    pColVal->cid = pTColumn->colId;
583,048,082✔
658
    pColVal->value.type = pTColumn->type;
583,048,082✔
659
    pColVal->flag = CV_FLAG_VALUE;
583,048,082✔
660
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
583,048,082!
661
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
14,704,493✔
662
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
29,408,986!
663
    } else {
664
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
568,343,589✔
665
    }
666
  }
667

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

671
void tRowDestroy(SRow *pRow) {
773,518,865✔
672
  if (pRow) taosMemoryFree(pRow);
773,518,865!
673
}
773,428,619✔
674

675
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
268,104,786✔
676
  SRowKey key1, key2;
677
  tRowGetKey(*(SRow **)p1, &key1);
536,209,572✔
678
  tRowGetKey(*(SRow **)p2, &key2);
533,420,012✔
679
  return tRowKeyCompare(&key1, &key2);
270,688,395✔
680
}
681
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
894✔
682
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
237✔
683
  int32_t code = 0;
237✔
684

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

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

696
  for (int32_t i = 0; i < nRow; i++) {
1,131✔
697
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
894✔
698

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

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

710
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
905✔
711
    SColVal *pColVal = NULL;
668✔
712
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
798✔
713
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
754✔
714
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
846✔
715
        pColValT = tRowIterNext(aIter[iRow]);
92✔
716
      }
717

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

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

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

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

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

759
int32_t tRowSort(SArray *aRowP) {
34,226✔
760
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
34,226✔
761
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
34,223✔
762
  if (code != TSDB_CODE_SUCCESS) {
34,223!
763
    uError("taosArrayMSort failed caused by %d", code);
×
764
  }
765
  return code;
34,223✔
766
}
767

768
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, int8_t flag) {
34,268✔
769
  int32_t code = 0;
34,268✔
770

771
  int32_t iStart = 0;
34,268✔
772
  while (iStart < aRowP->size) {
37,731,632✔
773
    SRowKey key1;
774
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
37,713,015✔
775

776
    tRowGetKey(row1, &key1);
75,429,062✔
777

778
    int32_t iEnd = iStart + 1;
37,691,978✔
779
    while (iEnd < aRowP->size) {
37,690,951✔
780
      SRowKey key2;
781
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
37,662,724✔
782
      tRowGetKey(row2, &key2);
75,344,990✔
783

784
      if (tRowKeyCompare(&key1, &key2) != 0) break;
37,668,110!
785

786
      iEnd++;
×
787
    }
788

789
    if (iEnd - iStart > 1) {
37,697,364✔
790
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
237✔
791
      if (code) return code;
237!
792
    }
793

794
    // the array is also changing, so the iStart just ++ instead of iEnd
795
    iStart++;
37,697,364✔
796
  }
797

798
  return code;
18,617✔
799
}
800

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

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

821
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) {
995,903✔
822
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
995,903!
823

824
  int32_t code = 0;
995,903✔
825

826
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
995,903!
827
  if (pIter == NULL) {
1,033,146!
828
    code = terrno;
×
829
    goto _exit;
×
830
  }
831

832
  pIter->pRow = pRow;
1,033,146✔
833
  pIter->pTSchema = pTSchema;
1,033,146✔
834
  pIter->iTColumn = 0;
1,033,146✔
835

836
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
1,033,146✔
837

838
  uint8_t         *data = pRow->data;
1,029,980✔
839
  SPrimaryKeyIndex index;
840
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,030,019✔
841
    data += tGetPrimaryKeyIndex(data, &index);
39✔
842
  }
843

844
  if (pRow->flag >> 4) {
1,029,980✔
845
    pIter->iCol = 0;
1,026,008✔
846
    pIter->pIdx = (SKVIdx *)data;
1,026,008✔
847
    if (pRow->flag & KV_FLG_LIT) {
1,026,008✔
848
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
1,023,480✔
849
    } else if (pRow->flag & KV_FLG_MID) {
2,528✔
850
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1);  // * sizeof(uint16_t)
2,400✔
851
    } else {
852
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2);  // * sizeof(uint32_t)
128✔
853
    }
854
  } else {
855
    switch (pRow->flag) {
3,972!
856
      case (HAS_NULL | HAS_NONE):
1✔
857
        pIter->pb = data;
1✔
858
        break;
1✔
859
      case HAS_VALUE:
2,593✔
860
        pIter->pf = data;
2,593✔
861
        pIter->pv = pIter->pf + pTSchema->flen;
2,593✔
862
        break;
2,593✔
863
      case (HAS_VALUE | HAS_NONE):
737✔
864
      case (HAS_VALUE | HAS_NULL):
865
        pIter->pb = data;
737✔
866
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
737✔
867
        pIter->pv = pIter->pf + pTSchema->flen;
737✔
868
        break;
737✔
869
      case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
870
        pIter->pb = data;
×
871
        pIter->pf = data + BIT2_SIZE(pTSchema->numOfCols - 1);
×
872
        pIter->pv = pIter->pf + pTSchema->flen;
×
873
        break;
×
874
      default:
641✔
875
        break;
641✔
876
    }
877
  }
878

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

888
void tRowIterClose(SRowIter **ppIter) {
976,515✔
889
  SRowIter *pIter = *ppIter;
976,515✔
890
  if (pIter) {
976,515!
891
    taosMemoryFree(pIter);
976,777!
892
  }
893
  *ppIter = NULL;
1,035,694✔
894
}
1,035,694✔
895

896
SColVal *tRowIterNext(SRowIter *pIter) {
11,826,444✔
897
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
11,826,444✔
898
    return NULL;
973,839✔
899
  }
900

901
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
10,852,605✔
902

903
  // timestamp
904
  if (0 == pIter->iTColumn) {
10,852,605✔
905
    pIter->cv.cid = pTColumn->colId;
1,005,749✔
906
    pIter->cv.value.type = pTColumn->type;
1,005,749✔
907
    pIter->cv.flag = CV_FLAG_VALUE;
1,005,749✔
908
    VALUE_SET_TRIVIAL_DATUM(&pIter->cv.value, pIter->pRow->ts);
1,005,749✔
909
    goto _exit;
1,005,749✔
910
  }
911

912
  if (pIter->pRow->flag == HAS_NONE) {
9,846,856✔
913
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1✔
914
    goto _exit;
1✔
915
  }
916

917
  if (pIter->pRow->flag == HAS_NULL) {
9,846,855✔
918
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,841✔
919
    goto _exit;
1,841✔
920
  }
921

922
  if (pIter->pRow->flag >> 4) {  // KV
9,845,014!
923
    if (pIter->iCol < pIter->pIdx->nCol) {
10,461,420✔
924
      uint8_t *pData;
925

926
      if (pIter->pRow->flag & KV_FLG_LIT) {
8,636,940✔
927
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
8,568,141✔
928
      } else if (pIter->pRow->flag & KV_FLG_MID) {
68,799!
929
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
72,000✔
930
      } else {
931
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
932
      }
933

934
      int16_t cid;
935
      pData += tGetI16v(pData, &cid);
8,636,940✔
936

937
      if (TABS(cid) == pTColumn->colId) {
8,636,940!
938
        if (cid < 0) {
8,720,714✔
939
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,516,825✔
940
        } else {
941
          pIter->cv.cid = pTColumn->colId;
7,203,889✔
942
          pIter->cv.value.type = pTColumn->type;
7,203,889✔
943
          pIter->cv.flag = CV_FLAG_VALUE;
7,203,889✔
944

945
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
7,203,889!
946
            pData += tGetU32v(pData, &pIter->cv.value.nData);
794,684!
947
            if (pIter->cv.value.nData > 0) {
794,684!
948
              pIter->cv.value.pData = pData;
1,976,356✔
949
            } else {
950
              pIter->cv.value.pData = NULL;
×
951
            }
952
          } else {
953
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
6,409,205✔
954
          }
955
        }
956

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

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

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

1017
_exit:
12,227,237✔
1018
  pIter->iTColumn++;
12,227,237✔
1019
  return &pIter->cv;
12,227,237✔
1020
}
1021

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

1025
  if (flag) return code;
1,067!
1026

1027
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
7,138✔
1028
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
6,065✔
1029
    if (code) return code;
6,071!
1030
  }
1031

1032
  return code;
1,073✔
1033
}
1034
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
35,010✔
1035
  int32_t code = 0;
35,010✔
1036

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

1042
  while (pColData) {
246,029✔
1043
    if (pTColumn) {
210,997!
1044
      if (pTColumn->colId == pColData->cid) {  // NULL
210,997!
1045
        if (flag == 0) {
211,002✔
1046
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
210,831✔
1047
        } else {
1048
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
171✔
1049
        }
1050
        if (code) goto _exit;
211,024!
1051

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

1066
_exit:
35,032✔
1067
  return code;
35,032✔
1068
}
1069
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
721,730,066✔
1070
                                      int32_t flag) {
1071
  int32_t code = 0;
721,730,066✔
1072

1073
  int32_t   iColData = 0;
721,730,066✔
1074
  SColData *pColData = &aColData[iColData];
721,730,066✔
1075
  int32_t   iTColumn = 1;
721,730,066✔
1076
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
721,730,066✔
1077

1078
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
721,730,066✔
1079
  SPrimaryKeyIndex index;
1080
  uint8_t         *data = pRow->data;
721,730,066✔
1081
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
986,919,152✔
1082
    data += tGetPrimaryKeyIndex(data, &index);
265,195,209✔
1083
  }
1084

1085
  switch (pRow->flag) {
721,723,943!
1086
    case HAS_VALUE:
711,432,893✔
1087
      pf = data;  // TODO: fix here
711,432,893✔
1088
      pv = pf + pTSchema->flen;
711,432,893✔
1089
      break;
711,432,893✔
1090
    case (HAS_NULL | HAS_NONE):
1,297✔
1091
      pb = data;
1,297✔
1092
      break;
1,297✔
1093
    case (HAS_VALUE | HAS_NONE):
10,541,181✔
1094
    case (HAS_VALUE | HAS_NULL):
1095
      pb = data;
10,541,181✔
1096
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
10,541,181✔
1097
      pv = pf + pTSchema->flen;
10,541,181✔
1098
      break;
10,541,181✔
1099
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1100
      pb = data;
×
1101
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1102
      pv = pf + pTSchema->flen;
×
1103
      break;
×
1104
    default:
×
1105
      return TSDB_CODE_INVALID_DATA_FMT;
×
1106
  }
1107

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

1134
          if (bv == BIT_FLG_NONE) {
32,606,941✔
1135
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,341!
1136
              goto _exit;
×
1137
            goto _continue;
43,340✔
1138
          } else if (bv == BIT_FLG_NULL) {
32,563,600✔
1139
            if (flag == 0) {
10,529,122✔
1140
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
10,526,983✔
1141
            } else {
1142
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
2,139✔
1143
            }
1144
            if (code) goto _exit;
10,529,245!
1145
            goto _continue;
10,529,245✔
1146
          }
1147
        }
1148

1149
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1150
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
45,007,709!
1151
          uint32_t nData;
1152
          pData += tGetU32v(pData, &nData);
45,007,709✔
1153
          if (flag == 0) {
45,007,709!
1154
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
48,418,834✔
1155
          } else {
1156
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1157
          }
1158
          if (code) goto _exit;
49,160,984!
1159
        } else {
1160
          if (flag == 0) {
2,147,483,647✔
1161
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,147,483,647✔
1162
                                                                          TYPE_BYTES[pColData->type]);
2,147,483,647✔
1163
          } else {
1164
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
1,801,668✔
1165
                                                                          TYPE_BYTES[pColData->type], flag > 0);
1,801,668✔
1166
          }
1167
          if (code) goto _exit;
2,147,483,647!
1168
        }
1169

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

1185
_exit:
724,069,216✔
1186
  return code;
724,069,216✔
1187
}
1188
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
3,765,358✔
1189
  int32_t code = 0;
3,765,358✔
1190

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

1198
  // primary keys
1199
  uint8_t         *data = pRow->data;
3,765,358✔
1200
  SPrimaryKeyIndex index;
1201
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
4,039,789✔
1202
    data += tGetPrimaryKeyIndex(data, &index);
274,430✔
1203
  }
1204

1205
  SKVIdx *pKVIdx = (SKVIdx *)data;
3,765,359✔
1206
  if (pRow->flag & KV_FLG_LIT) {
3,765,359✔
1207
    pv = pKVIdx->idx + pKVIdx->nCol;
3,704,267✔
1208
  } else if (pRow->flag & KV_FLG_MID) {
61,092!
1209
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
62,019✔
1210
  } else if (pRow->flag & KV_FLG_BIG) {
×
1211
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1212
  } else {
1213
    return TSDB_CODE_INVALID_PARA;
×
1214
  }
1215

1216
  while (pColData) {
43,646,753✔
1217
    if (pTColumn) {
39,875,274✔
1218
      if (pTColumn->colId == pColData->cid) {
39,476,151✔
1219
        while (iCol < pKVIdx->nCol) {
39,440,791✔
1220
          uint8_t *pData;
1221
          if (pRow->flag & KV_FLG_LIT) {
34,290,509✔
1222
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
32,604,619✔
1223
          } else if (pRow->flag & KV_FLG_MID) {
1,685,890!
1224
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,685,950✔
1225
          } else if (pRow->flag & KV_FLG_BIG) {
×
1226
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1227
          } else {
1228
            return TSDB_CODE_INVALID_DATA_FMT;
×
1229
          }
1230

1231
          int16_t cid;
1232
          pData += tGetI16v(pData, &cid);
34,290,569✔
1233

1234
          if (TABS(cid) == pTColumn->colId) {
34,290,569✔
1235
            if (cid < 0) {
33,854,053✔
1236
              if (flag == 0) {
6,646,452✔
1237
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
6,643,011✔
1238
              } else {
1239
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
3,441✔
1240
              }
1241
              if (code) goto _exit;
6,200,151!
1242
            } else {
1243
              uint32_t nData;
1244
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
27,207,601!
1245
                pData += tGetU32v(pData, &nData);
6,873,535✔
1246
              } else {
1247
                nData = 0;
20,334,066✔
1248
              }
1249
              if (flag == 0) {
27,207,601!
1250
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
27,365,814✔
1251
              } else {
1252
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1253
              }
1254
              if (code) goto _exit;
27,659,429!
1255
            }
1256
            iCol++;
33,859,580✔
1257
            goto _continue;
33,859,580✔
1258
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
436,516✔
1259
            break;
39,180✔
1260
          } else {
1261
            iCol++;
397,336✔
1262
          }
1263
        }
1264

1265
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
5,189,462!
1266

1267
      _continue:
5,189,087✔
1268
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
39,048,667✔
1269
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
39,048,667✔
1270
      } else if (pTColumn->colId > pColData->cid) {
432,696!
1271
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1272
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1273
      } else {
1274
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
432,696✔
1275
      }
1276
    } else {
1277
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,123!
1278
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,104✔
1279
    }
1280
  }
1281

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

1293
  if (pRow->flag == HAS_NONE) {
725,587,047✔
1294
    return tRowNoneUpsertColData(aColData, nColData, flag);
1,067✔
1295
  } else if (pRow->flag == HAS_NULL) {
725,585,980✔
1296
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
35,019✔
1297
  } else if (pRow->flag >> 4) {  // KV row
725,550,961✔
1298
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
3,768,424✔
1299
  } else {  // TUPLE row
1300
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
721,782,537✔
1301
  }
1302
}
1303

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

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

1311
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1312

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

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

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

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

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

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

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

1390
  return 0;
×
1391
}
1392

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

1403
  if (key1->numOfPKs == key2->numOfPKs) {
216,763,347!
1404
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
306,345,779!
1405
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
217,805,074✔
1406
      if (ret) return ret;
217,795,371!
1407
    }
1408
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1409
    return -1;
×
1410
  } else {
1411
    return 1;
×
1412
  }
1413

1414
  return 0;
88,540,705✔
1415
}
1416

1417
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
686,310,021✔
1418
  pDst->ts = pSrc->ts;
686,310,021✔
1419
  pDst->numOfPKs = pSrc->numOfPKs;
686,310,021✔
1420

1421
  if (pSrc->numOfPKs > 0) {
686,310,021✔
1422
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
42,579,400✔
1423
      SValue *pVal = &pDst->pks[i];
21,096,468✔
1424
      pVal->type = pSrc->pks[i].type;
21,096,468✔
1425

1426
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
21,096,468✔
1427
    }
1428
  }
1429
}
686,697,002✔
1430

1431
// STag ========================================
1432
static int tTagValCmprFn(const void *p1, const void *p2) {
134,169,849✔
1433
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
134,169,849✔
1434
    return -1;
46,382,397✔
1435
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
87,787,452✔
1436
    return 1;
47,938,335✔
1437
  }
1438

1439
  return 0;
39,849,117✔
1440
}
1441
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
13,675✔
1442
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
13,675✔
1443
}
1444

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

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

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

1538
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
875,066✔
1539
  int32_t n = 0;
875,066✔
1540

1541
  // key
1542
  if (isJson) {
875,066✔
1543
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
1,616✔
1544
  } else {
1545
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
1,748,516✔
1546
  }
1547

1548
  // type
1549
  n += tPutI8(p ? p + n : p, pTagVal->type);
875,066✔
1550

1551
  // value
1552
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
875,066!
1553
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
648,302✔
1554
  } else {
1555
    p = p ? p + n : p;
550,915✔
1556
    n += tDataTypes[pTagVal->type].bytes;
550,915✔
1557
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
550,915✔
1558
  }
1559

1560
  return n;
875,066✔
1561
}
1562
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
132,808,936✔
1563
  int32_t n = 0;
132,808,936✔
1564

1565
  // key
1566
  if (isJson) {
132,808,936✔
1567
    n += tGetCStr(p + n, &pTagVal->pKey);
32,494!
1568
  } else {
1569
    n += tGetI16v(p + n, &pTagVal->cid);
265,585,378✔
1570
  }
1571

1572
  // type
1573
  n += tGetI8(p + n, &pTagVal->type);
132,808,936!
1574

1575
  // value
1576
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
132,808,936!
1577
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
43,837,748!
1578
  } else {
1579
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
110,890,062✔
1580
    n += tDataTypes[pTagVal->type].bytes;
110,890,062✔
1581
  }
1582

1583
  return n;
132,808,936✔
1584
}
1585

1586
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
47,841✔
1587

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

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

1603
  // sort
1604
  if (isJson) {
162,689✔
1605
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
321✔
1606
  } else {
1607
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
162,368✔
1608
  }
1609

1610
  // get size
1611
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
600,251✔
1612
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
437,559✔
1613
  }
1614
  if (szTag <= INT8_MAX) {
162,692✔
1615
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
146,171✔
1616
  } else {
1617
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
16,521✔
1618
    isLarge = 1;
16,521✔
1619
  }
1620

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

1638
  if (isLarge) {
162,744✔
1639
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
16,521✔
1640
  } else {
1641
    p = (uint8_t *)&(*ppTag)->idx[nTag];
146,223✔
1642
  }
1643
  n = 0;
162,744✔
1644
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
600,358✔
1645
    if (isLarge) {
437,626✔
1646
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
116,438✔
1647
    } else {
1648
      (*ppTag)->idx[iTag] = n;
321,188✔
1649
    }
1650
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
437,626✔
1651
  }
1652
#ifdef TD_DEBUG_PRINT_TAG
1653
  debugPrintSTag(*ppTag, __func__, __LINE__);
1654
#endif
1655

1656
  return code;
162,732✔
1657

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

1662
void tTagFree(STag *pTag) {
65,535✔
1663
  if (pTag) taosMemoryFree(pTag);
65,535!
1664
}
65,535✔
1665

1666
char *tTagValToData(const STagVal *value, bool isJson) {
13,688,193✔
1667
  if (!value) {
13,688,193!
1668
    return NULL;
×
1669
  }
1670

1671
  char  *data = NULL;
13,688,193✔
1672
  int8_t typeBytes = 0;
13,688,193✔
1673
  if (isJson) {
13,688,193✔
1674
    typeBytes = CHAR_BYTES;
7,436✔
1675
  }
1676

1677
  if (IS_VAR_DATA_TYPE(value->type)) {
13,688,193!
1678
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
3,849,555!
1679
    if (data == NULL) {
3,850,768!
1680
      return NULL;
×
1681
    }
1682

1683
    if (isJson) {
3,850,768✔
1684
      *data = value->type;
2,943✔
1685
    }
1686

1687
    varDataLen(data + typeBytes) = value->nData;
3,850,768✔
1688
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
3,850,768✔
1689
  } else {
1690
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
9,838,638✔
1691
  }
1692

1693
  return data;
13,689,406✔
1694
}
1695

1696
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
41,580,848✔
1697
  if (!pTag || !pTagVal) {
41,580,848!
1698
    return false;
×
1699
  }
1700

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

1711
  if (isLarge) {
41,755,981✔
1712
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
34,443,521✔
1713
  } else {
1714
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,312,460✔
1715
  }
1716

1717
  pTagVal->type = TSDB_DATA_TYPE_NULL;
41,755,981✔
1718
  pTagVal->pData = NULL;
41,755,981✔
1719
  pTagVal->nData = 0;
41,755,981✔
1720
  while (lidx <= ridx) {
135,524,376✔
1721
    midx = (lidx + ridx) / 2;
133,455,753✔
1722
    if (isLarge) {
133,455,753✔
1723
      offset = ((int16_t *)pTag->idx)[midx];
110,621,242✔
1724
    } else {
1725
      offset = pTag->idx[midx];
22,834,511✔
1726
    }
1727

1728
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
133,455,753✔
1729
    if (isJson) {
133,945,822✔
1730
      c = tTagValJsonCmprFn(pTagVal, &tv);
13,463✔
1731
    } else {
1732
      c = tTagValCmprFn(pTagVal, &tv);
133,932,359✔
1733
    }
1734

1735
    if (c < 0) {
135,253,000✔
1736
      ridx = midx - 1;
45,881,009✔
1737
    } else if (c > 0) {
89,371,991✔
1738
      lidx = midx + 1;
47,887,386✔
1739
    } else {
1740
      (void)memcpy(pTagVal, &tv, sizeof(tv));
41,484,605✔
1741
      return true;
41,484,605✔
1742
    }
1743
  }
1744
  return false;
2,068,623✔
1745
}
1746

1747
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
613,770✔
1748
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,227,540✔
1749
}
1750

1751
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
19,319,836✔
1752

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

1760
  if (isLarge) {
1,862✔
1761
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
16✔
1762
  } else {
1763
    p = (uint8_t *)&pTag->idx[pTag->nTag];
1,846✔
1764
  }
1765

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

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

1785
  return code;
1,862✔
1786

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

1791
// STSchema ========================================
1792
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
16,563,018✔
1793
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
16,563,018!
1794
  if (pTSchema == NULL) {
16,598,982!
1795
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1796
    return NULL;
×
1797
  }
1798

1799
  pTSchema->numOfCols = numOfCols;
16,598,982✔
1800
  pTSchema->version = version;
16,598,982✔
1801

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

1817
  // other columns
1818
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
191,064,112✔
1819
    SSchema  *pSchema = &aSchema[iCol];
174,465,130✔
1820
    STColumn *pTColumn = &pTSchema->columns[iCol];
174,465,130✔
1821

1822
    pTColumn->colId = pSchema->colId;
174,465,130✔
1823
    pTColumn->type = pSchema->type;
174,465,130✔
1824
    pTColumn->flags = pSchema->flags;
174,465,130✔
1825
    pTColumn->offset = pTSchema->flen;
174,465,130✔
1826

1827
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
174,465,130!
1828
      pTColumn->bytes = pSchema->bytes;
34,300,723✔
1829
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
34,300,723✔
1830
    } else {
1831
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
140,164,407✔
1832
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
140,164,407✔
1833
    }
1834

1835
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
174,465,130✔
1836
  }
1837

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

1842
  return pTSchema;
16,598,982✔
1843
}
1844

1845
static int32_t tTColumnCompare(const void *p1, const void *p2) {
9,578,109✔
1846
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
9,578,109✔
1847
    return -1;
1,426,373✔
1848
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
8,151,736✔
1849
    return 1;
5,709,375✔
1850
  }
1851

1852
  return 0;
2,442,361✔
1853
}
1854

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

1860
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
2,442,882✔
1861
}
1862

1863
// SColData ========================================
1864
void tColDataDestroy(void *ph) {
23,670,061✔
1865
  if (ph) {
23,670,061!
1866
    SColData *pColData = (SColData *)ph;
23,670,235✔
1867

1868
    tFree(pColData->pBitMap);
23,670,235!
1869
    tFree(pColData->aOffset);
23,670,238✔
1870
    tFree(pColData->pData);
23,670,247!
1871
  }
1872
}
23,670,857✔
1873

1874
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
25,762,511✔
1875
  pColData->cid = cid;
25,762,511✔
1876
  pColData->type = type;
25,762,511✔
1877
  pColData->cflag = cflag;
25,762,511✔
1878
  tColDataClear(pColData);
25,762,511✔
1879
}
25,765,100✔
1880

1881
void tColDataClear(SColData *pColData) {
52,710,939✔
1882
  pColData->numOfNone = 0;
52,710,939✔
1883
  pColData->numOfNull = 0;
52,710,939✔
1884
  pColData->numOfValue = 0;
52,710,939✔
1885
  pColData->nVal = 0;
52,710,939✔
1886
  pColData->flag = 0;
52,710,939✔
1887
  pColData->nData = 0;
52,710,939✔
1888
}
52,710,939✔
1889

1890
void tColDataDeepClear(SColData *pColData) {
125,942✔
1891
  pColData->pBitMap = NULL;
125,942✔
1892
  pColData->aOffset = NULL;
125,942✔
1893
  pColData->pData = NULL;
125,942✔
1894

1895
  tColDataClear(pColData);
125,942✔
1896
}
125,941✔
1897

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

1901
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1902
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
84,548,493!
1903
    if (code) goto _exit;
95,548,798!
1904
    pColData->aOffset[pColData->nVal] = pColData->nData;
95,548,798✔
1905

1906
    if (nData) {
95,548,798!
1907
      code = tRealloc(&pColData->pData, pColData->nData + nData);
94,221,570!
1908
      if (code) goto _exit;
94,779,805!
1909
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
94,779,805✔
1910
      pColData->nData += nData;
94,779,805✔
1911
    }
1912
  } else {
1913
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
1914
      return TSDB_CODE_INVALID_PARA;
×
1915
    }
1916
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
1917
    if (code) goto _exit;
2,147,483,647!
1918
    if (pData) {
2,147,483,647!
1919
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
1920
    } else {
1921
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
38,356,440✔
1922
    }
1923
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
1924
  }
1925
  pColData->nVal++;
2,147,483,647✔
1926

1927
_exit:
2,147,483,647✔
1928
  return code;
2,147,483,647✔
1929
}
1930
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
6,291,294✔
1931
  pColData->flag = HAS_VALUE;
6,292,889✔
1932
  pColData->numOfValue++;
6,291,294✔
1933
  return tColDataPutValue(pColData, pData, nData);
6,293,402✔
1934
}
1935
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
176,362✔
1936
  pColData->flag = HAS_NONE;
176,362✔
1937
  pColData->numOfNone++;
176,362✔
1938
  pColData->nVal++;
176,362✔
1939
  return 0;
176,362✔
1940
}
1941
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
382,887✔
1942
  pColData->flag = HAS_NULL;
384,487✔
1943
  pColData->numOfNull++;
384,487✔
1944
  pColData->nVal++;
384,487✔
1945
  return 0;
382,887✔
1946
}
1947
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,305✔
1948
  int32_t code = 0;
1,305✔
1949

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

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

1957
  pColData->flag |= HAS_VALUE;
1,308✔
1958
  pColData->numOfValue++;
1,308✔
1959

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

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

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

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

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

1995
  return code;
601✔
1996
}
1997
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
140,441✔
1998
  int32_t code = 0;
140,551✔
1999

2000
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
140,551✔
2001
  code = tRealloc(&pColData->pBitMap, nBit);
140,499!
2002
  if (code) return code;
140,554!
2003

2004
  memset(pColData->pBitMap, 0, nBit);
140,554✔
2005
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
140,554!
2006

2007
  pColData->flag |= HAS_VALUE;
140,554✔
2008
  pColData->numOfValue++;
140,554✔
2009

2010
  if (pColData->nVal) {
140,554!
2011
    if (IS_VAR_DATA_TYPE(pColData->type)) {
140,554!
2012
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
7,396✔
2013
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
7,396!
2014
      if (code) return code;
7,396!
2015
      memset(pColData->aOffset, 0, nOffset);
7,396✔
2016
    } else {
2017
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
133,158✔
2018
      code = tRealloc(&pColData->pData, pColData->nData);
133,158!
2019
      if (code) return code;
133,156!
2020
      memset(pColData->pData, 0, pColData->nData);
133,156✔
2021
    }
2022
  }
2023

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2096
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
9,369✔
2097
  if (code) return code;
9,368!
2098

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

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

2112
  pColData->flag |= HAS_NONE;
6,071✔
2113
  pColData->numOfNone++;
6,071✔
2114

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

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

2122
  return tColDataPutValue(pColData, NULL, 0);
6,073✔
2123
}
2124
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
706,400✔
2125
  int32_t code = 0;
729,943✔
2126

2127
  pColData->flag |= HAS_NULL;
729,943✔
2128
  pColData->numOfNull++;
729,943✔
2129

2130
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
729,943✔
2131
  code = tRealloc(&pColData->pBitMap, nBit);
729,639✔
2132
  if (code) return code;
729,954!
2133

2134
  memset(pColData->pBitMap, 255, nBit);
729,954✔
2135
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
729,954!
2136

2137
  return tColDataPutValue(pColData, NULL, 0);
729,951✔
2138
}
2139
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
54,799✔
2140
  int32_t code = 0;
56,800✔
2141

2142
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
56,799!
2143
  if (code) return code;
56,849!
2144

2145
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
56,849!
2146
  pColData->numOfValue++;
56,849!
2147

2148
  return tColDataPutValue(pColData, pData, nData);
57,515✔
2149
}
2150
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
101,637✔
2151
  int32_t code = 0;
101,637✔
2152

2153
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
101,637!
2154
  if (code) return code;
101,665!
2155

2156
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
101,665✔
2157
  pColData->numOfNone++;
101,665✔
2158

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

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

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

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

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

2179
  return tColDataPutValue(pColData, NULL, 0);
1✔
2180
}
2181
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
568,348,776✔
2182
  int32_t code = 0;
571,318,239✔
2183

2184
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
571,317,839!
2185
  if (code) return code;
572,247,378!
2186
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
572,247,378!
2187
  pColData->numOfValue++;
572,247,378!
2188

2189
  return tColDataPutValue(pColData, pData, nData);
574,973,863✔
2190
}
2191
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
3,995✔
2192
  int32_t code = 0;
3,995✔
2193

2194
  pColData->flag |= HAS_NONE;
3,995✔
2195
  pColData->numOfNone++;
3,995✔
2196

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

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

2206
  tFree(pColData->pBitMap);
3,996!
2207
  pColData->pBitMap = pBitMap;
3,996✔
2208

2209
  return tColDataPutValue(pColData, NULL, 0);
3,997✔
2210
}
2211
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
32,179,321✔
2212
  int32_t code = 0;
35,157,534✔
2213

2214
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
35,153,939!
2215
  if (code) return code;
35,174,091!
2216
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
35,174,091✔
2217
  pColData->numOfNull++;
35,174,091✔
2218

2219
  return tColDataPutValue(pColData, NULL, 0);
35,187,928✔
2220
}
2221
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2222
  int32_t code = 0;
×
2223

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

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

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

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

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

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

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

2271
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
9✔
2272
  pColData->numOfNone--;
9✔
2273
  pColData->nVal--;
9✔
2274
  if (pColData->numOfNone) {
9!
2275
    return tColDataAppendValue10(pColData, pData, nData);
×
2276
  } else {
2277
    pColData->flag = 0;
9✔
2278
    return tColDataAppendValue00(pColData, pData, nData);
9✔
2279
  }
2280
}
2281
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
2282
  pColData->numOfNone--;
24✔
2283
  pColData->nVal--;
24✔
2284
  if (pColData->numOfNone) {
24!
2285
    return tColDataAppendValue12(pColData, pData, nData);
×
2286
  } else {
2287
    pColData->flag = 0;
24✔
2288
    return tColDataAppendValue02(pColData, pData, nData);
24✔
2289
  }
2290
  return 0;
2291
}
2292
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
1,644✔
2293
  if (forward) {
1,644!
2294
    pColData->numOfNull--;
1,644✔
2295
    pColData->nVal--;
1,644✔
2296
    if (pColData->numOfNull) {
1,644✔
2297
      return tColDataAppendValue20(pColData, pData, nData);
58✔
2298
    } else {
2299
      pColData->flag = 0;
1,586✔
2300
      return tColDataAppendValue00(pColData, pData, nData);
1,586✔
2301
    }
2302
  }
2303
  return 0;
×
2304
}
2305
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2306
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2307
    pColData->numOfNone--;
×
2308
    pColData->nVal--;
×
2309
    if (pColData->numOfNone) {
×
2310
      return tColDataAppendValue30(pColData, pData, nData);
×
2311
    } else {
2312
      pColData->flag = HAS_NULL;
×
2313
      return tColDataAppendValue20(pColData, pData, nData);
×
2314
    }
2315
  } else if (forward) {  // NULL ==> VALUE
×
2316
    pColData->numOfNull--;
×
2317
    pColData->nVal--;
×
2318
    if (pColData->numOfNull) {
×
2319
      return tColDataAppendValue30(pColData, pData, nData);
×
2320
    } else {
2321
      pColData->flag = HAS_NONE;
×
2322
      return tColDataAppendValue10(pColData, pData, nData);
×
2323
    }
2324
  }
2325
  return 0;
×
2326
}
2327
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
2328
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
2329
    pColData->numOfNone--;
80✔
2330
    pColData->numOfNull++;
80✔
2331
    if (pColData->numOfNone) {
80!
2332
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2333
    } else {
2334
      pColData->flag = HAS_NULL;
80✔
2335
    }
2336
  }
2337
  return 0;
80✔
2338
}
2339
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
35,415,174✔
2340
  if (forward) {  // VALUE ==> VALUE
35,415,174!
2341
    pColData->nVal--;
35,415,353✔
2342
    if (IS_VAR_DATA_TYPE(pColData->type)) {
35,415,353!
2343
      pColData->nData = pColData->aOffset[pColData->nVal];
790,846✔
2344
    } else {
2345
      pColData->nData -= TYPE_BYTES[pColData->type];
34,624,507✔
2346
    }
2347
    return tColDataPutValue(pColData, pData, nData);
35,437,766✔
2348
  }
2349
  return 0;
×
2350
}
2351
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24,815✔
2352
  if (forward) {  // VALUE ==> NULL
24,815!
2353
    pColData->numOfValue--;
24,815✔
2354
    pColData->nVal--;
24,815✔
2355
    if (pColData->numOfValue) {
24,815✔
2356
      if (IS_VAR_DATA_TYPE(pColData->type)) {
23,239!
2357
        pColData->nData = pColData->aOffset[pColData->nVal];
1,042✔
2358
      } else {
2359
        pColData->nData -= TYPE_BYTES[pColData->type];
22,197✔
2360
      }
2361
      return tColDataAppendValue42(pColData, pData, nData);
23,238✔
2362
    } else {
2363
      pColData->flag = 0;
1,576✔
2364
      pColData->nData = 0;
1,576✔
2365
      return tColDataAppendValue02(pColData, pData, nData);
1,576✔
2366
    }
2367
  }
2368
  return 0;
×
2369
}
2370
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,690✔
2371
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
5,690✔
2372
    pColData->numOfNone--;
5,597✔
2373
    pColData->nVal--;
5,597✔
2374
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,597!
2375
      pColData->nData -= TYPE_BYTES[pColData->type];
4,477✔
2376
    }
2377
    if (pColData->numOfNone) {
5,597✔
2378
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2379
    } else {
2380
      pColData->flag = HAS_VALUE;
3,597✔
2381
      return tColDataAppendValue40(pColData, pData, nData);
3,598✔
2382
    }
2383
  } else if (forward) {  // VALUE ==> VALUE
93!
2384
    pColData->nVal--;
93✔
2385
    if (IS_VAR_DATA_TYPE(pColData->type)) {
93!
2386
      pColData->nData = pColData->aOffset[pColData->nVal];
22✔
2387
    } else {
2388
      pColData->nData -= TYPE_BYTES[pColData->type];
71✔
2389
    }
2390
    return tColDataPutValue(pColData, pData, nData);
93✔
2391
  }
2392
  return 0;
×
2393
}
2394
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
304✔
2395
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
304!
2396
    pColData->numOfNone--;
304✔
2397
    pColData->nVal--;
304✔
2398
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
304!
2399
      pColData->nData -= TYPE_BYTES[pColData->type];
244✔
2400
    }
2401
    if (pColData->numOfNone) {
304!
2402
      return tColDataAppendValue52(pColData, pData, nData);
×
2403
    } else {
2404
      pColData->flag = HAS_VALUE;
304!
2405
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2406
    }
2407
  } else if (forward) {  // VALUE ==> NULL
×
2408
    pColData->numOfValue--;
×
2409
    pColData->nVal--;
×
2410
    if (pColData->numOfValue) {
×
2411
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2412
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2413
      } else {
2414
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2415
      }
2416
      return tColDataAppendValue52(pColData, pData, nData);
×
2417
    } else {
2418
      pColData->flag = HAS_NONE;
×
2419
      pColData->nData = 0;
×
2420
      return tColDataAppendValue12(pColData, pData, nData);
×
2421
    }
2422
  }
2423
  return 0;
×
2424
}
2425
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
59,340,232✔
2426
  if (forward) {
59,340,232!
2427
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
59,340,234✔
2428
      pColData->numOfNull--;
3,006,332✔
2429
      pColData->nVal--;
3,006,332✔
2430
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,006,332!
2431
        pColData->nData -= TYPE_BYTES[pColData->type];
3,001,485✔
2432
      }
2433
      if (pColData->numOfNull) {
3,006,332✔
2434
        return tColDataAppendValue60(pColData, pData, nData);
2,969,063✔
2435
      } else {
2436
        pColData->flag = HAS_VALUE;
37,269✔
2437
        return tColDataAppendValue40(pColData, pData, nData);
37,270✔
2438
      }
2439
    } else {  // VALUE ==> VALUE
2440
      pColData->nVal--;
56,333,902✔
2441
      if (IS_VAR_DATA_TYPE(pColData->type)) {
56,333,902!
2442
        pColData->nData = pColData->aOffset[pColData->nVal];
2,663✔
2443
      } else {
2444
        pColData->nData -= TYPE_BYTES[pColData->type];
56,331,239✔
2445
      }
2446
      return tColDataPutValue(pColData, pData, nData);
56,333,904✔
2447
    }
2448
  }
2449
  return 0;
×
2450
}
2451
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,146,859✔
2452
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
3,146,859!
2453
    pColData->numOfValue--;
2,974,670✔
2454
    pColData->nVal--;
2,974,670✔
2455
    if (pColData->numOfValue) {
2,974,670✔
2456
      if (IS_VAR_DATA_TYPE(pColData->type)) {
2,974,618!
2457
        pColData->nData = pColData->aOffset[pColData->nVal];
2,508✔
2458
      } else {
2459
        pColData->nData -= TYPE_BYTES[pColData->type];
2,972,110✔
2460
      }
2461
      return tColDataAppendValue62(pColData, pData, nData);
2,974,620✔
2462
    } else {
2463
      pColData->flag = HAS_NULL;
52✔
2464
      pColData->nData = 0;
52!
2465
      return tColDataAppendValue20(pColData, pData, nData);
53✔
2466
    }
2467
  }
2468
  return 0;
172,189✔
2469
}
2470
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
401✔
2471
  int32_t code = 0;
401✔
2472

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

2572
    //    VALUE             NONE        NULL
2573
};
2574
int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward) {
95,832,225✔
2575
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
95,832,225!
2576
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
95,832,435!
2577

2578
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
95,832,435!
2579

2580
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
95,832,435✔
2581
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData, forward);
95,832,435!
2582
}
2583

2584
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
95,353,017✔
2585
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
95,353,017✔
2586
}
95,353,017✔
2587
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
1,553,573✔
2588
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
1,553,573✔
2589
}
1,553,573✔
2590
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
11,489✔
2591
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2592
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,489!
2593
    case 0:
1,045✔
2594
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,045✔
2595
      break;
1,045✔
2596
    case 1:
10,447✔
2597
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,447✔
2598
      break;
10,447✔
2599
    default:
×
2600
      break;
×
2601
  }
2602
}
11,489✔
2603
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
2604
  SValue value = {.type = pColData->type};
2,147,483,647✔
2605
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2606
    if (iVal + 1 < pColData->nVal) {
209,075,461!
2607
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
215,293,894✔
2608
    } else {
2609
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2610
    }
2611
    value.pData = pColData->pData + pColData->aOffset[iVal];
209,075,461✔
2612
  } else {
2613
    valueSetDatum(&value, pColData->type, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
2614
                  tDataTypes[pColData->type].bytes);
2,147,483,647✔
2615
  }
2616
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
2617
}
423,155,174✔
2618
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
225,291✔
2619
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2620
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
225,291!
2621
    case 0:
102,634✔
2622
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
102,634✔
2623
      break;
102,634✔
2624
    case 1:
122,908✔
2625
      tColDataGetValue4(pColData, iVal, pColVal);
2626
      break;
123,139✔
2627
    default:
×
2628
      break;
×
2629
  }
2630
}
225,522✔
2631
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
445,491,133✔
2632
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2633
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
445,491,133!
2634
    case 0:
23,178,947✔
2635
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
23,178,947✔
2636
      break;
23,178,947✔
2637
    case 1:
422,487,870✔
2638
      tColDataGetValue4(pColData, iVal, pColVal);
2639
      break;
423,012,774✔
2640
    default:
×
2641
      break;
×
2642
  }
2643
}
446,016,037✔
2644
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
11✔
2645
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
2646
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
11!
2647
    case 0:
5✔
2648
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
5✔
2649
      break;
5✔
2650
    case 1:
5✔
2651
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
5✔
2652
      break;
5✔
2653
    case 2:
1!
2654
      tColDataGetValue4(pColData, iVal, pColVal);
2655
      break;
1✔
2656
    default:
×
2657
      break;
×
2658
  }
2659
}
11✔
2660
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2661
    NULL,               // 0
2662
    tColDataGetValue1,  // HAS_NONE
2663
    tColDataGetValue2,  // HAS_NULL
2664
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2665
    tColDataGetValue4,  // HAS_VALUE
2666
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2667
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2668
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2669
};
2670
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
2671
  if (iVal < 0 || iVal >= pColData->nVal ||
2,147,483,647!
2672
      (pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
2,147,483,647!
2673
    return TSDB_CODE_INVALID_PARA;
×
2674
  }
2675
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
2676
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
2677
}
2678

2679
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
608,112,991✔
2680
  switch (pColData->flag) {
608,112,991!
2681
    case HAS_NONE:
×
2682
      return 0;
×
2683
    case HAS_NULL:
×
2684
      return 1;
×
2685
    case (HAS_NULL | HAS_NONE):
11,495✔
2686
      return GET_BIT1(pColData->pBitMap, iVal);
11,495✔
2687
    case HAS_VALUE:
×
2688
      return 2;
×
2689
    case (HAS_VALUE | HAS_NONE):
607,146✔
2690
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
607,146✔
2691
    case (HAS_VALUE | HAS_NULL):
607,533,077✔
2692
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
607,533,077✔
2693
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2694
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
2695
    default:
×
2696
      return 0;
×
2697
  }
2698
}
2699

2700
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg) {
7,924✔
2701
  int32_t code = 0;
7,924✔
2702

2703
  *pColData = *pColDataFrom;
7,924✔
2704

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

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

2742
  // value
2743
  if (pColData->nData) {
7,924✔
2744
    pColData->pData = xMalloc(arg, pColData->nData);
7,823✔
2745
    if (pColData->pData == NULL) {
7,823!
2746
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2747
      goto _exit;
×
2748
    }
2749

2750
    (void)memcpy(pColData->pData, pColDataFrom->pData, pColData->nData);
7,823✔
2751
  } else {
2752
    pColData->pData = NULL;
101✔
2753
  }
2754

2755
_exit:
7,924✔
2756
  return code;
7,924✔
2757
}
2758

2759
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
6,272,510✔
2760
  int32_t code;
2761
  SBuffer local;
2762

2763
  if (!(colData->nVal > 0)) {
6,272,510!
2764
    return TSDB_CODE_INVALID_PARA;
×
2765
  }
2766

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

2776
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
6,272,510!
2777
    return 0;
237,659✔
2778
  }
2779

2780
  tBufferInit(&local);
2781
  if (assist == NULL) {
6,034,851!
2782
    assist = &local;
×
2783
  }
2784

2785
  // bitmap
2786
  if (colData->flag != HAS_VALUE) {
6,034,851✔
2787
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
777,322✔
2788
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
1✔
2789
    } else {
2790
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
777,321✔
2791
    }
2792

2793
    SCompressInfo cinfo = {
777,322✔
2794
        .dataType = TSDB_DATA_TYPE_TINYINT,
2795
        .cmprAlg = info->cmprAlg,
777,322✔
2796
        .originalSize = info->bitmapOriginalSize,
777,322✔
2797
    };
2798

2799
    code = tCompressDataToBuffer(colData->pBitMap, &cinfo, output, assist);
777,322✔
2800
    if (code) {
777,348!
2801
      tBufferDestroy(&local);
2802
      return code;
×
2803
    }
2804

2805
    info->bitmapCompressedSize = cinfo.compressedSize;
777,348✔
2806
  }
2807

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

2813
  // offset
2814
  if (IS_VAR_DATA_TYPE(colData->type)) {
6,034,276!
2815
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
971,777✔
2816

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

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

2829
    info->offsetCompressedSize = cinfo.compressedSize;
971,716✔
2830
  }
2831

2832
  // data
2833
  if (colData->nData > 0) {
6,034,215!
2834
    info->dataOriginalSize = colData->nData;
6,034,354✔
2835

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

2842
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
6,034,354✔
2843
    if (code) {
6,034,798!
2844
      tBufferDestroy(&local);
2845
      return code;
×
2846
    }
2847

2848
    info->dataCompressedSize = cinfo.compressedSize;
6,034,798✔
2849
  }
2850

2851
  tBufferDestroy(&local);
2852
  return 0;
6,034,659✔
2853
}
2854

2855
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
19,532,404✔
2856
  int32_t  code;
2857
  SBuffer  local;
2858
  uint8_t *data = (uint8_t *)input;
19,532,404✔
2859

2860
  tBufferInit(&local);
2861
  if (assist == NULL) {
19,532,404!
2862
    assist = &local;
×
2863
  }
2864

2865
  tColDataClear(colData);
19,532,404✔
2866
  colData->cid = info->columnId;
19,531,515✔
2867
  colData->type = info->dataType;
19,531,515✔
2868
  colData->cflag = info->columnFlag;
19,531,515✔
2869
  colData->nVal = info->numOfData;
19,531,515✔
2870
  colData->flag = info->flag;
19,531,515✔
2871

2872
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
19,531,515✔
2873
    goto _exit;
2,695,074✔
2874
  }
2875

2876
  // bitmap
2877
  if (info->bitmapOriginalSize > 0) {
16,836,441✔
2878
    SCompressInfo cinfo = {
503,201✔
2879
        .dataType = TSDB_DATA_TYPE_TINYINT,
2880
        .cmprAlg = info->cmprAlg,
503,201✔
2881
        .originalSize = info->bitmapOriginalSize,
503,201✔
2882
        .compressedSize = info->bitmapCompressedSize,
503,201✔
2883
    };
2884

2885
    code = tRealloc(&colData->pBitMap, cinfo.originalSize);
503,201!
2886
    if (code) {
503,191!
2887
      tBufferDestroy(&local);
2888
      return code;
×
2889
    }
2890

2891
    code = tDecompressData(data, &cinfo, colData->pBitMap, cinfo.originalSize, assist);
503,191✔
2892
    if (code) {
503,185!
2893
      tBufferDestroy(&local);
2894
      return code;
×
2895
    }
2896

2897
    data += cinfo.compressedSize;
503,185✔
2898
  }
2899

2900
  if (info->flag == (HAS_NONE | HAS_NULL)) {
16,836,425✔
2901
    goto _exit;
609✔
2902
  }
2903

2904
  // offset
2905
  if (info->offsetOriginalSize > 0) {
16,835,816✔
2906
    SCompressInfo cinfo = {
2,697,358✔
2907
        .cmprAlg = info->cmprAlg,
2,697,358✔
2908
        .dataType = TSDB_DATA_TYPE_INT,
2909
        .originalSize = info->offsetOriginalSize,
2,697,358✔
2910
        .compressedSize = info->offsetCompressedSize,
2,697,358✔
2911
    };
2912

2913
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
2,697,358!
2914
    if (code) {
2,697,426!
2915
      tBufferDestroy(&local);
2916
      return code;
×
2917
    }
2918

2919
    code = tDecompressData(data, &cinfo, colData->aOffset, cinfo.originalSize, assist);
2,697,426✔
2920
    if (code) {
2,697,463!
2921
      tBufferDestroy(&local);
2922
      return code;
×
2923
    }
2924

2925
    data += cinfo.compressedSize;
2,697,463✔
2926
  }
2927

2928
  // data
2929
  if (info->dataOriginalSize > 0) {
16,835,921✔
2930
    colData->nData = info->dataOriginalSize;
16,834,818✔
2931

2932
    SCompressInfo cinfo = {
16,834,818✔
2933
        .cmprAlg = info->cmprAlg,
16,834,818✔
2934
        .dataType = colData->type,
16,834,818✔
2935
        .originalSize = info->dataOriginalSize,
16,834,818✔
2936
        .compressedSize = info->dataCompressedSize,
16,834,818✔
2937
    };
2938

2939
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
16,834,818!
2940
    if (code) {
16,834,711!
2941
      tBufferDestroy(&local);
2942
      return code;
×
2943
    }
2944

2945
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
16,834,711✔
2946
    if (code) {
16,834,317!
2947
      tBufferDestroy(&local);
2948
      return code;
×
2949
    }
2950

2951
    data += cinfo.compressedSize;
16,834,317✔
2952
  }
2953

2954
_exit:
1,103✔
2955
  switch (colData->flag) {
19,531,103✔
2956
    case HAS_NONE:
2,443,134✔
2957
      colData->numOfNone = colData->nVal;
2,443,134✔
2958
      break;
2,443,134✔
2959
    case HAS_NULL:
253,958✔
2960
      colData->numOfNull = colData->nVal;
253,958✔
2961
      break;
253,958✔
2962
    case HAS_VALUE:
16,331,057✔
2963
      colData->numOfValue = colData->nVal;
16,331,057✔
2964
      break;
16,331,057✔
2965
    default:
502,954✔
2966
      for (int32_t i = 0; i < colData->nVal; i++) {
341,038,483✔
2967
        uint8_t bitValue = tColDataGetBitValue(colData, i);
340,536,296✔
2968
        if (bitValue == 0) {
340,535,529✔
2969
          colData->numOfNone++;
195,301✔
2970
        } else if (bitValue == 1) {
340,340,228✔
2971
          colData->numOfNull++;
17,730,194✔
2972
        } else {
2973
          colData->numOfValue++;
322,610,034✔
2974
        }
2975
      }
2976
  }
2977
  tBufferDestroy(&local);
2978
  return 0;
19,530,336✔
2979
}
2980

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

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

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

3055
_exit:
10✔
3056
  return code;
575✔
3057
}
3058

3059
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
6,353,666✔
3060
                               checkWKBGeometryFn cgeos) {
3061
  int32_t code = 0;
6,353,666✔
3062

3063
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
6,353,666✔
3064
    if (!(pColData->type == pBind->buffer_type)) {
5,786,533!
3065
      return TSDB_CODE_INVALID_PARA;
×
3066
    }
3067
  }
3068

3069
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
6,353,666!
3070
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
524,757✔
3071
      code = igeos();
201✔
3072
      if (code) {
201!
3073
        return code;
×
3074
      }
3075
    }
3076
    for (int32_t i = 0; i < pBind->num; ++i) {
2,474,046✔
3077
      if (pBind->is_null && pBind->is_null[i]) {
1,774,431✔
3078
        if (pColData->cflag & COL_IS_KEY) {
103,579!
3079
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3080
          goto _exit;
×
3081
        }
3082
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
103,579✔
3083
        if (code) goto _exit;
104,248!
3084
      } else if (pBind->length[i] > buffMaxLen) {
1,670,852!
3085
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3086
      } else {
3087
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
1,670,852✔
3088
          code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]);
202✔
3089
          if (code) goto _exit;
202!
3090
        }
3091
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
1,670,852✔
3092
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
1,670,852✔
3093
      }
3094
    }
3095
  } else {  // fixed-length data type
3096
    bool allValue;
3097
    bool allNull;
3098
    if (pBind->is_null) {
5,828,909✔
3099
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
535,967✔
3100
      allNull = (same && pBind->is_null[0] != 0);
535,967!
3101
      allValue = (same && pBind->is_null[0] == 0);
535,967!
3102
    } else {
3103
      allNull = false;
5,292,942✔
3104
      allValue = true;
5,292,942✔
3105
    }
3106

3107
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
5,828,909!
3108
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3109
      goto _exit;
×
3110
    }
3111

3112
    if (allValue) {
5,828,909✔
3113
      // optimize (todo)
3114
      for (int32_t i = 0; i < pBind->num; ++i) {
199,484,856✔
3115
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
191,565,070✔
3116
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
191,565,070✔
3117
      }
3118
    } else if (allNull) {
294,207!
3119
      // optimize (todo)
3120
      for (int32_t i = 0; i < pBind->num; ++i) {
970,863✔
3121
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
476,918✔
3122
        if (code) goto _exit;
493,521!
3123
      }
3124
    } else {
3125
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3126
        if (pBind->is_null[i]) {
50,012✔
3127
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
4,256✔
3128
          if (code) goto _exit;
4,256!
3129
        } else {
3130
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
45,756✔
3131
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
45,756✔
3132
        }
3133
      }
3134
    }
3135
  }
3136

3137
_exit:
×
3138
  return code;
8,930,211✔
3139
}
3140

3141
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
×
3142
                                checkWKBGeometryFn cgeos) {
3143
  int32_t code = 0;
×
3144

3145
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
×
3146
    if (!(pColData->type == pBind->buffer_type)) {
×
3147
      return TSDB_CODE_INVALID_PARA;
×
3148
    }
3149
  }
3150

3151
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
×
3152
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
3153
      code = igeos();
×
3154
      if (code) {
×
3155
        return code;
×
3156
      }
3157
    }
3158

3159
    uint8_t *buf = pBind->buffer;
×
3160
    for (int32_t i = 0; i < pBind->num; ++i) {
×
3161
      if (pBind->is_null && pBind->is_null[i]) {
×
3162
        if (pColData->cflag & COL_IS_KEY) {
×
3163
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3164
          goto _exit;
×
3165
        }
3166
        if (pBind->is_null[i] == 1) {
×
3167
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3168
          if (code) goto _exit;
×
3169
        } else {
3170
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3171
          if (code) goto _exit;
×
3172
        }
3173
      } else if (pBind->length[i] > buffMaxLen) {
×
3174
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3175
      } else {
3176
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
3177
          code = cgeos(buf, pBind->length[i]);
×
3178
          if (code) goto _exit;
×
3179
        }
3180
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);
×
3181
        buf += pBind->length[i];
×
3182
      }
3183
    }
3184
  } else {  // fixed-length data type
3185
    bool allValue;
3186
    bool allNull;
3187
    bool allNone;
3188
    if (pBind->is_null) {
×
3189
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
×
3190
      allNull = (same && pBind->is_null[0] == 1);
×
3191
      allNone = (same && pBind->is_null[0] > 1);
×
3192
      allValue = (same && pBind->is_null[0] == 0);
×
3193
    } else {
3194
      allNull = false;
×
3195
      allNone = false;
×
3196
      allValue = true;
×
3197
    }
3198

3199
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
×
3200
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3201
      goto _exit;
×
3202
    }
3203

3204
    if (allValue) {
×
3205
      // optimize (todo)
3206
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3207
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3208
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3209
          *val = 1;
×
3210
        }
3211

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

3242
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3243
        }
3244
      }
3245
    }
3246
  }
3247

3248
_exit:
×
3249
  return code;
×
3250
}
3251

3252
/* build rows to `rowArray` from bind
3253
 * `infos` is the bind information array
3254
 * `numOfInfos` is the number of bind information
3255
 * `infoSorted` is whether the bind information is sorted by column id
3256
 * `pTSchema` is the schema of the table
3257
 * `rowArray` is the array to store the rows
3258
 * `pOrdered` is the pointer to store ordered
3259
 * `pDupTs` is the pointer to store duplicateTs
3260
 */
3261
int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
545✔
3262
                           SArray *rowArray, bool *pOrdered, bool *pDupTs) {
3263
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
545!
3264
    return TSDB_CODE_INVALID_PARA;
×
3265
  }
3266

3267
  if (!infoSorted) {
551!
3268
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo2), NULL, tBindInfoCompare);
×
3269
  }
3270

3271
  int32_t code = 0;
551✔
3272
  int32_t numOfRows = infos[0].bind->num;
551✔
3273
  SArray *colValArray, *bufArray;
3274
  SColVal colVal;
3275

3276
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
551!
3277
    return terrno;
×
3278
  }
3279
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
552!
3280
    taosArrayDestroy(colValArray);
×
3281
    return terrno;
×
3282
  }
3283
  for (int i = 0; i < numOfInfos; ++i) {
2,777✔
3284
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
4,448!
3285
      taosArrayDestroy(colValArray);
×
3286
      taosArrayDestroy(bufArray);
×
3287
      return terrno;
×
3288
    }
3289
  }
3290

3291
  SRowKey rowKey, lastRowKey;
3292
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
196,817!
3293
    taosArrayClear(colValArray);
207,171✔
3294

3295
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
877,360✔
3296
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
666,144!
3297
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
3298
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
3299
        } else {
3300
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3301
        }
3302
      } else {
3303
        SValue value = {
666,144✔
3304
            .type = infos[iInfo].type,
666,144✔
3305
        };
3306
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
666,144!
3307
          int32_t   length = infos[iInfo].bind->length[iRow];
6,633✔
3308
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
6,633✔
3309
          value.nData = length;
6,633✔
3310
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
6,633!
3311
            code = TSDB_CODE_INVALID_PARA;
×
3312
            goto _exit;
×
3313
          }
3314
          value.pData = *data;
6,633✔
3315
          *data += length;
6,633✔
3316
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3317
        } else {
3318
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
659,511✔
3319
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
659,511!
3320
            *val = 1;
×
3321
          }
3322
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
659,511✔
3323
        }
3324
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
701,080✔
3325
      }
3326
      if (taosArrayPush(colValArray, &colVal) == NULL) {
671,550!
3327
        code = terrno;
×
3328
        goto _exit;
×
3329
      }
3330
    }
3331

3332
    SRow *row;
3333
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
211,216!
3334
      goto _exit;
×
3335
    }
3336

3337
    if ((taosArrayPush(rowArray, &row)) == NULL) {
196,333!
3338
      code = terrno;
×
3339
      goto _exit;
×
3340
    }
3341

3342
    if (pOrdered && pDupTs) {
196,333!
3343
      tRowGetKey(row, &rowKey);
392,734!
3344
      if (iRow == 0) {
196,298✔
3345
        *pOrdered = true;
549✔
3346
        *pDupTs = false;
549✔
3347
      } else {
3348
        // no more compare if we already get disordered or duplicate rows
3349
        if (*pOrdered && !*pDupTs) {
195,749✔
3350
          int32_t code = tRowKeyCompare(&rowKey, &lastRowKey);
195,669✔
3351
          *pOrdered = (code >= 0);
195,669✔
3352
          *pDupTs = (code == 0);
195,669✔
3353
        }
3354
      }
3355
      lastRowKey = rowKey;
196,298✔
3356
    }
3357
  }
3358

3359
_exit:
×
3360
  taosArrayDestroy(colValArray);
×
3361
  taosArrayDestroy(bufArray);
553✔
3362
  return code;
559✔
3363
}
3364

3365
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
346✔
3366
  int32_t code = TSDB_CODE_SUCCESS;
346✔
3367

3368
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
346!
3369
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
146✔
3370
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
51✔
3371
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
73✔
3372
    if (iToRow == 0) {
73✔
3373
      pToColData->aOffset[iToRow] = 0;
14✔
3374
    }
3375

3376
    if (iToRow < pToColData->nVal - 1) {
73✔
3377
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
64✔
3378
    }
3379

3380
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
73✔
3381
                 nData);
3382
  } else {
3383
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
273✔
3384
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
273✔
3385
  }
3386
  return code;
346✔
3387
}
3388

3389
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
354✔
3390
                                        int32_t iToRow) {
3391
  int32_t code = TSDB_CODE_SUCCESS;
354✔
3392

3393
  switch (pFromColData->flag) {
354!
3394
    case HAS_NONE:
8✔
3395
    case HAS_NULL:
3396
      break;
8✔
3397
    case (HAS_NULL | HAS_NONE): {
×
3398
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
3399
    } break;
×
3400
    case HAS_VALUE: {
298✔
3401
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
298!
3402
    } break;
298✔
3403
    case (HAS_VALUE | HAS_NONE):
48✔
3404
    case (HAS_VALUE | HAS_NULL): {
3405
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
48✔
3406
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
48!
3407
    } break;
48✔
3408
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
3409
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
3410
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3411
    } break;
×
3412
    default:
×
3413
      return -1;
×
3414
  }
3415

3416
  return code;
354✔
3417
}
3418

3419
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
75✔
3420
                               int32_t nColData) {
3421
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3422

3423
  for (int32_t i = 0; i < nColData; i++) {
429✔
3424
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
354✔
3425
    if (code != TSDB_CODE_SUCCESS) {
354!
3426
      return code;
×
3427
    }
3428
  }
3429

3430
  return code;
75✔
3431
}
3432

3433
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
75✔
3434
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3435

3436
  for (int32_t i = 0; i < nColData; i++) {
429✔
3437
    SColVal cv = {0};
354✔
3438
    code = tColDataGetValue(&aFromColData[i], iFromRow, &cv);
354✔
3439
    if (code != TSDB_CODE_SUCCESS) {
354!
3440
      return code;
×
3441
    }
3442
    code = tColDataAppendValue(&aToColData[i], &cv);
354✔
3443
    if (code != TSDB_CODE_SUCCESS) {
354!
3444
      return code;
×
3445
    }
3446
  }
3447

3448
  return code;
75✔
3449
}
3450

3451
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
198,274,330✔
3452
  SColVal cv;
3453

3454
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
198,274,330✔
3455
  key->numOfPKs = 0;
198,274,330✔
3456

3457
  for (int i = 1; i < nColData; i++) {
198,293,590!
3458
    if (aColData[i].cflag & COL_IS_KEY) {
198,987,385✔
3459
      tColDataGetValue4(&aColData[i], iRow, &cv);
18,530!
3460
      key->pks[key->numOfPKs++] = cv.value;
19,260✔
3461
    } else {
3462
      break;
198,968,855✔
3463
    }
3464
  }
3465
}
198,275,060✔
3466

3467
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
23✔
3468
  SColData *aDstColData = NULL;
23✔
3469
  int32_t   i = start, j = mid + 1, k = 0;
23✔
3470
  SRowKey   keyi, keyj;
3471

3472
  if (end > start) {
23!
3473
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
23!
3474
    if (aDstColData == NULL) {
23!
3475
      return terrno;
×
3476
    }
3477
    for (int c = 0; c < nColData; ++c) {
129✔
3478
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
106✔
3479
    }
3480
  }
3481

3482
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
23✔
3483
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
23✔
3484
  while (i <= mid && j <= end) {
63✔
3485
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
40✔
3486
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
30!
3487
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
30✔
3488
    } else {
3489
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
10!
3490
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
10✔
3491
    }
3492
  }
3493

3494
  while (i <= mid) {
35✔
3495
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
12!
3496
  }
3497

3498
  while (j <= end) {
46✔
3499
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
23!
3500
  }
3501

3502
  for (i = start, k = 0; i <= end; ++i, ++k) {
98✔
3503
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
75!
3504
  }
3505

3506
  if (aDstColData) {
23!
3507
    for (int32_t i = 0; i < nColData; i++) {
129✔
3508
      tColDataDestroy(&aDstColData[i]);
106✔
3509
    }
3510
    taosMemoryFree(aDstColData);
23!
3511
  }
3512

3513
  return TSDB_CODE_SUCCESS;
23✔
3514
}
3515

3516
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
52✔
3517
  int32_t ret = TSDB_CODE_SUCCESS;
52✔
3518
  int32_t mid;
3519

3520
  if (start >= end) {
52✔
3521
    return TSDB_CODE_SUCCESS;
29✔
3522
  }
3523

3524
  mid = (start + end) / 2;
23✔
3525

3526
  ret = tColDataMergeSort(aColData, start, mid, nColData);
23✔
3527
  if (ret != TSDB_CODE_SUCCESS) {
23!
3528
    return ret;
×
3529
  }
3530

3531
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
23✔
3532
  if (ret != TSDB_CODE_SUCCESS) {
23!
3533
    return ret;
×
3534
  }
3535

3536
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
23✔
3537
}
3538

3539
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
6✔
3540
  int32_t nVal = aColData[0].nVal;
6✔
3541

3542
  if (nVal < 2) return TSDB_CODE_SUCCESS;
6!
3543

3544
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
6✔
3545
}
3546

3547
static int32_t tColDataMerge(SArray **colArr) {
3✔
3548
  int32_t code = 0;
3✔
3549
  SArray *src = *colArr;
3✔
3550
  SArray *dst = NULL;
3✔
3551

3552
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
3✔
3553
  if (dst == NULL) {
3!
3554
    return terrno;
×
3555
  }
3556

3557
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
12✔
3558
    SColData *srcCol = taosArrayGet(src, i);
9✔
3559

3560
    SColData *dstCol = taosArrayReserve(dst, 1);
9✔
3561
    if (dstCol == NULL) {
9!
3562
      code = terrno;
×
3563
      goto _exit;
×
3564
    }
3565
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
9✔
3566
  }
3567

3568
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
3✔
3569
  SRowKey lastKey;
3570
  for (int32_t i = 0; i < numRows; i++) {
9✔
3571
    SRowKey key;
3572
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
3573

3574
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
9!
3575
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3576
        SColData *srcCol = taosArrayGet(src, j);
9✔
3577
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3578

3579
        SColVal cv;
3580
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3581
        if (code != TSDB_CODE_SUCCESS) {
9!
3582
          goto _exit;
×
3583
        }
3584
        code = tColDataAppendValue(dstCol, &cv);
9✔
3585
        if (code) {
9!
3586
          goto _exit;
×
3587
        }
3588
      }
3589
      lastKey = key;
3✔
3590
    } else {  // update existing row
3591
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3592
        SColData *srcCol = taosArrayGet(src, j);
9✔
3593
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3594

3595
        SColVal cv;
3596
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3597
        if (code != TSDB_CODE_SUCCESS) {
9!
3598
          goto _exit;
×
3599
        }
3600
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3601
        if (code) {
9!
3602
          goto _exit;
×
3603
        }
3604
      }
3605
    }
3606
  }
3607

3608
_exit:
3✔
3609
  if (code) {
3!
3610
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3611
  } else {
3612
    taosArrayDestroyEx(src, tColDataDestroy);
3✔
3613
    *colArr = dst;
3✔
3614
  }
3615
  return code;
3✔
3616
}
3617

3618
int32_t tColDataSortMerge(SArray **arr) {
30,591✔
3619
  SArray   *colDataArr = *arr;
30,591✔
3620
  int32_t   nColData = TARRAY_SIZE(colDataArr);
30,591✔
3621
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
30,591✔
3622

3623
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
30,591!
3624
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3625
  }
3626
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
30,591!
3627
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3628
  }
3629
  if (!(aColData[0].flag == HAS_VALUE)) {
30,591!
3630
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3631
  }
3632

3633
  if (aColData[0].nVal <= 1) goto _exit;
30,591✔
3634

3635
  int8_t doSort = 0;
30,433✔
3636
  int8_t doMerge = 0;
30,433✔
3637
  // scan -------
3638
  SRowKey lastKey;
3639
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
30,433✔
3640
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
96,123,650!
3641
    SRowKey key;
3642
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
96,783,092✔
3643

3644
    int32_t c = tRowKeyCompare(&lastKey, &key);
96,093,222✔
3645
    if (c < 0) {
96,093,222✔
3646
      lastKey = key;
95,712,354✔
3647
      continue;
95,712,354✔
3648
    } else if (c > 0) {
380,868✔
3649
      doSort = 1;
6✔
3650
      break;
6✔
3651
    } else {
3652
      doMerge = 1;
380,862✔
3653
    }
3654
  }
3655

3656
  // sort -------
3657
  if (doSort) {
×
3658
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
6!
3659
  }
3660

3661
  if (doMerge != 1) {
1,215,492✔
3662
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
30,432✔
3663
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
96,804,323!
3664
      SRowKey key;
3665
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
97,958,949✔
3666

3667
      int32_t c = tRowKeyCompare(&lastKey, &key);
96,773,891✔
3668
      if (c == 0) {
96,773,891!
3669
        doMerge = 1;
×
3670
        break;
×
3671
      }
3672
      lastKey = key;
96,773,891✔
3673
    }
3674
  }
3675

3676
  // merge -------
3677
  if (doMerge) {
30,434✔
3678
    int32_t code = tColDataMerge(arr);
3✔
3679
    if (code) return code;
3!
3680
  }
3681

3682
_exit:
30,434✔
3683
  return 0;
30,592✔
3684
}
3685

3686
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
188,008✔
3687
  int32_t code = 0;
188,008✔
3688

3689
  if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
376,016!
3690
  if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
376,016!
3691
  if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
376,016!
3692
  if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
376,016!
3693

3694
  // bitmap
3695
  switch (pColData->flag) {
188,008!
3696
    case (HAS_NULL | HAS_NONE):
2,138✔
3697
    case (HAS_VALUE | HAS_NONE):
3698
    case (HAS_VALUE | HAS_NULL):
3699
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
2,138✔
3700
      if (code) return code;
2,138!
3701
      break;
2,138✔
3702
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3703
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
3704
      if (code) return code;
×
3705
      break;
×
3706
    default:
185,870✔
3707
      break;
185,870✔
3708
  }
3709

3710
  // value
3711
  if (pColData->flag & HAS_VALUE) {
188,008✔
3712
    if (IS_VAR_DATA_TYPE(pColData->type)) {
187,642✔
3713
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
1,257✔
3714
      if (code) return code;
1,257!
3715

3716
      code = tEncodeI32v(pEncoder, pColData->nData);
1,257✔
3717
      if (code) return code;
1,257!
3718

3719
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
1,257✔
3720
      if (code) return code;
1,257!
3721
    } else {
3722
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
186,385✔
3723
      if (code) return code;
186,385!
3724
    }
3725
  }
3726

3727
  return code;
188,008✔
3728
}
3729

3730
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
13,560✔
3731
  int32_t code = 0;
13,560✔
3732

3733
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
27,121!
3734
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
27,119!
3735
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
27,118!
3736
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
27,117!
3737

3738
  if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
13,557!
3739
    return TSDB_CODE_INVALID_PARA;
1✔
3740
  }
3741

3742
  // bitmap
3743
  switch (pColData->flag) {
13,556!
3744
    case (HAS_NULL | HAS_NONE):
232✔
3745
    case (HAS_VALUE | HAS_NONE):
3746
    case (HAS_VALUE | HAS_NULL):
3747
      code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
232!
3748
      if (code) return code;
232!
3749
      break;
232✔
3750
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3751
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
3752
      if (code) return code;
×
3753
      break;
×
3754
    default:
13,324✔
3755
      break;
13,324✔
3756
  }
3757

3758
  // value
3759
  if (pColData->flag & HAS_VALUE) {
13,556✔
3760
    if (IS_VAR_DATA_TYPE(pColData->type)) {
13,336!
3761
      code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
516!
3762
      if (code) return code;
516!
3763

3764
      code = tDecodeI32v(pDecoder, &pColData->nData);
516✔
3765
      if (code) return code;
521!
3766

3767
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
521!
3768
      if (code) return code;
521!
3769
    } else {
3770
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
12,820✔
3771
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
12,820!
3772
      if (code) return code;
12,820!
3773
    }
3774
  }
3775
  pColData->cflag = 0;
13,561✔
3776

3777
  return code;
13,561✔
3778
}
3779

3780
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
188,008✔
3781
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
188,008✔
3782
  if (code) return code;
188,009!
3783
  return tEncodeI8(pEncoder, pColData->cflag);
376,018✔
3784
}
3785

3786
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
13,559✔
3787
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
13,559✔
3788
  if (code) return code;
13,560!
3789

3790
  code = tDecodeI8(pDecoder, &pColData->cflag);
13,560✔
3791
  return code;
13,558✔
3792
}
3793

3794
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
187,994✔
3795
  if (version == 0) {
187,994!
3796
    return tEncodeColDataVersion0(pEncoder, pColData);
×
3797
  } else if (version == 1) {
187,994!
3798
    return tEncodeColDataVersion1(pEncoder, pColData);
188,016✔
3799
  } else {
3800
    return TSDB_CODE_INVALID_PARA;
×
3801
  }
3802
}
3803

3804
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
13,559✔
3805
  if (version == 0) {
13,559!
3806
    return tDecodeColDataVersion0(pDecoder, pColData);
×
3807
  } else if (version == 1) {
13,559!
3808
    return tDecodeColDataVersion1(pDecoder, pColData);
13,559✔
3809
  } else {
3810
    return TSDB_CODE_INVALID_PARA;
×
3811
  }
3812
}
3813

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

3816
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
848,609,615✔
3817
  if (ppRow == NULL) {
848,609,615!
3818
    return TSDB_CODE_INVALID_PARA;
×
3819
  }
3820

3821
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
848,609,615!
3822
    return TSDB_CODE_OUT_OF_RANGE;
×
3823
  }
3824

3825
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
848,609,615✔
3826
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
1,697,219,230!
3827
}
3828

3829
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3830
  do {                                       \
3831
    (SUM) += (VAL);                          \
3832
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3833
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3834
  } while (0)
3835

3836
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, SColumnDataAgg* pAggs) {
5,673✔
3837
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,673✔
3838
  int16_t*numOfNull = &pAggs->numOfNull;
5,673✔
3839
  *sum = 0;
5,673✔
3840
  *max = 0;
5,673✔
3841
  *min = 1;
5,673✔
3842
  *numOfNull = 0;
5,673✔
3843

3844
  int8_t val;
3845
  if (HAS_VALUE == pColData->flag) {
5,673!
3846
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,249,201✔
3847
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,243,528✔
3848
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,243,528✔
3849
    }
3850
  } else {
3851
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3852
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3853
        case 0:
×
3854
        case 1:
3855
          (*numOfNull)++;
×
3856
          break;
×
3857
        case 2:
×
3858
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
×
3859
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3860
          break;
×
3861
        default:
×
3862
          break;
×
3863
      }
3864
    }
3865
  }
3866
}
5,673✔
3867

3868
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, SColumnDataAgg* pAggs) {
5,823✔
3869
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,823✔
3870
  int16_t *numOfNull = &pAggs->numOfNull;
5,823✔
3871
  *sum = 0;
5,823✔
3872
  *max = INT8_MIN;
5,823✔
3873
  *min = INT8_MAX;
5,823✔
3874
  *numOfNull = 0;
5,823✔
3875

3876
  int8_t val;
3877
  if (HAS_VALUE == pColData->flag) {
5,823!
3878
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,517,918✔
3879
      val = ((int8_t *)pColData->pData)[iVal];
4,512,095✔
3880
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,512,095✔
3881
    }
3882
  } else {
3883
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3884
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3885
        case 0:
×
3886
        case 1:
3887
          (*numOfNull)++;
×
3888
          break;
×
3889
        case 2:
×
3890
          val = ((int8_t *)pColData->pData)[iVal];
×
3891
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3892
          break;
×
3893
        default:
×
3894
          break;
×
3895
      }
3896
    }
3897
  }
3898
}
5,823✔
3899

3900
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, SColumnDataAgg* pAggs) {
5,709✔
3901
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,709✔
3902
  int16_t *numOfNull = &pAggs->numOfNull;
5,709✔
3903
  *sum = 0;
5,709✔
3904
  *max = INT16_MIN;
5,709✔
3905
  *min = INT16_MAX;
5,709✔
3906
  *numOfNull = 0;
5,709✔
3907

3908
  int16_t val;
3909
  if (HAS_VALUE == pColData->flag) {
5,709!
3910
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,368,710✔
3911
      val = ((int16_t *)pColData->pData)[iVal];
4,363,001✔
3912
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,363,001✔
3913
    }
3914
  } else {
3915
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3916
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3917
        case 0:
×
3918
        case 1:
3919
          (*numOfNull)++;
×
3920
          break;
×
3921
        case 2:
×
3922
          val = ((int16_t *)pColData->pData)[iVal];
×
3923
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3924
          break;
×
3925
        default:
×
3926
          break;
×
3927
      }
3928
    }
3929
  }
3930
}
5,709✔
3931

3932
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, SColumnDataAgg* pAggs) {
297,704✔
3933
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
297,704✔
3934
  int16_t *numOfNull = &pAggs->numOfNull;
297,704✔
3935
  *sum = 0;
297,704✔
3936
  *max = INT32_MIN;
297,704✔
3937
  *min = INT32_MAX;
297,704✔
3938
  *numOfNull = 0;
297,704✔
3939

3940
  int32_t val;
3941
  if (HAS_VALUE == pColData->flag) {
297,704✔
3942
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
753,009,480✔
3943
      val = ((int32_t *)pColData->pData)[iVal];
752,793,546✔
3944
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
752,793,546✔
3945
    }
3946
  } else {
3947
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
255,445,302✔
3948
      switch (tColDataGetBitValue(pColData, iVal)) {
255,365,107!
3949
        case 0:
12,808,587✔
3950
        case 1:
3951
          (*numOfNull)++;
12,808,587✔
3952
          break;
12,808,587✔
3953
        case 2:
242,587,079✔
3954
          val = ((int32_t *)pColData->pData)[iVal];
242,587,079✔
3955
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
242,587,079✔
3956
          break;
242,587,079✔
3957
        default:
×
3958
          break;
×
3959
      }
3960
    }
3961
  }
3962
}
296,129✔
3963

3964
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, SColumnDataAgg* pAggs) {
108,467✔
3965
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
108,467✔
3966
  int16_t *numOfNull = &pAggs->numOfNull;
108,467✔
3967
  *sum = 0;
108,467✔
3968
  *max = INT64_MIN;
108,467✔
3969
  *min = INT64_MAX;
108,467✔
3970
  *numOfNull = 0;
108,467✔
3971

3972
  int64_t val;
3973
  if (HAS_VALUE == pColData->flag) {
108,467✔
3974
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
327,104,097✔
3975
      val = ((int64_t *)pColData->pData)[iVal];
326,996,092✔
3976
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
326,996,092✔
3977
    }
3978
  } else {
3979
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
90,144✔
3980
      switch (tColDataGetBitValue(pColData, iVal)) {
89,682!
3981
        case 0:
75,200✔
3982
        case 1:
3983
          (*numOfNull)++;
75,200✔
3984
          break;
75,200✔
3985
        case 2:
14,482✔
3986
          val = ((int64_t *)pColData->pData)[iVal];
14,482✔
3987
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
14,482✔
3988
          break;
14,482✔
3989
        default:
×
3990
          break;
×
3991
      }
3992
    }
3993
  }
3994
}
108,467✔
3995

3996
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, SColumnDataAgg* pAggs) {
195,515✔
3997
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
195,515✔
3998
  int16_t *numOfNull = &pAggs->numOfNull;
195,515✔
3999
  *(double *)sum = 0;
195,515✔
4000
  *(double *)max = -FLT_MAX;
195,515✔
4001
  *(double *)min = FLT_MAX;
195,515✔
4002
  *numOfNull = 0;
195,515✔
4003

4004
  float val;
4005
  if (HAS_VALUE == pColData->flag) {
195,515✔
4006
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
780,073,383✔
4007
      val = ((float *)pColData->pData)[iVal];
779,877,869✔
4008
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
779,877,869✔
4009
    }
4010
  } else {
4011
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
106✔
4012
      switch (tColDataGetBitValue(pColData, iVal)) {
105!
4013
        case 0:
95✔
4014
        case 1:
4015
          (*numOfNull)++;
95✔
4016
          break;
95✔
4017
        case 2:
10✔
4018
          val = ((float *)pColData->pData)[iVal];
10✔
4019
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
10!
4020
          break;
10✔
4021
        default:
×
4022
          break;
×
4023
      }
4024
    }
4025
  }
4026
}
195,515✔
4027

4028
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, SColumnDataAgg* pAggs) {
10,906✔
4029
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
10,906✔
4030
  int16_t *numOfNull = &pAggs->numOfNull;
10,906✔
4031
  *(double *)sum = 0;
10,906✔
4032
  *(double *)max = -DBL_MAX;
10,906✔
4033
  *(double *)min = DBL_MAX;
10,906✔
4034
  *numOfNull = 0;
10,906✔
4035

4036
  double val;
4037
  if (HAS_VALUE == pColData->flag) {
10,906!
4038
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
24,352,271✔
4039
      val = ((double *)pColData->pData)[iVal];
24,341,365✔
4040
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
24,341,365✔
4041
    }
4042
  } else {
4043
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4044
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4045
        case 0:
×
4046
        case 1:
4047
          (*numOfNull)++;
×
4048
          break;
×
4049
        case 2:
×
4050
          val = ((double *)pColData->pData)[iVal];
×
4051
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
×
4052
          break;
×
4053
        default:
×
4054
          break;
×
4055
      }
4056
    }
4057
  }
4058
}
10,906✔
4059

4060
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,791✔
4061
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,791✔
4062
  int16_t *numOfNull = &pAggs->numOfNull;
2,791✔
4063
  *(uint64_t *)sum = 0;
2,791✔
4064
  *(uint64_t *)max = 0;
2,791✔
4065
  *(uint64_t *)min = UINT8_MAX;
2,791✔
4066
  *numOfNull = 0;
2,791✔
4067

4068
  uint8_t val;
4069
  if (HAS_VALUE == pColData->flag) {
2,791!
4070
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,484,329✔
4071
      val = ((uint8_t *)pColData->pData)[iVal];
3,481,538✔
4072
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,481,538✔
4073
    }
4074
  } else {
4075
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4076
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4077
        case 0:
×
4078
        case 1:
4079
          (*numOfNull)++;
×
4080
          break;
×
4081
        case 2:
×
4082
          val = ((uint8_t *)pColData->pData)[iVal];
×
4083
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4084
          break;
×
4085
        default:
×
4086
          break;
×
4087
      }
4088
    }
4089
  }
4090
}
2,791✔
4091

4092
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,791✔
4093
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,791✔
4094
  int16_t *numOfNull = &pAggs->numOfNull;
2,791✔
4095
  *(uint64_t *)sum = 0;
2,791✔
4096
  *(uint64_t *)max = 0;
2,791✔
4097
  *(uint64_t *)min = UINT16_MAX;
2,791✔
4098
  *numOfNull = 0;
2,791✔
4099

4100
  uint16_t val;
4101
  if (HAS_VALUE == pColData->flag) {
2,791!
4102
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,484,329✔
4103
      val = ((uint16_t *)pColData->pData)[iVal];
3,481,538✔
4104
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,481,538✔
4105
    }
4106
  } else {
4107
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4108
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4109
        case 0:
×
4110
        case 1:
4111
          (*numOfNull)++;
×
4112
          break;
×
4113
        case 2:
×
4114
          val = ((uint16_t *)pColData->pData)[iVal];
×
4115
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4116
          break;
×
4117
        default:
×
4118
          break;
×
4119
      }
4120
    }
4121
  }
4122
}
2,791✔
4123

4124
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,791✔
4125
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,791✔
4126
  int16_t *numOfNull = &pAggs->numOfNull;
2,791✔
4127
  *(uint64_t *)sum = 0;
2,791✔
4128
  *(uint64_t *)max = 0;
2,791✔
4129
  *(uint64_t *)min = UINT32_MAX;
2,791✔
4130
  *numOfNull = 0;
2,791✔
4131

4132
  uint32_t val;
4133
  if (HAS_VALUE == pColData->flag) {
2,791!
4134
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,482,685✔
4135
      val = ((uint32_t *)pColData->pData)[iVal];
3,479,894✔
4136
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,479,894✔
4137
    }
4138
  } else {
4139
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4140
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4141
        case 0:
×
4142
        case 1:
4143
          (*numOfNull)++;
×
4144
          break;
×
4145
        case 2:
×
4146
          val = ((uint32_t *)pColData->pData)[iVal];
×
4147
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4148
          break;
×
4149
        default:
×
4150
          break;
×
4151
      }
4152
    }
4153
  }
4154
}
2,791✔
4155

4156
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, SColumnDataAgg* pAggs) {
2,791✔
4157
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,791✔
4158
  int16_t *numOfNull = &pAggs->numOfNull;
2,791✔
4159
  *(uint64_t *)sum = 0;
2,791✔
4160
  *(uint64_t *)max = 0;
2,791✔
4161
  *(uint64_t *)min = UINT64_MAX;
2,791✔
4162
  *numOfNull = 0;
2,791✔
4163

4164
  uint64_t val;
4165
  if (HAS_VALUE == pColData->flag) {
2,791!
4166
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,479,977✔
4167
      val = ((uint64_t *)pColData->pData)[iVal];
3,477,186✔
4168
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,477,186✔
4169
    }
4170
  } else {
4171
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4172
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4173
        case 0:
×
4174
        case 1:
4175
          (*numOfNull)++;
×
4176
          break;
×
4177
        case 2:
×
4178
          val = ((uint64_t *)pColData->pData)[iVal];
×
4179
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4180
          break;
×
4181
        default:
×
4182
          break;
×
4183
      }
4184
    }
4185
  }
4186
}
2,791✔
4187

4188
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, SColumnDataAgg* pAggs) {
18,563✔
4189
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,563✔
4190
  int16_t *numOfNull = &pAggs->numOfNull;
18,563✔
4191
  *(uint64_t *)sum = 0;
18,563✔
4192
  *(uint64_t *)max = 0;
18,563✔
4193
  *(uint64_t *)min = 0;
18,563✔
4194
  *numOfNull = 0;
18,563✔
4195

4196
  switch (pColData->flag) {
18,563!
4197
    case HAS_NONE:
×
4198
    case HAS_NULL:
4199
    case (HAS_NONE | HAS_NULL):
4200
      *numOfNull = pColData->nVal;
×
4201
      break;
×
4202
    case HAS_VALUE:
18,563✔
4203
      *numOfNull = 0;
18,563✔
4204
      break;
18,563✔
4205
    case (HAS_VALUE | HAS_NULL):
×
4206
    case (HAS_VALUE | HAS_NONE):
4207
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4208
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
×
4209
          (*numOfNull)++;
×
4210
        }
4211
      }
4212
      break;
×
4213
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4214
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4215
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4216
          (*numOfNull)++;
×
4217
        }
4218
      }
4219
      break;
×
4220
    default:
×
4221
      break;
×
4222
  }
4223
}
18,563✔
4224

4225
#define CALC_DECIMAL_SUM_MAX_MIN(TYPE, pSumOp, pCompOp, pColData, pSum, pMax, pMin)           \
4226
  do {                                                                                        \
4227
    if (decimal128AddCheckOverflow((Decimal *)pSum, pVal, DECIMAL_WORD_NUM(TYPE))) *pOverflow = true; \
4228
    pSumOp->add(pSum, pVal, DECIMAL_WORD_NUM(TYPE));                                                  \
4229
    if (pCompOp->gt(pVal, pMax, DECIMAL_WORD_NUM(TYPE))) {                                            \
4230
      *(pMax) = *pVal;                                                                        \
4231
    }                                                                                         \
4232
    if (pCompOp->lt(pVal, pMin, DECIMAL_WORD_NUM(TYPE))) {                                            \
4233
      *(pMin) = *pVal;                                                                        \
4234
    }                                                                                         \
4235
  } while (0)
4236

4237
static FORCE_INLINE void tColDataCalcSMADecimal64Type(SColData* pColData, SColumnDataAgg* pAggs) {
140✔
4238
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum;
140✔
4239
  Decimal64  *pMax = (Decimal64 *)pAggs->decimal128Max, *pMin = (Decimal64 *)pAggs->decimal128Min;
140✔
4240
  uint8_t *pOverflow = &pAggs->overflow;
140✔
4241
  *pSum = DECIMAL128_ZERO;
140✔
4242
  *pMax = DECIMAL64_MIN;
140✔
4243
  *pMin = DECIMAL64_MAX;
140✔
4244
  pAggs->numOfNull = 0;
140✔
4245
  pAggs->colId |= DECIMAL_AGG_FLAG;
140✔
4246

4247
  Decimal64   *pVal = NULL;
140✔
4248
  const SDecimalOps *pSumOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
140✔
4249
  const SDecimalOps *pCompOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
140✔
4250
  if (HAS_VALUE == pColData->flag) {
140✔
4251
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
808✔
4252
      pVal = ((Decimal64*)pColData->pData) + iVal;
800✔
4253
      CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
800!
4254
    }
4255
  } else {
4256
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
102,432✔
4257
      switch (tColDataGetBitValue(pColData, iVal)) {
102,300!
4258
        case 0:
1,617✔
4259
        case 1:
4260
          pAggs->numOfNull++;
1,617✔
4261
          break;
1,617✔
4262
        case 2:
100,683✔
4263
          pVal = ((Decimal64 *)pColData->pData) + iVal;
100,683✔
4264
          CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
100,683!
4265
          break;
100,683✔
4266
        default:
×
4267
          break;
×
4268
      }
4269
    }
4270
  }
4271
}
140✔
4272

4273
static FORCE_INLINE void tColDataCalcSMADecimal128Type(SColData* pColData, SColumnDataAgg* pAggs) {
356✔
4274
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum, *pMax = (Decimal128 *)pAggs->decimal128Max,
356✔
4275
             *pMin = (Decimal128 *)pAggs->decimal128Min;
356✔
4276
  uint8_t *pOverflow = &pAggs->overflow;
356✔
4277
  *pSum = DECIMAL128_ZERO;
356✔
4278
  *pMax = DECIMAL128_MIN;
356✔
4279
  *pMin = DECIMAL128_MAX;
356✔
4280
  pAggs->numOfNull = 0;
356✔
4281
  pAggs->colId |= DECIMAL_AGG_FLAG;
356✔
4282

4283
  Decimal128        *pVal = NULL;
356✔
4284
  const SDecimalOps *pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
356✔
4285
  if (HAS_VALUE == pColData->flag) {
356✔
4286
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
1,212✔
4287
      pVal = ((Decimal128*)pColData->pData) + iVal;
1,200✔
4288
      CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
1,200✔
4289
    }
4290
  } else {
4291
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
317,689✔
4292
      switch (tColDataGetBitValue(pColData, iVal)) {
317,345!
4293
        case 0:
5,113✔
4294
        case 1:
4295
          pAggs->numOfNull++;
5,113✔
4296
          break;
5,113✔
4297
        case 2:
312,233✔
4298
          pVal = ((Decimal128*)pColData->pData) + iVal;
312,233✔
4299
          CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
312,233✔
4300
          break;
312,232✔
4301
        default:
×
4302
          break;
×
4303
      }
4304
    }
4305
  }
4306
}
356✔
4307

4308
void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAgg* pAggs) = {
4309
    NULL,
4310
    tColDataCalcSMABool,           // TSDB_DATA_TYPE_BOOL
4311
    tColDataCalcSMATinyInt,        // TSDB_DATA_TYPE_TINYINT
4312
    tColDataCalcSMATinySmallInt,   // TSDB_DATA_TYPE_SMALLINT
4313
    tColDataCalcSMAInt,            // TSDB_DATA_TYPE_INT
4314
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_BIGINT
4315
    tColDataCalcSMAFloat,          // TSDB_DATA_TYPE_FLOAT
4316
    tColDataCalcSMADouble,         // TSDB_DATA_TYPE_DOUBLE
4317
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARCHAR
4318
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_TIMESTAMP
4319
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_NCHAR
4320
    tColDataCalcSMAUTinyInt,       // TSDB_DATA_TYPE_UTINYINT
4321
    tColDataCalcSMATinyUSmallInt,  // TSDB_DATA_TYPE_USMALLINT
4322
    tColDataCalcSMAUInt,           // TSDB_DATA_TYPE_UINT
4323
    tColDataCalcSMAUBigInt,        // TSDB_DATA_TYPE_UBIGINT
4324
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_JSON
4325
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARBINARY
4326
    tColDataCalcSMADecimal128Type, // TSDB_DATA_TYPE_DECIMAL
4327
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_BLOB
4328
    NULL,                          // TSDB_DATA_TYPE_MEDIUMBLOB
4329
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_GEOMETRY
4330
    tColDataCalcSMADecimal64Type,  // TSDB_DATA_TYPE_DECIMAL64
4331
};
4332

4333
// SValueColumn ================================
4334
int32_t tValueColumnInit(SValueColumn *valCol) {
20,426,760✔
4335
  valCol->type = TSDB_DATA_TYPE_NULL;
20,426,760✔
4336
  valCol->numOfValues = 0;
20,426,760✔
4337
  tBufferInit(&valCol->data);
20,426,760✔
4338
  tBufferInit(&valCol->offsets);
20,426,760✔
4339
  return 0;
20,426,760✔
4340
}
4341

4342
void tValueColumnDestroy(SValueColumn *valCol) {
46,957,279✔
4343
  valCol->type = TSDB_DATA_TYPE_NULL;
46,957,279✔
4344
  valCol->numOfValues = 0;
46,957,279✔
4345
  tBufferDestroy(&valCol->data);
46,957,279✔
4346
  tBufferDestroy(&valCol->offsets);
46,957,277✔
4347
  return;
46,957,277✔
4348
}
4349

4350
void tValueColumnClear(SValueColumn *valCol) {
23,786,694✔
4351
  valCol->type = TSDB_DATA_TYPE_NULL;
23,786,694✔
4352
  valCol->numOfValues = 0;
23,786,694✔
4353
  tBufferClear(&valCol->data);
23,786,694✔
4354
  tBufferClear(&valCol->offsets);
23,786,694✔
4355
  return;
23,786,694✔
4356
}
4357

4358
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
965,785✔
4359
  int32_t code;
4360

4361
  if (valCol->numOfValues == 0) {
965,785✔
4362
    valCol->type = value->type;
4,524✔
4363
  }
4364

4365
  if (!(value->type == valCol->type)) {
965,785!
4366
    return TSDB_CODE_INVALID_PARA;
×
4367
  }
4368

4369
  if (IS_VAR_DATA_TYPE(value->type)) {
965,785!
4370
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
22!
4371
      return code;
×
4372
    }
4373
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
22!
4374
      return code;
×
4375
    }
4376
  } else {
4377
    code = tBufferPut(&valCol->data, VALUE_GET_DATUM(value, value->type), tDataTypes[value->type].bytes);
965,774!
4378
    if (code) return code;
965,775!
4379
  }
4380
  valCol->numOfValues++;
965,786✔
4381

4382
  return 0;
965,786✔
4383
}
4384

4385
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
276,346,838✔
4386
  int32_t code;
4387

4388
  if (idx < 0 || idx >= valCol->numOfValues) {
276,346,838!
4389
    return TSDB_CODE_OUT_OF_RANGE;
×
4390
  }
4391

4392
  if (IS_VAR_DATA_TYPE(valCol->type)) {
276,356,616!
4393
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
×
4394
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
×
4395
    int32_t  oldDataSize = nextOffset - offsets[idx];
×
4396
    int32_t  bytesAdded = value->nData - oldDataSize;
×
4397

4398
    if (bytesAdded != 0) {
×
4399
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
×
4400
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
×
4401
              tBufferGetSize(&valCol->data) - nextOffset);
×
4402
      valCol->data.size += bytesAdded;
×
4403

4404
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
×
4405
        offsets[i] += bytesAdded;
×
4406
      }
4407
    }
4408
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
×
4409
  } else {
4410
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, VALUE_GET_DATUM(value, valCol->type),
276,371,490!
4411
                        tDataTypes[valCol->type].bytes);
276,371,490✔
4412
  }
4413
  return 0;
4414
}
4415

4416
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
576,398,288✔
4417
  if (idx < 0 || idx >= valCol->numOfValues) {
576,398,288!
4418
    return TSDB_CODE_OUT_OF_RANGE;
×
4419
  }
4420

4421
  value->type = valCol->type;
576,446,190✔
4422
  if (IS_VAR_DATA_TYPE(value->type)) {
576,446,190!
4423
    int32_t       offset, nextOffset;
4424
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
2,100✔
4425

4426
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
2,100!
4427
    if (idx == valCol->numOfValues - 1) {
52✔
4428
      nextOffset = tBufferGetSize(&valCol->data);
48✔
4429
    } else {
4430
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
4✔
4431
    }
4432
    value->nData = nextOffset - offset;
51✔
4433
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
51✔
4434
  } else {
4435
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
576,444,090✔
4436
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
1,152,888,180!
4437
  }
4438
  return 0;
576,444,141✔
4439
}
4440

4441
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
4,523✔
4442
  int32_t code;
4443

4444
  if (!(valCol->numOfValues > 0)) {
4,523!
4445
    return TSDB_CODE_INVALID_PARA;
×
4446
  }
4447

4448
  (*info) = (SValueColumnCompressInfo){
4,523✔
4449
      .cmprAlg = info->cmprAlg,
4,523✔
4450
      .type = valCol->type,
4,523✔
4451
  };
4452

4453
  // offset
4454
  if (IS_VAR_DATA_TYPE(valCol->type)) {
4,523!
4455
    SCompressInfo cinfo = {
5✔
4456
        .cmprAlg = info->cmprAlg,
5✔
4457
        .dataType = TSDB_DATA_TYPE_INT,
4458
        .originalSize = valCol->offsets.size,
5✔
4459
    };
4460

4461
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
5✔
4462
    if (code) return code;
6!
4463

4464
    info->offsetOriginalSize = cinfo.originalSize;
6✔
4465
    info->offsetCompressedSize = cinfo.compressedSize;
6✔
4466
  }
4467

4468
  // data
4469
  SCompressInfo cinfo = {
4,524✔
4470
      .cmprAlg = info->cmprAlg,
4,524✔
4471
      .dataType = valCol->type,
4,524✔
4472
      .originalSize = valCol->data.size,
4,524✔
4473
  };
4474

4475
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
4,524✔
4476
  if (code) return code;
4,524!
4477

4478
  info->dataOriginalSize = cinfo.originalSize;
4,524✔
4479
  info->dataCompressedSize = cinfo.compressedSize;
4,524✔
4480

4481
  return 0;
4,524✔
4482
}
4483

4484
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
164,042✔
4485
                               SBuffer *assist) {
4486
  int32_t code;
4487

4488
  tValueColumnClear(valCol);
164,042✔
4489
  valCol->type = info->type;
164,042✔
4490
  // offset
4491
  if (IS_VAR_DATA_TYPE(valCol->type)) {
164,042!
4492
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
×
4493

4494
    SCompressInfo cinfo = {
×
4495
        .dataType = TSDB_DATA_TYPE_INT,
4496
        .cmprAlg = info->cmprAlg,
×
4497
        .originalSize = info->offsetOriginalSize,
×
4498
        .compressedSize = info->offsetCompressedSize,
×
4499
    };
4500

4501
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
×
4502
    if (code) {
×
4503
      return code;
×
4504
    }
4505
  } else {
4506
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
164,042✔
4507
  }
4508

4509
  // data
4510
  SCompressInfo cinfo = {
164,042✔
4511
      .dataType = valCol->type,
164,042✔
4512
      .cmprAlg = info->cmprAlg,
164,042✔
4513
      .originalSize = info->dataOriginalSize,
164,042✔
4514
      .compressedSize = info->dataCompressedSize,
164,042✔
4515
  };
4516

4517
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
164,042✔
4518
  if (code) {
164,045!
4519
    return code;
×
4520
  }
4521

4522
  return 0;
164,045✔
4523
}
4524

4525
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
4,524✔
4526
  int32_t code;
4527
  uint8_t fmtVer = 0;
4,524✔
4528

4529
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
9,048!
4530
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
9,048!
4531
  if ((code = tBufferPutI8(buffer, info->type))) return code;
9,048!
4532
  if (IS_VAR_DATA_TYPE(info->type)) {
4,524!
4533
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
10!
4534
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
10!
4535
  }
4536
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
9,048!
4537
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
9,048!
4538

4539
  return 0;
4,524✔
4540
}
4541

4542
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
164,042✔
4543
  int32_t code;
4544
  uint8_t fmtVer;
4545

4546
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
164,042!
4547
  if (fmtVer == 0) {
164,044!
4548
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
164,044!
4549
    if ((code = tBufferGetI8(reader, &info->type))) return code;
164,044!
4550
    if (IS_VAR_DATA_TYPE(info->type)) {
164,043!
4551
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
×
4552
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
×
4553
    } else {
4554
      info->offsetOriginalSize = 0;
164,044✔
4555
      info->offsetCompressedSize = 0;
164,044✔
4556
    }
4557
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
164,044!
4558
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
164,044!
4559
  } else {
4560
    return TSDB_CODE_INVALID_PARA;
×
4561
  }
4562

4563
  return 0;
164,044✔
4564
}
4565

4566
int32_t tCompressData(void          *input,       // input
12,801,552✔
4567
                      SCompressInfo *info,        // compress info
4568
                      void          *output,      // output
4569
                      int32_t        outputSize,  // output size
4570
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4571
) {
4572
  int32_t extraSizeNeeded;
4573
  int32_t code;
4574

4575
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
12,801,552!
4576
  if (!(outputSize >= extraSizeNeeded)) {
12,801,552!
4577
    return TSDB_CODE_INVALID_PARA;
×
4578
  }
4579

4580
  if (info->cmprAlg == NO_COMPRESSION) {
12,801,552!
4581
    (void)memcpy(output, input, info->originalSize);
×
4582
    info->compressedSize = info->originalSize;
×
4583
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
15,119,253!
4584
    SBuffer local;
4585

4586
    tBufferInit(&local);
4587
    if (buffer == NULL) {
2,314,806!
4588
      buffer = &local;
×
4589
    }
4590

4591
    if (info->cmprAlg == TWO_STAGE_COMP) {
2,314,806!
4592
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
2,317,595✔
4593
      if (code) {
2,317,595!
4594
        tBufferDestroy(&local);
4595
        return code;
×
4596
      }
4597
    }
4598

4599
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
4,632,507✔
4600
        input,                                                   // input
4601
        info->originalSize,                                      // input size
4602
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
2,314,806✔
4603
        output,                                                  // output
4604
        outputSize,                                              // output size
4605
        info->cmprAlg,                                           // compression algorithm
2,314,806✔
4606
        buffer->data,                                            // buffer
4607
        buffer->capacity                                         // buffer size
2,314,806✔
4608
    );
4609
    if (info->compressedSize < 0) {
2,317,701!
4610
      tBufferDestroy(&local);
4611
      return TSDB_CODE_COMPRESS_ERROR;
×
4612
    }
4613

4614
    tBufferDestroy(&local);
4615
  } else {
4616
    DEFINE_VAR(info->cmprAlg)
10,486,746✔
4617
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
10,486,746!
4618
      (void)memcpy(output, input, info->originalSize);
×
4619
      info->compressedSize = info->originalSize;
×
4620
      return 0;
×
4621
    }
4622
    SBuffer local;
4623

4624
    tBufferInit(&local);
4625
    if (buffer == NULL) {
10,486,746!
4626
      buffer = &local;
×
4627
    }
4628
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
10,486,746✔
4629

4630
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
20,974,400✔
4631
        input,                                                      // input
4632
        info->originalSize,                                         // input size
4633
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
10,486,757✔
4634
        output,                                                     // output
4635
        outputSize,                                                 // output size
4636
        info->cmprAlg,                                              // compression algorithm
4637
        buffer->data,                                               // buffer
4638
        buffer->capacity                                            // buffer size
10,486,757✔
4639
    );
4640
    if (info->compressedSize < 0) {
10,487,643!
4641
      tBufferDestroy(&local);
4642
      return TSDB_CODE_COMPRESS_ERROR;
×
4643
    }
4644

4645
    tBufferDestroy(&local);
4646
    // new col compress
4647
  }
4648

4649
  return 0;
12,805,344✔
4650
}
4651

4652
int32_t tDecompressData(void                *input,       // input
69,273,126✔
4653
                        const SCompressInfo *info,        // compress info
4654
                        void                *output,      // output
4655
                        int32_t              outputSize,  // output size
4656
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4657
) {
4658
  int32_t code;
4659

4660
  if (!(outputSize >= info->originalSize)) {
69,273,126!
4661
    return TSDB_CODE_INVALID_PARA;
×
4662
  }
4663

4664
  if (info->cmprAlg == NO_COMPRESSION) {
69,273,126!
4665
    if (!(info->compressedSize == info->originalSize)) {
×
4666
      return TSDB_CODE_INVALID_PARA;
×
4667
    }
4668
    (void)memcpy(output, input, info->compressedSize);
×
4669
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
99,055,055!
4670
    SBuffer local;
4671

4672
    tBufferInit(&local);
4673
    if (buffer == NULL) {
29,754,174!
4674
      buffer = &local;
×
4675
    }
4676

4677
    if (info->cmprAlg == TWO_STAGE_COMP) {
29,754,174!
4678
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
29,781,885✔
4679
      if (code) {
29,783,006!
4680
        tBufferDestroy(&local);
4681
        return code;
×
4682
      }
4683
    }
4684

4685
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
29,755,295✔
4686
        input,                                                  // input
4687
        info->compressedSize,                                   // inputSize
29,755,295✔
4688
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
29,755,295✔
4689
        output,                                                 // output
4690
        outputSize,                                             // output size
4691
        info->cmprAlg,                                          // compression algorithm
29,755,295✔
4692
        buffer->data,                                           // helper buffer
4693
        buffer->capacity                                        // extra buffer size
29,755,295✔
4694
    );
4695
    if (decompressedSize < 0) {
29,781,929!
4696
      tBufferDestroy(&local);
4697
      return TSDB_CODE_COMPRESS_ERROR;
×
4698
    }
4699

4700
    if (!(decompressedSize == info->originalSize)) {
29,781,929!
4701
      return TSDB_CODE_COMPRESS_ERROR;
×
4702
    }
4703
    tBufferDestroy(&local);
4704
  } else {
4705
    DEFINE_VAR(info->cmprAlg);
39,518,952✔
4706
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
39,518,952!
4707
      (void)memcpy(output, input, info->compressedSize);
×
4708
      return 0;
×
4709
    }
4710
    SBuffer local;
4711

4712
    tBufferInit(&local);
4713
    if (buffer == NULL) {
39,518,952!
4714
      buffer = &local;
×
4715
    }
4716
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
39,518,952✔
4717
    if (code) {
39,519,549!
4718
      return code;
×
4719
    }
4720

4721
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
39,519,549✔
4722
        input,                                                  // input
4723
        info->compressedSize,                                   // inputSize
39,519,549✔
4724
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
39,519,549✔
4725
        output,                                                 // output
4726
        outputSize,                                             // output size
4727
        info->cmprAlg,                                          // compression algorithm
39,519,549✔
4728
        buffer->data,                                           // helper buffer
4729
        buffer->capacity                                        // extra buffer size
39,519,549✔
4730
    );
4731
    if (decompressedSize < 0) {
39,521,001!
4732
      tBufferDestroy(&local);
4733
      return TSDB_CODE_COMPRESS_ERROR;
×
4734
    }
4735

4736
    if (!(decompressedSize == info->originalSize)) {
39,521,001!
4737
      return TSDB_CODE_COMPRESS_ERROR;
×
4738
    }
4739
    tBufferDestroy(&local);
4740
  }
4741

4742
  return 0;
69,302,930✔
4743
}
4744

4745
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
12,802,115✔
4746
  int32_t code;
4747

4748
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
12,802,115✔
4749
  if (code) return code;
12,802,133!
4750

4751
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
12,802,133✔
4752
  if (code) return code;
12,802,879!
4753

4754
  output->size += info->compressedSize;
12,802,879✔
4755
  return 0;
12,802,879✔
4756
}
4757

4758
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
29,776,048✔
4759
  int32_t code;
4760

4761
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
29,776,048✔
4762
  if (code) return code;
29,775,162!
4763

4764
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
29,775,162✔
4765
  if (code) return code;
29,781,111!
4766

4767
  output->size += info->originalSize;
29,781,111✔
4768
  return 0;
29,781,111✔
4769
}
4770

4771
// handle all types, including var data
4772
void valueSetDatum(SValue *pVal, int8_t type, void *pDatum, uint32_t len) {
2,147,483,647✔
4773
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
2,147,483,647!
4774
    pVal->pData = pDatum;
×
4775
    pVal->nData = len;
×
4776
  } else {
4777
    switch (len) {
2,147,483,647!
4778
      case sizeof(uint8_t):
1,275,202,682✔
4779
        pVal->val = *(uint8_t *)pDatum;
1,275,202,682✔
4780
        break;
1,275,202,682✔
4781
      case sizeof(uint16_t):
731,793,898✔
4782
        pVal->val = *(uint16_t *)pDatum;
731,793,898✔
4783
        break;
731,793,898✔
4784
      case sizeof(uint32_t):
2,147,483,647✔
4785
        pVal->val = *(uint32_t *)pDatum;
2,147,483,647✔
4786
        break;
2,147,483,647✔
4787
      case sizeof(uint64_t):
2,147,483,647✔
4788
        pVal->val = *(uint64_t *)pDatum;
2,147,483,647✔
4789
        break;
2,147,483,647✔
4790
      default:
×
4791
        break;
×
4792
    }
4793
  }
4794
}
2,147,483,647✔
4795

4796
void valueCloneDatum(SValue *pDst, const SValue *pSrc, int8_t type) {
61,505,081✔
4797
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
61,505,081!
4798
    memcpy(pDst->pData, pSrc->pData, pSrc->nData);
×
4799
    pDst->nData = pSrc->nData;
×
4800
  } else {
4801
    pDst->val = pSrc->val;
61,836,650✔
4802
  }
4803
}
61,505,081✔
4804
void valueClearDatum(SValue *pVal, int8_t type) {
×
4805
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
4806
    taosMemoryFreeClear(pVal->pData);
×
4807
    pVal->nData = 0;
×
4808
  } else {
4809
    pVal->val = 0;
×
4810
  }
4811
}
×
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