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

taosdata / TDengine / #3542

27 Nov 2024 02:52AM UTC coverage: 60.819% (+0.04%) from 60.776%
#3542

push

travis-ci

web-flow
Merge pull request #28931 from taosdata/enh/jdbc-demo-3.0

update jdbc demo, and version history

120305 of 252779 branches covered (47.59%)

Branch coverage included in aggregate %.

201010 of 275538 relevant lines covered (72.95%)

19989893.51 hits per line

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

65.36
/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) {
580,295,662✔
65
  int32_t n = 0;
580,295,662✔
66
  n += tPutI8(p ? p + n : p, index->type);
580,295,662✔
67
  n += tPutU32v(p ? p + n : p, index->offset);
580,295,662✔
68
  return n;
580,295,662✔
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,755,898✔
113
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
33,755,898✔
114
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
33,755,898✔
115
  return 0;
33,755,898✔
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;
205,937,341✔
123
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
205,937,341✔
124
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
205,937,341!
125
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
205,937,341✔
126
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
205,937,341✔
127
    sinfo->numOfPKs++;
205,937,341✔
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
594,066,076✔
133
                           + colVal->value.nData;               // value
594,066,076✔
134

135
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
594,066,076✔
136
                            + tPutU32v(NULL, colVal->value.nData)  // size
594,066,076✔
137
                            + colVal->value.nData;                 // value
594,066,076✔
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,202,577,305✔
146
  int32_t  code = 0;
1,202,577,305✔
147
  int32_t  colValIndex = 1;
1,202,577,305✔
148
  int32_t  numOfColVals = TARRAY_SIZE(colVals);
1,202,577,305✔
149
  SColVal *colValArray = (SColVal *)TARRAY_DATA(colVals);
1,202,577,305✔
150

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

161
  *sinfo = (SRowBuildScanInfo){
1,202,577,305✔
162
      .tupleFixedSize = schema->flen,
1,202,577,305✔
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,511,952✔
183
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {
2,147,483,647!
184
          if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
2,147,483,647!
185
        }
186

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

198
  if (sinfo->numOfNone) {
1,202,577,227✔
199
    sinfo->flag |= HAS_NONE;
383,328,568✔
200
  }
201
  if (sinfo->numOfNull) {
1,202,577,227✔
202
    sinfo->flag |= HAS_NULL;
22,758,399✔
203
  }
204
  if (sinfo->numOfValue) {
1,202,577,227✔
205
    sinfo->flag |= HAS_VALUE;
1,146,719,469✔
206
  }
207

208
  // Tuple
209
  sinfo->tupleFlag = sinfo->flag;
1,202,577,227✔
210
  switch (sinfo->flag) {
1,202,577,227!
211
    case HAS_NONE:
65,648,593✔
212
    case HAS_NULL:
213
      sinfo->tupleBitmapSize = 0;
65,648,593✔
214
      sinfo->tupleFixedSize = 0;
65,648,593✔
215
      break;
65,648,593✔
216
    case HAS_VALUE:
812,372,069✔
217
      sinfo->tupleBitmapSize = 0;
812,372,069✔
218
      sinfo->tupleFixedSize = schema->flen;
812,372,069✔
219
      break;
812,372,069✔
220
    case (HAS_NONE | HAS_NULL):
24,520✔
221
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,520✔
222
      sinfo->tupleFixedSize = 0;
24,520✔
223
      break;
24,520✔
224
    case (HAS_NONE | HAS_VALUE):
335,482,398✔
225
    case (HAS_NULL | HAS_VALUE):
226
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
335,482,398✔
227
      sinfo->tupleFixedSize = schema->flen;
335,482,398✔
228
      break;
335,482,398✔
229
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
2,464,041✔
230
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
2,464,041✔
231
      sinfo->tupleFixedSize = schema->flen;
2,464,041✔
232
      break;
2,464,041✔
233
  }
234
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,404,539,658✔
235
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
204,922,428✔
236
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
204,922,428✔
237
  }
238
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,199,617,230✔
239
                        + sinfo->tuplePKSize      // primary keys
1,199,617,230✔
240
                        + sinfo->tupleBitmapSize  // bitmap
1,199,617,230✔
241
                        + sinfo->tupleFixedSize   // fixed part
1,199,617,230✔
242
                        + sinfo->tupleVarSize;    // var part
1,199,617,230✔
243

244
  // Key-Value
245
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,199,617,230!
246
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,209,347,878✔
247
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,209,347,878✔
248
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
249
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
5,047,435✔
250
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
5,047,435✔
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,400,462,150✔
256
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
202,241,457✔
257
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
202,241,457✔
258
  }
259
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,198,220,693✔
260
                     + sinfo->kvPKSize        // primary keys
1,198,220,693✔
261
                     + sinfo->kvIndexSize     // index array
1,198,220,693✔
262
                     + sinfo->kvPayloadSize;  // payload
1,198,220,693✔
263

264
_exit:
1,198,220,771✔
265
  return code;
1,198,220,771✔
266
}
267

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

272
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
886,651,244✔
273
  if (*ppRow == NULL) {
895,882,707✔
274
    return terrno;
61,797✔
275
  }
276
  (*ppRow)->flag = sinfo->tupleFlag;
895,820,910✔
277
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
895,820,910✔
278
  (*ppRow)->sver = schema->version;
895,820,910✔
279
  (*ppRow)->len = sinfo->tupleRowSize;
895,820,910✔
280
  (*ppRow)->ts = colValArray[0].value.val;
895,820,910✔
281

282
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
895,820,910✔
283
    return 0;
66,281,432✔
284
  }
285

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

291
  // primary keys
292
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,032,090,826✔
293
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
205,033,380✔
294
  }
295

296
  // bitmap + fixed + varlen
297
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
827,057,446✔
298
  int32_t colValIndex = 1;
827,057,446✔
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;
146,210,425✔
312
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
146,210,425✔
313
            if (colValArray[colValIndex].value.nData) {
146,210,425!
314
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
150,951,680✔
315
              varlen += colValArray[colValIndex].value.nData;
150,951,680✔
316
            }
317
          } else {
318
            (void)memcpy(fixed + schema->columns[i].offset, &colValArray[colValIndex].value.val,
2,147,483,647✔
319
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
320
          }
321
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
15,365,579!
322
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
18,389,885!
323
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
479,190!
325
        }
326

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

338
  return 0;
827,057,446✔
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) {
11,477,537!
345
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,803,346✔
346
  } else {
347
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
3,674,191✔
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) {
324,186,536✔
353
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
324,186,536✔
354

355
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
324,186,536✔
356
  if (*ppRow == NULL) {
324,284,445✔
357
    return terrno;
30,972✔
358
  }
359
  (*ppRow)->flag = sinfo->kvFlag;
324,253,473✔
360
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
324,253,473✔
361
  (*ppRow)->sver = schema->version;
324,253,473✔
362
  (*ppRow)->len = sinfo->kvRowSize;
324,253,473✔
363
  (*ppRow)->ts = colValArray[0].value.val;
324,253,473✔
364

365
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
324,253,473!
366
    return TSDB_CODE_INVALID_PARA;
×
367
  }
368

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

374
  // primary keys
375
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
325,806,286✔
376
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
1,552,821✔
377
  }
378

379
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
324,253,465✔
380
  int32_t colValIndex = 1;
324,253,465✔
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);
442,292,098✔
392
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
442,292,098✔
393
            if (colValArray[colValIndex].value.nData > 0) {
442,292,098!
394
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
449,974,814✔
395
                           colValArray[colValIndex].value.nData);
449,974,814✔
396
            }
397
            payloadSize += colValArray[colValIndex].value.nData;
442,292,098✔
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,097,147✔
406
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
30,194,294✔
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;
324,253,465✔
420
}
421

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

426
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,201,740,989✔
427
  if (code) return code;
1,211,986,137✔
428

429
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,211,986,059✔
430
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
888,859,578✔
431
  } else {
432
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
323,126,481✔
433
  }
434
  return code;
1,215,973,525✔
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,
15✔
454
                          SArray *rowArray) {
455
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
15!
456
    return TSDB_CODE_INVALID_PARA;
×
457
  }
458

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

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

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

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

475
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
2,385✔
476
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
2,265!
477
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
478
      } else {
479
        SValue value = {
2,265✔
480
            .type = infos[iInfo].type,
2,265✔
481
        };
482
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
2,265!
483
          value.nData = infos[iInfo].bind->length[iRow];
308✔
484
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
308!
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;
308✔
489
        } else {
490
          (void)memcpy(&value.val, (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
1,957✔
491
                       infos[iInfo].bind->buffer_length);
1,957✔
492
        }
493
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
2,265✔
494
      }
