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

taosdata / TDengine / #3873

21 Apr 2025 07:22AM UTC coverage: 63.063% (+0.1%) from 62.968%
#3873

push

travis-ci

GitHub
docs(opc): add perssit data support (#30783)

156631 of 316378 branches covered (49.51%)

Branch coverage included in aggregate %.

242184 of 316027 relevant lines covered (76.63%)

20271838.47 hits per line

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

64.82
/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 "decimal.h"
19
#include "tRealloc.h"
20
#include "tdatablock.h"
21
#include "tlog.h"
22

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

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

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

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

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

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

65
static int32_t tPutPrimaryKeyIndex(uint8_t *p, const SPrimaryKeyIndex *index) {
1,424,833,776✔
66
  int32_t n = 0;
1,424,833,776✔
67
  n += tPutI8(p ? p + n : p, index->type);
1,424,833,776✔
68
  n += tPutU32v(p ? p + n : p, index->offset);
1,424,833,776✔
69
  return n;
1,424,833,776✔
70
}
71

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

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

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

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

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

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

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

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

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

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

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

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

163
  *sinfo = (SRowBuildScanInfo){
1,662,661,329✔
164
      .tupleFixedSize = schema->flen,
1,662,661,329✔
165
  };
166

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

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

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

189
        colValIndex++;
2,147,483,647✔
190
        break;
2,147,483,647✔
191
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {
18,084,932✔
192
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
66!
193
        break;
33✔
194
      } else {  // skip useless value
195
        colValIndex++;
18,084,899✔
196
      }
197
    }
198
  }
199

200
  if (sinfo->numOfNone) {
1,662,661,329✔
201
    sinfo->flag |= HAS_NONE;
471,923,022✔
202
  }
203
  if (sinfo->numOfNull) {
1,662,661,329✔
204
    sinfo->flag |= HAS_NULL;
44,619,255✔
205
  }
206
  if (sinfo->numOfValue) {
1,662,661,329✔
207
    sinfo->flag |= HAS_VALUE;
1,630,968,900✔
208
  }
209

210
  // Tuple
211
  sinfo->tupleFlag = sinfo->flag;
1,662,661,329✔
212
  switch (sinfo->flag) {
1,662,661,329!
213
    case HAS_NONE:
55,405,994✔
214
    case HAS_NULL:
215
      sinfo->tupleBitmapSize = 0;
55,405,994✔
216
      sinfo->tupleFixedSize = 0;
55,405,994✔
217
      break;
55,405,994✔
218
    case HAS_VALUE:
1,177,805,066✔
219
      sinfo->tupleBitmapSize = 0;
1,177,805,066✔
220
      sinfo->tupleFixedSize = schema->flen;
1,177,805,066✔
221
      break;
1,177,805,066✔
222
    case (HAS_NONE | HAS_NULL):
24,493✔
223
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,493✔
224
      sinfo->tupleFixedSize = 0;
24,493✔
225
      break;
24,493✔
226
    case (HAS_NONE | HAS_VALUE):
456,302,916✔
227
    case (HAS_NULL | HAS_VALUE):
228
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
456,302,916✔
229
      sinfo->tupleFixedSize = schema->flen;
456,302,916✔
230
      break;
456,302,916✔
231
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
2,463,058✔
232
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
2,463,058✔
233
      sinfo->tupleFixedSize = schema->flen;
2,463,058✔
234
      break;
2,463,058✔
235
  }
236
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
2,147,483,647✔
237
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
491,687,606✔
238
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
491,687,606✔
239
  }
240
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,659,320,435✔
241
                        + sinfo->tuplePKSize      // primary keys
1,659,320,435✔
242
                        + sinfo->tupleBitmapSize  // bitmap
1,659,320,435✔
243
                        + sinfo->tupleFixedSize   // fixed part
1,659,320,435✔
244
                        + sinfo->tupleVarSize;    // var part
1,659,320,435✔
245

246
  // Key-Value
247
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,659,320,435!
248
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,681,801,182✔
249
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,681,801,182✔
250
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
251
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
5,683,134✔
252
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
5,683,134✔
253
  } else {
254
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
255
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
256
  }
257
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
2,146,514,782✔
258
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
488,118,493✔
259
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
488,118,493✔
260
  }
261
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,658,396,289✔
262
                     + sinfo->kvPKSize        // primary keys
1,658,396,289✔
263
                     + sinfo->kvIndexSize     // index array
1,658,396,289✔
264
                     + sinfo->kvPayloadSize;  // payload
1,658,396,289✔
265

266
_exit:
1,658,396,289✔
267
  return code;
1,658,396,289✔
268
}
269

270
static int32_t tRowBuildTupleRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
1,257,636,297✔
271
                                 SRow **ppRow) {
272
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
1,257,636,297✔
273

274
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
1,257,636,297!
275
  if (*ppRow == NULL) {
1,278,143,871!
276
    return terrno;
×
277
  }
278
  (*ppRow)->flag = sinfo->tupleFlag;
1,278,143,871✔
279
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
1,278,143,871✔
280
  (*ppRow)->sver = schema->version;
1,278,143,871✔
281
  (*ppRow)->len = sinfo->tupleRowSize;
1,278,143,871✔
282
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
1,278,143,871✔
283

284
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
1,278,143,871✔
285
    return 0;
57,944,181✔
286
  }
287

288
  uint8_t *primaryKeys = (*ppRow)->data;
1,220,199,690✔
289
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
1,220,199,690✔
290
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
1,220,199,690✔
291
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
1,220,199,690✔
292

293
  // primary keys
294
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,692,048,082✔
295
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
477,993,861✔
296
  }
297

298
  // bitmap + fixed + varlen
299
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
1,214,054,221✔
300
  int32_t colValIndex = 1;
1,214,054,221✔
301
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
302
    for (;;) {
303
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647!
304
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
305
        break;
×
306
      }
307

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

312
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
313
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
164,656,297✔
314
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
164,656,297✔
315
            if (colValArray[colValIndex].value.nData) {
164,656,297!
316
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
175,022,407✔
317
              varlen += colValArray[colValIndex].value.nData;
175,022,407✔
318
            }
319
          } else {
320
            (void)memcpy(fixed + schema->columns[i].offset,
2,147,483,647✔
321
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
2,147,483,647!
322
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
323
          }
324
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
31,292,737!
325
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
37,744,680!
326
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
327
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
462,574!
328
        }
329

330
        colValIndex++;
2,147,483,647✔
331
        break;
2,147,483,647✔
332
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
5,378,455✔
333
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
11!
334
        break;
11✔
335
      } else {
336
        colValIndex++;
5,378,444✔
337
      }
338
    }
339
  }
340

341
  return 0;
1,214,054,221✔
342
}
343

344
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
345
  if (flag & KV_FLG_LIT) {
2,147,483,647✔
346
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
2,147,483,647✔
347
  } else if (flag & KV_FLG_MID) {
5,820,310!
348
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,803,312✔
349
  } else {
350
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
×
351
  }
352
  indices->nCol++;
2,147,483,647✔
353
}
2,147,483,647✔
354

355
static int32_t tRowBuildKVRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema, SRow **ppRow) {
423,968,824✔
356
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
423,968,824✔
357

358
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
423,968,824!
359
  if (*ppRow == NULL) {
424,329,684!
360
    return terrno;
×
361
  }
362
  (*ppRow)->flag = sinfo->kvFlag;
424,329,684✔
363
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
424,329,684✔
364
  (*ppRow)->sver = schema->version;
424,329,684✔
365
  (*ppRow)->len = sinfo->kvRowSize;
424,329,684✔
366
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
424,329,684✔
367

368
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
424,329,684!
369
    return TSDB_CODE_INVALID_PARA;
4,469✔
370
  }
371

372
  uint8_t *primaryKeys = (*ppRow)->data;
424,325,215✔
373
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
424,325,215✔
374
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
424,325,215✔
375
  uint32_t payloadSize = 0;
424,325,215✔
376

377
  // primary keys
378
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
441,867,250✔
379
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
17,546,079✔
380
  }
381

382
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
424,321,171✔
383
  int32_t colValIndex = 1;
424,321,171✔
384
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
385
    for (;;) {
386
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647✔
387
        break;
44✔
388
      }
389

390
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
391
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
2,147,483,647✔
392
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
2,147,483,647✔
393
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
394
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
555,137,635✔
395
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
555,137,635✔
396
            if (colValArray[colValIndex].value.nData > 0) {
555,137,635!
397
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
567,007,788✔
398
                           colValArray[colValIndex].value.nData);
567,007,788✔
399
            }
400
            payloadSize += colValArray[colValIndex].value.nData;
555,137,635✔
401
          } else {
402
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
2,147,483,647✔
403
            (void)memcpy(payload + payloadSize,
2,147,483,647✔
404
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
2,147,483,647!
405
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
406
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
2,147,483,647✔
407
          }
408
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
2,147,483,647✔
409
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
16,897,435✔
410
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
33,794,870✔
411
        }
412

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

423
  return 0;
424,321,171✔
424
}
425

426
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
1,664,018,597✔
427
  int32_t           code;
428
  SRowBuildScanInfo sinfo;
429

430
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,664,018,597✔
431
  if (code) return code;
1,684,634,294!
432

433
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,684,634,294✔
434
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
1,261,522,829✔
435
  } else {
436
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
423,111,465✔
437
  }
438
  return code;
1,689,792,332✔
439
}
440

441
static int32_t tBindInfoCompare(const void *p1, const void *p2, const void *param) {
1✔
442
  if (((SBindInfo *)p1)->columnId < ((SBindInfo *)p2)->columnId) {
1!
443
    return -1;
1✔
444
  } else if (((SBindInfo *)p1)->columnId > ((SBindInfo *)p2)->columnId) {
×
445
    return 1;
×
446
  }
447
  return 0;
×
448
}
449

450
/* build rows to `rowArray` from bind
451
 * `infos` is the bind information array
452
 * `numOfInfos` is the number of bind information
453
 * `infoSorted` is whether the bind information is sorted by column id
454
 * `pTSchema` is the schema of the table
455
 * `rowArray` is the array to store the rows
456
 * `pOrdered` is the pointer to store ordered
457
 * `pDupTs` is the pointer to store duplicateTs
458
 */
459
int32_t tRowBuildFromBind(SBindInfo *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
50,787✔
460
                          SArray *rowArray, bool *pOrdered, bool *pDupTs) {
461
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
50,787!
462
    return TSDB_CODE_INVALID_PARA;
×
463
  }
464

465
  if (!infoSorted) {
50,865!
466
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
467
  }
468

469
  int32_t code = 0;
50,865✔
470
  int32_t numOfRows = infos[0].bind->num;
50,865✔
471
  SArray *colValArray;
472
  SColVal colVal;
473

474
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
50,865!
475
    return terrno;
×
476
  }
477

478
  SRowKey rowKey, lastRowKey;
479
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
96,764,062!
480
    taosArrayClear(colValArray);
104,910,320✔
481

482
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
438,047,276✔
483
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
328,988,872✔
484
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
31✔
485
      } else {
486
        SValue value = {
328,988,841✔
487
            .type = infos[iInfo].type,
328,988,841✔
488
        };
489
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
328,988,841!
490
          value.nData = infos[iInfo].bind->length[iRow];
176,854✔
491
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
176,854!
492
            code = TSDB_CODE_INVALID_PARA;
×
493
            goto _exit;
×
494
          }
495
          value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
176,854✔
496
        } else {
497
          valueSetDatum(&value, infos[iInfo].type,
328,811,987✔
498
                        (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
328,811,987✔
499
                        infos[iInfo].bind->buffer_length);
328,811,987✔
500
        }
501
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
358,949,804✔
502
      }
503
      if (taosArrayPush(colValArray, &colVal) == NULL) {
333,880,042!
504
        code = terrno;
×
505
        goto _exit;
×
506
      }
507
    }
508

509
    SRow *row;
510
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
109,058,404!
511
      goto _exit;
×
512
    }
513

514
    if ((taosArrayPush(rowArray, &row)) == NULL) {
96,737,189!
515
      code = terrno;
×
516
      goto _exit;
×
517
    }
518

519
    if (pOrdered && pDupTs) {
96,737,189!
520
      tRowGetKey(row, &rowKey);
193,947,714!
521
      if (iRow == 0) {
96,949,831✔
522
        *pOrdered = true;
50,649✔
523
        *pDupTs = false;
50,649✔
524
      } else {
525
        if (*pOrdered) {
96,899,182!
526
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
96,922,816✔
527
          *pOrdered = (res >= 0);
96,922,816✔
528
          if (!*pDupTs) {
96,922,816!
529
            *pDupTs = (res == 0);
97,044,427✔
530
          }
531
        }
532
      }
533
      lastRowKey = rowKey;
96,949,831✔
534
    }
535
  }
536

537
_exit:
×
538
  taosArrayDestroy(colValArray);
×
539
  return code;
51,006✔
540
}
541

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

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

548
  if (iCol == 0) {
2,147,483,647✔
549
    pColVal->cid = pTColumn->colId;
71,275,235✔
550
    pColVal->value.type = pTColumn->type;
71,275,235✔
551
    pColVal->flag = CV_FLAG_VALUE;
71,275,235✔
552
    VALUE_SET_TRIVIAL_DATUM(&pColVal->value, pRow->ts);
71,275,235✔
553
    return 0;
71,275,235✔
554
  }
555

556
  if (pRow->flag == HAS_NONE) {
2,147,483,647✔
557
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2,439,749✔
558
    return 0;
2,439,749✔
559
  }
560

561
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
562
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,211,563✔
563
    return 0;
1,211,563✔
564
  }
565

566
  SPrimaryKeyIndex index;
567
  uint8_t         *data = pRow->data;
2,147,483,647✔
568
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
2,147,483,647✔
569
    data += tGetPrimaryKeyIndex(data, &index);
137,349,810✔
570
  }
571

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

576
    if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
577
      pv = pIdx->idx + pIdx->nCol;
2,147,483,647✔
578
    } else if (pRow->flag & KV_FLG_MID) {
71,993,009!
579
      pv = pIdx->idx + (pIdx->nCol << 1);
93,556,488✔
580
    } else {
581
      pv = pIdx->idx + (pIdx->nCol << 2);
×
582
    }
583

584
    int16_t lidx = 0;
2,147,483,647✔
585
    int16_t ridx = pIdx->nCol - 1;
2,147,483,647✔
586
    while (lidx <= ridx) {
2,147,483,647✔
587
      int16_t  mid = (lidx + ridx) >> 1;
2,147,483,647✔
588
      uint8_t *pData = NULL;
2,147,483,647✔
589
      if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
590
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
2,147,483,647✔
591
      } else if (pRow->flag & KV_FLG_MID) {
397,478,808!
592
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
397,729,445✔
593
      } else {
594
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
595
      }
596

597
      int16_t cid;
598
      pData += tGetI16v(pData, &cid);
2,147,483,647✔
599

600
      if (TABS(cid) == pTColumn->colId) {
2,147,483,647✔
601
        if (cid < 0) {
2,147,483,647✔
602
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
87,923,935✔
603
        } else {
604
          pColVal->cid = pTColumn->colId;
2,147,483,647✔
605
          pColVal->value.type = pTColumn->type;
2,147,483,647✔
606
          pColVal->flag = CV_FLAG_VALUE;
2,147,483,647✔
607

608
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
2,147,483,647!
609
            pData += tGetU32v(pData, &pColVal->value.nData);
765,812,831!
610
            if (pColVal->value.nData > 0) {
765,812,831!
611
              pColVal->value.pData = pData;
901,109,018✔
612
            } else {
613
              pColVal->value.pData = NULL;
×
614
            }
615
          } else {
616
            valueSetDatum(&pColVal->value, pTColumn->type, pData, pTColumn->bytes);
2,147,483,647✔
617
          }
618
        }
619
        return 0;
2,147,483,647✔
620
      } else if (TABS(cid) < pTColumn->colId) {
2,147,483,647✔
621
        lidx = mid + 1;
2,147,483,647✔
622
      } else {
623
        ridx = mid - 1;
2,147,483,647✔
624
      }
625
    }
626

627
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2,147,483,647✔
628
  } else {  // Tuple Row
629
    uint8_t *bitmap = data;
825,084,990✔
630
    uint8_t *fixed;
631
    uint8_t *varlen;
632
    uint8_t  bit;
633

634
    if (pRow->flag == HAS_VALUE) {
825,084,990✔
635
      fixed = bitmap;
781,281,219✔
636
      bit = BIT_FLG_VALUE;
781,281,219✔
637
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
43,803,771!
638
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
639
      bit = GET_BIT2(bitmap, iCol - 1);
×
640
    } else {
641
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
43,803,771✔
642
      bit = GET_BIT1(bitmap, iCol - 1);
43,803,771✔
643

644
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
43,803,771✔
645
        if (bit) bit++;
20,499✔
646
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
43,783,272!
647
        bit++;
45,077,642✔
648
      }
649
    }
650
    varlen = fixed + pTSchema->flen;
825,084,990✔
651

652
    if (bit == BIT_FLG_NONE) {
825,084,990✔
653
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,255✔
654
      return 0;
7,255✔
655
    } else if (bit == BIT_FLG_NULL) {
825,077,735✔
656
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
13,998,480✔
657
      return 0;
13,998,480✔
658
    }
659

660
    pColVal->cid = pTColumn->colId;
811,079,255✔
661
    pColVal->value.type = pTColumn->type;
811,079,255✔
662
    pColVal->flag = CV_FLAG_VALUE;
811,079,255✔
663
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
811,079,255!
664
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
43,037,646✔
665
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
86,075,292!
666
    } else {
667
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
768,041,609✔
668
    }
669
  }
670

671
  return 0;
2,147,483,647✔
672
}
673

674
void tRowDestroy(SRow *pRow) {
1,220,321,738✔
675
  if (pRow) taosMemoryFree(pRow);
1,220,321,738!
676
}
1,221,417,515✔
677

678
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
719,877,026✔
679
  SRowKey key1, key2;
680
  tRowGetKey(*(SRow **)p1, &key1);
1,439,754,052✔
681
  tRowGetKey(*(SRow **)p2, &key2);
1,438,574,242✔
682
  return tRowKeyCompare(&key1, &key2);
737,030,681✔
683
}
684
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
1,048✔
685
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
260✔
686
  int32_t code = 0;
260✔
687

688
  int32_t    nRow = iEnd - iStart;
260✔
689
  SRowIter **aIter = NULL;
260✔
690
  SArray    *aColVal = NULL;
260✔
691
  SRow      *pRow = NULL;
260✔
692

693
  aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
260!
694
  if (aIter == NULL) {
260!
695
    code = terrno;
×
696
    goto _exit;
×
697
  }
698

699
  for (int32_t i = 0; i < nRow; i++) {
1,308✔
700
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
1,048✔
701

702
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
1,048✔
703
    if (code) goto _exit;
1,048!
704
  }
705

706
  // merge
