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

taosdata / TDengine / #3543

29 Nov 2024 02:58AM UTC coverage: 60.842% (+0.02%) from 60.819%
#3543

push

travis-ci

web-flow
Merge pull request #28973 from taosdata/merge/mainto3.0

merge: from main to 3.0

120460 of 253224 branches covered (47.57%)

Branch coverage included in aggregate %.

706 of 908 new or added lines in 18 files covered. (77.75%)

2401 existing lines in 137 files now uncovered.

201633 of 276172 relevant lines covered (73.01%)

19045673.23 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

161
  *sinfo = (SRowBuildScanInfo){
1,178,098,588✔
162
      .tupleFixedSize = schema->flen,
1,178,098,588✔
163
  };
164

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

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

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

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

198
  if (sinfo->numOfNone) {
1,178,098,510✔
199
    sinfo->flag |= HAS_NONE;
401,149,076✔
200
  }
201
  if (sinfo->numOfNull) {
1,178,098,510✔
202
    sinfo->flag |= HAS_NULL;
22,782,711✔
203
  }
204
  if (sinfo->numOfValue) {
1,178,098,510✔
205
    sinfo->flag |= HAS_VALUE;
1,122,282,174✔
206
  }
207

208
  // Tuple
209
  sinfo->tupleFlag = sinfo->flag;
1,178,098,510✔
210
  switch (sinfo->flag) {
1,178,098,510!
211
    case HAS_NONE:
62,538,493✔
212
    case HAS_NULL:
213
      sinfo->tupleBitmapSize = 0;
62,538,493✔
214
      sinfo->tupleFixedSize = 0;
62,538,493✔
215
      break;
62,538,493✔
216
    case HAS_VALUE:
764,228,397✔
217
      sinfo->tupleBitmapSize = 0;
764,228,397✔
218
      sinfo->tupleFixedSize = schema->flen;
764,228,397✔
219
      break;
764,228,397✔
220
    case (HAS_NONE | HAS_NULL):
24,303✔
221
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,303✔
222
      sinfo->tupleFixedSize = 0;
24,303✔
223
      break;
24,303✔
224
    case (HAS_NONE | HAS_VALUE):
356,581,161✔
225
    case (HAS_NULL | HAS_VALUE):
226
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
356,581,161✔
227
      sinfo->tupleFixedSize = schema->flen;
356,581,161✔
228
      break;
356,581,161✔
229
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
2,463,356✔
230
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
2,463,356✔
231
      sinfo->tupleFixedSize = schema->flen;
2,463,356✔
232
      break;
2,463,356✔
233
  }
234
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,381,412,270✔
235
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
203,622,379✔
236
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
203,622,379✔
237
  }
238
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,177,789,891✔
239
                        + sinfo->tuplePKSize      // primary keys
1,177,789,891✔
240
                        + sinfo->tupleBitmapSize  // bitmap
1,177,789,891✔
241
                        + sinfo->tupleFixedSize   // fixed part
1,177,789,891✔
242
                        + sinfo->tupleVarSize;    // var part
1,177,789,891✔
243

244
  // Key-Value
245
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,177,789,891!
246
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,180,464,107✔
247
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,180,464,107✔
248
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
249
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
4,108,600✔
250
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
4,108,600✔
251
  } else {
252
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
253
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
254
  }
255
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,381,100,207✔
256
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
203,843,570✔
257
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
203,843,570✔
258
  }
259
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,177,256,637✔
260
                     + sinfo->kvPKSize        // primary keys
1,177,256,637✔
261
                     + sinfo->kvIndexSize     // index array
1,177,256,637✔
262
                     + sinfo->kvPayloadSize;  // payload
1,177,256,637✔
263

264
_exit:
1,177,256,715✔
265
  return code;
1,177,256,715✔
266
}
267

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

272
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
838,420,818✔
273
  if (*ppRow == NULL) {
846,256,669!
UNCOV
274
    return terrno;
×
275
  }
276
  (*ppRow)->flag = sinfo->tupleFlag;
847,313,043✔
277
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
847,313,043✔
278
  (*ppRow)->sver = schema->version;
847,313,043✔
279
  (*ppRow)->len = sinfo->tupleRowSize;
847,313,043✔
280
  (*ppRow)->ts = colValArray[0].value.val;
847,313,043✔
281

282
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
847,313,043!
283
    return 0;
64,424,988✔
284
  }
285

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

291
  // primary keys
292
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
988,168,683✔
293
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
207,777,755✔
294
  }
295

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

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

310
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
311
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
148,414,353✔
312
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
148,414,353✔
313
            if (colValArray[colValIndex].value.nData) {
148,414,353!
314
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
148,939,487✔
315
              varlen += colValArray[colValIndex].value.nData;
148,939,487✔
316
            }
317
          } else {
318
            (void)memcpy(fixed + schema->columns[i].offset, &colValArray[colValIndex].value.val,
2,147,483,647✔
319
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
320
          }
321
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
18,311,647!
322
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
18,409,437!
323
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
468,501!
325
        }
326

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

338
  return 0;
780,390,928✔
339
}
340

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

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

355
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
345,282,105✔
356
  if (*ppRow == NULL) {
345,504,518✔
357
    return terrno;
65,812✔
358
  }
359
  (*ppRow)->flag = sinfo->kvFlag;
345,438,706✔
360
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
345,438,706✔
361
  (*ppRow)->sver = schema->version;
345,438,706✔
362
  (*ppRow)->len = sinfo->kvRowSize;
345,438,706✔
363
  (*ppRow)->ts = colValArray[0].value.val;
345,438,706✔
364

365
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
345,438,706!
366
    return TSDB_CODE_INVALID_PARA;
×
367
  }
368

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

374
  // primary keys
375
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
346,571,579✔
376
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
1,132,875✔
377
  }
378

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

387
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
388
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
2,147,483,647✔
389
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
2,147,483,647✔
390
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
391
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
526,474,251✔
392
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
526,474,251✔
393
            if (colValArray[colValIndex].value.nData > 0) {
526,474,251!
394
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
533,497,824✔
395
                           colValArray[colValIndex].value.nData);
533,497,824✔
396
            }
397
            payloadSize += colValArray[colValIndex].value.nData;
526,474,251✔
398
          } else {
399
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
2,147,483,647✔
400
            (void)memcpy(payload + payloadSize, &colValArray[colValIndex].value.val,
2,147,483,647✔
401
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
402
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
2,147,483,647✔
403
          }
404
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
2,147,483,647✔
405
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
15,095,844✔
406
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
30,191,688✔
407
        }
408

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

419
  return 0;
345,438,704✔
420
}
421

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

426
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,177,982,736✔
427
  if (code) return code;
1,184,107,201✔
428

429
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,184,107,123✔
430
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
839,107,355✔
431
  } else {
432
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
344,999,768✔
433
  }
434
  return code;
1,186,499,800✔
435
}
436

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

551
    if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
552
      pv = pIdx->idx + pIdx->nCol;
2,147,483,647✔
553
    } else if (pRow->flag & KV_FLG_MID) {
68,411,860!
554
      pv = pIdx->idx + (pIdx->nCol << 1);
95,349,286✔
555
    } else {
556
      pv = pIdx->idx + (pIdx->nCol << 2);
×
557
    }
558

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

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

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

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

602
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2,147,483,647✔
603
  } else {  // Tuple Row
604
    uint8_t *bitmap = data;
871,366,828✔
605
    uint8_t *fixed;
606
    uint8_t *varlen;
607
    uint8_t  bit;
608

609
    if (pRow->flag == HAS_VALUE) {
871,366,828✔
610
      fixed = bitmap;
747,570,865✔
611
      bit = BIT_FLG_VALUE;
747,570,865✔
612
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
123,795,963!
613
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
614
      bit = GET_BIT2(bitmap, iCol - 1);
×
615
    } else {
616
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
123,795,963✔
617
      bit = GET_BIT1(bitmap, iCol - 1);
123,795,963✔
618

619
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
123,795,963✔
620
        if (bit) bit++;
21,519✔
621
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
123,774,444!
622
        bit++;
137,996,543✔
623
      }
624
    }
625
    varlen = fixed + pTSchema->flen;
871,366,828✔
626

627
    if (bit == BIT_FLG_NONE) {
871,366,828✔
628
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,631✔
629
      return 0;
7,631✔
630
    } else if (bit == BIT_FLG_NULL) {
871,359,197✔
631
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
23,816,982✔
632
      return 0;
23,816,982✔
633
    }
634

635
    pColVal->cid = pTColumn->colId;
847,542,215✔
636
    pColVal->value.type = pTColumn->type;
847,542,215✔
637
    pColVal->flag = CV_FLAG_VALUE;