495
      if (taosArrayPush(colValArray, &colVal) == NULL) {
2,230!
496
        code = terrno;
×
497
        goto _exit;
×
498
      }
499
    }
500

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

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

512
_exit:
15✔
513
  taosArrayDestroy(colValArray);
15✔
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;
38,812,053✔
525
    pColVal->value.type = pTColumn->type;
38,812,053✔
526
    pColVal->flag = CV_FLAG_VALUE;
38,812,053✔
527
    (void)memcpy(&pColVal->value.val, &pRow->ts, sizeof(TSKEY));
38,812,053✔
528
    return 0;
38,812,053✔
529
  }
530

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

536
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
537
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,120,459✔
538
    return 0;
1,120,459✔
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);
42,190,332✔
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) {
58,098,645!
554
      pv = pIdx->idx + (pIdx->nCol << 1);
83,572,346✔
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) {
348,664,259!
567
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
348,786,934✔
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);
87,130,765✔
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);
714,978,814!
585
            if (pColVal->value.nData > 0) {
714,978,814!
586
              pColVal->value.pData = pData;
803,121,978✔
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;
812,816,645✔
605
    uint8_t *fixed;
606
    uint8_t *varlen;
607
    uint8_t  bit;
608

609
    if (pRow->flag == HAS_VALUE) {
812,816,645✔
610
      fixed = bitmap;
707,882,276✔
611
      bit = BIT_FLG_VALUE;
707,882,276✔
612
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
104,934,369!
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;
104,934,369✔
617
      bit = GET_BIT1(bitmap, iCol - 1);
104,934,369✔
618

619
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
104,934,369✔
620
        if (bit) bit++;
21,519✔
621
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
104,912,850!
622
        bit++;
141,981,999✔
623
      }
624
    }
625
    varlen = fixed + pTSchema->flen;
812,816,645✔
626

627
    if (bit == BIT_FLG_NONE) {
812,816,645✔
628
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,631✔
629
      return 0;
7,631✔
630
    } else if (bit == BIT_FLG_NULL) {
812,809,014✔
631
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
24,129,348✔
632
      return 0;
24,129,348✔
633
    }
634

635
    pColVal->cid = pTColumn->colId;
788,679,666✔
636
    pColVal->value.type = pTColumn->type;
788,679,666✔
637
    pColVal->flag = CV_FLAG_VALUE;
788,679,666✔
638
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
788,679,666!
639
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
36,798,168✔
640
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
73,596,336!
641
    } else {
642
      (void)memcpy(&pColVal->value.val, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
751,881,498✔
643
    }
644
  }
645

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

649
void tRowDestroy(SRow *pRow) {
830,181,317✔
650
  if (pRow) taosMemoryFree(pRow);
830,181,317!
651
}
830,293,031✔
652

653
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
264,698,736✔
654
  SRowKey key1, key2;
655
  tRowGetKey(*(SRow **)p1, &key1);
264,698,736✔
656
  tRowGetKey(*(SRow **)p2, &key2);
248,484,395✔
657
  return tRowKeyCompare(&key1, &key2);
264,448,321✔
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,845✔
738
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
49,845✔
739
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
49,842✔
740
  if (code != TSDB_CODE_SUCCESS) {
49,841!
741
    uError("taosArrayMSort failed caused by %d", code);
×
742
  }
743
  return code;
49,841✔
744
}
745

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

749
  int32_t iStart = 0;
49,913✔
750
  while (iStart < aRowP->size) {
38,561,127!
751
    SRowKey key1;
752
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
38,566,999✔
753

754
    tRowGetKey(row1, &key1);
38,737,365✔
755

756
    int32_t iEnd = iStart + 1;
38,512,938✔
757
    while (iEnd < aRowP->size) {
38,496,761✔
758
      SRowKey key2;
759
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
38,480,750✔
760
      tRowGetKey(row2, &key2);
38,687,485✔
761

762
      if (tRowKeyCompare(&key1, &key2) != 0) break;
38,479,026!
763

764
      iEnd++;
×
765
    }
766

767
    if (iEnd - iStart > 1) {
38,511,214✔
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++;
38,511,214✔
774
  }
775

776
  return code;
×
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,093✔
800
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
209,093!
801

802
  int32_t code = 0;
209,093✔
803

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

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

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

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

822
  if (pRow->flag >> 4) {
208,945✔
823
    pIter->iCol = 0;
188,287✔
824
    pIter->pIdx = (SKVIdx *)data;
188,287✔
825
    if (pRow->flag & KV_FLG_LIT) {
188,287!
826
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
188,291✔
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,658!
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:
4✔
853
        break;
4✔
854
    }
855
  }
856

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

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

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

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

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

890
  if (pIter->pRow->flag == HAS_NONE) {
4,565,741✔
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,565,710✔
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,564,314✔
901
    if (pIter->iCol < pIter->pIdx->nCol) {
4,502,470✔
902
      uint8_t *pData;
903

904
      if (pIter->pRow->flag & KV_FLG_LIT) {
2,627,219!
905
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
2,627,224✔
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,627,219✔
914

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

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

935
        pIter->iCol++;
2,627,211✔
936
        goto _exit;
2,627,211✔
937
      } else if (TABS(cid) > pTColumn->colId) {
8!
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,875,251✔
946
      goto _exit;
1,875,251✔
947
    }
948
  } else {  // Tuple
949
    uint8_t bv = BIT_FLG_VALUE;
61,844✔
950
    if (pIter->pb) {
61,844✔
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,757✔
979
    pIter->cv.value.type = pTColumn->type;
61,757✔
980
    pIter->cv.flag = CV_FLAG_VALUE;
61,757✔
981
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
69,261!
982
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
7,504✔
983
      pData += tGetU32v(pData, &pIter->cv.value.nData);
7,504!
984
      if (pIter->cv.value.nData > 0) {
7,504!
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,757✔
993
  }
994

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

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

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

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

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

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

1020
  while (pColData) {
607,124✔
1021
    if (pTColumn) {
440,549!
1022
      if (pTColumn->colId == pColData->cid) {  // NULL
440,549✔
1023
        if (flag == 0) {
440,528✔
1024
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
440,464✔
1025
        } else {
1026
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
64✔
1027
        }
1028
        if (code) goto _exit;
440,560!
1029

1030
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
440,560✔
1031
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
440,560✔
1032
      } else if (pTColumn->colId > pColData->cid) {  // NONE
21!
1033
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1034
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1035
      } else {
1036
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
21!
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:
166,575✔
1045
  return code;
166,575✔
1046
}
1047
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
1,028,694,025✔
1048
                                      int32_t flag) {
1049
  int32_t code = 0;
1,028,694,025✔
1050

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

1056
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
1,028,694,025✔
1057
  SPrimaryKeyIndex index;
1058
  uint8_t         *data = pRow->data;
1,028,694,025✔
1059
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,465,335,936✔
1060
    data += tGetPrimaryKeyIndex(data, &index);
436,787,364✔
1061
  }
1062

1063
  switch (pRow->flag) {
1,028,548,572!
1064
    case HAS_VALUE:
1,017,888,126✔
1065
      pf = data;  // TODO: fix here
1,017,888,126✔
1066
      pv = pf + pTSchema->flen;
1,017,888,126✔
1067
      break;
1,017,888,126✔
1068
    case (HAS_NULL | HAS_NONE):
1,296✔
1069
      pb = data;
1,296✔
1070
      break;
1,296✔
1071
    case (HAS_VALUE | HAS_NONE):
11,146,831✔
1072
    case (HAS_VALUE | HAS_NULL):
1073
      pb = data;
11,146,831✔
1074
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
11,146,831✔
1075
      pv = pf + pTSchema->flen;
11,146,831✔
1076
      break;
11,146,831✔
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,903,461!
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,239✔
1099
              bv = GET_BIT1(pb, iTColumn - 1);
199,239✔
1100
              if (bv) bv++;
199,239✔
1101
              break;
199,239✔
1102
            case (HAS_VALUE | HAS_NULL):
75,680,309✔
1103
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
75,680,309✔
1104
              break;
75,680,309✔
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,905,468✔
1113
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,386!
1114
              goto _exit;
×
1115
            goto _continue;
43,389✔
1116
          } else if (bv == BIT_FLG_NULL) {
75,862,082✔
1117
            if (flag == 0) {
14,976,533✔
1118
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
14,804,389✔
1119
            } else {
1120
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
172,144✔
1121
            }
1122
            if (code) goto _exit;
14,976,445!
1123
            goto _continue;
14,976,445✔
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);
62,472,627!
1129
          uint32_t nData;
1130
          pData += tGetU32v(pData, &nData);
62,472,627✔
1131
          if (flag == 0) {
62,472,627!
1132
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
67,194,121✔
1133
          } else {
1134
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1135
          }
1136
          if (code) goto _exit;
68,536,640!
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,
15,967,572✔
1143
                                                                          TYPE_BYTES[pColData->type], flag > 0);
15,967,572✔
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,104!
1159
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
420,103✔
1160
    }
1161
  }
1162

1163
_exit:
1,034,576,855✔
1164
  return code;
1,034,576,855✔
1165
}
1166
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
6,634,082✔
1167
  int32_t code = 0;
6,634,082✔
1168

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

1176
  // primary keys
1177
  uint8_t         *data = pRow->data;
6,634,082✔
1178
  SPrimaryKeyIndex index;
1179
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
6,882,110✔
1180
    data += tGetPrimaryKeyIndex(data, &index);
248,077✔
1181
  }
