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

taosdata / TDengine / #3530

16 Nov 2024 07:44AM UTC coverage: 60.219% (-0.7%) from 60.888%
#3530

push

travis-ci

web-flow
Update 03-ad.md

118417 of 252124 branches covered (46.97%)

Branch coverage included in aggregate %.

198982 of 274951 relevant lines covered (72.37%)

6072359.98 hits per line

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

64.87
/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) {
547,446✔
65
  int32_t n = 0;
547,446✔
66
  n += tPutI8(p ? p + n : p, index->type);
547,446✔
67
  n += tPutU32v(p ? p + n : p, index->offset);
547,446✔
68
  return n;
547,446✔
69
}
70

71
static int32_t tGetPrimaryKeyIndex(uint8_t *p, SPrimaryKeyIndex *index) {
18,155,641✔
72
  int32_t n = 0;
18,155,641✔
73
  n += tGetI8(p + n, &index->type);
18,155,641!
74
  n += tGetU32v(p + n, &index->offset);
18,155,641!
75
  return n;
18,155,641✔
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++;
640,232,599✔
107
  return 0;
640,232,599✔
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++;
27,636,932✔
113
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
27,636,932✔
114
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
27,636,932✔
115
  return 0;
27,636,932✔
116
}
117

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

121
  if (isPK) {
970,908,193✔
122
    sinfo->tupleIndices[sinfo->numOfPKs].type = colVal->value.type;
182,482✔
123
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
182,482✔
124
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
182,482!
125
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
182,482✔
126
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
182,482✔
127
    sinfo->numOfPKs++;
182,482✔
128
  }
129

130
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
970,908,193✔
131
  if (IS_VAR_DATA_TYPE(colVal->value.type)) {
970,908,193!
132
    sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)  // size
167,342,246✔
133
                           + colVal->value.nData;               // value
167,342,246✔
134

135
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
167,342,246✔
136
                            + tPutU32v(NULL, colVal->value.nData)  // size
167,342,246✔
137
                            + colVal->value.nData;                 // value
167,342,246✔
138
  } else {
139
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)              // colId
803,565,947✔
140
                            + tDataTypes[colVal->value.type].bytes;  // value
803,565,947✔
141
  }
142
  sinfo->numOfValue++;
970,908,193✔
143
}
970,908,193✔
144

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

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

161
  *sinfo = (SRowBuildScanInfo){
214,322,046✔
162
      .tupleFixedSize = schema->flen,
214,322,046✔
163
  };
164

165
  // loop scan
166
  for (int32_t i = 1; i < schema->numOfCols; i++) {
1,845,394,820✔
167
    for (;;) {
168
      if (colValIndex >= numOfColVals) {
1,631,882,676✔
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) {
1,631,882,596✔
174
        if (!(colValArray[colValIndex].value.type == schema->columns[i].type)) {
1,631,072,748!
175
          code = TSDB_CODE_INVALID_PARA;
×
176
          goto _exit;
×
177
        }
178

179
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {
1,631,072,748✔
180
          tRowBuildScanAddValue(sinfo, &colValArray[colValIndex], schema->columns + i);
970,908,193✔
181
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {
660,164,555✔
182
          if ((code = tRowBuildScanAddNull(sinfo, schema->columns + i))) goto _exit;
55,274,020✔
183
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {
632,527,545!
184
          if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
1,280,464,990!
185
        }
186

187
        colValIndex++;
1,631,072,670✔
188
        break;
1,631,072,670✔
189
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {
809,848✔
190
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
48!
191
        break;
24✔
192
      } else {  // skip useless value
193
        colValIndex++;
809,824✔
194
      }
195
    }
196
  }
197

198
  if (sinfo->numOfNone) {
214,321,968✔
199
    sinfo->flag |= HAS_NONE;
72,041,063✔
200
  }
201
  if (sinfo->numOfNull) {
214,321,968✔
202
    sinfo->flag |= HAS_NULL;
16,853,895✔
203
  }
204
  if (sinfo->numOfValue) {
214,321,968✔
205
    sinfo->flag |= HAS_VALUE;
154,938,359✔
206
  }
207

208
  // Tuple
209
  sinfo->tupleFlag = sinfo->flag;
214,321,968✔
210
  switch (sinfo->flag) {
214,321,968!
211
    case HAS_NONE:
59,658,329✔
212
    case HAS_NULL:
213
      sinfo->tupleBitmapSize = 0;
59,658,329✔
214
      sinfo->tupleFixedSize = 0;
59,658,329✔
215
      break;
59,658,329✔
216
    case HAS_VALUE:
128,449,045✔
217
      sinfo->tupleBitmapSize = 0;
128,449,045✔
218
      sinfo->tupleFixedSize = schema->flen;
128,449,045✔
219
      break;
128,449,045✔
220
    case (HAS_NONE | HAS_NULL):
24,268✔
221
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,268✔
222
      sinfo->tupleFixedSize = 0;
24,268✔
223
      break;
24,268✔
224
    case (HAS_NONE | HAS_VALUE):
24,323,321✔
225
    case (HAS_NULL | HAS_VALUE):
226
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,323,321✔
227
      sinfo->tupleFixedSize = schema->flen;
24,323,321✔
228
      break;
24,323,321✔
229
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
2,462,001✔
230
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
2,462,001✔
231
      sinfo->tupleFixedSize = schema->flen;
2,462,001✔
232
      break;
2,462,001✔
233
  }
234
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
214,504,450✔
235
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
182,482✔
236
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
182,482✔
237
  }
238
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
214,321,968✔
239
                        + sinfo->tuplePKSize      // primary keys
214,321,968✔
240
                        + sinfo->tupleBitmapSize  // bitmap
214,321,968✔
241
                        + sinfo->tupleFixedSize   // fixed part
214,321,968✔
242
                        + sinfo->tupleVarSize;    // var part
214,321,968✔
243

244
  // Key-Value
245
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
214,321,968✔
246
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
209,337,647✔
247
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
209,337,647✔
248
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
4,984,321!
249
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
5,392,404✔
250
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
5,392,404✔
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++) {
214,504,450✔
256
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
182,482✔
257
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
182,482✔
258
  }
259
  sinfo->kvRowSize = sizeof(SRow)             // SRow
214,321,968✔
260
                     + sinfo->kvPKSize        // primary keys
214,321,968✔
261
                     + sinfo->kvIndexSize     // index array
214,321,968✔
262
                     + sinfo->kvPayloadSize;  // payload
214,321,968✔
263

264
_exit:
214,322,046✔
265
  return code;
214,322,046✔
266
}
267

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

272
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
195,898,135✔
273
  if (*ppRow == NULL) {
199,096,284✔
274
    return terrno;
154,895✔
275
  }
276
  (*ppRow)->flag = sinfo->tupleFlag;
198,941,389✔
277
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
198,941,389✔
278
  (*ppRow)->sver = schema->version;
198,941,389✔
279
  (*ppRow)->len = sinfo->tupleRowSize;
198,941,389✔
280
  (*ppRow)->ts = colValArray[0].value.val;
198,941,389✔
281

282
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
198,941,389✔
283
    return 0;
61,939,416✔
284
  }
285

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

291
  // primary keys
292
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
137,104,298✔
293
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
102,325✔
294
  }
295

296
  // bitmap + fixed + varlen
297
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
137,001,973✔
298
  int32_t colValIndex = 1;
137,001,973✔
299
  for (int32_t i = 1; i < schema->numOfCols; i++) {
1,060,545,875✔
300
    for (;;) {
301
      if (colValIndex >= numOfColVals) {  // NONE
923,592,195✔
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) {
923,592,179✔
307
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
923,543,884✔
308
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_VALUE);
910,772,384!
309

310
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
910,772,384!
311
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
149,569,001✔
312
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
149,569,001✔
313
            if (colValArray[colValIndex].value.nData) {
149,569,001!
314
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
150,841,962✔
315
              varlen += colValArray[colValIndex].value.nData;
150,841,962✔
316
            }
317
          } else {
318
            (void)memcpy(fixed + schema->columns[i].offset, &colValArray[colValIndex].value.val,
761,203,383✔
319
                         tDataTypes[schema->columns[i].type].bytes);
761,203,383✔
320
          }
321
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
12,771,500✔
322
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
12,599,518!
323
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
171,982!
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
467,151!
325
        }
326

327
        colValIndex++;
923,543,884✔
328
        break;
923,543,884✔
329
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
48,295✔
330
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
2!
331
        break;
2✔
332
      } else {
333
        colValIndex++;
48,293✔
334
      }
335
    }
336
  }
337

338
  return 0;
137,001,973✔
339
}
340

341
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
342
  if (flag & KV_FLG_LIT) {
82,383,935✔
343
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
74,688,350✔
344
  } else if (flag & KV_FLG_MID) {
7,695,585!
345
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,691,165✔
346
  } else {
347
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
4,420✔
348
  }
349
  indices->nCol++;
82,383,935✔
350
}
82,383,935✔
351

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

355
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
18,681,578✔
356
  if (*ppRow == NULL) {
18,906,163!
357
    return terrno;
×
358
  }
359
  (*ppRow)->flag = sinfo->kvFlag;
18,926,089✔
360
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
18,926,089✔
361
  (*ppRow)->sver = schema->version;
18,926,089✔
362
  (*ppRow)->len = sinfo->kvRowSize;
18,926,089✔
363
  (*ppRow)->ts = colValArray[0].value.val;
18,926,089✔
364

365
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
18,926,089!
366
    return TSDB_CODE_INVALID_PARA;
×
367
  }
368

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

374
  // primary keys
375
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
19,006,246✔
376
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
80,157✔
377
  }
378

379
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
18,926,089✔
380
  int32_t colValIndex = 1;
18,926,089✔
381
  for (int32_t i = 1; i < schema->numOfCols; i++) {
206,000,869✔
382
    for (;;) {
383
      if (colValIndex >= numOfColVals) {  // NONE
187,059,460✔
384
        break;
64✔
385
      }
386

387
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
187,059,396!
388
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
187,074,694✔
389
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
67,615,878✔
390
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
67,615,878!
391
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
18,780,210✔
392
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
18,780,210✔
393
            if (colValArray[colValIndex].value.nData > 0) {
18,780,210✔
394
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
18,749,277✔
395
                           colValArray[colValIndex].value.nData);
18,749,277✔
396
            }
397
            payloadSize += colValArray[colValIndex].value.nData;
18,780,210✔
398
          } else {
399
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
48,835,668✔
400
            (void)memcpy(payload + payloadSize, &colValArray[colValIndex].value.val,
48,835,668✔
401
                         tDataTypes[schema->columns[i].type].bytes);
48,835,668✔
402
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
48,835,668✔
403
          }
404
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
119,458,816✔
405
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
14,768,057✔
406
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
29,536,114✔
407
        }
408

409
        colValIndex++;
187,074,694✔
410
        break;
187,074,694✔
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;
18,926,089✔
420
}
421

422
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
214,436,802✔
423
  int32_t           code;
424
  SRowBuildScanInfo sinfo;
425

426
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
214,436,802✔
427
  if (code) return code;
214,772,071✔
428

429
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
214,771,993✔
430
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
196,143,041✔
431
  } else {
432
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
18,628,952✔
433
  }
434
  return code;
217,075,507✔
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++) {
174✔
473
    taosArrayClear(colValArray);
158✔
474

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

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

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

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

517
int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
1,135,221,203✔
518
  if (!(iCol < pTSchema->numOfCols)) return TSDB_CODE_INVALID_PARA;
1,135,221,203!
519
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,135,221,203!
520

521
  STColumn *pTColumn = pTSchema->columns + iCol;
1,135,221,203✔
522

523
  if (iCol == 0) {
1,135,221,203✔
524
    pColVal->cid = pTColumn->colId;
26,861,338✔
525
    pColVal->value.type = pTColumn->type;
26,861,338✔
526
    pColVal->flag = CV_FLAG_VALUE;
26,861,338✔
527
    (void)memcpy(&pColVal->value.val, &pRow->ts, sizeof(TSKEY));
26,861,338✔
528
    return 0;
26,861,338✔
529
  }
530

531
  if (pRow->flag == HAS_NONE) {
1,108,359,865✔
532
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
228,004✔
533
    return 0;
228,004✔
534
  }
535

536
  if (pRow->flag == HAS_NULL) {
1,108,131,861✔
537
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,158,408✔
538
    return 0;
1,158,408✔
539
  }
540

541
  SPrimaryKeyIndex index;
542
  uint8_t         *data = pRow->data;
1,106,973,453✔
543
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,116,951,099✔
544
    data += tGetPrimaryKeyIndex(data, &index);
10,027,826✔
545
  }
546

547
  if (pRow->flag >> 4) {  // KV Row
1,106,923,273✔
548
    SKVIdx  *pIdx = (SKVIdx *)data;
346,897,541✔
549
    uint8_t *pv = NULL;
346,897,541✔
550

551
    if (pRow->flag & KV_FLG_LIT) {
346,897,541✔
552
      pv = pIdx->idx + pIdx->nCol;
277,717,103✔
553
    } else if (pRow->flag & KV_FLG_MID) {
69,180,438✔
554
      pv = pIdx->idx + (pIdx->nCol << 1);
69,034,883✔
555
    } else {
556
      pv = pIdx->idx + (pIdx->nCol << 2);
145,555✔
557
    }
558

559
    int16_t lidx = 0;
346,897,541✔
560
    int16_t ridx = pIdx->nCol - 1;
346,897,541✔
561
    while (lidx <= ridx) {
1,146,637,662✔
562
      int16_t  mid = (lidx + ridx) >> 1;
1,055,765,213✔
563
      uint8_t *pData = NULL;
1,055,765,213✔
564
      if (pRow->flag & KV_FLG_LIT) {
1,055,765,213✔
565
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
766,736,226✔
566
      } else if (pRow->flag & KV_FLG_MID) {
289,028,987!
567
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
289,076,758✔
568
      } else {
569
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
570
      }
571

572
      int16_t cid;
573
      pData += tGetI16v(pData, &cid);
1,055,765,213✔
574

575
      if (TABS(cid) == pTColumn->colId) {
1,055,765,213✔
576
        if (cid < 0) {
256,025,092✔
577
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
83,726,134✔
578
        } else {
579
          pColVal->cid = pTColumn->colId;
172,298,958✔
580
          pColVal->value.type = pTColumn->type;
172,298,958✔
581
          pColVal->flag = CV_FLAG_VALUE;
172,298,958✔
582

583
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
172,298,958!
584
            pData += tGetU32v(pData, &pColVal->value.nData);
25,769,320!
585
            if (pColVal->value.nData > 0) {
25,769,320!
586
              pColVal->value.pData = pData;
28,346,623✔
587
            } else {
588
              pColVal->value.pData = NULL;
×
589
            }
590
          } else {
591
            (void)memcpy(&pColVal->value.val, pData, pTColumn->bytes);
146,529,638✔
592
          }
593
        }
594
        return 0;
256,025,092✔
595
      } else if (TABS(cid) < pTColumn->colId) {
799,740,121✔
596
        lidx = mid + 1;
401,770,316✔
597
      } else {
598
        ridx = mid - 1;
397,969,805✔
599
      }
600
    }