847,542,215✔
638
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
847,542,215!
639
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
60,259,986✔
640
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
120,519,972!
641
    } else {
642
      (void)memcpy(&pColVal->value.val, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
787,282,229✔
643
    }
644
  }
645

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

649
void tRowDestroy(SRow *pRow) {
780,943,466✔
650
  if (pRow) taosMemoryFree(pRow);
780,943,466!
651
}
780,871,617✔
652

653
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
264,528,546✔
654
  SRowKey key1, key2;
655
  tRowGetKey(*(SRow **)p1, &key1);
264,528,546✔
656
  tRowGetKey(*(SRow **)p2, &key2);
258,401,218✔
657
  return tRowKeyCompare(&key1, &key2);
267,237,645✔
658
}
659
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
1,054✔
660
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
263✔
661
  int32_t code = 0;
263✔
662

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

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

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

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

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

688
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
1,009✔
689
    SColVal *pColVal = NULL;
746✔
690
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
882✔
691
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
841✔
692
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
932✔
693
        pColValT = tRowIterNext(aIter[iRow]);
91✔
694
      }
695

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

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

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

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

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

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

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

749
  int32_t iStart = 0;
49,595✔
750
  while (iStart < aRowP->size) {
37,733,121✔
751
    SRowKey key1;
752
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
37,725,811✔
753

754
    tRowGetKey(row1, &key1);
37,903,794✔
755

756
    int32_t iEnd = iStart + 1;
37,685,671✔
757
    while (iEnd < aRowP->size) {
37,662,660✔
758
      SRowKey key2;
759
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
37,634,210✔
760
      tRowGetKey(row2, &key2);
37,811,989✔
761

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

764
      iEnd++;
×
765
    }
766

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

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

776
  return code;
7,310✔
777
}
778

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

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

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

802
  int32_t code = 0;
209,090✔
803

804
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
209,090✔
805
  if (pIter == NULL) {
209,099✔
806
    code = terrno;
1✔
807
    goto _exit;
×
808
  }
809

810
  pIter->pRow = pRow;
209,098✔
811
  pIter->pTSchema = pTSchema;
209,098✔
812
  pIter->iTColumn = 0;
209,098✔
813

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

816
  uint8_t         *data = pRow->data;
208,943✔
817
  SPrimaryKeyIndex index;
818
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
208,984✔
819
    data += tGetPrimaryKeyIndex(data, &index);
41✔
820
  }
821

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

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

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

874
SColVal *tRowIterNext(SRowIter *pIter) {
4,980,370✔
875
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
4,980,370✔
876
    return NULL;
208,041✔
877
  }
878

879
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
4,772,329✔
880

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

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

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

900
  if (pIter->pRow->flag >> 4) {  // KV
4,562,549✔
901
    if (pIter->iCol < pIter->pIdx->nCol) {
4,500,889✔
902
      uint8_t *pData;
903

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

912
      int16_t cid;
913
      pData += tGetI16v(pData, &cid);
2,626,596✔
914

915
      if (TABS(cid) == pTColumn->colId) {
2,626,596✔
916
        if (cid < 0) {
2,626,562✔
917
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
175✔
918
        } else {
919
          pIter->cv.cid = pTColumn->colId;
2,626,387✔
920
          pIter->cv.value.type = pTColumn->type;
2,626,387✔
921
          pIter->cv.flag = CV_FLAG_VALUE;
2,626,387✔
922

923
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
2,626,387!
924
            pData += tGetU32v(pData, &pIter->cv.value.nData);
375,158!
925
            if (pIter->cv.value.nData > 0) {
375,158!
926
              pIter->cv.value.pData = pData;
375,442✔
927
            } else {
928
              pIter->cv.value.pData = NULL;
×
929
            }
930
          } else {
931
            (void)memcpy(&pIter->cv.value.val, pData, pTColumn->bytes);
2,251,229✔
932
          }
933
        }
934

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

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

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

995
_exit:
4,772,389✔
996
  pIter->iTColumn++;
4,772,389✔
997
  return &pIter->cv;
4,772,389✔
998
}
999

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

1003
  if (flag) return code;
10,817✔
1004

1005
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
95,457✔
1006
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
89,591✔
1007
    if (code) return code;
89,590!
1008
  }
1009

1010
  return code;
5,866✔
1011
}
1012
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
167,749✔
1013
  int32_t code = 0;
167,749✔
1014

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

1020
  while (pColData) {
609,378✔
1021
    if (pTColumn) {
441,531!
1022
      if (pTColumn->colId == pColData->cid) {  // NULL
441,531!
1023
        if (flag == 0) {
441,535✔
1024
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
441,494✔
1025
        } else {
1026
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
41✔
1027
        }
1028
        if (code) goto _exit;
441,633!
1029

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

1044
_exit:
167,847✔
1045
  return code;
167,847✔
1046
}
1047
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
765,137,224✔
1048
                                      int32_t flag) {
1049
  int32_t code = 0;
765,137,224✔
1050

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

1056
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
765,137,224✔
1057
  SPrimaryKeyIndex index;
1058
  uint8_t         *data = pRow->data;
765,137,224✔
1059
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
989,843,617✔
1060
    data += tGetPrimaryKeyIndex(data, &index);
224,828,291✔
1061
  }
1062

1063
  switch (pRow->flag) {
765,015,326!
1064
    case HAS_VALUE:
754,335,318✔
1065
      pf = data;  // TODO: fix here
754,335,318✔
1066
      pv = pf + pTSchema->flen;
754,335,318✔
1067
      break;
754,335,318✔
1068
    case (HAS_NULL | HAS_NONE):
1,296✔
1069
      pb = data;
1,296✔
1070
      break;
1,296✔
1071
    case (HAS_VALUE | HAS_NONE):
11,141,475✔
1072
    case (HAS_VALUE | HAS_NULL):
1073
      pb = data;
11,141,475✔
1074
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
11,141,475✔
1075
      pv = pf + pTSchema->flen;
11,141,475✔
1076
      break;
11,141,475✔
1077
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1078
      pb = data;
×
1079
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1080
      pv = pf + pTSchema->flen;
×
1081
      break;
×
1082
    default:
×
1083
      return TSDB_CODE_INVALID_DATA_FMT;
×
1084
  }
1085

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

1112
          if (bv == BIT_FLG_NONE) {
75,889,732✔
1113
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,384!
1114
              goto _exit;
×
1115
            goto _continue;
43,385✔
1116
          } else if (bv == BIT_FLG_NULL) {
75,846,348✔
1117
            if (flag == 0) {
14,974,791✔
1118
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
14,801,421✔
1119
            } else {
1120
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
173,370✔
1121
            }
1122
            if (code) goto _exit;
14,976,199!
1123
            goto _continue;
14,976,199✔
1124
          }
1125
        }
1126

1127
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1128
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
59,294,469!
1129
          uint32_t nData;
1130
          pData += tGetU32v(pData, &nData);
59,294,469✔
1131
          if (flag == 0) {
59,294,469!
1132
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
64,640,767✔
1133
          } else {
1134
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1135
          }
1136
          if (code) goto _exit;
65,867,317!
1137
        } else {
1138
          if (flag == 0) {
2,147,483,647✔
1139
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,147,483,647✔
1140
                                                                          TYPE_BYTES[pColData->type]);
2,147,483,647✔
1141
          } else {
1142
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
18,158,724✔
1143
                                                                          TYPE_BYTES[pColData->type], flag > 0);
18,158,724✔
1144
          }
1145
          if (code) goto _exit;
2,147,483,647!
1146
        }
1147

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

1163
_exit:
770,296,527✔
1164
  return code;
770,296,527✔
1165
}
1166
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
6,615,568✔
1167
  int32_t code = 0;
6,615,568✔
1168

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

1176
  // primary keys
1177
  uint8_t         *data = pRow->data;
6,615,568✔
1178
  SPrimaryKeyIndex index;
1179
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
6,863,453✔
1180
    data += tGetPrimaryKeyIndex(data, &index);
247,955✔
1181
  }
1182

1183
  SKVIdx *pKVIdx = (SKVIdx *)data;
6,615,498✔
1184
  if (pRow->flag & KV_FLG_LIT) {
6,615,498✔
1185
    pv = pKVIdx->idx + pKVIdx->nCol;
6,549,561✔
1186
  } else if (pRow->flag & KV_FLG_MID) {
65,937!
1187
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
70,116✔
1188
  } else if (pRow->flag & KV_FLG_BIG) {
×
1189
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1190
  } else {
1191
    return TSDB_CODE_INVALID_PARA;
×
1192
  }
1193