707
  aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
260✔
708
  if (aColVal == NULL) {
260!
709
    code = terrno;
×
710
    goto _exit;
×
711
  }
712

713
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
1,006✔
714
    SColVal *pColVal = NULL;
746✔
715
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
892✔
716
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
846✔
717
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
948✔
718
        pColValT = tRowIterNext(aIter[iRow]);
102✔
719
      }
720

721
      // todo: take strategy according to the flag
722
      if (COL_VAL_IS_VALUE(pColValT)) {
846✔
723
        pColVal = pColValT;
700✔
724
        break;
700✔
725
      } else if (COL_VAL_IS_NULL(pColValT)) {
146✔
726
        if (pColVal == NULL) {
2✔
727
          pColVal = pColValT;
1✔
728
        }
729
      }
730
    }
731

732
    if (pColVal) {
746✔
733
      if (taosArrayPush(aColVal, pColVal) == NULL) {
701!
734
        code = terrno;
×
735
        goto _exit;
×
736
      }
737
    }
738
  }
739

740
  // build
741
  code = tRowBuild(aColVal, pTSchema, &pRow);
260✔
742
  if (code) goto _exit;
260!
743

744
  taosArrayRemoveBatch(aRowP, iStart, nRow, (FDelete)tRowPDestroy);
260✔
745
  if (taosArrayInsert(aRowP, iStart, &pRow) == NULL) {
260!
746
    code = terrno;
×
747
    goto _exit;
×
748
  }
749

750
_exit:
260✔
751
  if (aIter) {
260!
752
    for (int32_t i = 0; i < nRow; i++) {
1,308✔
753
      tRowIterClose(&aIter[i]);
1,048✔
754
    }
755
    taosMemoryFree(aIter);
260!
756
  }
757
  if (aColVal) taosArrayDestroy(aColVal);
260!
758
  if (code) tRowDestroy(pRow);
260!
759
  return code;
260✔
760
}
761

762
int32_t tRowSort(SArray *aRowP) {
98,322✔
763
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
98,322✔
764
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
66,721✔
765
  if (code != TSDB_CODE_SUCCESS) {
66,741!
766
    uError("taosArrayMSort failed caused by %d", code);
×
767
  }
768
  return code;
66,740✔
769
}
770

771
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, int8_t flag) {
98,366✔
772
  int32_t code = 0;
98,366✔
773

774
  int32_t iStart = 0;
98,366✔
775
  while (iStart < aRowP->size) {
117,586,600✔
776
    SRowKey key1;
777
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
117,519,274✔
778

779
    tRowGetKey(row1, &key1);
235,004,500✔
780

781
    int32_t iEnd = iStart + 1;
117,478,271✔
782
    while (iEnd < aRowP->size) {
117,476,961✔
783
      SRowKey key2;
784
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
117,386,934✔
785
      tRowGetKey(row2, &key2);
234,799,856✔
786

787
      if (tRowKeyCompare(&key1, &key2) != 0) break;
117,396,897!
788

789
      iEnd++;
×
790
    }
791

792
    if (iEnd - iStart > 1) {
117,488,234✔
793
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
260✔
794
      if (code) return code;
260!
795
    }
796

797
    // the array is also changing, so the iStart just ++ instead of iEnd
798
    iStart++;
117,488,234✔
799
  }
800

801
  return code;
67,326✔
802
}
803

804
// SRowIter ========================================
805
struct SRowIter {
806
  SRow     *pRow;
807
  STSchema *pTSchema;
808

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

824
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) {
1,625,607✔
825
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,625,607!
826

827
  int32_t code = 0;
1,625,607✔
828

829
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
1,625,607!
830
  if (pIter == NULL) {
1,698,097!
831
    code = terrno;
×
832
    goto _exit;
×
833
  }
834

835
  pIter->pRow = pRow;
1,698,097✔
836
  pIter->pTSchema = pTSchema;
1,698,097✔
837
  pIter->iTColumn = 0;
1,698,097✔
838

839
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
1,698,097!
840

841
  uint8_t         *data = pRow->data;
1,696,467✔
842
  SPrimaryKeyIndex index;
843
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,739,836✔
844
    data += tGetPrimaryKeyIndex(data, &index);
43,395✔
845
  }
846

847
  if (pRow->flag >> 4) {
1,696,441✔
848
    pIter->iCol = 0;
1,690,077✔
849
    pIter->pIdx = (SKVIdx *)data;
1,690,077✔
850
    if (pRow->flag & KV_FLG_LIT) {
1,690,077✔
851
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
1,686,465✔
852
    } else if (pRow->flag & KV_FLG_MID) {
3,612✔
853
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1);  // * sizeof(uint16_t)
3,300✔
854
    } else {
855
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2);  // * sizeof(uint32_t)
312✔
856
    }
857
  } else {
858
    switch (pRow->flag) {
6,364!
859
      case (HAS_NULL | HAS_NONE):
1✔
860
        pIter->pb = data;
1✔
861
        break;
1✔
862
      case HAS_VALUE:
3,329✔
863
        pIter->pf = data;
3,329✔
864
        pIter->pv = pIter->pf + pTSchema->flen;
3,329✔
865
        break;
3,329✔
866
      case (HAS_VALUE | HAS_NONE):
1,202✔
867
      case (HAS_VALUE | HAS_NULL):
868
        pIter->pb = data;
1,202✔
869
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
1,202✔
870
        pIter->pv = pIter->pf + pTSchema->flen;
1,202✔
871
        break;
1,202✔
872
      case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
873
        pIter->pb = data;
×
874
        pIter->pf = data + BIT2_SIZE(pTSchema->numOfCols - 1);
×
875
        pIter->pv = pIter->pf + pTSchema->flen;
×
876
        break;
×
877
      default:
1,832✔
878
        break;
1,832✔
879
    }
880
  }
881

882
_exit:
1,698,071✔
883
  if (code) {
1,698,071!
884
    *ppIter = NULL;
×
885
  } else {
886
    *ppIter = pIter;
1,698,071✔
887
  }
888
  return code;
1,698,071✔
889
}
890

891
void tRowIterClose(SRowIter **ppIter) {
1,610,505✔
892
  SRowIter *pIter = *ppIter;
1,610,505✔
893
  if (pIter) {
1,610,505!
894
    taosMemoryFree(pIter);
1,610,987!
895
  }
896
  *ppIter = NULL;
1,709,380✔
897
}
1,709,380✔
898

899
SColVal *tRowIterNext(SRowIter *pIter) {
20,296,121✔
900
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
20,296,121✔
901
    return NULL;
1,609,806✔
902
  }
903

904
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
18,686,315✔
905

906
  // timestamp
907
  if (0 == pIter->iTColumn) {
18,686,315✔
908
    pIter->cv.cid = pTColumn->colId;
1,651,556✔
909
    pIter->cv.value.type = pTColumn->type;
1,651,556✔
910
    pIter->cv.flag = CV_FLAG_VALUE;
1,651,556✔
911
    VALUE_SET_TRIVIAL_DATUM(&pIter->cv.value, pIter->pRow->ts);
1,651,556✔
912
    goto _exit;
1,651,556✔
913
  }
914

915
  if (pIter->pRow->flag == HAS_NONE) {
17,034,759✔
916
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
79,030✔
917
    goto _exit;
79,030✔
918
  }
919

920
  if (pIter->pRow->flag == HAS_NULL) {
16,955,729✔
921
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
3,031✔
922
    goto _exit;
3,031✔
923
  }
924

925
  if (pIter->pRow->flag >> 4) {  // KV
16,952,698!
926
    if (pIter->iCol < pIter->pIdx->nCol) {
17,997,541✔
927
      uint8_t *pData;
928

929
      if (pIter->pRow->flag & KV_FLG_LIT) {
14,148,643✔
930
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
14,055,621✔
931
      } else if (pIter->pRow->flag & KV_FLG_MID) {
93,022!
932
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
99,000✔
933
      } else {
934
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
935
      }
936

937
      int16_t cid;
938
      pData += tGetI16v(pData, &cid);
14,148,643✔
939

940
      if (TABS(cid) == pTColumn->colId) {
14,148,643!
941
        if (cid < 0) {
14,658,930✔
942
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
2,382,394✔
943
        } else {
944
          pIter->cv.cid = pTColumn->colId;
12,276,536✔
945
          pIter->cv.value.type = pTColumn->type;
12,276,536✔
946
          pIter->cv.flag = CV_FLAG_VALUE;
12,276,536✔
947

948
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
12,276,536!
949
            pData += tGetU32v(pData, &pIter->cv.value.nData);
1,510,213!
950
            if (pIter->cv.value.nData > 0) {
1,510,213!
951
              pIter->cv.value.pData = pData;
3,229,661✔
952
            } else {
953
              pIter->cv.value.pData = NULL;
×
954
            }
955
          } else {
956
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
10,766,323✔
957
          }
958
        }
959

960
        pIter->iCol++;
15,699,757✔
961
        goto _exit;
15,699,757✔
962
      } else if (TABS(cid) > pTColumn->colId) {
×
963
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
94✔
964
        goto _exit;
94✔
965
      } else {
966
        uError("unexpected column id %d, %d", cid, pTColumn->colId);
×
967
        goto _exit;
×
968
      }
969
    } else {
970
      pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
3,848,898✔
971
      goto _exit;
3,848,898✔
972
    }
973
  } else {  // Tuple
974
    uint8_t bv = BIT_FLG_VALUE;
×
975
    if (pIter->pb) {
×
976
      switch (pIter->pRow->flag) {
5,411!
977
        case (HAS_NULL | HAS_NONE):
3✔
978
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
3✔
979
          break;
3✔
980
        case (HAS_VALUE | HAS_NONE):
47✔
981
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
47✔
982
          if (bv) bv++;
47✔
983
          break;
47✔
984
        case (HAS_VALUE | HAS_NULL):
5,361✔
985
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
5,361✔
986
          break;
5,361✔
987
        case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
988
          bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1);
×
989
          break;
×
990
        default:
×
991
          break;
×
992
      }
993

994
      if (bv == BIT_FLG_NONE) {
5,411✔
995
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
17✔
996
        goto _exit;
17✔
997
      } else if (bv == BIT_FLG_NULL) {
5,394✔
998
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
624✔
999
        goto _exit;
624✔
1000
      }
1001
    }
1002

1003
    pIter->cv.cid = pTColumn->colId;
×
1004
    pIter->cv.value.type = pTColumn->type;
×
1005
    pIter->cv.flag = CV_FLAG_VALUE;
×
1006
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
1007
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
×
1008
      pData += tGetU32v(pData, &pIter->cv.value.nData);
×
1009
      if (pIter->cv.value.nData > 0) {
×
1010
        pIter->cv.value.pData = pData;
3,064✔
1011
      } else {
1012
        pIter->cv.value.pData = NULL;
×
1013
      }
1014
    } else {
1015
      valueSetDatum(&pIter->cv.value, pTColumn->type, pIter->pf + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
33,856✔
1016
    }
1017
    goto _exit;
36,917✔
1018
  }
1019

1020
_exit:
21,319,924✔
1021
  pIter->iTColumn++;
21,319,924✔
1022
  return &pIter->cv;
21,319,924✔
1023
}
1024

1025
static int32_t tRowNoneUpsertColData(SColData *aColData, int32_t nColData, int32_t flag) {
10,843✔
1026
  int32_t code = 0;
10,843✔
1027

1028
  if (flag) return code;
10,843✔
1029

1030
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
95,222✔
1031
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
89,305✔
1032
    if (code) return code;
89,325!
1033
  }
1034

1035
  return code;
5,917✔
1036
}
1037
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
187,394✔
1038
  int32_t code = 0;
187,394✔
1039

1040
  int32_t   iColData = 0;
187,394✔
1041
  SColData *pColData = &aColData[iColData];
187,394✔
1042
  int32_t   iTColumn = 1;
187,394✔
1043
  STColumn *pTColumn = &pSchema->columns[iTColumn];
187,394✔
1044

1045
  while (pColData) {
710,351✔
1046
    if (pTColumn) {
522,938!
1047
      if (pTColumn->colId == pColData->cid) {  // NULL
522,938✔
1048
        if (flag == 0) {
522,936✔
1049
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
522,771✔
1050
        } else {
1051
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
165✔
1052
        }
1053
        if (code) goto _exit;
522,955!
1054

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

1069
_exit:
187,413✔
1070
  return code;
187,413✔
1071
}
1072
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
1,068,882,768✔
1073
                                      int32_t flag) {
1074
  int32_t code = 0;
1,068,882,768✔
1075

1076
  int32_t   iColData = 0;
1,068,882,768✔
1077
  SColData *pColData = &aColData[iColData];
1,068,882,768✔
1078
  int32_t   iTColumn = 1;
1,068,882,768✔
1079
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
1,068,882,768✔
1080

1081
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
1,068,882,768✔
1082
  SPrimaryKeyIndex index;
1083
  uint8_t         *data = pRow->data;
1,068,882,768✔
1084
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,558,562,982✔
1085
    data += tGetPrimaryKeyIndex(data, &index);
489,650,651✔
1086
  }
1087

1088
  switch (pRow->flag) {
1,068,912,331!
1089
    case HAS_VALUE:
1,035,575,006✔
1090
      pf = data;  // TODO: fix here
1,035,575,006✔
1091
      pv = pf + pTSchema->flen;
1,035,575,006✔
1092
      break;
1,035,575,006✔
1093
    case (HAS_NULL | HAS_NONE):
1,297✔
1094
      pb = data;
1,297✔
1095
      break;
1,297✔
1096
    case (HAS_VALUE | HAS_NONE):
33,463,977✔
1097
    case (HAS_VALUE | HAS_NULL):
1098
      pb = data;
33,463,977✔
1099
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
33,463,977✔
1100
      pv = pf + pTSchema->flen;
33,463,977✔
1101
      break;
33,463,977✔
1102
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1103
      pb = data;
×
1104
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1105
      pv = pf + pTSchema->flen;
×
1106
      break;
×
1107
    default:
×
1108
      return TSDB_CODE_INVALID_DATA_FMT;
×
1109
  }
1110

1111
  while (pColData) {
2,147,483,647✔
1112
    if (pTColumn) {
2,147,483,647✔
1113
      if (pTColumn->colId == pColData->cid) {
2,147,483,647!
1114
        if (!(pTColumn->type == pColData->type)) {
2,147,483,647!
1115
          return TSDB_CODE_INVALID_PARA;
×
1116
        }
1117
        if (pb) {
2,147,483,647✔
1118
          uint8_t bv;
1119
          switch (pRow->flag) {
108,449,746!
1120
            case (HAS_NULL | HAS_NONE):
25,933✔
1121
              bv = GET_BIT1(pb, iTColumn - 1);
25,933✔
1122
              break;
25,933✔
1123
            case (HAS_VALUE | HAS_NONE):
199,277✔
1124
              bv = GET_BIT1(pb, iTColumn - 1);
199,277✔
1125
              if (bv) bv++;
199,277✔
1126
              break;
199,277✔
1127
            case (HAS_VALUE | HAS_NULL):
108,224,437✔
1128
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
108,224,437✔
1129
              break;
108,224,437✔
1130
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1131
              bv = GET_BIT2(pb, iTColumn - 1);
×
1132
              break;
×
1133
            default:
99✔
1134
              return TSDB_CODE_INVALID_DATA_FMT;
99✔
1135
          }
1136

1137
          if (bv == BIT_FLG_NONE) {
108,449,647✔
1138
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
43,382!
1139
              goto _exit;
×
1140
            goto _continue;
43,385✔
1141
          } else if (bv == BIT_FLG_NULL) {
108,406,265✔
1142
            if (flag == 0) {
36,185,968✔
1143
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
36,182,327✔
1144
            } else {
1145
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
3,641✔
1146
            }
1147
            if (code) goto _exit;
36,186,320!
1148
            goto _continue;
36,186,320✔
1149
          }
1150
        }
1151

1152
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1153
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
55,581,402!
1154
          uint32_t nData;
1155
          pData += tGetU32v(pData, &nData);
55,581,402✔
1156
          if (flag == 0) {
55,581,402!
1157
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
59,727,072✔
1158
          } else {
1159
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1160
          }
1161
          if (code) goto _exit;
61,199,074!
1162
        } else {
1163
          if (flag == 0) {
2,147,483,647✔
1164
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,147,483,647✔
1165
                                                                          TYPE_BYTES[pColData->type]);
2,147,483,647✔
1166
          } else {
1167
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
14,741,299✔
1168
                                                                          TYPE_BYTES[pColData->type], flag > 0);
14,741,299✔
1169
          }
1170
          if (code) goto _exit;
2,147,483,647!
1171
        }
1172

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

1188
_exit:
1,073,195,066✔
1189
  return code;
1,073,195,066✔
1190
}
1191
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
7,919,582✔
1192
  int32_t code = 0;
7,919,582✔
1193

1194
  uint8_t  *pv = NULL;
7,919,582✔
1195
  int32_t   iColData = 0;
7,919,582✔
1196
  SColData *pColData = &aColData[iColData];
7,919,582✔
1197
  int32_t   iTColumn = 1;
7,919,582✔
1198
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
7,919,582✔
1199
  int32_t   iCol = 0;
7,919,582✔
1200

1201
  // primary keys
1202
  uint8_t         *data = pRow->data;
7,919,582✔
1203
  SPrimaryKeyIndex index;
1204
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
8,854,552✔
1205
    data += tGetPrimaryKeyIndex(data, &index);
934,946✔
1206
  }
1207

1208
  SKVIdx *pKVIdx = (SKVIdx *)data;
7,919,606✔
1209
  if (pRow->flag & KV_FLG_LIT) {
7,919,606✔
1210
    pv = pKVIdx->idx + pKVIdx->nCol;
7,852,752✔
1211
  } else if (pRow->flag & KV_FLG_MID) {
66,854!
1212
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
70,251✔
1213
  } else if (pRow->flag & KV_FLG_BIG) {
×
1214
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1215
  } else {
1216
    return TSDB_CODE_INVALID_PARA;
×
1217
  }
1218

