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

taosdata / TDengine / #3660

15 Mar 2025 09:06AM UTC coverage: 62.039% (-1.3%) from 63.314%
#3660

push

travis-ci

web-flow
feat(stream): support stream processing for virtual tables (#30144)

* enh: add client processing

* enh: add mnode vtables processing

* enh: add mnode vtable processing

* enh: add normal child vtable support

* fix: compile issues

* fix: compile issues

* fix: create stream issues

* fix: multi stream scan issue

* fix: remove debug info

* fix: agg task and task level issues

* fix: correct task output type

* fix: split vtablescan from agg

* fix: memory leak issues

* fix: add limitations

* Update 09-error-code.md

* Update 09-error-code.md

* fix: remove usless case

* feat(stream): extract original table data in source scan task

Implemented functionality in the source task to extract data
corresponding to the virtual table from the original table using WAL.
The extracted data is then sent to the downstream merge task for further
processing.

* feat(stream): multi-way merge using loser tree in virtual merge task

Implemented multi-way merge in the merge task using a loser tree to
combine data from multiple original table into a single virtual table.
The merged virtual table data is then pushed downstream for further
processing.  Introduced memory limit handling during the merge process
with configurable behavior when the memory limit is reached.

* fix(test): remove useless cases

---------

Co-authored-by: dapan1121 <wpan@taosdata.com>
Co-authored-by: Pan Wei <72057773+dapan1121@users.noreply.github.com>

154078 of 317582 branches covered (48.52%)

Branch coverage included in aggregate %.

313 of 2391 new or added lines in 34 files covered. (13.09%)

26134 existing lines in 205 files now uncovered.

240261 of 318051 relevant lines covered (75.54%)

16655189.27 hits per line

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

61.0
/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) {
740,444,374✔
66
  int32_t n = 0;
740,444,374✔
67
  n += tPutI8(p ? p + n : p, index->type);
740,444,374✔
68
  n += tPutU32v(p ? p + n : p, index->offset);
740,444,374✔
69
  return n;
740,444,374✔
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) {
UNCOV
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) {
UNCOV
112
  if ((pTColumn->flags & COL_IS_KEY)) return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
113
  sinfo->numOfNull++;
26,343,298✔
114
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
26,343,298✔
115
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
26,343,298✔
116
  return 0;
26,343,298✔
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;
256,954,687✔
124
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
256,954,687✔
125
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
256,954,687!
126
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
256,954,687✔
127
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
256,954,687✔
128
    sinfo->numOfPKs++;
256,954,687✔
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
467,860,227✔
134
                           + colVal->value.nData;               // value
467,860,227✔
135

136
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
467,860,227✔
137
                            + tPutU32v(NULL, colVal->value.nData)  // size
467,860,227✔
138
                            + colVal->value.nData;                 // value
467,860,227✔
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) {
953,742,831✔
147
  int32_t  code = 0;
953,742,831✔
148
  int32_t  colValIndex = 1;
953,742,831✔
149
  int32_t  numOfColVals = TARRAY_SIZE(colVals);
953,742,831✔
150
  SColVal *colValArray = (SColVal *)TARRAY_DATA(colVals);
953,742,831✔
151

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

162
  *sinfo = (SRowBuildScanInfo){
953,742,831✔
163
      .tupleFixedSize = schema->flen,
953,742,831✔
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;
×
UNCOV
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,686,596!
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) {
7,922,172✔
191
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
62!
192
        break;
31✔
193
      } else {  // skip useless value
194
        colValIndex++;
7,922,141✔
195
      }
196
    }
197
  }
198

199
  if (sinfo->numOfNone) {
953,742,831✔
200
    sinfo->flag |= HAS_NONE;
273,692,627✔
201
  }
202
  if (sinfo->numOfNull) {
953,742,831✔
203
    sinfo->flag |= HAS_NULL;
19,102,994✔
204
  }
205
  if (sinfo->numOfValue) {
953,742,831✔
206
    sinfo->flag |= HAS_VALUE;
923,968,881✔
207
  }
208

209
  // Tuple
210
  sinfo->tupleFlag = sinfo->flag;
953,742,831✔
211
  switch (sinfo->flag) {
953,742,831!
212
    case HAS_NONE:
36,352,863✔
213
    case HAS_NULL:
214
      sinfo->tupleBitmapSize = 0;
36,352,863✔
215
      sinfo->tupleFixedSize = 0;
36,352,863✔
216
      break;
36,352,863✔
217
    case HAS_VALUE:
671,348,321✔
218
      sinfo->tupleBitmapSize = 0;
671,348,321✔
219
      sinfo->tupleFixedSize = schema->flen;
671,348,321✔
220
      break;
671,348,321✔
221
    case (HAS_NONE | HAS_NULL):
24,449✔
222
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,449✔
223
      sinfo->tupleFixedSize = 0;
24,449✔
224
      break;
24,449✔
225
    case (HAS_NONE | HAS_VALUE):
255,532,851✔
226
    case (HAS_NULL | HAS_VALUE):
227
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
255,532,851✔
228
      sinfo->tupleFixedSize = schema->flen;
255,532,851✔
229
      break;
255,532,851✔
230
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
453,197✔
231
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
453,197✔
232
      sinfo->tupleFixedSize = schema->flen;
453,197✔
233
      break;
453,197✔
234
  }
235
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,208,778,772✔
236
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
257,302,284✔
237
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
257,302,284✔
238
  }
239
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
951,476,488✔
240
                        + sinfo->tuplePKSize      // primary keys
951,476,488✔
241
                        + sinfo->tupleBitmapSize  // bitmap
951,476,488✔
242
                        + sinfo->tupleFixedSize   // fixed part
951,476,488✔
243
                        + sinfo->tupleVarSize;    // var part
951,476,488✔
244

245
  // Key-Value
246
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
951,476,488!
247
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
956,759,787✔
248
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
956,759,787✔
UNCOV
249
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
250
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
3,762,087✔
251
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
3,762,087✔
252
  } else {
253
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
UNCOV
254
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
255
  }
256
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,205,573,558✔
257
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
254,663,984✔
258
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
254,663,984✔
259
  }
260
  sinfo->kvRowSize = sizeof(SRow)             // SRow
950,909,574✔
261
                     + sinfo->kvPKSize        // primary keys
950,909,574✔
262
                     + sinfo->kvIndexSize     // index array
950,909,574✔
263
                     + sinfo->kvPayloadSize;  // payload
950,909,574✔
264

265
_exit:
950,909,574✔
266
  return code;
950,909,574✔
267
}
268

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

273
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
714,582,607!
274
  if (*ppRow == NULL) {
720,799,324!
UNCOV
275
    return terrno;
×
276
  }
277
  (*ppRow)->flag = sinfo->tupleFlag;
720,799,324✔
278
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
720,799,324✔
279
  (*ppRow)->sver = schema->version;
720,799,324✔
280
  (*ppRow)->len = sinfo->tupleRowSize;
720,799,324✔
281
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
720,799,324✔
282

283
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
720,799,324✔
284
    return 0;
37,598,886✔
285
  }
286

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

292
  // primary keys
293
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
936,636,043✔
294
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
255,901,296✔
295
  }
296

297
  // bitmap + fixed + varlen
298
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
680,734,747✔
299
  int32_t colValIndex = 1;
680,734,747✔
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);
×
UNCOV
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;
147,086,390✔
313
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
147,086,390✔
314
            if (colValArray[colValIndex].value.nData) {
147,086,390!
315
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
154,443,064✔
316
              varlen += colValArray[colValIndex].value.nData;
154,443,064✔
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
8,394,358!
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
13,260,678!
UNCOV
325
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
326
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
471,412!
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
3,059,677✔
332
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
9!
333
        break;
9✔
334
      } else {
335
        colValIndex++;
3,059,668✔
336
      }
337
    }
338
  }
339

340
  return 0;
680,734,747✔
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,419,527!
347
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,549,887✔
348
  } else {
UNCOV
349
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
×
350
  }
351
  indices->nCol++;
2,147,483,647✔
352
}
2,147,483,647✔
353

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

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

367
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
243,569,411!
UNCOV
368
    return TSDB_CODE_INVALID_PARA;
×
369
  }
370

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

376
  // primary keys
377
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
244,649,847✔
378
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
1,066,921✔
379
  }
380

381
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
243,582,926✔
382
  int32_t colValIndex = 1;
243,582,926✔
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);
316,526,629✔
394
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
316,526,629✔
395
            if (colValArray[colValIndex].value.nData > 0) {
316,526,629!
396
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
322,997,071✔
397
                           colValArray[colValIndex].value.nData);
322,997,071✔
398
            }
399
            payloadSize += colValArray[colValIndex].value.nData;
316,526,629✔
400
          } else {
401
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
1,867,526,257✔
402
            (void)memcpy(payload + payloadSize, VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
1,867,526,257!
403
                         tDataTypes[schema->columns[i].type].bytes);
1,867,526,257✔
404
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
1,867,526,257✔
405
          }
406
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
2,147,483,647✔
407
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
12,833,638✔
408
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
25,667,276✔
409
        }
410

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

421
  return 0;
243,582,926✔
422
}
423

424
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
953,963,950✔
425
  int32_t           code;
426
  SRowBuildScanInfo sinfo;
427

428
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
953,963,950✔
429
  if (code) return code;
959,667,288!
430

431
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
959,667,288✔
432
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
717,024,474✔
433
  } else {
434
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
242,642,814✔
435
  }
436
  return code;
962,494,614✔
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;
×
UNCOV
442
  } else if (((SBindInfo *)p1)->columnId > ((SBindInfo *)p2)->columnId) {
×
443
    return 1;
×
444
  }
UNCOV
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,250✔
458
                          SArray *rowArray, bool *pOrdered, bool *pDupTs) {
459
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
34,250!
UNCOV
460
    return TSDB_CODE_INVALID_PARA;
×
461
  }
462

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

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

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

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

480
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
746,511✔
481
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
681,265✔
482
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
32✔
483
      } else {
484
        SValue value = {
681,233✔
485
            .type = infos[iInfo].type,
681,233✔
486
        };
487
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
681,233!
488
          value.nData = infos[iInfo].bind->length[iRow];
175,704✔
489
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
175,704!
UNCOV
490
            code = TSDB_CODE_INVALID_PARA;
×
UNCOV
491
            goto _exit;
×
492
          }
493
          value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
175,704✔
494
        } else {
495
          valueSetDatum(&value, infos[iInfo].type,
505,529✔
496
                        (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
505,529✔
497
                        infos[iInfo].bind->buffer_length);
505,529✔
498
        }
499
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
686,946✔
500
      }