1194
  while (pColData) {
107,391,529✔
1195
    if (pTColumn) {
100,805,319✔
1196
      if (pTColumn->colId == pColData->cid) {
100,406,131✔
1197
        while (iCol < pKVIdx->nCol) {
100,353,439✔
1198
          uint8_t *pData;
1199
          if (pRow->flag & KV_FLG_LIT) {
69,348,544✔
1200
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
67,405,157✔
1201
          } else if (pRow->flag & KV_FLG_MID) {
1,943,387!
1202
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,943,491✔
1203
          } else if (pRow->flag & KV_FLG_BIG) {
×
1204
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1205
          } else {
1206
            return TSDB_CODE_INVALID_DATA_FMT;
×
1207
          }
1208

1209
          int16_t cid;
1210
          pData += tGetI16v(pData, &cid);
69,348,648✔
1211

1212
          if (TABS(cid) == pTColumn->colId) {
69,348,648✔
1213
            if (cid < 0) {
36,454,802✔
1214
              if (flag == 0) {
8,721,026✔
1215
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
8,717,635✔
1216
              } else {
1217
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
3,391✔
1218
              }
1219
              if (code) goto _exit;
8,271,910!
1220
            } else {
1221
              uint32_t nData;
1222
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
27,733,776!
1223
                pData += tGetU32v(pData, &nData);
6,146,733✔
1224
              } else {
1225
                nData = 0;
21,587,043✔
1226
              }
1227
              if (flag == 0) {
27,733,776!
1228
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
27,808,721✔
1229
              } else {
1230
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1231
              }
1232
              if (code) goto _exit;
28,149,932!
1233
            }
1234
            iCol++;
36,421,842✔
1235
            goto _continue;
36,421,842✔
1236
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
32,893,846✔
1237
            break;
32,507,407✔
1238
          } else {
1239
            iCol++;
386,439✔
1240
          }
1241
        }
1242

1243
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
63,512,302!
1244

1245
      _continue:
63,511,723✔
1246
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
99,933,565✔
1247
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
99,933,565✔
1248
      } else if (pTColumn->colId > pColData->cid) {
439,131!
1249
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1250
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1251
      } else {
1252
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
439,131✔
1253
      }
1254
    } else {
1255
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,188!
1256
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,156✔
1257
    }
1258
  }
1259

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

1271
  if (pRow->flag == HAS_NONE) {
772,004,303✔
1272
    return tRowNoneUpsertColData(aColData, nColData, flag);
10,817✔
1273
  } else if (pRow->flag == HAS_NULL) {
771,993,486✔
1274
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
167,754✔
1275
  } else if (pRow->flag >> 4) {  // KV row
771,825,732✔
1276
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
6,615,909✔
1277
  } else {  // TUPLE row
1278
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
765,209,823✔
1279
  }
1280
}
1281

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

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

1289
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1290

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

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

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

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

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

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

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

UNCOV
1368
  return 0;
×
1369
}
1370

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

1381
  if (key1->numOfPKs == key2->numOfPKs) {
80,431,474!
1382
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
129,376,195!
1383
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
49,648,593✔
1384
      if (ret) return ret;
49,632,990!
1385
    }
1386
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1387
    return -1;
6✔
1388
  } else {
1389
    return 1;
×
1390
  }
1391

1392
  return 0;
79,727,602✔
1393
}
1394

1395
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
736,117,012✔
1396
  pDst->ts = pSrc->ts;
736,117,012✔
1397
  pDst->numOfPKs = pSrc->numOfPKs;
736,117,012✔
1398

1399
  if (pSrc->numOfPKs > 0) {
736,117,012✔
1400
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
63,583,602✔
1401
      SValue *pVal = &pDst->pks[i];
31,818,083✔
1402
      pVal->type = pSrc->pks[i].type;
31,818,083✔
1403

1404
      if (IS_NUMERIC_TYPE(pVal->type)) {
31,818,083!
1405
        pVal->val = pSrc->pks[i].val;
30,529,347✔
1406
      } else {
1407
        pVal->nData = pSrc->pks[i].nData;
1,288,736✔
1408
        (void)memcpy(pVal->pData, pSrc->pks[i].pData, pVal->nData);
1,288,736✔
1409
      }
1410
    }
1411
  }
1412
}
736,117,012✔
1413

1414
// STag ========================================
1415
static int tTagValCmprFn(const void *p1, const void *p2) {
127,136,598✔
1416
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
127,136,598✔
1417
    return -1;
43,470,213✔
1418
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
83,666,385✔
1419
    return 1;
46,028,277✔
1420
  }
1421

1422
  return 0;
37,638,108✔
1423
}
1424
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
10,892✔
1425
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
10,892✔
1426
}
1427

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

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

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

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

1524
  // key
1525
  if (isJson) {
901,290✔
1526
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
3,760✔
1527
  } else {
1528
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
1,798,820✔
1529
  }
1530

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

1534
  // value
1535
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
901,290!
1536
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
559,930✔
1537
  } else {
1538
    p = p ? p + n : p;
621,325✔
1539
    n += tDataTypes[pTagVal->type].bytes;
621,325✔
1540
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
621,325✔
1541
  }
1542

1543
  return n;
901,290✔
1544
}
1545
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
125,106,271✔
1546
  int32_t n = 0;
125,106,271✔
1547

1548
  // key
1549
  if (isJson) {
125,106,271✔
1550
    n += tGetCStr(p + n, &pTagVal->pKey);
27,402!
1551
  } else {
1552
    n += tGetI16v(p + n, &pTagVal->cid);
250,185,140!
1553
  }
1554

1555
  // type
1556
  n += tGetI8(p + n, &pTagVal->type);
125,106,271!
1557

1558
  // value
1559
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
125,106,271!
1560
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
39,956,810!
1561
  } else {
1562
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
105,127,866✔
1563
    n += tDataTypes[pTagVal->type].bytes;
105,127,866✔
1564
  }
1565

1566
  return n;
125,106,271✔
1567
}
1568

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

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

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

1586
  // sort
1587
  if (isJson) {
165,084✔
1588
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
582✔
1589
  } else {
1590
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
164,502✔
1591
  }
1592

1593
  // get size
1594
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
615,865✔
1595
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
450,782✔
1596
  }
1597
  if (szTag <= INT8_MAX) {
165,083✔
1598
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
148,807✔
1599
  } else {
1600
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
16,276✔
1601
    isLarge = 1;
16,276✔
1602
  }
1603

1604
  // build tag
1605
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
165,083✔
1606
  if ((*ppTag) == NULL) {
165,137✔
1607
    code = terrno;
6✔
1608
    goto _err;
×
1609
  }
1610
  (*ppTag)->flags = 0;
165,131✔
1611
  if (isJson) {
165,131✔
1612
    (*ppTag)->flags |= TD_TAG_JSON;
582✔
1613
  }
1614
  if (isLarge) {
165,131✔
1615
    (*ppTag)->flags |= TD_TAG_LARGE;
16,279✔
1616
  }
1617
  (*ppTag)->len = szTag;
165,131✔
1618
  (*ppTag)->nTag = nTag;
165,131✔
1619
  (*ppTag)->ver = version;
165,131✔
1620

1621
  if (isLarge) {
165,131✔
1622
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
16,279✔
1623
  } else {
1624
    p = (uint8_t *)&(*ppTag)->idx[nTag];
148,852✔
1625
  }
1626
  n = 0;
165,131✔
1627
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
615,913✔
1628
    if (isLarge) {
450,795✔
1629
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
104,038✔
1630
    } else {
1631
      (*ppTag)->idx[iTag] = n;
346,757✔
1632
    }
1633
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
450,795✔
1634
  }
1635
#ifdef TD_DEBUG_PRINT_TAG
1636
  debugPrintSTag(*ppTag, __func__, __LINE__);
1637
#endif
1638

1639
  return code;
165,118✔
1640

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

1645
void tTagFree(STag *pTag) {
2,104,370✔
1646
  if (pTag) taosMemoryFree(pTag);
2,104,370✔
1647
}
2,104,370✔
1648

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

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

1660
  if (IS_VAR_DATA_TYPE(value->type)) {
12,965,200!
1661
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
3,416,015✔
1662
    if (data == NULL) {
3,422,625!
1663
      return NULL;
×
1664
    }
1665

1666
    if (isJson) {
3,422,625✔
1667
      *data = value->type;
2,378✔
1668
    }
1669

1670
    varDataLen(data + typeBytes) = value->nData;
3,422,625✔
1671
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
3,422,625✔
1672
  } else {
1673
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
9,549,185✔
1674
  }
1675

1676
  return data;
12,971,810✔
1677
}
1678

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

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

1694
  if (isLarge) {
39,269,599✔
1695
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
32,034,241✔
1696
  } else {
1697
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,235,358✔
1698
  }
1699

1700
  pTagVal->type = TSDB_DATA_TYPE_NULL;