1182

1183
  SKVIdx *pKVIdx = (SKVIdx *)data;
6,634,033✔
1184
  if (pRow->flag & KV_FLG_LIT) {
6,634,033✔
1185
    pv = pKVIdx->idx + pKVIdx->nCol;
6,567,740✔
1186
  } else if (pRow->flag & KV_FLG_MID) {
66,293!
1187
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
70,288✔
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,583,736✔
1195
    if (pTColumn) {
100,980,693✔
1196
      if (pTColumn->colId == pColData->cid) {
100,581,430✔
1197
        while (iCol < pKVIdx->nCol) {
100,522,226✔
1198
          uint8_t *pData;
1199
          if (pRow->flag & KV_FLG_LIT) {
69,443,419✔
1200
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
67,480,656✔
1201
          } else if (pRow->flag & KV_FLG_MID) {
1,962,763!
1202
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,962,871✔
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,443,527✔
1211

1212
          if (TABS(cid) == pTColumn->colId) {
69,443,527✔
1213
            if (cid < 0) {
36,552,754✔
1214
              if (flag == 0) {
8,742,335✔
1215
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
8,739,048✔
1216
              } else {
1217
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
3,287✔
1218
              }
1219
              if (code) goto _exit;
8,281,848!
1220
            } else {
1221
              uint32_t nData;
1222
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
27,810,419!
1223
                pData += tGetU32v(pData, &nData);
6,169,925✔
1224
              } else {
1225
                nData = 0;
21,640,494✔
1226
              }
1227
              if (flag == 0) {
27,810,419!
1228
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
27,878,086✔
1229
              } else {
1230
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1231
              }
1232
              if (code) goto _exit;
28,236,293!
1233
            }
1234
            iCol++;
36,518,141✔
1235
            goto _continue;
36,518,141✔
1236
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
32,890,773✔
1237
            break;
32,507,297✔
1238
          } else {
1239
            iCol++;
383,476✔
1240
          }
1241
        }
1242

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

1245
      _continue:
63,585,648✔
1246
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
100,103,789✔
1247
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
100,103,789✔
1248
      } else if (pTColumn->colId > pColData->cid) {
442,680!
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;
442,680✔
1253
      }
1254
    } else {
1255
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,263!
1256
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,239✔
1257
    }
1258
  }
1259

1260
_exit:
6,603,043✔
1261
  return code;
6,603,043✔
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) {
1,035,643,205✔
1268
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,035,643,205!
1269
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
1,035,643,205!
1270

1271
  if (pRow->flag == HAS_NONE) {
1,035,643,205✔
1272
    return tRowNoneUpsertColData(aColData, nColData, flag);
10,803✔
1273
  } else if (pRow->flag == HAS_NULL) {
1,035,632,402✔
1274
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
166,544✔
1275
  } else if (pRow->flag >> 4) {  // KV row
1,035,465,858✔
1276
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
6,634,996✔
1277
  } else {  // TUPLE row
1278
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
1,028,830,862✔
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);
13,520,504✔
1304
    }
1305

1306
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
1307
      key->pks[i].pData = tdata;
3,240,139✔
1308
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
6,480,278!
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) {
50,141,063✔
1327
  switch (tv1->type) {
50,141,063!
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,126,997✔
1334
      T_COMPARE_SCALAR_VALUE(int32_t, &tv1->val, &tv2->val);
2,126,997✔
1335
    case TSDB_DATA_TYPE_BIGINT:
43,674,972✔
1336
    case TSDB_DATA_TYPE_TIMESTAMP:
1337
      T_COMPARE_SCALAR_VALUE(int64_t, &tv1->val, &tv2->val);
43,674,972✔
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,155,387✔
1347
      T_COMPARE_SCALAR_VALUE(uint32_t, &tv1->val, &tv2->val);
1,155,387✔
1348
    case TSDB_DATA_TYPE_UBIGINT:
1,169,156✔
1349
      T_COMPARE_SCALAR_VALUE(uint64_t, &tv1->val, &tv2->val);
1,169,156✔
1350
    case TSDB_DATA_TYPE_GEOMETRY:
2,008,941✔
1351
    case TSDB_DATA_TYPE_BINARY: {
1352
      int32_t ret = strncmp((const char *)tv1->pData, (const char *)tv2->pData, TMIN(tv1->nData, tv2->nData));
2,008,941✔
1353
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
2,008,941✔
1354
    }
1355
    case TSDB_DATA_TYPE_NCHAR: {
×
1356
      int32_t ret = tasoUcs4Compare((TdUcs4 *)tv1->pData, (TdUcs4 *)tv2->pData,
×
1357
                                    tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1358
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1359
    }
1360
    case TSDB_DATA_TYPE_VARBINARY: {
×
1361
      int32_t ret = memcmp(tv1->pData, tv2->pData, tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1362
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1363
    }
1364
    default:
5,610✔
1365
      break;
5,610✔
1366
  }
1367

1368
  return 0;
5,610✔
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) {
30,030,270!
1382
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
121,130,390!
1383
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
50,071,029✔
1384
      if (ret) return ret;
50,119,845!
1385
    }
1386
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1387
    return -1;
4✔
1388
  } else {
1389
    return 1;
×
1390
  }
1391

1392
  return 0;
71,059,361✔
1393
}
1394

1395
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
729,916,217✔
1396
  pDst->ts = pSrc->ts;
729,916,217✔
1397
  pDst->numOfPKs = pSrc->numOfPKs;
729,916,217✔
1398

1399
  if (pSrc->numOfPKs > 0) {
729,916,217✔
1400
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
62,953,781✔
1401
      SValue *pVal = &pDst->pks[i];
31,511,061✔
1402
      pVal->type = pSrc->pks[i].type;
31,511,061✔
1403

1404
      if (IS_NUMERIC_TYPE(pVal->type)) {
31,511,061!
1405
        pVal->val = pSrc->pks[i].val;
29,843,086✔
1406
      } else {
1407
        pVal->nData = pSrc->pks[i].nData;
1,667,975✔
1408
        (void)memcpy(pVal->pData, pSrc->pks[i].pData, pVal->nData);
1,667,975✔
1409
      }
1410
    }
1411
  }
1412
}
729,916,217✔
1413

1414
// STag ========================================
1415
static int tTagValCmprFn(const void *p1, const void *p2) {
142,488,242✔
1416
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
142,488,242✔
1417
    return -1;
48,739,321✔
1418
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
93,748,921✔
1419
    return 1;
52,185,609✔
1420
  }
1421

1422
  return 0;
41,563,312✔
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) {
890,614✔
1522
  int32_t n = 0;
890,614✔
1523

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

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

1534
  // value
1535
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
890,614!
1536
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
560,002✔
1537
  } else {
1538
    p = p ? p + n : p;
610,613✔
1539
    n += tDataTypes[pTagVal->type].bytes;
610,613✔
1540
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
610,613✔
1541
  }
1542

1543
  return n;
890,614✔
1544
}
1545
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
140,401,959✔
1546
  int32_t n = 0;
140,401,959✔
1547

1548
  // key
1549
  if (isJson) {
140,401,959✔
1550
    n += tGetCStr(p + n, &pTagVal->pKey);
27,402!
1551
  } else {
1552
    n += tGetI16v(p + n, &pTagVal->cid);
280,776,516!
1553
  }
1554

1555
  // type
1556
  n += tGetI8(p + n, &pTagVal->type);
140,401,959!
1557