1219
  while (pColData) {
116,601,294✔
1220
    if (pTColumn) {
108,747,001✔
1221
      if (pTColumn->colId == pColData->cid) {
108,347,886✔
1222
        while (iCol < pKVIdx->nCol) {
108,291,116✔
1223
          uint8_t *pData;
1224
          if (pRow->flag & KV_FLG_LIT) {
77,240,312✔
1225
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
75,292,770✔
1226
          } else if (pRow->flag & KV_FLG_MID) {
1,947,542!
1227
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,947,608✔
1228
          } else if (pRow->flag & KV_FLG_BIG) {
×
1229
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1230
          } else {
1231
            return TSDB_CODE_INVALID_DATA_FMT;
×
1232
          }
1233

1234
          int16_t cid;
1235
          pData += tGetI16v(pData, &cid);
77,240,378✔
1236

1237
          if (TABS(cid) == pTColumn->colId) {
77,240,378✔
1238
            if (cid < 0) {
44,372,646✔
1239
              if (flag == 0) {
11,628,782✔
1240
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
11,621,610✔
1241
              } else {
1242
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
7,172✔
1243
              }
1244
              if (code) goto _exit;
11,084,880!
1245
            } else {
1246
              uint32_t nData;
1247
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
32,743,864!
1248
                pData += tGetU32v(pData, &nData);
7,126,560✔
1249
              } else {
1250
                nData = 0;
25,617,304✔
1251
              }
1252
              if (flag == 0) {
32,743,864!
1253
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
32,921,391✔
1254
              } else {
1255
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1256
              }
1257
              if (code) goto _exit;
33,219,931!
1258
            }
1259
            iCol++;
44,304,811✔
1260
            goto _continue;
44,304,811✔
1261
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
32,867,732✔
1262
            break;
32,507,268✔
1263
          } else {
1264
            iCol++;
360,464✔
1265
          }
1266
        }
1267

1268
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
63,558,072!
1269

1270
      _continue:
63,557,142✔
1271
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
107,861,953✔
1272
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
107,861,953✔
1273
      } else if (pTColumn->colId > pColData->cid) {
417,234!
1274
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1275
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1276
      } else {
1277
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
417,234!
1278
      }
1279
    } else {
1280
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,115!
1281
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,104✔
1282
    }
1283
  }
1284

1285
_exit:
7,854,293✔
1286
  return code;
7,854,293✔
1287
}
1288
/* flag > 0: forward update
1289
 * flag == 0: append
1290
 * flag < 0: backward update
1291
 */
1292
int32_t tRowUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
1,076,857,232✔
1293
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,076,857,232!
1294
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
1,076,857,232!
1295

1296
  if (pRow->flag == HAS_NONE) {
1,076,857,232✔
1297
    return tRowNoneUpsertColData(aColData, nColData, flag);
10,843✔
1298
  } else if (pRow->flag == HAS_NULL) {
1,076,846,389✔
1299
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
187,394✔
1300
  } else if (pRow->flag >> 4) {  // KV row
1,076,658,995✔
1301
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
7,920,637✔
1302
  } else {  // TUPLE row
1303
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
1,068,738,358✔
1304
  }
1305
}
1306

1307
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
2,147,483,647✔
1308
  key->numOfPKs = row->numOfPKs;
2,147,483,647✔
1309

1310
  if (key->numOfPKs == 0) {
2,147,483,647!
1311
    return;
×
1312
  }
1313

1314
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1315

1316
  uint8_t *data = row->data;
2,147,483,647✔
1317

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

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

1326
    uint8_t *tdata = data + indices[i].offset;
2,147,483,647✔
1327
    if (row->flag >> 4) {
2,147,483,647✔
1328
      tdata += tGetI16v(tdata, NULL);
16,078,680✔
1329
    }
1330

1331
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
1332
      key->pks[i].pData = tdata;
2,721,448✔
1333
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
5,442,896!
1334
    } else {
1335
      valueSetDatum(key->pks + i, indices[i].type, tdata, tDataTypes[indices[i].type].bytes);
2,147,483,647✔
1336
    }
1337
  }
1338
}
1339

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

1351
int32_t tValueCompare(const SValue *tv1, const SValue *tv2) {
2,147,483,647✔
1352
  switch (tv1->type) {
2,147,483,647!
1353
    case TSDB_DATA_TYPE_BOOL:
×
1354
    case TSDB_DATA_TYPE_TINYINT:
1355
      T_COMPARE_SCALAR_VALUE(int8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1356
    case TSDB_DATA_TYPE_SMALLINT:
×
1357
      T_COMPARE_SCALAR_VALUE(int16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1358
    case TSDB_DATA_TYPE_INT:
1,181,511✔
1359
      T_COMPARE_SCALAR_VALUE(int32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
1,181,511✔
1360
    case TSDB_DATA_TYPE_BIGINT:
2,147,483,647✔
1361
    case TSDB_DATA_TYPE_TIMESTAMP:
1362
      T_COMPARE_SCALAR_VALUE(int64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
2,147,483,647✔
1363
    case TSDB_DATA_TYPE_FLOAT:
×
1364
      T_COMPARE_SCALAR_VALUE(float, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1365
    case TSDB_DATA_TYPE_DOUBLE:
×
1366
      T_COMPARE_SCALAR_VALUE(double, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1367
    case TSDB_DATA_TYPE_UTINYINT:
×
1368
      T_COMPARE_SCALAR_VALUE(uint8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1369
    case TSDB_DATA_TYPE_USMALLINT:
×
1370
      T_COMPARE_SCALAR_VALUE(uint16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
1371
    case TSDB_DATA_TYPE_UINT:
1,125,005✔
1372
      T_COMPARE_SCALAR_VALUE(uint32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
1,125,005✔
1373
    case TSDB_DATA_TYPE_UBIGINT:
1,144,095✔
1374
      T_COMPARE_SCALAR_VALUE(uint64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
1,144,095✔
1375
    case TSDB_DATA_TYPE_GEOMETRY:
1,970,303✔
1376
    case TSDB_DATA_TYPE_BINARY: {
1377
      int32_t ret = strncmp((const char *)tv1->pData, (const char *)tv2->pData, TMIN(tv1->nData, tv2->nData));
1,970,303✔
1378
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
1,970,303✔
1379
    }
1380
    case TSDB_DATA_TYPE_NCHAR: {
×
1381
      int32_t ret = taosUcs4Compare((TdUcs4 *)tv1->pData, (TdUcs4 *)tv2->pData,
×
1382
                                    tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1383
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1384
    }
1385
    case TSDB_DATA_TYPE_VARBINARY: {
×
1386
      int32_t ret = memcmp(tv1->pData, tv2->pData, tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
1387
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
1388
    }
1389
    default:
565✔
1390
      break;
565✔
1391
  }
1392

1393
  return 0;
565✔
1394
}
1395

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

1406
  if (key1->numOfPKs == key2->numOfPKs) {
2,147,483,647!
1407
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
2,147,483,647!
1408
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
2,147,483,647✔
1409
      if (ret) return ret;
2,147,483,647!
1410
    }
1411
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1412
    return -1;
×
1413
  } else {
1414
    return 1;
×
1415
  }
1416

1417
  return 0;
482,579,475✔
1418
}
1419

1420
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
845,025,782✔
1421
  pDst->ts = pSrc->ts;
845,025,782✔
1422
  pDst->numOfPKs = pSrc->numOfPKs;
845,025,782✔
1423

1424
  if (pSrc->numOfPKs > 0) {
845,025,782✔
1425
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
96,872,305✔
1426
      SValue *pVal = &pDst->pks[i];
48,288,528✔
1427
      pVal->type = pSrc->pks[i].type;
48,288,528✔
1428

1429
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
48,288,528✔
1430
    }
1431
  }
1432
}
845,323,233✔
1433

1434
// STag ========================================
1435
static int tTagValCmprFn(const void *p1, const void *p2) {
135,493,924✔
1436
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
135,493,924✔
1437
    return -1;
46,151,974✔
1438
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
89,341,950✔
1439
    return 1;
49,240,311✔
1440
  }
1441

1442
  return 0;
40,101,639✔
1443
}
1444
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
11,902✔
1445
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
11,902✔
1446
}
1447

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

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

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

1541
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
1,199,424✔
1542
  int32_t n = 0;
1,199,424✔
1543

1544
  // key
1545
  if (isJson) {
1,199,424✔
1546
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
4,116✔
1547
  } else {
1548
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
2,394,732✔
1549
  }
1550

1551
  // type
1552
  n += tPutI8(p ? p + n : p, pTagVal->type);
1,199,424✔
1553

1554
  // value
1555
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
1,199,424!
1556
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
890,386✔
1557
  } else {
1558
    p = p ? p + n : p;
754,231✔
1559
    n += tDataTypes[pTagVal->type].bytes;
754,231✔
1560
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
754,231✔
1561
  }
1562

1563
  return n;
1,199,424✔
1564
}
1565
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
134,241,507✔
1566
  int32_t n = 0;
134,241,507✔
1567

1568
  // key
1569
  if (isJson) {
134,241,507✔
1570
    n += tGetCStr(p + n, &pTagVal->pKey);
28,846!
1571
  } else {
1572
    n += tGetI16v(p + n, &pTagVal->cid);
268,454,168!
1573
  }
1574

1575
  // type
1576
  n += tGetI8(p + n, &pTagVal->type);
134,241,507!
1577

1578
  // value
1579
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
134,241,507!
1580
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
44,461,062!
1581
  } else {
1582
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
112,010,976✔
1583
    n += tDataTypes[pTagVal->type].bytes;
112,010,976✔
1584
  }
1585

1586
  return n;
134,241,507✔
1587
}
1588

1589
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
42,536✔
1590

1591
bool tTagIsJsonNull(void *data) {
7,060✔
1592
  STag  *pTag = (STag *)data;
7,060✔
1593
  int8_t isJson = tTagIsJson(pTag);
7,060✔
1594
  if (!isJson) return false;
7,060✔
1595
  return ((STag *)data)->nTag == 0;
3,088✔
1596
}
1597

1598
int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
235,327✔
1599
  int32_t  code = 0;
235,327✔
1600
  uint8_t *p = NULL;
235,327✔
1601
  int16_t  n = 0;
235,327✔
1602
  int16_t  nTag = taosArrayGetSize(pArray);
235,327✔
1603
  int32_t  szTag = 0;
235,363✔
1604
  int8_t   isLarge = 0;
235,363✔
1605

1606
  // sort
1607
  if (isJson) {
235,363✔
1608
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
660✔
1609
  } else {
1610
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
234,703✔
1611
  }
1612

1613
  // get size
1614
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
835,195✔
1615
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
599,820✔
1616
  }
1617
  if (szTag <= INT8_MAX) {
235,375✔
1618
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
216,609✔
1619
  } else {
1620
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
18,766✔
1621
    isLarge = 1;
18,766✔
1622
  }
1623

1624
  // build tag
1625
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
235,375!
1626
  if ((*ppTag) == NULL) {
235,489!
1627
    code = terrno;
×
1628
    goto _err;
×
1629
  }
1630
  (*ppTag)->flags = 0;
235,489✔
1631
  if (isJson) {
235,489✔
1632
    (*ppTag)->flags |= TD_TAG_JSON;
660✔
1633
  }
1634
  if (isLarge) {
235,489✔
1635
    (*ppTag)->flags |= TD_TAG_LARGE;
18,779✔
1636
  }
1637
  (*ppTag)->len = szTag;
235,489✔
1638
  (*ppTag)->nTag = nTag;
235,489✔
1639
  (*ppTag)->ver = version;
235,489✔
1640

1641
  if (isLarge) {
235,489✔
1642
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
18,779✔
1643
  } else {
1644
    p = (uint8_t *)&(*ppTag)->idx[nTag];
216,710✔
1645
  }
1646
  n = 0;
235,489✔
1647
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
835,347✔
1648
    if (isLarge) {
599,914✔
1649
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
145,948✔
1650
    } else {
1651
      (*ppTag)->idx[iTag] = n;
453,966✔
1652
    }
1653
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
599,914✔
1654
  }
1655
#ifdef TD_DEBUG_PRINT_TAG
1656
  debugPrintSTag(*ppTag, __func__, __LINE__);
1657
#endif
1658

1659
  return code;
235,433✔
1660

1661
_err:
×
1662
  return code;
×
1663
}
1664

1665
void tTagFree(STag *pTag) {
2,127,719✔
1666
  if (pTag) taosMemoryFree(pTag);
2,127,719!
1667
}
2,127,722✔
1668

1669
char *tTagValToData(const STagVal *value, bool isJson) {
14,367,112✔
1670
  if (!value) {
14,367,112!
1671
    return NULL;
×
1672
  }
1673

1674
  char  *data = NULL;
14,367,112✔
1675
  int8_t typeBytes = 0;
14,367,112✔
1676
  if (isJson) {
14,367,112✔
1677
    typeBytes = CHAR_BYTES;
6,261✔
1678
  }
1679

1680
  if (IS_VAR_DATA_TYPE(value->type)) {
14,367,112✔
1681
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
3,837,186!
1682
    if (data == NULL) {
3,842,065!
1683
      return NULL;
×
1684
    }
1685

1686
    if (isJson) {
3,842,065✔
1687
      *data = value->type;
2,448✔
1688
    }
1689

1690
    varDataLen(data + typeBytes) = value->nData;
3,842,065✔
1691
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
3,842,065✔
1692
  } else {
1693
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
10,529,926✔
1694
  }
1695

1696
  return data;
14,371,991✔
1697
}
1698

1699
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
42,126,559✔
1700
  if (!pTag || !pTagVal) {
42,126,559!
1701
    return false;
×
1702
  }
1703

1704
  int16_t  lidx = 0;
42,266,482✔
1705
  int16_t  ridx = pTag->nTag - 1;
42,266,482✔
1706
  int16_t  midx;
1707
  uint8_t *p;
1708
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
42,266,482✔
1709
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
42,266,482✔
1710
  int16_t  offset;
1711
  STagVal  tv;
1712
  int      c;
1713

1714
  if (isLarge) {
42,266,482✔
1715
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
34,518,090✔
1716
  } else {
1717
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,748,392✔
1718
  }
1719

1720
  pTagVal->type = TSDB_DATA_TYPE_NULL;
42,266,482✔
1721
  pTagVal->pData = NULL;
42,266,482✔
1722
  pTagVal->nData = 0;
42,266,482✔
1723
  while (lidx <= ridx) {
136,958,576✔
1724
    midx = (lidx + ridx) / 2;
134,909,304✔
1725
    if (isLarge) {
134,909,304✔
1726
      offset = ((int16_t *)pTag->idx)[midx];
111,429,189✔
1727
    } else {
1728
      offset = pTag->idx[midx];
23,480,115✔
1729
    }
1730

1731
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
134,909,304✔
1732
    if (isJson) {
135,178,784✔
1733
      c = tTagValJsonCmprFn(pTagVal, &tv);
11,388✔
1734
    } else {
1735
      c = tTagValCmprFn(pTagVal, &tv);
135,167,396✔
1736
    }
1737

1738
    if (c < 0) {
136,669,736✔
1739
      ridx = midx - 1;
45,516,258✔
1740
    } else if (c > 0) {
91,153,478✔
1741
      lidx = midx + 1;
49,175,836✔
1742
    } else {
1743
      (void)memcpy(pTagVal, &tv, sizeof(tv));
41,977,642✔
1744
      return true;
41,977,642✔
1745
    }
1746
  }
1747
  return false;
2,049,272✔
1748
}
1749

1750
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
813,414✔
1751
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,626,828✔
1752
}
1753

1754
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
20,173,038✔
1755

1756
int32_t tTagToValArray(const STag *pTag, SArray **ppArray) {
2,073✔
1757
  int32_t  code = 0;
2,073✔
1758
  uint8_t *p = NULL;
2,073✔
1759
  STagVal  tv = {0};
2,073✔
1760
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
2,073✔
1761
  int16_t  offset = 0;
2,073✔
1762

1763
  if (isLarge) {
2,073✔
1764
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
16✔
1765
  } else {
1766
    p = (uint8_t *)&pTag->idx[pTag->nTag];
2,057✔
1767
  }
1768

1769
  (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
2,073✔
1770
  if (*ppArray == NULL) {
2,073!
1771
    code = terrno;
×
1772
    goto _err;
×
1773
  }
1774

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

1788
  return code;
2,073✔
1789

1790
_err:
×
1791
  return code;
×
1792
}
1793

1794
// STSchema ========================================
1795
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
17,361,090✔
1796
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
17,361,090!
1797
  if (pTSchema == NULL) {
17,395,490!
1798
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1799
    return NULL;
×
1800
  }
1801

1802
  pTSchema->numOfCols = numOfCols;
17,395,490✔
1803
  pTSchema->version = version;
17,395,490✔
1804

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

1820
  // other columns
1821
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
237,007,348✔
1822
    SSchema  *pSchema = &aSchema[iCol];
219,611,858✔
1823
    STColumn *pTColumn = &pTSchema->columns[iCol];
219,611,858✔
1824

1825
    pTColumn->colId = pSchema->colId;
219,611,858✔
1826
    pTColumn->type = pSchema->type;
219,611,858✔
1827
    pTColumn->flags = pSchema->flags;
219,611,858✔
1828
    pTColumn->offset = pTSchema->flen;
219,611,858✔
1829

1830
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
219,611,858!
1831
      pTColumn->bytes = pSchema->bytes;
39,415,326✔
1832
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
39,415,326✔
1833
    } else {
1834
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
180,196,532✔
1835
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
180,196,532✔
1836
    }
1837

1838
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
219,611,858✔
1839
  }
1840

1841
#if 1  // todo : remove this
1842
  pTSchema->tlen += (int32_t)TD_BITMAP_BYTES(numOfCols);
17,395,490✔
1843
#endif
1844

1845
  return pTSchema;
17,395,490✔
1846
}
1847

1848
static int32_t tTColumnCompare(const void *p1, const void *p2) {
11,613,242✔
1849
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
11,613,242✔
1850
    return -1;
1,778,895✔
1851
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
9,834,347✔
1852
    return 1;
6,974,971✔
1853
  }
1854

1855
  return 0;
2,859,376✔
1856
}
1857

1858
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid) {
2,860,871✔
1859
  STColumn tcol = {
2,860,871✔
1860
      .colId = cid,
1861
  };
1862

1863
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
2,860,871✔
1864
}
1865

1866
// SColData ========================================
1867
void tColDataDestroy(void *ph) {
28,021,301✔
1868
  if (ph) {
28,021,301!
1869
    SColData *pColData = (SColData *)ph;
28,021,515✔
1870

1871
    tFree(pColData->pBitMap);
28,021,515!
1872
    tFree(pColData->aOffset);
28,021,622!
1873
    tFree(pColData->pData);
28,021,714!
1874
  }
1875
}
28,023,870✔
1876

1877
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
30,292,392✔
1878
  pColData->cid = cid;
30,292,392✔
1879
  pColData->type = type;
30,292,392✔
1880
  pColData->cflag = cflag;
30,292,392✔
1881
  tColDataClear(pColData);
30,292,392✔
1882
}
30,295,498✔
1883

1884
void tColDataClear(SColData *pColData) {
62,488,124✔
1885
  pColData->numOfNone = 0;
62,488,124✔
1886
  pColData->numOfNull = 0;
62,488,124✔
1887
  pColData->numOfValue = 0;
62,488,124✔
1888
  pColData->nVal = 0;
62,488,124✔
1889
  pColData->flag = 0;
62,488,124✔
1890
  pColData->nData = 0;
62,488,124✔
1891
}
62,488,124✔
1892