501
      if (taosArrayPush(colValArray, &colVal) == NULL) {
664,468!
UNCOV
502
        code = terrno;
×
UNCOV
503
        goto _exit;
×
504
      }
505
    }
506

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

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

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

534
_exit:
33,662✔
535
  taosArrayDestroy(colValArray);
33,662✔
536
  return code;
34,293✔
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;
71,029,042✔
547
    pColVal->value.type = pTColumn->type;
71,029,042✔
548
    pColVal->flag = CV_FLAG_VALUE;
71,029,042✔
549
    VALUE_SET_TRIVIAL_DATUM(&pColVal->value, pRow->ts);
71,029,042✔
550
    return 0;
71,029,042✔
551
  }
552

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

558
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
559
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
847,335✔
560
    return 0;
847,335✔
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);
92,619,843✔
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) {
73,943,312!
576
      pv = pIdx->idx + (pIdx->nCol << 1);
88,266,229✔
577
    } else {
UNCOV
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) {
370,354,710!
589
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
370,466,513✔
590
      } else {
UNCOV
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);
85,118,988✔
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);
636,172,164!
607
            if (pColVal->value.nData > 0) {
636,172,164!
608
              pColVal->value.pData = pData;
669,830,923✔
609
            } else {
UNCOV
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);
1,712,354,502✔
625
  } else {  // Tuple Row
626
    uint8_t *bitmap = data;
590,642,608✔
627
    uint8_t *fixed;
628
    uint8_t *varlen;
629
    uint8_t  bit;
630

631
    if (pRow->flag == HAS_VALUE) {
590,642,608!
632
      fixed = bitmap;
621,328,610✔
633
      bit = BIT_FLG_VALUE;
621,328,610✔
UNCOV
634
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
×
UNCOV
635
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
UNCOV
636
      bit = GET_BIT2(bitmap, iCol - 1);
×
637
    } else {
UNCOV
638
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
UNCOV
639
      bit = GET_BIT1(bitmap, iCol - 1);
×
640

UNCOV
641
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
×
642
        if (bit) bit++;
21,203✔
UNCOV
643
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
×
644
        bit++;
2,170,424✔
645
      }
646
    }
647
    varlen = fixed + pTSchema->flen;
590,642,608✔
648

649
    if (bit == BIT_FLG_NONE) {
590,642,608✔
650
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,218✔
651
      return 0;
7,218✔
652
    } else if (bit == BIT_FLG_NULL) {
590,635,390✔
653
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
364,799✔
654
      return 0;
364,799✔
655
    }
656

657
    pColVal->cid = pTColumn->colId;
590,270,591✔
658
    pColVal->value.type = pTColumn->type;
590,270,591✔
659
    pColVal->flag = CV_FLAG_VALUE;
590,270,591✔
660
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
590,270,591!
UNCOV
661
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
×
UNCOV
662
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
×
663
    } else {
664
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
590,494,814✔
665
    }
666
  }
667

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

671
void tRowDestroy(SRow *pRow) {
690,398,915✔
672
  if (pRow) taosMemoryFree(pRow);
690,398,915!
673
}
690,368,594✔
674

675
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
241,922,203✔
676
  SRowKey key1, key2;
677
  tRowGetKey(*(SRow **)p1, &key1);
483,844,406✔
678
  tRowGetKey(*(SRow **)p2, &key2);
482,529,390✔
679
  return tRowKeyCompare(&key1, &key2);
249,402,684✔
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!
UNCOV
692
    code = terrno;
×
UNCOV
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!
UNCOV
706
    code = terrno;
×
UNCOV
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!
UNCOV
731
        code = terrno;
×
UNCOV
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!
UNCOV
743
    code = terrno;
×
UNCOV
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) {
33,666✔
760
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
33,666✔
761
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
33,663✔
762
  if (code != TSDB_CODE_SUCCESS) {
33,662!
UNCOV
763
    uError("taosArrayMSort failed caused by %d", code);
×
764
  }
765
  return code;
33,662✔
766
}
767

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

771
  int32_t iStart = 0;
33,707✔
772
  while (iStart < aRowP->size) {
35,076,401✔
773
    SRowKey key1;
774
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
35,074,374✔
775

776
    tRowGetKey(row1, &key1);
70,099,160✔
777

778
    int32_t iEnd = iStart + 1;
35,051,249✔
779
    while (iEnd < aRowP->size) {
35,037,820✔
780
      SRowKey key2;
781
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
35,033,829✔
782
      tRowGetKey(row2, &key2);
70,032,198✔
783

784
      if (tRowKeyCompare(&key1, &key2) != 0) break;
35,025,274!
785

UNCOV
786
      iEnd++;
×
787
    }
788

789
    if (iEnd - iStart > 1) {
35,042,694✔
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++;
35,042,694✔
796
  }
797

798
  return code;
2,027✔
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) {
888,691✔
822
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
888,691!
823

824
  int32_t code = 0;
888,691✔
825

826
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
888,691!
827
  if (pIter == NULL) {
919,296!
UNCOV
828
    code = terrno;
×
UNCOV
829
    goto _exit;
×
830
  }
831

832
  pIter->pRow = pRow;
919,296✔
833
  pIter->pTSchema = pTSchema;
919,296✔
834
  pIter->iTColumn = 0;
919,296✔
835

836
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
919,296✔
837

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

844
  if (pRow->flag >> 4) {
917,897✔
845
    pIter->iCol = 0;
914,698✔
846
    pIter->pIdx = (SKVIdx *)data;
914,698✔
847
    if (pRow->flag & KV_FLG_LIT) {
914,698✔
848
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
914,199✔
849
    } else if (pRow->flag & KV_FLG_MID) {
499!
850
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1);  // * sizeof(uint16_t)
600✔
851
    } else {
UNCOV
852
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2);  // * sizeof(uint32_t)
×
853
    }
854
  } else {
855
    switch (pRow->flag) {
3,199!
856
      case (HAS_NULL | HAS_NONE):
1✔
857
        pIter->pb = data;
1✔
858
        break;
1✔
859
      case HAS_VALUE:
2,577✔
860
        pIter->pf = data;
2,577✔
861
        pIter->pv = pIter->pf + pTSchema->flen;
2,577✔
862
        break;
2,577✔
863
      case (HAS_VALUE | HAS_NONE):
739✔
864
      case (HAS_VALUE | HAS_NULL):
865
        pIter->pb = data;
739✔
866
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
739✔
867
        pIter->pv = pIter->pf + pTSchema->flen;
739✔
868
        break;
739✔
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;
×
UNCOV
873
        break;
×
UNCOV
874
      default:
×
UNCOV
875
        break;
×
876
    }
877
  }
878

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

888
void tRowIterClose(SRowIter **ppIter) {
875,713✔
889
  SRowIter *pIter = *ppIter;
875,713✔
890
  if (pIter) {
875,713!
891
    taosMemoryFree(pIter);
876,120!
892
  }
893
  *ppIter = NULL;
921,100✔
894
}
921,100✔
895

896
SColVal *tRowIterNext(SRowIter *pIter) {
10,904,264✔
897
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
10,904,264✔
898
    return NULL;
875,201✔
899
  }
900

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

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

912
  if (pIter->pRow->flag == HAS_NONE) {
9,130,470✔
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,130,469✔
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,128,628!
923
    if (pIter->iCol < pIter->pIdx->nCol) {
9,630,171✔
924
      uint8_t *pData;
925

926
      if (pIter->pRow->flag & KV_FLG_LIT) {
7,921,104✔
927
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
7,906,789✔
928
      } else if (pIter->pRow->flag & KV_FLG_MID) {
14,315!
929
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
18,000✔
930
      } else {
UNCOV
931
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
932
      }
933

934
      int16_t cid;
935
      pData += tGetI16v(pData, &cid);
7,921,104✔
936

937
      if (TABS(cid) == pTColumn->colId) {
7,921,104!
938
        if (cid < 0) {
8,001,597✔
939
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,355,878✔
940
        } else {
941
          pIter->cv.cid = pTColumn->colId;
6,645,719✔
942
          pIter->cv.value.type = pTColumn->type;
6,645,719✔
943
          pIter->cv.flag = CV_FLAG_VALUE;
6,645,719✔
944

945
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
6,645,719!
946
            pData += tGetU32v(pData, &pIter->cv.value.nData);
816,086!
947
            if (pIter->cv.value.nData > 0) {
816,086!
948
              pIter->cv.value.pData = pData;
1,751,874✔
949
            } else {
UNCOV
950
              pIter->cv.value.pData = NULL;
×
951
            }
952
          } else {
953
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
5,829,633✔
954
          }
955
        }
956

957
        pIter->iCol++;
8,516,485✔
958
        goto _exit;
8,516,485✔
UNCOV
959
      } else if (TABS(cid) > pTColumn->colId) {
×
960
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
82✔
961
        goto _exit;
82✔
962
      } else {
UNCOV
963
        uError("unexpected column id %d, %d", cid, pTColumn->colId);
×
UNCOV
964
        goto _exit;
×
965
      }
966
    } else {
967
      pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1,709,067✔
968
      goto _exit;
1,709,067✔
969
    }
970
  } else {  // Tuple
UNCOV
971
    uint8_t bv = BIT_FLG_VALUE;
×
UNCOV
972
    if (pIter->pb) {
×
973
      switch (pIter->pRow->flag) {
3,209!
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,175✔
982
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
3,175✔
983
          break;
3,175✔
984
        case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
985
          bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1);
×
UNCOV
986
          break;
×
UNCOV
987
        default:
×
UNCOV
988
          break;
×
989
      }
990

991
      if (bv == BIT_FLG_NONE) {
3,209✔
992
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
13✔
993
        goto _exit;
13✔
994
      } else if (bv == BIT_FLG_NULL) {
3,196✔
995
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
342✔
996
        goto _exit;
342✔
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)) {
×
UNCOV
1004
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
×
UNCOV
1005
      pData += tGetU32v(pData, &pIter->cv.value.nData);
×
1006
      if (pIter->cv.value.nData > 0) {
×
1007
        pIter->cv.value.pData = pData;
2,577✔
1008
      } else {
UNCOV
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,356✔
1013
    }
1014
    goto _exit;
31,932✔
1015
  }
1016

1017
_exit:
11,158,356✔
1018
  pIter->iTColumn++;
11,158,356✔
1019
  return &pIter->cv;
11,158,356✔
1020
}
1021

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

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

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

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

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