601

602
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
90,872,449✔
603
  } else {  // Tuple Row
604
    uint8_t *bitmap = data;
760,025,732✔
605
    uint8_t *fixed;
606
    uint8_t *varlen;
607
    uint8_t  bit;
608

609
    if (pRow->flag == HAS_VALUE) {
760,025,732✔
610
      fixed = bitmap;
654,598,064✔
611
      bit = BIT_FLG_VALUE;
654,598,064✔
612
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
105,427,668!
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;
105,427,668✔
617
      bit = GET_BIT1(bitmap, iCol - 1);
105,427,668✔
618

619
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
105,427,668✔
620
        if (bit) bit++;
21,504✔
621
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
105,406,164!
622
        bit++;
137,211,022✔
623
      }
624
    }
625
    varlen = fixed + pTSchema->flen;
760,025,732✔
626

627
    if (bit == BIT_FLG_NONE) {
760,025,732✔
628
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,626✔
629
      return 0;
7,626✔
630
    } else if (bit == BIT_FLG_NULL) {
760,018,106✔
631
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
23,779,709✔
632
      return 0;
23,779,709✔
633
    }
634

635
    pColVal->cid = pTColumn->colId;
736,238,397✔
636
    pColVal->value.type = pTColumn->type;
736,238,397✔
637
    pColVal->flag = CV_FLAG_VALUE;
736,238,397✔
638
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
736,238,397!
639
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
45,167,383✔
640
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
90,334,766!
641
    } else {
642
      (void)memcpy(&pColVal->value.val, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
691,071,014✔
643
    }
644
  }
645

646
  return 0;
827,110,846✔
647
}
648

649
void tRowDestroy(SRow *pRow) {
133,314,117✔
650
  if (pRow) taosMemoryFree(pRow);
133,314,117!
651
}
133,307,953✔
652

653
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
49,996,573✔
654
  SRowKey key1, key2;
655
  tRowGetKey(*(SRow **)p1, &key1);
49,996,573✔
656
  tRowGetKey(*(SRow **)p2, &key2);
49,996,573✔
657
  return tRowKeyCompare(&key1, &key2);
50,511,981✔
658
}
659
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
1,024✔
660
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
248✔
661
  int32_t code = 0;
248✔
662

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

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

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

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

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

688
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
934✔
689
    SColVal *pColVal = NULL;
686✔
690
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
812✔
691
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
776✔
692
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
857✔
693
        pColValT = tRowIterNext(aIter[iRow]);
81✔
694
      }
695

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

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

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

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

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

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

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

749
  int32_t iStart = 0;
17,856✔
750
  while (iStart < aRowP->size) {
8,536,877✔
751
    SRowKey key1;
752
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
8,515,615✔
753

754
    tRowGetKey(row1, &key1);
8,512,332✔
755

756
    int32_t iEnd = iStart + 1;
8,514,341✔
757
    while (iEnd < aRowP->size) {
8,517,601✔
758
      SRowKey key2;
759
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
8,494,930✔
760
      tRowGetKey(row2, &key2);
8,493,210✔
761

762
      if (tRowKeyCompare(&key1, &key2) != 0) break;
8,499,610✔
763

764
      iEnd++;
3,260✔
765
    }
766

767
    if (iEnd - iStart > 1) {
8,519,021✔
768
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
248✔
769
      if (code) return code;
248!
770
    }
771

772
    // the array is also changing, so the iStart just ++ instead of iEnd
773
    iStart++;
8,519,021✔
774
  }
775

776
  return code;
21,262✔
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) {
21,461✔
800
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
21,461!
801

802
  int32_t code = 0;
21,461✔
803

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

810
  pIter->pRow = pRow;
21,461✔
811
  pIter->pTSchema = pTSchema;
21,461✔
812
  pIter->iTColumn = 0;
21,461✔
813

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

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

822
  if (pRow->flag >> 4) {
21,306✔
823
    pIter->iCol = 0;
682✔
824
    pIter->pIdx = (SKVIdx *)data;
682✔
825
    if (pRow->flag & KV_FLG_LIT) {
682!
826
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
682✔
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,624!
834
      case (HAS_NULL | HAS_NONE):
1✔
835
        pIter->pb = data;
1✔
836
        break;
1✔
837
      case HAS_VALUE:
20,543✔
838
        pIter->pf = data;
20,543✔
839
        pIter->pv = pIter->pf + pTSchema->flen;
20,543✔
840
        break;
20,543✔
841
      case (HAS_VALUE | HAS_NONE):
80✔
842
      case (HAS_VALUE | HAS_NULL):
843
        pIter->pb = data;
80✔
844
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
80✔
845
        pIter->pv = pIter->pf + pTSchema->flen;
80✔
846
        break;
80✔
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:
×
853
        break;
×
854
    }
855
  }
856

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

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

874
SColVal *tRowIterNext(SRowIter *pIter) {
105,775✔
875
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
105,775✔
876
    return NULL;
20,437✔
877
  }
878

879
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
85,338✔
880

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

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

895
  if (pIter->pRow->flag == HAS_NULL) {
64,577✔
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
63,181✔
901
    if (pIter->iCol < pIter->pIdx->nCol) {
1,147✔
902
      uint8_t *pData;
903

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

915
      if (TABS(cid) == pTColumn->colId) {
1,122✔
916
        if (cid < 0) {
1,028✔
917
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
175✔
918
        } else {
919
          pIter->cv.cid = pTColumn->colId;
853✔
920
          pIter->cv.value.type = pTColumn->type;
853✔
921
          pIter->cv.flag = CV_FLAG_VALUE;
853✔
922

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

935
        pIter->iCol++;
1,028✔
936
        goto _exit;
1,028✔
937
      } else if (TABS(cid) > pTColumn->colId) {
94!
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);
25✔
946
      goto _exit;
25✔
947
    }
948
  } else {  // Tuple
949
    uint8_t bv = BIT_FLG_VALUE;
62,034✔
950
    if (pIter->pb) {
62,034✔
951
      switch (pIter->pRow->flag) {
785!
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):
22✔
956
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
22✔
957
          if (bv) bv++;
22✔
958
          break;
22✔
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) {
785✔
970
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7✔
971
        goto _exit;
7✔
972
      } else if (bv == BIT_FLG_NULL) {
778✔
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,957✔
979
    pIter->cv.value.type = pTColumn->type;
61,957✔
980
    pIter->cv.flag = CV_FLAG_VALUE;
61,957✔
981
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
69,696!
982
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
7,739✔
983
      pData += tGetU32v(pData, &pIter->cv.value.nData);
7,739!
984
      if (pIter->cv.value.nData > 0) {
7,739!
985
        pIter->cv.value.pData = pData;
7,739✔
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,218✔
991
    }
992
    goto _exit;
61,957✔
993
  }
994

995
_exit:
85,338✔
996
  pIter->iTColumn++;
85,338✔
997
  return &pIter->cv;
85,338✔
998
}
999

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

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

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

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

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

1020
  while (pColData) {
608,958✔
1021
    if (pTColumn) {
441,501!
1022
      if (pTColumn->colId == pColData->cid) {  // NULL
441,501✔
1023
        if (flag == 0) {
441,480✔
1024
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
441,371✔
1025
        } else {
1026
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
109✔
1027
        }
1028
        if (code) goto _exit;
441,399!
1029

1030
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
441,399✔
1031
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
441,399✔
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:
167,457✔
1045
  return code;
167,457✔
1046
}
1047
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
102,228,999✔
1048
                                      int32_t flag) {
1049
  int32_t code = 0;
102,228,999✔
1050

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

1056
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
102,228,999✔
1057
  SPrimaryKeyIndex index;
1058
  uint8_t         *data = pRow->data;
102,228,999✔
1059
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
102,329,614✔
1060
    data += tGetPrimaryKeyIndex(data, &index);
100,615✔
1061
  }
1062

1063
  switch (pRow->flag) {
102,228,999!
1064
    case HAS_VALUE:
97,022,718✔
1065
      pf = data;  // TODO: fix here
97,022,718✔
1066
      pv = pf + pTSchema->flen;
97,022,718✔
1067
      break;
97,022,718✔
1068
    case (HAS_NULL | HAS_NONE):
1,296✔
1069
      pb = data;
1,296✔
1070
      break;
1,296✔
1071
    case (HAS_VALUE | HAS_NONE):
5,483,247✔
1072
    case (HAS_VALUE | HAS_NULL):
1073
      pb = data;
5,483,247✔
1074
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
5,483,247✔
1075
      pv = pf + pTSchema->flen;
5,483,247✔
1076
      break;
5,483,247✔
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) {
583,648,481✔
1087
    if (pTColumn) {
477,027,377✔
1088
      if (pTColumn->colId == pColData->cid) {
476,607,331!
1089
        if (!(pTColumn->type == pColData->type)) {
477,022,210!
1090
          return TSDB_CODE_INVALID_PARA;
×
1091
        }
1092
        if (pb) {
477,022,210✔
1093
          uint8_t bv;
1094
          switch (pRow->flag) {
58,919,416!
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,320✔
1099
              bv = GET_BIT1(pb, iTColumn - 1);
199,320✔
1100
              if (bv) bv++;
199,320✔
1101
              break;
199,320✔
1102
            case (HAS_VALUE | HAS_NULL):
58,692,986✔
1103
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
58,692,986✔
1104
              break;
58,692,986✔
1105
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1106
              bv = GET_BIT2(pb, iTColumn - 1);
×
1107
              break;
×
1108
            default:
1,190✔
1109
              return TSDB_CODE_INVALID_DATA_FMT;
1,190✔
1110
          }
1111

1112
          if (bv == BIT_FLG_NONE) {
58,918,226✔
1113
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,385!
1114
              goto _exit;
×
1115
            goto _continue;
43,391✔
1116
          } else if (bv == BIT_FLG_NULL) {
58,874,841✔
1117
            if (flag == 0) {
9,313,247✔
1118
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
9,142,616✔
1119
            } else {
1120
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
170,631✔
1121
            }
1122
            if (code) goto _exit;
9,312,488!
1123
            goto _continue;
9,312,488✔
1124
          }
1125
        }
1126

1127
        if (IS_VAR_DATA_TYPE(pColData->type)) {
536,945,152!
1128
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
63,428,385!
1129
          uint32_t nData;
1130
          pData += tGetU32v(pData, &nData);
63,428,385✔
1131
          if (flag == 0) {
63,428,385!
1132
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
67,704,945✔
1133
          } else {
1134
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1135
          }
1136
          if (code) goto _exit;
69,280,764!
1137
        } else {
1138
          if (flag == 0) {
404,236,003✔
1139
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
387,756,555✔
1140
                                                                          TYPE_BYTES[pColData->type]);
387,756,555✔
1141
          } else {
1142
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
16,479,448✔
1143
                                                                          TYPE_BYTES[pColData->type], flag > 0);
16,479,448✔
1144
          }
1145
          if (code) goto _exit;
402,499,413!
1146
        }
1147

1148
      _continue:
402,499,413✔
1149
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
481,136,056✔
1150
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
481,136,056✔
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,046!
1159
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
420,043✔
1160
    }
1161
  }
1162

1163
_exit:
106,621,104✔
1164
  return code;
106,621,104✔
1165
}
1166
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
6,101,325✔
1167
  int32_t code = 0;
6,101,325✔
1168

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

1176
  // primary keys
1177
  uint8_t         *data = pRow->data;
6,101,325✔
1178
  SPrimaryKeyIndex index;
1179
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
6,200,094✔
1180
    data += tGetPrimaryKeyIndex(data, &index);
98,753✔
1181
  }
1182

1183
  SKVIdx *pKVIdx = (SKVIdx *)data;
6,101,341✔
1184
  if (pRow->flag & KV_FLG_LIT) {
6,101,341✔
1185
    pv = pKVIdx->idx + pKVIdx->nCol;
6,040,544✔
1186
  } else if (pRow->flag & KV_FLG_MID) {
60,797!
1187
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
64,847✔
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) {
96,967,059✔
1195
    if (pTColumn) {
90,998,768✔
1196
      if (pTColumn->colId == pColData->cid) {
90,599,710✔
1197
        while (iCol < pKVIdx->nCol) {
90,510,100✔
1198
          uint8_t *pData;
1199
          if (pRow->flag & KV_FLG_LIT) {
63,335,670✔
1200
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
61,561,021✔
1201
          } else if (pRow->flag & KV_FLG_MID) {
1,774,649!
1202
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,774,884✔
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);
63,335,905✔
1211

1212
          if (TABS(cid) == pTColumn->colId) {
63,335,905✔
1213
            if (cid < 0) {
30,494,648✔
1214
              if (flag == 0) {
8,439,282✔
1215
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
8,424,663✔
1216
              } else {
1217
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
14,619✔
1218
              }
1219
              if (code) goto _exit;
7,896,853!
1220
            } else {
1221
              uint32_t nData;
1222
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
22,055,366!
1223
                pData += tGetU32v(pData, &nData);
5,230,857✔
1224
              } else {
1225
                nData = 0;
16,824,509✔
1226
              }
1227
              if (flag == 0) {
22,055,366!
1228
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
22,210,936✔
1229
              } else {
1230
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1231
              }
1232
              if (code) goto _exit;
22,462,011!
1233
            }
1234
            iCol++;
30,358,864✔
1235
            goto _continue;
30,358,864✔
1236
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
32,841,257✔
1237
            break;
32,507,190✔
1238
          } else {
1239
            iCol++;
334,067✔
1240
          }
1241
        }
1242

1243
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
59,681,620!
1244

1245
      _continue:
59,680,103✔
1246
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
90,038,967✔
1247
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
90,038,967✔
1248
      } else if (pTColumn->colId > pColData->cid) {
423,677!
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;
423,677!
1253
      }
1254
    } else {
1255
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,058!
1256
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,024✔
1257
    }
1258
  }
1259

1260
_exit:
5,968,291✔
1261
  return code;
5,968,291✔
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) {
108,183,036✔
1268
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
108,183,036!
1269
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
108,183,036!
1270

1271
  if (pRow->flag == HAS_NONE) {
108,183,036✔
1272
    return tRowNoneUpsertColData(aColData, nColData, flag);
10,830✔
1273
  } else if (pRow->flag == HAS_NULL) {
108,172,206✔
1274
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
167,539✔
1275
  } else if (pRow->flag >> 4) {  // KV row
108,004,667✔
1276
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
6,099,393✔
1277
  } else {  // TUPLE row
1278
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
101,905,274✔
1279
  }
1280
}
1281