1893
void tColDataDeepClear(SColData *pColData) {
188,418✔
1894
  pColData->pBitMap = NULL;
188,418✔
1895
  pColData->aOffset = NULL;
188,418✔
1896
  pColData->pData = NULL;
188,418✔
1897

1898
  tColDataClear(pColData);
188,418✔
1899
}
188,408✔
1900

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

1904
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1905
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
111,100,861!
1906
    if (code) goto _exit;
122,483,769!
1907
    pColData->aOffset[pColData->nVal] = pColData->nData;
122,483,769✔
1908

1909
    if (nData) {
122,483,769!
1910
      code = tRealloc(&pColData->pData, pColData->nData + nData);
119,133,406!
1911
      if (code) goto _exit;
120,048,707!
1912
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
120,048,707✔
1913
      pColData->nData += nData;
120,048,707✔
1914
    }
1915
  } else {
1916
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
1917
      return TSDB_CODE_INVALID_PARA;
×
1918
    }
1919
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
1920
    if (code) goto _exit;
2,147,483,647!
1921
    if (pData) {
2,147,483,647!
1922
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
1923
    } else {
1924
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
240,111,010✔
1925
    }
1926
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
1927
  }
1928
  pColData->nVal++;
2,147,483,647✔
1929

1930
_exit:
2,147,483,647✔
1931
  return code;
2,147,483,647✔
1932
}
1933
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
8,145,011✔
1934
  pColData->flag = HAS_VALUE;
8,153,750✔
1935
  pColData->numOfValue++;
8,145,011✔
1936
  return tColDataPutValue(pColData, pData, nData);
8,154,379✔
1937
}
1938
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
245,118✔
1939
  pColData->flag = HAS_NONE;
245,118✔
1940
  pColData->numOfNone++;
245,118✔
1941
  pColData->nVal++;
245,118✔
1942
  return 0;
245,118✔
1943
}
1944
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
460,606✔
1945
  pColData->flag = HAS_NULL;
469,124✔
1946
  pColData->numOfNull++;
469,124✔
1947
  pColData->nVal++;
469,124✔
1948
  return 0;
460,606✔
1949
}
1950
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,437✔
1951
  int32_t code = 0;
1,437✔
1952

1953
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
1,437✔
1954
  code = tRealloc(&pColData->pBitMap, nBit);
1,437!
1955
  if (code) return code;
1,437!
1956

1957
  memset(pColData->pBitMap, 0, nBit);
1,437✔
1958
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,437!
1959

1960
  pColData->flag |= HAS_VALUE;
1,437✔
1961
  pColData->numOfValue++;
1,437✔
1962

1963
  if (pColData->nVal) {
1,437!
1964
    if (IS_VAR_DATA_TYPE(pColData->type)) {
1,437!
1965
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
257✔
1966
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
257!
1967
      if (code) return code;
257!
1968
      memset(pColData->aOffset, 0, nOffset);
257✔
1969
    } else {
1970
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
1,180✔
1971
      code = tRealloc(&pColData->pData, pColData->nData);
1,180!
1972
      if (code) return code;
1,180!
1973
      memset(pColData->pData, 0, pColData->nData);
1,180✔
1974
    }
1975
  }
1976

1977
  return tColDataPutValue(pColData, pData, nData);
1,437✔
1978
}
1979
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
84,920,176✔
1980
  pColData->nVal++;
84,920,176✔
1981
  pColData->numOfNone++;
84,920,176✔
1982
  return 0;
84,920,176✔
1983
}
1984
static FORCE_INLINE int32_t tColDataAppendValue12(SColData *pColData, uint8_t *pData, uint32_t nData) {
601✔
1985
  int32_t code = 0;
601✔
1986

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

1991
  memset(pColData->pBitMap, 0, nBit);
601✔
1992
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
601!
1993

1994
  pColData->flag |= HAS_NULL;
601✔
1995
  pColData->numOfNull++;
601✔
1996
  pColData->nVal++;
601✔
1997

1998
  return code;
601✔
1999
}
2000
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
200,805✔
2001
  int32_t code = 0;
201,362✔
2002

2003
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
201,362✔
2004
  code = tRealloc(&pColData->pBitMap, nBit);
201,074!
2005
  if (code) return code;
201,363!
2006

2007
  memset(pColData->pBitMap, 0, nBit);
201,363✔
2008
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
201,363!
2009

2010
  pColData->flag |= HAS_VALUE;
201,363✔
2011
  pColData->numOfValue++;
201,363✔
2012

2013
  if (pColData->nVal) {
201,363!
2014
    if (IS_VAR_DATA_TYPE(pColData->type)) {
201,364!
2015
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
7,752✔
2016
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
7,752!
2017
      if (code) return code;
7,750!
2018
      memset(pColData->aOffset, 0, nOffset);
7,750✔
2019
    } else {
2020
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
193,612✔
2021
      code = tRealloc(&pColData->pData, pColData->nData);
193,612!
2022
      if (code) return code;
193,612!
2023
      memset(pColData->pData, 0, pColData->nData);
193,612✔
2024
    }
2025
  }
2026

2027
  return tColDataPutValue(pColData, pData, nData);
201,362✔
2028
}
2029
static FORCE_INLINE int32_t tColDataAppendValue21(SColData *pColData, uint8_t *pData, uint32_t nData) {
10,080✔
2030
  int32_t code = 0;
10,080✔
2031

2032
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
10,080✔
2033
  code = tRealloc(&pColData->pBitMap, nBit);
10,080✔
2034
  if (code) return code;
10,080!
2035

2036
  memset(pColData->pBitMap, 255, nBit);
10,080✔
2037
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
10,080!
2038

2039
  pColData->flag |= HAS_NONE;
10,080✔
2040
  pColData->numOfNone++;
10,080✔
2041
  pColData->nVal++;
10,080✔
2042

2043
  return code;
10,080✔
2044
}
2045
static FORCE_INLINE int32_t tColDataAppendValue22(SColData *pColData, uint8_t *pData, uint32_t nData) {
9,801,877✔
2046
  pColData->nVal++;
9,801,877✔
2047
  pColData->numOfNull++;
9,801,877✔
2048
  return 0;
9,801,877✔
2049
}
2050
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
5✔
2051
  int32_t code = 0;
5✔
2052

2053
  pColData->flag |= HAS_VALUE;
5✔
2054
  pColData->numOfValue++;
5✔
2055

2056
  uint8_t *pBitMap = NULL;
5✔
2057
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
5!
2058
  if (code) return code;
5!
2059

2060
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
1,005!
2061
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal));
1,000!
2062
  }
2063
  SET_BIT2_EX(pBitMap, pColData->nVal, 2);
5!
2064

2065
  tFree(pColData->pBitMap);
5!
2066
  pColData->pBitMap = pBitMap;
5✔
2067

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

2082
  return tColDataPutValue(pColData, pData, nData);
5✔
2083
}
2084
static FORCE_INLINE int32_t tColDataAppendValue31(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,989,900✔
2085
  int32_t code = 0;
1,989,900✔
2086

2087
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,989,900!
2088
  if (code) return code;
1,989,900!
2089

2090
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
1,989,900✔
2091
  pColData->numOfNone++;
1,989,900✔
2092
  pColData->nVal++;
1,989,900✔
2093

2094
  return code;
1,989,900✔
2095
}
2096
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
9,366✔
2097
  int32_t code = 0;
9,366✔
2098

2099
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
9,366!
2100
  if (code) return code;
9,368!
2101

2102
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
9,368!
2103
  pColData->numOfNull++;
9,368✔
2104
  pColData->nVal++;
9,368✔
2105

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

2115
  pColData->flag |= HAS_NONE;
147,027✔
2116
  pColData->numOfNone++;
147,027✔
2117

2118
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
147,027✔
2119
  code = tRealloc(&pColData->pBitMap, nBit);
147,027✔
2120
  if (code) return code;
147,080!
2121

2122
  memset(pColData->pBitMap, 255, nBit);
147,080✔
2123
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
147,080✔
2124

2125
  return tColDataPutValue(pColData, NULL, 0);
147,071✔
2126
}
2127
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,609,004✔
2128
  int32_t code = 0;
1,718,770✔
2129

2130
  pColData->flag |= HAS_NULL;
1,718,770✔
2131
  pColData->numOfNull++;
1,718,770✔
2132

2133
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
1,718,770✔
2134
  code = tRealloc(&pColData->pBitMap, nBit);
1,718,466✔
2135
  if (code) return code;
1,718,782!
2136

2137
  memset(pColData->pBitMap, 255, nBit);
1,718,782✔
2138
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
1,718,782!
2139

2140
  return tColDataPutValue(pColData, NULL, 0);
1,718,788✔
2141
}
2142
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,361,112✔
2143
  int32_t code = 0;
1,363,113✔
2144

2145
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,363,112!
2146
  if (code) return code;
1,363,715!
2147

2148
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,363,715!
2149
  pColData->numOfValue++;
1,363,715!
2150

2151
  return tColDataPutValue(pColData, pData, nData);
1,365,980✔
2152
}
2153
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
14,124,121✔
2154
  int32_t code = 0;
14,124,121✔
2155

2156
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
14,124,121✔
2157
  if (code) return code;
14,124,102!
2158

2159
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
14,124,102✔
2160
  pColData->numOfNone++;
14,124,102✔
2161

2162
  return tColDataPutValue(pColData, NULL, 0);
14,125,837✔
2163
}
2164
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
12,466✔
2165
  int32_t code = 0;
12,466✔
2166

2167
  pColData->flag |= HAS_NULL;
12,466✔
2168
  pColData->numOfNull++;
12,466✔
2169

2170
  uint8_t *pBitMap = NULL;
12,466✔
2171
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
12,466!
2172
  if (code) return code;
12,466!
2173

2174
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,766,571!
2175
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
3,754,105!
2176
  }
2177
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
12,466!
2178

2179
  tFree(pColData->pBitMap);
12,466!
2180
  pColData->pBitMap = pBitMap;
12,466!
2181

2182
  return tColDataPutValue(pColData, NULL, 0);
12,466✔
2183
}
2184
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,147,483,647✔
2185
  int32_t code = 0;
2,147,483,647✔
2186

2187
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
2,147,483,647!
2188
  if (code) return code;
2,147,483,647!
2189
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
2,147,483,647!
2190
  pColData->numOfValue++;
2,147,483,647!
2191

2192
  return tColDataPutValue(pColData, pData, nData);
2,147,483,647✔
2193
}
2194
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
28,925✔
2195
  int32_t code = 0;
28,925✔
2196

2197
  pColData->flag |= HAS_NONE;
28,925✔
2198
  pColData->numOfNone++;
28,925✔
2199

2200
  uint8_t *pBitMap = NULL;
28,925✔
2201
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
28,925!
2202
  if (code) return code;
28,925!
2203

2204
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,656,188✔
2205
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
2,627,263✔
2206
  }
2207
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
28,925✔
2208

2209
  tFree(pColData->pBitMap);
28,925!
2210
  pColData->pBitMap = pBitMap;
28,927✔
2211

2212
  return tColDataPutValue(pColData, NULL, 0);
28,926✔
2213
}
2214
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
200,944,150✔
2215
  int32_t code = 0;
218,984,516✔
2216

2217
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
218,980,924!
2218
  if (code) return code;
219,003,115!
2219
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
219,003,115✔
2220
  pColData->numOfNull++;
219,003,115✔
2221

2222
  return tColDataPutValue(pColData, NULL, 0);
219,018,403✔
2223
}
2224
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
660,096✔
2225
  int32_t code = 0;
660,096✔
2226

2227
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
660,096!
2228
  if (code) return code;
660,096!
2229
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 2);
660,096!
2230
  pColData->numOfValue++;
660,096!
2231

2232
  return tColDataPutValue(pColData, pData, nData);
660,096✔
2233
}
2234
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
4,955,074✔
2235
  int32_t code = 0;
4,955,074✔
2236

2237
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
4,955,074!
2238
  if (code) return code;
4,955,074!
2239
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 0);
4,955,074✔
2240
  pColData->numOfNone++;
4,955,074!
2241

2242
  return tColDataPutValue(pColData, NULL, 0);
4,955,074✔
2243
}
2244
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
562,831✔
2245
  int32_t code = 0;
562,831✔
2246

2247
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
562,831!
2248
  if (code) return code;
562,831!
2249
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 1);
562,831!
2250
  pColData->numOfNull++;
562,831!
2251

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

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

2274
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
9✔
2275
  pColData->numOfNone--;
9✔
2276
  pColData->nVal--;
9✔
2277
  if (pColData->numOfNone) {
9!
2278
    return tColDataAppendValue10(pColData, pData, nData);
×
2279
  } else {
2280
    pColData->flag = 0;
9✔
2281
    return tColDataAppendValue00(pColData, pData, nData);
9✔
2282
  }
2283
}
2284
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
2285
  pColData->numOfNone--;
24✔
2286
  pColData->nVal--;
24✔
2287
  if (pColData->numOfNone) {
24!
2288
    return tColDataAppendValue12(pColData, pData, nData);
×
2289
  } else {
2290
    pColData->flag = 0;
24✔
2291
    return tColDataAppendValue02(pColData, pData, nData);
24✔
2292
  }
2293
  return 0;
2294
}
2295
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
8,999✔
2296
  if (forward) {
8,999!
2297
    pColData->numOfNull--;
8,999✔
2298
    pColData->nVal--;
8,999✔
2299
    if (pColData->numOfNull) {
8,999✔
2300
      return tColDataAppendValue20(pColData, pData, nData);
269✔
2301
    } else {
2302
      pColData->flag = 0;
8,730✔
2303
      return tColDataAppendValue00(pColData, pData, nData);
8,730✔
2304
    }
2305
  }
2306
  return 0;
×
2307
}
2308
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2309
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2310
    pColData->numOfNone--;
×
2311
    pColData->nVal--;
×
2312
    if (pColData->numOfNone) {
×
2313
      return tColDataAppendValue30(pColData, pData, nData);
×
2314
    } else {
2315
      pColData->flag = HAS_NULL;
×
2316
      return tColDataAppendValue20(pColData, pData, nData);
×
2317
    }
2318
  } else if (forward) {  // NULL ==> VALUE
×
2319
    pColData->numOfNull--;
×
2320
    pColData->nVal--;
×
2321
    if (pColData->numOfNull) {
×
2322
      return tColDataAppendValue30(pColData, pData, nData);
×
2323
    } else {
2324
      pColData->flag = HAS_NONE;
×
2325
      return tColDataAppendValue10(pColData, pData, nData);
×
2326
    }
2327
  }
2328
  return 0;
×
2329
}
2330
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
2331
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
2332
    pColData->numOfNone--;
80✔
2333
    pColData->numOfNull++;
80✔
2334
    if (pColData->numOfNone) {
80!
2335
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2336
    } else {
2337
      pColData->flag = HAS_NULL;
80✔
2338
    }
2339
  }
2340
  return 0;
80✔
2341
}
2342
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
239,188,406✔
2343
  if (forward) {  // VALUE ==> VALUE
239,188,406!
2344
    pColData->nVal--;
239,190,204✔
2345
    if (IS_VAR_DATA_TYPE(pColData->type)) {
239,190,204!
2346
      pColData->nData = pColData->aOffset[pColData->nVal];
1,074,006✔
2347
    } else {
2348
      pColData->nData -= TYPE_BYTES[pColData->type];
238,116,198✔
2349
    }
2350
    return tColDataPutValue(pColData, pData, nData);
239,316,148✔
2351
  }
2352
  return 0;
×
2353
}
2354
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
117,956✔
2355
  if (forward) {  // VALUE ==> NULL
117,956!
2356
    pColData->numOfValue--;
117,956✔
2357
    pColData->nVal--;
117,956✔
2358
    if (pColData->numOfValue) {
117,956✔
2359
      if (IS_VAR_DATA_TYPE(pColData->type)) {
109,462!
2360
        pColData->nData = pColData->aOffset[pColData->nVal];
1,044✔
2361
      } else {
2362
        pColData->nData -= TYPE_BYTES[pColData->type];
108,418✔
2363
      }
2364
      return tColDataAppendValue42(pColData, pData, nData);
109,461✔
2365
    } else {
2366
      pColData->flag = 0;
8,494✔
2367
      pColData->nData = 0;
8,494✔
2368
      return tColDataAppendValue02(pColData, pData, nData);
8,494✔
2369
    }
2370
  }
2371
  return 0;
×
2372
}
2373
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
44,956✔
2374
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
44,956✔
2375
    pColData->numOfNone--;
5,599✔
2376
    pColData->nVal--;
5,599✔
2377
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,599!
2378
      pColData->nData -= TYPE_BYTES[pColData->type];
4,479✔
2379
    }
2380
    if (pColData->numOfNone) {
5,599✔
2381
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2382
    } else {
2383
      pColData->flag = HAS_VALUE;
3,599✔
2384
      return tColDataAppendValue40(pColData, pData, nData);
3,598✔
2385
    }
2386
  } else if (forward) {  // VALUE ==> VALUE
39,357!
2387
    pColData->nVal--;
39,359✔
2388
    if (IS_VAR_DATA_TYPE(pColData->type)) {
39,359!
2389
      pColData->nData = pColData->aOffset[pColData->nVal];
5,623✔
2390
    } else {
2391
      pColData->nData -= TYPE_BYTES[pColData->type];
33,736✔
2392
    }
2393
    return tColDataPutValue(pColData, pData, nData);
39,371✔
2394
  }
2395
  return 0;
×
2396
}
2397
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
304✔
2398
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
304!
2399
    pColData->numOfNone--;
304✔
2400
    pColData->nVal--;
304✔
2401
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
304!
2402
      pColData->nData -= TYPE_BYTES[pColData->type];
244✔
2403
    }
2404
    if (pColData->numOfNone) {
304!
2405
      return tColDataAppendValue52(pColData, pData, nData);
×
2406
    } else {
2407
      pColData->flag = HAS_VALUE;
304!
2408
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2409
    }
2410
  } else if (forward) {  // VALUE ==> NULL
×
2411
    pColData->numOfValue--;
×
2412
    pColData->nVal--;
×
2413
    if (pColData->numOfValue) {
×
2414
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2415
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2416
      } else {
2417
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2418
      }
2419
      return tColDataAppendValue52(pColData, pData, nData);
×
2420
    } else {
2421
      pColData->flag = HAS_NONE;
×
2422
      pColData->nData = 0;
×
2423
      return tColDataAppendValue12(pColData, pData, nData);
×
2424
    }
2425
  }
2426
  return 0;
×
2427
}
2428
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
360,729,557✔
2429
  if (forward) {
360,729,557!
2430
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
360,729,561✔
2431
      pColData->numOfNull--;
18,152,530✔
2432
      pColData->nVal--;
18,152,530✔
2433
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
18,152,530!
2434
        pColData->nData -= TYPE_BYTES[pColData->type];
18,147,491✔
2435
      }
2436
      if (pColData->numOfNull) {
18,152,530✔
2437
        return tColDataAppendValue60(pColData, pData, nData);
18,027,273✔
2438
      } else {
2439
        pColData->flag = HAS_VALUE;
125,257✔
2440
        return tColDataAppendValue40(pColData, pData, nData);
125,257✔
2441
      }