1558
  // value
1559
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
140,401,959!
1560
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
48,583,802!
1561
  } else {
1562
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
116,110,058✔
1563
    n += tDataTypes[pTagVal->type].bytes;
116,110,058✔
1564
  }
1565

1566
  return n;
140,401,959✔
1567
}
1568

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

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

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

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

1593
  // get size
1594
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
604,963✔
1595
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
445,366✔
1596
  }
1597
  if (szTag <= INT8_MAX) {
159,597✔
1598
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
143,318✔
1599
  } else {
1600
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
16,279✔
1601
    isLarge = 1;
16,279✔
1602
  }
1603

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

1621
  if (isLarge) {
159,623✔
1622
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
16,278✔
1623
  } else {
1624
    p = (uint8_t *)&(*ppTag)->idx[nTag];
143,345✔
1625
  }
1626
  n = 0;
159,623✔
1627
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
605,011✔
1628
    if (isLarge) {
445,395✔
1629
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
104,154✔
1630
    } else {
1631
      (*ppTag)->idx[iTag] = n;
341,241✔
1632
    }
1633
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
445,395✔
1634
  }
1635
#ifdef TD_DEBUG_PRINT_TAG
1636
  debugPrintSTag(*ppTag, __func__, __LINE__);
1637
#endif
1638

1639
  return code;
159,616✔
1640

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

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

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

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

1660
  if (IS_VAR_DATA_TYPE(value->type)) {
15,913,313!
1661
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
4,605,544✔
1662
    if (data == NULL) {
4,609,930!
1663
      return NULL;
×
1664
    }
1665

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

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

1676
  return data;
15,917,699✔
1677
}
1678

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

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

1694
  if (isLarge) {
43,694,329✔
1695
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
35,912,325✔
1696
  } else {
1697
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,782,004✔
1698
  }
1699

1700
  pTagVal->type = TSDB_DATA_TYPE_NULL;
43,694,329✔
1701
  pTagVal->pData = NULL;
43,694,329✔
1702
  pTagVal->nData = 0;
43,694,329✔
1703
  while (lidx <= ridx) {
144,060,650✔
1704
    midx = (lidx + ridx) / 2;
141,130,251✔
1705
    if (isLarge) {
141,130,251✔
1706
      offset = ((int16_t *)pTag->idx)[midx];
117,399,450✔
1707
    } else {
1708
      offset = pTag->idx[midx];
23,730,801✔
1709
    }
1710

1711
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
141,130,251✔
1712
    if (isJson) {
141,945,498✔
1713
      c = tTagValJsonCmprFn(pTagVal, &tv);
10,408✔
1714
    } else {
1715
      c = tTagValCmprFn(pTagVal, &tv);
141,935,090✔
1716
    }
1717

1718
    if (c < 0) {
143,743,768✔
1719
      ridx = midx - 1;
48,227,047✔
1720
    } else if (c > 0) {
95,516,721✔
1721
      lidx = midx + 1;
52,139,274✔
1722
    } else {
1723
      (void)memcpy(pTagVal, &tv, sizeof(tv));
43,377,447✔
1724
      return true;
43,377,447✔
1725
    }
1726
  }
1727
  return false;
2,930,399✔
1728
}
1729

1730
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
738,060✔
1731
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,476,120✔
1732
}
1733

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

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

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

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

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

1768
  return code;
2,187✔
1769

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

1774
// STSchema ========================================
1775
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
15,951,011✔
1776
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
15,951,011✔
1777
  if (pTSchema == NULL) {
15,994,170✔
1778
    terrno = TSDB_CODE_OUT_OF_MEMORY;
25,244✔
1779
    return NULL;
×
1780
  }
1781

1782
  pTSchema->numOfCols = numOfCols;
15,968,926✔
1783
  pTSchema->version = version;
15,968,926✔
1784

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

1800
  // other columns
1801
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
218,897,088✔
1802
    SSchema  *pSchema = &aSchema[iCol];
202,928,162✔
1803
    STColumn *pTColumn = &pTSchema->columns[iCol];
202,928,162✔
1804

1805
    pTColumn->colId = pSchema->colId;
202,928,162✔
1806
    pTColumn->type = pSchema->type;
202,928,162✔
1807
    pTColumn->flags = pSchema->flags;
202,928,162✔
1808
    pTColumn->offset = pTSchema->flen;
202,928,162✔
1809

1810
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
202,928,162!
1811
      pTColumn->bytes = pSchema->bytes;
38,313,958✔
1812
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
38,313,958✔
1813
    } else {
1814
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
164,614,204✔
1815
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
164,614,204✔
1816
    }
1817

1818
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
202,928,162✔
1819
  }
1820

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

1825
  return pTSchema;
15,968,926✔
1826
}
1827

1828
static int32_t tTColumnCompare(const void *p1, const void *p2) {
11,210,008✔
1829
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
11,210,008✔
1830
    return -1;
1,728,705✔
1831
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
9,481,303✔
1832
    return 1;
6,697,305✔
1833
  }
1834

1835
  return 0;
2,783,998✔
1836
}
1837

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

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

1846
// SColData ========================================
1847
void tColDataDestroy(void *ph) {
23,925,014✔
1848
  if (ph) {
23,925,014!
1849
    SColData *pColData = (SColData *)ph;
23,925,259✔
1850

1851
    tFree(pColData->pBitMap);
23,925,259✔
1852
    tFree(pColData->aOffset);
23,925,385✔
1853
    tFree(pColData->pData);
23,925,441✔
1854
  }
1855
}
23,926,539✔
1856

1857
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
24,440,140✔
1858
  pColData->cid = cid;
24,440,140✔
1859
  pColData->type = type;
24,440,140✔
1860
  pColData->cflag = cflag;
24,440,140✔
1861
  tColDataClear(pColData);
24,440,140✔
1862
}
24,444,766✔
1863

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

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

1878
  tColDataClear(pColData);
850✔
1879
}
857✔
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);
130,267,125!
1886
    if (code) goto _exit;
142,776,938!
1887
    pColData->aOffset[pColData->nVal] = pColData->nData;
142,776,938✔
1888

1889
    if (nData) {
142,776,938!
1890
      code = tRealloc(&pColData->pData, pColData->nData + nData);
138,065,793!
1891
      if (code) goto _exit;
138,374,098!
1892
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
138,374,098✔
1893
      pColData->nData += nData;
138,374,098✔
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]);
45,914,913✔
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,523,930✔
1914
  pColData->flag = HAS_VALUE;
3,524,120✔
1915
  pColData->numOfValue++;
3,523,930✔
1916
  return tColDataPutValue(pColData, pData, nData);
3,524,586✔
1917
}
1918
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
246,265✔
1919
  pColData->flag = HAS_NONE;
246,265✔
1920
  pColData->numOfNone++;
246,265✔
1921
  pColData->nVal++;
246,265✔
1922
  return 0;
246,265✔
1923
}
1924
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
182,092✔
1925
  pColData->flag = HAS_NULL;
182,188✔
1926
  pColData->numOfNull++;
182,188✔
1927
  pColData->nVal++;
182,188✔
1928
  return 0;
182,092✔
1929
}
1930
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,412✔
1931
  int32_t code = 0;
1,412✔
1932

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

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

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

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

1957
  return tColDataPutValue(pColData, pData, nData);
1,417✔
1958
}
1959
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
84,701,432✔
1960
  pColData->nVal++;
84,701,432✔
1961
  pColData->numOfNone++;
84,701,432✔
1962
  return 0;
84,701,432✔
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,624✔
1981
  int32_t code = 0;
22,650✔
1982

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

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

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

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

2007
  return tColDataPutValue(pColData, pData, nData);
22,650✔
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,214,345✔
2026
  pColData->nVal++;
9,214,345✔
2027
  pColData->numOfNull++;
9,214,345✔
2028
  return 0;
9,214,345✔
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,377✔
2077
  int32_t code = 0;
9,377✔
2078

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

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

2086
  return code;
9,377✔
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) {
148,548✔
2093
  int32_t code = 0;
148,548✔
2094

2095
  pColData->flag |= HAS_NONE;
148,548✔
2096
  pColData->numOfNone++;
148,548✔
2097

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

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

2105
  return tColDataPutValue(pColData, NULL, 0);
148,591✔
2106
}
2107
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
286,933✔
2108
  int32_t code = 0;
293,150✔
2109

2110
  pColData->flag |= HAS_NULL;
293,150✔
2111
  pColData->numOfNull++;
293,150✔
2112

2113
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
293,150✔
2114
  code = tRealloc(&pColData->pBitMap, nBit);