1282
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
8,148,234✔
1283
  key->numOfPKs = row->numOfPKs;
8,148,234✔
1284

1285
  if (key->numOfPKs == 0) {
8,148,234!
1286
    return;
×
1287
  }
1288

1289
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1290

1291
  uint8_t *data = row->data;
8,148,234✔
1292

1293
  for (int32_t i = 0; i < row->numOfPKs; i++) {
16,282,364✔
1294
    data += tGetPrimaryKeyIndex(data, &indices[i]);
8,150,881✔
1295
  }
1296

1297
  // primary keys
1298
  for (int32_t i = 0; i < row->numOfPKs; i++) {
16,286,975✔
1299
    key->pks[i].type = indices[i].type;
8,155,492✔
1300

1301
    uint8_t *tdata = data + indices[i].offset;
8,155,492✔
1302
    if (row->flag >> 4) {
8,155,492✔
1303
      tdata += tGetI16v(tdata, NULL);
7,008,907✔
1304
    }
1305

1306
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
8,155,492!
1307
      key->pks[i].pData = tdata;
2,132,725✔
1308
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
4,265,450!
1309
    } else {
1310
      (void)memcpy(&key->pks[i].val, tdata, tDataTypes[indices[i].type].bytes);
6,022,767✔
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) {
7,456,460✔
1327
  switch (tv1->type) {
7,456,460!
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,101,771✔
1334
      T_COMPARE_SCALAR_VALUE(int32_t, &tv1->val, &tv2->val);
2,101,771✔
1335
    case TSDB_DATA_TYPE_BIGINT:
1,136,953✔
1336
    case TSDB_DATA_TYPE_TIMESTAMP:
1337
      T_COMPARE_SCALAR_VALUE(int64_t, &tv1->val, &tv2->val);
1,136,953✔
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,128,536✔
1347
      T_COMPARE_SCALAR_VALUE(uint32_t, &tv1->val, &tv2->val);
1,128,536✔
1348
    case TSDB_DATA_TYPE_UBIGINT:
1,138,808✔
1349
      T_COMPARE_SCALAR_VALUE(uint64_t, &tv1->val, &tv2->val);
1,138,808✔
1350
    case TSDB_DATA_TYPE_GEOMETRY:
1,952,977✔
1351
    case TSDB_DATA_TYPE_BINARY: {
1352
      int32_t ret = strncmp((const char *)tv1->pData, (const char *)tv2->pData, TMIN(tv1->nData, tv2->nData));
1,952,977✔
1353
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
1,952,977✔
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:
×
1365
      break;
×
1366
  }
1367

1368
  return 0;
×
1369
}
1370

1371
// NOTE:
1372
// set key->numOfPKs to 0 as the smallest key with ts
1373
// set key->numOfPKs to (TD_MAX_PK_COLS + 1) as the largest key with ts
1374
FORCE_INLINE int32_t tRowKeyCompare(const SRowKey *key1, const SRowKey *key2) {
1,179,174,175✔
1375
  if (key1->ts < key2->ts) {
1,238,186,577!
1376
    return -1;
640,405,080✔
1377
  } else if (key1->ts > key2->ts) {
597,781,497!
1378
    return 1;
549,822,063✔
1379
  }
1380

1381
  if (key1->numOfPKs == key2->numOfPKs) {
47,959,434!
1382
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
77,545,194!
1383
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
7,457,129✔
1384
      if (ret) return ret;
7,453,618!
1385
    }
1386
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1387
    return -1;
7✔
1388
  } else {
1389
    return 1;
×
1390
  }
1391

1392
  return 0;
70,088,065✔
1393
}
1394

1395
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
343,004,233✔
1396
  pDst->ts = pSrc->ts;
343,004,233✔
1397
  pDst->numOfPKs = pSrc->numOfPKs;
343,004,233✔
1398

1399
  if (pSrc->numOfPKs > 0) {
343,004,233✔
1400
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
14,943,334✔
1401
      SValue *pVal = &pDst->pks[i];
7,472,721✔
1402
      pVal->type = pSrc->pks[i].type;
7,472,721✔
1403

1404
      if (IS_NUMERIC_TYPE(pVal->type)) {
7,472,721!
1405
        pVal->val = pSrc->pks[i].val;
5,229,737✔
1406
      } else {
1407
        pVal->nData = pSrc->pks[i].nData;
2,242,984✔
1408
        (void)memcpy(pVal->pData, pSrc->pks[i].pData, pVal->nData);
2,242,984✔
1409
      }
1410
    }
1411
  }
1412
}
343,004,233✔
1413

1414
// STag ========================================
1415
static int tTagValCmprFn(const void *p1, const void *p2) {
36,089,069✔
1416
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
36,089,069✔
1417
    return -1;
11,149,330✔
1418
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
24,939,739✔
1419
    return 1;
14,020,777✔
1420
  }
1421

1422
  return 0;
10,918,962✔
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) {
828,732✔
1522
  int32_t n = 0;
828,732✔
1523

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

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

1534
  // value
1535
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
828,732!
1536
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
555,670✔
1537
  } else {
1538
    p = p ? p + n : p;
550,897✔
1539
    n += tDataTypes[pTagVal->type].bytes;
550,897✔
1540
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
550,897✔
1541
  }
1542

1543
  return n;
828,732✔
1544
}
1545
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
35,671,074✔
1546
  int32_t n = 0;
35,671,074✔
1547

1548
  // key
1549
  if (isJson) {
35,671,074✔
1550
    n += tGetCStr(p + n, &pTagVal->pKey);
27,402!
1551
  } else {
1552
    n += tGetI16v(p + n, &pTagVal->cid);
71,314,746✔
1553
  }
1554

1555
  // type
1556
  n += tGetI8(p + n, &pTagVal->type);
35,671,074!
1557

1558
  // value
1559
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
35,671,074!
1560
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
9,402,654!
1561
  } else {
1562
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
30,969,747✔
1563
    n += tDataTypes[pTagVal->type].bytes;
30,969,747✔
1564
  }
1565

1566
  return n;
35,671,074✔
1567
}
1568

1569
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
39,334✔
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) {
134,993✔
1579
  int32_t  code = 0;
134,993✔
1580
  uint8_t *p = NULL;
134,993✔
1581
  int16_t  n = 0;
134,993✔
1582
  int16_t  nTag = taosArrayGetSize(pArray);
134,993✔
1583
  int32_t  szTag = 0;
134,996✔
1584
  int8_t   isLarge = 0;
134,996✔
1585

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

1593
  // get size
1594
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
549,374✔
1595
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
414,384✔
1596
  }
1597
  if (szTag <= INT8_MAX) {
134,990✔
1598
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
119,237✔
1599
  } else {
1600
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
15,753✔
1601
    isLarge = 1;
15,753✔
1602
  }
1603

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

1621
  if (isLarge) {
135,000✔
1622
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
15,753✔
1623
  } else {
1624
    p = (uint8_t *)&(*ppTag)->idx[nTag];
119,247✔
1625
  }
1626
  n = 0;
135,000✔
1627
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
549,380✔
1628
    if (isLarge) {
414,385✔
1629
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
97,406✔
1630
    } else {
1631
      (*ppTag)->idx[iTag] = n;
316,979✔
1632
    }
1633
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
414,385✔
1634
  }
1635
#ifdef TD_DEBUG_PRINT_TAG
1636
  debugPrintSTag(*ppTag, __func__, __LINE__);
1637
#endif
1638

1639
  return code;
134,995✔
1640

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

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

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

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

1660
  if (IS_VAR_DATA_TYPE(value->type)) {
5,939,961✔
1661
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
2,053,757✔
1662
    if (data == NULL) {
2,060,540!
1663
      return NULL;
×
1664
    }
1665

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

1670
    varDataLen(data + typeBytes) = value->nData;
2,060,540✔
1671
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
2,060,540✔
1672
  } else {
1673
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
3,886,204✔
1674
  }
1675

1676
  return data;
5,946,744✔
1677
}
1678

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

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

1694
  if (isLarge) {
11,768,678✔
1695
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
3,932,266✔
1696
  } else {
1697
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,836,412✔
1698
  }
1699

1700
  pTagVal->type = TSDB_DATA_TYPE_NULL;
11,768,678✔
1701
  pTagVal->pData = NULL;
11,768,678✔
1702
  pTagVal->nData = 0;
11,768,678✔
1703
  while (lidx <= ridx) {
36,493,563✔
1704
    midx = (lidx + ridx) / 2;
35,692,104✔
1705
    if (isLarge) {
35,692,104✔
1706
      offset = ((int16_t *)pTag->idx)[midx];
12,675,034✔
1707
    } else {
1708
      offset = pTag->idx[midx];
23,017,070✔
1709
    }
1710

1711
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
35,692,104✔
1712
    if (isJson) {
35,697,792✔
1713
      c = tTagValJsonCmprFn(pTagVal, &tv);
10,408✔
1714
    } else {
1715
      c = tTagValCmprFn(pTagVal, &tv);
35,687,384✔
1716
    }
1717

1718
    if (c < 0) {
36,132,331✔
1719
      ridx = midx - 1;
10,711,986✔
1720
    } else if (c > 0) {
25,420,345✔
1721
      lidx = midx + 1;
14,012,899✔
1722
    } else {
1723
      (void)memcpy(pTagVal, &tv, sizeof(tv));
11,407,446✔
1724
      return true;
11,407,446✔
1725
    }
1726
  }
1727
  return false;
801,459✔
1728
}
1729

1730
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
503,827✔
1731
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,007,654✔
1732
}
1733

1734
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
4,966,643✔
1735

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

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

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

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

1768
  return code;
2,189✔
1769

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

1774
// STSchema ========================================
1775
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
4,123,274✔
1776
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
4,123,274✔
1777
  if (pTSchema == NULL) {
4,124,665✔
1778
    terrno = TSDB_CODE_OUT_OF_MEMORY;
271✔
1779
    return NULL;
×
1780
  }
1781

1782
  pTSchema->numOfCols = numOfCols;
4,124,394✔
1783
  pTSchema->version = version;
4,124,394✔
1784

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

1800
  // other columns
1801
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
94,943,410✔
1802
    SSchema  *pSchema = &aSchema[iCol];
90,819,016✔
1803
    STColumn *pTColumn = &pTSchema->columns[iCol];
90,819,016✔
1804

1805
    pTColumn->colId = pSchema->colId;
90,819,016✔
1806
    pTColumn->type = pSchema->type;
90,819,016✔
1807
    pTColumn->flags = pSchema->flags;
90,819,016✔
1808
    pTColumn->offset = pTSchema->flen;
90,819,016✔
1809

1810
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
90,819,016✔
1811
      pTColumn->bytes = pSchema->bytes;
23,104,185✔
1812
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
23,104,185✔
1813
    } else {
1814
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
67,714,831✔
1815
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
67,714,831✔
1816
    }
1817

1818
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
90,819,016✔
1819
  }
1820

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

1825
  return pTSchema;
4,124,394✔
1826
}
1827

1828
static int32_t tTColumnCompare(const void *p1, const void *p2) {
1,840,597✔
1829
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
1,840,597✔
1830
    return -1;
307,674✔
1831
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
1,532,923✔
1832
    return 1;
1,093,343✔
1833
  }
1834

1835
  return 0;
439,580✔
1836
}
1837

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

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

1846
// SColData ========================================
1847
void tColDataDestroy(void *ph) {
7,323,431✔
1848
  if (ph) {
7,323,431!
1849
    SColData *pColData = (SColData *)ph;
7,323,641✔
1850

1851
    tFree(pColData->pBitMap);
7,323,641✔
1852
    tFree(pColData->aOffset);
7,323,744✔
1853
    tFree(pColData->pData);
7,323,823✔
1854
  }
1855
}
7,324,924✔
1856

1857
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
7,501,754✔
1858
  pColData->cid = cid;
7,501,754✔
1859
  pColData->type = type;
7,501,754✔
1860
  pColData->cflag = cflag;
7,501,754✔
1861
  tColDataClear(pColData);
7,501,754✔
1862
}
7,502,682✔
1863

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

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

1878
  tColDataClear(pColData);
868✔
1879
}
868✔
1880

1881
static FORCE_INLINE int32_t tColDataPutValue(SColData *pColData, uint8_t *pData, uint32_t nData) {
1882
  int32_t code = 0;
823,050,654✔
1883

1884
  if (IS_VAR_DATA_TYPE(pColData->type)) {
769,488,037!
1885
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
134,718,198!
1886
    if (code) goto _exit;
140,884,108!
1887
    pColData->aOffset[pColData->nVal] = pColData->nData;
140,884,108✔
1888

1889
    if (nData) {
140,884,108!
1890
      code = tRealloc(&pColData->pData, pColData->nData + nData);
136,277,326!
1891
      if (code) goto _exit;
136,890,645!
1892
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
136,890,645✔
1893
      pColData->nData += nData;
136,890,645✔
1894
    }
1895
  } else {
1896
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
688,332,456!
1897
      return TSDB_CODE_INVALID_PARA;
×
1898
    }
1899
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
688,332,456!
1900
    if (code) goto _exit;
687,994,698!
1901
    if (pData) {
687,994,698!
1902
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
656,500,523✔
1903
    } else {
1904
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
31,494,175✔
1905
    }
1906
    pColData->nData += tDataTypes[pColData->type].bytes;
687,994,698✔
1907
  }
1908
  pColData->nVal++;
829,492,125✔
1909

1910
_exit:
829,492,125✔
1911
  return code;
829,492,125✔
1912
}
1913
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,712,313✔
1914
  pColData->flag = HAS_VALUE;
1,712,506✔
1915
  pColData->numOfValue++;
1,712,313✔
1916
  return tColDataPutValue(pColData, pData, nData);
1,714,876✔
1917
}
1918
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
150,733✔
1919
  pColData->flag = HAS_NONE;
150,733✔
1920
  pColData->numOfNone++;
150,733✔
1921
  pColData->nVal++;
150,733✔
1922
  return 0;
150,733✔
1923
}
1924
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
180,784✔
1925
  pColData->flag = HAS_NULL;
180,866✔
1926
  pColData->numOfNull++;
180,866✔
1927
  pColData->nVal++;
180,866✔
1928
  return 0;
180,784✔
1929
}
1930
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,421✔
1931
  int32_t code = 0;
1,421✔
1932

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

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

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

1943
  if (pColData->nVal) {
1,422!
1944
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,421!
1945
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
255✔
1946
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
255!
1947
      if (code) return code;
254!
1948
      memset(pColData->aOffset, 0, nOffset);
254✔
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,166!
1953
      memset(pColData->pData, 0, pColData->nData);
1,166✔
1954
    }
1955
  }
1956

1957
  return tColDataPutValue(pColData, pData, nData);