2442
    } else {  // VALUE ==> VALUE
2443
      pColData->nVal--;
342,577,031✔
2444
      if (IS_VAR_DATA_TYPE(pColData->type)) {
342,577,031!
2445
        pColData->nData = pColData->aOffset[pColData->nVal];
2,676✔
2446
      } else {
2447
        pColData->nData -= TYPE_BYTES[pColData->type];
342,574,355✔
2448
      }
2449
      return tColDataPutValue(pColData, pData, nData);
342,577,033✔
2450
    }
2451
  }
2452
  return 0;
×
2453
}
2454
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
19,005,078✔
2455
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
19,005,078!
2456
    pColData->numOfValue--;
18,037,062✔
2457
    pColData->nVal--;
18,037,062✔
2458
    if (pColData->numOfValue) {
18,037,062✔
2459
      if (IS_VAR_DATA_TYPE(pColData->type)) {
18,036,774!
2460
        pColData->nData = pColData->aOffset[pColData->nVal];
2,513✔
2461
      } else {
2462
        pColData->nData -= TYPE_BYTES[pColData->type];
18,034,261✔
2463
      }
2464
      return tColDataAppendValue62(pColData, pData, nData);
18,036,773✔
2465
    } else {
2466
      pColData->flag = HAS_NULL;
288✔
2467
      pColData->nData = 0;
288!
2468
      return tColDataAppendValue20(pColData, pData, nData);
290✔
2469
    }
2470
  }
2471
  return 0;
968,016✔
2472
}
2473
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
401✔
2474
  int32_t code = 0;
401✔
2475

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

2575
    //    VALUE             NONE        NULL
2576
};
2577
int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward) {
605,522,068✔
2578
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
605,522,068!
2579
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
605,523,075!
2580

2581
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
605,523,075!
2582

2583
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
605,523,075✔
2584
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData, forward);
605,523,075!
2585
}
2586

2587
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
102,569,455✔
2588
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
102,569,455✔
2589
}
102,569,455✔
2590
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
3,647,917✔
2591
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
3,647,917✔
2592
}
3,647,917✔
2593
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
11,939✔
2594
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2595
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
11,939!
2596
    case 0:
1,086✔
2597
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,086✔
2598
      break;
1,086✔
2599
    case 1:
10,853✔
2600
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,853✔
2601
      break;
10,853✔
2602
    default:
×
2603
      break;
×
2604
  }
2605
}
11,939✔
2606
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
2607
  SValue value = {.type = pColData->type};
2,147,483,647✔
2608
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2609
    if (iVal + 1 < pColData->nVal) {
219,350,525!
2610
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
227,876,805✔
2611
    } else {
2612
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2613
    }
2614
    value.pData = pColData->pData + pColData->aOffset[iVal];
219,350,525✔
2615
  } else {
2616
    valueSetDatum(&value, pColData->type, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
2617
                  tDataTypes[pColData->type].bytes);
2,147,483,647✔
2618
  }
2619
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
2620
}
2,147,483,647✔
2621
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
8,897,113✔
2622
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2623
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
8,897,113!
2624
    case 0:
4,470,325✔
2625
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
4,470,325✔
2626
      break;
4,470,325✔
2627
    case 1:
4,523,254✔
2628
      tColDataGetValue4(pColData, iVal, pColVal);
2629
      break;
4,550,549✔
2630
    default:
×
2631
      break;
×
2632
  }
2633
}
8,924,408✔
2634
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
2,147,483,647✔
2635
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2636
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
2,147,483,647!
2637
    case 0:
200,634,280✔
2638
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
200,634,280✔
2639
      break;
200,634,280✔
2640
    case 1:
2,147,483,647✔
2641
      tColDataGetValue4(pColData, iVal, pColVal);
2642
      break;
2,147,483,647✔
2643
    default:
×
2644
      break;
×
2645
  }
2646
}
2,147,483,647✔
2647
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
11✔
2648
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
2649
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
11!
2650
    case 0:
5✔
2651
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
5✔
2652
      break;
5✔
2653
    case 1:
5✔
2654
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
5✔
2655
      break;
5✔
2656
    case 2:
1!
2657
      tColDataGetValue4(pColData, iVal, pColVal);
2658
      break;
1✔
2659
    default:
×
2660
      break;
×
2661
  }
2662
}
11✔
2663
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2664
    NULL,               // 0
2665
    tColDataGetValue1,  // HAS_NONE
2666
    tColDataGetValue2,  // HAS_NULL
2667
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2668
    tColDataGetValue4,  // HAS_VALUE
2669
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2670
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2671
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2672
};
2673
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
2674
  if (iVal < 0 || iVal >= pColData->nVal ||
2,147,483,647!
2675
      (pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
2,147,483,647!
2676
    return TSDB_CODE_INVALID_PARA;
×
2677
  }
2678
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
2679
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
2680
}
2681

2682
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
2,147,483,647✔
2683
  switch (pColData->flag) {
2,147,483,647!
2684
    case HAS_NONE:
×
2685
      return 0;
×
2686
    case HAS_NULL:
×
2687
      return 1;
×
2688
    case (HAS_NULL | HAS_NONE):
11,946✔
2689
      return GET_BIT1(pColData->pBitMap, iVal);
11,946✔
2690
    case HAS_VALUE:
×
2691
      return 2;
×
2692
    case (HAS_VALUE | HAS_NONE):
24,070,163✔
2693
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
24,070,163✔
2694
    case (HAS_VALUE | HAS_NULL):
2,147,483,647✔
2695
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
2,147,483,647✔
2696
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
12,466,522✔
2697
      return GET_BIT2(pColData->pBitMap, iVal);
12,466,522✔
2698
    default:
×
2699
      return 0;
×
2700
  }
2701
}
2702

2703
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg) {
27,665✔
2704
  int32_t code = 0;
27,665✔
2705

2706
  *pColData = *pColDataFrom;
27,665✔
2707

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

2733
  // offset
2734
  if (IS_VAR_DATA_TYPE(pColData->type) && (pColData->flag & HAS_VALUE)) {
27,665!
2735
    pColData->aOffset = xMalloc(arg, pColData->nVal << 2);
104✔
2736
    if (pColData->aOffset == NULL) {
104!
2737
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2738
      goto _exit;
×
2739
    }
2740
    (void)memcpy(pColData->aOffset, pColDataFrom->aOffset, pColData->nVal << 2);
104✔
2741
  } else {
2742
    pColData->aOffset = NULL;
27,561✔
2743
  }
2744

2745
  // value
2746
  if (pColData->nData) {
27,665✔
2747
    pColData->pData = xMalloc(arg, pColData->nData);
27,575✔
2748
    if (pColData->pData == NULL) {
27,574!
2749
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2750
      goto _exit;
×
2751
    }
2752

2753
    (void)memcpy(pColData->pData, pColDataFrom->pData, pColData->nData);
27,574✔
2754
  } else {
2755
    pColData->pData = NULL;
90✔
2756
  }
2757

2758
_exit:
27,664✔
2759
  return code;
27,664✔
2760
}
2761

2762
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
7,873,071✔
2763
  int32_t code;
2764
  SBuffer local;
2765

2766
  if (!(colData->nVal > 0)) {
7,873,071!
2767
    return TSDB_CODE_INVALID_PARA;
×
2768
  }
2769

2770
  (*info) = (SColDataCompressInfo){
7,873,071✔
2771
      .cmprAlg = info->cmprAlg,
7,873,071✔
2772
      .columnFlag = colData->cflag,
7,873,071✔
2773
      .flag = colData->flag,
7,873,071✔
2774
      .dataType = colData->type,
7,873,071✔
2775
      .columnId = colData->cid,
7,873,071✔
2776
      .numOfData = colData->nVal,
7,873,071✔
2777
  };
2778

2779
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
7,873,071!
2780
    return 0;
242,216✔
2781
  }
2782

2783
  tBufferInit(&local);
2784
  if (assist == NULL) {
7,630,855!
2785
    assist = &local;
×
2786
  }
2787

2788
  // bitmap
2789
  if (colData->flag != HAS_VALUE) {
7,630,855✔
2790
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
1,705,816✔
2791
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
37,401✔
2792
    } else {
2793
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
1,668,415✔
2794
    }
2795

2796
    SCompressInfo cinfo = {
1,705,816✔
2797
        .dataType = TSDB_DATA_TYPE_TINYINT,
2798
        .cmprAlg = info->cmprAlg,
1,705,816✔
2799
        .originalSize = info->bitmapOriginalSize,
1,705,816✔
2800
    };
2801

2802
    code = tCompressDataToBuffer(colData->pBitMap, &cinfo, output, assist);
1,705,816✔
2803
    if (code) {
1,705,885!
2804
      tBufferDestroy(&local);
2805
      return code;
×
2806
    }
2807

2808
    info->bitmapCompressedSize = cinfo.compressedSize;
1,705,885✔
2809
  }
2810

2811
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
7,630,924✔
2812
    tBufferDestroy(&local);
2813
    return 0;
10,596✔
2814
  }
2815

2816
  // offset
2817
  if (IS_VAR_DATA_TYPE(colData->type)) {
7,620,328!
2818
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
1,010,666✔
2819

2820
    SCompressInfo cinfo = {
1,010,666✔
2821
        .dataType = TSDB_DATA_TYPE_INT,
2822
        .cmprAlg = info->cmprAlg,
1,010,666✔
2823
        .originalSize = info->offsetOriginalSize,
1,010,666✔
2824
    };
2825

2826
    code = tCompressDataToBuffer(colData->aOffset, &cinfo, output, assist);
1,010,666✔
2827
    if (code) {
1,010,787!
2828
      tBufferDestroy(&local);
2829
      return code;
×
2830
    }
2831

2832
    info->offsetCompressedSize = cinfo.compressedSize;
1,010,787✔
2833
  }
2834

2835
  // data
2836
  if (colData->nData > 0) {
7,620,449!
2837
    info->dataOriginalSize = colData->nData;
7,620,494✔
2838

2839
    SCompressInfo cinfo = {
7,620,494✔
2840
        .dataType = colData->type,
7,620,494✔
2841
        .cmprAlg = info->cmprAlg,
7,620,494✔
2842
        .originalSize = info->dataOriginalSize,
7,620,494✔
2843
    };
2844

2845
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
7,620,494✔
2846
    if (code) {
7,620,826!
2847
      tBufferDestroy(&local);
2848
      return code;
×
2849
    }
2850

2851
    info->dataCompressedSize = cinfo.compressedSize;
7,620,826✔
2852
  }
2853

2854
  tBufferDestroy(&local);
2855
  return 0;
7,620,781✔
2856
}
2857

2858
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
22,795,931✔
2859
  int32_t  code;
2860
  SBuffer  local;
2861
  uint8_t *data = (uint8_t *)input;
22,795,931✔
2862

2863
  tBufferInit(&local);
2864
  if (assist == NULL) {
22,795,931!
2865
    assist = &local;
×
2866
  }
2867

2868
  tColDataClear(colData);
22,795,931✔
2869
  colData->cid = info->columnId;
22,794,818✔
2870
  colData->type = info->dataType;
22,794,818✔
2871
  colData->cflag = info->columnFlag;
22,794,818✔
2872
  colData->nVal = info->numOfData;
22,794,818✔
2873
  colData->flag = info->flag;
22,794,818✔
2874

2875
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
22,794,818✔
2876
    goto _exit;
3,187,794✔
2877
  }
2878

2879
  // bitmap
2880
  if (info->bitmapOriginalSize > 0) {
19,607,024✔
2881
    SCompressInfo cinfo = {
1,844,219✔
2882
        .dataType = TSDB_DATA_TYPE_TINYINT,
2883
        .cmprAlg = info->cmprAlg,
1,844,219✔
2884
        .originalSize = info->bitmapOriginalSize,
1,844,219✔
2885
        .compressedSize = info->bitmapCompressedSize,
1,844,219✔
2886
    };
2887

2888
    code = tRealloc(&colData->pBitMap, cinfo.originalSize);
1,844,219!
2889
    if (code) {
1,843,896!
2890
      tBufferDestroy(&local);
2891
      return code;
×
2892
    }
2893

2894
    code = tDecompressData(data, &cinfo, colData->pBitMap, cinfo.originalSize, assist);
1,843,896✔
2895
    if (code) {
1,844,027!
2896
      tBufferDestroy(&local);
2897
      return code;
×
2898
    }
2899

2900
    data += cinfo.compressedSize;
1,844,027✔
2901
  }
2902

2903
  if (info->flag == (HAS_NONE | HAS_NULL)) {
19,606,832✔
2904
    goto _exit;
618✔
2905
  }
2906

2907
  // offset
2908
  if (info->offsetOriginalSize > 0) {
19,606,214✔
2909
    SCompressInfo cinfo = {
2,823,957✔
2910
        .cmprAlg = info->cmprAlg,
2,823,957✔
2911
        .dataType = TSDB_DATA_TYPE_INT,
2912
        .originalSize = info->offsetOriginalSize,
2,823,957✔
2913
        .compressedSize = info->offsetCompressedSize,
2,823,957✔
2914
    };
2915

2916
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
2,823,957!
2917
    if (code) {
2,824,134!
2918
      tBufferDestroy(&local);
2919
      return code;
×
2920
    }
2921

2922
    code = tDecompressData(data, &cinfo, colData->aOffset, cinfo.originalSize, assist);
2,824,134✔
2923
    if (code) {
2,823,909!
2924
      tBufferDestroy(&local);
2925
      return code;
×
2926
    }
2927

2928
    data += cinfo.compressedSize;
2,823,909✔
2929
  }
2930

2931
  // data
2932
  if (info->dataOriginalSize > 0) {
19,606,166✔
2933
    colData->nData = info->dataOriginalSize;
19,604,603✔
2934

2935
    SCompressInfo cinfo = {
19,604,603✔
2936
        .cmprAlg = info->cmprAlg,
19,604,603✔
2937
        .dataType = colData->type,
19,604,603✔
2938
        .originalSize = info->dataOriginalSize,
19,604,603✔
2939
        .compressedSize = info->dataCompressedSize,
19,604,603✔
2940
    };
2941

2942
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
19,604,603!
2943
    if (code) {
19,605,976!
2944
      tBufferDestroy(&local);
2945
      return code;
×
2946
    }
2947

2948
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
19,605,976✔
2949
    if (code) {
19,605,000!
2950
      tBufferDestroy(&local);
2951
      return code;
×
2952
    }
2953

2954
    data += cinfo.compressedSize;
19,605,000✔
2955
  }
2956

2957
_exit:
1,563✔
2958
  switch (colData->flag) {
22,794,975✔
2959
    case HAS_NONE:
2,861,008✔
2960
      colData->numOfNone = colData->nVal;
2,861,008✔
2961
      break;
2,861,008✔
2962
    case HAS_NULL:
329,739✔
2963
      colData->numOfNull = colData->nVal;
329,739✔
2964
      break;
329,739✔
2965
    case HAS_VALUE:
17,760,404✔
2966
      colData->numOfValue = colData->nVal;
17,760,404✔
2967
      break;
17,760,404✔
2968
    default:
1,843,824✔
2969
      for (int32_t i = 0; i < colData->nVal; i++) {
2,147,483,647✔
2970
        uint8_t bitValue = tColDataGetBitValue(colData, i);
2,147,483,647✔
2971
        if (bitValue == 0) {
2,147,483,647✔
2972
          colData->numOfNone++;
4,734,401✔
2973
        } else if (bitValue == 1) {
2,147,483,647✔
2974
          colData->numOfNull++;
218,617,123✔
2975
        } else {
2976
          colData->numOfValue++;
2,147,483,647✔
2977
        }
2978
      }
2979
  }
2980
  tBufferDestroy(&local);
2981
  return 0;
22,795,323✔
2982
}
2983

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

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

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

3058
_exit:
10✔
3059
  return code;
571✔
3060
}
3061

3062
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
6,523,503✔
3063
                               checkWKBGeometryFn cgeos) {
3064
  int32_t code = 0;
6,523,503✔
3065

3066
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
6,523,503✔
3067
    if (!(pColData->type == pBind->buffer_type)) {
5,955,002!
3068
      return TSDB_CODE_INVALID_PARA;
×
3069
    }
3070
  }
3071

3072
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
6,523,503!
3073
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
568,986✔
3074
      code = igeos();
203✔
3075
      if (code) {
202!
3076
        return code;
×
3077
      }
3078
    }
3079
    for (int32_t i = 0; i < pBind->num; ++i) {
2,478,631✔
3080
      if (pBind->is_null && pBind->is_null[i]) {
1,785,702✔
3081
        if (pColData->cflag & COL_IS_KEY) {
100,659!
3082
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3083
          goto _exit;
×
3084
        }
3085
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
100,659✔
3086
        if (code) goto _exit;
101,261!
3087
      } else if (pBind->length[i] > buffMaxLen) {
1,685,043!
3088
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3089
      } else {
3090
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
1,685,043✔
3091
          code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]);
204✔
3092
          if (code) {
205✔
3093
            uError("stmt col[%d] bind geometry wrong format", i);
1!
3094
            goto _exit;
1✔
3095
          }
3096
        }
3097
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
1,685,043✔
3098
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
1,685,043✔
3099
      }
3100
    }
3101
  } else {  // fixed-length data type
3102
    bool allValue;
3103
    bool allNull;
3104
    if (pBind->is_null) {
5,954,517✔
3105
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
556,770✔
3106
      allNull = (same && pBind->is_null[0] != 0);
556,770!
3107
      allValue = (same && pBind->is_null[0] == 0);
556,770!
3108
    } else {
3109
      allNull = false;
5,397,747✔
3110
      allValue = true;
5,397,747✔
3111
    }
3112

3113
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
5,954,517!
3114
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3115
      goto _exit;
×
3116
    }
3117

3118
    if (allValue) {
5,954,517✔
3119
      // optimize (todo)
3120
      for (int32_t i = 0; i < pBind->num; ++i) {
196,747,052✔
3121
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
189,022,292✔
3122
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
189,022,292✔
3123
      }
3124
    } else if (allNull) {
338,842!
3125
      // optimize (todo)
3126
      for (int32_t i = 0; i < pBind->num; ++i) {
975,426✔
3127
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
480,580✔
3128
        if (code) goto _exit;
494,633!
3129
      }
3130
    } else {
3131
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3132
        if (pBind->is_null[i]) {
79✔
3133
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
29✔
3134
          if (code) goto _exit;
29!
3135
        } else {
3136
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
50✔
3137
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
50✔
3138
        }
3139
      }
3140
    }
3141
  }
3142

3143
_exit:
×
3144
  return code;
8,770,585✔
3145
}
3146

3147
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
225✔
3148
                                checkWKBGeometryFn cgeos) {
3149
  int32_t code = 0;
225✔
3150

3151
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
225!
3152
    if (!(pColData->type == pBind->buffer_type)) {
225!
3153
      return TSDB_CODE_INVALID_PARA;
×
3154
    }
3155
  }
3156

3157
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
323!
3158
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
98✔
3159
      code = igeos();
3✔
3160
      if (code) {
3!
3161
        return code;
×
3162
      }
3163
    }
3164

3165
    uint8_t *buf = pBind->buffer;
98✔
3166
    for (int32_t i = 0; i < pBind->num; ++i) {
388✔
3167
      if (pBind->is_null && pBind->is_null[i]) {
290✔
3168
        if (pColData->cflag & COL_IS_KEY) {
2!
3169
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3170
          goto _exit;
×
3171
        }
3172
        if (pBind->is_null[i] == 1) {
2!
3173
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
2✔
3174
          if (code) goto _exit;
2!
3175
        } else {
3176
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3177
          if (code) goto _exit;
×
3178
        }
3179
      } else if (pBind->length[i] > buffMaxLen) {
288!
3180
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3181
      } else {
3182
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
288✔
3183
          code = cgeos(buf, pBind->length[i]);
7✔
3184
          if (code) {
7!
3185
            uError("stmt2 col[%d] bind geometry wrong format", i);
×
3186
            goto _exit;
×
3187
          }
3188
        }
3189
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);
288✔
3190
        buf += pBind->length[i];
288✔
3191
      }
3192
    }
3193
  } else {  // fixed-length data type
3194
    bool allValue;
3195
    bool allNull;
3196
    bool allNone;
3197
    if (pBind->is_null) {
127!
3198
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
×
3199
      allNull = (same && pBind->is_null[0] == 1);
×
3200
      allNone = (same && pBind->is_null[0] > 1);
×
3201
      allValue = (same && pBind->is_null[0] == 0);
×
3202
    } else {
3203
      allNull = false;
127✔
3204
      allNone = false;
127✔
3205
      allValue = true;
127✔
3206
    }
3207

3208
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
127!
3209
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3210
      goto _exit;
×
3211
    }
3212

3213
    if (allValue) {
127!
3214
      // optimize (todo)
3215
      for (int32_t i = 0; i < pBind->num; ++i) {
470✔
3216
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
343✔
3217
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
343!
3218
          *val = 1;
1✔
3219
        }
3220

3221
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
343✔
3222
      }
3223
    } else if (allNull) {
×
3224
      // optimize (todo)
3225
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3226
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3227
        if (code) goto _exit;
×
3228
      }
3229
    } else if (allNone) {
×
3230
      // optimize (todo)
3231
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3232
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3233
        if (code) goto _exit;
×
3234
      }
3235
    } else {
3236
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3237
        if (pBind->is_null[i]) {
×
3238
          if (pBind->is_null[i] == 1) {
×
3239
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3240
            if (code) goto _exit;
×
3241
          } else {
3242
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
3243
            if (code) goto _exit;
×
3244
          }
3245
        } else {
3246
          uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3247
          if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3248
            *val = 1;
×
3249
          }
3250

3251
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3252
        }
3253
      }
3254
    }
3255
  }
3256

3257
_exit:
×
3258
  return code;
225✔
3259
}
3260

3261
/* build rows to `rowArray` from bind
3262
 * `infos` is the bind information array
3263
 * `numOfInfos` is the number of bind information
3264
 * `infoSorted` is whether the bind information is sorted by column id
3265
 * `pTSchema` is the schema of the table
3266
 * `rowArray` is the array to store the rows
3267
 * `pOrdered` is the pointer to store ordered
3268
 * `pDupTs` is the pointer to store duplicateTs
3269
 */
3270
int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
5,718✔
3271
                           SArray *rowArray, bool *pOrdered, bool *pDupTs) {
3272
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
5,718!
3273
    return TSDB_CODE_INVALID_PARA;
×
3274
  }
3275

3276
  if (!infoSorted) {
5,742✔
3277
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo2), NULL, tBindInfoCompare);
1✔
3278
  }
3279

3280
  int32_t code = 0;
5,742✔
3281
  int32_t numOfRows = infos[0].bind->num;
5,742✔
3282
  SArray *colValArray, *bufArray;
3283
  SColVal colVal;
3284

3285
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
5,742!
3286
    return terrno;
×
3287
  }
3288
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
5,748!
3289
    taosArrayDestroy(colValArray);
×
3290
    return terrno;
×
3291
  }
3292
  for (int i = 0; i < numOfInfos; ++i) {
36,414✔
3293
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
61,333!
3294
      taosArrayDestroy(colValArray);
×
3295
      taosArrayDestroy(bufArray);
×
3296
      return terrno;
×
3297
    }
3298
  }
3299

3300
  SRowKey rowKey, lastRowKey;
3301
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
246,584!
3302
    taosArrayClear(colValArray);
246,875✔
3303

3304
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
1,181,691✔
3305
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
914,559✔
3306
        if (infos[iInfo].bind->is_null[iRow] == 1) {
2!
3307
          if (iInfo == 0) {
2✔
3308
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
1✔
3309
            goto _exit;
1✔
3310
          }
3311
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
1✔
3312
        } else {
3313
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3314
        }
3315
      } else {
3316
        SValue value = {
914,557✔
3317
            .type = infos[iInfo].type,
914,557✔
3318
        };
3319
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
914,557!
3320
          int32_t   length = infos[iInfo].bind->length[iRow];
6,794✔
3321
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
6,794✔
3322
          value.nData = length;
6,794✔
3323
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
6,794!
3324
            code = TSDB_CODE_INVALID_PARA;
×
3325
            goto _exit;
×
3326
          }
3327
          value.pData = *data;
6,794✔
3328
          *data += length;
6,794✔
3329
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3330
        } else {
3331
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
907,763✔
3332
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
907,763✔
3333
            *val = 1;
1✔
3334
          }
3335
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
907,763✔
3336
        }
3337
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
946,296✔
3338
      }
3339
      if (taosArrayPush(colValArray, &colVal) == NULL) {
935,121!
3340
        code = terrno;
×
3341
        goto _exit;
×
3342
      }
3343
    }
3344

3345
    SRow *row;
3346
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
267,132!
3347
      goto _exit;
×
3348
    }
3349

3350
    if ((taosArrayPush(rowArray, &row)) == NULL) {
240,829!
3351
      code = terrno;
×
3352
      goto _exit;
×
3353
    }
3354

3355
    if (pOrdered && pDupTs) {
240,829!
3356
      tRowGetKey(row, &rowKey);
481,752✔
3357
      if (iRow == 0) {
240,889✔
3358
        *pOrdered = true;
5,725✔
3359
        *pDupTs = false;
5,725✔
3360
      } else {
3361
        if (*pOrdered) {
235,164!
3362
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
235,164✔
3363
          *pOrdered = (res >= 0);
235,164✔
3364
          if (!*pDupTs) {
235,164!
3365
            *pDupTs = (res == 0);
235,187✔
3366
          }
3367
        }
3368
      }
3369
      lastRowKey = rowKey;
240,889✔
3370
    }
3371
  }
3372
_exit:
×
3373
  taosArrayDestroy(colValArray);
×
3374
  taosArrayDestroy(bufArray);
5,752✔
3375
  return code;
5,773✔
3376
}
3377

3378
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
346✔
3379
  int32_t code = TSDB_CODE_SUCCESS;
346✔
3380

3381
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
346!
3382
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
146✔
3383
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
51✔
3384
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
73✔
3385
    if (iToRow == 0) {
73✔
3386
      pToColData->aOffset[iToRow] = 0;
14✔
3387
    }
3388

3389
    if (iToRow < pToColData->nVal - 1) {
73✔
3390
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
64✔
3391
    }
3392

3393
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
73✔
3394
                 nData);
3395
  } else {
3396
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
273✔
3397
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
273✔
3398
  }
3399
  return code;
346✔
3400
}
3401

3402
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
354✔
3403
                                        int32_t iToRow) {
3404
  int32_t code = TSDB_CODE_SUCCESS;
354✔
3405
  int     bit_val = 0;
354✔
3406

3407
  switch (pFromColData->flag) {
354!
3408
    case HAS_NONE: {
×
3409
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
3410
    } break;
×
3411
    case HAS_NULL: {
8✔
3412
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
8!
3413
    } break;
8✔
3414
    case (HAS_NULL | HAS_NONE): {
×
3415
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
3416
      if (0 == bit_val)
×
3417
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
3418
      else
3419
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
×
3420
    } break;
×
3421
    case HAS_VALUE: {
298✔
3422
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
298!
3423
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
298!
3424
    } break;
298✔
3425
    case (HAS_VALUE | HAS_NONE): {
×
3426
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
3427
      if (0 == bit_val)
×
3428
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
3429
      else
3430
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
×
3431
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3432
    } break;
×
3433
    case (HAS_VALUE | HAS_NULL): {
48✔
3434
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
48✔
3435
      if (0 == bit_val)
48✔
3436
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
29!
3437
      else
3438
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
19!
3439
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
48!
3440
    } break;
48✔
3441
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
3442
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
3443
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3444
    } break;
×
3445
    default:
×
3446
      return -1;
×
3447
  }
3448

3449
  return code;
354✔
3450
}
3451

3452
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
75✔
3453
                               int32_t nColData) {
3454
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3455

3456
  for (int32_t i = 0; i < nColData; i++) {
429✔
3457
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
354✔
3458
    if (code != TSDB_CODE_SUCCESS) {
354!
3459
      return code;
×
3460
    }
3461
  }
3462

3463
  return code;
75✔
3464
}
3465

3466
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
75✔
3467
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3468

3469
  for (int32_t i = 0; i < nColData; i++) {
429✔
3470
    SColVal cv = {0};
354✔
3471
    code = tColDataGetValue(&aFromColData[i], iFromRow, &cv);
354✔
3472
    if (code != TSDB_CODE_SUCCESS) {
354!
3473
      return code;
×
3474
    }
3475
    code = tColDataAppendValue(&aToColData[i], &cv);
354✔
3476
    if (code != TSDB_CODE_SUCCESS) {
354!
3477
      return code;
×
3478
    }
3479
  }
3480

3481
  return code;
75✔
3482
}
3483

3484
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
225,030,006✔
3485
  SColVal cv;
3486

3487
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
225,030,006✔
3488
  key->numOfPKs = 0;
225,030,006✔
3489

3490
  for (int i = 1; i < nColData; i++) {
225,048,789!
3491
    if (aColData[i].cflag & COL_IS_KEY) {
225,894,398✔
3492
      tColDataGetValue4(&aColData[i], iRow, &cv);
18,238!
3493
      key->pks[key->numOfPKs++] = cv.value;
18,783✔
3494
    } else {
3495
      break;
225,876,160✔
3496
    }
3497
  }
3498
}
225,030,551✔
3499

3500
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
23✔
3501
  SColData *aDstColData = NULL;
23✔
3502
  int32_t   i = start, j = mid + 1, k = 0;
23✔
3503
  SRowKey   keyi, keyj;
3504

3505
  if (end > start) {
23!
3506
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
23!
3507
    if (aDstColData == NULL) {
23!
3508
      return terrno;
×
3509
    }
3510
    for (int c = 0; c < nColData; ++c) {
129✔
3511
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
106✔
3512
    }
3513
  }
3514

3515
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
23✔
3516
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
23✔
3517
  while (i <= mid && j <= end) {
63✔
3518
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
40✔
3519
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
30!
3520
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
30✔
3521
    } else {
3522
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
10!
3523
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
10✔
3524
    }
3525
  }
3526

3527
  while (i <= mid) {
35✔
3528
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
12!
3529
  }
3530

3531
  while (j <= end) {
46✔
3532
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
23!
3533
  }
3534

3535
  for (i = start, k = 0; i <= end; ++i, ++k) {
98✔
3536
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
75!
3537
  }
3538

3539
  if (aDstColData) {
23!
3540
    for (int32_t i = 0; i < nColData; i++) {
129✔
3541
      tColDataDestroy(&aDstColData[i]);
106✔
3542
    }
3543
    taosMemoryFree(aDstColData);
23!
3544
  }
3545

3546
  return TSDB_CODE_SUCCESS;
23✔
3547
}
3548

3549
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
52✔
3550
  int32_t ret = TSDB_CODE_SUCCESS;
52✔
3551
  int32_t mid;
3552

3553
  if (start >= end) {
52✔
3554
    return TSDB_CODE_SUCCESS;
29✔
3555
  }
3556

3557
  mid = (start + end) / 2;
23✔
3558

3559
  ret = tColDataMergeSort(aColData, start, mid, nColData);
23✔
3560
  if (ret != TSDB_CODE_SUCCESS) {
23!
3561
    return ret;
×
3562
  }
3563

3564
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
23✔
3565
  if (ret != TSDB_CODE_SUCCESS) {
23!
3566
    return ret;
×
3567
  }
3568

3569
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
23✔
3570
}
3571

3572
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
6✔
3573
  int32_t nVal = aColData[0].nVal;
6✔
3574

3575
  if (nVal < 2) return TSDB_CODE_SUCCESS;
6!
3576

3577
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
6✔
3578
}
3579

3580
static int32_t tColDataMerge(SArray **colArr) {
3✔
3581
  int32_t code = 0;
3✔
3582
  SArray *src = *colArr;
3✔
3583
  SArray *dst = NULL;
3✔
3584

3585
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
3✔
3586
  if (dst == NULL) {
3!
3587
    return terrno;
×
3588
  }
3589

3590
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
12✔
3591
    SColData *srcCol = taosArrayGet(src, i);
9✔
3592

3593
    SColData *dstCol = taosArrayReserve(dst, 1);
9✔
3594
    if (dstCol == NULL) {
9!
3595
      code = terrno;
×
3596
      goto _exit;
×
3597
    }
3598
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
9✔
3599
  }
3600

3601
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
3✔
3602
  SRowKey lastKey;
3603
  for (int32_t i = 0; i < numRows; i++) {
9✔
3604
    SRowKey key;
3605
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
3606

3607
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
9!
3608
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3609
        SColData *srcCol = taosArrayGet(src, j);
9✔
3610
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3611

3612
        SColVal cv;
3613
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3614
        if (code != TSDB_CODE_SUCCESS) {
9!
3615
          goto _exit;
×
3616
        }
3617
        code = tColDataAppendValue(dstCol, &cv);
9✔
3618
        if (code) {
9!
3619
          goto _exit;
×
3620
        }
3621
      }
3622
      lastKey = key;
3✔
3623
    } else {  // update existing row
3624
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3625
        SColData *srcCol = taosArrayGet(src, j);
9✔
3626
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3627

3628
        SColVal cv;
3629
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3630
        if (code != TSDB_CODE_SUCCESS) {
9!
3631
          goto _exit;
×
3632
        }
3633
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3634
        if (code) {
9!
3635
          goto _exit;
×
3636
        }
3637
      }
3638
    }
3639
  }
3640

3641
_exit:
3✔
3642
  if (code) {
3!
3643
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3644
  } else {
3645
    taosArrayDestroyEx(src, tColDataDestroy);
3✔
3646
    *colArr = dst;
3✔
3647
  }
3648
  return code;
3✔
3649
}
3650

3651
int32_t tColDataSortMerge(SArray **arr) {
40,893✔
3652
  SArray   *colDataArr = *arr;
40,893✔
3653
  int32_t   nColData = TARRAY_SIZE(colDataArr);
40,893✔
3654
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
40,893✔
3655

3656
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
40,893!
3657
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3658
  }
3659
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
40,893!
3660
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3661
  }
3662
  if (!(aColData[0].flag == HAS_VALUE)) {
40,893!
3663
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3664
  }
3665

3666
  if (aColData[0].nVal <= 1) goto _exit;
40,893✔
3667

3668
  int8_t doSort = 0;
40,702✔
3669
  int8_t doMerge = 0;
40,702✔
3670
  // scan -------
3671
  SRowKey lastKey;
3672
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
40,702✔
3673
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
105,302,955!
3674
    SRowKey key;
3675
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
106,626,083✔
3676

3677
    int32_t c = tRowKeyCompare(&lastKey, &key);
105,262,251✔
3678
    if (c < 0) {
105,262,251✔
3679
      lastKey = key;
105,239,138✔
3680
      continue;
105,239,138✔
3681
    } else if (c > 0) {
23,113✔
3682
      doSort = 1;
6✔
3683
      break;
6✔
3684
    } else {
3685
      doMerge = 1;
23,107✔
3686
    }
3687
  }
3688

3689
  // sort -------
3690
  if (doSort) {
×
3691
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
6!
3692
  }
3693

3694
  if (doMerge != 1) {
2,099,386✔
3695
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
40,735✔
3696
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
105,071,438!
3697
      SRowKey key;
3698
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
107,089,345✔
3699

3700
      int32_t c = tRowKeyCompare(&lastKey, &key);
105,030,705✔
3701
      if (c == 0) {
105,030,705!
3702
        doMerge = 1;
×
3703
        break;
×
3704
      }
3705
      lastKey = key;
105,030,705✔
3706
    }
3707
  }
3708

3709
  // merge -------
3710
  if (doMerge) {
40,744✔
3711
    int32_t code = tColDataMerge(arr);
3✔
3712
    if (code) return code;
3!
3713
  }
3714

3715
_exit:
40,744✔
3716
  return 0;
40,935✔
3717
}
3718

3719
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
251,874✔
3720
  int32_t code = 0;
251,874✔
3721

3722
  if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
503,748!
3723
  if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
503,748!
3724
  if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
503,748!
3725
  if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
503,748!
3726

3727
  // bitmap
3728
  switch (pColData->flag) {
251,874!
3729
    case (HAS_NULL | HAS_NONE):
2,106✔
3730
    case (HAS_VALUE | HAS_NONE):
3731
    case (HAS_VALUE | HAS_NULL):
3732
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
2,106✔
3733
      if (code) return code;
2,106!
3734
      break;
2,106✔
3735
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3736
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
3737
      if (code) return code;
×
3738
      break;
×
3739
    default:
249,768✔
3740
      break;
249,768✔
3741
  }
3742

3743
  // value
3744
  if (pColData->flag & HAS_VALUE) {
251,874✔
3745
    if (IS_VAR_DATA_TYPE(pColData->type)) {
251,538!
3746
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
1,704✔
3747
      if (code) return code;
1,704!
3748

3749
      code = tEncodeI32v(pEncoder, pColData->nData);
1,704✔
3750
      if (code) return code;
1,704!
3751

3752
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
1,704✔
3753
      if (code) return code;
1,704!
3754
    } else {
3755
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
249,834✔
3756
      if (code) return code;
249,834!
3757
    }
3758
  }
3759

3760
  return code;
251,874✔
3761
}
3762

3763
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
73,122✔
3764
  int32_t code = 0;
73,122✔
3765

3766
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
146,247!
3767
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
146,244!
3768
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
146,225!
3769
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
146,209!
3770

3771
  if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