39,269,599✔
1701
  pTagVal->pData = NULL;
39,269,599✔
1702
  pTagVal->nData = 0;
39,269,599✔
1703
  while (lidx <= ridx) {
128,114,942✔
1704
    midx = (lidx + ridx) / 2;
125,447,634✔
1705
    if (isLarge) {
125,447,634✔
1706
      offset = ((int16_t *)pTag->idx)[midx];
102,026,046✔
1707
    } else {
1708
      offset = pTag->idx[midx];
23,421,588✔
1709
    }
1710

1711
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
125,447,634✔
1712
    if (isJson) {
126,582,035✔
1713
      c = tTagValJsonCmprFn(pTagVal, &tv);
10,408✔
1714
    } else {
1715
      c = tTagValCmprFn(pTagVal, &tv);
126,571,627✔
1716
    }
1717

1718
    if (c < 0) {
128,311,893✔
1719
      ridx = midx - 1;
42,896,274✔
1720
    } else if (c > 0) {
85,415,619✔
1721
      lidx = midx + 1;
45,949,069✔
1722
    } else {
1723
      (void)memcpy(pTagVal, &tv, sizeof(tv));
39,466,550✔
1724
      return true;
39,466,550✔
1725
    }
1726
  }
1727
  return false;
2,667,308✔
1728
}
1729

1730
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
807,845✔
1731
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,615,690✔
1732
}
1733

1734
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
16,993,282✔
1735

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

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

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

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

1768
  return code;
2,189✔
1769

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

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

1782
  pTSchema->numOfCols = numOfCols;
16,151,997✔
1783
  pTSchema->version = version;
16,151,997✔
1784

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

1800
  // other columns
1801
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
219,345,617✔
1802
    SSchema  *pSchema = &aSchema[iCol];
203,193,620✔
1803
    STColumn *pTColumn = &pTSchema->columns[iCol];
203,193,620✔
1804

1805
    pTColumn->colId = pSchema->colId;
203,193,620✔
1806
    pTColumn->type = pSchema->type;
203,193,620✔
1807
    pTColumn->flags = pSchema->flags;
203,193,620✔
1808
    pTColumn->offset = pTSchema->flen;
203,193,620✔
1809

1810
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
203,193,620!
1811
      pTColumn->bytes = pSchema->bytes;
38,237,290✔
1812
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
38,237,290✔
1813
    } else {
1814
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
164,956,330✔
1815
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
164,956,330✔
1816
    }
1817

1818
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
203,193,620✔
1819
  }
1820

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

1825
  return pTSchema;
16,151,997✔
1826
}
1827

1828
static int32_t tTColumnCompare(const void *p1, const void *p2) {
6,367,054✔
1829
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
6,367,054✔
1830
    return -1;
969,783✔
1831
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
5,397,271✔
1832
    return 1;
3,822,385✔
1833
  }
1834

1835
  return 0;
1,574,886✔
1836
}
1837

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

1843
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
1,575,846✔
1844
}
1845

1846
// SColData ========================================
1847
void tColDataDestroy(void *ph) {
20,138,643✔
1848
  if (ph) {
20,138,643!
1849
    SColData *pColData = (SColData *)ph;
20,138,918✔
1850

1851
    tFree(pColData->pBitMap);
20,138,918✔
1852
    tFree(pColData->aOffset);
20,139,092✔
1853
    tFree(pColData->pData);
20,139,151✔
1854
  }
1855
}
20,139,085✔
1856

1857
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
20,587,074✔
1858
  pColData->cid = cid;
20,587,074✔
1859
  pColData->type = type;
20,587,074✔
1860
  pColData->cflag = cflag;
20,587,074✔
1861
  tColDataClear(pColData);
20,587,074✔
1862
}
20,589,595✔
1863

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

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

1878
  tColDataClear(pColData);
787✔
1879
}
788✔
1880

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

1884
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1885
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
127,207,906!
1886
    if (code) goto _exit;
135,080,863!
1887
    pColData->aOffset[pColData->nVal] = pColData->nData;
135,080,863✔
1888

1889
    if (nData) {
135,080,863!
1890
      code = tRealloc(&pColData->pData, pColData->nData + nData);
130,522,774!
1891
      if (code) goto _exit;
130,854,064!
1892
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
130,854,064✔
1893
      pColData->nData += nData;
130,854,064✔
1894
    }
1895
  } else {
1896
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
1897
      return TSDB_CODE_INVALID_PARA;
×
1898
    }
1899
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
1900
    if (code) goto _exit;
2,147,483,647!
1901
    if (pData) {
2,147,483,647!
1902
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
1903
    } else {
1904
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
42,748,532✔
1905
    }
1906
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
1907
  }
1908
  pColData->nVal++;
2,147,483,647✔
1909

1910
_exit:
2,147,483,647✔
1911
  return code;
2,147,483,647✔
1912
}
1913
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
3,083,791✔
1914
  pColData->flag = HAS_VALUE;
3,083,987✔
1915
  pColData->numOfValue++;
3,083,791✔
1916
  return tColDataPutValue(pColData, pData, nData);
3,086,095✔
1917
}
1918
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
253,861✔
1919
  pColData->flag = HAS_NONE;
253,861✔
1920
  pColData->numOfNone++;
253,861✔
1921
  pColData->nVal++;
253,861✔
1922
  return 0;
253,861✔
1923
}
1924
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
182,355✔
1925
  pColData->flag = HAS_NULL;
182,486✔
1926
  pColData->numOfNull++;
182,486✔
1927
  pColData->nVal++;
182,486✔
1928
  return 0;
182,355✔
1929
}
1930
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,421✔
1931
  int32_t code = 0;
1,421✔
1932

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

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

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

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

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

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

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

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

1978
  return code;
601✔
1979
}
1980
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
22,945✔
1981
  int32_t code = 0;
22,947✔
1982

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

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

1990
  pColData->flag |= HAS_VALUE;
22,947✔
1991
  pColData->numOfValue++;
22,947✔
1992

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

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

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

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

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

2023
  return code;
10,080✔
2024
}
2025
static FORCE_INLINE int32_t tColDataAppendValue22(SColData *pColData, uint8_t *pData, uint32_t nData) {
9,198,414✔
2026
  pColData->nVal++;
9,198,414✔
2027
  pColData->numOfNull++;
9,198,414✔
2028
  return 0;
9,198,414✔
2029
}
2030
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
5✔
2031
  int32_t code = 0;
5✔
2032

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

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

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

2045
  tFree(pColData->pBitMap);
5!
2046
  pColData->pBitMap = pBitMap;
5✔
2047

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

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

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

2070
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
1,989,900✔
2071
  pColData->numOfNone++;
1,989,900✔
2072
  pColData->nVal++;
1,989,900✔
2073

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

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

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

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

2095
  pColData->flag |= HAS_NONE;
161,151✔
2096
  pColData->numOfNone++;
161,151✔
2097

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

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

2105
  return tColDataPutValue(pColData, NULL, 0);
161,191✔
2106
}
2107
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
286,585✔
2108
  int32_t code = 0;
292,690✔
2109

2110
  pColData->flag |= HAS_NULL;
292,690✔
2111
  pColData->numOfNull++;
292,690✔
2112

2113
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
292,690✔
2114
  code = tRealloc(&pColData->pBitMap, nBit);
292,386✔
2115
  if (code) return code;
292,704!
2116

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

2120
  return tColDataPutValue(pColData, NULL, 0);
292,707✔
2121
}
2122
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,304,722✔
2123
  int32_t code = 0;
1,306,723✔
2124

2125
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,306,722!
2126
  if (code) return code;
1,306,892!
2127

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

2131
  return tColDataPutValue(pColData, pData, nData);
1,308,841✔
2132
}
2133
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
14,106,318✔
2134
  int32_t code = 0;
14,106,318✔
2135

2136
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
14,106,318!
2137
  if (code) return code;
14,106,385!
2138

2139
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
14,106,385✔
2140
  pColData->numOfNone++;
14,106,385✔
2141

2142
  return tColDataPutValue(pColData, NULL, 0);
14,109,407✔
2143
}
2144
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
12,466✔
2145
  int32_t code = 0;
12,466✔
2146

2147
  pColData->flag |= HAS_NULL;
12,466✔
2148
  pColData->numOfNull++;
12,466✔
2149

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

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

2159
  tFree(pColData->pBitMap);
12,466!
2160
  pColData->pBitMap = pBitMap;
12,466!
2161

2162
  return tColDataPutValue(pColData, NULL, 0);
12,466✔
2163
}
2164
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
372,091,324✔
2165
  int32_t code = 0;
372,258,195✔
2166

2167
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
372,257,795!
2168
  if (code) return code;
372,567,404!
2169
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
372,567,404!
2170
  pColData->numOfValue++;