292,846✔
2115
  if (code) return code;
293,167!
2116

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

2120
  return tColDataPutValue(pColData, NULL, 0);
293,164✔
2121
}
2122
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,347,747✔
2123
  int32_t code = 0;
1,349,748✔
2124

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

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

2131
  return tColDataPutValue(pColData, pData, nData);
1,352,184✔
2132
}
2133
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
14,120,149✔
2134
  int32_t code = 0;
14,120,149✔
2135

2136
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
14,120,149!
2137
  if (code) return code;
14,120,351!
2138

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

2142
  return tColDataPutValue(pColData, NULL, 0);
14,122,808✔
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,545!
2155
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
3,754,079!
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) {
373,643,645✔
2165
  int32_t code = 0;
373,811,129✔
2166

2167
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
373,810,729!
2168
  if (code) return code;
374,548,360!
2169
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
374,548,360!
2170
  pColData->numOfValue++;
374,548,360✔
2171

2172
  return tColDataPutValue(pColData, pData, nData);
375,166,132✔
2173
}
2174
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
28,927✔
2175
  int32_t code = 0;
28,927✔
2176

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

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

2184
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,903,060✔
2185
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
3,874,133✔
2186
  }
2187
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
28,927✔
2188

2189
  tFree(pColData->pBitMap);
28,927✔
2190
  pColData->pBitMap = pBitMap;
28,927✔
2191

2192
  return tColDataPutValue(pColData, NULL, 0);
28,926✔
2193
}
2194
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
24,659,453✔
2195
  int32_t code = 0;
24,837,158✔
2196

2197
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
24,833,562!
2198
  if (code) return code;
24,843,753!
2199
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
24,843,753✔
2200
  pColData->numOfNull++;
24,843,753✔
2201

2202
  return tColDataPutValue(pColData, NULL, 0);
24,852,767✔
2203
}
2204
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
659,030✔
2205
  int32_t code = 0;
659,030✔
2206

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

2212
  return tColDataPutValue(pColData, pData, nData);
659,030✔
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) {
563,923✔
2225
  int32_t code = 0;
563,923✔
2226

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

2232
  return tColDataPutValue(pColData, NULL, 0);
563,923✔
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) {
189✔
2277
  if (forward) {
189!
2278
    pColData->numOfNull--;
189✔
2279
    pColData->nVal--;
189✔
2280
    if (pColData->numOfNull) {
189✔
2281
      return tColDataAppendValue20(pColData, pData, nData);
8✔
2282
    } else {
2283
      pColData->flag = 0;
181✔
2284
      return tColDataAppendValue00(pColData, pData, nData);
181✔
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) {
45,451,873✔
2324
  if (forward) {  // VALUE ==> VALUE
45,451,873!
2325
    pColData->nVal--;
45,452,201✔
2326
    if (IS_VAR_DATA_TYPE(pColData->type)) {
45,452,201!
2327
      pColData->nData = pColData->aOffset[pColData->nVal];
1,175,095✔
2328
    } else {
2329
      pColData->nData -= TYPE_BYTES[pColData->type];
44,277,106✔
2330
    }
2331
    return tColDataPutValue(pColData, pData, nData);
45,478,233✔
2332
  }
2333
  return 0;
×
2334
}
2335
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,985✔
2336
  if (forward) {  // VALUE ==> NULL
5,985!
2337
    pColData->numOfValue--;
5,985✔
2338
    pColData->nVal--;
5,985✔
2339
    if (pColData->numOfValue) {
5,985✔
2340
      if (IS_VAR_DATA_TYPE(pColData->type)) {
5,913!
2341
        pColData->nData = pColData->aOffset[pColData->nVal];
1,147✔
2342
      } else {
2343
        pColData->nData -= TYPE_BYTES[pColData->type];
4,766✔
2344
      }
2345
      return tColDataAppendValue42(pColData, pData, nData);
5,913✔
2346
    } else {
2347
      pColData->flag = 0;
72✔
2348
      pColData->nData = 0;
72✔
2349
      return tColDataAppendValue02(pColData, pData, nData);
72✔
2350
    }
2351
  }
2352
  return 0;
×
2353
}
2354
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
43,863✔
2355
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
43,863✔
2356
    pColData->numOfNone--;
5,598✔
2357
    pColData->nVal--;
5,598✔
2358
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,598!
2359
      pColData->nData -= TYPE_BYTES[pColData->type];
4,478✔
2360
    }
2361
    if (pColData->numOfNone) {
5,598✔
2362
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2363
    } else {
2364
      pColData->flag = HAS_VALUE;
3,598✔
2365
      return tColDataAppendValue40(pColData, pData, nData);
3,599✔
2366
    }
2367
  } else if (forward) {  // VALUE ==> VALUE
38,265!
2368
    pColData->nVal--;
38,267✔
2369
    if (IS_VAR_DATA_TYPE(pColData->type)) {
38,267!
2370
      pColData->nData = pColData->aOffset[pColData->nVal];
5,470✔
2371
    } else {
2372
      pColData->nData -= TYPE_BYTES[pColData->type];
32,797✔
2373
    }
2374
    return tColDataPutValue(pColData, pData, nData);
38,272✔
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,313,101✔
2410
  if (forward) {
3,313,101!
2411
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
3,313,101✔
2412
      pColData->numOfNull--;
187,937✔
2413
      pColData->nVal--;
187,937✔
2414
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
187,937!
2415
        pColData->nData -= TYPE_BYTES[pColData->type];
157,259✔
2416
      }
2417
      if (pColData->numOfNull) {
187,937✔
2418
        return tColDataAppendValue60(pColData, pData, nData);
167,085✔
2419
      } else {
2420
        pColData->flag = HAS_VALUE;
20,853✔
2421
        return tColDataAppendValue40(pColData, pData, nData);
20,854✔
2422
      }
2423
    } else {  // VALUE ==> VALUE
2424
      pColData->nVal--;
3,125,164✔
2425
      if (IS_VAR_DATA_TYPE(pColData->type)) {
3,125,164!
2426
        pColData->nData = pColData->aOffset[pColData->nVal];
481,721✔
2427
      } else {
2428
        pColData->nData -= TYPE_BYTES[pColData->type];
2,643,443✔
2429
      }
2430
      return tColDataPutValue(pColData, pData, nData);
3,125,166✔
2431
    }
2432
  }
2433
  return 0;
×
2434
}
2435
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
197,263✔
2436
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
197,263!
2437
    pColData->numOfValue--;
174,127✔
2438
    pColData->nVal--;
174,127✔
2439
    if (pColData->numOfValue) {
174,127✔
2440
      if (IS_VAR_DATA_TYPE(pColData->type)) {
174,109!
2441
        pColData->nData = pColData->aOffset[pColData->nVal];
27,511✔
2442
      } else {
2443
        pColData->nData -= TYPE_BYTES[pColData->type];
146,598✔
2444
      }
2445
      return tColDataAppendValue62(pColData, pData, nData);
174,110✔
2446
    } else {
2447
      pColData->flag = HAS_NULL;
18✔
2448
      pColData->nData = 0;
18!
2449
      return tColDataAppendValue20(pColData, pData, nData);
18✔
2450
    }
2451
  }
2452
  return 0;
23,136✔
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,596✔
2506
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
3,596✔
2507
  if (bv == 0) {  // NONE ==> NULL
3,596!
2508
    pColData->numOfNone--;
3,596✔
2509
    pColData->nVal--;
3,596✔
2510
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,596!
2511
      pColData->nData -= TYPE_BYTES[pColData->type];
2,544✔
2512
    }
2513
    if (pColData->numOfNone) {
3,596!
2514
      return tColDataAppendValue72(pColData, pData, nData);
×
2515
    } else {
2516
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
114,448✔
2517
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
110,852✔
2518
      }
2519
      pColData->flag = (HAS_VALUE | HAS_NULL);
3,596!
2520
      return tColDataAppendValue62(pColData, pData, nData);
3,596✔
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,427✔
2544
  return 0;
12,427✔
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) {
31,895,149✔
2559
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
31,895,149!
2560
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
31,895,762!
2561

2562
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
31,895,762!
2563

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

2569
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
120,400,648✔
2570
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
120,400,648✔
2571
}
120,400,648✔
2572
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
3,647,232✔
2573
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
3,647,232✔
2574
}
3,647,232✔
2575
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
11,105✔
2576
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2577
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,105✔
2578
    case 0:
1,009✔
2579
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,009✔
2580
      break;
1,009✔
2581
    case 1:
10,095✔
2582
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,095✔
2583
      break;
10,095✔
2584
    default:
1✔
2585
      break;
1✔
2586
  }
2587
}
11,105✔
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) {
226,164,101!
2592
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
230,076,085✔
2593
    } else {
2594
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2595
    }
2596
    value.pData = pColData->pData + pColData->aOffset[iVal];
226,164,101✔
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
}
208,809,725✔
2603
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
6,876,441✔
2604
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2605
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
6,876,441!
2606
    case 0:
3,443,908✔
2607
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
3,443,908✔
2608
      break;
3,443,908✔
2609
    case 1:
3,498,418✔
2610
      tColDataGetValue4(pColData, iVal, pColVal);
2611
      break;
3,498,418✔
2612
    default:
×
2613
      break;
×
2614
  }
2615
}
6,876,441✔
2616
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
217,288,319✔
2617
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2618
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
217,288,319!
2619
    case 0:
12,593,872✔
2620
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
12,593,872✔
2621
      break;
12,593,872✔
2622
    case 1:
205,311,240✔
2623
      tColDataGetValue4(pColData, iVal, pColVal);
2624
      break;
205,311,240✔
2625
    default:
×
2626
      break;
×
2627
  }
2628
}
217,288,319✔
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) {
616,698,759✔
2660
  switch (pColData->flag) {
616,698,759!
2661
    case HAS_NONE:
×
2662
      return 0;
×
2663
    case HAS_NULL:
×
2664
      return 1;
×
2665
    case (HAS_NULL | HAS_NONE):
11,103✔
2666
      return GET_BIT1(pColData->pBitMap, iVal);
11,103✔
2667
    case HAS_VALUE:
×
2668
      return 2;
×
2669
    case (HAS_VALUE | HAS_NONE):
7,732,229✔
2670
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
7,732,229✔
2671
    case (HAS_VALUE | HAS_NULL):
608,786,398✔
2672
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
608,786,398✔
2673
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2674
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
2675
    default:
169,007✔
2676
      return 0;
169,007✔
2677
  }
2678
}
2679

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

2683
  *pColData = *pColDataFrom;
538✔
2684

2685
  // bitmap
2686
  switch (pColData->flag) {
538!
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:
494✔
2706
      pColData->pBitMap = NULL;
494✔
2707
      break;
494✔
2708
  }
2709

2710
  // offset
2711
  if (IS_VAR_DATA_TYPE(pColData->type) && (pColData->flag & HAS_VALUE)) {
538!
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;
417✔
2720
  }
2721

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

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

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

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

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

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

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

2760
  tBufferInit(&local);
2761
  if (assist == NULL) {
3,270,296!
2762
    assist = &local;
×
2763
  }
2764

2765
  // bitmap
2766
  if (colData->flag != HAS_VALUE) {
3,270,296✔
2767
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
438,075✔
2768
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
37,401✔
2769
    } else {
2770
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
400,674✔
2771
    }
2772

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

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

2785
    info->bitmapCompressedSize = cinfo.compressedSize;
438,135✔
2786
  }
2787

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

2793
  // offset
2794
  if (IS_VAR_DATA_TYPE(colData->type)) {
3,259,760!
2795
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
378,642✔
2796

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

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

2809
    info->offsetCompressedSize = cinfo.compressedSize;
378,696✔
2810
  }
2811

2812
  // data
2813
  if (colData->nData > 0) {
3,259,814!
2814
    info->dataOriginalSize = colData->nData;
3,259,866✔
2815

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

2822
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
3,259,866✔
2823
    if (code) {
3,260,129!
2824
      tBufferDestroy(&local);
2825
      return code;
×
2826
    }
2827

2828
    info->dataCompressedSize = cinfo.compressedSize;
3,260,129✔
2829
  }
2830

2831
  tBufferDestroy(&local);
2832
  return 0;
3,260,077✔
2833
}
2834

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

2840
  tBufferInit(&local);
2841
  if (assist == NULL) {
21,365,376!
2842
    assist = &local;
×
2843
  }
2844

2845
  tColDataClear(colData);
21,365,376✔
2846
  colData->cid = info->columnId;
21,364,350✔
2847
  colData->type = info->dataType;
21,364,350✔
2848
  colData->cflag = info->columnFlag;
21,364,350✔
2849
  colData->nVal = info->numOfData;
21,364,350✔
2850
  colData->flag = info->flag;
21,364,350✔
2851

2852
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
21,364,350✔
2853
    goto _exit;
3,112,257✔
2854
  }
2855

2856
  // bitmap
2857
  if (info->bitmapOriginalSize > 0) {
18,252,093✔
2858
    SCompressInfo cinfo = {
960,369✔
2859
        .dataType = TSDB_DATA_TYPE_TINYINT,
2860
        .cmprAlg = info->cmprAlg,
960,369✔
2861
        .originalSize = info->bitmapOriginalSize,
960,369✔
2862
        .compressedSize = info->bitmapCompressedSize,
960,369✔
2863
    };
2864

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

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

2877
    data += cinfo.compressedSize;
960,173✔
2878
  }
2879

2880
  if (info->flag == (HAS_NONE | HAS_NULL)) {
18,251,897✔
2881
    goto _exit;
600✔
2882
  }
2883

2884
  // offset
2885
  if (info->offsetOriginalSize > 0) {
18,251,297✔
2886
    SCompressInfo cinfo = {
2,866,743✔
2887
        .cmprAlg = info->cmprAlg,
2,866,743✔
2888
        .dataType = TSDB_DATA_TYPE_INT,
2889
        .originalSize = info->offsetOriginalSize,
2,866,743✔
2890
        .compressedSize = info->offsetCompressedSize,
2,866,743✔
2891
    };
2892

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

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

2905
    data += cinfo.compressedSize;
2,866,915✔
2906
  }
2907

2908
  // data
2909
  if (info->dataOriginalSize > 0) {
18,251,469✔
2910
    colData->nData = info->dataOriginalSize;
18,249,700✔
2911

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

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

2925
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
18,252,029✔
2926
    if (code) {
18,247,238!
2927
      tBufferDestroy(&local);
2928
      return code;
×
2929
    }
2930

2931
    data += cinfo.compressedSize;
18,247,238✔
2932
  }
2933

2934
_exit:
1,769✔
2935
  switch (colData->flag) {
21,361,864✔
2936
    case HAS_NONE:
2,785,458✔
2937
      colData->numOfNone = colData->nVal;
2,785,458✔
2938
      break;
2,785,458✔
2939
    case HAS_NULL:
328,738✔
2940
      colData->numOfNull = colData->nVal;
328,738✔
2941
      break;
328,738✔
2942
    case HAS_VALUE:
17,287,208✔
2943
      colData->numOfValue = colData->nVal;
17,287,208✔
2944
      break;
17,287,208✔
2945
    default:
960,460✔
2946
      for (int32_t i = 0; i < colData->nVal; i++) {
344,552,967✔
2947
        uint8_t bitValue = tColDataGetBitValue(colData, i);
343,596,890✔
2948
        if (bitValue == 0) {
343,592,507✔
2949
          colData->numOfNone++;
3,705,236✔
2950
        } else if (bitValue == 1) {
339,887,271✔
2951
          colData->numOfNull++;
25,121,691✔
2952
        } else {
2953
          colData->numOfValue++;
314,765,580✔
2954
        }
2955
      }
2956
  }
2957
  tBufferDestroy(&local);
2958
  return 0;
21,357,481✔
2959
}
2960

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

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

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

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

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

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

3049
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
614!
3050
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
94!
3051
      code = igeos();
×
3052
      if (code) {
×
3053
        return code;
×
3054
      }
3055
    }
3056
    for (int32_t i = 0; i < pBind->num; ++i) {
772✔
3057
      if (pBind->is_null && pBind->is_null[i]) {
685✔
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) {
676!
3065
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3066
      } else {
3067
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
676!
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](
676✔
3072
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
676✔
3073
      }
3074
    }
3075
  } else {  // fixed-length data type
3076
    bool allValue;
3077
    bool allNull;
3078
    if (pBind->is_null) {
520✔
3079
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
470✔
3080
      allNull = (same && pBind->is_null[0] != 0);
470✔
3081
      allValue = (same && pBind->is_null[0] == 0);
470✔
3082
    } else {
3083
      allNull = false;
50✔
3084
      allValue = true;
50✔
3085
    }
3086

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

3092
    if (allValue) {
516✔
3093
      // optimize (todo)
3094
      for (int32_t i = 0; i < pBind->num; ++i) {
4,381✔
3095
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
3,888✔
3096
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
3,888✔
3097
      }
3098
    } else if (allNull) {
28✔
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) {
105✔
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:
26✔
3118
  return code;
614✔
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,244✔
3412
  SColVal cv;
3413

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

3417
  for (int i = 1; i < nColData; i++) {
1,310!
3418
    if (aColData[i].cflag & COL_IS_KEY) {
1,311✔
3419
      tColDataGetValue4(&aColData[i], iRow, &cv);
66✔
3420
      key->pks[key->numOfPKs++] = cv.value;
66✔
3421
    } else {
3422
      break;
1,245✔
3423
    }
3424
  }
3425
}
1,244✔
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) {
448✔
3595
    SRowKey key;
3596
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
378✔
3597

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

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

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

3621
      int32_t c = tRowKeyCompare(&lastKey, &key);
384✔
3622
      if (c == 0) {
384!
3623
        doMerge = 1;
×
3624
        break;
×
3625
      }
3626
      lastKey = key;
384✔
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,229✔
3641
  int32_t n = 0;
2,229✔
3642

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

3648
  // bitmap
3649
  switch (pColData->flag) {
2,229!
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,141✔
3661
      break;
2,141✔
3662
  }
3663

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

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

3679
  return n;
2,229✔
3680
}
3681

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

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

3690
  // bitmap
3691
  switch (pColData->flag) {
2,224!
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,112✔
3703
      break;
2,112✔
3704
  }
3705

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

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

3723
  return n;
2,224✔
3724
}
3725

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

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

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

3748
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
2,220✔
3749
  if (version == 0) {
2,220!
3750
    return tGetColDataVersion0(pBuf, pColData);
×
3751
  } else if (version == 1) {
2,220!
3752
    return tGetColDataVersion1(pBuf, pColData);
2,224✔
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,605✔
3766
                                             int16_t *numOfNull) {
3767
  *sum = 0;
7,605✔
3768
  *max = 0;
7,605✔
3769
  *min = 1;
7,605✔
3770
  *numOfNull = 0;
7,605✔
3771

3772
  int8_t val;
3773
  if (HAS_VALUE == pColData->flag) {
7,605✔
3774
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,334,771✔
3775
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,328,632✔
3776
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,328,632✔
3777
    }
3778
  } else {
3779
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
3780
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
3781
        case 0:
236,352✔
3782
        case 1:
3783
          (*numOfNull)++;
236,352✔
3784
          break;
236,352✔
3785
        case 2:
4,500,885✔
3786
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,500,885✔
3787
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,500,885✔
3788
          break;
4,500,885✔
3789
        default:
×
3790
          break;
×
3791
      }
3792
    }
3793
  }
3794
}
7,605✔
3795

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

3803
  int8_t val;
3804
  if (HAS_VALUE == pColData->flag) {
7,641✔
3805
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,454,083✔
3806
      val = ((int8_t *)pColData->pData)[iVal];
4,447,908✔
3807
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,447,908✔
3808
    }
3809
  } else {
3810
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
3811
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
3812
        case 0:
236,889✔
3813
        case 1:
3814
          (*numOfNull)++;
236,889✔
3815
          break;
236,889✔
3816
        case 2:
4,500,348✔
3817
          val = ((int8_t *)pColData->pData)[iVal];
4,500,348✔
3818
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,500,348✔
3819
          break;
4,500,348✔
3820
        default:
×
3821
          break;
×
3822
      }
3823
    }
3824
  }
3825
}
7,641✔
3826

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

3834
  int16_t val;
3835
  if (HAS_VALUE == pColData->flag) {
7,641✔
3836
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,454,132✔
3837
      val = ((int16_t *)pColData->pData)[iVal];
4,447,957✔
3838
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,447,957✔
3839
    }
3840
  } else {
3841
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
3842
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
3843
        case 0:
236,798✔
3844
        case 1:
3845
          (*numOfNull)++;
236,798✔
3846
          break;
236,798✔
3847
        case 2:
4,500,439✔
3848
          val = ((int16_t *)pColData->pData)[iVal];
4,500,439✔
3849
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,500,439✔
3850
          break;
4,500,439✔
3851
        default:
×
3852
          break;
×
3853
      }
3854
    }
3855
  }
3856
}
7,641✔
3857

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

3865
  int32_t val;
3866
  if (HAS_VALUE == pColData->flag) {
397,065✔
3867
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
1,258,072,777✔
3868
      val = ((int32_t *)pColData->pData)[iVal];
1,257,706,939✔
3869
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
1,257,706,939✔
3870
    }
3871
  } else {
3872
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
87,424,366✔
3873
      switch (tColDataGetBitValue(pColData, iVal)) {
87,398,120!
3874
        case 0:
5,207,248✔
3875
        case 1:
3876
          (*numOfNull)++;
5,207,248✔
3877
          break;
5,207,248✔
3878
        case 2:
82,245,192✔
3879
          val = ((int32_t *)pColData->pData)[iVal];
82,245,192✔
3880
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
82,245,192✔
3881
          break;
82,245,192✔
3882
        default:
×
3883
          break;
×
3884
      }
3885
    }
3886
  }
3887
}
392,084✔
3888

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

3896
  int64_t val;
3897
  if (HAS_VALUE == pColData->flag) {
142,069✔
3898
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
406,712,978✔
3899
      val = ((int64_t *)pColData->pData)[iVal];
406,577,064✔
3900
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
406,577,064✔
3901
    }
3902
  } else {
3903
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
20,647,752✔
3904
      switch (tColDataGetBitValue(pColData, iVal)) {
20,642,036!
3905
        case 0:
1,917,180✔
3906
        case 1:
3907
          (*numOfNull)++;
1,917,180✔
3908
          break;
1,917,180✔
3909
        case 2:
18,727,756✔
3910
          val = ((int64_t *)pColData->pData)[iVal];
18,727,756✔
3911
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
18,727,756✔
3912
          break;
18,727,756✔
3913
        default:
×
3914
          break;
×
3915
      }
3916
    }
3917
  }
3918
}
141,630✔
3919

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

3927
  float val;
3928
  if (HAS_VALUE == pColData->flag) {
246,007✔
3929
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
979,560,809✔
3930
      val = ((float *)pColData->pData)[iVal];
979,316,268✔
3931
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
979,316,268✔
3932
    }
3933
  } else {
3934
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,808✔
3935
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,342!
3936
        case 0:
236,986✔
3937
        case 1:
3938
          (*numOfNull)++;
236,986✔
3939
          break;
236,986✔
3940
        case 2:
4,500,356✔
3941
          val = ((float *)pColData->pData)[iVal];
4,500,356✔
3942
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,500,356✔
3943
          break;
4,500,356✔
3944
        default:
×
3945
          break;
×
3946
      }
3947
    }
3948
  }
3949
}
246,007✔
3950

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

3958
  double val;
3959
  if (HAS_VALUE == pColData->flag) {
8,725✔
3960
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
11,188,855✔
3961
      val = ((double *)pColData->pData)[iVal];
11,181,596✔
3962
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
11,181,596✔
3963
    }
3964
  } else {
3965
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
3966
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
3967
        case 0:
235,590✔
3968
        case 1:
3969
          (*numOfNull)++;
235,590✔
3970
          break;
235,590✔
3971
        case 2:
4,501,647✔
3972
          val = ((double *)pColData->pData)[iVal];
4,501,647✔
3973
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,501,647✔
3974
          break;
4,501,647✔
3975
        default:
×
3976
          break;
×
3977
      }
3978
    }
3979
  }
3980
}
8,725✔
3981

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

3989
  uint8_t val;
3990
  if (HAS_VALUE == pColData->flag) {
4,726✔
3991
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,570,121✔
3992
      val = ((uint8_t *)pColData->pData)[iVal];
3,566,861✔
3993
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,566,861✔
3994
    }
3995
  } else {
3996
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
3997
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
3998
        case 0:
236,924✔
3999
        case 1:
4000
          (*numOfNull)++;
236,924✔
4001
          break;
236,924✔
4002
        case 2:
4,500,313✔
4003
          val = ((uint8_t *)pColData->pData)[iVal];
4,500,313✔
4004
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,500,313✔
4005
          break;
4,500,313✔
4006
        default:
×
4007
          break;
×
4008
      }
4009
    }
4010
  }
4011
}
4,726✔
4012

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

4020
  uint16_t val;
4021
  if (HAS_VALUE == pColData->flag) {
4,726✔
4022
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,570,121✔
4023
      val = ((uint16_t *)pColData->pData)[iVal];
3,566,861✔
4024
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,566,861✔
4025
    }