73,103!
3772
    return TSDB_CODE_INVALID_PARA;
×
3773
  }
3774

3775
  // bitmap
3776
  switch (pColData->flag) {
73,109!
3777
    case (HAS_NULL | HAS_NONE):
112✔
3778
    case (HAS_VALUE | HAS_NONE):
3779
    case (HAS_VALUE | HAS_NULL):
3780
      code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
112!
3781
      if (code) return code;
112!
3782
      break;
112✔
3783
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3784
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
3785
      if (code) return code;
×
3786
      break;
×
3787
    default:
72,997✔
3788
      break;
72,997✔
3789
  }
3790

3791
  // value
3792
  if (pColData->flag & HAS_VALUE) {
73,109✔
3793
    if (IS_VAR_DATA_TYPE(pColData->type)) {
72,913!
3794
      code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
376!
3795
      if (code) return code;
376!
3796

3797
      code = tDecodeI32v(pDecoder, &pColData->nData);
376✔
3798
      if (code) return code;
378!
3799

3800
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
378!
3801
      if (code) return code;
378!
3802
    } else {
3803
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
72,537✔
3804
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
72,537!
3805
      if (code) return code;
72,537!
3806
    }
3807
  }
3808
  pColData->cflag = 0;
73,111✔
3809

3810
  return code;
73,111✔
3811
}
3812

3813
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
251,881✔
3814
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
251,881✔
3815
  if (code) return code;
251,858!
3816
  return tEncodeI8(pEncoder, pColData->cflag);
503,716✔
3817
}
3818

3819
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
73,122✔
3820
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
73,122✔
3821
  if (code) return code;
73,105!
3822

3823
  code = tDecodeI8(pDecoder, &pColData->cflag);
73,105✔
3824
  return code;
73,107✔
3825
}
3826

3827
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
251,863✔
3828
  if (version == 0) {
251,863!
3829
    return tEncodeColDataVersion0(pEncoder, pColData);
×
3830
  } else if (version == 1) {
251,863!
3831
    return tEncodeColDataVersion1(pEncoder, pColData);
251,898✔
3832
  } else {
3833
    return TSDB_CODE_INVALID_PARA;
×
3834
  }
3835
}
3836

3837
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
73,123✔
3838
  if (version == 0) {
73,123!
3839
    return tDecodeColDataVersion0(pDecoder, pColData);
×
3840
  } else if (version == 1) {
73,123!
3841
    return tDecodeColDataVersion1(pDecoder, pColData);
73,124✔
3842
  } else {
3843
    return TSDB_CODE_INVALID_PARA;
×
3844
  }
3845
}
3846

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

3849
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
1,199,043,804✔
3850
  if (ppRow == NULL) {
1,199,043,804!
3851
    return TSDB_CODE_INVALID_PARA;
×
3852
  }
3853

3854
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
1,199,043,804!
3855
    return TSDB_CODE_OUT_OF_RANGE;
×
3856
  }
3857

3858
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
1,199,043,804✔
3859
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
2,147,483,647!
3860
}
3861

3862
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3863
  do {                                       \
3864
    (SUM) += (VAL);                          \
3865
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3866
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3867
  } while (0)
3868

3869
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, SColumnDataAgg *pAggs) {
18,169✔
3870
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,169✔
3871
  int16_t *numOfNull = &pAggs->numOfNull;
18,169✔
3872
  *sum = 0;
18,169✔
3873
  *max = 0;
18,169✔
3874
  *min = 1;
18,169✔
3875
  *numOfNull = 0;
18,169✔
3876

3877
  int8_t val;
3878
  if (HAS_VALUE == pColData->flag) {
18,169✔
3879
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,749,359✔
3880
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,738,691✔
3881
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,738,691✔
3882
    }
3883
  } else {
3884
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,507,501✔
3885
      switch (tColDataGetBitValue(pColData, iVal)) {
2,500,000!
3886
        case 0:
1,500,000✔
3887
        case 1:
3888
          (*numOfNull)++;
1,500,000✔
3889
          break;
1,500,000✔
3890
        case 2:
1,000,000✔
3891
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
1,000,000✔
3892
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
1,000,000✔
3893
          break;
1,000,000✔
3894
        default:
×
3895
          break;
×
3896
      }
3897
    }
3898
  }
3899
}
18,169✔
3900

3901
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, SColumnDataAgg *pAggs) {
18,361✔
3902
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,361✔
3903
  int16_t *numOfNull = &pAggs->numOfNull;
18,361✔
3904
  *sum = 0;
18,361✔
3905
  *max = INT8_MIN;
18,361✔
3906
  *min = INT8_MAX;
18,361✔
3907
  *numOfNull = 0;
18,361✔
3908

3909
  int8_t val;
3910
  if (HAS_VALUE == pColData->flag) {
18,361✔
3911
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
5,044,240✔
3912
      val = ((int8_t *)pColData->pData)[iVal];
5,033,394✔
3913
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
5,033,394✔
3914
    }
3915
  } else {
3916
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,522,515✔
3917
      switch (tColDataGetBitValue(pColData, iVal)) {
2,515,000!
3918
        case 0:
1,852,496✔
3919
        case 1:
3920
          (*numOfNull)++;
1,852,496✔
3921
          break;
1,852,496✔
3922
        case 2:
662,504✔
3923
          val = ((int8_t *)pColData->pData)[iVal];
662,504✔
3924
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
662,504✔
3925
          break;
662,504✔
3926
        default:
×
3927
          break;
×
3928
      }
3929
    }
3930
  }
3931
}
18,361✔
3932

3933
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, SColumnDataAgg *pAggs) {
18,203✔
3934
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,203✔
3935
  int16_t *numOfNull = &pAggs->numOfNull;
18,203✔
3936
  *sum = 0;
18,203✔
3937
  *max = INT16_MIN;
18,203✔
3938
  *min = INT16_MAX;
18,203✔
3939
  *numOfNull = 0;
18,203✔
3940

3941
  int16_t val;
3942
  if (HAS_VALUE == pColData->flag) {
18,203✔
3943
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,869,024✔
3944
      val = ((int16_t *)pColData->pData)[iVal];
4,858,318✔
3945
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,858,318✔
3946
    }
3947
  } else {
3948
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,507,497✔
3949
      switch (tColDataGetBitValue(pColData, iVal)) {
2,500,000!
3950
        case 0:
1,841,659✔
3951
        case 1:
3952
          (*numOfNull)++;
1,841,659✔
3953
          break;
1,841,659✔
3954
        case 2:
658,341✔
3955
          val = ((int16_t *)pColData->pData)[iVal];
658,341✔
3956
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
658,341✔
3957
          break;
658,341✔
3958
        default:
×
3959
          break;
×
3960
      }
3961
    }
3962
  }
3963
}
18,203✔
3964

3965
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, SColumnDataAgg *pAggs) {
1,038,582✔
3966
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
1,038,582✔
3967
  int16_t *numOfNull = &pAggs->numOfNull;
1,038,582✔
3968
  *sum = 0;
1,038,582✔
3969
  *max = INT32_MIN;
1,038,582✔
3970
  *min = INT32_MAX;
1,038,582✔
3971
  *numOfNull = 0;
1,038,582✔
3972

3973
  int32_t val;
3974
  if (HAS_VALUE == pColData->flag) {
1,038,582✔
3975
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
856,256,294✔
3976
      val = ((int32_t *)pColData->pData)[iVal];
855,972,286✔
3977
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
855,972,286✔
3978
    }
3979
  } else {
3980
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,147,483,647✔
3981
      switch (tColDataGetBitValue(pColData, iVal)) {
2,147,483,647!
3982
        case 0:
142,296,036✔
3983
        case 1:
3984
          (*numOfNull)++;
142,296,036✔
3985
          break;
142,296,036✔
3986
        case 2:
2,147,483,647✔
3987
          val = ((int32_t *)pColData->pData)[iVal];
2,147,483,647✔
3988
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
2,147,483,647✔
3989
          break;
2,147,483,647✔
3990
        default:
×
3991
          break;
×
3992
      }
3993
    }
3994
  }
3995
}
1,020,824✔
3996

3997
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, SColumnDataAgg *pAggs) {
451,001✔
3998
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
451,001✔
3999
  int16_t *numOfNull = &pAggs->numOfNull;
451,001✔
4000
  *sum = 0;
451,001✔
4001
  *max = INT64_MIN;
451,001✔
4002
  *min = INT64_MAX;
451,001✔
4003
  *numOfNull = 0;
451,001✔
4004

4005
  int64_t val;
4006
  if (HAS_VALUE == pColData->flag) {
451,001✔
4007
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
1,528,522,323✔
4008
      val = ((int64_t *)pColData->pData)[iVal];
1,528,083,312✔
4009
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
1,528,083,312✔
4010
    }
4011
  } else {
4012
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
17,676,404✔
4013
      switch (tColDataGetBitValue(pColData, iVal)) {
17,664,401!
4014
        case 0:
3,118,662✔
4015
        case 1:
4016
          (*numOfNull)++;
3,118,662✔
4017
          break;
3,118,662✔
4018
        case 2:
14,547,784✔
4019
          val = ((int64_t *)pColData->pData)[iVal];
14,547,784✔
4020
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
14,547,784✔
4021
          break;
14,547,784✔
4022
        default:
×
4023
          break;
×
4024
      }
4025
    }
4026
  }
4027
}
451,014✔
4028

4029
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, SColumnDataAgg *pAggs) {
250,725✔
4030
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
250,725✔
4031
  int16_t *numOfNull = &pAggs->numOfNull;
250,725✔
4032
  *(double *)sum = 0;
250,725✔
4033
  *(double *)max = -FLT_MAX;
250,725✔
4034
  *(double *)min = FLT_MAX;
250,725✔
4035
  *numOfNull = 0;
250,725✔
4036

4037
  float val;
4038
  if (HAS_VALUE == pColData->flag) {
250,725✔
4039
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
955,231,980✔
4040
      val = ((float *)pColData->pData)[iVal];
954,988,769✔
4041
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
954,988,769✔
4042
    }
4043
  } else {
4044
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,522,619✔
4045
      switch (tColDataGetBitValue(pColData, iVal)) {
2,515,105!
4046
        case 0:
1,853,607✔
4047
        case 1:
4048
          (*numOfNull)++;
1,853,607✔
4049
          break;
1,853,607✔
4050
        case 2:
661,498✔
4051
          val = ((float *)pColData->pData)[iVal];
661,498✔
4052
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
661,498✔
4053
          break;
661,498✔
4054
        default:
×
4055
          break;
×
4056
      }
4057
    }
4058
  }
4059
}
250,725✔
4060

4061
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, SColumnDataAgg *pAggs) {
33,284✔
4062
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
33,284✔
4063
  int16_t *numOfNull = &pAggs->numOfNull;
33,284✔
4064
  *(double *)sum = 0;
33,284✔
4065
  *(double *)max = -DBL_MAX;
33,284✔
4066
  *(double *)min = DBL_MAX;
33,284✔
4067
  *numOfNull = 0;
33,284✔
4068

4069
  double val;
4070
  if (HAS_VALUE == pColData->flag) {
33,284✔
4071
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
34,411,052✔
4072
      val = ((double *)pColData->pData)[iVal];
34,385,283✔
4073
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
34,385,283✔
4074
    }
4075
  } else {
4076
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,522,515✔
4077
      switch (tColDataGetBitValue(pColData, iVal)) {
2,515,000!
4078
        case 0:
1,850,816✔
4079
        case 1:
4080
          (*numOfNull)++;
1,850,816✔
4081
          break;
1,850,816✔
4082
        case 2:
664,184✔
4083
          val = ((double *)pColData->pData)[iVal];
664,184✔
4084
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
664,184✔
4085
          break;
664,184✔
4086
        default:
×
4087
          break;
×
4088
      }
4089
    }
4090
  }
4091
}
33,284✔
4092

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

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

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

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

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

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

4189
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, SColumnDataAgg *pAggs) {
2,790✔
4190
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
2,790✔
4191
  int16_t *numOfNull = &pAggs->numOfNull;
2,790✔
4192
  *(uint64_t *)sum = 0;
2,790✔
4193
  *(uint64_t *)max = 0;
2,790✔
4194
  *(uint64_t *)min = UINT64_MAX;
2,790✔
4195
  *numOfNull = 0;
2,790✔
4196

4197
  uint64_t val;
4198
  if (HAS_VALUE == pColData->flag) {
2,790!
4199
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,480,696✔
4200
      val = ((uint64_t *)pColData->pData)[iVal];
3,477,905✔
4201
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,477,905✔
4202
    }
4203
  } else {
4204
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4205
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4206
        case 0:
×
4207
        case 1:
4208
          (*numOfNull)++;
×
4209
          break;
×
4210
        case 2:
×
4211
          val = ((uint64_t *)pColData->pData)[iVal];
×
4212
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4213
          break;
×
4214
        default:
×
4215
          break;
×
4216
      }
4217
    }
4218
  }
4219
}
2,790✔
4220

4221
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, SColumnDataAgg *pAggs) {
35,825✔
4222
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
35,825✔
4223
  int16_t *numOfNull = &pAggs->numOfNull;
35,825✔
4224
  *(uint64_t *)sum = 0;
35,825✔
4225
  *(uint64_t *)max = 0;
35,825✔
4226
  *(uint64_t *)min = 0;
35,825✔
4227
  *numOfNull = 0;
35,825✔
4228

4229
  switch (pColData->flag) {
35,825!
4230
    case HAS_NONE:
×
4231
    case HAS_NULL:
4232
    case (HAS_NONE | HAS_NULL):
4233
      *numOfNull = pColData->nVal;
×
4234
      break;
×
4235
    case HAS_VALUE:
26,960✔
4236
      *numOfNull = 0;
26,960✔
4237
      break;
26,960✔
4238
    case (HAS_VALUE | HAS_NULL):
8,865✔
4239
    case (HAS_VALUE | HAS_NONE):
4240
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,973,865✔
4241
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
2,965,000✔
4242
          (*numOfNull)++;
1,782,031✔
4243
        }
4244
      }
4245
      break;
8,865✔
4246
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4247
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4248
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4249
          (*numOfNull)++;
×
4250
        }
4251
      }
4252
      break;
×
4253
    default:
×
4254
      break;
×
4255
  }
4256
}
35,825✔
4257

4258
#define CALC_DECIMAL_SUM_MAX_MIN(TYPE, pSumOp, pCompOp, pColData, pSum, pMax, pMin)                   \
4259
  do {                                                                                                \
4260
    if (decimal128AddCheckOverflow((Decimal *)pSum, pVal, DECIMAL_WORD_NUM(TYPE))) *pOverflow = true; \
4261
    pSumOp->add(pSum, pVal, DECIMAL_WORD_NUM(TYPE));                                                  \
4262
    if (pCompOp->gt(pVal, pMax, DECIMAL_WORD_NUM(TYPE))) {                                            \
4263
      *(pMax) = *pVal;                                                                                \
4264
    }                                                                                                 \
4265
    if (pCompOp->lt(pVal, pMin, DECIMAL_WORD_NUM(TYPE))) {                                            \
4266
      *(pMin) = *pVal;                                                                                \
4267
    }                                                                                                 \
4268
  } while (0)
4269

4270
static FORCE_INLINE void tColDataCalcSMADecimal64Type(SColData *pColData, SColumnDataAgg *pAggs) {
184✔
4271
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum;
184✔
4272
  Decimal64  *pMax = (Decimal64 *)pAggs->decimal128Max, *pMin = (Decimal64 *)pAggs->decimal128Min;
184✔
4273
  uint8_t    *pOverflow = &pAggs->overflow;
184✔
4274
  *pSum = DECIMAL128_ZERO;
184✔
4275
  *pMax = DECIMAL64_MIN;
184✔
4276
  *pMin = DECIMAL64_MAX;
184✔
4277
  pAggs->numOfNull = 0;
184✔
4278
  pAggs->colId |= DECIMAL_AGG_FLAG;
184✔
4279

4280
  Decimal64         *pVal = NULL;
184✔
4281
  const SDecimalOps *pSumOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
184✔
4282
  const SDecimalOps *pCompOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
184✔
4283
  if (HAS_VALUE == pColData->flag) {
184✔
4284
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
1,212✔
4285
      pVal = ((Decimal64 *)pColData->pData) + iVal;
1,200✔
4286
      CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
1,200!
4287
    }
4288
  } else {
4289
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
143,372✔
4290
      switch (tColDataGetBitValue(pColData, iVal)) {
143,200!
4291
        case 0:
6,931✔
4292
        case 1:
4293
          pAggs->numOfNull++;
6,931✔
4294
          break;
6,931✔
4295
        case 2:
136,269✔
4296
          pVal = ((Decimal64 *)pColData->pData) + iVal;
136,269✔
4297
          CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
136,269!
4298
          break;
136,269✔
4299
        default:
×
4300
          break;
×
4301
      }
4302
    }
4303
  }
4304
}
184✔
4305

4306
static FORCE_INLINE void tColDataCalcSMADecimal128Type(SColData *pColData, SColumnDataAgg *pAggs) {
494✔
4307
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum, *pMax = (Decimal128 *)pAggs->decimal128Max,
494✔
4308
             *pMin = (Decimal128 *)pAggs->decimal128Min;
494✔
4309
  uint8_t *pOverflow = &pAggs->overflow;
494✔
4310
  *pSum = DECIMAL128_ZERO;
494✔
4311
  *pMax = DECIMAL128_MIN;
494✔
4312
  *pMin = DECIMAL128_MAX;
494✔
4313
  pAggs->numOfNull = 0;
494✔
4314
  pAggs->colId |= DECIMAL_AGG_FLAG;
494✔
4315

4316
  Decimal128        *pVal = NULL;
494✔
4317
  const SDecimalOps *pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
494✔
4318
  if (HAS_VALUE == pColData->flag) {
494✔
4319
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
808✔
4320
      pVal = ((Decimal128 *)pColData->pData) + iVal;
800✔
4321
      CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
800✔
4322
    }
4323
  } else {
4324
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
454,086✔
4325
      switch (tColDataGetBitValue(pColData, iVal)) {
453,600!
4326
        case 0:
20,553✔
4327
        case 1:
4328
          pAggs->numOfNull++;
20,553✔
4329
          break;
20,553✔
4330
        case 2:
433,047✔
4331
          pVal = ((Decimal128 *)pColData->pData) + iVal;
433,047✔
4332
          CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
433,047✔
4333
          break;
433,047✔
4334
        default:
×
4335
          break;
×
4336
      }
4337
    }
4338
  }
4339
}
494✔
4340

4341
void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAgg *pAggs) = {
4342
    NULL,
4343
    tColDataCalcSMABool,            // TSDB_DATA_TYPE_BOOL
4344
    tColDataCalcSMATinyInt,         // TSDB_DATA_TYPE_TINYINT
4345
    tColDataCalcSMATinySmallInt,    // TSDB_DATA_TYPE_SMALLINT
4346
    tColDataCalcSMAInt,             // TSDB_DATA_TYPE_INT
4347
    tColDataCalcSMABigInt,          // TSDB_DATA_TYPE_BIGINT
4348
    tColDataCalcSMAFloat,           // TSDB_DATA_TYPE_FLOAT
4349
    tColDataCalcSMADouble,          // TSDB_DATA_TYPE_DOUBLE
4350
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_VARCHAR
4351
    tColDataCalcSMABigInt,          // TSDB_DATA_TYPE_TIMESTAMP
4352
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_NCHAR
4353
    tColDataCalcSMAUTinyInt,        // TSDB_DATA_TYPE_UTINYINT
4354
    tColDataCalcSMATinyUSmallInt,   // TSDB_DATA_TYPE_USMALLINT
4355
    tColDataCalcSMAUInt,            // TSDB_DATA_TYPE_UINT
4356
    tColDataCalcSMAUBigInt,         // TSDB_DATA_TYPE_UBIGINT
4357
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_JSON
4358
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_VARBINARY
4359
    tColDataCalcSMADecimal128Type,  // TSDB_DATA_TYPE_DECIMAL
4360
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_BLOB
4361
    NULL,                           // TSDB_DATA_TYPE_MEDIUMBLOB
4362
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_GEOMETRY
4363
    tColDataCalcSMADecimal64Type,   // TSDB_DATA_TYPE_DECIMAL64
4364
};
4365

4366
// SValueColumn ================================
4367
int32_t tValueColumnInit(SValueColumn *valCol) {
22,524,204✔
4368
  valCol->type = TSDB_DATA_TYPE_NULL;
22,524,204✔
4369
  valCol->numOfValues = 0;
22,524,204✔
4370
  tBufferInit(&valCol->data);
22,524,204✔
4371
  tBufferInit(&valCol->offsets);
22,524,204✔
4372
  return 0;
22,524,204✔
4373
}
4374

4375
void tValueColumnDestroy(SValueColumn *valCol) {
55,241,794✔
4376
  valCol->type = TSDB_DATA_TYPE_NULL;
55,241,794✔
4377
  valCol->numOfValues = 0;
55,241,794✔
4378
  tBufferDestroy(&valCol->data);
55,241,794✔
4379
  tBufferDestroy(&valCol->offsets);
55,242,208✔
4380
  return;
55,242,169✔
4381
}
4382

4383
void tValueColumnClear(SValueColumn *valCol) {
29,067,306✔
4384
  valCol->type = TSDB_DATA_TYPE_NULL;
29,067,306✔
4385
  valCol->numOfValues = 0;
29,067,306✔
4386
  tBufferClear(&valCol->data);
29,067,306✔
4387
  tBufferClear(&valCol->offsets);
29,067,306✔
4388
  return;
29,067,306✔
4389
}
4390

4391
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
2,521,652✔
4392
  int32_t code;
4393

4394
  if (valCol->numOfValues == 0) {
2,521,652✔
4395
    valCol->type = value->type;
18,721✔
4396
  }
4397

4398
  if (!(value->type == valCol->type)) {
2,521,652!
4399
    return TSDB_CODE_INVALID_PARA;
×
4400
  }
4401

4402
  if (IS_VAR_DATA_TYPE(value->type)) {
2,521,652!
4403
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
18,723!
4404
      return code;
×
4405
    }
4406
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
18,723!
4407
      return code;
×
4408
    }
4409
  } else {
4410
    code = tBufferPut(&valCol->data, VALUE_GET_DATUM(value, value->type), tDataTypes[value->type].bytes);
2,512,291!
4411
    if (code) return code;
2,512,291!
4412
  }
4413
  valCol->numOfValues++;
2,521,652✔
4414

4415
  return 0;
2,521,652✔
4416
}
4417

4418
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
501,005,672✔
4419
  int32_t code;
4420

4421
  if (idx < 0 || idx >= valCol->numOfValues) {
501,005,672!
4422
    return TSDB_CODE_OUT_OF_RANGE;
×
4423
  }
4424

4425
  if (IS_VAR_DATA_TYPE(valCol->type)) {
501,021,393!
4426
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
×
4427
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
×
4428
    int32_t  oldDataSize = nextOffset - offsets[idx];
×
4429
    int32_t  bytesAdded = value->nData - oldDataSize;
×
4430

4431
    if (bytesAdded != 0) {
×
4432
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
×
4433
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
×
4434
              tBufferGetSize(&valCol->data) - nextOffset);
×
4435
      valCol->data.size += bytesAdded;
×
4436

4437
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
×
4438
        offsets[i] += bytesAdded;
×
4439
      }
4440
    }
4441
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
×
4442
  } else {
4443
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, VALUE_GET_DATUM(value, valCol->type),
501,030,351!
4444
                        tDataTypes[valCol->type].bytes);
501,030,351!
4445
  }
4446
  return 0;
4447
}
4448

4449
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
1,154,152,191✔
4450
  if (idx < 0 || idx >= valCol->numOfValues) {
1,154,152,191!
4451
    return TSDB_CODE_OUT_OF_RANGE;
×
4452
  }
4453

4454
  value->type = valCol->type;
1,154,243,479✔
4455
  if (IS_VAR_DATA_TYPE(value->type)) {
1,154,243,479!
4456
    int32_t       offset, nextOffset;
4457
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
720,866✔
4458

4459
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
720,866!
4460
    if (idx == valCol->numOfValues - 1) {
852,325✔
4461
      nextOffset = tBufferGetSize(&valCol->data);
253,266✔
4462
    } else {
4463
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
599,059✔
4464
    }
4465
    value->nData = nextOffset - offset;
851,747✔
4466
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
851,747✔
4467
  } else {
4468
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
1,153,522,613✔
4469
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
2,147,483,647!
4470
  }
4471
  return 0;
1,154,374,360✔
4472
}
4473

4474
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
18,719✔
4475
  int32_t code;
4476

4477
  if (!(valCol->numOfValues > 0)) {
18,719!
4478
    return TSDB_CODE_INVALID_PARA;
×
4479
  }
4480

4481
  (*info) = (SValueColumnCompressInfo){
18,719✔
4482
      .cmprAlg = info->cmprAlg,
18,719✔
4483
      .type = valCol->type,
18,719✔
4484
  };
4485

4486
  // offset
4487
  if (IS_VAR_DATA_TYPE(valCol->type)) {
18,719!
4488
    SCompressInfo cinfo = {
2,992✔
4489
        .cmprAlg = info->cmprAlg,
2,992✔
4490
        .dataType = TSDB_DATA_TYPE_INT,
4491
        .originalSize = valCol->offsets.size,
2,992✔
4492
    };
4493

4494
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
2,992✔
4495
    if (code) return code;
2,994!
4496

4497
    info->offsetOriginalSize = cinfo.originalSize;
2,994✔
4498
    info->offsetCompressedSize = cinfo.compressedSize;
2,994✔
4499
  }
4500

4501
  // data
4502
  SCompressInfo cinfo = {
18,721✔
4503
      .cmprAlg = info->cmprAlg,
18,721✔
4504
      .dataType = valCol->type,
18,721✔
4505
      .originalSize = valCol->data.size,
18,721✔
4506
  };
4507

4508
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
18,721✔
4509
  if (code) return code;
18,720!
4510

4511
  info->dataOriginalSize = cinfo.originalSize;
18,720✔
4512
  info->dataCompressedSize = cinfo.compressedSize;
18,720✔
4513

4514
  return 0;
18,720✔
4515
}
4516

4517
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
1,911,238✔
4518
                               SBuffer *assist) {
4519
  int32_t code;
4520

4521
  tValueColumnClear(valCol);
1,911,238✔
4522
  valCol->type = info->type;
1,911,245✔
4523
  // offset
4524
  if (IS_VAR_DATA_TYPE(valCol->type)) {
2,417,612!
4525
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
506,012✔
4526

4527
    SCompressInfo cinfo = {
506,012✔
4528
        .dataType = TSDB_DATA_TYPE_INT,
4529
        .cmprAlg = info->cmprAlg,
506,012✔
4530
        .originalSize = info->offsetOriginalSize,
506,012✔
4531
        .compressedSize = info->offsetCompressedSize,
506,012✔
4532
    };
4533

4534
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
506,012✔
4535
    if (code) {
506,367!
4536
      return code;
×
4537
    }
4538
  } else {
4539
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
1,405,233✔
4540
  }
4541

4542
  // data
4543
  SCompressInfo cinfo = {
1,911,600✔
4544
      .dataType = valCol->type,
1,911,600✔
4545
      .cmprAlg = info->cmprAlg,
1,911,600✔
4546
      .originalSize = info->dataOriginalSize,
1,911,600✔
4547
      .compressedSize = info->dataCompressedSize,
1,911,600✔
4548
  };
4549

4550
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
1,911,600✔
4551
  if (code) {
1,911,589!
4552
    return code;
×
4553
  }
4554

4555
  return 0;
1,911,589✔
4556
}
4557

4558
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
18,720✔
4559
  int32_t code;
4560
  uint8_t fmtVer = 0;
18,720✔
4561

4562
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
37,440!
4563
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
37,440!
4564
  if ((code = tBufferPutI8(buffer, info->type))) return code;
37,440!
4565
  if (IS_VAR_DATA_TYPE(info->type)) {
18,720!
4566
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
5,988!
4567
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
5,988!
4568
  }
4569
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
37,440!
4570
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
37,440!
4571

4572
  return 0;
18,720✔
4573
}
4574

4575
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
1,911,433✔
4576
  int32_t code;
4577
  uint8_t fmtVer;
4578

4579
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
1,911,433!
4580
  if (fmtVer == 0) {
1,911,449!
4581
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
1,911,464!
4582
    if ((code = tBufferGetI8(reader, &info->type))) return code;
1,911,230!
4583
    if (IS_VAR_DATA_TYPE(info->type)) {
1,911,098!
4584
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
505,955!
4585
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
506,089!
4586
    } else {
4587
      info->offsetOriginalSize = 0;
1,405,143✔
4588
      info->offsetCompressedSize = 0;
1,405,143✔
4589
    }
4590
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
1,911,193!
4591
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
1,911,005!
4592
  } else {
4593
    return TSDB_CODE_INVALID_PARA;
×
4594
  }
4595

4596
  return 0;
1,911,027✔
4597
}
4598

4599
int32_t tCompressData(void          *input,       // input
16,662,075✔
4600
                      SCompressInfo *info,        // compress info
4601
                      void          *output,      // output
4602
                      int32_t        outputSize,  // output size
4603
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4604
) {
4605
  int32_t extraSizeNeeded;
4606
  int32_t code;
4607

4608
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
16,662,075!
4609
  if (!(outputSize >= extraSizeNeeded)) {
16,662,075!
4610
    return TSDB_CODE_INVALID_PARA;
×
4611
  }
4612

4613
  if (info->cmprAlg == NO_COMPRESSION) {
16,662,075!
4614
    (void)memcpy(output, input, info->originalSize);
×
4615
    info->compressedSize = info->originalSize;
×
4616
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
19,308,378✔
4617
    SBuffer local;
4618

4619
    tBufferInit(&local);
4620
    if (buffer == NULL) {
2,643,764!
4621
      buffer = &local;
×
4622
    }
4623

4624
    if (info->cmprAlg == TWO_STAGE_COMP) {
2,643,764!
4625
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
2,646,131✔
4626
      if (code) {
2,646,131!
4627
        tBufferDestroy(&local);
4628
        return code;
×
4629
      }
4630
    }
4631

4632
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
5,290,067✔
4633
        input,                                                   // input
4634
        info->originalSize,                                      // input size
4635
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
2,643,764✔
4636
        output,                                                  // output
4637
        outputSize,                                              // output size
4638
        info->cmprAlg,                                           // compression algorithm
2,643,764✔
4639
        buffer->data,                                            // buffer
4640
        buffer->capacity                                         // buffer size
2,643,764✔
4641
    );
4642
    if (info->compressedSize < 0) {
2,646,303!
4643
      tBufferDestroy(&local);
4644
      return TSDB_CODE_COMPRESS_ERROR;
×
4645
    }
4646

4647
    tBufferDestroy(&local);
4648
  } else {
4649
    DEFINE_VAR(info->cmprAlg)
14,018,311✔
4650
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
14,018,311!
4651
      (void)memcpy(output, input, info->originalSize);
×
4652
      info->compressedSize = info->originalSize;
×
4653
      return 0;
×
4654
    }
4655
    SBuffer local;
4656

4657
    tBufferInit(&local);
4658
    if (buffer == NULL) {
14,018,311!
4659
      buffer = &local;
×
4660
    }
4661
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
14,018,311✔
4662

4663
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
28,038,115✔
4664
        input,                                                      // input
4665
        info->originalSize,                                         // input size
4666
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
14,018,326✔
4667
        output,                                                     // output
4668
        outputSize,                                                 // output size
4669
        info->cmprAlg,                                              // compression algorithm
4670
        buffer->data,                                               // buffer
4671
        buffer->capacity                                            // buffer size
14,018,326✔
4672
    );
4673
    if (info->compressedSize < 0) {
14,019,789!
4674
      tBufferDestroy(&local);
4675
      return TSDB_CODE_COMPRESS_ERROR;
×
4676
    }
4677

4678
    tBufferDestroy(&local);
4679
    // new col compress
4680
  }
4681

4682
  return 0;
16,666,092✔
4683
}
4684

4685
int32_t tDecompressData(void                *input,       // input
87,130,255✔
4686
                        const SCompressInfo *info,        // compress info
4687
                        void                *output,      // output
4688
                        int32_t              outputSize,  // output size
4689
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4690
) {
4691
  int32_t code;
4692

4693
  if (!(outputSize >= info->originalSize)) {
87,130,255!
4694
    return TSDB_CODE_INVALID_PARA;
×
4695
  }
4696

4697
  if (info->cmprAlg == NO_COMPRESSION) {
87,130,255!
4698
    if (!(info->compressedSize == info->originalSize)) {
×
4699
      return TSDB_CODE_INVALID_PARA;
×
4700
    }
4701
    (void)memcpy(output, input, info->compressedSize);
×
4702
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
126,322,030!
4703
    SBuffer local;
4704

4705
    tBufferInit(&local);
4706
    if (buffer == NULL) {
39,144,349!
4707
      buffer = &local;
×
4708
    }
4709

4710
    if (info->cmprAlg == TWO_STAGE_COMP) {
39,144,349!
4711
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
39,186,349✔
4712
      if (code) {
39,187,344!
4713
        tBufferDestroy(&local);
4714
        return code;
×
4715
      }
4716
    }
4717

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

4733
    if (!(decompressedSize == info->originalSize)) {
39,191,775!
4734
      return TSDB_CODE_COMPRESS_ERROR;
×
4735
    }
4736
    tBufferDestroy(&local);
4737
  } else {
4738
    DEFINE_VAR(info->cmprAlg);
47,985,906✔
4739
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
47,985,906!
4740
      (void)memcpy(output, input, info->compressedSize);
×
4741
      return 0;
×
4742
    }
4743
    SBuffer local;
4744

4745
    tBufferInit(&local);
4746
    if (buffer == NULL) {
47,985,906!
4747
      buffer = &local;
×
4748
    }
4749
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
47,985,906✔
4750
    if (code) {
47,986,669!
4751
      return code;
×
4752
    }
4753

4754
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
47,986,669✔
4755
        input,                                                  // input
4756
        info->compressedSize,                                   // inputSize
47,986,669✔
4757
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
47,986,669✔
4758
        output,                                                 // output
4759
        outputSize,                                             // output size
4760
        info->cmprAlg,                                          // compression algorithm
47,986,669✔
4761
        buffer->data,                                           // helper buffer
4762
        buffer->capacity                                        // extra buffer size
47,986,669✔
4763
    );
4764
    if (decompressedSize < 0) {
47,993,328!
4765
      tBufferDestroy(&local);
4766
      return TSDB_CODE_COMPRESS_ERROR;
×
4767
    }
4768

4769
    if (!(decompressedSize == info->originalSize)) {
47,993,328!
4770
      return TSDB_CODE_COMPRESS_ERROR;
×
4771
    }
4772
    tBufferDestroy(&local);
4773
  }
4774

4775
  return 0;
87,185,103✔
4776
}
4777

4778
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
16,662,413✔
4779
  int32_t code;
4780

4781
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
16,662,413✔
4782
  if (code) return code;
16,662,419!
4783

4784
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
16,662,419✔
4785
  if (code) return code;
16,663,521!
4786

4787
  output->size += info->compressedSize;
16,663,521✔
4788
  return 0;
16,663,521✔
4789
}
4790

4791
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
39,188,657✔
4792
  int32_t code;
4793

4794
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
39,188,657✔
4795
  if (code) return code;
39,182,643!
4796

4797
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
39,182,643✔
4798
  if (code) return code;
39,190,559!
4799

4800
  output->size += info->originalSize;
39,190,559✔
4801
  return 0;
39,190,559✔
4802
}
4803

4804
// handle all types, including var data
4805
void valueSetDatum(SValue *pVal, int8_t type, void *pDatum, uint32_t len) {
2,147,483,647✔
4806
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
2,147,483,647!
4807
    pVal->pData = pDatum;
×
4808
    pVal->nData = len;
×
4809
  } else {
4810
    switch (len) {
2,147,483,647!
4811
      case sizeof(uint8_t):
1,527,222,011✔
4812
        pVal->val = *(uint8_t *)pDatum;
1,527,222,011✔
4813
        break;
1,527,222,011✔
4814
      case sizeof(uint16_t):
841,264,013✔
4815
        pVal->val = *(uint16_t *)pDatum;
841,264,013✔
4816
        break;
841,264,013✔
4817
      case sizeof(uint32_t):
2,147,483,647✔
4818
        pVal->val = *(uint32_t *)pDatum;
2,147,483,647✔
4819
        break;
2,147,483,647✔
4820
      case sizeof(uint64_t):
2,147,483,647✔
4821
        pVal->val = *(uint64_t *)pDatum;
2,147,483,647✔
4822
        break;
2,147,483,647✔
4823
      default:
×
4824
        break;
×
4825
    }
4826
  }
4827
}
2,147,483,647✔
4828

4829
void valueCloneDatum(SValue *pDst, const SValue *pSrc, int8_t type) {
100,356,698✔
4830
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
100,356,698!
4831
    memcpy(pDst->pData, pSrc->pData, pSrc->nData);
1,757,521✔
4832
    pDst->nData = pSrc->nData;
1,757,521✔
4833
  } else {
4834
    pDst->val = pSrc->val;
98,599,177✔
4835
  }
4836
}
100,356,698✔
4837
void valueClearDatum(SValue *pVal, int8_t type) {
×
4838
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
4839
    taosMemoryFreeClear(pVal->pData);
×
4840
    pVal->nData = 0;
×
4841
  } else {
4842
    pVal->val = 0;
×
4843
  }
4844
}
×
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