372,567,404✔
2171

2172
  return tColDataPutValue(pColData, pData, nData);
372,889,746✔
2173
}
2174
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
28,925✔
2175
  int32_t code = 0;
28,925✔
2176

2177
  pColData->flag |= HAS_NONE;
28,925✔
2178
  pColData->numOfNone++;
28,925✔
2179

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

2184
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,902,848✔
2185
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
3,873,923✔
2186
  }
2187
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
28,925✔
2188

2189
  tFree(pColData->pBitMap);
28,925!
2190
  pColData->pBitMap = pBitMap;
28,923✔
2191

2192
  return tColDataPutValue(pColData, NULL, 0);
28,924✔
2193
}
2194
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
24,603,904✔
2195
  int32_t code = 0;
24,783,147✔
2196

2197
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
24,779,553!
2198
  if (code) return code;
24,793,237!
2199
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
24,793,237✔
2200
  pColData->numOfNull++;
24,793,237✔
2201

2202
  return tColDataPutValue(pColData, NULL, 0);
24,808,666✔
2203
}
2204
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
660,560✔
2205
  int32_t code = 0;
660,560✔
2206

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

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

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

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

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

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

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

2255
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
9✔
2256
  pColData->numOfNone--;
9✔
2257
  pColData->nVal--;
9✔
2258
  if (pColData->numOfNone) {
9!
2259
    return tColDataAppendValue10(pColData, pData, nData);
×
2260
  } else {
2261
    pColData->flag = 0;
9✔
2262
    return tColDataAppendValue00(pColData, pData, nData);
9✔
2263
  }
2264
}
2265
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
2266
  pColData->numOfNone--;
24✔
2267
  pColData->nVal--;
24✔
2268
  if (pColData->numOfNone) {
24!
2269
    return tColDataAppendValue12(pColData, pData, nData);
×
2270
  } else {
2271
    pColData->flag = 0;
24✔
2272
    return tColDataAppendValue02(pColData, pData, nData);
24✔
2273
  }
2274
  return 0;
2275
}
2276
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
187✔
2277
  if (forward) {
187!
2278
    pColData->numOfNull--;
187✔
2279
    pColData->nVal--;
187✔
2280
    if (pColData->numOfNull) {
187!
UNCOV
2281
      return tColDataAppendValue20(pColData, pData, nData);
×
2282
    } else {
2283
      pColData->flag = 0;
187✔
2284
      return tColDataAppendValue00(pColData, pData, nData);
187✔
2285
    }
2286
  }
2287
  return 0;
×
2288
}
2289
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2290
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2291
    pColData->numOfNone--;
×
2292
    pColData->nVal--;
×
2293
    if (pColData->numOfNone) {
×
2294
      return tColDataAppendValue30(pColData, pData, nData);
×
2295
    } else {
2296
      pColData->flag = HAS_NULL;
×
2297
      return tColDataAppendValue20(pColData, pData, nData);
×
2298
    }
2299
  } else if (forward) {  // NULL ==> VALUE
×
2300
    pColData->numOfNull--;
×
2301
    pColData->nVal--;
×
2302
    if (pColData->numOfNull) {
×
2303
      return tColDataAppendValue30(pColData, pData, nData);
×
2304
    } else {
2305
      pColData->flag = HAS_NONE;
×
2306
      return tColDataAppendValue10(pColData, pData, nData);
×
2307
    }
2308
  }
2309
  return 0;
×
2310
}
2311
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
2312
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
2313
    pColData->numOfNone--;
80✔
2314
    pColData->numOfNull++;
80✔
2315
    if (pColData->numOfNone) {
80!
2316
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2317
    } else {
2318
      pColData->flag = HAS_NULL;
80✔
2319
    }
2320
  }
2321
  return 0;
80✔
2322
}
2323
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
52,185,119✔
2324
  if (forward) {  // VALUE ==> VALUE
52,185,119!
2325
    pColData->nVal--;
52,189,118✔
2326
    if (IS_VAR_DATA_TYPE(pColData->type)) {
52,189,118!
2327
      pColData->nData = pColData->aOffset[pColData->nVal];
1,077,001✔
2328
    } else {
2329
      pColData->nData -= TYPE_BYTES[pColData->type];
51,112,117✔
2330
    }
2331
    return tColDataPutValue(pColData, pData, nData);
52,196,701✔
2332
  }
2333
  return 0;
×
2334
}
2335
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,908✔
2336
  if (forward) {  // VALUE ==> NULL
5,908!
2337
    pColData->numOfValue--;
5,908✔
2338
    pColData->nVal--;
5,908✔
2339
    if (pColData->numOfValue) {
5,908✔
2340
      if (IS_VAR_DATA_TYPE(pColData->type)) {
5,801!
2341
        pColData->nData = pColData->aOffset[pColData->nVal];
1,156✔
2342
      } else {
2343
        pColData->nData -= TYPE_BYTES[pColData->type];
4,645✔
2344
      }
2345
      return tColDataAppendValue42(pColData, pData, nData);
5,800✔
2346
    } else {
2347
      pColData->flag = 0;
107✔
2348
      pColData->nData = 0;
107✔
2349
      return tColDataAppendValue02(pColData, pData, nData);
107✔
2350
    }
2351
  }
2352
  return 0;
×
2353
}
2354
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
39,375✔
2355
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
39,375✔
2356
    pColData->numOfNone--;
5,599✔
2357
    pColData->nVal--;
5,599✔
2358
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,599!
2359
      pColData->nData -= TYPE_BYTES[pColData->type];
4,479✔
2360
    }
2361
    if (pColData->numOfNone) {
5,599✔
2362
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2363
    } else {
2364
      pColData->flag = HAS_VALUE;
3,599✔
2365
      return tColDataAppendValue40(pColData, pData, nData);
3,600✔
2366
    }
2367
  } else if (forward) {  // VALUE ==> VALUE
33,776!
2368
    pColData->nVal--;
33,777✔
2369
    if (IS_VAR_DATA_TYPE(pColData->type)) {
33,777!
2370
      pColData->nData = pColData->aOffset[pColData->nVal];
4,832✔
2371
    } else {
2372
      pColData->nData -= TYPE_BYTES[pColData->type];
28,945✔
2373
    }
2374
    return tColDataPutValue(pColData, pData, nData);
33,777✔
2375
  }
2376
  return 0;
×
2377
}
2378
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
304✔
2379
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
304!
2380
    pColData->numOfNone--;
304✔
2381
    pColData->nVal--;
304✔
2382
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
304!
2383
      pColData->nData -= TYPE_BYTES[pColData->type];
244✔
2384
    }
2385
    if (pColData->numOfNone) {
304!
2386
      return tColDataAppendValue52(pColData, pData, nData);
×
2387
    } else {
2388
      pColData->flag = HAS_VALUE;
304!
2389
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2390
    }
2391
  } else if (forward) {  // VALUE ==> NULL
×
2392
    pColData->numOfValue--;
×
2393
    pColData->nVal--;
×
2394
    if (pColData->numOfValue) {
×
2395
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2396
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2397
      } else {
2398
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2399
      }
2400
      return tColDataAppendValue52(pColData, pData, nData);
×
2401
    } else {
2402
      pColData->flag = HAS_NONE;
×
2403
      pColData->nData = 0;
×
2404
      return tColDataAppendValue12(pColData, pData, nData);
×
2405
    }
2406
  }
2407
  return 0;
×
2408
}
2409
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,306,687✔
2410
  if (forward) {
3,306,687!
2411
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
3,306,687✔
2412
      pColData->numOfNull--;
187,394✔
2413
      pColData->nVal--;
187,394✔
2414
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
187,394!
2415
        pColData->nData -= TYPE_BYTES[pColData->type];
157,289✔
2416
      }
2417
      if (pColData->numOfNull) {
187,394✔
2418
        return tColDataAppendValue60(pColData, pData, nData);
166,472✔
2419
      } else {
2420
        pColData->flag = HAS_VALUE;
20,923✔
2421
        return tColDataAppendValue40(pColData, pData, nData);
20,924✔
2422
      }
2423
    } else {  // VALUE ==> VALUE
2424
      pColData->nVal--;
3,119,293✔
2425
      if (IS_VAR_DATA_TYPE(pColData->type)) {
3,119,293!
2426
        pColData->nData = pColData->aOffset[pColData->nVal];
481,088✔
2427
      } else {
2428
        pColData->nData -= TYPE_BYTES[pColData->type];
2,638,205✔
2429
      }
2430
      return tColDataPutValue(pColData, pData, nData);
3,119,292✔
2431
    }
2432
  }
2433
  return 0;
×
2434
}
2435
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
198,861✔
2436
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
198,861!
2437
    pColData->numOfValue--;