1,420✔
1958
}
1959
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
76,232,224✔
1960
  pColData->nVal++;
76,232,224✔
1961
  pColData->numOfNone++;
76,232,224✔
1962
  return 0;
76,232,224✔
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) {
21,326✔
1981
  int32_t code = 0;
21,330✔
1982

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

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

1990
  pColData->flag |= HAS_VALUE;
21,330✔
1991
  pColData->numOfValue++;
21,330✔
1992

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

2007
  return tColDataPutValue(pColData, pData, nData);
21,330✔
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,192,118✔
2026
  pColData->nVal++;
9,192,118✔
2027
  pColData->numOfNull++;
9,192,118✔
2028
  return 0;
9,192,118✔
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,373✔
2077
  int32_t code = 0;
9,373✔
2078

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

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

2086
  return code;
9,373✔
2087
}
2088
static FORCE_INLINE int32_t tColDataAppendValue40(SColData *pColData, uint8_t *pData, uint32_t nData) {
558,054,683✔
2089
  pColData->numOfValue++;
558,054,683✔
2090
  return tColDataPutValue(pColData, pData, nData);
564,340,579✔
2091
}
2092
static FORCE_INLINE int32_t tColDataAppendValue41(SColData *pColData, uint8_t *pData, uint32_t nData) {
144,837✔
2093
  int32_t code = 0;
144,837✔
2094

2095
  pColData->flag |= HAS_NONE;
144,837✔
2096
  pColData->numOfNone++;
144,837✔
2097

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

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

2105
  return tColDataPutValue(pColData, NULL, 0);
144,880✔
2106
}
2107
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
223,437✔
2108
  int32_t code = 0;
229,646✔
2109

2110
  pColData->flag |= HAS_NULL;
229,646✔
2111
  pColData->numOfNull++;
229,646✔
2112

2113
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
229,646✔
2114
  code = tRealloc(&pColData->pBitMap, nBit);
229,342✔
2115
  if (code) return code;
229,649!
2116

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

2120
  return tColDataPutValue(pColData, NULL, 0);
229,650✔
2121
}
2122
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,359,633✔
2123
  int32_t code = 0;
1,361,633✔
2124

2125
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,361,632!
2126
  if (code) return code;
1,362,286!
2127

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

2131
  return tColDataPutValue(pColData, pData, nData);
1,364,975✔
2132
}
2133
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
14,122,494✔
2134
  int32_t code = 0;
14,122,494✔
2135

2136
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
14,122,494!
2137
  if (code) return code;
14,122,541!
2138

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

2142
  return tColDataPutValue(pColData, NULL, 0);
14,125,067✔
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,146!
2155
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
3,753,680!
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) {
177,708,493✔
2165
  int32_t code = 0;
177,873,674✔
2166

2167
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
177,873,274!
2168
  if (code) return code;
178,004,178!
2169
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
178,004,178!
2170
  pColData->numOfValue++;
178,004,178✔
2171

2172
  return tColDataPutValue(pColData, pData, nData);
178,173,120✔
2173
}
2174
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
28,926✔
2175
  int32_t code = 0;
28,926✔
2176

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

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

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

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

2192
  return tColDataPutValue(pColData, NULL, 0);
28,927✔
2193
}
2194
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
14,137,172✔
2195
  int32_t code = 0;
14,313,278✔
2196

2197
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
14,309,684!
2198
  if (code) return code;
14,314,890!
2199
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
14,314,890✔
2200
  pColData->numOfNull++;
14,314,890✔
2201

2202
  return tColDataPutValue(pColData, NULL, 0);
14,318,384✔
2203
}
2204
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
660,793✔
2205
  int32_t code = 0;
660,793✔
2206

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

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

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

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

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

2232
  return tColDataPutValue(pColData, NULL, 0);
562,559✔
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) {
313,129,011✔
2247
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) {
313,129,011!
2248
    return TSDB_CODE_INVALID_PARA;
×
2249
  }
2250
  return tColDataAppendValueImpl[pColData->flag][pColVal->flag](
313,265,553✔
2251
      pColData, IS_VAR_DATA_TYPE(pColData->type) ? pColVal->value.pData : (uint8_t *)&pColVal->value.val,
313,265,553!
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) {
184✔
2277
  if (forward) {
184!
2278
    pColData->numOfNull--;
184✔
2279
    pColData->nVal--;
184✔
2280
    if (pColData->numOfNull) {
184!
2281
      return tColDataAppendValue20(pColData, pData, nData);
×
2282
    } else {
2283
      pColData->flag = 0;
184✔
2284
      return tColDataAppendValue00(pColData, pData, nData);
184✔
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,690,234✔
2324
  if (forward) {  // VALUE ==> VALUE
45,690,234!
2325
    pColData->nVal--;
45,695,508✔
2326
    if (IS_VAR_DATA_TYPE(pColData->type)) {
45,695,508!
2327
      pColData->nData = pColData->aOffset[pColData->nVal];
1,253,467✔
2328
    } else {
2329
      pColData->nData -= TYPE_BYTES[pColData->type];
44,442,041✔
2330
    }
2331
    return tColDataPutValue(pColData, pData, nData);
45,695,509✔
2332
  }
2333
  return 0;
×
2334
}
2335
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,963✔
2336
  if (forward) {  // VALUE ==> NULL
5,963!
2337
    pColData->numOfValue--;
5,963✔
2338
    pColData->nVal--;
5,963✔
2339
    if (pColData->numOfValue) {
5,963✔
2340
      if (IS_VAR_DATA_TYPE(pColData->type)) {
5,905!
2341
        pColData->nData = pColData->aOffset[pColData->nVal];
1,171✔
2342
      } else {
2343
        pColData->nData -= TYPE_BYTES[pColData->type];
4,734✔
2344
      }
2345
      return tColDataAppendValue42(pColData, pData, nData);
5,905✔
2346
    } else {
2347
      pColData->flag = 0;
58✔
2348
      pColData->nData = 0;
58✔
2349
      return tColDataAppendValue02(pColData, pData, nData);
58✔
2350
    }
2351
  }
2352
  return 0;
×
2353
}
2354
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
44,633✔
2355
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
44,633✔
2356
    pColData->numOfNone--;
5,589✔
2357
    pColData->nVal--;
5,589✔
2358
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,589!
2359
      pColData->nData -= TYPE_BYTES[pColData->type];
4,473✔
2360
    }
2361
    if (pColData->numOfNone) {
5,589✔
2362
      return tColDataAppendValue50(pColData, pData, nData);
1,999✔
2363
    } else {
2364
      pColData->flag = HAS_VALUE;
3,590✔
2365
      return tColDataAppendValue40(pColData, pData, nData);
3,595✔
2366
    }
2367
  } else if (forward) {  // VALUE ==> VALUE
39,044!
2368
    pColData->nVal--;
39,044✔
2369
    if (IS_VAR_DATA_TYPE(pColData->type)) {
39,044!
2370
      pColData->nData = pColData->aOffset[pColData->nVal];
5,573✔
2371
    } else {
2372
      pColData->nData -= TYPE_BYTES[pColData->type];
33,471✔
2373
    }
2374
    return tColDataPutValue(pColData, pData, nData);
39,056✔
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,289,096✔
2410
  if (forward) {
3,289,096!
2411
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
3,289,096✔
2412
      pColData->numOfNull--;
185,642✔
2413
      pColData->nVal--;
185,642✔
2414
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
185,642!
2415
        pColData->nData -= TYPE_BYTES[pColData->type];
155,524✔
2416
      }
2417
      if (pColData->numOfNull) {
185,642✔
2418
        return tColDataAppendValue60(pColData, pData, nData);
164,781✔
2419
      } else {
2420
        pColData->flag = HAS_VALUE;
20,861✔
2421
        return tColDataAppendValue40(pColData, pData, nData);
20,864✔
2422
      }
2423
    } else {  // VALUE ==> VALUE
2424
      pColData->nVal--;
3,103,454✔
2425
      if (IS_VAR_DATA_TYPE(pColData->type)) {
3,103,454!
2426
        pColData->nData = pColData->aOffset[pColData->nVal];
478,576✔
2427
      } else {
2428
        pColData->nData -= TYPE_BYTES[pColData->type];
2,624,878✔
2429
      }
2430
      return tColDataPutValue(pColData, pData, nData);
3,103,455✔
2431
    }
2432
  }
2433
  return 0;
×
2434
}
2435
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
195,587✔
2436
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
195,587!
2437
    pColData->numOfValue--;
172,516✔
2438
    pColData->nVal--;
172,516✔
2439
    if (pColData->numOfValue) {
172,516✔
2440
      if (IS_VAR_DATA_TYPE(pColData->type)) {
172,512!
2441
        pColData->nData = pColData->aOffset[pColData->nVal];
27,512✔
2442
      } else {
2443
        pColData->nData -= TYPE_BYTES[pColData->type];
145,000✔
2444
      }
2445
      return tColDataAppendValue62(pColData, pData, nData);
172,514✔
2446
    } else {
2447
      pColData->flag = HAS_NULL;
4✔
2448
      pColData->nData = 0;
4!
2449
      return tColDataAppendValue20(pColData, pData, nData);
4✔
2450
    }
2451
  }
2452
  return 0;
23,071✔
2453
}
2454
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
401✔
2455
  int32_t code = 0;
401✔
2456

2457
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
401✔
2458
  if (bv == 0) {  // NONE ==> VALUE
401✔
2459
    pColData->numOfNone--;
400✔
2460
    pColData->nVal--;
400✔
2461
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
400!
2462
      pColData->nData -= TYPE_BYTES[pColData->type];
320✔
2463
    }
2464
    if (pColData->numOfNone) {
400!
2465
      return tColDataAppendValue70(pColData, pData, nData);
×
2466
    } else {
2467
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
21,200✔
2468
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
20,800✔
2469
      }
2470
      pColData->flag = (HAS_VALUE | HAS_NULL);
400!
2471
      return tColDataAppendValue60(pColData, pData, nData);
400✔
2472
    }
2473
  } else if (bv == 1) {  // NULL ==> VALUE
1!
2474
    if (forward) {
1!
2475
      pColData->numOfNull--;
1✔
2476
      pColData->nVal--;
1✔
2477
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
1!
2478
        pColData->nData -= TYPE_BYTES[pColData->type];
1✔
2479
      }
2480
      if (pColData->numOfNull) {
1!
2481
        return tColDataAppendValue70(pColData, pData, nData);
×
2482
      } else {
2483
        for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
3✔
2484
          SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) ? 1 : 0);
2✔
2485
        }
2486
        pColData->flag = (HAS_VALUE | HAS_NONE);
1!
2487
        return tColDataAppendValue50(pColData, pData, nData);
1✔
2488
      }
2489
    }
2490
  } else if (bv == 2) {  // VALUE ==> VALUE
×
2491
    if (forward) {
×
2492
      pColData->nVal--;
×
2493
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2494
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2495
      } else {
2496
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2497
      }
2498
      return tColDataPutValue(pColData, pData, nData);
×
2499
    }
2500
  } else {
2501
    return TSDB_CODE_INVALID_PARA;
×
2502
  }
2503
  return 0;
×
2504
}
2505
static int32_t tColDataUpdateValue72(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,594✔
2506
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
3,594✔
2507
  if (bv == 0) {  // NONE ==> NULL
3,594!
2508
    pColData->numOfNone--;
3,594✔
2509
    pColData->nVal--;
3,594✔
2510
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,594!
2511
      pColData->nData -= TYPE_BYTES[pColData->type];
2,543✔
2512
    }
2513
    if (pColData->numOfNone) {
3,594!
2514
      return tColDataAppendValue72(pColData, pData, nData);
×
2515
    } else {
2516
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
114,281✔
2517
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
110,687✔
2518
      }
2519
      pColData->flag = (HAS_VALUE | HAS_NULL);
3,594!
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,457✔
2544
  return 0;
12,457✔
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,998,117✔
2559
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
31,998,117!
2560
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
31,999,933!
2561

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

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

2569
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
11,134,847✔
2570
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
11,134,847✔
2571
}
11,134,847✔
2572
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
3,641,935✔
2573
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
3,641,935✔
2574
}
3,641,935✔
2575
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
11,160✔
2576
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2577
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,160!
2578
    case 0:
1,015✔
2579
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,015✔
2580
      break;
1,015✔
2581
    case 1:
10,145✔
2582
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,145✔
2583
      break;
10,145✔
2584
    default:
×
2585
      break;
×
2586
  }
2587
}
11,160✔
2588
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
536,480,464✔
2589
  SValue value = {.type = pColData->type};
663,894,447✔
2590
  if (IS_VAR_DATA_TYPE(pColData->type)) {
654,746,399!
2591
    if (iVal + 1 < pColData->nVal) {
147,005,581!
2592
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
150,087,343✔
2593
    } else {
2594
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2595
    }
2596
    value.pData = pColData->pData + pColData->aOffset[iVal];
147,005,581✔
2597
  } else {
2598
    (void)memcpy(&value.val, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
516,888,866✔
2599
                 tDataTypes[pColData->type].bytes);
516,888,866✔
2600
  }
2601
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
663,894,447✔
2602
}
127,413,983✔
2603
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
11,603,435✔
2604
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2605
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,603,435!
2606
    case 0:
5,835,244✔
2607
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
5,835,244✔
2608
      break;
5,835,244✔
2609
    case 1:
5,904,830✔
2610
      tColDataGetValue4(pColData, iVal, pColVal);
2611
      break;
5,904,830✔
2612
    default:
×
2613
      break;
×
2614
  }
2615
}
11,603,435✔
2616
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
129,468,575✔
2617
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2618
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
129,468,575!
2619
    case 0:
7,968,920✔
2620
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
7,968,920✔
2621
      break;
7,968,920✔
2622
    case 1:
121,509,086✔
2623
      tColDataGetValue4(pColData, iVal, pColVal);
2624
      break;
121,509,086✔
2625
    default:
×
2626
      break;
×
2627
  }
2628
}
129,468,575✔
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) {
691,555,212✔
2656
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
691,555,212✔
2657
}
712,736,760✔
2658

2659
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
474,022,126✔
2660
  switch (pColData->flag) {
474,022,126!
2661
    case HAS_NONE:
×
2662
      return 0;
×
2663
    case HAS_NULL:
×
2664
      return 1;
×
2665
    case (HAS_NULL | HAS_NONE):
11,156✔
2666
      return GET_BIT1(pColData->pBitMap, iVal);
11,156✔
2667
    case HAS_VALUE:
×
2668
      return 2;
×
2669
    case (HAS_VALUE | HAS_NONE):
12,525,744✔
2670
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
12,525,744✔
2671
    case (HAS_VALUE | HAS_NULL):
461,544,581✔
2672
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
461,544,581✔
2673
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
22✔
2674
      return GET_BIT2(pColData->pBitMap, iVal);
22✔
2675
    default:
×
2676
      return 0;
×
2677
  }