4026
  } else {
4027
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
4028
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
4029
        case 0:
236,529✔
4030
        case 1:
4031
          (*numOfNull)++;
236,529✔
4032
          break;
236,529✔
4033
        case 2:
4,500,708✔
4034
          val = ((uint16_t *)pColData->pData)[iVal];
4,500,708✔
4035
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,500,708✔
4036
          break;
4,500,708✔
4037
        default:
×
4038
          break;
×
4039
      }
4040
    }
4041
  }
4042
}
4,726✔
4043

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

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

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

4082
  uint64_t val;
4083
  if (HAS_VALUE == pColData->flag) {
4,726✔
4084
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,568,251✔
4085
      val = ((uint64_t *)pColData->pData)[iVal];
3,564,991✔
4086
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,564,991✔
4087
    }
4088
  } else {
4089
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,738,703✔
4090
      switch (tColDataGetBitValue(pColData, iVal)) {
4,737,237!
4091
        case 0:
237,264✔
4092
        case 1:
4093
          (*numOfNull)++;
237,264✔
4094
          break;
237,264✔
4095
        case 2:
4,499,973✔
4096
          val = ((uint64_t *)pColData->pData)[iVal];
4,499,973✔
4097
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,499,973✔
4098
          break;
4,499,973✔
4099
        default:
×
4100
          break;
×
4101
      }
4102
    }
4103
  }
4104
}
4,726✔
4105

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

4113
  switch (pColData->flag) {
24,885!
4114
    case HAS_NONE:
×
4115
    case HAS_NULL:
4116
    case (HAS_NONE | HAS_NULL):
4117
      *numOfNull = pColData->nVal;
×
4118
      break;
×
4119
    case HAS_VALUE:
21,953✔
4120
      *numOfNull = 0;
21,953✔
4121
      break;
21,953✔
4122
    case (HAS_VALUE | HAS_NULL):
2,932✔
4123
    case (HAS_VALUE | HAS_NONE):
4124
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,477,406✔
4125
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
9,474,474✔
4126
          (*numOfNull)++;
473,945✔
4127
        }
4128
      }
4129
      break;
2,932✔
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
}
24,885✔
4141

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

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

4175
void tValueColumnDestroy(SValueColumn *valCol) {
47,831,135✔
4176
  valCol->type = TSDB_DATA_TYPE_NULL;
47,831,135✔
4177
  valCol->numOfValues = 0;
47,831,135✔
4178
  tBufferDestroy(&valCol->data);
47,831,135✔
4179
  tBufferDestroy(&valCol->offsets);
47,831,141✔
4180
  return;
47,831,115✔
4181
}
4182

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

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

4194
  if (valCol->numOfValues == 0) {
1,773,547✔
4195
    valCol->type = value->type;
16,523✔
4196
  }
4197

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

4202
  if (IS_VAR_DATA_TYPE(value->type)) {
1,773,547!
4203
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
19,168!
4204
      return code;
×
4205
    }
4206
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
19,168!
4207
      return code;
×
4208
    }
4209
  } else {
4210
    code = tBufferPut(&valCol->data, &value->val, tDataTypes[value->type].bytes);
1,763,963✔
4211
    if (code) return code;
1,763,963!
4212
  }
4213
  valCol->numOfValues++;
1,773,547✔
4214

4215
  return 0;
1,773,547✔
4216
}
4217

4218
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
459,468,998✔
4219
  int32_t code;
4220

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

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

4231
    if (bytesAdded != 0) {
17,271✔
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);
17,271✔
4242
  } else {
4243
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, &value->val,
459,483,115✔
4244
                        tDataTypes[valCol->type].bytes);
459,491,190✔
4245
  }
4246
  return 0;
4247
}
4248

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

4254
  value->type = valCol->type;
922,826,028✔
4255
  if (IS_VAR_DATA_TYPE(value->type)) {
922,826,028!
4256
    int32_t       offset, nextOffset;
4257
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
727,928✔
4258

4259
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
727,928!
4260
    if (idx == valCol->numOfValues - 1) {
735,543✔
4261
      nextOffset = tBufferGetSize(&valCol->data);
210,600✔
4262
    } else {
4263
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
524,943✔
4264
    }
4265
    value->nData = nextOffset - offset;
735,177✔
4266
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
735,177✔
4267
  } else {
4268
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
922,098,100✔
4269
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, &value->val));
1,844,196,200!
4270
  }
4271
  return 0;
922,833,277✔
4272
}
4273

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

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

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

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

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

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

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

4308
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
16,525✔
4309
  if (code) return code;
16,526!
4310

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

4314
  return 0;
16,526✔
4315
}
4316

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

4321
  tValueColumnClear(valCol);
772,266✔
4322
  valCol->type = info->type;
772,343✔
4323
  // offset
4324
  if (IS_VAR_DATA_TYPE(valCol->type)) {
1,023,996!
4325
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
251,464✔
4326

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

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

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

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

4355
  return 0;
772,639✔
4356
}
4357

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

4362
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
33,050!
4363
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
33,050!
4364
  if ((code = tBufferPutI8(buffer, info->type))) return code;
33,050!
4365
  if (IS_VAR_DATA_TYPE(info->type)) {
16,525!
4366
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
6,584!
4367
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
6,584!
4368
  }
4369
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
33,050!
4370
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
33,050!
4371

4372
  return 0;
16,525✔
4373
}
4374

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

4379
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
772,416!
4380
  if (fmtVer == 0) {
772,360!
4381
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
772,388!
4382
    if ((code = tBufferGetI8(reader, &info->type))) return code;
772,230!
4383
    if (IS_VAR_DATA_TYPE(info->type)) {
772,144!
4384
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
251,432!
4385
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
251,497!
4386
    } else {
4387
      info->offsetOriginalSize = 0;
520,712✔
4388
      info->offsetCompressedSize = 0;
520,712✔
4389
    }
4390
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
772,221!
4391
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
772,265!
4392
  } else {
4393
    return TSDB_CODE_INVALID_PARA;
×
4394
  }
4395

4396
  return 0;
772,185✔
4397
}
4398

4399
int32_t tCompressData(void          *input,       // input
7,601,262✔
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;
7,601,262!
4409
  if (!(outputSize >= extraSizeNeeded)) {
7,601,262!
4410
    return TSDB_CODE_INVALID_PARA;
×
4411
  }
4412

4413
  if (info->cmprAlg == NO_COMPRESSION) {
7,601,262!
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) {
9,320,891✔
4417
    SBuffer local;
4418

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

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

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

4447
    tBufferDestroy(&local);
4448
  } else {
4449
    DEFINE_VAR(info->cmprAlg)
5,883,981✔
4450
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
5,883,981!
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,883,981!
4459
      buffer = &local;
×
4460
    }
4461
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
5,883,981✔
4462

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

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

4482
  return 0;
7,604,755✔
4483
}
4484

4485
int32_t tDecompressData(void                *input,       // input
73,264,732✔
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)) {
73,264,732!
4494
    return TSDB_CODE_INVALID_PARA;
×
4495
  }
4496

4497
  if (info->cmprAlg == NO_COMPRESSION) {
73,264,732!
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) {
103,292,066!
4503
    SBuffer local;
4504

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

4510
    if (info->cmprAlg == TWO_STAGE_COMP) {
30,007,786!
4511
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
30,031,456✔
4512
      if (code) {
30,033,189!
4513
        tBufferDestroy(&local);
4514
        return code;
×
4515
      }
4516
    }
4517

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

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

4545
    tBufferInit(&local);
4546
    if (buffer == NULL) {
43,256,946!
4547
      buffer = &local;
×
4548
    }
4549
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
43,256,946✔
4550
    if (code) {
43,258,073!
4551
      return code;
×
4552
    }
4553

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

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

4575
  return 0;
73,281,107✔
4576
}
4577

4578
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
7,601,750✔
4579
  int32_t code;
4580

4581
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
7,601,750✔
4582
  if (code) return code;
7,601,758!
4583

4584
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
7,601,758✔
4585
  if (code) return code;
7,602,265!
4586

4587
  output->size += info->compressedSize;
7,602,265✔
4588
  return 0;
7,602,265✔
4589
}
4590

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

4594
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
30,023,583✔
4595
  if (code) return code;
30,026,846!
4596

4597
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
30,026,846✔
4598
  if (code) return code;
30,025,957!
4599

4600
  output->size += info->originalSize;
30,025,957✔
4601
  return 0;
30,025,957✔
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