175,651✔
2438
    pColData->nVal--;
175,651✔
2439
    if (pColData->numOfValue) {
175,651✔
2440
      if (IS_VAR_DATA_TYPE(pColData->type)) {
175,649!
2441
        pColData->nData = pColData->aOffset[pColData->nVal];
27,969✔
2442
      } else {
2443
        pColData->nData -= TYPE_BYTES[pColData->type];
147,680✔
2444
      }
2445
      return tColDataAppendValue62(pColData, pData, nData);
175,648✔
2446
    } else {
2447
      pColData->flag = HAS_NULL;
2✔
2448
      pColData->nData = 0;
2!
2449
      return tColDataAppendValue20(pColData, pData, nData);
2✔
2450
    }
2451
  }
2452
  return 0;
23,210✔
2453
}
2454
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
401✔
2455
  int32_t code = 0;
401✔
2456

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

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

2562
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
36,648,529!
2563

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

2569
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
53,680,236✔
2570
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
53,680,236✔
2571
}
53,680,236✔
2572
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
3,644,049✔
2573
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
3,644,049✔
2574
}
3,644,049✔
2575
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
10,994✔
2576
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2577
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
10,994!
2578
    case 0:
1,000✔
2579
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,000✔
2580
      break;
1,000✔
2581
    case 1:
9,996✔
2582
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
9,996✔
2583
      break;
9,996✔
UNCOV
2584
    default:
×
UNCOV
2585
      break;
×
2586
  }
2587
}
10,994✔
2588
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
2589
  SValue value = {.type = pColData->type};
2,147,483,647✔
2590
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2591
    if (iVal + 1 < pColData->nVal) {
271,025,955!
2592
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
274,345,217✔
2593
    } else {
2594
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2595
    }
2596
    value.pData = pColData->pData + pColData->aOffset[iVal];
271,025,955✔
2597
  } else {
2598
    (void)memcpy(&value.val, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
2599
                 tDataTypes[pColData->type].bytes);
2,147,483,647✔
2600
  }
2601
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
2602
}
206,884,146✔
2603
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
8,097,058✔
2604
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2605
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
8,097,058!
2606
    case 0:
4,078,632✔
2607
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
4,078,632✔
2608
      break;
4,078,632✔
2609
    case 1:
4,142,324✔
2610
      tColDataGetValue4(pColData, iVal, pColVal);
2611
      break;
4,142,324✔
2612
    default:
×
2613
      break;
×
2614
  }
2615
}
8,097,058✔
2616
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
214,700,413✔
2617
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2618
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
214,700,413!
2619
    case 0:
12,539,320✔
2620
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
12,539,320✔
2621
      break;
12,539,320✔
2622
    case 1:
202,741,755✔
2623
      tColDataGetValue4(pColData, iVal, pColVal);
2624
      break;
202,741,755✔
2625
    default:
×
2626
      break;
×
2627
  }
2628
}
214,700,413✔
2629
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
11✔
2630
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
2631
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
11!
2632
    case 0:
5✔
2633
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
5✔
2634
      break;
5✔
2635
    case 1:
5✔
2636
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
5✔
2637
      break;
5✔
2638
    case 2:
1!
2639
      tColDataGetValue4(pColData, iVal, pColVal);
2640
      break;
1✔
2641
    default:
×
2642
      break;
×
2643
  }
2644
}
11✔
2645
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2646
    NULL,               // 0
2647
    tColDataGetValue1,  // HAS_NONE
2648
    tColDataGetValue2,  // HAS_NULL
2649
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2650
    tColDataGetValue4,  // HAS_VALUE
2651
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2652
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2653
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2654
};
2655
void tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
2656
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
2657
}
2,147,483,647✔
2658

2659
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
612,943,455✔
2660
  switch (pColData->flag) {
612,943,455!
2661
    case HAS_NONE:
×
2662
      return 0;
×
2663
    case HAS_NULL:
×
2664
      return 1;
×
2665
    case (HAS_NULL | HAS_NONE):
11,000✔
2666
      return GET_BIT1(pColData->pBitMap, iVal);
11,000✔
2667
    case HAS_VALUE:
×
2668
      return 2;
×
2669
    case (HAS_VALUE | HAS_NONE):
8,890,801✔
2670
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
8,890,801✔
2671
    case (HAS_VALUE | HAS_NULL):
604,024,298✔
2672
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
604,024,298✔
2673
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2674
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
2675
    default:
17,334✔
2676
      return 0;
17,334✔
2677
  }
2678
}
2679

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

2683
  *pColData = *pColDataFrom;
532✔
2684

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

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

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

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

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

2739
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
3,032,693✔
2740
  int32_t code;
2741
  SBuffer local;
2742

2743
  if (!(colData->nVal > 0)) {
3,032,693!
2744
    return TSDB_CODE_INVALID_PARA;
×
2745
  }
2746

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

2756
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
3,032,693!
2757
    return 0;
148,293✔
2758
  }
2759

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

2765
  // bitmap
2766
  if (colData->flag != HAS_VALUE) {
2,884,400✔
2767
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
450,579✔
2768
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
37,401✔
2769
    } else {
2770
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
413,178✔
2771
    }
2772

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

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

2785
    info->bitmapCompressedSize = cinfo.compressedSize;
450,721✔
2786
  }
2787

2788
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
2,884,542✔
2789
    tBufferDestroy(&local);
2790
    return 0;
10,596✔
2791
  }
2792

2793
  // offset
2794
  if (IS_VAR_DATA_TYPE(colData->type)) {
2,873,946!
2795
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
378,998✔
2796

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

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

2809
    info->offsetCompressedSize = cinfo.compressedSize;
379,029✔
2810
  }
2811

2812
  // data
2813
  if (colData->nData > 0) {
2,873,977!
2814
    info->dataOriginalSize = colData->nData;
2,874,057✔
2815

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

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

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

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

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

2840
  tBufferInit(&local);
2841
  if (assist == NULL) {
17,641,442!
2842
    assist = &local;
×
2843
  }
2844

2845
  tColDataClear(colData);
17,641,442✔
2846
  colData->cid = info->columnId;
17,640,471✔
2847
  colData->type = info->dataType;
17,640,471✔
2848
  colData->cflag = info->columnFlag;
17,640,471✔
2849
  colData->nVal = info->numOfData;
17,640,471✔
2850
  colData->flag = info->flag;
17,640,471✔
2851

2852
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
17,640,471✔
2853
    goto _exit;
1,902,566✔
2854
  }
2855

2856
  // bitmap
2857
  if (info->bitmapOriginalSize > 0) {
15,737,905✔
2858
    SCompressInfo cinfo = {
1,082,942✔
2859
        .dataType = TSDB_DATA_TYPE_TINYINT,
2860
        .cmprAlg = info->cmprAlg,
1,082,942✔
2861
        .originalSize = info->bitmapOriginalSize,
1,082,942✔
2862
        .compressedSize = info->bitmapCompressedSize,
1,082,942✔
2863
    };
2864

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

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

2877
    data += cinfo.compressedSize;
1,082,675✔
2878
  }
2879

2880
  if (info->flag == (HAS_NONE | HAS_NULL)) {
15,737,638✔
2881
    goto _exit;
600✔
2882
  }
2883

2884
  // offset
2885
  if (info->offsetOriginalSize > 0) {
15,737,038✔
2886
    SCompressInfo cinfo = {
3,183,234✔
2887
        .cmprAlg = info->cmprAlg,
3,183,234✔
2888
        .dataType = TSDB_DATA_TYPE_INT,
2889
        .originalSize = info->offsetOriginalSize,
3,183,234✔
2890
        .compressedSize = info->offsetCompressedSize,
3,183,234✔
2891
    };
2892

2893
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
3,183,234!
2894
    if (code) {
3,183,396!
2895
      tBufferDestroy(&local);
2896
      return code;
×
2897
    }
2898

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

2905
    data += cinfo.compressedSize;
3,183,410✔
2906
  }
2907

2908
  // data
2909
  if (info->dataOriginalSize > 0) {
15,737,214✔
2910
    colData->nData = info->dataOriginalSize;
15,736,029✔
2911

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

2919
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
15,736,029!
2920
    if (code) {
15,737,901!
2921
      tBufferDestroy(&local);
2922
      return code;
×
2923
    }
2924

2925
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
15,737,901✔
2926
    if (code) {
15,735,549!
2927
      tBufferDestroy(&local);
2928
      return code;
×
2929
    }
2930

2931
    data += cinfo.compressedSize;
15,735,549✔
2932
  }
2933