1042
  while (pColData) {
248,129✔
1043
    if (pTColumn) {
212,944!
1044
      if (pTColumn->colId == pColData->cid) {  // NULL
212,944✔
1045
        if (flag == 0) {
212,942✔
1046
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
212,769✔
1047
        } else {
1048
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
173✔
1049
        }
1050
        if (code) goto _exit;
212,959!
1051

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

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

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

1078
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
640,636,480✔
1079
  SPrimaryKeyIndex index;
1080
  uint8_t         *data = pRow->data;
640,636,480✔
1081
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
905,881,427✔
1082
    data += tGetPrimaryKeyIndex(data, &index);
265,276,837✔
1083
  }
1084

1085
  switch (pRow->flag) {
640,604,590!
1086
    case HAS_VALUE:
630,404,265✔
1087
      pf = data;  // TODO: fix here
630,404,265✔
1088
      pv = pf + pTSchema->flen;
630,404,265✔
1089
      break;
630,404,265✔
1090
    case (HAS_NULL | HAS_NONE):
1,297✔
1091
      pb = data;
1,297✔
1092
      break;
1,297✔
1093
    case (HAS_VALUE | HAS_NONE):
10,542,934✔
1094
    case (HAS_VALUE | HAS_NULL):
1095
      pb = data;
10,542,934✔
1096
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
10,542,934✔
1097
      pv = pf + pTSchema->flen;
10,542,934✔
1098
      break;
10,542,934✔
1099
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1100
      pb = data;
×
1101
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1102
      pv = pf + pTSchema->flen;
×
UNCOV
1103
      break;
×
UNCOV
1104
    default:
×
UNCOV
1105
      return TSDB_CODE_INVALID_DATA_FMT;
×
1106
  }
1107

1108
  while (pColData) {
2,147,483,647✔
1109
    if (pTColumn) {
2,060,701,761✔
1110
      if (pTColumn->colId == pColData->cid) {
2,060,134,642!
1111
        if (!(pTColumn->type == pColData->type)) {
2,061,232,907!
UNCOV
1112
          return TSDB_CODE_INVALID_PARA;
×
1113
        }
1114
        if (pb) {
2,061,232,907✔
1115
          uint8_t bv;
1116
          switch (pRow->flag) {
32,600,219!
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,582✔
1121
              bv = GET_BIT1(pb, iTColumn - 1);
198,582✔
1122
              if (bv) bv++;
198,582✔
1123
              break;
198,582✔
1124
            case (HAS_VALUE | HAS_NULL):
32,377,112✔
1125
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
32,377,112✔
1126
              break;
32,377,112✔
UNCOV
1127
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
UNCOV
1128
              bv = GET_BIT2(pb, iTColumn - 1);
×
UNCOV
1129
              break;
×
UNCOV
1130
            default:
×
UNCOV
1131
              return TSDB_CODE_INVALID_DATA_FMT;
×
1132
          }
1133

1134
          if (bv == BIT_FLG_NONE) {
32,601,627✔
1135
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,346!
UNCOV
1136
              goto _exit;
×
1137
            goto _continue;
43,346✔
1138
          } else if (bv == BIT_FLG_NULL) {
32,558,281✔
1139
            if (flag == 0) {
10,527,656✔
1140
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
10,525,490✔
1141
            } else {
1142
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
2,166✔
1143
            }
1144
            if (code) goto _exit;
10,527,639!
1145
            goto _continue;
10,527,639✔
1146
          }
1147
        }
1148

1149
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,095,097,782!
1150
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
40,367,628!
1151
          uint32_t nData;
1152
          pData += tGetU32v(pData, &nData);
40,367,628✔
1153
          if (flag == 0) {
40,367,628!
1154
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
43,675,320✔
1155
          } else {
UNCOV
1156
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1157
          }
1158
          if (code) goto _exit;
44,434,469!
1159
        } else {
1160
          if (flag == 0) {
2,010,295,685✔
1161
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,007,696,215✔
1162
                                                                          TYPE_BYTES[pColData->type]);
2,007,696,215✔
1163
          } else {
1164
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,599,470✔
1165
                                                                          TYPE_BYTES[pColData->type], flag > 0);
2,599,470✔
1166
          }
1167
          if (code) goto _exit;
2,009,038,972!
1168
        }
1169

1170
      _continue:
2,009,038,972✔
1171
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
2,064,044,426✔
1172
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
2,064,044,426✔
UNCOV
1173
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
1174
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
UNCOV
1175
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1176
      } else {
UNCOV
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;
567,119!
1181
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
567,117✔
1182
    }
1183
  }
1184

1185
_exit:
643,760,013✔
1186
  return code;
643,760,013✔
1187
}
1188
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
3,782,529✔
1189
  int32_t code = 0;
3,782,529✔
1190

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

1198
  // primary keys
1199
  uint8_t         *data = pRow->data;
3,782,529✔
1200
  SPrimaryKeyIndex index;
1201
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
4,056,073✔
1202
    data += tGetPrimaryKeyIndex(data, &index);
273,547✔
1203
  }
1204

1205
  SKVIdx *pKVIdx = (SKVIdx *)data;
3,782,526✔
1206
  if (pRow->flag & KV_FLG_LIT) {
3,782,526✔
1207
    pv = pKVIdx->idx + pKVIdx->nCol;
3,719,539✔
1208
  } else if (pRow->flag & KV_FLG_MID) {
62,987✔
1209
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
62,846✔
1210
  } else if (pRow->flag & KV_FLG_BIG) {
141!
UNCOV
1211
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1212
  } else {
1213
    return TSDB_CODE_INVALID_PARA;
141✔
1214
  }
1215

1216
  while (pColData) {
43,879,299✔
1217
    if (pTColumn) {
40,113,342✔
1218
      if (pTColumn->colId == pColData->cid) {
39,714,218✔
1219
        while (iCol < pKVIdx->nCol) {
39,670,051✔
1220
          uint8_t *pData;
1221
          if (pRow->flag & KV_FLG_LIT) {
34,448,045✔
1222
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
32,755,759✔
1223
          } else if (pRow->flag & KV_FLG_MID) {
1,692,286!
1224
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,692,344✔
1225
          } else if (pRow->flag & KV_FLG_BIG) {
×
UNCOV
1226
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1227
          } else {
UNCOV
1228
            return TSDB_CODE_INVALID_DATA_FMT;
×
1229
          }
1230

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

1234
          if (TABS(cid) == pTColumn->colId) {
34,448,103✔
1235
            if (cid < 0) {
34,026,522✔
1236
              if (flag == 0) {
6,666,285✔
1237
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
6,662,996✔
1238
              } else {
1239
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
3,289✔
1240
              }
1241
              if (code) goto _exit;
6,215,921!
1242
            } else {
1243
              uint32_t nData;
1244
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
27,360,237!
1245
                pData += tGetU32v(pData, &nData);
6,904,565✔
1246
              } else {
1247
                nData = 0;
20,455,672✔
1248
              }
1249
              if (flag == 0) {
27,360,237!
1250
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
27,554,851✔
1251
              } else {
UNCOV
1252
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1253
              }
1254
              if (code) goto _exit;
27,794,307!
1255
            }
1256
            iCol++;
34,010,228✔
1257
            goto _continue;
34,010,228✔
1258
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
421,581✔
1259
            break;
39,326✔
1260
          } else {
1261
            iCol++;
382,255✔
1262
          }
1263
        }
1264

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

1267
      _continue:
5,261,165✔
1268
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
39,271,393✔
1269
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
39,271,393✔
1270
      } else if (pTColumn->colId > pColData->cid) {
426,422!
UNCOV
1271
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
UNCOV
1272
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1273
      } else {
1274
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
426,422✔
1275
      }
1276
    } else {
1277
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,124!
1278
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,099✔
1279
    }
1280
  }
1281

1282
_exit:
3,765,957✔
1283
  return code;
3,765,957✔
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) {
644,482,508✔
1290
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
644,482,508!
1291
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
644,482,508!
1292

1293
  if (pRow->flag == HAS_NONE) {
644,482,508✔
1294
    return tRowNoneUpsertColData(aColData, nColData, flag);
1,072✔
1295
  } else if (pRow->flag == HAS_NULL) {
644,481,436✔
1296
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
35,168✔
1297
  } else if (pRow->flag >> 4) {  // KV row
644,446,268✔
1298
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
3,783,528✔
1299
  } else {  // TUPLE row
1300
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
640,662,740✔
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!
UNCOV
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,856✔
1326
    }
1327

1328
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
1329
      key->pks[i].pData = tdata;
771✔
1330
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
1,542!
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,833,251✔
1349
  switch (tv1->type) {
217,833,251!
1350
    case TSDB_DATA_TYPE_BOOL:
×
1351
    case TSDB_DATA_TYPE_TINYINT:
UNCOV
1352
      T_COMPARE_SCALAR_VALUE(int8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
UNCOV
1353
    case TSDB_DATA_TYPE_SMALLINT:
×
UNCOV
1354
      T_COMPARE_SCALAR_VALUE(int16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1355
    case TSDB_DATA_TYPE_INT:
35,943✔
1356
      T_COMPARE_SCALAR_VALUE(int32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
35,943✔
1357
    case TSDB_DATA_TYPE_BIGINT:
217,813,851✔
1358
    case TSDB_DATA_TYPE_TIMESTAMP:
1359
      T_COMPARE_SCALAR_VALUE(int64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
217,813,851✔
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:
×
UNCOV
1369
      T_COMPARE_SCALAR_VALUE(uint32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
UNCOV
1370
    case TSDB_DATA_TYPE_UBIGINT:
×
UNCOV
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: {
×
UNCOV
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
    }
UNCOV
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
    }
UNCOV
1386
    default:
×
1387
      break;
×
1388
  }
1389

UNCOV
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) {
213,403,805!
1404
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
303,873,753!
1405
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
217,835,303✔
1406
      if (ret) return ret;
217,830,671!
1407
    }
1408
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
UNCOV
1409
    return -1;
×
1410
  } else {
UNCOV
1411
    return 1;
×
1412
  }
1413

1414
  return 0;
86,038,450✔
1415
}
1416

1417
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
532,688,340✔
1418
  pDst->ts = pSrc->ts;
532,688,340✔
1419
  pDst->numOfPKs = pSrc->numOfPKs;
532,688,340✔
1420

1421
  if (pSrc->numOfPKs > 0) {
532,688,340✔
1422
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
50,637,837✔
1423
      SValue *pVal = &pDst->pks[i];
25,192,616✔
1424
      pVal->type = pSrc->pks[i].type;
25,192,616✔
1425

1426
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
25,192,616✔
1427
    }
1428
  }
1429
}
532,937,984✔
1430

1431
// STag ========================================
1432
static int tTagValCmprFn(const void *p1, const void *p2) {
126,101,910✔
1433
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
126,101,910✔
1434
    return -1;
42,277,634✔
1435
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
83,824,276✔
1436
    return 1;
46,595,512✔
1437
  }
1438

1439
  return 0;
37,228,764✔
1440
}
1441
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
13,674✔
1442
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
13,674✔
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) {
876,386✔
1539
  int32_t n = 0;
876,386✔
1540

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

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

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

1560
  return n;
876,386✔
1561
}
1562
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
124,913,453✔
1563
  int32_t n = 0;
124,913,453✔
1564

1565
  // key
1566
  if (isJson) {
124,913,453✔
1567
    n += tGetCStr(p + n, &pTagVal->pKey);
32,484✔
1568
  } else {
1569
    n += tGetI16v(p + n, &pTagVal->cid);
249,794,422!
1570
  }
1571

1572
  // type
1573
  n += tGetI8(p + n, &pTagVal->type);
124,913,453!
1574

1575
  // value
1576
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
124,913,453!
1577
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
43,449,614!
1578
  } else {
1579
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
103,188,646✔
1580
    n += tDataTypes[pTagVal->type].bytes;
103,188,646✔
1581
  }
1582

1583
  return n;
124,913,453✔
1584
}
1585

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

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

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

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

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

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

1638
  if (isLarge) {
162,751✔
1639
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
16,599✔
1640
  } else {
1641
    p = (uint8_t *)&(*ppTag)->idx[nTag];
146,152✔
1642
  }
1643
  n = 0;
162,751✔
1644
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
601,004✔
1645
    if (isLarge) {
438,260✔
1646
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
117,382✔
1647
    } else {
1648
      (*ppTag)->idx[iTag] = n;
320,878✔
1649
    }
1650
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
438,260✔
1651
  }
1652
#ifdef TD_DEBUG_PRINT_TAG
1653
  debugPrintSTag(*ppTag, __func__, __LINE__);
1654
#endif
1655

1656
  return code;
162,744✔
1657

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

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

1666
char *tTagValToData(const STagVal *value, bool isJson) {
10,405,790✔
1667
  if (!value) {
10,405,790!
UNCOV
1668
    return NULL;
×
1669
  }
1670

1671
  char  *data = NULL;
10,405,790✔
1672
  int8_t typeBytes = 0;
10,405,790✔
1673
  if (isJson) {
10,405,790✔
1674
    typeBytes = CHAR_BYTES;
7,439✔
1675
  }
1676

1677
  if (IS_VAR_DATA_TYPE(value->type)) {
10,405,790!
1678
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
2,857,710!
1679
    if (data == NULL) {
2,858,810!
UNCOV
1680
      return NULL;
×
1681
    }
1682

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

1687
    varDataLen(data + typeBytes) = value->nData;
2,858,810✔
1688
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
2,858,810✔
1689
  } else {
1690
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
7,548,080✔
1691
  }
1692

1693
  return data;
10,406,890✔
1694
}
1695

1696
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
39,092,450✔
1697
  if (!pTag || !pTagVal) {
39,092,450!
UNCOV
1698
    return false;
×
1699
  }
1700

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

1711
  if (isLarge) {
39,244,163✔
1712
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
31,731,731✔
1713
  } else {
1714
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,512,432✔
1715
  }
1716

1717
  pTagVal->type = TSDB_DATA_TYPE_NULL;
39,244,163✔
1718
  pTagVal->pData = NULL;
39,244,163✔
1719
  pTagVal->nData = 0;
39,244,163✔
1720
  while (lidx <= ridx) {
127,587,609✔
1721
    midx = (lidx + ridx) / 2;
125,561,173✔
1722
    if (isLarge) {
125,561,173✔
1723
      offset = ((int16_t *)pTag->idx)[midx];
102,754,395✔
1724
    } else {
1725
      offset = pTag->idx[midx];
22,806,778✔
1726
    }
1727

1728
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
125,561,173✔
1729
    if (isJson) {
125,716,650✔
1730
      c = tTagValJsonCmprFn(pTagVal, &tv);
13,458✔
1731
    } else {
1732
      c = tTagValCmprFn(pTagVal, &tv);
125,703,192✔
1733
    }
1734

1735
    if (c < 0) {
127,017,913✔
1736
      ridx = midx - 1;
41,780,201✔
1737
    } else if (c > 0) {
85,237,712✔
1738
      lidx = midx + 1;
46,563,245✔
1739
    } else {
1740
      (void)memcpy(pTagVal, &tv, sizeof(tv));
38,674,467✔
1741
      return true;
38,674,467✔
1742
    }
1743
  }
1744
  return false;
2,026,436✔
1745
}
1746

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

1751
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
19,206,409✔
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!
UNCOV
1768
    code = terrno;
×
UNCOV
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!
UNCOV
1780
      code = terrno;
×
UNCOV
1781
      goto _err;
×
1782
    }
1783
  }
1784

1785
  return code;
1,862✔
1786

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

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

1799
  pTSchema->numOfCols = numOfCols;
16,635,158✔
1800
  pTSchema->version = version;
16,635,158✔
1801

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

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

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

1827
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
174,955,764!
1828
      pTColumn->bytes = pSchema->bytes;
34,754,026✔
1829
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
34,754,026✔
1830
    } else {
1831
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
140,201,738✔
1832
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
140,201,738✔
1833
    }
1834

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

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

1842
  return pTSchema;
16,635,158✔
1843
}
1844

1845
static int32_t tTColumnCompare(const void *p1, const void *p2) {
5,737,024✔
1846
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
5,737,024✔
1847
    return -1;
854,568✔
1848
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
4,882,456✔
1849
    return 1;
3,434,455✔
1850
  }
1851

1852
  return 0;
1,448,001✔
1853
}
1854

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

1860
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
1,448,145✔
1861
}
1862

1863
// SColData ========================================
1864
void tColDataDestroy(void *ph) {
18,992,534✔
1865
  if (ph) {
18,992,534!
1866
    SColData *pColData = (SColData *)ph;
18,992,746✔
1867

1868
    tFree(pColData->pBitMap);
18,992,746!
1869
    tFree(pColData->aOffset);
18,992,756✔
1870
    tFree(pColData->pData);
18,992,783!
1871
  }
1872
}
18,993,949✔
1873

1874
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
21,075,589✔
1875
  pColData->cid = cid;
21,075,589✔
1876
  pColData->type = type;
21,075,589✔
1877
  pColData->cflag = cflag;
21,075,589✔
1878
  tColDataClear(pColData);
21,075,589✔
1879
}
21,078,162✔
1880

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

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

1895
  tColDataClear(pColData);
125,889✔
1896
}
125,890✔
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);
67,570,152!
1903
    if (code) goto _exit;
79,524,081!
1904
    pColData->aOffset[pColData->nVal] = pColData->nData;
79,524,081✔
1905

1906
    if (nData) {
79,524,081!
1907
      code = tRealloc(&pColData->pData, pColData->nData + nData);
78,419,683!
1908
      if (code) goto _exit;
79,024,213!
1909
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
79,024,213✔
1910
      pColData->nData += nData;
79,024,213✔
1911
    }
1912
  } else {
1913
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
UNCOV
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,652,756✔
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,123,343✔
1931
  pColData->flag = HAS_VALUE;
6,124,930✔
1932
  pColData->numOfValue++;
6,123,343✔
1933
  return tColDataPutValue(pColData, pData, nData);
6,125,486✔
1934
}
1935
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
169,582✔
1936
  pColData->flag = HAS_NONE;
169,582✔
1937
  pColData->numOfNone++;
169,582✔
1938
  pColData->nVal++;
169,582✔
1939
  return 0;
169,582✔
1940
}
1941
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
402,862✔
1942
  pColData->flag = HAS_NULL;
404,341✔
1943
  pColData->numOfNull++;
404,341✔
1944
  pColData->nVal++;
404,341✔
1945
  return 0;
402,862✔
1946
}
1947
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,314✔
1948
  int32_t code = 0;
1,314✔
1949

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

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

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

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

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

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

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

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

1995
  return code;
600✔
1996
}
1997
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
160,233✔
1998
  int32_t code = 0;
160,333✔
1999

2000
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
160,333✔
2001
  code = tRealloc(&pColData->pBitMap, nBit);
160,284!
2002
  if (code) return code;
160,335!
2003

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

2007
  pColData->flag |= HAS_VALUE;
160,335✔
2008
  pColData->numOfValue++;
160,335✔
2009

2010
  if (pColData->nVal) {
160,335!
2011
    if (IS_VAR_DATA_TYPE(pColData->type)) {
160,334!
2012
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
7,390✔
2013
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
7,390!
2014
      if (code) return code;
7,390!
2015
      memset(pColData->aOffset, 0, nOffset);
7,390✔
2016
    } else {
2017
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
152,944✔
2018
      code = tRealloc(&pColData->pData, pColData->nData);
152,944!
2019
      if (code) return code;
152,945!
2020
      memset(pColData->pData, 0, pColData->nData);
152,945✔
2021
    }
2022
  }
2023

2024
  return tColDataPutValue(pColData, pData, nData);
160,334✔
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,600,389✔
2043
  pColData->nVal++;
4,600,389✔
2044
  pColData->numOfNull++;
4,600,389✔
2045
  return 0;
4,600,389✔
2046
}
UNCOV
2047
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2048
  int32_t code = 0;
×
2049

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

2053
  uint8_t *pBitMap = NULL;
×
UNCOV
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++) {
×
UNCOV
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);
×
UNCOV
2063
  pColData->pBitMap = pBitMap;
×
2064

2065
  if (pColData->nVal) {
×
UNCOV
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;
×
UNCOV
2073
      code = tRealloc(&pColData->pData, pColData->nData);
×
2074
      if (code) return code;
×
2075
      memset(pColData->pData, 0, pColData->nData);
×
2076
    }
2077
  }
2078

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

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

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

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

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

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

2103
  return code;
9,384✔
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,076✔
2110
  int32_t code = 0;
6,076✔
2111

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

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

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

2122
  return tColDataPutValue(pColData, NULL, 0);
6,079✔
2123
}
2124
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
686,440✔
2125
  int32_t code = 0;
710,068✔
2126

2127
  pColData->flag |= HAS_NULL;
710,068✔
2128
  pColData->numOfNull++;
710,068✔
2129

2130
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
710,068✔
2131
  code = tRealloc(&pColData->pBitMap, nBit);
709,764✔
2132
  if (code) return code;
710,074!
2133

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

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

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

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

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

2153
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
102,349!
2154
  if (code) return code;
102,426!
2155

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

2159
  return tColDataPutValue(pColData, NULL, 0);
102,493✔
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) {
570,384,016✔
2182
  int32_t code = 0;
573,348,056✔
2183

2184
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
573,347,656!
2185
  if (code) return code;
574,568,881!
2186
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
574,568,881!
2187
  pColData->numOfValue++;
574,568,881!
2188

2189
  return tColDataPutValue(pColData, pData, nData);
576,903,037✔
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,993!
2200

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

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

2209
  return tColDataPutValue(pColData, NULL, 0);
3,995✔
2210
}
2211
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
32,174,925✔
2212
  int32_t code = 0;
35,150,903✔
2213

2214
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
35,147,307!
2215
  if (code) return code;
35,157,972!
2216
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
35,157,972✔
2217
  pColData->numOfNull++;
35,157,972✔
2218

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

2224
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
UNCOV
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
}
UNCOV
2241
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2242
  int32_t code = 0;
×
2243

2244
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
UNCOV
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!
UNCOV
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!
UNCOV
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!
UNCOV
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,629✔
2293
  if (forward) {
1,629!
2294
    pColData->numOfNull--;
1,629✔
2295
    pColData->nVal--;
1,629✔
2296
    if (pColData->numOfNull) {
1,629✔
2297
      return tColDataAppendValue20(pColData, pData, nData);
51✔
2298
    } else {
2299
      pColData->flag = 0;
1,578✔
2300
      return tColDataAppendValue00(pColData, pData, nData);
1,578✔
2301
    }
2302
  }
UNCOV
2303
  return 0;
×
2304
}
UNCOV
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
×
UNCOV
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--;
×
UNCOV
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!
UNCOV
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,587,903✔
2340
  if (forward) {  // VALUE ==> VALUE
35,587,903!
2341
    pColData->nVal--;
35,588,089✔
2342
    if (IS_VAR_DATA_TYPE(pColData->type)) {
35,588,089!
2343
      pColData->nData = pColData->aOffset[pColData->nVal];
577,047✔
2344
    } else {
2345
      pColData->nData -= TYPE_BYTES[pColData->type];
35,011,042✔
2346
    }
2347
    return tColDataPutValue(pColData, pData, nData);
35,611,700✔
2348
  }
UNCOV
2349
  return 0;
×
2350
}
2351
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24,779✔
2352
  if (forward) {  // VALUE ==> NULL
24,779!
2353
    pColData->numOfValue--;
24,779✔
2354
    pColData->nVal--;
24,779✔
2355
    if (pColData->numOfValue) {
24,779✔
2356
      if (IS_VAR_DATA_TYPE(pColData->type)) {
23,324!
2357
        pColData->nData = pColData->aOffset[pColData->nVal];
1,042✔
2358
      } else {
2359
        pColData->nData -= TYPE_BYTES[pColData->type];
22,282✔
2360
      }
2361
      return tColDataAppendValue42(pColData, pData, nData);
23,325✔
2362
    } else {
2363
      pColData->flag = 0;
1,455✔
2364
      pColData->nData = 0;
1,455✔
2365
      return tColDataAppendValue02(pColData, pData, nData);
1,455✔
2366
    }
2367
  }
UNCOV
2368
  return 0;
×
2369
}
2370
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,667✔
2371
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
5,667✔
2372
    pColData->numOfNone--;
5,595✔
2373
    pColData->nVal--;
5,595✔
2374
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,595!
2375
      pColData->nData -= TYPE_BYTES[pColData->type];
4,475✔
2376
    }
2377
    if (pColData->numOfNone) {
5,595✔
2378
      return tColDataAppendValue50(pColData, pData, nData);
1,999✔
2379
    } else {
2380
      pColData->flag = HAS_VALUE;
3,596✔
2381
      return tColDataAppendValue40(pColData, pData, nData);
3,596✔
2382
    }
2383
  } else if (forward) {  // VALUE ==> VALUE
72!
2384
    pColData->nVal--;
77✔
2385
    if (IS_VAR_DATA_TYPE(pColData->type)) {
77!
2386
      pColData->nData = pColData->aOffset[pColData->nVal];
20✔
2387
    } else {
2388
      pColData->nData -= TYPE_BYTES[pColData->type];
57✔
2389
    }
2390
    return tColDataPutValue(pColData, pData, nData);
78✔
2391
  }
UNCOV
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!
UNCOV
2402
      return tColDataAppendValue52(pColData, pData, nData);
×
2403
    } else {
2404
      pColData->flag = HAS_VALUE;
304!
2405
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2406
    }
UNCOV
2407
  } else if (forward) {  // VALUE ==> NULL
×
UNCOV
2408
    pColData->numOfValue--;
×
UNCOV
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
      }
UNCOV
2416
      return tColDataAppendValue52(pColData, pData, nData);
×
2417
    } else {
UNCOV
2418
      pColData->flag = HAS_NONE;
×
2419
      pColData->nData = 0;
×
UNCOV
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,279,762✔
2426
  if (forward) {
59,279,762!
2427
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
59,279,762✔
2428
      pColData->numOfNull--;
3,000,895✔
2429
      pColData->nVal--;
3,000,895✔
2430
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,000,895!
2431
        pColData->nData -= TYPE_BYTES[pColData->type];
2,996,048✔
2432
      }
2433
      if (pColData->numOfNull) {
3,000,895✔
2434
        return tColDataAppendValue60(pColData, pData, nData);
2,963,640✔
2435
      } else {
2436
        pColData->flag = HAS_VALUE;
37,255✔
2437
        return tColDataAppendValue40(pColData, pData, nData);
37,258✔
2438
      }
2439
    } else {  // VALUE ==> VALUE
2440
      pColData->nVal--;
56,278,867✔
2441
      if (IS_VAR_DATA_TYPE(pColData->type)) {
56,278,867!
2442
        pColData->nData = pColData->aOffset[pColData->nVal];
2,657✔
2443
      } else {
2444
        pColData->nData -= TYPE_BYTES[pColData->type];
56,276,210✔
2445
      }
2446
      return tColDataPutValue(pColData, pData, nData);
56,278,867✔
2447
    }
2448
  }
UNCOV
2449
  return 0;
×
2450
}
2451
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,144,107✔
2452
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
3,144,107!
2453
    pColData->numOfValue--;
2,972,431✔
2454
    pColData->nVal--;
2,972,431✔
2455
    if (pColData->numOfValue) {
2,972,431✔
2456
      if (IS_VAR_DATA_TYPE(pColData->type)) {
2,972,382!
2457
        pColData->nData = pColData->aOffset[pColData->nVal];
2,509✔
2458
      } else {
2459
        pColData->nData -= TYPE_BYTES[pColData->type];
2,969,873✔
2460
      }
2461
      return tColDataAppendValue62(pColData, pData, nData);
2,972,382✔
2462
    } else {
2463
      pColData->flag = HAS_NULL;
49✔
2464
      pColData->nData = 0;
49!
2465
      return tColDataAppendValue20(pColData, pData, nData);
50✔
2466
    }
2467
  }
2468
  return 0;
171,676✔
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!
UNCOV
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!
UNCOV
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
    }
UNCOV
2506
  } else if (bv == 2) {  // VALUE ==> VALUE
×
UNCOV
2507
    if (forward) {
×
UNCOV
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
      }
UNCOV
2514
      return tColDataPutValue(pColData, pData, nData);
×
2515
    }
2516
  } else {
2517
    return TSDB_CODE_INVALID_PARA;
×
2518
  }
UNCOV
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,596✔
2525
    pColData->nVal--;
3,596✔
2526
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,596!
2527
      pColData->nData -= TYPE_BYTES[pColData->type];
2,544✔
2528
    }
2529
    if (pColData->numOfNone) {
3,596!
UNCOV
2530
      return tColDataAppendValue72(pColData, pData, nData);
×
2531
    } else {
2532
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
114,233✔
2533
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
110,637✔
2534
      }
2535
      pColData->flag = (HAS_VALUE | HAS_NULL);
3,596✔
2536
      return tColDataAppendValue62(pColData, pData, nData);
3,595✔
2537
    }
UNCOV
2538
  } else if (bv == 2 && forward) {  // VALUE ==> NULL
×
UNCOV
2539
    pColData->numOfValue--;
×
UNCOV
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
      }
UNCOV
2547
      return tColDataAppendValue72(pColData, pData, nData);
×
2548
    } else {
UNCOV
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;
×
UNCOV
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,602✔
2560
  return 0;
13,602✔
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,407,449✔
2575
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
95,407,449!
2576
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
95,407,789!
2577

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

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

2584
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
48,963,530✔
2585
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
48,963,530✔
2586
}
48,963,530✔
2587
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
1,538,187✔
2588
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
1,538,187✔
2589
}
1,538,187✔
2590
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
11,553✔
2591
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2592
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,553!
2593
    case 0:
1,050✔
2594
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,050✔
2595
      break;
1,050✔
2596
    case 1:
10,505✔
2597
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,505✔
2598
      break;
10,505✔
UNCOV
2599
    default:
×
UNCOV
2600
      break;
×
2601
  }
2602
}
11,553✔
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) {
134,608,253!
2607
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
136,728,530✔
2608
    } else {
UNCOV
2609
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2610
    }
2611
    value.pData = pColData->pData + pColData->aOffset[iVal];
134,608,253✔
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,068,212✔
2618
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
225,065✔
2619
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2620
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
225,065!
2621
    case 0:
102,359✔
2622
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
102,359✔
2623
      break;
102,359✔
2624
    case 1:
122,935✔
2625
      tColDataGetValue4(pColData, iVal, pColVal);
2626
      break;
123,120✔
UNCOV
2627
    default:
×
UNCOV
2628
      break;
×
2629
  }
2630
}
225,250✔
2631
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
445,232,761✔
2632
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2633
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
445,232,761!
2634
    case 0:
23,153,367✔
2635
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
23,153,367✔
2636
      break;
23,153,367✔
2637
    case 1:
422,242,489✔
2638
      tColDataGetValue4(pColData, iVal, pColVal);
2639
      break;
422,925,305✔
UNCOV
2640
    default:
×
UNCOV
2641
      break;
×
2642
  }
2643
}
445,915,577✔
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✔
UNCOV
2656
    default:
×
UNCOV
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!
UNCOV
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) {
607,754,497✔
2680
  switch (pColData->flag) {
607,754,497!
UNCOV
2681
    case HAS_NONE:
×
UNCOV
2682
      return 0;
×
UNCOV
2683
    case HAS_NULL:
×
UNCOV
2684
      return 1;
×
2685
    case (HAS_NULL | HAS_NONE):
11,557✔
2686
      return GET_BIT1(pColData->pBitMap, iVal);
11,557✔
2687
    case HAS_VALUE:
×
2688
      return 2;
×
2689
    case (HAS_VALUE | HAS_NONE):
605,390✔
2690
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
605,390✔
2691
    case (HAS_VALUE | HAS_NULL):
607,149,313✔
2692
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
607,149,313✔
2693
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2694
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
UNCOV
2695
    default:
×
UNCOV
2696
      return 0;
×
2697
  }
2698
}
2699

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

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

2705
  // bitmap
2706
  switch (pColData->flag) {
7,921!
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!
UNCOV
2712
        code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
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):
×
UNCOV
2718
      pColData->pBitMap = xMalloc(arg, BIT2_SIZE(pColData->nVal));
×
UNCOV
2719
      if (pColData->pBitMap == NULL) {
×
UNCOV
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,817✔
2726
      pColData->pBitMap = NULL;
7,817✔
2727
      break;
7,817✔
2728
  }
2729

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

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

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

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

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

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

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

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

2780
  tBufferInit(&local);
2781
  if (assist == NULL) {
5,895,414!
UNCOV
2782
    assist = &local;
×
2783
  }
2784

2785
  // bitmap
2786
  if (colData->flag != HAS_VALUE) {
5,895,414✔
2787
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
777,253✔
2788
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
1✔
2789
    } else {
2790
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
777,252✔
2791
    }
2792

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

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

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

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

2813
  // offset
2814
  if (IS_VAR_DATA_TYPE(colData->type)) {
5,894,848!
2815
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
967,403✔
2816

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

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

2829
    info->offsetCompressedSize = cinfo.compressedSize;
967,390✔
2830
  }
2831

2832
  // data
2833
  if (colData->nData > 0) {
5,894,835!
2834
    info->dataOriginalSize = colData->nData;
5,894,937✔
2835

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

2842
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
5,894,937✔
2843
    if (code) {
5,895,305!
2844
      tBufferDestroy(&local);
UNCOV
2845
      return code;
×
2846
    }
2847

2848
    info->dataCompressedSize = cinfo.compressedSize;
5,895,305✔
2849
  }
2850

2851
  tBufferDestroy(&local);
2852
  return 0;
5,895,203✔
2853
}
2854

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

2860
  tBufferInit(&local);
2861
  if (assist == NULL) {
14,899,895!
UNCOV
2862
    assist = &local;
×
2863
  }
2864

2865
  tColDataClear(colData);
14,899,895✔
2866
  colData->cid = info->columnId;
14,899,471✔
2867
  colData->type = info->dataType;
14,899,471✔
2868
  colData->cflag = info->columnFlag;
14,899,471✔
2869
  colData->nVal = info->numOfData;
14,899,471✔
2870
  colData->flag = info->flag;
14,899,471✔
2871

2872
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
14,899,471✔
2873
    goto _exit;
1,700,290✔
2874
  }
2875

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

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

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

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

2900
  if (info->flag == (HAS_NONE | HAS_NULL)) {
13,199,069✔
2901
    goto _exit;
611✔
2902
  }
2903

2904
  // offset
2905
  if (info->offsetOriginalSize > 0) {
13,198,458✔
2906
    SCompressInfo cinfo = {
2,118,601✔
2907
        .cmprAlg = info->cmprAlg,
2,118,601✔
2908
        .dataType = TSDB_DATA_TYPE_INT,
2909
        .originalSize = info->offsetOriginalSize,
2,118,601✔
2910
        .compressedSize = info->offsetCompressedSize,
2,118,601✔
2911
    };
2912

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

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

2925
    data += cinfo.compressedSize;
2,118,682✔
2926
  }
2927

2928
  // data
2929
  if (info->dataOriginalSize > 0) {
13,198,539✔
2930
    colData->nData = info->dataOriginalSize;
13,196,657✔
2931

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

2939
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
13,196,657!
2940
    if (code) {
13,198,016!
2941
      tBufferDestroy(&local);
UNCOV
2942
      return code;
×
2943
    }
2944

2945
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
13,198,016✔
2946
    if (code) {
13,195,093!
2947
      tBufferDestroy(&local);
UNCOV
2948
      return code;
×
2949
    }
2950

2951
    data += cinfo.compressedSize;
13,195,093✔
2952
  }
2953

2954
_exit:
1,882✔
2955
  switch (colData->flag) {
14,897,876✔
2956
    case HAS_NONE:
1,448,209✔
2957
      colData->numOfNone = colData->nVal;
1,448,209✔
2958
      break;
1,448,209✔
2959
    case HAS_NULL:
253,723✔
2960
      colData->numOfNull = colData->nVal;
253,723✔
2961
      break;
253,723✔
2962
    case HAS_VALUE:
12,691,651✔
2963
      colData->numOfValue = colData->nVal;
12,691,651✔
2964
      break;
12,691,651✔
2965
    default:
504,293✔
2966
      for (int32_t i = 0; i < colData->nVal; i++) {
340,769,598✔
2967
        uint8_t bitValue = tColDataGetBitValue(colData, i);
340,268,981✔
2968
        if (bitValue == 0) {
340,265,305✔
2969
          colData->numOfNone++;
195,073✔
2970
        } else if (bitValue == 1) {
340,070,232✔
2971
          colData->numOfNull++;
17,717,473✔
2972
        } else {
2973
          colData->numOfValue++;
322,352,759✔
2974
        }
2975
      }
2976
  }
2977
  tBufferDestroy(&local);
2978
  return 0;
14,894,200✔
2979
}
2980

2981
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
574✔
2982
                                    char *data) {
2983
  int32_t code = 0;
574✔
2984
  if (data == NULL) {
574✔
2985
    if (pColData->cflag & COL_IS_KEY) {
13!
UNCOV
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
561!
2996
    for (int32_t i = 0; i < nRows; ++i) {
281✔
2997
      int32_t offset = *((int32_t *)lengthOrbitmap + i);
181✔
2998
      if (offset == -1) {
181!
UNCOV
2999
        if (pColData->cflag & COL_IS_KEY) {
×
UNCOV
3000
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
UNCOV
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);
UNCOV
3010
          code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
UNCOV
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;
461✔
3019
    bool allNull = true;
461✔
3020
    for (int32_t i = 0; i < nRows; ++i) {
1,296✔
3021
      if (!colDataIsNull_f(lengthOrbitmap, i)) {
835✔
3022
        allNull = false;
622✔
3023
      } else {
3024
        allValue = false;
213✔
3025
      }
3026
    }
3027
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
461!
UNCOV
3028
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
UNCOV
3029
      goto _exit;
×
3030
    }
3031

3032
    if (allValue) {
461✔
3033
      // optimize (todo)
3034
      for (int32_t i = 0; i < nRows; ++i) {
975✔
3035
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
608✔
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;
574✔
3057
}
3058

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

3063
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
8,588,872✔
3064
    if (!(pColData->type == pBind->buffer_type)) {
8,005,547!
UNCOV
3065
      return TSDB_CODE_INVALID_PARA;
×
3066
    }
3067
  }
3068

3069
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
8,588,872!
3070
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
686,567✔
3071
      code = igeos();
201✔
3072
      if (code) {
201!
UNCOV
3073
        return code;
×
3074
      }
3075
    }
3076
    for (int32_t i = 0; i < pBind->num; ++i) {
2,658,679✔
3077
      if (pBind->is_null && pBind->is_null[i]) {
1,853,618✔
3078
        if (pColData->cflag & COL_IS_KEY) {
103,978!
UNCOV
3079
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
UNCOV
3080
          goto _exit;
×
3081
        }
3082
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
103,978✔
3083
        if (code) goto _exit;
104,401!
3084
      } else if (pBind->length[i] > buffMaxLen) {
1,749,640!
UNCOV
3085
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3086
      } else {
3087
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
1,749,640✔
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,749,640✔
3092
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
1,749,640✔
3093
      }
3094
    }
3095
  } else {  // fixed-length data type
3096
    bool allValue;
3097
    bool allNull;
3098
    if (pBind->is_null) {
7,902,305✔
3099
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
550,116✔
3100
      allNull = (same && pBind->is_null[0] != 0);
550,116!
3101
      allValue = (same && pBind->is_null[0] == 0);
550,116!
3102
    } else {
3103
      allNull = false;
7,352,189✔
3104
      allValue = true;
7,352,189✔
3105
    }
3106

3107
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
7,902,305!
UNCOV
3108
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
UNCOV
3109
      goto _exit;
×
3110
    }
3111

3112
    if (allValue) {
7,902,305✔
3113
      // optimize (todo)
3114
      for (int32_t i = 0; i < pBind->num; ++i) {
235,952,481✔
3115
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
227,044,058✔
3116
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
227,044,058✔
3117
      }
3118
    } else if (allNull) {
226,873!
3119
      // optimize (todo)
3120
      for (int32_t i = 0; i < pBind->num; ++i) {
989,107✔
3121
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
491,359✔
3122
        if (code) goto _exit;
497,259!
3123
      }
3124
    } else {
UNCOV
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,316✔
3128
          if (code) goto _exit;
4,316!
3129
        } else {
3130
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
45,696✔
3131
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
45,696✔
3132
        }
3133
      }
3134
    }
3135
  }
3136

UNCOV
3137
_exit:
×
3138
  return code;
9,946,257✔
3139
}
3140

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

3145
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
×
UNCOV
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
×
UNCOV
3152
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
UNCOV
3153
      code = igeos();
×
UNCOV
3154
      if (code) {
×
3155
        return code;
×
3156
      }
3157
    }
3158

3159
    uint8_t *buf = pBind->buffer;
×
UNCOV
3160
    for (int32_t i = 0; i < pBind->num; ++i) {
×
UNCOV
3161
      if (pBind->is_null && pBind->is_null[i]) {
×
UNCOV
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
        }
UNCOV
3173
      } else if (pBind->length[i] > buffMaxLen) {
×
3174
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3175
      } else {
UNCOV
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;
UNCOV
3188
    if (pBind->is_null) {
×
UNCOV
3189
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
×
UNCOV
3190
      allNull = (same && pBind->is_null[0] == 1);
×
UNCOV
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;
×
UNCOV
3201
      goto _exit;
×
3202
    }
3203

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

3212
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3213
      }
UNCOV
3214
    } else if (allNull) {
×
3215
      // optimize (todo)
3216
      for (int32_t i = 0; i < pBind->num; ++i) {
×
UNCOV
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) {
×
UNCOV
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]) {
×
UNCOV
3229
          if (pBind->is_null[i] == 1) {
×
UNCOV
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) {
×
UNCOV
3239
            *val = 1;
×
3240
          }
3241

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

UNCOV
3248
_exit:
×
UNCOV
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,
550✔
3262
                           SArray *rowArray, bool *pOrdered, bool *pDupTs) {
3263
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
550!
UNCOV
3264
    return TSDB_CODE_INVALID_PARA;
×
3265
  }
3266

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

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

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

3291
  SRowKey rowKey, lastRowKey;
3292
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
197,385!
3293
    taosArrayClear(colValArray);
206,912✔
3294

3295
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
895,802✔
3296
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
685,567!
UNCOV
3297
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
UNCOV
3298
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
3299
        } else {
UNCOV
3300
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3301
        }
3302
      } else {
3303
        SValue value = {
685,567✔
3304
            .type = infos[iInfo].type,
685,567✔
3305
        };
3306
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
685,567!
3307
          int32_t   length = infos[iInfo].bind->length[iRow];
6,524✔
3308
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
6,524✔
3309
          value.nData = length;
6,524✔
3310
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
6,524!
UNCOV
3311
            code = TSDB_CODE_INVALID_PARA;
×
UNCOV
3312
            goto _exit;
×
3313
          }
3314
          value.pData = *data;
6,524✔
3315
          *data += length;
6,524✔
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;
679,043✔
3319
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
679,043!
UNCOV
3320
            *val = 1;
×
3321
          }
3322
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
679,043✔
3323
        }
3324
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
711,412✔
3325
      }
3326
      if (taosArrayPush(colValArray, &colVal) == NULL) {
691,112!
UNCOV
3327
        code = terrno;
×
UNCOV
3328
        goto _exit;
×
3329
      }
3330
    }
3331

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

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

3342
    if (pOrdered && pDupTs) {
196,596!
3343
      tRowGetKey(row, &rowKey);
393,340!
3344
      if (iRow == 0) {
196,906✔
3345
        *pOrdered = true;
551✔
3346
        *pDupTs = false;
551✔
3347
      } else {
3348
        // no more compare if we already get disordered or duplicate rows
3349
        if (*pOrdered && !*pDupTs) {
196,355!
3350
          int32_t code = tRowKeyCompare(&rowKey, &lastRowKey);
196,602✔
3351
          *pOrdered = (code >= 0);
196,602✔
3352
          *pDupTs = (code == 0);
196,602✔
3353
        }
3354
      }
3355
      lastRowKey = rowKey;
196,906✔
3356
    }
3357
  }
3358

UNCOV
3359
_exit:
×
UNCOV
3360
  taosArrayDestroy(colValArray);
×
3361
  taosArrayDestroy(bufArray);
553✔
3362
  return code;
556✔
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✔
UNCOV
3397
    case (HAS_NULL | HAS_NONE): {
×
UNCOV
3398
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
UNCOV
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✔
UNCOV
3408
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
UNCOV
3409
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
UNCOV
3410
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
UNCOV
3411
    } break;
×
UNCOV
3412
    default:
×
UNCOV
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!
UNCOV
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!
UNCOV
3440
      return code;
×
3441
    }
3442
    code = tColDataAppendValue(&aToColData[i], &cv);
354✔
3443
    if (code != TSDB_CODE_SUCCESS) {
354!
UNCOV
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) {
202,469,213✔
3452
  SColVal cv;
3453

3454
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
202,469,213✔
3455
  key->numOfPKs = 0;
202,469,213✔
3456

3457
  for (int i = 1; i < nColData; i++) {
202,488,999!
3458
    if (aColData[i].cflag & COL_IS_KEY) {
203,110,553✔
3459
      tColDataGetValue4(&aColData[i], iRow, &cv);
19,579!
3460
      key->pks[key->numOfPKs++] = cv.value;
19,786✔
3461
    } else {
3462
      break;
203,090,974✔
3463
    }
3464
  }
3465
}
202,469,420✔
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!
UNCOV
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!
UNCOV
3528
    return ret;
×
3529
  }
3530

3531
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
23✔
3532
  if (ret != TSDB_CODE_SUCCESS) {
23!
UNCOV
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!
UNCOV
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!
UNCOV
3562
      code = terrno;
×
UNCOV
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!
UNCOV
3582
          goto _exit;
×
3583
        }
3584
        code = tColDataAppendValue(dstCol, &cv);
9✔
3585
        if (code) {
9!
UNCOV
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!
UNCOV
3598
          goto _exit;
×
3599
        }
3600
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3601
        if (code) {
9!
UNCOV
3602
          goto _exit;
×
3603
        }
3604
      }
3605
    }
3606
  }
3607

3608
_exit:
3✔
3609
  if (code) {
3!
UNCOV
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!
UNCOV
3624
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3625
  }
3626
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
30,591!
UNCOV
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) {
97,589,034!
3641
    SRowKey key;
3642
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
97,959,432✔
3643

3644
    int32_t c = tRowKeyCompare(&lastKey, &key);
97,558,608✔
3645
    if (c < 0) {
97,558,608✔
3646
      lastKey = key;
97,235,662✔
3647
      continue;
97,235,662✔
3648
    } else if (c > 0) {
322,946✔
3649
      doSort = 1;
6✔
3650
      break;
6✔
3651
    } else {
3652
      doMerge = 1;
322,940✔
3653
    }
3654
  }
3655

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

3661
  if (doMerge != 1) {
811,698✔
3662
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
30,434✔
3663
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
98,046,521!
3664
      SRowKey key;
3665
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
98,797,348✔
3666

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

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

3682
_exit:
30,437✔
3683
  return 0;
30,595✔
3684
}
3685

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

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

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

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

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

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

3727
  return code;
188,035✔
3728
}
3729

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

3733
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
27,100!
3734
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
27,100!
3735
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
27,099!
3736
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
27,097!
3737

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

3742
  // bitmap
3743
  switch (pColData->flag) {
13,547!
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✔
UNCOV
3750
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
UNCOV
3751
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
UNCOV
3752
      if (code) return code;
×
UNCOV
3753
      break;
×
3754
    default:
13,315✔
3755
      break;
13,315✔
3756
  }
3757

3758
  // value
3759
  if (pColData->flag & HAS_VALUE) {
13,547✔
3760
    if (IS_VAR_DATA_TYPE(pColData->type)) {
13,327!
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;
519!
3766

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

3777
  return code;
13,550✔
3778
}
3779

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

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

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

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

3804
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
13,549✔
3805
  if (version == 0) {
13,549!
3806
    return tDecodeColDataVersion0(pDecoder, pColData);
×
3807
  } else if (version == 1) {
13,549!
3808
    return tDecodeColDataVersion1(pDecoder, pColData);
13,549✔
3809
  } else {
UNCOV
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) {
772,141,259✔
3817
  if (ppRow == NULL) {
772,141,259!
UNCOV
3818
    return TSDB_CODE_INVALID_PARA;
×
3819
  }
3820

3821
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
772,141,259!
UNCOV
3822
    return TSDB_CODE_OUT_OF_RANGE;
×
3823
  }
3824

3825
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
772,141,259✔
3826
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
1,544,282,518!
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,505✔
3837
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
5,505✔
3838
  int16_t*numOfNull = &pAggs->numOfNull;
5,505✔
3839
  *sum = 0;
5,505✔
3840
  *max = 0;
5,505✔
3841
  *min = 1;
5,505✔
3842
  *numOfNull = 0;
5,505✔
3843

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

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

3876
  int8_t val;
3877
  if (HAS_VALUE == pColData->flag) {
5,655!
3878
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,106,374✔
3879
      val = ((int8_t *)pColData->pData)[iVal];
4,100,719✔
3880
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,100,719✔
3881
    }
3882
  } else {
UNCOV
3883
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
3884
      switch (tColDataGetBitValue(pColData, iVal)) {
×
UNCOV
3885
        case 0:
×
3886
        case 1:
3887
          (*numOfNull)++;
×
3888
          break;
×
3889
        case 2:
×
UNCOV
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,655✔
3899

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

3908
  int16_t val;
3909
  if (HAS_VALUE == pColData->flag) {
5,541!
3910
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,956,514✔
3911
      val = ((int16_t *)pColData->pData)[iVal];
3,950,973✔
3912
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
3,950,973✔
3913
    }
3914
  } else {
UNCOV
3915
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
3916
      switch (tColDataGetBitValue(pColData, iVal)) {
×
UNCOV
3917
        case 0:
×
3918
        case 1:
3919
          (*numOfNull)++;
×
3920
          break;
×
UNCOV
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,541✔
3931

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

3940
  int32_t val;
3941
  if (HAS_VALUE == pColData->flag) {
276,448✔
3942
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
668,037,199✔
3943
      val = ((int32_t *)pColData->pData)[iVal];
667,842,430✔
3944
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
667,842,430✔
3945
    }
3946
  } else {
3947
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
255,436,987✔
3948
      switch (tColDataGetBitValue(pColData, iVal)) {
255,356,357!
3949
        case 0:
12,800,518✔
3950
        case 1:
3951
          (*numOfNull)++;
12,800,518✔
3952
          break;
12,800,518✔
3953
        case 2:
242,584,054✔
3954
          val = ((int32_t *)pColData->pData)[iVal];
242,584,054✔
3955
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
242,584,054✔
3956
          break;
242,584,054✔
UNCOV
3957
        default:
×
UNCOV
3958
          break;
×
3959
      }
3960
    }
3961
  }
3962
}
275,399✔
3963

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

3972
  int64_t val;
3973
  if (HAS_VALUE == pColData->flag) {
107,725✔
3974
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
325,828,761✔
3975
      val = ((int64_t *)pColData->pData)[iVal];
325,721,498✔
3976
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
325,721,498✔
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✔
UNCOV
3989
        default:
×
3990
          break;
×
3991
      }
3992
    }
3993
  }
3994
}
107,725✔
3995

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

4004
  float val;
4005
  if (HAS_VALUE == pColData->flag) {
154,739✔
4006
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
614,028,485✔
4007
      val = ((float *)pColData->pData)[iVal];
613,873,747✔
4008
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
613,873,747✔
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
}
154,739✔
4027

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

4036
  double val;
4037
  if (HAS_VALUE == pColData->flag) {
9,722!
4038
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
20,755,924✔
4039
      val = ((double *)pColData->pData)[iVal];
20,746,202✔
4040
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
20,746,202✔
4041
    }
4042
  } else {
4043
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4044
      switch (tColDataGetBitValue(pColData, iVal)) {
×
UNCOV
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:
×
UNCOV
4054
          break;
×
4055
      }
4056
    }
4057
  }
4058
}
9,722✔
4059

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

4068
  uint8_t val;
4069
  if (HAS_VALUE == pColData->flag) {
2,626!
4070
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,074,992✔
4071
      val = ((uint8_t *)pColData->pData)[iVal];
3,072,366✔
4072
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,072,366✔
4073
    }
4074
  } else {
4075
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
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;
×
UNCOV
4085
        default:
×
UNCOV
4086
          break;
×
4087
      }
4088
    }
4089
  }
4090
}
2,626✔
4091

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

4100
  uint16_t val;
4101
  if (HAS_VALUE == pColData->flag) {
2,626!
4102
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,075,066✔
4103
      val = ((uint16_t *)pColData->pData)[iVal];
3,072,440✔
4104
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,072,440✔
4105
    }
4106
  } else {
UNCOV
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);
×
UNCOV
4116
          break;
×
UNCOV
4117
        default:
×
UNCOV
4118
          break;
×
4119
      }
4120
    }
4121
  }
4122
}
2,626✔
4123

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

4132
  uint32_t val;
4133
  if (HAS_VALUE == pColData->flag) {
2,626!
4134
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,074,808✔
4135
      val = ((uint32_t *)pColData->pData)[iVal];
3,072,182✔
4136
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,072,182✔
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];
×
UNCOV
4147
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
UNCOV
4148
          break;
×
UNCOV
4149
        default:
×
UNCOV
4150
          break;
×
4151
      }
4152
    }
4153
  }
4154
}
2,626✔
4155

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

4164
  uint64_t val;
4165
  if (HAS_VALUE == pColData->flag) {
2,626!
4166
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,074,365✔
4167
      val = ((uint64_t *)pColData->pData)[iVal];
3,071,739✔
4168
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,071,739✔
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:
×
UNCOV
4178
          val = ((uint64_t *)pColData->pData)[iVal];
×
UNCOV
4179
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
UNCOV
4180
          break;
×
UNCOV
4181
        default:
×
UNCOV
4182
          break;
×
4183
      }
4184
    }
4185
  }
4186
}
2,626✔
4187

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

4196
  switch (pColData->flag) {
16,137!
UNCOV
4197
    case HAS_NONE:
×
4198
    case HAS_NULL:
4199
    case (HAS_NONE | HAS_NULL):
UNCOV
4200
      *numOfNull = pColData->nVal;
×
4201
      break;
×
4202
    case HAS_VALUE:
16,137✔
4203
      *numOfNull = 0;
16,137✔
4204
      break;
16,137✔
UNCOV
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
      }
UNCOV
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) {
×
UNCOV
4216
          (*numOfNull)++;
×
4217
        }
4218
      }
UNCOV
4219
      break;
×
UNCOV
4220
    default:
×
UNCOV
4221
      break;
×
4222
  }
4223
}
16,137✔
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) {
505✔
4252
      pVal = ((Decimal64*)pColData->pData) + iVal;
500✔
4253
      CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
500!
4254
    }
4255
  } else {
4256
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
102,735✔
4257
      switch (tColDataGetBitValue(pColData, iVal)) {
102,600!
4258
        case 0:
1,644✔
4259
        case 1:
4260
          pAggs->numOfNull++;
1,644✔
4261
          break;
1,644✔
4262
        case 2:
100,956✔
4263
          pVal = ((Decimal64 *)pColData->pData) + iVal;
100,956✔
4264
          CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
100,956!
4265
          break;
100,956✔
UNCOV
4266
        default:
×
UNCOV
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,010✔
4287
      pVal = ((Decimal128*)pColData->pData) + iVal;
1,000✔
4288
      CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
1,000✔
4289
    }
4290
  } else {
4291
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
318,446✔
4292
      switch (tColDataGetBitValue(pColData, iVal)) {
318,100!
4293
        case 0:
5,151✔
4294
        case 1:
4295
          pAggs->numOfNull++;
5,151✔
4296
          break;
5,151✔
4297
        case 2:
312,949✔
4298
          pVal = ((Decimal128*)pColData->pData) + iVal;
312,949✔
4299
          CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
312,949✔
4300
          break;
312,949✔
UNCOV
4301
        default:
×
UNCOV
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) {
15,535,926✔
4335
  valCol->type = TSDB_DATA_TYPE_NULL;
15,535,926✔
4336
  valCol->numOfValues = 0;
15,535,926✔
4337
  tBufferInit(&valCol->data);
15,535,926✔
4338
  tBufferInit(&valCol->offsets);
15,535,926✔
4339
  return 0;
15,535,926✔
4340
}
4341

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

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

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

4361
  if (valCol->numOfValues == 0) {
961,135✔
4362
    valCol->type = value->type;
4,508✔
4363
  }
4364

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

4369
  if (IS_VAR_DATA_TYPE(value->type)) {
961,135!
4370
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
26!
UNCOV
4371
      return code;
×
4372
    }
4373
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
26!
UNCOV
4374
      return code;
×
4375
    }
4376
  } else {
4377
    code = tBufferPut(&valCol->data, VALUE_GET_DATUM(value, value->type), tDataTypes[value->type].bytes);
961,122!
4378
    if (code) return code;
961,123!
4379
  }
4380
  valCol->numOfValues++;
961,136✔
4381

4382
  return 0;
961,136✔
4383
}
4384

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

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

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

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

UNCOV
4404
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
×
UNCOV
4405
        offsets[i] += bytesAdded;
×
4406
      }
4407
    }
UNCOV
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,262,142!
4411
                        tDataTypes[valCol->type].bytes);
276,262,142✔
4412
  }
4413
  return 0;
4414
}
4415

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

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

4426
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
28,924!
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,932,654✔
4436
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
1,153,865,308!
4437
  }
4438
  return 0;
576,932,705✔
4439
}
4440

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

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

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

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

4461
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
6✔
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,507✔
4470
      .cmprAlg = info->cmprAlg,
4,507✔
4471
      .dataType = valCol->type,
4,507✔
4472
      .originalSize = valCol->data.size,
4,507✔
4473
  };
4474

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

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

4481
  return 0;
4,508✔
4482
}
4483

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

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

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

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

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

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

4522
  return 0;
162,444✔
4523
}
4524

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

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

4539
  return 0;
4,508✔
4540
}
4541

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

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

4563
  return 0;
162,444✔
4564
}
4565

4566
int32_t tCompressData(void          *input,       // input
12,352,381✔
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,352,381!
4576
  if (!(outputSize >= extraSizeNeeded)) {
12,352,381!
UNCOV
4577
    return TSDB_CODE_INVALID_PARA;
×
4578
  }
4579

4580
  if (info->cmprAlg == NO_COMPRESSION) {
12,352,381!
UNCOV
4581
    (void)memcpy(output, input, info->originalSize);
×
UNCOV
4582
    info->compressedSize = info->originalSize;
×
4583
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
14,474,726!
4584
    SBuffer local;
4585

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

4591
    if (info->cmprAlg == TWO_STAGE_COMP) {
2,119,664!
4592
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
2,122,237✔
4593
      if (code) {
2,122,237!
4594
        tBufferDestroy(&local);
UNCOV
4595
        return code;
×
4596
      }
4597
    }
4598

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

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

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

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

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

4649
  return 0;
12,355,674✔
4650
}
4651

4652
int32_t tDecompressData(void                *input,       // input
55,365,610✔
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)) {
55,365,610!
UNCOV
4661
    return TSDB_CODE_INVALID_PARA;
×
4662
  }
4663

4664
  if (info->cmprAlg == NO_COMPRESSION) {
55,365,610!
UNCOV
4665
    if (!(info->compressedSize == info->originalSize)) {
×
UNCOV
4666
      return TSDB_CODE_INVALID_PARA;
×
4667
    }
UNCOV
4668
    (void)memcpy(output, input, info->compressedSize);
×
4669
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
78,724,541!
4670
    SBuffer local;
4671

4672
    tBufferInit(&local);
4673
    if (buffer == NULL) {
23,342,573!
UNCOV
4674
      buffer = &local;
×
4675
    }
4676

4677
    if (info->cmprAlg == TWO_STAGE_COMP) {
23,342,573!
4678
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
23,361,318✔
4679
      if (code) {
23,361,676!
4680
        tBufferDestroy(&local);
UNCOV
4681
        return code;
×
4682
      }
4683
    }
4684

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

4700
    if (!(decompressedSize == info->originalSize)) {
23,358,931!
UNCOV
4701
      return TSDB_CODE_COMPRESS_ERROR;
×
4702
    }
4703
    tBufferDestroy(&local);
4704
  } else {
4705
    DEFINE_VAR(info->cmprAlg);
32,023,037✔
4706
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
32,023,037!
UNCOV
4707
      (void)memcpy(output, input, info->compressedSize);
×
UNCOV
4708
      return 0;
×
4709
    }
4710
    SBuffer local;
4711

4712
    tBufferInit(&local);
4713
    if (buffer == NULL) {
32,023,037!
UNCOV
4714
      buffer = &local;
×
4715
    }
4716
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
32,023,037✔
4717
    if (code) {
32,023,622!
UNCOV
4718
      return code;
×
4719
    }
4720

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

4736
    if (!(decompressedSize == info->originalSize)) {
32,019,555!
UNCOV
4737
      return TSDB_CODE_COMPRESS_ERROR;
×
4738
    }
4739
    tBufferDestroy(&local);
4740
  }
4741

4742
  return 0;
55,378,486✔
4743
}
4744

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

4748
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
12,352,779✔
4749
  if (code) return code;
12,352,794!
4750

4751
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
12,352,794✔
4752
  if (code) return code;
12,353,502!
4753

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

4758
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
23,356,557✔
4759
  int32_t code;
4760

4761
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
23,356,557✔
4762
  if (code) return code;
23,355,624!
4763

4764
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
23,355,624✔
4765
  if (code) return code;
23,359,524!
4766

4767
  output->size += info->originalSize;
23,359,524✔
4768
  return 0;
23,359,524✔
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!
UNCOV
4774
    pVal->pData = pDatum;
×
UNCOV
4775
    pVal->nData = len;
×
4776
  } else {
4777
    switch (len) {
2,147,483,647!
4778
      case sizeof(uint8_t):
1,059,936,832✔
4779
        pVal->val = *(uint8_t *)pDatum;
1,059,936,832✔
4780
        break;
1,059,936,832✔
4781
      case sizeof(uint16_t):
565,121,174✔
4782
        pVal->val = *(uint16_t *)pDatum;
565,121,174✔
4783
        break;
565,121,174✔
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✔
UNCOV
4790
      default:
×
UNCOV
4791
        break;
×
4792
    }
4793
  }
4794
}
2,147,483,647✔
4795

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