2678
}
2679

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

2683
  *pColData = *pColDataFrom;
517✔
2684

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

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

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

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

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

2739
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
1,849,775✔
2740
  int32_t code;
2741
  SBuffer local;
2742

2743
  if (!(colData->nVal > 0)) {
1,849,775!
2744
    return TSDB_CODE_INVALID_PARA;
×
2745
  }
2746

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

2756
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
1,849,775!
2757
    return 0;
148,397✔
2758
  }
2759

2760
  tBufferInit(&local);
2761
  if (assist == NULL) {
1,701,378!
2762
    assist = &local;
×
2763
  }
2764

2765
  // bitmap
2766
  if (colData->flag != HAS_VALUE) {
1,701,378✔
2767
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
379,374✔
2768
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
37,401✔
2769
    } else {
2770
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
341,973✔
2771
    }
2772

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

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

2785
    info->bitmapCompressedSize = cinfo.compressedSize;
379,443✔
2786
  }
2787

2788
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
1,701,447✔
2789
    tBufferDestroy(&local);
2790
    return 0;
10,595✔
2791
  }
2792

2793
  // offset
2794
  if (IS_VAR_DATA_TYPE(colData->type)) {
1,690,852!
2795
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
360,747✔
2796

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

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

2809
    info->offsetCompressedSize = cinfo.compressedSize;
360,680✔
2810
  }
2811

2812
  // data
2813
  if (colData->nData > 0) {
1,690,785!
2814
    info->dataOriginalSize = colData->nData;
1,690,876✔
2815

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

2822
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
1,690,876✔
2823
    if (code) {
1,691,179!
2824
      tBufferDestroy(&local);
2825
      return code;
×
2826
    }
2827

2828
    info->dataCompressedSize = cinfo.compressedSize;
1,691,179✔
2829
  }
2830

2831
  tBufferDestroy(&local);
2832
  return 0;
1,691,088✔
2833
}
2834

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

2840
  tBufferInit(&local);
2841
  if (assist == NULL) {
5,499,650!
2842
    assist = &local;
×
2843
  }
2844

2845
  tColDataClear(colData);
5,499,650✔
2846
  colData->cid = info->columnId;
5,498,851✔
2847
  colData->type = info->dataType;
5,498,851✔
2848
  colData->cflag = info->columnFlag;
5,498,851✔
2849
  colData->nVal = info->numOfData;
5,498,851✔
2850
  colData->flag = info->flag;
5,498,851✔
2851

2852
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
5,498,851✔
2853
    goto _exit;
767,616✔
2854
  }
2855

2856
  // bitmap
2857
  if (info->bitmapOriginalSize > 0) {
4,731,235✔
2858
    SCompressInfo cinfo = {
1,219,183✔
2859
        .dataType = TSDB_DATA_TYPE_TINYINT,
2860
        .cmprAlg = info->cmprAlg,
1,219,183✔
2861
        .originalSize = info->bitmapOriginalSize,
1,219,183✔
2862
        .compressedSize = info->bitmapCompressedSize,
1,219,183✔
2863
    };
2864

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

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

2877
    data += cinfo.compressedSize;
1,219,137✔
2878
  }
2879

2880
  if (info->flag == (HAS_NONE | HAS_NULL)) {
4,731,189✔
2881
    goto _exit;
601✔
2882
  }
2883

2884
  // offset
2885
  if (info->offsetOriginalSize > 0) {
4,730,588✔
2886
    SCompressInfo cinfo = {
1,140,532✔
2887
        .cmprAlg = info->cmprAlg,
1,140,532✔
2888
        .dataType = TSDB_DATA_TYPE_INT,
2889
        .originalSize = info->offsetOriginalSize,
1,140,532✔
2890
        .compressedSize = info->offsetCompressedSize,
1,140,532✔
2891
    };
2892

2893
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
1,140,532!
2894
    if (code) {
1,140,694!
2895
      tBufferDestroy(&local);
2896
      return code;
×
2897
    }
2898

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

2905
    data += cinfo.compressedSize;
1,140,785✔
2906
  }
2907

2908
  // data
2909
  if (info->dataOriginalSize > 0) {
4,730,841✔
2910
    colData->nData = info->dataOriginalSize;
4,730,690✔
2911

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

2919
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
4,730,690!
2920
    if (code) {
4,731,002!
2921
      tBufferDestroy(&local);
2922
      return code;
×
2923
    }
2924

2925
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
4,731,002✔
2926
    if (code) {
4,731,867!
2927
      tBufferDestroy(&local);
2928
      return code;
×
2929
    }
2930

2931
    data += cinfo.compressedSize;
4,731,867✔
2932
  }
2933

2934
_exit:
151✔
2935
  switch (colData->flag) {
5,500,235✔
2936
    case HAS_NONE:
441,492✔
2937
      colData->numOfNone = colData->nVal;
441,492✔
2938
      break;
441,492✔
2939
    case HAS_NULL:
328,848✔
2940
      colData->numOfNull = colData->nVal;
328,848✔
2941
      break;
328,848✔
2942
    case HAS_VALUE:
3,512,907✔
2943
      colData->numOfValue = colData->nVal;
3,512,907✔
2944
      break;
3,512,907✔
2945
    default:
1,216,988✔
2946
      for (int32_t i = 0; i < colData->nVal; i++) {
271,224,645✔
2947
        uint8_t bitValue = tColDataGetBitValue(colData, i);
270,005,291✔
2948
        if (bitValue == 0) {
270,007,657✔
2949
          colData->numOfNone++;
6,103,214✔
2950
        } else if (bitValue == 1) {
263,904,443✔
2951
          colData->numOfNull++;
21,001,537✔
2952
        } else {
2953
          colData->numOfValue++;
242,902,906✔
2954
        }
2955
      }
2956
  }
2957
  tBufferDestroy(&local);
2958
  return 0;
5,502,601✔
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) {
614✔
3040
  int32_t code = 0;
614✔
3041

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

3048
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
614!
3049
    for (int32_t i = 0; i < pBind->num; ++i) {
781✔
3050
      if (pBind->is_null && pBind->is_null[i]) {
688✔
3051
        if (pColData->cflag & COL_IS_KEY) {
9✔
3052
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
2✔
3053
          goto _exit;
2✔
3054
        }
3055
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
7✔
3056
        if (code) goto _exit;
7!
3057
      } else if (pBind->length[i] > buffMaxLen) {
679!
3058
        uError("var data length too big, len:%d, max:%d", pBind->length[i], buffMaxLen);
×
3059
        return TSDB_CODE_INVALID_PARA;
×
3060
      } else {
3061
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
679✔
3062
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
679✔
3063
      }
3064
    }
3065
  } else {  // fixed-length data type
3066
    bool allValue;
3067
    bool allNull;
3068
    if (pBind->is_null) {
520✔
3069
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
469✔
3070
      allNull = (same && pBind->is_null[0] != 0);
469✔
3071
      allValue = (same && pBind->is_null[0] == 0);
469✔
3072
    } else {
3073
      allNull = false;
51✔
3074
      allValue = true;
51✔
3075
    }
3076

3077
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
520✔
3078
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
4✔
3079
      goto _exit;
4✔
3080
    }
3081

3082
    if (allValue) {
516✔
3083
      // optimize (todo)
3084
      for (int32_t i = 0; i < pBind->num; ++i) {
4,353✔
3085
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
3,850✔
3086
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
3,850✔
3087
      }
3088
    } else if (allNull) {
29✔
3089
      // optimize (todo)
3090
      for (int32_t i = 0; i < pBind->num; ++i) {
4✔
3091
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
2✔
3092
        if (code) goto _exit;
2!
3093
      }
3094
    } else {
3095
      for (int32_t i = 0; i < pBind->num; ++i) {
106✔
3096
        if (pBind->is_null[i]) {
79✔
3097
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
29✔
3098
          if (code) goto _exit;
29!
3099
        } else {
3100
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
50✔
3101
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
50✔
3102
        }
3103
      }
3104
    }
3105
  }
3106

3107
_exit:
27✔
3108
  return code;
631✔
3109
}
3110

3111
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen) {
×
3112
  int32_t code = 0;
×
3113

3114
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
×
3115
    if (!(pColData->type == pBind->buffer_type)) {
×
3116
      return TSDB_CODE_INVALID_PARA;
×
3117
    }
3118
  }
3119

3120
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
×
3121
    uint8_t *buf = pBind->buffer;
×
3122
    for (int32_t i = 0; i < pBind->num; ++i) {
×
3123
      if (pBind->is_null && pBind->is_null[i]) {
×
3124
        if (pColData->cflag & COL_IS_KEY) {
×
3125
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3126
          goto _exit;
×
3127
        }
3128
        if (pBind->is_null[i] == 1) {
×
3129
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3130
          if (code) goto _exit;
×
3131
        } else {
3132
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3133
          if (code) goto _exit;
×
3134
        }
3135
      } else if (pBind->length[i] > buffMaxLen) {
×
3136
        uError("var data length too big, len:%d, max:%d", pBind->length[i], buffMaxLen);
×
3137
        return TSDB_CODE_INVALID_PARA;
×
3138
      } else {
3139
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);
×
3140
        buf += pBind->length[i];
×
3141
      }
3142
    }
3143
  } else {  // fixed-length data type
3144
    bool allValue;
3145
    bool allNull;
3146
    bool allNone;
3147
    if (pBind->is_null) {
×
3148
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
×
3149
      allNull = (same && pBind->is_null[0] == 1);
×
3150
      allNone = (same && pBind->is_null[0] > 1);
×
3151
      allValue = (same && pBind->is_null[0] == 0);
×
3152
    } else {
3153
      allNull = false;
×
3154
      allNone = false;
×
3155
      allValue = true;
×
3156
    }
3157

3158
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
×
3159
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3160
      goto _exit;
×
3161
    }
3162

3163
    if (allValue) {
×
3164
      // optimize (todo)
3165
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3166
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3167
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3168
          *val = 1;
×
3169
        }
3170

3171
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3172
      }
3173
    } else if (allNull) {
×
3174
      // optimize (todo)
3175
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3176
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3177
        if (code) goto _exit;
×
3178
      }
3179
    } else if (allNone) {
×
3180
      // optimize (todo)
3181
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3182
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3183
        if (code) goto _exit;
×
3184
      }
3185
    } else {
3186
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3187
        if (pBind->is_null[i]) {
×
3188
          if (pBind->is_null[i] == 1) {
×
3189
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3190
            if (code) goto _exit;
×
3191
          } else {
3192
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3193
            if (code) goto _exit;
×
3194
          }
3195
        } else {
3196
          uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3197
          if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3198
            *val = 1;
×
3199
          }
3200

3201
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3202
        }
3203
      }
3204
    }
3205
  }
3206

3207
_exit:
×
3208
  return code;
×
3209
}
3210

3211
/* build rows to `rowArray` from bind
3212
 * `infos` is the bind information array
3213
 * `numOfInfos` is the number of bind information
3214
 * `infoSorted` is whether the bind information is sorted by column id
3215
 * `pTSchema` is the schema of the table
3216
 * `rowArray` is the array to store the rows
3217
 */
3218
int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
×
3219
                           SArray *rowArray) {
3220
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
×
3221
    return TSDB_CODE_INVALID_PARA;
×
3222
  }
3223

3224
  if (!infoSorted) {
×
3225
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
3226
  }
3227

3228
  int32_t code = 0;
×
3229
  int32_t numOfRows = infos[0].bind->num;
×
3230
  SArray *colValArray, *bufArray;
3231
  SColVal colVal;
3232

3233
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
×
3234
    return terrno;
×
3235
  }
3236
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
×
3237
    taosArrayDestroy(colValArray);
×
3238
    return terrno;
×
3239
  }
3240
  for (int i = 0; i < numOfInfos; ++i) {
×
3241
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
×
3242
      taosArrayDestroy(colValArray);
×
3243
      taosArrayDestroy(bufArray);
×
3244
      return terrno;
×
3245
    }
3246
  }
3247

3248
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
3249
    taosArrayClear(colValArray);
×
3250

3251
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
×
3252
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
×
3253
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
3254
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
3255
        } else {
3256
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3257
        }
3258
      } else {
3259
        SValue value = {
×
3260
            .type = infos[iInfo].type,
×
3261
        };
3262
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
×
3263
          int32_t   length = infos[iInfo].bind->length[iRow];
×
3264
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
×
3265
          value.nData = length;
×
3266
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
×
3267
            code = TSDB_CODE_INVALID_PARA;
×
3268
            goto _exit;
×
3269
          }
3270
          value.pData = *data;
×
3271
          *data += length;
×
3272
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3273
        } else {
3274
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
×
3275
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
×
3276
            *val = 1;
×
3277
          }
3278
          (void)memcpy(&value.val, val,
×
3279
                       /*(uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,*/
3280
                       infos[iInfo].bytes /*bind->buffer_length*/);
×
3281
        }
3282
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
×
3283
      }
3284
      if (taosArrayPush(colValArray, &colVal) == NULL) {
×
3285
        code = terrno;
×
3286
        goto _exit;
×
3287
      }
3288
    }
3289

3290
    SRow *row;
3291
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
×
3292
      goto _exit;
×
3293
    }
3294

3295
    if ((taosArrayPush(rowArray, &row)) == NULL) {
×
3296
      code = terrno;
×
3297
      goto _exit;
×
3298
    }
3299
  }
3300

3301
_exit:
×
3302
  taosArrayDestroy(colValArray);
×
3303
  taosArrayDestroy(bufArray);
×
3304
  return code;
×
3305
}
3306

3307
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
286✔
3308
  int32_t code = TSDB_CODE_SUCCESS;
286✔
3309

3310
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
286!
3311
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
116✔
3312
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
42✔
3313
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
58✔
3314
    if (iToRow == 0) {
58✔
3315
      pToColData->aOffset[iToRow] = 0;
8✔
3316
    }
3317

3318
    if (iToRow < pToColData->nVal - 1) {
58✔
3319
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
52✔
3320
    }
3321

3322
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
58✔
3323
                 nData);
3324
  } else {
3325
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
228✔
3326
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
228✔
3327
  }
3328
  return code;
286✔
3329
}
3330

3331
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
294✔
3332
                                        int32_t iToRow) {
3333
  int32_t code = TSDB_CODE_SUCCESS;
294✔
3334

3335
  switch (pFromColData->flag) {
294!
3336
    case HAS_NONE:
8✔
3337
    case HAS_NULL:
3338
      break;
8✔
3339
    case (HAS_NULL | HAS_NONE): {
×
3340
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
3341
    } break;
×
3342
    case HAS_VALUE: {
238✔
3343
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
238!
3344
    } break;
238✔
3345
    case (HAS_VALUE | HAS_NONE):
48✔
3346
    case (HAS_VALUE | HAS_NULL): {
3347
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
48✔
3348
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
48!
3349
    } break;
48✔
3350
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
3351
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
3352
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3353
    } break;
×
3354
    default:
×
3355
      return -1;
×
3356
  }