2934
_exit:
1,185✔
2935
  switch (colData->flag) {
17,639,900✔
2936
    case HAS_NONE:
1,576,271✔
2937
      colData->numOfNone = colData->nVal;
1,576,271✔
2938
      break;
1,576,271✔
2939
    case HAS_NULL:
328,775✔
2940
      colData->numOfNull = colData->nVal;
328,775✔
2941
      break;
328,775✔
2942
    case HAS_VALUE:
14,652,751✔
2943
      colData->numOfValue = colData->nVal;
14,652,751✔
2944
      break;
14,652,751✔
2945
    default:
1,082,103✔
2946
      for (int32_t i = 0; i < colData->nVal; i++) {
342,071,647✔
2947
        uint8_t bitValue = tColDataGetBitValue(colData, i);
340,992,199✔
2948
        if (bitValue == 0) {
340,989,544✔
2949
          colData->numOfNone++;
4,286,603✔
2950
        } else if (bitValue == 1) {
336,702,941✔
2951
          colData->numOfNull++;
24,889,322✔
2952
        } else {
2953
          colData->numOfValue++;
311,813,619✔
2954
        }
2955
      }
2956
  }
2957
  tBufferDestroy(&local);
2958
  return 0;
17,637,245✔
2959
}
2960

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

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

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

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

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

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

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

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

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

3117
_exit:
28✔
3118
  return code;
606✔
3119
}
3120

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3379
  return code;
294✔
3380
}
3381

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

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

3393
  return code;
60✔
3394
}
3395

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

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

3408
  return code;
60✔
3409
}
3410

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

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

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

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

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

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

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

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

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

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

3473
  return TSDB_CODE_SUCCESS;
17✔
3474
}
3475

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3636
_exit:
72✔
3637
  return 0;
180✔
3638
}
3639

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

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

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

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

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

3679
  return n;
2,166✔
3680
}
3681

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

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

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

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

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

3723
  return n;
2,210✔
3724
}
3725

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

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

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

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

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

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

3772
  int8_t val;
3773
  if (HAS_VALUE == pColData->flag) {
7,591✔
3774
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,334,382✔
3775
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,328,259✔
3776
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,328,259✔
3777
    }
3778
  } else {
3779
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
3780
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
3781
        case 0:
236,335✔
3782
        case 1:
3783
          (*numOfNull)++;
236,335✔
3784
          break;
236,335✔
3785
        case 2:
4,496,966✔
3786
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,496,966✔
3787
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,496,966✔
3788
          break;
4,496,966✔
3789
        default:
×
3790
          break;
×
3791
      }
3792
    }
3793
  }
3794
}
7,591✔
3795

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

3803
  int8_t val;
3804
  if (HAS_VALUE == pColData->flag) {
7,627✔
3805
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,451,958✔
3806
      val = ((int8_t *)pColData->pData)[iVal];
4,445,799✔
3807
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,445,799✔
3808
    }
3809
  } else {
3810
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
3811
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
3812
        case 0:
235,432✔
3813
        case 1:
3814
          (*numOfNull)++;
235,432✔
3815
          break;
235,432✔
3816
        case 2:
4,497,869✔
3817
          val = ((int8_t *)pColData->pData)[iVal];
4,497,869✔
3818
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,497,869✔
3819
          break;
4,497,869✔
3820
        default:
×
3821
          break;
×
3822
      }
3823
    }
3824
  }
3825
}
7,627✔
3826

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

3834
  int16_t val;
3835
  if (HAS_VALUE == pColData->flag) {
7,627✔
3836
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,453,002✔
3837
      val = ((int16_t *)pColData->pData)[iVal];
4,446,843✔
3838
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,446,843✔
3839
    }
3840
  } else {
3841
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
3842
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
3843
        case 0:
237,013✔
3844
        case 1:
3845
          (*numOfNull)++;
237,013✔
3846
          break;
237,013✔
3847
        case 2:
4,496,288✔
3848
          val = ((int16_t *)pColData->pData)[iVal];
4,496,288✔
3849
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,496,288✔
3850
          break;
4,496,288✔
3851
        default:
×
3852
          break;
×
3853
      }
3854
    }
3855
  }
3856
}
7,627✔
3857

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

3865
  int32_t val;
3866
  if (HAS_VALUE == pColData->flag) {
259,606✔
3867
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
799,536,837✔
3868
      val = ((int32_t *)pColData->pData)[iVal];
799,308,271✔
3869
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
799,308,271✔
3870
    }
3871
  } else {
3872
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
87,280,403✔
3873
      switch (tColDataGetBitValue(pColData, iVal)) {
87,249,910!
3874
        case 0:
5,184,584✔
3875
        case 1:
3876
          (*numOfNull)++;
5,184,584✔
3877
          break;
5,184,584✔
3878
        case 2:
82,099,704✔
3879
          val = ((int32_t *)pColData->pData)[iVal];
82,099,704✔
3880
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
82,099,704✔
3881
          break;
82,099,704✔
3882
        default:
×
3883
          break;
×
3884
      }
3885
    }
3886
  }
3887
}
259,059✔
3888

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

3896
  int64_t val;
3897
  if (HAS_VALUE == pColData->flag) {
79,907✔
3898
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
204,418,678✔
3899
      val = ((int64_t *)pColData->pData)[iVal];
204,344,928✔
3900
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
204,344,928✔
3901
    }
3902
  } else {
3903
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
20,570,855✔
3904
      switch (tColDataGetBitValue(pColData, iVal)) {
20,568,178!
3905
        case 0:
1,914,636✔
3906
        case 1:
3907
          (*numOfNull)++;
1,914,636✔
3908
          break;
1,914,636✔
3909
        case 2:
18,658,538✔
3910
          val = ((int64_t *)pColData->pData)[iVal];
18,658,538✔
3911
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
18,658,538✔
3912
          break;
18,658,538✔
3913
        default:
×
3914
          break;
×
3915
      }
3916
    }
3917
  }
3918
}
76,427✔
3919

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

3927
  float val;
3928
  if (HAS_VALUE == pColData->flag) {
218,879✔
3929
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
868,760,172✔
3930
      val = ((float *)pColData->pData)[iVal];
868,542,762✔
3931
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
868,542,762✔
3932
    }
3933
  } else {
3934
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,875✔
3935
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,406!
3936
        case 0:
236,928✔
3937
        case 1:
3938
          (*numOfNull)++;
236,928✔
3939
          break;
236,928✔
3940
        case 2:
4,496,478✔
3941
          val = ((float *)pColData->pData)[iVal];
4,496,478✔
3942
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,496,478✔
3943
          break;
4,496,478✔
3944
        default:
×
3945
          break;
×
3946
      }
3947
    }
3948
  }
3949
}
218,879✔
3950

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

3958
  double val;
3959
  if (HAS_VALUE == pColData->flag) {
8,215✔
3960
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,559,598✔
3961
      val = ((double *)pColData->pData)[iVal];
9,552,851✔
3962
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
9,552,851✔
3963
    }
3964
  } else {
3965
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
3966
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
3967
        case 0:
236,284✔
3968
        case 1:
3969
          (*numOfNull)++;
236,284✔
3970
          break;
236,284✔
3971
        case 2:
4,497,017✔
3972
          val = ((double *)pColData->pData)[iVal];
4,497,017✔
3973
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,497,017✔
3974
          break;
4,497,017✔
3975
        default:
×
3976
          break;
×
3977
      }
3978
    }
3979
  }
3980
}
8,215✔
3981

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

3989
  uint8_t val;
3990
  if (HAS_VALUE == pColData->flag) {
4,712✔
3991
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,569,897✔
3992
      val = ((uint8_t *)pColData->pData)[iVal];
3,566,653✔
3993
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,566,653✔
3994
    }
3995
  } else {
3996
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
3997
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
3998
        case 0:
235,635✔
3999
        case 1:
4000
          (*numOfNull)++;
235,635✔
4001
          break;
235,635✔
4002
        case 2:
4,497,666✔
4003
          val = ((uint8_t *)pColData->pData)[iVal];
4,497,666✔
4004
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,497,666✔
4005
          break;
4,497,666✔
4006
        default:
×
4007
          break;
×
4008
      }
4009
    }
4010
  }
4011
}
4,712✔
4012

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

4020
  uint16_t val;
4021
  if (HAS_VALUE == pColData->flag) {
4,712✔
4022
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,569,888✔
4023
      val = ((uint16_t *)pColData->pData)[iVal];
3,566,644✔
4024
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,566,644✔
4025
    }
4026
  } else {
4027
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
4028
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
4029
        case 0:
237,173✔
4030
        case 1:
4031
          (*numOfNull)++;
237,173✔
4032
          break;
237,173✔
4033
        case 2:
4,496,128✔
4034
          val = ((uint16_t *)pColData->pData)[iVal];
4,496,128✔
4035
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,496,128✔
4036
          break;
4,496,128✔
4037
        default:
×
4038
          break;
×
4039
      }
4040
    }
4041
  }
4042
}
4,712✔
4043

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

4051
  uint32_t val;
4052
  if (HAS_VALUE == pColData->flag) {
4,712✔
4053
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,569,877✔
4054
      val = ((uint32_t *)pColData->pData)[iVal];
3,566,633✔
4055
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,566,633✔
4056
    }
4057
  } else {
4058
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
4059
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
4060
        case 0:
236,738✔
4061
        case 1:
4062
          (*numOfNull)++;
236,738✔
4063
          break;
236,738✔
4064
        case 2:
4,496,563✔
4065
          val = ((uint32_t *)pColData->pData)[iVal];
4,496,563✔
4066
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,496,563✔
4067
          break;
4,496,563✔
4068
        default:
×
4069
          break;
×
4070
      }
4071
    }
4072
  }
4073
}
4,712✔
4074

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

4082
  uint64_t val;
4083
  if (HAS_VALUE == pColData->flag) {
4,712✔
4084
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,569,899✔
4085
      val = ((uint64_t *)pColData->pData)[iVal];
3,566,655✔
4086
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,566,655✔
4087
    }
4088
  } else {
4089
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,734,769✔
4090
      switch (tColDataGetBitValue(pColData, iVal)) {
4,733,301!
4091
        case 0:
238,286✔
4092
        case 1:
4093
          (*numOfNull)++;
238,286✔
4094
          break;
238,286✔
4095
        case 2:
4,495,015✔
4096
          val = ((uint64_t *)pColData->pData)[iVal];
4,495,015✔
4097
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,495,015✔
4098
          break;
4,495,015✔
4099
        default:
×
4100
          break;
×
4101
      }
4102
    }
4103
  }
4104
}
4,712✔
4105

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

4113
  switch (pColData->flag) {
23,882!
4114
    case HAS_NONE:
×
4115
    case HAS_NULL:
4116
    case (HAS_NONE | HAS_NULL):
4117
      *numOfNull = pColData->nVal;
×
4118
      break;
×
4119
    case HAS_VALUE:
20,946✔
4120
      *numOfNull = 0;
20,946✔
4121
      break;
20,946✔
4122
    case (HAS_VALUE | HAS_NULL):
2,936✔
4123
    case (HAS_VALUE | HAS_NONE):
4124
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,469,538✔
4125
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
9,466,602✔
4126
          (*numOfNull)++;
474,934✔
4127
        }
4128
      }
4129
      break;
2,936✔
4130
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4131
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4132
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4133
          (*numOfNull)++;
×
4134
        }
4135
      }
4136
      break;
×
4137
    default:
×
4138
      break;
×
4139
  }
4140
}
23,882✔
4141

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

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

4175
void tValueColumnDestroy(SValueColumn *valCol) {
43,600,878✔
4176
  valCol->type = TSDB_DATA_TYPE_NULL;
43,600,878✔
4177
  valCol->numOfValues = 0;
43,600,878✔
4178
  tBufferDestroy(&valCol->data);
43,600,878✔
4179
  tBufferDestroy(&valCol->offsets);
43,601,046✔
4180
  return;
43,600,963✔
4181
}
4182

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

4191
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
980,619✔
4192
  int32_t code;
4193

4194
  if (valCol->numOfValues == 0) {
980,619✔
4195
    valCol->type = value->type;
14,999✔
4196
  }
4197

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

4202
  if (IS_VAR_DATA_TYPE(value->type)) {
980,619!
4203
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
19,166!
4204
      return code;
×
4205
    }
4206
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
19,166!
4207
      return code;
×
4208
    }
4209
  } else {
4210
    code = tBufferPut(&valCol->data, &value->val, tDataTypes[value->type].bytes);
971,036✔
4211
    if (code) return code;
971,037!
4212
  }
4213
  valCol->numOfValues++;
980,620✔
4214

4215
  return 0;
980,620✔
4216
}
4217

4218
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
238,115,953✔
4219
  int32_t code;
4220

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

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

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

4237
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
12!
4238
        offsets[i] += bytesAdded;
×
4239
      }
4240
    }
4241
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
25,510✔
4242
  } else {
4243
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, &value->val,
238,150,643✔
4244
                        tDataTypes[valCol->type].bytes);
238,116,278✔
4245
  }
4246
  return 0;
4247
}
4248

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

4254
  value->type = valCol->type;
482,192,026✔
4255
  if (IS_VAR_DATA_TYPE(value->type)) {
482,192,026!
4256
    int32_t       offset, nextOffset;
4257
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
510,338✔
4258

4259
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
510,338!
4260
    if (idx == valCol->numOfValues - 1) {
543,891✔
4261
      nextOffset = tBufferGetSize(&valCol->data);
248,451✔
4262
    } else {
4263
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
295,440✔
4264
    }
4265
    value->nData = nextOffset - offset;
543,356✔
4266
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
543,356✔
4267
  } else {
4268
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
481,681,688✔
4269
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, &value->val));
963,363,376!
4270
  }
4271
  return 0;
482,225,044✔
4272
}
4273

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

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

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

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

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

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

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

4308
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
14,999✔
4309
  if (code) return code;
14,997!
4310

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

4314
  return 0;
14,997✔
4315
}
4316

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

4321
  tValueColumnClear(valCol);
775,538✔
4322
  valCol->type = info->type;
775,522✔
4323
  // offset
4324
  if (IS_VAR_DATA_TYPE(valCol->type)) {
1,132,942!
4325
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
357,002✔
4326

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

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

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

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

4355
  return 0;
775,861✔
4356
}
4357

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

4362
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
29,994!
4363
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
29,994!
4364
  if ((code = tBufferPutI8(buffer, info->type))) return code;
29,994!
4365
  if (IS_VAR_DATA_TYPE(info->type)) {
14,997!
4366
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
7,968!
4367
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
7,968!
4368
  }
4369
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
29,994!
4370
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
29,994!
4371

4372
  return 0;
14,997✔
4373
}
4374

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

4379
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
775,925!
4380
  if (fmtVer == 0) {
775,846!
4381
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
775,880!
4382
    if ((code = tBufferGetI8(reader, &info->type))) return code;
775,681!
4383
    if (IS_VAR_DATA_TYPE(info->type)) {
775,492!
4384
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
357,039!
4385
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
357,231!
4386
    } else {
4387
      info->offsetOriginalSize = 0;
418,453✔
4388
      info->offsetCompressedSize = 0;
418,453✔
4389
    }
4390
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
775,649!
4391
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
775,478!
4392
  } else {
4393
    return TSDB_CODE_INVALID_PARA;
×
4394
  }
4395

4396
  return 0;
775,351✔
4397
}
4398

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

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

4413
  if (info->cmprAlg == NO_COMPRESSION) {
6,727,557!
4414
    (void)memcpy(output, input, info->originalSize);
×
4415
    info->compressedSize = info->originalSize;
×
4416
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
8,264,706✔
4417
    SBuffer local;
4418

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

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

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

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

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

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

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

4482
  return 0;
6,731,600✔
4483
}
4484

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

4493
  if (!(outputSize >= info->originalSize)) {
66,580,416!
4494
    return TSDB_CODE_INVALID_PARA;
×
4495
  }
4496

4497
  if (info->cmprAlg == NO_COMPRESSION) {
66,580,416!
4498
    if (!(info->compressedSize == info->originalSize)) {
×
4499
      return TSDB_CODE_INVALID_PARA;
×
4500
    }
4501
    (void)memcpy(output, input, info->compressedSize);
×
4502
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
93,952,997!
4503
    SBuffer local;
4504

4505
    tBufferInit(&local);
4506
    if (buffer == NULL) {
27,341,531!
4507
      buffer = &local;
×
4508
    }
4509

4510
    if (info->cmprAlg == TWO_STAGE_COMP) {
27,341,531!
4511
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
27,373,065✔
4512
      if (code) {
27,373,796!
4513
        tBufferDestroy(&local);
4514
        return code;
×
4515
      }
4516
    }
4517

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

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

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

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

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

4575
  return 0;
66,613,165✔
4576
}
4577

4578
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
6,727,944✔
4579
  int32_t code;
4580

4581
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
6,727,944✔
4582
  if (code) return code;
6,727,939!
4583

4584
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
6,727,939✔
4585
  if (code) return code;
6,728,941!
4586

4587
  output->size += info->compressedSize;
6,728,941✔
4588
  return 0;
6,728,941✔
4589
}
4590

4591
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
27,369,029✔
4592
  int32_t code;
4593

4594
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
27,369,029✔
4595
  if (code) return code;
27,369,539!
4596

4597
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
27,369,539✔
4598
  if (code) return code;
27,371,992!
4599

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

© 2025 Coveralls, Inc