3357

3358
  return code;
294✔
3359
}
3360

3361
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
60✔
3362
                               int32_t nColData) {
3363
  int32_t code = TSDB_CODE_SUCCESS;
60✔
3364

3365
  for (int32_t i = 0; i < nColData; i++) {
354✔
3366
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
294✔
3367
    if (code != TSDB_CODE_SUCCESS) {
294!
3368
      return code;
×
3369
    }
3370
  }
3371

3372
  return code;
60✔
3373
}
3374

3375
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
60✔
3376
  int32_t code = TSDB_CODE_SUCCESS;
60✔
3377

3378
  for (int32_t i = 0; i < nColData; i++) {
354✔
3379
    SColVal cv = {0};
294✔
3380
    tColDataGetValue(&aFromColData[i], iFromRow, &cv);
294✔
3381
    code = tColDataAppendValue(&aToColData[i], &cv);
294✔
3382
    if (code != TSDB_CODE_SUCCESS) {
294!
3383
      return code;
×
3384
    }
3385
  }
3386

3387
  return code;
60✔
3388
}
3389

3390
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
1,244✔
3391
  SColVal cv;
3392

3393
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
1,244✔
3394
  key->numOfPKs = 0;
1,244✔
3395

3396
  for (int i = 1; i < nColData; i++) {
1,310!
3397
    if (aColData[i].cflag & COL_IS_KEY) {
1,310✔
3398
      tColDataGetValue4(&aColData[i], iRow, &cv);
66✔
3399
      key->pks[key->numOfPKs++] = cv.value;
66✔
3400
    } else {
3401
      break;
1,244✔
3402
    }
3403
  }
3404
}
1,244✔
3405

3406
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
17✔
3407
  SColData *aDstColData = NULL;
17✔
3408
  int32_t   i = start, j = mid + 1, k = 0;
17✔
3409
  SRowKey   keyi, keyj;
3410

3411
  if (end > start) {
17!
3412
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
17✔
3413
    if (aDstColData == NULL) {
17!
3414
      return terrno;
×
3415
    }
3416
    for (int c = 0; c < nColData; ++c) {
99✔
3417
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
82✔
3418
    }
3419
  }
3420

3421
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
17✔
3422
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
17✔
3423
  while (i <= mid && j <= end) {
48✔
3424
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
31✔
3425
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
24!
3426
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
24✔
3427
    } else {
3428
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
7!
3429
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
7✔
3430
    }
3431
  }
3432

3433
  while (i <= mid) {
26✔
3434
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
9!
3435
  }
3436

3437
  while (j <= end) {
37✔
3438
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
20!
3439
  }
3440

3441
  for (i = start, k = 0; i <= end; ++i, ++k) {
77✔
3442
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
60!
3443
  }
3444

3445
  if (aDstColData) {
17!
3446
    for (int32_t i = 0; i < nColData; i++) {
99✔
3447
      tColDataDestroy(&aDstColData[i]);
82✔
3448
    }
3449
    taosMemoryFree(aDstColData);
17✔
3450
  }
3451

3452
  return TSDB_CODE_SUCCESS;
17✔
3453
}
3454

3455
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
37✔
3456
  int32_t ret = TSDB_CODE_SUCCESS;
37✔
3457
  int32_t mid;
3458

3459
  if (start >= end) {
37✔
3460
    return TSDB_CODE_SUCCESS;
20✔
3461
  }
3462

3463
  mid = (start + end) / 2;
17✔
3464

3465
  ret = tColDataMergeSort(aColData, start, mid, nColData);
17✔
3466
  if (ret != TSDB_CODE_SUCCESS) {
17!
3467
    return ret;
×
3468
  }
3469

3470
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
17✔
3471
  if (ret != TSDB_CODE_SUCCESS) {
17!
3472
    return ret;
×
3473
  }
3474

3475
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
17✔
3476
}
3477

3478
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
3✔
3479
  int32_t nVal = aColData[0].nVal;
3✔
3480

3481
  if (nVal < 2) return TSDB_CODE_SUCCESS;
3!
3482

3483
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
3✔
3484
}
3485

3486
static int32_t tColDataMerge(SArray **colArr) {
3✔
3487
  int32_t code = 0;
3✔
3488
  SArray *src = *colArr;
3✔
3489
  SArray *dst = NULL;
3✔
3490

3491
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
3✔
3492
  if (dst == NULL) {
3!
3493
    return terrno;
×
3494
  }
3495

3496
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
12✔
3497
    SColData *srcCol = taosArrayGet(src, i);
9✔
3498

3499
    SColData *dstCol = taosArrayReserve(dst, 1);
9✔
3500
    if (dstCol == NULL) {
9!
3501
      code = terrno;
×
3502
      goto _exit;
×
3503
    }
3504
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
9✔
3505
  }
3506

3507
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
3✔
3508
  SRowKey lastKey;
3509
  for (int32_t i = 0; i < numRows; i++) {
9✔
3510
    SRowKey key;
3511
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
3512

3513
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
9!
3514
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3515
        SColData *srcCol = taosArrayGet(src, j);
9✔
3516
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3517

3518
        SColVal cv;
3519
        tColDataGetValue(srcCol, i, &cv);
9✔
3520
        code = tColDataAppendValue(dstCol, &cv);
9✔
3521
        if (code) {
9!
3522
          goto _exit;
×
3523
        }
3524
      }
3525
      lastKey = key;
3✔
3526
    } else {  // update existing row
3527
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3528
        SColData *srcCol = taosArrayGet(src, j);
9✔
3529
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3530

3531
        SColVal cv;
3532
        tColDataGetValue(srcCol, i, &cv);
9✔
3533
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3534
        if (code) {
9!
3535
          goto _exit;
×
3536
        }
3537
      }
3538
    }
3539
  }
3540

3541
_exit:
3✔
3542
  if (code) {
3!
3543
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3544
  } else {
3545
    taosArrayDestroyEx(src, tColDataDestroy);
3✔
3546
    *colArr = dst;
3✔
3547
  }
3548
  return code;
3✔
3549
}
3550

3551
int32_t tColDataSortMerge(SArray **arr) {
181✔
3552
  SArray   *colDataArr = *arr;
181✔
3553
  int32_t   nColData = TARRAY_SIZE(colDataArr);
181✔
3554
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
181✔
3555

3556
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
181!
3557
    return TSDB_CODE_INVALID_PARA;
×
3558
  }
3559
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
181!
3560
    return TSDB_CODE_INVALID_PARA;
×
3561
  }
3562
  if (!(aColData[0].flag == HAS_VALUE)) {
181!
3563
    return TSDB_CODE_INVALID_PARA;
×
3564
  }
3565

3566
  if (aColData[0].nVal <= 1) goto _exit;
181✔
3567

3568
  int8_t doSort = 0;
73✔
3569
  int8_t doMerge = 0;
73✔
3570
  // scan -------
3571
  SRowKey lastKey;
3572
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
73✔
3573
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
454✔
3574
    SRowKey key;
3575
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
384✔
3576

3577
    int32_t c = tRowKeyCompare(&lastKey, &key);
384✔
3578
    if (c < 0) {
384✔
3579
      lastKey = key;
378✔
3580
      continue;
378✔
3581
    } else if (c > 0) {
6✔
3582
      doSort = 1;
3✔
3583
      break;
3✔
3584
    } else {
3585
      doMerge = 1;
3✔
3586
    }
3587
  }
3588

3589
  // sort -------
3590
  if (doSort) {
73✔
3591
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
3!
3592
  }
3593

3594
  if (doMerge != 1) {
73✔
3595
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
70✔
3596
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
463✔
3597
      SRowKey key;
3598
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
393✔
3599

3600
      int32_t c = tRowKeyCompare(&lastKey, &key);
393✔
3601
      if (c == 0) {
393!
3602
        doMerge = 1;
×
3603
        break;
×
3604
      }
3605
      lastKey = key;
393✔
3606
    }
3607
  }
3608

3609
  // merge -------
3610
  if (doMerge) {
73✔
3611
    int32_t code = tColDataMerge(arr);
3✔
3612
    if (code) return code;
3!
3613
  }
3614

3615
_exit:
73✔
3616
  return 0;
181✔
3617
}
3618

3619
static int32_t tPutColDataVersion0(uint8_t *pBuf, SColData *pColData) {
2,226✔
3620
  int32_t n = 0;
2,226✔
3621

3622
  n += tPutI16v(pBuf ? pBuf + n : NULL, pColData->cid);
2,226✔
3623
  n += tPutI8(pBuf ? pBuf + n : NULL, pColData->type);
2,226✔
3624
  n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nVal);
2,226✔
3625
  n += tPutI8(pBuf ? pBuf + n : NULL, pColData->flag);
2,226✔
3626

3627
  // bitmap
3628
  switch (pColData->flag) {
2,226!
3629
    case (HAS_NULL | HAS_NONE):
88✔
3630
    case (HAS_VALUE | HAS_NONE):
3631
    case (HAS_VALUE | HAS_NULL):
3632
      if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
88✔
3633
      n += BIT1_SIZE(pColData->nVal);
88✔
3634
      break;
88✔
3635
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3636
      if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
3637
      n += BIT2_SIZE(pColData->nVal);
×
3638
      break;
×
3639
    default:
2,138✔
3640
      break;
2,138✔
3641
  }
3642

3643
  // value
3644
  if (pColData->flag & HAS_VALUE) {
2,226✔
3645
    if (IS_VAR_DATA_TYPE(pColData->type)) {
2,043!
3646
      if (pBuf) (void)memcpy(pBuf + n, pColData->aOffset, pColData->nVal << 2);
354✔
3647
      n += (pColData->nVal << 2);
354✔
3648

3649
      n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nData);
354✔
3650
      if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
354✔
3651
      n += pColData->nData;
354✔
3652
    } else {
3653
      if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
1,689✔
3654
      n += pColData->nData;
1,689✔
3655
    }
3656
  }
3657

3658
  return n;
2,226✔
3659
}
3660

3661
static int32_t tGetColDataVersion0(uint8_t *pBuf, SColData *pColData) {
2,171✔
3662
  int32_t n = 0;
2,171✔
3663

3664
  n += tGetI16v(pBuf + n, &pColData->cid);
2,171!
3665
  n += tGetI8(pBuf + n, &pColData->type);
2,171!
3666
  n += tGetI32v(pBuf + n, &pColData->nVal);
2,171!
3667
  n += tGetI8(pBuf + n, &pColData->flag);
2,171!
3668

3669
  // bitmap
3670
  switch (pColData->flag) {
2,171!
3671
    case (HAS_NULL | HAS_NONE):
112✔
3672
    case (HAS_VALUE | HAS_NONE):
3673
    case (HAS_VALUE | HAS_NULL):
3674
      pColData->pBitMap = pBuf + n;
112✔
3675
      n += BIT1_SIZE(pColData->nVal);
112✔
3676
      break;
112✔
3677
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3678
      pColData->pBitMap = pBuf + n;
×
3679
      n += BIT2_SIZE(pColData->nVal);
×
3680
      break;
×
3681
    default:
2,059✔
3682
      break;
2,059✔
3683
  }
3684

3685
  // value
3686
  if (pColData->flag & HAS_VALUE) {
2,171✔
3687
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,975!
3688
      pColData->aOffset = (int32_t *)(pBuf + n);
397✔
3689
      n += (pColData->nVal << 2);
397✔
3690

3691
      n += tGetI32v(pBuf + n, &pColData->nData);
397!
3692
      pColData->pData = pBuf + n;
397✔
3693
      n += pColData->nData;
397✔
3694
    } else {
3695
      pColData->pData = pBuf + n;
1,578✔
3696
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
1,578✔
3697
      n += pColData->nData;
1,578✔
3698
    }
3699
  }
3700
  pColData->cflag = 0;
2,171✔
3701

3702
  return n;
2,171✔
3703
}
3704

3705
static int32_t tPutColDataVersion1(uint8_t *pBuf, SColData *pColData) {
2,226✔
3706
  int32_t n = tPutColDataVersion0(pBuf, pColData);
2,226✔
3707
  n += tPutI8(pBuf ? pBuf + n : NULL, pColData->cflag);
2,225✔
3708
  return n;
2,225✔
3709
}
3710

3711
static int32_t tGetColDataVersion1(uint8_t *pBuf, SColData *pColData) {
2,171✔
3712
  int32_t n = tGetColDataVersion0(pBuf, pColData);
2,171✔
3713
  n += tGetI8(pBuf ? pBuf + n : NULL, &pColData->cflag);
2,171!
3714
  return n;
2,171✔
3715
}
3716

3717
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
2,227✔
3718
  if (version == 0) {
2,227!
3719
    return tPutColDataVersion0(pBuf, pColData);
×
3720
  } else if (version == 1) {
2,227!
3721
    return tPutColDataVersion1(pBuf, pColData);
2,227✔
3722
  } else {
3723
    return TSDB_CODE_INVALID_PARA;
×
3724
  }
3725
}
3726

3727
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
2,171✔
3728
  if (version == 0) {
2,171!
3729
    return tGetColDataVersion0(pBuf, pColData);
×
3730
  } else if (version == 1) {
2,171!
3731
    return tGetColDataVersion1(pBuf, pColData);
2,171✔
3732
  } else {
3733
    return TSDB_CODE_INVALID_PARA;
×
3734
  }
3735
}
3736

3737
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3738
  do {                                       \
3739
    (SUM) += (VAL);                          \
3740
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3741
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3742
  } while (0)
3743

3744
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
5,791✔
3745
                                             int16_t *numOfNull) {
3746
  *sum = 0;
5,791✔
3747
  *max = 0;
5,791✔
3748
  *min = 1;
5,791✔
3749
  *numOfNull = 0;
5,791✔
3750

3751
  int8_t val;
3752
  if (HAS_VALUE == pColData->flag) {
5,791✔
3753
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,992,346✔
3754
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
3,988,023✔
3755
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
3,988,023✔
3756
    }
3757
  } else {
3758
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
3759
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
3760
        case 0:
236,373✔
3761
        case 1:
3762
          (*numOfNull)++;
236,373✔
3763
          break;
236,373✔
3764
        case 2:
4,498,776✔
3765
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,498,776✔
3766
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,498,776✔
3767
          break;
4,498,776✔
3768
        default:
×
3769
          break;
×
3770
      }
3771
    }
3772
  }
3773
}
5,791✔
3774

3775
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
5,827✔
3776
                                                int16_t *numOfNull) {
3777
  *sum = 0;
5,827✔
3778
  *max = INT8_MIN;
5,827✔
3779
  *min = INT8_MAX;
5,827✔
3780
  *numOfNull = 0;
5,827✔
3781

3782
  int8_t val;
3783
  if (HAS_VALUE == pColData->flag) {
5,827✔
3784
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,111,727✔
3785
      val = ((int8_t *)pColData->pData)[iVal];
4,107,368✔
3786
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,107,368✔
3787
    }
3788
  } else {
3789
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
3790
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
3791
        case 0:
237,156✔
3792
        case 1:
3793
          (*numOfNull)++;
237,156✔
3794
          break;
237,156✔
3795
        case 2:
4,497,993✔
3796
          val = ((int8_t *)pColData->pData)[iVal];
4,497,993✔
3797
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,497,993✔
3798
          break;
4,497,993✔
3799
        default:
×
3800
          break;
×
3801
      }
3802
    }
3803
  }
3804
}
5,827✔
3805

3806
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
5,826✔
3807
                                                     int16_t *numOfNull) {
3808
  *sum = 0;
5,826✔
3809
  *max = INT16_MIN;
5,826✔
3810
  *min = INT16_MAX;
5,826✔
3811
  *numOfNull = 0;
5,826✔
3812

3813
  int16_t val;
3814
  if (HAS_VALUE == pColData->flag) {
5,826✔
3815
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,110,229✔
3816
      val = ((int16_t *)pColData->pData)[iVal];
4,105,870✔
3817
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,105,870✔
3818
    }
3819
  } else {
3820
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,616✔
3821
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
3822
        case 0:
237,038✔
3823
        case 1:
3824
          (*numOfNull)++;
237,038✔
3825
          break;
237,038✔
3826
        case 2:
4,498,111✔
3827
          val = ((int16_t *)pColData->pData)[iVal];
4,498,111✔
3828
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,498,111✔
3829
          break;
4,498,111✔
3830
        default:
×
3831
          break;
×
3832
      }
3833
    }
3834
  }
3835
}
5,826✔
3836

3837
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
19,616✔
3838
                                            int16_t *numOfNull) {
3839
  *sum = 0;
19,616✔
3840
  *max = INT32_MIN;
19,616✔
3841
  *min = INT32_MAX;
19,616✔
3842
  *numOfNull = 0;
19,616✔
3843

3844
  int32_t val;
3845
  if (HAS_VALUE == pColData->flag) {
19,616✔
3846
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
36,555,860✔
3847
      val = ((int32_t *)pColData->pData)[iVal];
36,541,640✔
3848
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
36,541,640✔
3849
    }
3850
  } else {
3851
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
20,497,101✔
3852
      switch (tColDataGetBitValue(pColData, iVal)) {
20,494,184!
3853
        case 0:
1,817,461✔
3854
        case 1:
3855
          (*numOfNull)++;
1,817,461✔
3856
          break;
1,817,461✔
3857
        case 2:
18,682,691✔
3858
          val = ((int32_t *)pColData->pData)[iVal];
18,682,691✔
3859
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
18,682,691✔
3860
          break;
18,682,691✔
3861
        default:
×
3862
          break;
×
3863
      }
3864
    }
3865
  }
3866
}
17,137✔
3867

3868
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
11,634✔
3869
                                               int16_t *numOfNull) {
3870
  *sum = 0;
11,634✔
3871
  *max = INT64_MIN;
11,634✔
3872
  *min = INT64_MAX;
11,634✔
3873
  *numOfNull = 0;
11,634✔
3874

3875
  int64_t val;
3876
  if (HAS_VALUE == pColData->flag) {
11,634✔
3877
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,045,871✔
3878
      val = ((int64_t *)pColData->pData)[iVal];
9,040,394✔
3879
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
9,040,394✔
3880
    }
3881
  } else {
3882
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
20,659,173✔
3883
      switch (tColDataGetBitValue(pColData, iVal)) {
20,653,006!
3884
        case 0:
1,922,517✔
3885
        case 1:
3886
          (*numOfNull)++;
1,922,517✔
3887
          break;
1,922,517✔
3888
        case 2:
18,731,955✔
3889
          val = ((int64_t *)pColData->pData)[iVal];
18,731,955✔
3890
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
18,731,955✔
3891
          break;
18,731,955✔
3892
        default:
×
3893
          break;
×
3894
      }
3895
    }
3896
  }
3897
}
11,644✔
3898

3899
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
11,312✔
3900
                                              int16_t *numOfNull) {
3901
  *(double *)sum = 0;
11,312✔
3902
  *(double *)max = -FLT_MAX;
11,312✔
3903
  *(double *)min = FLT_MAX;
11,312✔
3904
  *numOfNull = 0;
11,312✔
3905

3906
  float val;
3907
  if (HAS_VALUE == pColData->flag) {
11,312✔
3908
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
25,642,444✔
3909
      val = ((float *)pColData->pData)[iVal];
25,632,601✔
3910
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
25,632,601✔
3911
    }
3912
  } else {
3913
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,723✔
3914
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,254!
3915
        case 0:
237,989✔
3916
        case 1:
3917
          (*numOfNull)++;
237,989✔
3918
          break;
237,989✔
3919
        case 2:
4,497,265✔
3920
          val = ((float *)pColData->pData)[iVal];
4,497,265✔
3921
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,497,265✔
3922
          break;
4,497,265✔
3923
        default:
×
3924
          break;
×
3925
      }
3926
    }
3927
  }
3928
}
11,312✔
3929

3930
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
6,918✔
3931
                                               int16_t *numOfNull) {
3932
  *(double *)sum = 0;
6,918✔
3933
  *(double *)max = -DBL_MAX;
6,918✔
3934
  *(double *)min = DBL_MAX;
6,918✔
3935
  *numOfNull = 0;
6,918✔
3936

3937
  double val;
3938
  if (HAS_VALUE == pColData->flag) {
6,918✔
3939
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
10,873,593✔
3940
      val = ((double *)pColData->pData)[iVal];
10,868,143✔
3941
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
10,868,143✔
3942
    }
3943
  } else {
3944
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
3945
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
3946
        case 0:
237,365✔
3947
        case 1:
3948
          (*numOfNull)++;
237,365✔
3949
          break;
237,365✔
3950
        case 2:
4,497,784✔
3951
          val = ((double *)pColData->pData)[iVal];
4,497,784✔
3952
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
4,497,784✔
3953
          break;
4,497,784✔
3954
        default:
×
3955
          break;
×
3956
      }
3957
    }
3958
  }
3959
}
6,918✔
3960

3961
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
2,928✔
3962
                                                 int16_t *numOfNull) {
3963
  *(uint64_t *)sum = 0;
2,928✔
3964
  *(uint64_t *)max = 0;
2,928✔
3965
  *(uint64_t *)min = UINT8_MAX;
2,928✔
3966
  *numOfNull = 0;
2,928✔
3967

3968
  uint8_t val;
3969
  if (HAS_VALUE == pColData->flag) {
2,928✔
3970
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,261,520✔
3971
      val = ((uint8_t *)pColData->pData)[iVal];
3,260,060✔
3972
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,260,060✔
3973
    }
3974
  } else {
3975
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
3976
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
3977
        case 0:
235,635✔
3978
        case 1:
3979
          (*numOfNull)++;
235,635✔
3980
          break;
235,635✔
3981
        case 2:
4,499,514✔
3982
          val = ((uint8_t *)pColData->pData)[iVal];
4,499,514✔
3983
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,499,514✔
3984
          break;
4,499,514✔
3985
        default:
×
3986
          break;
×
3987
      }
3988
    }
3989
  }
3990
}
2,928✔
3991

3992
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
2,928✔
3993
                                                      int16_t *numOfNull) {
3994
  *(uint64_t *)sum = 0;
2,928✔
3995
  *(uint64_t *)max = 0;
2,928✔
3996
  *(uint64_t *)min = UINT16_MAX;
2,928✔
3997
  *numOfNull = 0;
2,928✔
3998

3999
  uint16_t val;
4000
  if (HAS_VALUE == pColData->flag) {
2,928✔
4001
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,261,520✔
4002
      val = ((uint16_t *)pColData->pData)[iVal];
3,260,060✔
4003
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,260,060✔
4004
    }
4005
  } else {
4006
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
4007
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
4008
        case 0:
236,434✔
4009
        case 1:
4010
          (*numOfNull)++;
236,434✔
4011
          break;
236,434✔
4012
        case 2:
4,498,715✔
4013
          val = ((uint16_t *)pColData->pData)[iVal];
4,498,715✔
4014
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,498,715✔
4015
          break;
4,498,715✔
4016
        default:
×
4017
          break;
×
4018
      }
4019
    }
4020
  }
4021
}
2,928✔
4022

4023
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
2,928✔
4024
                                             int16_t *numOfNull) {
4025
  *(uint64_t *)sum = 0;
2,928✔
4026
  *(uint64_t *)max = 0;
2,928✔
4027
  *(uint64_t *)min = UINT32_MAX;
2,928✔
4028
  *numOfNull = 0;
2,928✔
4029

4030
  uint32_t val;
4031
  if (HAS_VALUE == pColData->flag) {
2,928✔
4032
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,261,520✔
4033
      val = ((uint32_t *)pColData->pData)[iVal];
3,260,060✔
4034
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,260,060✔
4035
    }
4036
  } else {
4037
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
4038
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
4039
        case 0:
237,011✔
4040
        case 1:
4041
          (*numOfNull)++;
237,011✔
4042
          break;
237,011✔
4043
        case 2:
4,498,138✔
4044
          val = ((uint32_t *)pColData->pData)[iVal];
4,498,138✔
4045
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,498,138✔
4046
          break;
4,498,138✔
4047
        default:
×
4048
          break;
×
4049
      }
4050
    }
4051
  }
4052
}
2,928✔
4053

4054
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
2,928✔
4055
                                                int16_t *numOfNull) {
4056
  *(uint64_t *)sum = 0;
2,928✔
4057
  *(uint64_t *)max = 0;
2,928✔
4058
  *(uint64_t *)min = UINT64_MAX;
2,928✔
4059
  *numOfNull = 0;
2,928✔
4060

4061
  uint64_t val;
4062
  if (HAS_VALUE == pColData->flag) {
2,928✔
4063
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,261,520✔
4064
      val = ((uint64_t *)pColData->pData)[iVal];
3,260,060✔
4065
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,260,060✔
4066
    }
4067
  } else {
4068
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,736,617✔
4069
      switch (tColDataGetBitValue(pColData, iVal)) {
4,735,149!
4070
        case 0:
236,779✔
4071
        case 1:
4072
          (*numOfNull)++;
236,779✔
4073
          break;
236,779✔
4074
        case 2:
4,498,370✔
4075
          val = ((uint64_t *)pColData->pData)[iVal];
4,498,370✔
4076
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
4,498,370✔
4077
          break;
4,498,370✔
4078
        default:
×
4079
          break;
×
4080
      }
4081
    }
4082
  }
4083
}
2,928✔
4084

4085
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
20,991✔
4086
                                                int16_t *numOfNull) {
4087
  *(uint64_t *)sum = 0;
20,991✔
4088
  *(uint64_t *)max = 0;
20,991✔
4089
  *(uint64_t *)min = 0;
20,991✔
4090
  *numOfNull = 0;
20,991✔
4091

4092
  switch (pColData->flag) {
20,991!
4093
    case HAS_NONE:
×
4094
    case HAS_NULL:
4095
    case (HAS_NONE | HAS_NULL):
4096
      *numOfNull = pColData->nVal;
×
4097
      break;
×
4098
    case HAS_VALUE:
18,055✔
4099
      *numOfNull = 0;
18,055✔
4100
      break;
18,055✔
4101
    case (HAS_VALUE | HAS_NULL):
2,936✔
4102
    case (HAS_VALUE | HAS_NONE):
4103
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
9,473,234✔
4104
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
9,470,298✔
4105
          (*numOfNull)++;
472,218✔
4106
        }
4107
      }
4108
      break;
2,936✔
4109
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4110
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4111
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4112
          (*numOfNull)++;
×
4113
        }
4114
      }
4115
      break;
×
4116
    default:
×
4117
      break;
×
4118
  }
4119
}
20,991✔
4120

4121
void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull) = {
4122
    NULL,
4123
    tColDataCalcSMABool,           // TSDB_DATA_TYPE_BOOL
4124
    tColDataCalcSMATinyInt,        // TSDB_DATA_TYPE_TINYINT
4125
    tColDataCalcSMATinySmallInt,   // TSDB_DATA_TYPE_SMALLINT
4126
    tColDataCalcSMAInt,            // TSDB_DATA_TYPE_INT
4127
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_BIGINT
4128
    tColDataCalcSMAFloat,          // TSDB_DATA_TYPE_FLOAT
4129
    tColDataCalcSMADouble,         // TSDB_DATA_TYPE_DOUBLE
4130
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARCHAR
4131
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_TIMESTAMP
4132
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_NCHAR
4133
    tColDataCalcSMAUTinyInt,       // TSDB_DATA_TYPE_UTINYINT
4134
    tColDataCalcSMATinyUSmallInt,  // TSDB_DATA_TYPE_USMALLINT
4135
    tColDataCalcSMAUInt,           // TSDB_DATA_TYPE_UINT
4136
    tColDataCalcSMAUBigInt,        // TSDB_DATA_TYPE_UBIGINT
4137
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_JSON
4138
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARBINARY
4139
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_DECIMAL
4140
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_BLOB
4141
    NULL,                          // TSDB_DATA_TYPE_MEDIUMBLOB
4142
    tColDataCalcSMAVarType         // TSDB_DATA_TYPE_GEOMETRY
4143
};
4144

4145
// SValueColumn ================================
4146
int32_t tValueColumnInit(SValueColumn *valCol) {
8,214,481✔
4147
  valCol->type = TSDB_DATA_TYPE_NULL;
8,214,481✔
4148
  valCol->numOfValues = 0;
8,214,481✔
4149
  tBufferInit(&valCol->data);
8,214,481✔
4150
  tBufferInit(&valCol->offsets);
8,214,481✔
4151
  return 0;
8,214,481✔
4152
}
4153

4154
void tValueColumnDestroy(SValueColumn *valCol) {
23,063,208✔
4155
  valCol->type = TSDB_DATA_TYPE_NULL;
23,063,208✔
4156
  valCol->numOfValues = 0;
23,063,208✔
4157
  tBufferDestroy(&valCol->data);
23,063,208✔
4158
  tBufferDestroy(&valCol->offsets);
23,063,358✔
4159
  return;
23,063,338✔
4160
}
4161

4162
void tValueColumnClear(SValueColumn *valCol) {
10,971,129✔
4163
  valCol->type = TSDB_DATA_TYPE_NULL;
10,971,129✔
4164
  valCol->numOfValues = 0;
10,971,129✔
4165
  tBufferClear(&valCol->data);
10,971,129✔
4166
  tBufferClear(&valCol->offsets);
10,971,129✔
4167
  return;
10,971,129✔
4168
}
4169

4170
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
22,157✔
4171
  int32_t code;
4172

4173
  if (valCol->numOfValues == 0) {
22,157✔
4174
    valCol->type = value->type;
8,409✔
4175
  }
4176

4177
  if (!(value->type == valCol->type)) {
22,157!
4178
    return TSDB_CODE_INVALID_PARA;
×
4179
  }
4180

4181
  if (IS_VAR_DATA_TYPE(value->type)) {
22,157!
4182
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
19,156!
4183
      return code;
×
4184
    }
4185
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
19,156!
4186
      return code;
×
4187
    }
4188
  } else {
4189
    code = tBufferPut(&valCol->data, &value->val, tDataTypes[value->type].bytes);
12,579✔
4190
    if (code) return code;
12,579!
4191
  }
4192
  valCol->numOfValues++;
22,157✔
4193

4194
  return 0;
22,157✔
4195
}
4196

4197
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
188,722✔
4198
  int32_t code;
4199

4200
  if (idx < 0 || idx >= valCol->numOfValues) {
188,722!
4201
    return TSDB_CODE_OUT_OF_RANGE;
×
4202
  }
4203

4204
  if (IS_VAR_DATA_TYPE(valCol->type)) {
188,726!
4205
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
28,412✔
4206
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
28,412!
4207
    int32_t  oldDataSize = nextOffset - offsets[idx];
28,412✔
4208
    int32_t  bytesAdded = value->nData - oldDataSize;
28,412✔
4209

4210
    if (bytesAdded != 0) {
28,412✔
4211
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
24!
4212
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
12✔
4213
              tBufferGetSize(&valCol->data) - nextOffset);
12✔
4214
      valCol->data.size += bytesAdded;
12✔
4215

4216
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
12!
4217
        offsets[i] += bytesAdded;
×
4218
      }
4219
    }
4220
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
28,412✔
4221
  } else {
4222
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, &value->val,
160,330✔
4223
                        tDataTypes[valCol->type].bytes);
160,314✔
4224
  }
4225
  return 0;
4226
}
4227

4228
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
2,300,846✔
4229
  if (idx < 0 || idx >= valCol->numOfValues) {
2,300,846!
4230
    return TSDB_CODE_OUT_OF_RANGE;
×
4231
  }
4232

4233
  value->type = valCol->type;
2,300,900✔
4234
  if (IS_VAR_DATA_TYPE(value->type)) {
2,300,900!
4235
    int32_t       offset, nextOffset;
4236
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
870,821✔
4237

4238
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
870,821!
4239
    if (idx == valCol->numOfValues - 1) {
871,691✔
4240
      nextOffset = tBufferGetSize(&valCol->data);
335,762✔
4241
    } else {
4242
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
535,929✔
4243
    }
4244
    value->nData = nextOffset - offset;
871,272✔
4245
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
871,272✔
4246
  } else {
4247
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
1,430,079✔
4248
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, &value->val));
2,860,158!
4249
  }
4250
  return 0;
2,301,351✔
4251
}
4252

4253
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
8,411✔
4254
  int32_t code;
4255

4256
  if (!(valCol->numOfValues > 0)) {
8,411!
4257
    return TSDB_CODE_INVALID_PARA;
×
4258
  }
4259

4260
  (*info) = (SValueColumnCompressInfo){
8,411✔
4261
      .cmprAlg = info->cmprAlg,
8,411✔
4262
      .type = valCol->type,
8,411✔
4263
  };
4264

4265
  // offset
4266
  if (IS_VAR_DATA_TYPE(valCol->type)) {
8,411!
4267
    SCompressInfo cinfo = {
3,153✔
4268
        .cmprAlg = info->cmprAlg,
3,153✔
4269
        .dataType = TSDB_DATA_TYPE_INT,
4270
        .originalSize = valCol->offsets.size,
3,153✔
4271
    };
4272

4273
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
3,153✔
4274
    if (code) return code;
3,153!
4275

4276
    info->offsetOriginalSize = cinfo.originalSize;
3,153✔
4277
    info->offsetCompressedSize = cinfo.compressedSize;
3,153✔
4278
  }
4279

4280
  // data
4281
  SCompressInfo cinfo = {
8,411✔
4282
      .cmprAlg = info->cmprAlg,
8,411✔
4283
      .dataType = valCol->type,
8,411✔
4284
      .originalSize = valCol->data.size,
8,411✔
4285
  };
4286

4287
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
8,411✔
4288
  if (code) return code;
8,411!
4289

4290
  info->dataOriginalSize = cinfo.originalSize;
8,411✔
4291
  info->dataCompressedSize = cinfo.compressedSize;
8,411✔
4292

4293
  return 0;
8,411✔
4294
}
4295

4296
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
1,149,505✔
4297
                               SBuffer *assist) {
4298
  int32_t code;
4299

4300
  tValueColumnClear(valCol);
1,149,505✔
4301
  valCol->type = info->type;
1,149,499✔
4302
  // offset
4303
  if (IS_VAR_DATA_TYPE(valCol->type)) {
1,713,768!
4304
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
564,095✔
4305

4306
    SCompressInfo cinfo = {
564,095✔
4307
        .dataType = TSDB_DATA_TYPE_INT,
4308
        .cmprAlg = info->cmprAlg,
564,095✔
4309
        .originalSize = info->offsetOriginalSize,
564,095✔
4310
        .compressedSize = info->offsetCompressedSize,
564,095✔
4311
    };
4312

4313
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
564,095✔
4314
    if (code) {
564,269!
4315
      return code;
×
4316
    }
4317
  } else {
4318
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
585,404✔
4319
  }
4320

4321
  // data
4322
  SCompressInfo cinfo = {
1,149,673✔
4323
      .dataType = valCol->type,
1,149,673✔
4324
      .cmprAlg = info->cmprAlg,
1,149,673✔
4325
      .originalSize = info->dataOriginalSize,
1,149,673✔
4326
      .compressedSize = info->dataCompressedSize,
1,149,673✔
4327
  };
4328

4329
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
1,149,673✔
4330
  if (code) {
1,149,700!
4331
    return code;
×
4332
  }
4333

4334
  return 0;
1,149,700✔
4335
}
4336

4337
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
8,410✔
4338
  int32_t code;
4339
  uint8_t fmtVer = 0;
8,410✔
4340

4341
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
16,820!
4342
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
16,820!
4343
  if ((code = tBufferPutI8(buffer, info->type))) return code;
16,820!
4344
  if (IS_VAR_DATA_TYPE(info->type)) {
8,410!
4345
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
6,304!
4346
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
6,304!
4347
  }
4348
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
16,820!
4349
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
16,820!
4350

4351
  return 0;
8,410✔
4352
}
4353

4354
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
1,149,462✔
4355
  int32_t code;
4356
  uint8_t fmtVer;
4357

4358
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
1,149,462!
4359
  if (fmtVer == 0) {
1,149,375!
4360
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
1,149,382!
4361
    if ((code = tBufferGetI8(reader, &info->type))) return code;
1,149,184!
4362
    if (IS_VAR_DATA_TYPE(info->type)) {
1,149,092!
4363
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
563,833!
4364
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
564,038!
4365
    } else {
4366
      info->offsetOriginalSize = 0;
585,259✔
4367
      info->offsetCompressedSize = 0;
585,259✔
4368
    }
4369
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
1,149,275!
4370
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
1,149,142!
4371
  } else {
4372
    return TSDB_CODE_INVALID_PARA;
×
4373
  }
4374

4375
  return 0;
1,149,151✔
4376
}
4377

4378
int32_t tCompressData(void          *input,       // input
3,820,620✔
4379
                      SCompressInfo *info,        // compress info
4380
                      void          *output,      // output
4381
                      int32_t        outputSize,  // output size
4382
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4383
) {
4384
  int32_t extraSizeNeeded;
4385
  int32_t code;
4386

4387
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
3,820,620!
4388
  if (!(outputSize >= extraSizeNeeded)) {
3,820,620!
4389
    return TSDB_CODE_INVALID_PARA;
×
4390
  }
4391

4392
  if (info->cmprAlg == NO_COMPRESSION) {
3,820,620!
4393
    (void)memcpy(output, input, info->originalSize);
×
4394
    info->compressedSize = info->originalSize;
×
4395
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
4,642,453!
4396
    SBuffer local;
4397

4398
    tBufferInit(&local);
4399
    if (buffer == NULL) {
819,085!
4400
      buffer = &local;
×
4401
    }
4402

4403
    if (info->cmprAlg == TWO_STAGE_COMP) {
819,085!
4404
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
821,674✔
4405
      if (code) {
821,674!
4406
        tBufferDestroy(&local);
4407
        return code;
×
4408
      }
4409
    }
4410

4411
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
1,640,918✔
4412
        input,                                                   // input
4413
        info->originalSize,                                      // input size
4414
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
819,085✔
4415
        output,                                                  // output
4416
        outputSize,                                              // output size
4417
        info->cmprAlg,                                           // compression algorithm
819,085✔
4418
        buffer->data,                                            // buffer
4419
        buffer->capacity                                         // buffer size
819,085✔
4420
    );
4421
    if (info->compressedSize < 0) {
821,833!
4422
      tBufferDestroy(&local);
4423
      return TSDB_CODE_COMPRESS_ERROR;
×
4424
    }
4425

4426
    tBufferDestroy(&local);
4427
  } else {
4428
    DEFINE_VAR(info->cmprAlg)
3,001,535✔
4429
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
3,001,535!
4430
      (void)memcpy(output, input, info->originalSize);
×
4431
      info->compressedSize = info->originalSize;
×
4432
      return 0;
×
4433
    }
4434
    SBuffer local;
4435

4436
    tBufferInit(&local);
4437
    if (buffer == NULL) {
3,001,535!
4438
      buffer = &local;
×
4439
    }
4440
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
3,001,535✔
4441

4442
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
6,004,078✔
4443
        input,                                                      // input
4444
        info->originalSize,                                         // input size
4445
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
3,001,539✔
4446
        output,                                                     // output
4447
        outputSize,                                                 // output size
4448
        info->cmprAlg,                                              // compression algorithm
4449
        buffer->data,                                               // buffer
4450
        buffer->capacity                                            // buffer size
3,001,539✔
4451
    );
4452
    if (info->compressedSize < 0) {
3,002,539!
4453
      tBufferDestroy(&local);
4454
      return TSDB_CODE_COMPRESS_ERROR;
×
4455
    }
4456

4457
    tBufferDestroy(&local);
4458
    // new col compress
4459
  }
4460

4461
  return 0;
3,824,372✔
4462
}
4463

4464
int32_t tDecompressData(void                *input,       // input
26,698,765✔
4465
                        const SCompressInfo *info,        // compress info
4466
                        void                *output,      // output
4467
                        int32_t              outputSize,  // output size
4468
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4469
) {
4470
  int32_t code;
4471

4472
  if (!(outputSize >= info->originalSize)) {
26,698,765!
4473
    return TSDB_CODE_INVALID_PARA;
×
4474
  }
4475

4476
  if (info->cmprAlg == NO_COMPRESSION) {
26,698,765!
4477
    if (!(info->compressedSize == info->originalSize)) {
×
4478
      return TSDB_CODE_INVALID_PARA;
×
4479
    }
4480
    (void)memcpy(output, input, info->compressedSize);
×
4481
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
40,694,424!
4482
    SBuffer local;
4483

4484
    tBufferInit(&local);
4485
    if (buffer == NULL) {
13,967,083!
4486
      buffer = &local;
×
4487
    }
4488

4489
    if (info->cmprAlg == TWO_STAGE_COMP) {
13,967,083!
4490
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
13,992,318✔
4491
      if (code) {
13,992,387!
4492
        tBufferDestroy(&local);
4493
        return code;
×
4494
      }
4495
    }
4496

4497
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
13,967,152✔
4498
        input,                                                  // input
4499
        info->compressedSize,                                   // inputSize
13,967,152✔
4500
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
13,967,152✔
4501
        output,                                                 // output
4502
        outputSize,                                             // output size
4503
        info->cmprAlg,                                          // compression algorithm
13,967,152✔
4504
        buffer->data,                                           // helper buffer
4505
        buffer->capacity                                        // extra buffer size
13,967,152✔
4506
    );
4507
    if (decompressedSize < 0) {
13,995,659!
4508
      tBufferDestroy(&local);
4509
      return TSDB_CODE_COMPRESS_ERROR;
×
4510
    }
4511

4512
    if (!(decompressedSize == info->originalSize)) {
13,995,659!
4513
      return TSDB_CODE_COMPRESS_ERROR;
×
4514
    }
4515
    tBufferDestroy(&local);
4516
  } else {
4517
    DEFINE_VAR(info->cmprAlg);
12,731,682✔
4518
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
12,731,682!
4519
      (void)memcpy(output, input, info->compressedSize);
×
4520
      return 0;
×
4521
    }
4522
    SBuffer local;
4523

4524
    tBufferInit(&local);
4525
    if (buffer == NULL) {
12,731,682!
4526
      buffer = &local;
×
4527
    }
4528
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
12,731,682✔
4529
    if (code) {
12,731,874!
4530
      return code;
×
4531
    }
4532

4533
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
12,731,874✔
4534
        input,                                                  // input
4535
        info->compressedSize,                                   // inputSize
12,731,874✔
4536
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
12,731,874✔
4537
        output,                                                 // output
4538
        outputSize,                                             // output size
4539
        info->cmprAlg,                                          // compression algorithm
12,731,874✔
4540
        buffer->data,                                           // helper buffer
4541
        buffer->capacity                                        // extra buffer size
12,731,874✔
4542
    );
4543
    if (decompressedSize < 0) {
12,733,858!
4544
      tBufferDestroy(&local);
4545
      return TSDB_CODE_COMPRESS_ERROR;
×
4546
    }
4547

4548
    if (!(decompressedSize == info->originalSize)) {
12,733,858!
4549
      return TSDB_CODE_COMPRESS_ERROR;
×
4550
    }
4551
    tBufferDestroy(&local);
4552
  }
4553

4554
  return 0;
26,729,517✔
4555
}
4556

4557
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
3,821,105✔
4558
  int32_t code;
4559

4560
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
3,821,105✔
4561
  if (code) return code;
3,821,101!
4562

4563
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
3,821,101✔
4564
  if (code) return code;
3,821,978!
4565

4566
  output->size += info->compressedSize;
3,821,978✔
4567
  return 0;
3,821,978✔
4568
}
4569

4570
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
13,993,333✔
4571
  int32_t code;
4572

4573
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
13,993,333✔
4574
  if (code) return code;
13,991,034!
4575

4576
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
13,991,034✔
4577
  if (code) return code;
13,995,240!
4578

4579
  output->size += info->originalSize;
13,995,240✔
4580
  return 0;
13,995,240✔
4581
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc