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

taosdata / TDengine / #4523

17 Jul 2025 02:02AM UTC coverage: 56.768% (+0.3%) from 56.447%
#4523

push

travis-ci

web-flow
Merge pull request #31914 from taosdata/fix/3.0/compare-ans-failed

fix:Convert line endings from LF to CRLF for ans file

140094 of 313745 branches covered (44.65%)

Branch coverage included in aggregate %.

212455 of 307292 relevant lines covered (69.14%)

18276193.53 hits per line

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

62.8
/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) {
623,610,428✔
66
  int32_t n = 0;
623,610,428✔
67
  n += tPutI8(p ? p + n : p, index->type);
623,610,428✔
68
  n += tPutU32v(p ? p + n : p, index->offset);
623,610,428✔
69
  return n;
623,610,428✔
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;
78✔
113
  sinfo->numOfNull++;
21,399,536✔
114
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
21,399,536✔
115
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
21,399,536✔
116
  return 0;
21,399,536✔
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;
212,266,686✔
124
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
212,266,686✔
125
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
212,266,686!
126
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
212,266,686✔
127
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
212,266,686✔
128
    sinfo->numOfPKs++;
212,266,686✔
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
626,881,835✔
134
                           + colVal->value.nData;               // value
626,881,835✔
135

136
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
626,881,835✔
137
                            + tPutU32v(NULL, colVal->value.nData)  // size
626,881,835✔
138
                            + colVal->value.nData;                 // value
626,881,835✔
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,233,482,856✔
147
  int32_t  code = 0;
1,233,482,856✔
148
  int32_t  colValIndex = 1;
1,233,482,856✔
149
  int32_t  numOfColVals = TARRAY_SIZE(colVals);
1,233,482,856✔
150
  SColVal *colValArray = (SColVal *)TARRAY_DATA(colVals);
1,233,482,856✔
151

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

163
  *sinfo = (SRowBuildScanInfo){
1,233,482,856✔
164
      .tupleFixedSize = schema->flen,
1,233,482,856✔
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;
276!
172
        break;
138✔
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;
42,799,228✔
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) {
213,180✔
192
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
74!
193
        break;
37✔
194
      } else {  // skip useless value
195
        colValIndex++;
213,143✔
196
      }
197
    }
198
  }
199

200
  if (sinfo->numOfNone) {
1,233,482,778✔
201
    sinfo->flag |= HAS_NONE;
373,183,220✔
202
  }
203
  if (sinfo->numOfNull) {
1,233,482,778✔
204
    sinfo->flag |= HAS_NULL;
15,067,315✔
205
  }
206
  if (sinfo->numOfValue) {
1,233,482,778✔
207
    sinfo->flag |= HAS_VALUE;
1,200,148,831✔
208
  }
209

210
  // Tuple
211
  sinfo->tupleFlag = sinfo->flag;
1,233,482,778✔
212
  switch (sinfo->flag) {
1,233,482,778!
213
    case HAS_NONE:
38,066,218✔
214
    case HAS_NULL:
215
      sinfo->tupleBitmapSize = 0;
38,066,218✔
216
      sinfo->tupleFixedSize = 0;
38,066,218✔
217
      break;
38,066,218✔
218
    case HAS_VALUE:
853,810,613✔
219
      sinfo->tupleBitmapSize = 0;
853,810,613✔
220
      sinfo->tupleFixedSize = schema->flen;
853,810,613✔
221
      break;
853,810,613✔
222
    case (HAS_NONE | HAS_NULL):
24,435✔
223
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
24,435✔
224
      sinfo->tupleFixedSize = 0;
24,435✔
225
      break;
24,435✔
226
    case (HAS_NONE | HAS_VALUE):
345,271,649✔
227
    case (HAS_NULL | HAS_VALUE):
228
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
345,271,649✔
229
      sinfo->tupleFixedSize = schema->flen;
345,271,649✔
230
      break;
345,271,649✔
231
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
2,462,671✔
232
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
2,462,671✔
233
      sinfo->tupleFixedSize = schema->flen;
2,462,671✔
234
      break;
2,462,671✔
235
  }
236
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,443,176,506✔
237
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
210,257,719✔
238
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
210,257,719✔
239
  }
240
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,232,918,787✔
241
                        + sinfo->tuplePKSize      // primary keys
1,232,918,787✔
242
                        + sinfo->tupleBitmapSize  // bitmap
1,232,918,787✔
243
                        + sinfo->tupleFixedSize   // fixed part
1,232,918,787✔
244
                        + sinfo->tupleVarSize;    // var part
1,232,918,787✔
245

246
  // Key-Value
247
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,232,918,787!
248
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,234,174,484✔
249
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,234,174,484✔
250
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
251
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
4,924,058✔
252
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
4,924,058✔
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++) {
1,442,488,576✔
258
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
210,074,857✔
259
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
210,074,857✔
260
  }
261
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,232,413,719✔
262
                     + sinfo->kvPKSize        // primary keys
1,232,413,719✔
263
                     + sinfo->kvIndexSize     // index array
1,232,413,719✔
264
                     + sinfo->kvPayloadSize;  // payload
1,232,413,719✔
265

266
_exit:
1,232,413,797✔
267
  return code;
1,232,413,797✔
268
}
269

270
static int32_t tRowBuildTupleRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
899,831,937✔
271
                                 SRow **ppRow) {
272
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
899,831,937✔
273

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

284
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
910,263,906!
285
    return 0;
36,629,790✔
286
  }
287

288
  uint8_t *primaryKeys = (*ppRow)->data;
873,634,116✔
289
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
873,634,116✔
290
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
873,634,116✔
291
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
873,634,116✔
292

293
  // primary keys
294
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,085,120,200✔
295
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
213,759,239✔
296
  }
297

298
  // bitmap + fixed + varlen
299
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
871,360,961✔
300
  int32_t colValIndex = 1;
871,360,961✔
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);
22!
305
        break;
22✔
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;
163,649,561✔
314
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
163,649,561✔
315
            if (colValArray[colValIndex].value.nData) {
163,649,561!
316
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
164,419,635✔
317
              varlen += colValArray[colValIndex].value.nData;
164,419,635✔
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
12,165,659✔
325
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
12,059,686!
326
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
105,973!
327
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
460,471!
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
×
333
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
15!
334
        break;
15✔
335
      } else {
336
        colValIndex++;
×
337
      }
338
    }
339
  }
340

341
  return 0;
871,360,961✔
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) {
6,210,180!
348
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
7,801,272✔
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) {
338,501,033✔
356
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
338,501,033✔
357

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

368
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
338,705,375!
369
    return TSDB_CODE_INVALID_PARA;
×
370
  }
371

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

377
  // primary keys
378
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
339,215,781✔
379
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
485,430✔
380
  }
381

382
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
338,730,351✔
383
  int32_t colValIndex = 1;
338,730,351✔
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;
116✔
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);
468,429,780✔
395
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
468,429,780✔
396
            if (colValArray[colValIndex].value.nData > 0) {
468,429,780!
397
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
477,233,636✔
398
                           colValArray[colValIndex].value.nData);
477,233,636✔
399
            }
400
            payloadSize += colValArray[colValIndex].value.nData;
468,429,780✔
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);
9,092,410✔
410
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
18,184,820✔
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;
338,730,351✔
424
}
425

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

430
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
1,233,673,609✔
431
  if (code) return code;
1,239,010,956✔
432

433
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
1,239,010,878✔
434
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
900,754,193✔
435
  } else {
436
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
338,256,685✔
437
  }
438
  return code;
1,242,739,060✔
439
}
440

441
static int32_t tBindInfoCompare(const void *p1, const void *p2, const void *param) {
×
442
  if (((SBindInfo *)p1)->columnId < ((SBindInfo *)p2)->columnId) {
×
443
    return -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,711✔
460
                          SArray *rowArray, bool *pOrdered, bool *pDupTs) {
461
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
50,711!
462
    return TSDB_CODE_INVALID_PARA;
×
463
  }
464

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

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

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

478
  SRowKey rowKey, lastRowKey;
479
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
101,095,790!
480
    taosArrayClear(colValArray);
109,316,254✔
481

482
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
453,547,957✔
483
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
338,136,352✔
484
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
32✔
485
      } else {
486
        SValue value = {
338,136,320✔
487
            .type = infos[iInfo].type,
338,136,320✔
488
        };
489
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
338,136,320!
490
          value.nData = infos[iInfo].bind->length[iRow];
175,408✔
491
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
175,408!
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;
175,408✔
496
        } else {
497
          valueSetDatum(&value, infos[iInfo].type,
337,960,912✔
498
                        (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
337,960,912✔
499
                        infos[iInfo].bind->buffer_length);
337,960,912✔
500
        }
501
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
364,704,562✔
502
      }
503
      if (taosArrayPush(colValArray, &colVal) == NULL) {
345,080,773!
504
        code = terrno;
×
505
        goto _exit;
×
506
      }
507
    }
508

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

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

519
    if (pOrdered && pDupTs) {
101,243,654!
520
      tRowGetKey(row, &rowKey);
203,016,600!
521
      if (iRow == 0) {
101,309,180✔
522
        *pOrdered = true;
50,986✔
523
        *pDupTs = false;
50,986✔
524
      } else {
525
        if (*pOrdered) {
101,258,194!
526
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
101,369,349✔
527
          *pOrdered = (res >= 0);
101,369,349✔
528
          if (!*pDupTs) {
101,369,349!
529
            *pDupTs = (res == 0);
101,497,115✔
530
          }
531
        }
532
      }
533
      lastRowKey = rowKey;
101,309,180✔
534
    }
535
  }
536

537
_exit:
×
538
  taosArrayDestroy(colValArray);
×
539
  return code;
51,295✔
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;
15,472,340✔
550
    pColVal->value.type = pTColumn->type;
15,472,340✔
551
    pColVal->flag = CV_FLAG_VALUE;
15,472,340✔
552
    VALUE_SET_TRIVIAL_DATUM(&pColVal->value, pRow->ts);
15,472,340✔
553
    return 0;
15,472,340✔
554
  }
555

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

561
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
562
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,083,420✔
563
    return 0;
1,083,420✔
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);
31,147,080✔
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) {
62,726,783!
579
      pv = pIdx->idx + (pIdx->nCol << 1);
85,012,290✔
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) {
359,816,533!
592
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
359,967,063✔
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);
37,129,586✔
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);
664,934,944!
610
            if (pColVal->value.nData > 0) {
664,934,944!
611
              pColVal->value.pData = pData;
831,698,553✔
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);
1,805,773,826✔
628
  } else {  // Tuple Row
629
    uint8_t *bitmap = data;
760,426,146✔
630
    uint8_t *fixed;
631
    uint8_t *varlen;
632
    uint8_t  bit;
633

634
    if (pRow->flag == HAS_VALUE) {
760,426,146✔
635
      fixed = bitmap;
726,483,877✔
636
      bit = BIT_FLG_VALUE;
726,483,877✔
637
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
33,942,269!
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;
33,942,269✔
642
      bit = GET_BIT1(bitmap, iCol - 1);
33,942,269✔
643

644
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
33,942,269✔
645
        if (bit) bit++;
21,507✔
646
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
33,920,762!
647
        bit++;
44,806,449✔
648
      }
649
    }
650
    varlen = fixed + pTSchema->flen;
760,426,146✔
651

652
    if (bit == BIT_FLG_NONE) {
760,426,146✔
653
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,625✔
654
      return 0;
7,625✔
655
    } else if (bit == BIT_FLG_NULL) {
760,418,521✔
656
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
13,880,508✔
657
      return 0;
13,880,508✔
658
    }
659

660
    pColVal->cid = pTColumn->colId;
746,538,013✔
661
    pColVal->value.type = pTColumn->type;
746,538,013✔
662
    pColVal->flag = CV_FLAG_VALUE;
746,538,013✔
663
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
746,538,013!
664
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
54,338,991✔
665
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
108,677,982!
666
    } else {
667
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
692,199,022✔
668
    }
669
  }
670

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

674
void tRowDestroy(SRow *pRow) {
863,592,062✔
675
  if (pRow) taosMemoryFree(pRow);
863,592,062!
676
}
863,743,840✔
677

678
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
875,370,954✔
679
  SRowKey key1, key2;
680
  tRowGetKey(*(SRow **)p1, &key1);
1,750,741,908✔
681
  tRowGetKey(*(SRow **)p2, &key2);
1,754,228,494✔
682
  return tRowKeyCompare(&key1, &key2);
906,308,375✔
683
}
684
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
1,108✔
685
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
290✔
686
  int32_t code = 0;
290✔
687

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

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

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

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

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

713
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
1,122✔
714
    SColVal *pColVal = NULL;
832✔
715
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
1,004✔
716
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
945✔
717
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
1,074✔
718
        pColValT = tRowIterNext(aIter[iRow]);
129✔
719
      }
720

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

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

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

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

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

762
int32_t tRowSort(SArray *aRowP) {
104,828✔
763
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
104,828✔
764
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
72,665✔
765
  if (code != TSDB_CODE_SUCCESS) {
72,673!
766
    uError("taosArrayMSort failed caused by %d", code);
×
767
  }
768
  return code;
72,673✔
769
}
770

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

774
  int32_t iStart = 0;
104,898✔
775
  while (iStart < aRowP->size) {
149,680,844✔
776
    SRowKey key1;
777
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
149,575,080✔
778

779
    tRowGetKey(row1, &key1);
299,082,230✔
780

781
    int32_t iEnd = iStart + 1;
149,562,016✔
782
    while (iEnd < aRowP->size) {
149,567,641✔
783
      SRowKey key2;
784
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
149,426,277✔
785
      tRowGetKey(row2, &key2);
298,802,072✔
786

787
      if (tRowKeyCompare(&key1, &key2) != 0) break;
149,440,207✔
788

789
      iEnd++;
5,625✔
790
    }
791

792
    if (iEnd - iStart > 1) {
149,575,946✔
793
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
290✔
794
      if (code) return code;
290!
795
    }
796

797
    // the array is also changing, so the iStart just ++ instead of iEnd
798
    iStart++;
149,575,946✔
799
  }
800

801
  return code;
105,764✔
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,136,106✔
825
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,136,106!
826

827
  int32_t code = 0;
1,136,106✔
828

829
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
1,136,106!
830
  if (pIter == NULL) {
1,169,948!
831
    code = terrno;
×
832
    goto _exit;
×
833
  }
834

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

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

841
  uint8_t         *data = pRow->data;
1,169,704✔
842
  SPrimaryKeyIndex index;
843
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,213,371✔
844
    data += tGetPrimaryKeyIndex(data, &index);
43,690✔
845
  }
846

847
  if (pRow->flag >> 4) {
1,169,681✔
848
    pIter->iCol = 0;
1,165,426✔
849
    pIter->pIdx = (SKVIdx *)data;
1,165,426✔
850
    if (pRow->flag & KV_FLG_LIT) {
1,165,426✔
851
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
1,162,552✔
852
    } else if (pRow->flag & KV_FLG_MID) {
2,874!
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)
×
856
    }
857
  } else {
858
    switch (pRow->flag) {
4,255!
859
      case (HAS_NULL | HAS_NONE):
1✔
860
        pIter->pb = data;
1✔
861
        break;
1✔
862
      case HAS_VALUE:
3,396✔
863
        pIter->pf = data;
3,396✔
864
        pIter->pv = pIter->pf + pTSchema->flen;
3,396✔
865
        break;
3,396✔
866
      case (HAS_VALUE | HAS_NONE):
1,287✔
867
      case (HAS_VALUE | HAS_NULL):
868
        pIter->pb = data;
1,287✔
869
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
1,287✔
870
        pIter->pv = pIter->pf + pTSchema->flen;
1,287✔
871
        break;
1,287✔
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:
×
878
        break;
×
879
    }
880
  }
881

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

891
void tRowIterClose(SRowIter **ppIter) {
1,114,568✔
892
  SRowIter *pIter = *ppIter;
1,114,568✔
893
  if (pIter) {
1,114,568!
894
    taosMemoryFree(pIter);
1,115,071!
895
  }
896
  *ppIter = NULL;
1,179,857✔
897
}
1,179,857✔
898

899
SColVal *tRowIterNext(SRowIter *pIter) {
13,698,711✔
900
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
13,698,711✔
901
    return NULL;
1,105,366✔
902
  }
903

904
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
12,593,345✔
905

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

915
  if (pIter->pRow->flag == HAS_NONE) {
11,447,074✔
916
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
71,409✔
917
    goto _exit;
71,409✔
918
  }
919

920
  if (pIter->pRow->flag == HAS_NULL) {
11,375,665✔
921
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
3,141✔
922
    goto _exit;
3,141✔
923
  }
924

925
  if (pIter->pRow->flag >> 4) {  // KV
11,372,524!
926
    if (pIter->iCol < pIter->pIdx->nCol) {
12,053,530✔
927
      uint8_t *pData;
928

929
      if (pIter->pRow->flag & KV_FLG_LIT) {
9,697,420✔
930
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
9,604,723✔
931
      } else if (pIter->pRow->flag & KV_FLG_MID) {
92,697!
932
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
98,153✔
933
      } else {
934
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
935
      }
936

937
      int16_t cid;
938
      pData += tGetI16v(pData, &cid);
9,697,420✔
939

940
      if (TABS(cid) == pTColumn->colId) {
9,697,420!
941
        if (cid < 0) {
9,978,030✔
942
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,722,580✔
943
        } else {
944
          pIter->cv.cid = pTColumn->colId;
8,255,450✔
945
          pIter->cv.value.type = pTColumn->type;
8,255,450✔
946
          pIter->cv.flag = CV_FLAG_VALUE;
8,255,450✔
947

948
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
8,255,450!
949
            pData += tGetU32v(pData, &pIter->cv.value.nData);
1,017,384!
950
            if (pIter->cv.value.nData > 0) {
1,017,384!
951
              pIter->cv.value.pData = pData;
2,237,866✔
952
            } else {
953
              pIter->cv.value.pData = NULL;
×
954
            }
955
          } else {
956
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
7,238,066✔
957
          }
958
        }
959

960
        pIter->iCol++;
10,797,915✔
961
        goto _exit;
10,797,915✔
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);
2,356,110✔
971
      goto _exit;
2,356,110✔
972
    }
973
  } else {  // Tuple
974
    uint8_t bv = BIT_FLG_VALUE;
×
975
    if (pIter->pb) {
×
976
      switch (pIter->pRow->flag) {
5,651!
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,601✔
985
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
5,601✔
986
          break;
5,601✔
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,651✔
995
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
17✔
996
        goto _exit;
17✔
997
      } else if (bv == BIT_FLG_NULL) {
5,634✔
998
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
703✔
999
        goto _exit;
703✔
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,037✔
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,747✔
1016
    }
1017
    goto _exit;
36,784✔
1018
  }
1019

1020
_exit:
14,412,444✔
1021
  pIter->iTColumn++;
14,412,444✔
1022
  return &pIter->cv;
14,412,444✔
1023
}
1024

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

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

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

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

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

1045
  while (pColData) {
739,722✔
1046
    if (pTColumn) {
558,217!
1047
      if (pTColumn->colId == pColData->cid) {  // NULL
558,217✔
1048
        if (flag == 0) {
558,192!
1049
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
558,207✔
1050
        } else {
1051
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
×
1052
        }
1053
        if (code) goto _exit;
558,183!
1054

1055
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
558,183✔
1056
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
558,183✔
1057
      } else if (pTColumn->colId > pColData->cid) {  // NONE
25!
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;
25!
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:
181,505✔
1070
  return code;
181,505✔
1071
}
1072
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
741,115,912✔
1073
                                      int32_t flag) {
1074
  int32_t code = 0;
741,115,912✔
1075

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

1081
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
741,115,912✔
1082
  SPrimaryKeyIndex index;
1083
  uint8_t         *data = pRow->data;
741,115,912✔
1084
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
976,263,556✔
1085
    data += tGetPrimaryKeyIndex(data, &index);
235,165,084✔
1086
  }
1087

1088
  switch (pRow->flag) {
741,098,472!
1089
    case HAS_VALUE:
732,302,883✔
1090
      pf = data;  // TODO: fix here
732,302,883✔
1091
      pv = pf + pTSchema->flen;
732,302,883✔
1092
      break;
732,302,883✔
1093
    case (HAS_NULL | HAS_NONE):
1,297✔
1094
      pb = data;
1,297✔
1095
      break;
1,297✔
1096
    case (HAS_VALUE | HAS_NONE):
8,797,976✔
1097
    case (HAS_VALUE | HAS_NULL):
1098
      pb = data;
8,797,976✔
1099
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
8,797,976✔
1100
      pv = pf + pTSchema->flen;
8,797,976✔
1101
      break;
8,797,976✔
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) {
35,215,426!
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):
265,339✔
1124
              bv = GET_BIT1(pb, iTColumn - 1);
265,339✔
1125
              if (bv) bv++;
265,339✔
1126
              break;
265,339✔
1127
            case (HAS_VALUE | HAS_NULL):
34,924,644✔
1128
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
34,924,644✔
1129
              break;
34,924,644✔
1130
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1131
              bv = GET_BIT2(pb, iTColumn - 1);
×
1132
              break;
×
1133
            default:
×
1134
              return TSDB_CODE_INVALID_DATA_FMT;
×
1135
          }
1136

1137
          if (bv == BIT_FLG_NONE) {
35,215,916✔
1138
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
48,445!
1139
              goto _exit;
×
1140
            goto _continue;
48,425✔
1141
          } else if (bv == BIT_FLG_NULL) {
35,167,471✔
1142
            if (flag == 0) {
11,510,837✔
1143
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
11,508,788✔
1144
            } else {
1145
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
2,049✔
1146
            }
1147
            if (code) goto _exit;
11,510,691!
1148
            goto _continue;
11,510,691✔
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);
61,522,173!
1154
          uint32_t nData;
1155
          pData += tGetU32v(pData, &nData);
61,522,173✔
1156
          if (flag == 0) {
61,522,173!
1157
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
66,446,032✔
1158
          } else {
1159
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1160
          }
1161
          if (code) goto _exit;
68,004,417!
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,
15,013,505✔
1168
                                                                          TYPE_BYTES[pColData->type], flag > 0);
15,013,505✔
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,277!
1184
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
420,269✔
1185
    }
1186
  }
1187

1188
_exit:
744,405,862✔
1189
  return code;
744,405,862✔
1190
}
1191
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
6,518,697✔
1192
  int32_t code = 0;
6,518,697✔
1193

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

1201
  // primary keys
1202
  uint8_t         *data = pRow->data;
6,518,697✔
1203
  SPrimaryKeyIndex index;
1204
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
6,791,999✔
1205
    data += tGetPrimaryKeyIndex(data, &index);
273,337✔
1206
  }
1207

1208
  SKVIdx *pKVIdx = (SKVIdx *)data;
6,518,662✔
1209
  if (pRow->flag & KV_FLG_LIT) {
6,518,662✔
1210
    pv = pKVIdx->idx + pKVIdx->nCol;
6,453,030✔
1211
  } else if (pRow->flag & KV_FLG_MID) {
65,632!
1212
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
70,264✔
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) {
106,073,817✔
1220
    if (pTColumn) {
99,585,942✔
1221
      if (pTColumn->colId == pColData->cid) {
99,186,814✔
1222
        while (iCol < pKVIdx->nCol) {
99,133,716✔
1223
          uint8_t *pData;
1224
          if (pRow->flag & KV_FLG_LIT) {
67,965,617✔
1225
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
66,015,634✔
1226
          } else if (pRow->flag & KV_FLG_MID) {
1,949,983!
1227
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,950,049✔
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);
67,965,683✔
1236

1237
          if (TABS(cid) == pTColumn->colId) {
67,965,683✔
1238
            if (cid < 0) {
35,088,411✔
1239
              if (flag == 0) {
8,678,452✔
1240
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
8,677,158✔
1241
              } else {
1242
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
1,294✔
1243
              }
1244
              if (code) goto _exit;
8,163,853!
1245
            } else {
1246
              uint32_t nData;
1247
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
26,409,959!
1248
                pData += tGetU32v(pData, &nData);
5,640,322✔
1249
              } else {
1250
                nData = 0;
20,769,637✔
1251
              }
1252
              if (flag == 0) {
26,409,959!
1253
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
26,614,062✔
1254
              } else {
1255
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1256
              }
1257
              if (code) goto _exit;
26,889,571!
1258
            }
1259
            iCol++;
35,053,424✔
1260
            goto _continue;
35,053,424✔
1261
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
32,877,272✔
1262
            break;
32,508,250✔
1263
          } else {
1264
            iCol++;
369,022✔
1265
          }
1266
        }
1267

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

1270
      _continue:
63,675,870✔
1271
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
98,729,294✔
1272
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
98,729,294✔
1273
      } else if (pTColumn->colId > pColData->cid) {
422,120!
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;
422,120!
1278
      }
1279
    } else {
1280
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
399,128!
1281
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
399,109✔
1282
    }
1283
  }
1284

1285
_exit:
6,487,875✔
1286
  return code;
6,487,875✔
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) {
747,777,884✔
1293
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
747,777,884!
1294
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
747,777,884!
1295

1296
  if (pRow->flag == HAS_NONE) {
747,777,884✔
1297
    return tRowNoneUpsertColData(aColData, nColData, flag);
10,853✔
1298
  } else if (pRow->flag == HAS_NULL) {
747,767,031✔
1299
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
181,514✔
1300
  } else if (pRow->flag >> 4) {  // KV row
747,585,517✔
1301
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
6,521,453✔
1302
  } else {  // TUPLE row
1303
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
741,064,064✔
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);
14,032,370✔
1329
    }
1330

1331
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
1332
      key->pks[i].pData = tdata;
3,451,716✔
1333
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
6,903,432!
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) {
52,843,702✔
1352
  switch (tv1->type) {
52,843,702!
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,165,866✔
1359
      T_COMPARE_SCALAR_VALUE(int32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
1,165,866✔
1360
    case TSDB_DATA_TYPE_BIGINT:
47,483,681✔
1361
    case TSDB_DATA_TYPE_TIMESTAMP:
1362
      T_COMPARE_SCALAR_VALUE(int64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
47,483,681✔
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,110,591✔
1372
      T_COMPARE_SCALAR_VALUE(uint32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
1,110,591✔
1373
    case TSDB_DATA_TYPE_UBIGINT:
1,131,205✔
1374
      T_COMPARE_SCALAR_VALUE(uint64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
1,131,205✔
1375
    case TSDB_DATA_TYPE_GEOMETRY:
1,951,946✔
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,951,946✔
1378
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
1,951,946✔
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:
413✔
1390
      break;
413✔
1391
  }
1392

1393
  return 0;
413✔
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) {
75,622,837!
1407
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
119,573,542!
1408
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
52,834,402✔
1409
      if (ret) return ret;
52,828,691!
1410
    }
1411
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1412
    return -1;
7✔
1413
  } else {
1414
    return 1;
×
1415
  }
1416

1417
  return 0;
66,739,140✔
1418
}
1419

1420
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
774,860,378✔
1421
  pDst->ts = pSrc->ts;
774,860,378✔
1422
  pDst->numOfPKs = pSrc->numOfPKs;
774,860,378✔
1423

1424
  if (pSrc->numOfPKs > 0) {
774,860,378✔
1425
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
67,018,468✔
1426
      SValue *pVal = &pDst->pks[i];
33,344,969✔
1427
      pVal->type = pSrc->pks[i].type;
33,344,969✔
1428

1429
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
33,344,969✔
1430
    }
1431
  }
1432
}
775,189,451✔
1433

1434
// STag ========================================
1435
static int tTagValCmprFn(const void *p1, const void *p2) {
144,690,722✔
1436
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
144,690,722✔
1437
    return -1;
49,790,931✔
1438
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
94,899,791✔
1439
    return 1;
51,790,550✔
1440
  }
1441

1442
  return 0;
43,109,241✔
1443
}
1444
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
16,341✔
1445
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
16,341✔
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,184,382✔
1542
  int32_t n = 0;
1,184,382✔
1543

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

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

1554
  // value
1555
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
1,184,382!
1556
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
914,560✔
1557
  } else {
1558
    p = p ? p + n : p;
727,102✔
1559
    n += tDataTypes[pTagVal->type].bytes;
727,102✔
1560
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
727,102✔
1561
  }
1562

1563
  return n;
1,184,382✔
1564
}
1565
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
143,050,790✔
1566
  int32_t n = 0;
143,050,790✔
1567

1568
  // key
1569
  if (isJson) {
143,050,790✔
1570
    n += tGetCStr(p + n, &pTagVal->pKey);
38,346!
1571
  } else {
1572
    n += tGetI16v(p + n, &pTagVal->cid);
286,063,234!
1573
  }
1574

1575
  // type
1576
  n += tGetI8(p + n, &pTagVal->type);
143,050,790!
1577

1578
  // value
1579
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
143,050,790!
1580
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
45,749,610!
1581
  } else {
1582
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
120,175,985✔
1583
    n += tDataTypes[pTagVal->type].bytes;
120,175,985✔
1584
  }
1585

1586
  return n;
143,050,790✔
1587
}
1588

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

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

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

1606
  // sort
1607
  if (isJson) {
227,149✔
1608
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
655✔
1609
  } else {
1610
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
226,494✔
1611
  }
1612

1613
  // get size
1614
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
819,354✔
1615
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
592,154✔
1616
  }
1617
  if (szTag <= INT8_MAX) {
227,200✔
1618
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
209,010✔
1619
  } else {
1620
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
18,190✔
1621
    isLarge = 1;
18,190✔
1622
  }
1623

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

1641
  if (isLarge) {
227,250✔
1642
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
18,222✔
1643
  } else {
1644
    p = (uint8_t *)&(*ppTag)->idx[nTag];
209,028✔
1645
  }
1646
  n = 0;
227,250✔
1647
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
819,594✔
1648
    if (isLarge) {
592,348✔
1649
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
138,907✔
1650
    } else {
1651
      (*ppTag)->idx[iTag] = n;
453,441✔
1652
    }
1653
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
592,348✔
1654
  }
1655
#ifdef TD_DEBUG_PRINT_TAG
1656
  debugPrintSTag(*ppTag, __func__, __LINE__);
1657
#endif
1658

1659
  return code;
227,246✔
1660

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

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

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

1674
  char  *data = NULL;
13,488,601✔
1675
  int8_t typeBytes = 0;
13,488,601✔
1676
  if (isJson) {
13,488,601✔
1677
    typeBytes = CHAR_BYTES;
9,288✔
1678
  }
1679

1680
  if (IS_VAR_DATA_TYPE(value->type)) {
13,488,601✔
1681
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
3,586,766!
1682
    if (data == NULL) {
3,590,033!
1683
      return NULL;
×
1684
    }
1685

1686
    if (isJson) {
3,590,033✔
1687
      *data = value->type;
5,560✔
1688
    }
1689

1690
    varDataLen(data + typeBytes) = value->nData;
3,590,033✔
1691
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
3,590,033✔
1692
  } else {
1693
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
9,901,835✔
1694
  }
1695

1696
  return data;
13,491,868✔
1697
}
1698

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

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

1714
  if (isLarge) {
44,034,657✔
1715
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
36,554,041✔
1716
  } else {
1717
    p = (uint8_t *)&pTag->idx[pTag->nTag];
7,480,616✔
1718
  }
1719

1720
  pTagVal->type = TSDB_DATA_TYPE_NULL;
44,034,657✔
1721
  pTagVal->pData = NULL;
44,034,657✔
1722
  pTagVal->nData = 0;
44,034,657✔
1723
  while (lidx <= ridx) {
144,913,754✔
1724
    midx = (lidx + ridx) / 2;
143,361,888✔
1725
    if (isLarge) {
143,361,888✔
1726
      offset = ((int16_t *)pTag->idx)[midx];
118,496,306✔
1727
    } else {
1728
      offset = pTag->idx[midx];
24,865,582✔
1729
    }
1730

1731
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
143,361,888✔
1732
    if (isJson) {
144,406,927✔
1733
      c = tTagValJsonCmprFn(pTagVal, &tv);
15,854✔
1734
    } else {
1735
      c = tTagValCmprFn(pTagVal, &tv);
144,391,073✔
1736
    }
1737

1738
    if (c < 0) {
145,863,069✔
1739
      ridx = midx - 1;
49,141,833✔
1740
    } else if (c > 0) {
96,721,236✔
1741
      lidx = midx + 1;
51,737,264✔
1742
    } else {
1743
      (void)memcpy(pTagVal, &tv, sizeof(tv));
44,983,972✔
1744
      return true;
44,983,972✔
1745
    }
1746
  }
1747
  return false;
1,551,866✔
1748
}
1749

1750
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
907,155✔
1751
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,814,310✔
1752
}
1753

1754
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
22,768,284✔
1755

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

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

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

1775
  for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
6,698✔
1776
    if (isLarge) {
4,148✔
1777
      offset = ((int16_t *)pTag->idx)[iTag];
22✔
1778
    } else {
1779
      offset = pTag->idx[iTag];
4,126✔
1780
    }
1781
    int32_t nt = tGetTagVal(p + offset, &tv, pTag->flags & TD_TAG_JSON);
4,148✔
1782
    if (taosArrayPush(*ppArray, &tv) == NULL) {
8,296!
1783
      code = terrno;
×
1784
      goto _err;
×
1785
    }
1786
  }
1787

1788
  return code;
2,550✔
1789

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

1794
// STSchema ========================================
1795
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
15,835,664✔
1796
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
15,835,664!
1797
  if (pTSchema == NULL) {
15,868,399!
1798
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1799
    return NULL;
×
1800
  }
1801

1802
  pTSchema->numOfCols = numOfCols;
15,868,399✔
1803
  pTSchema->version = version;
15,868,399✔
1804

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

1822
  // other columns
1823
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
233,672,434✔
1824
    SSchema  *pSchema = &aSchema[iCol];
217,804,035✔
1825
    STColumn *pTColumn = &pTSchema->columns[iCol];
217,804,035✔
1826

1827
    pTColumn->colId = pSchema->colId;
217,804,035✔
1828
    pTColumn->type = pSchema->type;
217,804,035✔
1829
    pTColumn->flags = pSchema->flags;
217,804,035✔
1830
    pTColumn->offset = pTSchema->flen;
217,804,035✔
1831

1832
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
217,804,035!
1833
      pTColumn->bytes = pSchema->bytes;
37,572,525✔
1834
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
37,572,525✔
1835
    } else {
1836
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
180,231,510✔
1837
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
180,231,510✔
1838
    }
1839

1840
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
217,804,035✔
1841
  }
1842

1843
#if 1  // todo : remove this
1844
  pTSchema->tlen += (int32_t)TD_BITMAP_BYTES(numOfCols);
15,868,399✔
1845
#endif
1846

1847
  return pTSchema;
15,868,399✔
1848
}
1849

1850
static int32_t tTColumnCompare(const void *p1, const void *p2) {
10,918,136✔
1851
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
10,918,136✔
1852
    return -1;
1,652,303✔
1853
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
9,265,833✔
1854
    return 1;
6,545,777✔
1855
  }
1856

1857
  return 0;
2,720,056✔
1858
}
1859

1860
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid) {
2,721,562✔
1861
  STColumn tcol = {
2,721,562✔
1862
      .colId = cid,
1863
  };
1864

1865
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
2,721,562✔
1866
}
1867

1868
// SColData ========================================
1869
void tColDataDestroy(void *ph) {
22,650,852✔
1870
  if (ph) {
22,650,852!
1871
    SColData *pColData = (SColData *)ph;
22,651,061✔
1872

1873
    tFree(pColData->pBitMap);
22,651,061!
1874
    tFree(pColData->aOffset);
22,651,137!
1875
    tFree(pColData->pData);
22,651,204!
1876
  }
1877
}
22,652,225✔
1878

1879
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
23,006,373✔
1880
  pColData->cid = cid;
23,006,373✔
1881
  pColData->type = type;
23,006,373✔
1882
  pColData->cflag = cflag;
23,006,373✔
1883
  tColDataClear(pColData);
23,006,373✔
1884
}
23,009,033✔
1885

1886
void tColDataClear(SColData *pColData) {
46,681,893✔
1887
  pColData->numOfNone = 0;
46,681,893✔
1888
  pColData->numOfNull = 0;
46,681,893✔
1889
  pColData->numOfValue = 0;
46,681,893✔
1890
  pColData->nVal = 0;
46,681,893✔
1891
  pColData->flag = 0;
46,681,893✔
1892
  pColData->nData = 0;
46,681,893✔
1893
}
46,681,893✔
1894

1895
void tColDataDeepClear(SColData *pColData) {
188,123✔
1896
  pColData->pBitMap = NULL;
188,123✔
1897
  pColData->aOffset = NULL;
188,123✔
1898
  pColData->pData = NULL;
188,123✔
1899

1900
  tColDataClear(pColData);
188,123✔
1901
}
188,152✔
1902

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

1906
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
1907
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
115,115,022!
1908
    if (code) goto _exit;
125,176,588!
1909
    pColData->aOffset[pColData->nVal] = pColData->nData;
125,176,588✔
1910

1911
    if (nData) {
125,176,588!
1912
      code = tRealloc(&pColData->pData, pColData->nData + nData);
122,018,045!
1913
      if (code) goto _exit;
123,207,503!
1914
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
123,207,503✔
1915
      pColData->nData += nData;
123,207,503✔
1916
    }
1917
  } else {
1918
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
1919
      return TSDB_CODE_INVALID_PARA;
×
1920
    }
1921
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
1922
    if (code) goto _exit;
2,147,483,647!
1923
    if (pData) {
2,147,483,647!
1924
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
1925
    } else {
1926
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
42,309,909✔
1927
    }
1928
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
1929
  }
1930
  pColData->nVal++;
2,147,483,647✔
1931

1932
_exit:
2,147,483,647✔
1933
  return code;
2,147,483,647✔
1934
}
1935
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
3,111,169✔
1936
  pColData->flag = HAS_VALUE;
3,111,332✔
1937
  pColData->numOfValue++;
3,111,169✔
1938
  return tColDataPutValue(pColData, pData, nData);
3,112,562✔
1939
}
1940
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
243,845✔
1941
  pColData->flag = HAS_NONE;
243,845✔
1942
  pColData->numOfNone++;
243,845✔
1943
  pColData->nVal++;
243,845✔
1944
  return 0;
243,845✔
1945
}
1946
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
188,127✔
1947
  pColData->flag = HAS_NULL;
188,187✔
1948
  pColData->numOfNull++;
188,187✔
1949
  pColData->nVal++;
188,187✔
1950
  return 0;
188,127✔
1951
}
1952
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,483✔
1953
  int32_t code = 0;
1,483✔
1954

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

1959
  memset(pColData->pBitMap, 0, nBit);
1,483✔
1960
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,483!
1961

1962
  pColData->flag |= HAS_VALUE;
1,483✔
1963
  pColData->numOfValue++;
1,483✔
1964

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

1979
  return tColDataPutValue(pColData, pData, nData);
1,484✔
1980
}
1981
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
85,189,771✔
1982
  pColData->nVal++;
85,189,771✔
1983
  pColData->numOfNone++;
85,189,771✔
1984
  return 0;
85,189,771✔
1985
}
1986
static FORCE_INLINE int32_t tColDataAppendValue12(SColData *pColData, uint8_t *pData, uint32_t nData) {
604✔
1987
  int32_t code = 0;
604✔
1988

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

1993
  memset(pColData->pBitMap, 0, nBit);
604✔
1994
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
604!
1995

1996
  pColData->flag |= HAS_NULL;
604✔
1997
  pColData->numOfNull++;
604✔
1998
  pColData->nVal++;
604✔
1999

2000
  return code;
604✔
2001
}
2002
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
29,133✔
2003
  int32_t code = 0;
29,133✔
2004

2005
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
29,133✔
2006
  code = tRealloc(&pColData->pBitMap, nBit);
29,133!
2007
  if (code) return code;
29,132!
2008

2009
  memset(pColData->pBitMap, 0, nBit);
29,132✔
2010
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
29,132!
2011

2012
  pColData->flag |= HAS_VALUE;
29,132✔
2013
  pColData->numOfValue++;
29,132✔
2014

2015
  if (pColData->nVal) {
29,132!
2016
    if (IS_VAR_DATA_TYPE(pColData->type)) {
29,133!
2017
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
7,725✔
2018
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
7,725!
2019
      if (code) return code;
7,726!
2020
      memset(pColData->aOffset, 0, nOffset);
7,726✔
2021
    } else {
2022
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
21,408✔
2023
      code = tRealloc(&pColData->pData, pColData->nData);
21,408!
2024
      if (code) return code;
21,407!
2025
      memset(pColData->pData, 0, pColData->nData);
21,407✔
2026
    }
2027
  }
2028

2029
  return tColDataPutValue(pColData, pData, nData);
29,134✔
2030
}
2031
static FORCE_INLINE int32_t tColDataAppendValue21(SColData *pColData, uint8_t *pData, uint32_t nData) {
10,080✔
2032
  int32_t code = 0;
10,080✔
2033

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

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

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

2045
  return code;
10,080✔
2046
}
2047
static FORCE_INLINE int32_t tColDataAppendValue22(SColData *pColData, uint8_t *pData, uint32_t nData) {
8,131,743✔
2048
  pColData->nVal++;
8,131,743✔
2049
  pColData->numOfNull++;
8,131,743✔
2050
  return 0;
8,131,743✔
2051
}
2052
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
5✔
2053
  int32_t code = 0;
5✔
2054

2055
  pColData->flag |= HAS_VALUE;
5✔
2056
  pColData->numOfValue++;
5✔
2057

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

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

2067
  tFree(pColData->pBitMap);
5!
2068
  pColData->pBitMap = pBitMap;
5✔
2069

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

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

2089
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,989,903!
2090
  if (code) return code;
1,989,903!
2091

2092
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
1,989,903✔
2093
  pColData->numOfNone++;
1,989,903✔
2094
  pColData->nVal++;
1,989,903✔
2095

2096
  return code;
1,989,903✔
2097
}
2098
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
9,376✔
2099
  int32_t code = 0;
9,376✔
2100

2101
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
9,376!
2102
  if (code) return code;
9,377!
2103

2104
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
9,377!
2105
  pColData->numOfNull++;
9,377✔
2106
  pColData->nVal++;
9,377✔
2107

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

2117
  pColData->flag |= HAS_NONE;
147,357✔
2118
  pColData->numOfNone++;
147,357✔
2119

2120
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
147,357✔
2121
  code = tRealloc(&pColData->pBitMap, nBit);
147,357✔
2122
  if (code) return code;
147,386!
2123

2124
  memset(pColData->pBitMap, 255, nBit);
147,386✔
2125
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
147,386✔
2126

2127
  return tColDataPutValue(pColData, NULL, 0);
147,381✔
2128
}
2129
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
253,250✔
2130
  int32_t code = 0;
258,554✔
2131

2132
  pColData->flag |= HAS_NULL;
258,554✔
2133
  pColData->numOfNull++;
258,554✔
2134

2135
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
258,554✔
2136
  code = tRealloc(&pColData->pBitMap, nBit);
258,250✔
2137
  if (code) return code;
258,579!
2138

2139
  memset(pColData->pBitMap, 255, nBit);
258,579✔
2140
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
258,579!
2141

2142
  return tColDataPutValue(pColData, NULL, 0);
258,592✔
2143
}
2144
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,391,854✔
2145
  int32_t code = 0;
1,393,856✔
2146

2147
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,393,854!
2148
  if (code) return code;
1,394,546!
2149

2150
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,394,546!
2151
  pColData->numOfValue++;
1,394,546!
2152

2153
  return tColDataPutValue(pColData, pData, nData);
1,397,601✔
2154
}
2155
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
14,177,274✔
2156
  int32_t code = 0;
14,177,274✔
2157

2158
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
14,177,274!
2159
  if (code) return code;
14,177,318!
2160

2161
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
14,177,318✔
2162
  pColData->numOfNone++;
14,177,318✔
2163

2164
  return tColDataPutValue(pColData, NULL, 0);
14,179,870✔
2165
}
2166
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
12,467✔
2167
  int32_t code = 0;
12,467✔
2168

2169
  pColData->flag |= HAS_NULL;
12,467✔
2170
  pColData->numOfNull++;
12,467✔
2171

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

2176
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,766,274!
2177
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
3,753,807!
2178
  }
2179
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
12,467!
2180

2181
  tFree(pColData->pBitMap);
12,467!
2182
  pColData->pBitMap = pBitMap;
12,467!
2183

2184
  return tColDataPutValue(pColData, NULL, 0);
12,467✔
2185
}
2186
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
282,408,682✔
2187
  int32_t code = 0;
282,411,642✔
2188

2189
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
282,411,242!
2190
  if (code) return code;
283,059,773!
2191
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
283,059,773!
2192
  pColData->numOfValue++;
283,059,773✔
2193

2194
  return tColDataPutValue(pColData, pData, nData);
284,628,227✔
2195
}
2196
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
28,925✔
2197
  int32_t code = 0;
28,925✔
2198

2199
  pColData->flag |= HAS_NONE;
28,925✔
2200
  pColData->numOfNone++;
28,925✔
2201

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

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

2211
  tFree(pColData->pBitMap);
28,925!
2212
  pColData->pBitMap = pBitMap;
28,925✔
2213

2214
  return tColDataPutValue(pColData, NULL, 0);
28,928✔
2215
}
2216
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
20,240,611✔
2217
  int32_t code = 0;
20,254,206✔
2218

2219
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
20,250,611!
2220
  if (code) return code;
20,263,861!
2221
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
20,263,861✔
2222
  pColData->numOfNull++;
20,263,861✔
2223

2224
  return tColDataPutValue(pColData, NULL, 0);
20,275,692✔
2225
}
2226
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
660,581✔
2227
  int32_t code = 0;
660,581✔
2228

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

2234
  return tColDataPutValue(pColData, pData, nData);
660,581✔
2235
}
2236
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
4,955,078✔
2237
  int32_t code = 0;
4,955,078✔
2238

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

2244
  return tColDataPutValue(pColData, NULL, 0);
4,955,078✔
2245
}
2246
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
562,646✔
2247
  int32_t code = 0;
562,646✔
2248

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

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

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

2276
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
14✔
2277
  pColData->numOfNone--;
14✔
2278
  pColData->nVal--;
14✔
2279
  if (pColData->numOfNone) {
14!
2280
    return tColDataAppendValue10(pColData, pData, nData);
×
2281
  } else {
2282
    pColData->flag = 0;
14✔
2283
    return tColDataAppendValue00(pColData, pData, nData);
14✔
2284
  }
2285
}
2286
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
2287
  pColData->numOfNone--;
24✔
2288
  pColData->nVal--;
24✔
2289
  if (pColData->numOfNone) {
24!
2290
    return tColDataAppendValue12(pColData, pData, nData);
×
2291
  } else {
2292
    pColData->flag = 0;
24✔
2293
    return tColDataAppendValue02(pColData, pData, nData);
24✔
2294
  }
2295
  return 0;
2296
}
2297
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
149✔
2298
  if (forward) {
149!
2299
    pColData->numOfNull--;
149✔
2300
    pColData->nVal--;
149✔
2301
    if (pColData->numOfNull) {
149!
2302
      return tColDataAppendValue20(pColData, pData, nData);
×
2303
    } else {
2304
      pColData->flag = 0;
149✔
2305
      return tColDataAppendValue00(pColData, pData, nData);
149✔
2306
    }
2307
  }
2308
  return 0;
×
2309
}
2310
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2311
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2312
    pColData->numOfNone--;
×
2313
    pColData->nVal--;
×
2314
    if (pColData->numOfNone) {
×
2315
      return tColDataAppendValue30(pColData, pData, nData);
×
2316
    } else {
2317
      pColData->flag = HAS_NULL;
×
2318
      return tColDataAppendValue20(pColData, pData, nData);
×
2319
    }
2320
  } else if (forward) {  // NULL ==> VALUE
×
2321
    pColData->numOfNull--;
×
2322
    pColData->nVal--;
×
2323
    if (pColData->numOfNull) {
×
2324
      return tColDataAppendValue30(pColData, pData, nData);
×
2325
    } else {
2326
      pColData->flag = HAS_NONE;
×
2327
      return tColDataAppendValue10(pColData, pData, nData);
×
2328
    }
2329
  }
2330
  return 0;
×
2331
}
2332
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
2333
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
2334
    pColData->numOfNone--;
80✔
2335
    pColData->numOfNull++;
80✔
2336
    if (pColData->numOfNone) {
80!
2337
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2338
    } else {
2339
      pColData->flag = HAS_NULL;
80✔
2340
    }
2341
  }
2342
  return 0;
80✔
2343
}
2344
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
45,176,855✔
2345
  if (forward) {  // VALUE ==> VALUE
45,176,855!
2346
    pColData->nVal--;
45,182,223✔
2347
    if (IS_VAR_DATA_TYPE(pColData->type)) {
45,182,223!
2348
      pColData->nData = pColData->aOffset[pColData->nVal];
996,115✔
2349
    } else {
2350
      pColData->nData -= TYPE_BYTES[pColData->type];
44,186,108✔
2351
    }
2352
    return tColDataPutValue(pColData, pData, nData);
45,204,466✔
2353
  }
2354
  return 0;
×
2355
}
2356
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
5,036✔
2357
  if (forward) {  // VALUE ==> NULL
5,036!
2358
    pColData->numOfValue--;
5,036✔
2359
    pColData->nVal--;
5,036✔
2360
    if (pColData->numOfValue) {
5,036✔
2361
      if (IS_VAR_DATA_TYPE(pColData->type)) {
5,000!
2362
        pColData->nData = pColData->aOffset[pColData->nVal];
999✔
2363
      } else {
2364
        pColData->nData -= TYPE_BYTES[pColData->type];
4,001✔
2365
      }
2366
      return tColDataAppendValue42(pColData, pData, nData);
5,001✔
2367
    } else {
2368
      pColData->flag = 0;
36✔
2369
      pColData->nData = 0;
36✔
2370
      return tColDataAppendValue02(pColData, pData, nData);
36✔
2371
    }
2372
  }
2373
  return 0;
×
2374
}
2375
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
44,599✔
2376
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
44,599✔
2377
    pColData->numOfNone--;
5,597✔
2378
    pColData->nVal--;
5,597✔
2379
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
5,597!
2380
      pColData->nData -= TYPE_BYTES[pColData->type];
4,477✔
2381
    }
2382
    if (pColData->numOfNone) {
5,597✔
2383
      return tColDataAppendValue50(pColData, pData, nData);
2,000✔
2384
    } else {
2385
      pColData->flag = HAS_VALUE;
3,597✔
2386
      return tColDataAppendValue40(pColData, pData, nData);
3,597✔
2387
    }
2388
  } else if (forward) {  // VALUE ==> VALUE
39,002!
2389
    pColData->nVal--;
39,002✔
2390
    if (IS_VAR_DATA_TYPE(pColData->type)) {
39,002!
2391
      pColData->nData = pColData->aOffset[pColData->nVal];
5,557✔
2392
    } else {
2393
      pColData->nData -= TYPE_BYTES[pColData->type];
33,445✔
2394
    }
2395
    return tColDataPutValue(pColData, pData, nData);
39,054✔
2396
  }
2397
  return 0;
×
2398
}
2399
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
304✔
2400
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
304!
2401
    pColData->numOfNone--;
304✔
2402
    pColData->nVal--;
304✔
2403
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
304!
2404
      pColData->nData -= TYPE_BYTES[pColData->type];
244✔
2405
    }
2406
    if (pColData->numOfNone) {
304!
2407
      return tColDataAppendValue52(pColData, pData, nData);
×
2408
    } else {
2409
      pColData->flag = HAS_VALUE;
304!
2410
      return tColDataAppendValue42(pColData, pData, nData);
304✔
2411
    }
2412
  } else if (forward) {  // VALUE ==> NULL
×
2413
    pColData->numOfValue--;
×
2414
    pColData->nVal--;
×
2415
    if (pColData->numOfValue) {
×
2416
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2417
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2418
      } else {
2419
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2420
      }
2421
      return tColDataAppendValue52(pColData, pData, nData);
×
2422
    } else {
2423
      pColData->flag = HAS_NONE;
×
2424
      pColData->nData = 0;
×
2425
      return tColDataAppendValue12(pColData, pData, nData);
×
2426
    }
2427
  }
2428
  return 0;
×
2429
}
2430
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
32,255✔
2431
  if (forward) {
32,255!
2432
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
32,255✔
2433
      pColData->numOfNull--;
22,583✔
2434
      pColData->nVal--;
22,583✔
2435
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
22,583!
2436
        pColData->nData -= TYPE_BYTES[pColData->type];
17,904✔
2437
      }
2438
      if (pColData->numOfNull) {
22,583✔
2439
        return tColDataAppendValue60(pColData, pData, nData);
2,560✔
2440
      } else {
2441
        pColData->flag = HAS_VALUE;
20,023✔
2442
        return tColDataAppendValue40(pColData, pData, nData);
20,023✔
2443
      }
2444
    } else {  // VALUE ==> VALUE
2445
      pColData->nVal--;
9,672✔
2446
      if (IS_VAR_DATA_TYPE(pColData->type)) {
9,672!
2447
        pColData->nData = pColData->aOffset[pColData->nVal];
2,356✔
2448
      } else {
2449
        pColData->nData -= TYPE_BYTES[pColData->type];
7,316✔
2450
      }
2451
      return tColDataPutValue(pColData, pData, nData);
9,672✔
2452
    }
2453
  }
2454
  return 0;
×
2455
}
2456
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24,381✔
2457
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
24,381!
2458
    pColData->numOfValue--;
10,000✔
2459
    pColData->nVal--;
10,000✔
2460
    if (pColData->numOfValue) {
10,000!
2461
      if (IS_VAR_DATA_TYPE(pColData->type)) {
10,000!
2462
        pColData->nData = pColData->aOffset[pColData->nVal];
2,201✔
2463
      } else {
2464
        pColData->nData -= TYPE_BYTES[pColData->type];
7,799✔
2465
      }
2466
      return tColDataAppendValue62(pColData, pData, nData);
10,002✔
2467
    } else {
2468
      pColData->flag = HAS_NULL;
×
2469
      pColData->nData = 0;
×
2470
      return tColDataAppendValue20(pColData, pData, nData);
×
2471
    }
2472
  }
2473
  return 0;
14,381✔
2474
}
2475
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
402✔
2476
  int32_t code = 0;
402✔
2477

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

2577
    //    VALUE             NONE        NULL
2578
};
2579
int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward) {
31,580,224✔
2580
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
31,580,224!
2581
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
31,583,952!
2582

2583
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
31,583,952!
2584

2585
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
31,583,952✔
2586
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData, forward);
31,583,952!
2587
}
2588

2589
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
88,996,720✔
2590
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
88,996,720✔
2591
}
88,996,720✔
2592
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
3,422,236✔
2593
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
3,422,236✔
2594
}
3,422,236✔
2595
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
15,871✔
2596
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2597
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
15,871!
2598
    case 0:
1,445✔
2599
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
1,445✔
2600
      break;
1,445✔
2601
    case 1:
14,428✔
2602
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
14,428✔
2603
      break;
14,428✔
2604
    default:
×
2605
      break;
×
2606
  }
2607
}
15,871✔
2608
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
2609
  SValue value = {.type = pColData->type};
2,147,483,647✔
2610
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2611
    if (iVal + 1 < pColData->nVal) {
257,038,944!
2612
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
264,734,197✔
2613
    } else {
2614
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2615
    }
2616
    value.pData = pColData->pData + pColData->aOffset[iVal];
257,038,944✔
2617
  } else {
2618
    valueSetDatum(&value, pColData->type, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
2619
                  tDataTypes[pColData->type].bytes);
2,147,483,647✔
2620
  }
2621
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
2622
}
129,661,014✔
2623
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
7,779,307✔
2624
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2625
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
7,779,307!
2626
    case 0:
3,930,683✔
2627
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
3,930,683✔
2628
      break;
3,930,683✔
2629
    case 1:
3,972,475✔
2630
      tColDataGetValue4(pColData, iVal, pColVal);
2631
      break;
4,012,906✔
2632
    default:
×
2633
      break;
×
2634
  }
2635
}
7,819,738✔
2636
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
148,938,527✔
2637
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2638
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
148,938,527!
2639
    case 0:
24,499,739✔
2640
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
24,499,739✔
2641
      break;
24,499,739✔
2642
    case 1:
124,594,536✔
2643
      tColDataGetValue4(pColData, iVal, pColVal);
2644
      break;
125,628,930✔
2645
    default:
×
2646
      break;
×
2647
  }
2648
}
149,972,921✔
2649
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
22✔
2650
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
2651
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
22!
2652
    case 0:
10✔
2653
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
10✔
2654
      break;
10✔
2655
    case 1:
10✔
2656
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10✔
2657
      break;
10✔
2658
    case 2:
2!
2659
      tColDataGetValue4(pColData, iVal, pColVal);
2660
      break;
2✔
2661
    default:
×
2662
      break;
×
2663
  }
2664
}
22✔
2665
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2666
    NULL,               // 0
2667
    tColDataGetValue1,  // HAS_NONE
2668
    tColDataGetValue2,  // HAS_NULL
2669
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2670
    tColDataGetValue4,  // HAS_VALUE
2671
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2672
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2673
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2674
};
2675
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
2676
  if (iVal < 0 || iVal >= pColData->nVal ||
2,147,483,647!
2677
      (pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
2,147,483,647!
2678
    return TSDB_CODE_INVALID_PARA;
×
2679
  }
2680
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
2681
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
2682
}
2683

2684
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
607,026,575✔
2685
  switch (pColData->flag) {
607,026,575!
2686
    case HAS_NONE:
×
2687
      return 0;
×
2688
    case HAS_NULL:
×
2689
      return 1;
×
2690
    case (HAS_NULL | HAS_NONE):
15,884✔
2691
      return GET_BIT1(pColData->pBitMap, iVal);
15,884✔
2692
    case HAS_VALUE:
×
2693
      return 2;
×
2694
    case (HAS_VALUE | HAS_NONE):
22,951,338✔
2695
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
22,951,338✔
2696
    case (HAS_VALUE | HAS_NULL):
571,554,090✔
2697
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
571,554,090✔
2698
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
12,466,544✔
2699
      return GET_BIT2(pColData->pBitMap, iVal);
12,466,544✔
2700
    default:
38,719✔
2701
      return 0;
38,719✔
2702
  }
2703
}
2704

2705
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg) {
20,498✔
2706
  int32_t code = 0;
20,498✔
2707

2708
  *pColData = *pColDataFrom;
20,498✔
2709

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

2735
  // offset
2736
  if (IS_VAR_DATA_TYPE(pColData->type) && (pColData->flag & HAS_VALUE)) {
20,498!
2737
    pColData->aOffset = xMalloc(arg, pColData->nVal << 2);
108✔
2738
    if (pColData->aOffset == NULL) {
108!
2739
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2740
      goto _exit;
×
2741
    }
2742
    (void)memcpy(pColData->aOffset, pColDataFrom->aOffset, pColData->nVal << 2);
108✔
2743
  } else {
2744
    pColData->aOffset = NULL;
20,390✔
2745
  }
2746

2747
  // value
2748
  if (pColData->nData) {
20,498✔
2749
    pColData->pData = xMalloc(arg, pColData->nData);
20,407✔
2750
    if (pColData->pData == NULL) {
20,406!
2751
      code = TSDB_CODE_OUT_OF_MEMORY;
×
2752
      goto _exit;
×
2753
    }
2754

2755
    (void)memcpy(pColData->pData, pColDataFrom->pData, pColData->nData);
20,406✔
2756
  } else {
2757
    pColData->pData = NULL;
91✔
2758
  }
2759

2760
_exit:
20,497✔
2761
  return code;
20,497✔
2762
}
2763

2764
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
2,939,541✔
2765
  int32_t code;
2766
  SBuffer local;
2767

2768
  if (!(colData->nVal > 0)) {
2,939,541!
2769
    return TSDB_CODE_INVALID_PARA;
×
2770
  }
2771

2772
  (*info) = (SColDataCompressInfo){
2,939,541✔
2773
      .cmprAlg = info->cmprAlg,
2,939,541✔
2774
      .columnFlag = colData->cflag,
2,939,541✔
2775
      .flag = colData->flag,
2,939,541✔
2776
      .dataType = colData->type,
2,939,541✔
2777
      .columnId = colData->cid,
2,939,541✔
2778
      .numOfData = colData->nVal,
2,939,541✔
2779
  };
2780

2781
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
2,939,541!
2782
    return 0;
142,133✔
2783
  }
2784

2785
  tBufferInit(&local);
2786
  if (assist == NULL) {
2,797,408!
2787
    assist = &local;
×
2788
  }
2789

2790
  // bitmap
2791
  if (colData->flag != HAS_VALUE) {
2,797,408✔
2792
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
395,398✔
2793
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
37,402✔
2794
    } else {
2795
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
357,996✔
2796
    }
2797

2798
    SCompressInfo cinfo = {
395,398✔
2799
        .dataType = TSDB_DATA_TYPE_TINYINT,
2800
        .cmprAlg = info->cmprAlg,
395,398✔
2801
        .originalSize = info->bitmapOriginalSize,
395,398✔
2802
    };
2803

2804
    code = tCompressDataToBuffer(colData->pBitMap, &cinfo, output, assist);
395,398✔
2805
    if (code) {
395,510!
2806
      tBufferDestroy(&local);
2807
      return code;
×
2808
    }
2809

2810
    info->bitmapCompressedSize = cinfo.compressedSize;
395,510✔
2811
  }
2812

2813
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
2,797,520✔
2814
    tBufferDestroy(&local);
2815
    return 0;
10,599✔
2816
  }
2817

2818
  // offset
2819
  if (IS_VAR_DATA_TYPE(colData->type)) {
2,786,921!
2820
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
362,571✔
2821

2822
    SCompressInfo cinfo = {
362,571✔
2823
        .dataType = TSDB_DATA_TYPE_INT,
2824
        .cmprAlg = info->cmprAlg,
362,571✔
2825
        .originalSize = info->offsetOriginalSize,
362,571✔
2826
    };
2827

2828
    code = tCompressDataToBuffer(colData->aOffset, &cinfo, output, assist);
362,571✔
2829
    if (code) {
362,750!
2830
      tBufferDestroy(&local);
2831
      return code;
×
2832
    }
2833

2834
    info->offsetCompressedSize = cinfo.compressedSize;
362,750✔
2835
  }
2836

2837
  // data
2838
  if (colData->nData > 0) {
2,787,100!
2839
    info->dataOriginalSize = colData->nData;
2,787,131✔
2840

2841
    SCompressInfo cinfo = {
2,787,131✔
2842
        .dataType = colData->type,
2,787,131✔
2843
        .cmprAlg = info->cmprAlg,
2,787,131✔
2844
        .originalSize = info->dataOriginalSize,
2,787,131✔
2845
    };
2846

2847
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
2,787,131✔
2848
    if (code) {
2,787,617!
2849
      tBufferDestroy(&local);
2850
      return code;
×
2851
    }
2852

2853
    info->dataCompressedSize = cinfo.compressedSize;
2,787,617✔
2854
  }
2855

2856
  tBufferDestroy(&local);
2857
  return 0;
2,787,586✔
2858
}
2859

2860
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
19,448,155✔
2861
  int32_t  code;
2862
  SBuffer  local;
2863
  uint8_t *data = (uint8_t *)input;
19,448,155✔
2864

2865
  tBufferInit(&local);
2866
  if (assist == NULL) {
19,448,155!
2867
    assist = &local;
×
2868
  }
2869

2870
  tColDataClear(colData);
19,448,155✔
2871
  colData->cid = info->columnId;
19,447,224✔
2872
  colData->type = info->dataType;
19,447,224✔
2873
  colData->cflag = info->columnFlag;
19,447,224✔
2874
  colData->nVal = info->numOfData;
19,447,224✔
2875
  colData->flag = info->flag;
19,447,224✔
2876

2877
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
19,447,224✔
2878
    goto _exit;
3,049,457✔
2879
  }
2880

2881
  // bitmap
2882
  if (info->bitmapOriginalSize > 0) {
16,397,767✔
2883
    SCompressInfo cinfo = {
1,096,095✔
2884
        .dataType = TSDB_DATA_TYPE_TINYINT,
2885
        .cmprAlg = info->cmprAlg,
1,096,095✔
2886
        .originalSize = info->bitmapOriginalSize,
1,096,095✔
2887
        .compressedSize = info->bitmapCompressedSize,
1,096,095✔
2888
    };
2889

2890
    code = tRealloc(&colData->pBitMap, cinfo.originalSize);
1,096,095!
2891
    if (code) {
1,095,633!
2892
      tBufferDestroy(&local);
2893
      return code;
×
2894
    }
2895

2896
    code = tDecompressData(data, &cinfo, colData->pBitMap, cinfo.originalSize, assist);
1,095,633✔
2897
    if (code) {
1,095,813!
2898
      tBufferDestroy(&local);
2899
      return code;
×
2900
    }
2901

2902
    data += cinfo.compressedSize;
1,095,813✔
2903
  }
2904

2905
  if (info->flag == (HAS_NONE | HAS_NULL)) {
16,397,485✔
2906
    goto _exit;
688✔
2907
  }
2908

2909
  // offset
2910
  if (info->offsetOriginalSize > 0) {
16,396,797✔
2911
    SCompressInfo cinfo = {
3,323,701✔
2912
        .cmprAlg = info->cmprAlg,
3,323,701✔
2913
        .dataType = TSDB_DATA_TYPE_INT,
2914
        .originalSize = info->offsetOriginalSize,
3,323,701✔
2915
        .compressedSize = info->offsetCompressedSize,
3,323,701✔
2916
    };
2917

2918
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
3,323,701!
2919
    if (code) {
3,323,853!
2920
      tBufferDestroy(&local);
2921
      return code;
×
2922
    }
2923

2924
    code = tDecompressData(data, &cinfo, colData->aOffset, cinfo.originalSize, assist);
3,323,853✔
2925
    if (code) {
3,323,641!
2926
      tBufferDestroy(&local);
2927
      return code;
×
2928
    }
2929

2930
    data += cinfo.compressedSize;
3,323,641✔
2931
  }
2932

2933
  // data
2934
  if (info->dataOriginalSize > 0) {
16,396,737✔
2935
    colData->nData = info->dataOriginalSize;
16,395,534✔
2936

2937
    SCompressInfo cinfo = {
16,395,534✔
2938
        .cmprAlg = info->cmprAlg,
16,395,534✔
2939
        .dataType = colData->type,
16,395,534✔
2940
        .originalSize = info->dataOriginalSize,
16,395,534✔
2941
        .compressedSize = info->dataCompressedSize,
16,395,534✔
2942
    };
2943

2944
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
16,395,534!
2945
    if (code) {
16,396,092!
2946
      tBufferDestroy(&local);
2947
      return code;
×
2948
    }
2949

2950
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
16,396,092✔
2951
    if (code) {
16,396,044!
2952
      tBufferDestroy(&local);
2953
      return code;
×
2954
    }
2955

2956
    data += cinfo.compressedSize;
16,396,044✔
2957
  }
2958

2959
_exit:
1,203✔
2960
  switch (colData->flag) {
19,447,392✔
2961
    case HAS_NONE:
2,721,692✔
2962
      colData->numOfNone = colData->nVal;
2,721,692✔
2963
      break;
2,721,692✔
2964
    case HAS_NULL:
330,544✔
2965
      colData->numOfNull = colData->nVal;
330,544✔
2966
      break;
330,544✔
2967
    case HAS_VALUE:
15,300,412✔
2968
      colData->numOfValue = colData->nVal;
15,300,412✔
2969
      break;
15,300,412✔
2970
    default:
1,094,744✔
2971
      for (int32_t i = 0; i < colData->nVal; i++) {
323,993,771✔
2972
        uint8_t bitValue = tColDataGetBitValue(colData, i);
322,898,805✔
2973
        if (bitValue == 0) {
322,899,027✔
2974
          colData->numOfNone++;
4,172,308✔
2975
        } else if (bitValue == 1) {
318,726,719✔
2976
          colData->numOfNull++;
72,050,113✔
2977
        } else {
2978
          colData->numOfValue++;
246,676,606✔
2979
        }
2980
      }
2981
  }
2982
  tBufferDestroy(&local);
2983
  return 0;
19,447,614✔
2984
}
2985

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

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

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

3060
_exit:
10✔
3061
  return code;
543✔
3062
}
3063

3064
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
9,683,606✔
3065
                               checkWKBGeometryFn cgeos) {
3066
  int32_t code = 0;
9,683,606✔
3067

3068
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
9,683,606✔
3069
    if (!(pColData->type == pBind->buffer_type)) {
9,094,205!
3070
      return TSDB_CODE_INVALID_PARA;
×
3071
    }
3072
  }
3073

3074
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
9,683,606!
3075
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
905,666✔
3076
      code = igeos();
199✔
3077
      if (code) {
198!
3078
        return code;
×
3079
      }
3080
    }
3081
    for (int32_t i = 0; i < pBind->num; ++i) {
2,877,162✔
3082
      if (pBind->is_null && pBind->is_null[i]) {
1,930,773✔
3083
        if (pColData->cflag & COL_IS_KEY) {
100,404✔
3084
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
2✔
3085
          goto _exit;
2✔
3086
        }
3087
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
100,402✔
3088
        if (code) goto _exit;
100,511!
3089
      } else if (pBind->length[i] > buffMaxLen) {
1,830,369!
3090
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3091
      } else {
3092
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
1,830,369✔
3093
          code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]);
199✔
3094
          if (code) {
200!
3095
            uError("stmt col[%d] bind geometry wrong format", i);
×
3096
            goto _exit;
×
3097
          }
3098
        }
3099
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
1,830,370✔
3100
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
1,830,370✔
3101
      }
3102
    }
3103
  } else {  // fixed-length data type
3104
    bool allValue;
3105
    bool allNull;
3106
    if (pBind->is_null) {
8,777,940✔
3107
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
573,798✔
3108
      allNull = (same && pBind->is_null[0] != 0);
573,798✔
3109
      allValue = (same && pBind->is_null[0] == 0);
573,798!
3110
    } else {
3111
      allNull = false;
8,204,142✔
3112
      allValue = true;
8,204,142✔
3113
    }
3114

3115
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
8,777,940✔
3116
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
4✔
3117
      goto _exit;
4✔
3118
    }
3119

3120
    if (allValue) {
8,777,936✔
3121
      // optimize (todo)
3122
      for (int32_t i = 0; i < pBind->num; ++i) {
217,004,525✔
3123
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
207,553,030✔
3124
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
207,553,030✔
3125
      }
3126
    } else if (allNull) {
547,709✔
3127
      // optimize (todo)
3128
      for (int32_t i = 0; i < pBind->num; ++i) {
992,962✔
3129
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
493,761✔
3130
        if (code) goto _exit;
499,026!
3131
      }
3132
    } else {
3133
      for (int32_t i = 0; i < pBind->num; ++i) {
53,852✔
3134
        if (pBind->is_null[i]) {
79✔
3135
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
29✔
3136
          if (code) goto _exit;
29!
3137
        } else {
3138
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
50✔
3139
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
50✔
3140
        }
3141
      }
3142
    }
3143
  }
3144

3145
_exit:
53,773✔
3146
  return code;
10,950,864✔
3147
}
3148

3149
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
×
3150
                                checkWKBGeometryFn cgeos) {
3151
  int32_t code = 0;
×
3152

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

3159
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
×
3160
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
3161
      code = igeos();
×
3162
      if (code) {
×
3163
        return code;
×
3164
      }
3165
    }
3166

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

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

3215
    if (allValue) {
×
3216
      // optimize (todo)
3217
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3218
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
3219
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
3220
          *val = 1;
×
3221
        }
3222

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

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

3259
_exit:
×
3260
  return code;
×
3261
}
3262

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

3278
  if (!infoSorted) {
5,684!
3279
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo2), NULL, tBindInfoCompare);
×
3280
  }
3281

3282
  int32_t code = 0;
5,684✔
3283
  int32_t numOfRows = infos[0].bind->num;
5,684✔
3284
  SArray *colValArray, *bufArray;
3285
  SColVal colVal;
3286
  int32_t numOfFixedValue = 0;
5,684✔
3287

3288
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
5,684!
3289
    return terrno;
×
3290
  }
3291
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
5,680!
3292
    taosArrayDestroy(colValArray);
×
3293
    return terrno;
×
3294
  }
3295
  for (int i = 0; i < numOfInfos; ++i) {
34,952✔
3296
    if (parsedCols) {
29,266!
3297
      SColVal *pParsedVal = tSimpleHashGet(parsedCols, &infos[i].columnId, sizeof(int16_t));
×
3298
      if (pParsedVal) {
×
3299
        continue;
×
3300
      }
3301
    }
3302
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
58,530!
3303
      taosArrayDestroy(colValArray);
×
3304
      taosArrayDestroy(bufArray);
×
3305
      return terrno;
×
3306
    }
3307
  }
3308

3309
  SRowKey rowKey, lastRowKey;
3310
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
242,047!
3311
    taosArrayClear(colValArray);
246,361✔
3312

3313
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
1,201,872✔
3314
      if (parsedCols) {
938,964!
3315
        SColVal *pParsedVal = tSimpleHashGet(parsedCols, &infos[iInfo].columnId, sizeof(int16_t));
×
3316
        if (pParsedVal) {
×
3317
          numOfFixedValue++;
×
3318
          colVal = *pParsedVal;
×
3319

3320
          if (taosArrayPush(colValArray, &colVal) == NULL) {
×
3321
            if (IS_VAR_DATA_TYPE(pParsedVal->value.type)) {
×
3322
              taosMemoryFree(colVal.value.pData);
×
3323
            }
3324
            code = terrno;
×
3325
            goto _exit;
×
3326
          }
3327
          continue;
×
3328
        }
3329
      }
3330

3331
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
940,297!
3332
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
3333
          if (iInfo == 0) {
×
3334
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3335
            goto _exit;
×
3336
          }
3337
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
3338
        } else {
3339
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3340
        }
3341
      } else {
3342
        SValue value = {
940,297✔
3343
            .type = infos[iInfo].type,
940,297✔
3344
        };
3345
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
940,297!
3346
          int32_t   length = infos[iInfo].bind->length[iRow];
6,565✔
3347
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo - numOfFixedValue];
6,565✔
3348
          value.nData = length;
6,565✔
3349
          if (value.nData > infos[iInfo].bytes - VARSTR_HEADER_SIZE) {
6,565!
3350
            code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
3351
            uError("stmt bind columnId:%d length:%d  greater than type maximum lenght: %d", infos[iInfo].columnId,
×
3352
                   value.nData + (uint32_t)VARSTR_HEADER_SIZE, infos[iInfo].bytes);
3353
            goto _exit;
×
3354
          }
3355
          value.pData = *data;
6,565✔
3356
          *data += length;
6,565✔
3357
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3358
        } else {
3359
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
933,732✔
3360
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
933,732!
3361
            *val = 1;
×
3362
          }
3363
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
933,732✔
3364
        }
3365
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
974,689✔
3366
      }
3367
      if (taosArrayPush(colValArray, &colVal) == NULL) {
955,849!
3368
        code = terrno;
×
3369
        goto _exit;
×
3370
      }
3371
    }
3372

3373
    SRow *row;
3374
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
262,908!
3375
      goto _exit;
×
3376
    }
3377

3378
    if ((taosArrayPush(rowArray, &row)) == NULL) {
236,368!
3379
      code = terrno;
×
3380
      goto _exit;
×
3381
    }
3382

3383
    if (pOrdered && pDupTs) {
236,368!
3384
      tRowGetKey(row, &rowKey);
473,450!
3385
      if (iRow == 0) {
236,718✔
3386
        *pOrdered = true;
5,675✔
3387
        *pDupTs = false;
5,675✔
3388
      } else {
3389
        if (*pOrdered) {
231,043!
3390
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
231,082✔
3391
          *pOrdered = (res >= 0);
231,082✔
3392
          if (!*pDupTs) {
231,082✔
3393
            *pDupTs = (res == 0);
230,470✔
3394
          }
3395
        }
3396
      }
3397
      lastRowKey = rowKey;
236,718✔
3398
    }
3399
  }
3400
_exit:
×
3401
  taosArrayDestroy(colValArray);
×
3402
  taosArrayDestroy(bufArray);
5,673✔
3403
  return code;
5,697✔
3404
}
3405

3406
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
346✔
3407
  int32_t code = TSDB_CODE_SUCCESS;
346✔
3408

3409
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
346!
3410
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
146✔
3411
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
51✔
3412
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
73✔
3413
    if (iToRow == 0) {
73✔
3414
      pToColData->aOffset[iToRow] = 0;
14✔
3415
    }
3416

3417
    if (iToRow < pToColData->nVal - 1) {
73✔
3418
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
64✔
3419
    }
3420

3421
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
73✔
3422
                 nData);
3423
  } else {
3424
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
273✔
3425
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
273✔
3426
  }
3427
  return code;
346✔
3428
}
3429

3430
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
354✔
3431
                                        int32_t iToRow) {
3432
  int32_t code = TSDB_CODE_SUCCESS;
354✔
3433
  int     bit_val = 0;
354✔
3434

3435
  switch (pFromColData->flag) {
354!
3436
    case HAS_NONE: {
×
3437
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
3438
    } break;
×
3439
    case HAS_NULL: {
8✔
3440
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
8!
3441
    } break;
8✔
3442
    case (HAS_NULL | HAS_NONE): {
×
3443
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
3444
      if (0 == bit_val)
×
3445
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
3446
      else
3447
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
×
3448
    } break;
×
3449
    case HAS_VALUE: {
298✔
3450
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
298!
3451
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
298!
3452
    } break;
298✔
3453
    case (HAS_VALUE | HAS_NONE): {
×
3454
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
3455
      if (0 == bit_val)
×
3456
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
3457
      else
3458
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
×
3459
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3460
    } break;
×
3461
    case (HAS_VALUE | HAS_NULL): {
48✔
3462
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
48✔
3463
      if (0 == bit_val)
48✔
3464
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
29!
3465
      else
3466
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
19!
3467
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
48!
3468
    } break;
48✔
3469
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
3470
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
3471
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3472
    } break;
×
3473
    default:
×
3474
      return -1;
×
3475
  }
3476

3477
  return code;
354✔
3478
}
3479

3480
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
75✔
3481
                               int32_t nColData) {
3482
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3483

3484
  for (int32_t i = 0; i < nColData; i++) {
429✔
3485
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
354✔
3486
    if (code != TSDB_CODE_SUCCESS) {
354!
3487
      return code;
×
3488
    }
3489
  }
3490

3491
  return code;
75✔
3492
}
3493

3494
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
75✔
3495
  int32_t code = TSDB_CODE_SUCCESS;
75✔
3496

3497
  for (int32_t i = 0; i < nColData; i++) {
429✔
3498
    SColVal cv = {0};
354✔
3499
    code = tColDataGetValue(&aFromColData[i], iFromRow, &cv);
354✔
3500
    if (code != TSDB_CODE_SUCCESS) {
354!
3501
      return code;
×
3502
    }
3503
    code = tColDataAppendValue(&aToColData[i], &cv);
354✔
3504
    if (code != TSDB_CODE_SUCCESS) {
354!
3505
      return code;
×
3506
    }
3507
  }
3508

3509
  return code;
75✔
3510
}
3511

3512
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
215,302,440✔
3513
  SColVal cv;
3514

3515
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
215,302,440✔
3516
  key->numOfPKs = 0;
215,302,440✔
3517

3518
  for (int i = 1; i < nColData; i++) {
215,321,616!
3519
    if (aColData[i].cflag & COL_IS_KEY) {
216,124,605✔
3520
      tColDataGetValue4(&aColData[i], iRow, &cv);
19,022!
3521
      key->pks[key->numOfPKs++] = cv.value;
19,176✔
3522
    } else {
3523
      break;
216,105,583✔
3524
    }
3525
  }
3526
}
215,302,594✔
3527

3528
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
23✔
3529
  SColData *aDstColData = NULL;
23✔
3530
  int32_t   i = start, j = mid + 1, k = 0;
23✔
3531
  SRowKey   keyi, keyj;
3532

3533
  if (end > start) {
23!
3534
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
23!
3535
    if (aDstColData == NULL) {
23!
3536
      return terrno;
×
3537
    }
3538
    for (int c = 0; c < nColData; ++c) {
129✔
3539
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
106✔
3540
    }
3541
  }
3542

3543
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
23✔
3544
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
23✔
3545
  while (i <= mid && j <= end) {
63✔
3546
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
40✔
3547
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
30!
3548
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
30✔
3549
    } else {
3550
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
10!
3551
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
10✔
3552
    }
3553
  }
3554

3555
  while (i <= mid) {
35✔
3556
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
12!
3557
  }
3558

3559
  while (j <= end) {
46✔
3560
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
23!
3561
  }
3562

3563
  for (i = start, k = 0; i <= end; ++i, ++k) {
98✔
3564
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
75!
3565
  }
3566

3567
  if (aDstColData) {
23!
3568
    for (int32_t i = 0; i < nColData; i++) {
129✔
3569
      tColDataDestroy(&aDstColData[i]);
106✔
3570
    }
3571
    taosMemoryFree(aDstColData);
23!
3572
  }
3573

3574
  return TSDB_CODE_SUCCESS;
23✔
3575
}
3576

3577
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
52✔
3578
  int32_t ret = TSDB_CODE_SUCCESS;
52✔
3579
  int32_t mid;
3580

3581
  if (start >= end) {
52✔
3582
    return TSDB_CODE_SUCCESS;
29✔
3583
  }
3584

3585
  mid = (start + end) / 2;
23✔
3586

3587
  ret = tColDataMergeSort(aColData, start, mid, nColData);
23✔
3588
  if (ret != TSDB_CODE_SUCCESS) {
23!
3589
    return ret;
×
3590
  }
3591

3592
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
23✔
3593
  if (ret != TSDB_CODE_SUCCESS) {
23!
3594
    return ret;
×
3595
  }
3596

3597
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
23✔
3598
}
3599

3600
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
6✔
3601
  int32_t nVal = aColData[0].nVal;
6✔
3602

3603
  if (nVal < 2) return TSDB_CODE_SUCCESS;
6!
3604

3605
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
6✔
3606
}
3607

3608
static int32_t tColDataMerge(SArray **colArr) {
3✔
3609
  int32_t code = 0;
3✔
3610
  SArray *src = *colArr;
3✔
3611
  SArray *dst = NULL;
3✔
3612

3613
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
3✔
3614
  if (dst == NULL) {
3!
3615
    return terrno;
×
3616
  }
3617

3618
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
12✔
3619
    SColData *srcCol = taosArrayGet(src, i);
9✔
3620

3621
    SColData *dstCol = taosArrayReserve(dst, 1);
9✔
3622
    if (dstCol == NULL) {
9!
3623
      code = terrno;
×
3624
      goto _exit;
×
3625
    }
3626
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
9✔
3627
  }
3628

3629
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
3✔
3630
  SRowKey lastKey;
3631
  for (int32_t i = 0; i < numRows; i++) {
9✔
3632
    SRowKey key;
3633
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
3634

3635
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
9!
3636
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3637
        SColData *srcCol = taosArrayGet(src, j);
9✔
3638
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3639

3640
        SColVal cv;
3641
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3642
        if (code != TSDB_CODE_SUCCESS) {
9!
3643
          goto _exit;
×
3644
        }
3645
        code = tColDataAppendValue(dstCol, &cv);
9✔
3646
        if (code) {
9!
3647
          goto _exit;
×
3648
        }
3649
      }
3650
      lastKey = key;
3✔
3651
    } else {  // update existing row
3652
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
3653
        SColData *srcCol = taosArrayGet(src, j);
9✔
3654
        SColData *dstCol = taosArrayGet(dst, j);
9✔
3655

3656
        SColVal cv;
3657
        code = tColDataGetValue(srcCol, i, &cv);
9✔
3658
        if (code != TSDB_CODE_SUCCESS) {
9!
3659
          goto _exit;
×
3660
        }
3661
        code = tColDataUpdateValue(dstCol, &cv, true);
9✔
3662
        if (code) {
9!
3663
          goto _exit;
×
3664
        }
3665
      }
3666
    }
3667
  }
3668

3669
_exit:
3✔
3670
  if (code) {
3!
3671
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3672
  } else {
3673
    taosArrayDestroyEx(src, tColDataDestroy);
3✔
3674
    *colArr = dst;
3✔
3675
  }
3676
  return code;
3✔
3677
}
3678

3679
int32_t tColDataSortMerge(SArray **arr) {
40,759✔
3680
  SArray   *colDataArr = *arr;
40,759✔
3681
  int32_t   nColData = TARRAY_SIZE(colDataArr);
40,759✔
3682
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
40,759✔
3683

3684
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
40,759!
3685
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3686
  }
3687
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
40,759!
3688
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3689
  }
3690
  if (!(aColData[0].flag == HAS_VALUE)) {
40,759!
3691
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3692
  }
3693

3694
  if (aColData[0].nVal <= 1) goto _exit;
40,759✔
3695

3696
  int8_t doSort = 0;
40,568✔
3697
  int8_t doMerge = 0;
40,568✔
3698
  // scan -------
3699
  SRowKey lastKey;
3700
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
40,568✔
3701
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
105,792,301!
3702
    SRowKey key;
3703
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
106,744,781✔
3704

3705
    int32_t c = tRowKeyCompare(&lastKey, &key);
105,751,745✔
3706
    if (c < 0) {
105,751,745✔
3707
      lastKey = key;
105,716,878✔
3708
      continue;
105,716,878✔
3709
    } else if (c > 0) {
34,867✔
3710
      doSort = 1;
6✔
3711
      break;
6✔
3712
    } else {
3713
      doMerge = 1;
34,861✔
3714
    }
3715
  }
3716

3717
  // sort -------
3718
  if (doSort) {
×
3719
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
6!
3720
  }
3721

3722
  if (doMerge != 1) {
1,740,564✔
3723
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
40,594✔
3724
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
105,945,041!
3725
      SRowKey key;
3726
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
107,604,409✔
3727

3728
      int32_t c = tRowKeyCompare(&lastKey, &key);
105,904,446✔
3729
      if (c == 0) {
105,904,446!
3730
        doMerge = 1;
×
3731
        break;
×
3732
      }
3733
      lastKey = key;
105,904,446✔
3734
    }
3735
  }
3736

3737
  // merge -------
3738
  if (doMerge) {
40,602✔
3739
    int32_t code = tColDataMerge(arr);
3✔
3740
    if (code) return code;
3!
3741
  }
3742

3743
_exit:
40,602✔
3744
  return 0;
40,793✔
3745
}
3746

3747
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
250,983✔
3748
  int32_t code = 0;
250,983✔
3749

3750
  if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
501,966!
3751
  if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
501,966!
3752
  if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
501,966!
3753
  if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
501,966!
3754

3755
  // bitmap
3756
  switch (pColData->flag) {
250,983!
3757
    case (HAS_NULL | HAS_NONE):
2,102✔
3758
    case (HAS_VALUE | HAS_NONE):
3759
    case (HAS_VALUE | HAS_NULL):
3760
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
2,102✔
3761
      if (code) return code;
2,102!
3762
      break;
2,102✔
3763
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3764
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
3765
      if (code) return code;
×
3766
      break;
×
3767
    default:
248,881✔
3768
      break;
248,881✔
3769
  }
3770

3771
  // value
3772
  if (pColData->flag & HAS_VALUE) {
250,983✔
3773
    if (IS_VAR_DATA_TYPE(pColData->type)) {
250,625!
3774
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
1,463✔
3775
      if (code) return code;
1,463!
3776

3777
      code = tEncodeI32v(pEncoder, pColData->nData);
1,463✔
3778
      if (code) return code;
1,463!
3779

3780
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
1,463✔
3781
      if (code) return code;
1,463!
3782
    } else {
3783
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
249,162✔
3784
      if (code) return code;
249,162!
3785
    }
3786
  }
3787

3788
  return code;
250,983✔
3789
}
3790

3791
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
62,522✔
3792
  int32_t code = 0;
62,522✔
3793

3794
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
125,042!
3795
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
125,028!
3796
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
125,008!
3797
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
125,000!
3798

3799
  if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
62,500!
3800
    return TSDB_CODE_INVALID_PARA;
×
3801
  }
3802

3803
  // bitmap
3804
  switch (pColData->flag) {
62,503!
3805
    case (HAS_NULL | HAS_NONE):
112✔
3806
    case (HAS_VALUE | HAS_NONE):
3807
    case (HAS_VALUE | HAS_NULL):
3808
      code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
112!
3809
      if (code) return code;
112!
3810
      break;
112✔
3811
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3812
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
3813
      if (code) return code;
×
3814
      break;
×
3815
    default:
62,391✔
3816
      break;
62,391✔
3817
  }
3818

3819
  // value
3820
  if (pColData->flag & HAS_VALUE) {
62,503✔
3821
    if (IS_VAR_DATA_TYPE(pColData->type)) {
62,309!
3822
      code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
376!
3823
      if (code) return code;
376!
3824

3825
      code = tDecodeI32v(pDecoder, &pColData->nData);
376✔
3826
      if (code) return code;
376!
3827

3828
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
376!
3829
      if (code) return code;
376!
3830
    } else {
3831
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
61,933✔
3832
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
61,933!
3833
      if (code) return code;
61,933!
3834
    }
3835
  }
3836
  pColData->cflag = 0;
62,503✔
3837

3838
  return code;
62,503✔
3839
}
3840

3841
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
250,997✔
3842
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
250,997✔
3843
  if (code) return code;
251,004!
3844
  return tEncodeI8(pEncoder, pColData->cflag);
502,008✔
3845
}
3846

3847
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
62,522✔
3848
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
62,522✔
3849
  if (code) return code;
62,502!
3850

3851
  code = tDecodeI8(pDecoder, &pColData->cflag);
62,502✔
3852
  return code;
62,502✔
3853
}
3854

3855
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
250,932✔
3856
  if (version == 0) {
250,932!
3857
    return tEncodeColDataVersion0(pEncoder, pColData);
×
3858
  } else if (version == 1) {
250,932!
3859
    return tEncodeColDataVersion1(pEncoder, pColData);
251,017✔
3860
  } else {
3861
    return TSDB_CODE_INVALID_PARA;
×
3862
  }
3863
}
3864

3865
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
62,523✔
3866
  if (version == 0) {
62,523!
3867
    return tDecodeColDataVersion0(pDecoder, pColData);
×
3868
  } else if (version == 1) {
62,523!
3869
    return tDecodeColDataVersion1(pDecoder, pColData);
62,524✔
3870
  } else {
3871
    return TSDB_CODE_INVALID_PARA;
×
3872
  }
3873
}
3874

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

3877
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
795,111,641✔
3878
  if (ppRow == NULL) {
795,111,641!
3879
    return TSDB_CODE_INVALID_PARA;
×
3880
  }
3881

3882
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
795,111,641!
3883
    return TSDB_CODE_OUT_OF_RANGE;
×
3884
  }
3885

3886
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
795,111,641✔
3887
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
1,590,223,282!
3888
}
3889

3890
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3891
  do {                                       \
3892
    (SUM) += (VAL);                          \
3893
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3894
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3895
  } while (0)
3896

3897
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, SColumnDataAgg *pAggs) {
18,462✔
3898
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,462✔
3899
  int16_t *numOfNull = &pAggs->numOfNull;
18,462✔
3900
  *sum = 0;
18,462✔
3901
  *max = 0;
18,462✔
3902
  *min = 1;
18,462✔
3903
  *numOfNull = 0;
18,462✔
3904

3905
  int8_t val;
3906
  if (HAS_VALUE == pColData->flag) {
18,462✔
3907
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,387,370✔
3908
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
4,376,408✔
3909
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,376,408✔
3910
    }
3911
  } else {
3912
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,507,500✔
3913
      switch (tColDataGetBitValue(pColData, iVal)) {
2,500,000!
3914
        case 0:
1,500,000✔
3915
        case 1:
3916
          (*numOfNull)++;
1,500,000✔
3917
          break;
1,500,000✔
3918
        case 2:
1,000,000✔
3919
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
1,000,000✔
3920
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
1,000,000✔
3921
          break;
1,000,000✔
3922
        default:
×
3923
          break;
×
3924
      }
3925
    }
3926
  }
3927
}
18,462✔
3928

3929
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, SColumnDataAgg *pAggs) {
18,603✔
3930
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,603✔
3931
  int16_t *numOfNull = &pAggs->numOfNull;
18,603✔
3932
  *sum = 0;
18,603✔
3933
  *max = INT8_MIN;
18,603✔
3934
  *min = INT8_MAX;
18,603✔
3935
  *numOfNull = 0;
18,603✔
3936

3937
  int8_t val;
3938
  if (HAS_VALUE == pColData->flag) {
18,603✔
3939
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,636,434✔
3940
      val = ((int8_t *)pColData->pData)[iVal];
4,625,346✔
3941
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,625,346✔
3942
    }
3943
  } else {
3944
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,522,515✔
3945
      switch (tColDataGetBitValue(pColData, iVal)) {
2,515,000!
3946
        case 0:
1,852,040✔
3947
        case 1:
3948
          (*numOfNull)++;
1,852,040✔
3949
          break;
1,852,040✔
3950
        case 2:
662,960✔
3951
          val = ((int8_t *)pColData->pData)[iVal];
662,960✔
3952
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
662,960✔
3953
          break;
662,960✔
3954
        default:
×
3955
          break;
×
3956
      }
3957
    }
3958
  }
3959
}
18,603✔
3960

3961
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, SColumnDataAgg *pAggs) {
18,495✔
3962
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
18,495✔
3963
  int16_t *numOfNull = &pAggs->numOfNull;
18,495✔
3964
  *sum = 0;
18,495✔
3965
  *max = INT16_MIN;
18,495✔
3966
  *min = INT16_MAX;
18,495✔
3967
  *numOfNull = 0;
18,495✔
3968

3969
  int16_t val;
3970
  if (HAS_VALUE == pColData->flag) {
18,495✔
3971
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
4,509,843✔
3972
      val = ((int16_t *)pColData->pData)[iVal];
4,498,848✔
3973
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
4,498,848✔
3974
    }
3975
  } else {
3976
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,507,500✔
3977
      switch (tColDataGetBitValue(pColData, iVal)) {
2,500,000!
3978
        case 0:
1,841,324✔
3979
        case 1:
3980
          (*numOfNull)++;
1,841,324✔
3981
          break;
1,841,324✔
3982
        case 2:
658,676✔
3983
          val = ((int16_t *)pColData->pData)[iVal];
658,676✔
3984
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
658,676✔
3985
          break;
658,676✔
3986
        default:
×
3987
          break;
×
3988
      }
3989
    }
3990
  }
3991
}
18,495✔
3992

3993
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, SColumnDataAgg *pAggs) {
334,165✔
3994
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
334,165✔
3995
  int16_t *numOfNull = &pAggs->numOfNull;
334,165✔
3996
  *sum = 0;
334,165✔
3997
  *max = INT32_MIN;
334,165✔
3998
  *min = INT32_MAX;
334,165✔
3999
  *numOfNull = 0;
334,165✔
4000

4001
  int32_t val;
4002
  if (HAS_VALUE == pColData->flag) {
334,165✔
4003
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
759,659,358✔
4004
      val = ((int32_t *)pColData->pData)[iVal];
759,397,796✔
4005
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
759,397,796✔
4006
    }
4007
  } else {
4008
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
105,683,255✔
4009
      switch (tColDataGetBitValue(pColData, iVal)) {
105,611,252!
4010
        case 0:
13,543,231✔
4011
        case 1:
4012
          (*numOfNull)++;
13,543,231✔
4013
          break;
13,543,231✔
4014
        case 2:
92,118,872✔
4015
          val = ((int32_t *)pColData->pData)[iVal];
92,118,872✔
4016
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
92,118,872✔
4017
          break;
92,118,872✔
4018
        default:
×
4019
          break;
×
4020
      }
4021
    }
4022
  }
4023
}
333,565✔
4024

4025
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, SColumnDataAgg *pAggs) {
234,831✔
4026
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
234,831✔
4027
  int16_t *numOfNull = &pAggs->numOfNull;
234,831✔
4028
  *sum = 0;
234,831✔
4029
  *max = INT64_MIN;
234,831✔
4030
  *min = INT64_MAX;
234,831✔
4031
  *numOfNull = 0;
234,831✔
4032

4033
  int64_t val;
4034
  if (HAS_VALUE == pColData->flag) {
234,831✔
4035
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
450,033,533✔
4036
      val = ((int64_t *)pColData->pData)[iVal];
449,810,938✔
4037
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
449,810,938✔
4038
    }
4039
  } else {
4040
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
18,499,226✔
4041
      switch (tColDataGetBitValue(pColData, iVal)) {
18,488,187!
4042
        case 0:
3,236,159✔
4043
        case 1:
4044
          (*numOfNull)++;
3,236,159✔
4045
          break;
3,236,159✔
4046
        case 2:
15,253,466✔
4047
          val = ((int64_t *)pColData->pData)[iVal];
15,253,466✔
4048
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
15,253,466✔
4049
          break;
15,253,466✔
4050
        default:
×
4051
          break;
×
4052
      }
4053
    }
4054
  }
4055
}
233,634✔
4056

4057
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, SColumnDataAgg *pAggs) {
203,583✔
4058
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
203,583✔
4059
  int16_t *numOfNull = &pAggs->numOfNull;
203,583✔
4060
  *(double *)sum = 0;
203,583✔
4061
  *(double *)max = -FLT_MAX;
203,583✔
4062
  *(double *)min = FLT_MAX;
203,583✔
4063
  *numOfNull = 0;
203,583✔
4064

4065
  float val;
4066
  if (HAS_VALUE == pColData->flag) {
203,583✔
4067
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
760,951,264✔
4068
      val = ((float *)pColData->pData)[iVal];
760,755,197✔
4069
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
760,755,197✔
4070
    }
4071
  } else {
4072
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,522,621✔
4073
      switch (tColDataGetBitValue(pColData, iVal)) {
2,515,105!
4074
        case 0:
1,853,572✔
4075
        case 1:
4076
          (*numOfNull)++;
1,853,572✔
4077
          break;
1,853,572✔
4078
        case 2:
661,533✔
4079
          val = ((float *)pColData->pData)[iVal];
661,533✔
4080
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
661,533✔
4081
          break;
661,533✔
4082
        default:
×
4083
          break;
×
4084
      }
4085
    }
4086
  }
4087
}
203,583✔
4088

4089
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, SColumnDataAgg *pAggs) {
29,946✔
4090
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
29,946✔
4091
  int16_t *numOfNull = &pAggs->numOfNull;
29,946✔
4092
  *(double *)sum = 0;
29,946✔
4093
  *(double *)max = -DBL_MAX;
29,946✔
4094
  *(double *)min = DBL_MAX;
29,946✔
4095
  *numOfNull = 0;
29,946✔
4096

4097
  double val;
4098
  if (HAS_VALUE == pColData->flag) {
29,946✔
4099
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
21,832,091✔
4100
      val = ((double *)pColData->pData)[iVal];
21,809,660✔
4101
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
21,809,660✔
4102
    }
4103
  } else {
4104
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,522,515✔
4105
      switch (tColDataGetBitValue(pColData, iVal)) {
2,515,000!
4106
        case 0:
1,850,404✔
4107
        case 1:
4108
          (*numOfNull)++;
1,850,404✔
4109
          break;
1,850,404✔
4110
        case 2:
664,596✔
4111
          val = ((double *)pColData->pData)[iVal];
664,596✔
4112
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
664,596✔
4113
          break;
664,596✔
4114
        default:
×
4115
          break;
×
4116
      }
4117
    }
4118
  }
4119
}
29,946✔
4120

4121
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, SColumnDataAgg *pAggs) {
3,213✔
4122
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
3,213✔
4123
  int16_t *numOfNull = &pAggs->numOfNull;
3,213✔
4124
  *(uint64_t *)sum = 0;
3,213✔
4125
  *(uint64_t *)max = 0;
3,213✔
4126
  *(uint64_t *)min = UINT8_MAX;
3,213✔
4127
  *numOfNull = 0;
3,213✔
4128

4129
  uint8_t val;
4130
  if (HAS_VALUE == pColData->flag) {
3,213!
4131
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,567,057✔
4132
      val = ((uint8_t *)pColData->pData)[iVal];
3,563,844✔
4133
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,563,844✔
4134
    }
4135
  } else {
4136
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4137
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4138
        case 0:
×
4139
        case 1:
4140
          (*numOfNull)++;
×
4141
          break;
×
4142
        case 2:
×
4143
          val = ((uint8_t *)pColData->pData)[iVal];
×
4144
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4145
          break;
×
4146
        default:
×
4147
          break;
×
4148
      }
4149
    }
4150
  }
4151
}
3,213✔
4152

4153
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, SColumnDataAgg *pAggs) {
3,213✔
4154
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
3,213✔
4155
  int16_t *numOfNull = &pAggs->numOfNull;
3,213✔
4156
  *(uint64_t *)sum = 0;
3,213✔
4157
  *(uint64_t *)max = 0;
3,213✔
4158
  *(uint64_t *)min = UINT16_MAX;
3,213✔
4159
  *numOfNull = 0;
3,213✔
4160

4161
  uint16_t val;
4162
  if (HAS_VALUE == pColData->flag) {
3,213!
4163
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,566,949✔
4164
      val = ((uint16_t *)pColData->pData)[iVal];
3,563,736✔
4165
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,563,736✔
4166
    }
4167
  } else {
4168
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4169
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4170
        case 0:
×
4171
        case 1:
4172
          (*numOfNull)++;
×
4173
          break;
×
4174
        case 2:
×
4175
          val = ((uint16_t *)pColData->pData)[iVal];
×
4176
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4177
          break;
×
4178
        default:
×
4179
          break;
×
4180
      }
4181
    }
4182
  }
4183
}
3,213✔
4184

4185
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, SColumnDataAgg *pAggs) {
3,213✔
4186
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
3,213✔
4187
  int16_t *numOfNull = &pAggs->numOfNull;
3,213✔
4188
  *(uint64_t *)sum = 0;
3,213✔
4189
  *(uint64_t *)max = 0;
3,213✔
4190
  *(uint64_t *)min = UINT32_MAX;
3,213✔
4191
  *numOfNull = 0;
3,213✔
4192

4193
  uint32_t val;
4194
  if (HAS_VALUE == pColData->flag) {
3,213!
4195
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,567,060✔
4196
      val = ((uint32_t *)pColData->pData)[iVal];
3,563,847✔
4197
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,563,847✔
4198
    }
4199
  } else {
4200
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4201
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4202
        case 0:
×
4203
        case 1:
4204
          (*numOfNull)++;
×
4205
          break;
×
4206
        case 2:
×
4207
          val = ((uint32_t *)pColData->pData)[iVal];
×
4208
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4209
          break;
×
4210
        default:
×
4211
          break;
×
4212
      }
4213
    }
4214
  }
4215
}
3,213✔
4216

4217
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, SColumnDataAgg *pAggs) {
3,213✔
4218
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
3,213✔
4219
  int16_t *numOfNull = &pAggs->numOfNull;
3,213✔
4220
  *(uint64_t *)sum = 0;
3,213✔
4221
  *(uint64_t *)max = 0;
3,213✔
4222
  *(uint64_t *)min = UINT64_MAX;
3,213✔
4223
  *numOfNull = 0;
3,213✔
4224

4225
  uint64_t val;
4226
  if (HAS_VALUE == pColData->flag) {
3,213!
4227
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,567,060✔
4228
      val = ((uint64_t *)pColData->pData)[iVal];
3,563,847✔
4229
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
3,563,847✔
4230
    }
4231
  } else {
4232
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4233
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4234
        case 0:
×
4235
        case 1:
4236
          (*numOfNull)++;
×
4237
          break;
×
4238
        case 2:
×
4239
          val = ((uint64_t *)pColData->pData)[iVal];
×
4240
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4241
          break;
×
4242
        default:
×
4243
          break;
×
4244
      }
4245
    }
4246
  }
4247
}
3,213✔
4248

4249
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, SColumnDataAgg *pAggs) {
36,205✔
4250
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
36,205✔
4251
  int16_t *numOfNull = &pAggs->numOfNull;
36,205✔
4252
  *(uint64_t *)sum = 0;
36,205✔
4253
  *(uint64_t *)max = 0;
36,205✔
4254
  *(uint64_t *)min = 0;
36,205✔
4255
  *numOfNull = 0;
36,205✔
4256

4257
  switch (pColData->flag) {
36,205!
4258
    case HAS_NONE:
×
4259
    case HAS_NULL:
4260
    case (HAS_NONE | HAS_NULL):
4261
      *numOfNull = pColData->nVal;
×
4262
      break;
×
4263
    case HAS_VALUE:
27,340✔
4264
      *numOfNull = 0;
27,340✔
4265
      break;
27,340✔
4266
    case (HAS_VALUE | HAS_NULL):
8,865✔
4267
    case (HAS_VALUE | HAS_NONE):
4268
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,973,865✔
4269
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
2,965,000✔
4270
          (*numOfNull)++;
1,782,004✔
4271
        }
4272
      }
4273
      break;
8,865✔
4274
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4275
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4276
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4277
          (*numOfNull)++;
×
4278
        }
4279
      }
4280
      break;
×
4281
    default:
×
4282
      break;
×
4283
  }
4284
}
36,205✔
4285

4286
#define CALC_DECIMAL_SUM_MAX_MIN(TYPE, pSumOp, pCompOp, pColData, pSum, pMax, pMin)                   \
4287
  do {                                                                                                \
4288
    if (decimal128AddCheckOverflow((Decimal *)pSum, pVal, DECIMAL_WORD_NUM(TYPE))) *pOverflow = true; \
4289
    pSumOp->add(pSum, pVal, DECIMAL_WORD_NUM(TYPE));                                                  \
4290
    if (pCompOp->gt(pVal, pMax, DECIMAL_WORD_NUM(TYPE))) {                                            \
4291
      *(pMax) = *pVal;                                                                                \
4292
    }                                                                                                 \
4293
    if (pCompOp->lt(pVal, pMin, DECIMAL_WORD_NUM(TYPE))) {                                            \
4294
      *(pMin) = *pVal;                                                                                \
4295
    }                                                                                                 \
4296
  } while (0)
4297

4298
static FORCE_INLINE void tColDataCalcSMADecimal64Type(SColData *pColData, SColumnDataAgg *pAggs) {
135✔
4299
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum;
135✔
4300
  Decimal64  *pMax = (Decimal64 *)pAggs->decimal128Max, *pMin = (Decimal64 *)pAggs->decimal128Min;
135✔
4301
  uint8_t    *pOverflow = &pAggs->overflow;
135✔
4302
  *pSum = DECIMAL128_ZERO;
135✔
4303
  *pMax = DECIMAL64_MIN;
135✔
4304
  *pMin = DECIMAL64_MAX;
135✔
4305
  pAggs->numOfNull = 0;
135✔
4306
  pAggs->colId |= DECIMAL_AGG_FLAG;
135✔
4307

4308
  Decimal64         *pVal = NULL;
135✔
4309
  const SDecimalOps *pSumOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
135✔
4310
  const SDecimalOps *pCompOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
135✔
4311
  if (HAS_VALUE == pColData->flag) {
135✔
4312
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
505✔
4313
      pVal = ((Decimal64 *)pColData->pData) + iVal;
500✔
4314
      CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
500!
4315
    }
4316
  } else {
4317
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
97,730✔
4318
      switch (tColDataGetBitValue(pColData, iVal)) {
97,600!
4319
        case 0:
6,161✔
4320
        case 1:
4321
          pAggs->numOfNull++;
6,161✔
4322
          break;
6,161✔
4323
        case 2:
91,439✔
4324
          pVal = ((Decimal64 *)pColData->pData) + iVal;
91,439✔
4325
          CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
91,439!
4326
          break;
91,439✔
4327
        default:
×
4328
          break;
×
4329
      }
4330
    }
4331
  }
4332
}
135✔
4333

4334
static FORCE_INLINE void tColDataCalcSMADecimal128Type(SColData *pColData, SColumnDataAgg *pAggs) {
349✔
4335
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum, *pMax = (Decimal128 *)pAggs->decimal128Max,
349✔
4336
             *pMin = (Decimal128 *)pAggs->decimal128Min;
349✔
4337
  uint8_t *pOverflow = &pAggs->overflow;
349✔
4338
  *pSum = DECIMAL128_ZERO;
349✔
4339
  *pMax = DECIMAL128_MIN;
349✔
4340
  *pMin = DECIMAL128_MAX;
349✔
4341
  pAggs->numOfNull = 0;
349✔
4342
  pAggs->colId |= DECIMAL_AGG_FLAG;
349✔
4343

4344
  Decimal128        *pVal = NULL;
349✔
4345
  const SDecimalOps *pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
349✔
4346
  if (HAS_VALUE == pColData->flag) {
349✔
4347
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
1,313✔
4348
      pVal = ((Decimal128 *)pColData->pData) + iVal;
1,300✔
4349
      CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
1,300✔
4350
    }
4351
  } else {
4352
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
311,136✔
4353
      switch (tColDataGetBitValue(pColData, iVal)) {
310,800!
4354
        case 0:
18,775✔
4355
        case 1:
4356
          pAggs->numOfNull++;
18,775✔
4357
          break;
18,775✔
4358
        case 2:
292,025✔
4359
          pVal = ((Decimal128 *)pColData->pData) + iVal;
292,025✔
4360
          CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
292,025✔
4361
          break;
292,025✔
4362
        default:
×
4363
          break;
×
4364
      }
4365
    }
4366
  }
4367
}
349✔
4368

4369
void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAgg *pAggs) = {
4370
    NULL,
4371
    tColDataCalcSMABool,            // TSDB_DATA_TYPE_BOOL
4372
    tColDataCalcSMATinyInt,         // TSDB_DATA_TYPE_TINYINT
4373
    tColDataCalcSMATinySmallInt,    // TSDB_DATA_TYPE_SMALLINT
4374
    tColDataCalcSMAInt,             // TSDB_DATA_TYPE_INT
4375
    tColDataCalcSMABigInt,          // TSDB_DATA_TYPE_BIGINT
4376
    tColDataCalcSMAFloat,           // TSDB_DATA_TYPE_FLOAT
4377
    tColDataCalcSMADouble,          // TSDB_DATA_TYPE_DOUBLE
4378
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_VARCHAR
4379
    tColDataCalcSMABigInt,          // TSDB_DATA_TYPE_TIMESTAMP
4380
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_NCHAR
4381
    tColDataCalcSMAUTinyInt,        // TSDB_DATA_TYPE_UTINYINT
4382
    tColDataCalcSMATinyUSmallInt,   // TSDB_DATA_TYPE_USMALLINT
4383
    tColDataCalcSMAUInt,            // TSDB_DATA_TYPE_UINT
4384
    tColDataCalcSMAUBigInt,         // TSDB_DATA_TYPE_UBIGINT
4385
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_JSON
4386
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_VARBINARY
4387
    tColDataCalcSMADecimal128Type,  // TSDB_DATA_TYPE_DECIMAL
4388
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_BLOB
4389
    NULL,                           // TSDB_DATA_TYPE_MEDIUMBLOB
4390
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_GEOMETRY
4391
    tColDataCalcSMADecimal64Type,   // TSDB_DATA_TYPE_DECIMAL64
4392
};
4393

4394
// SValueColumn ================================
4395
int32_t tValueColumnInit(SValueColumn *valCol) {
18,416,298✔
4396
  valCol->type = TSDB_DATA_TYPE_NULL;
18,416,298✔
4397
  valCol->numOfValues = 0;
18,416,298✔
4398
  tBufferInit(&valCol->data);
18,416,298✔
4399
  tBufferInit(&valCol->offsets);
18,416,298✔
4400
  return 0;
18,416,298✔
4401
}
4402

4403
void tValueColumnDestroy(SValueColumn *valCol) {
45,316,443✔
4404
  valCol->type = TSDB_DATA_TYPE_NULL;
45,316,443✔
4405
  valCol->numOfValues = 0;
45,316,443✔
4406
  tBufferDestroy(&valCol->data);
45,316,443✔
4407
  tBufferDestroy(&valCol->offsets);
45,316,722✔
4408
  return;
45,316,744✔
4409
}
4410

4411
void tValueColumnClear(SValueColumn *valCol) {
21,509,691✔
4412
  valCol->type = TSDB_DATA_TYPE_NULL;
21,509,691✔
4413
  valCol->numOfValues = 0;
21,509,691✔
4414
  tBufferClear(&valCol->data);
21,509,691✔
4415
  tBufferClear(&valCol->offsets);
21,509,691✔
4416
  return;
21,509,691✔
4417
}
4418

4419
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
832,992✔
4420
  int32_t code;
4421

4422
  if (valCol->numOfValues == 0) {
832,992✔
4423
    valCol->type = value->type;
12,390✔
4424
  }
4425

4426
  if (!(value->type == valCol->type)) {
832,992!
4427
    return TSDB_CODE_INVALID_PARA;
×
4428
  }
4429

4430
  if (IS_VAR_DATA_TYPE(value->type)) {
832,992!
4431
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
19,190!
4432
      return code;
×
4433
    }
4434
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
19,190!
4435
      return code;
×
4436
    }
4437
  } else {
4438
    code = tBufferPut(&valCol->data, VALUE_GET_DATUM(value, value->type), tDataTypes[value->type].bytes);
823,397!
4439
    if (code) return code;
823,397!
4440
  }
4441
  valCol->numOfValues++;
832,992✔
4442

4443
  return 0;
832,992✔
4444
}
4445

4446
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
235,541,280✔
4447
  int32_t code;
4448

4449
  if (idx < 0 || idx >= valCol->numOfValues) {
235,541,280!
4450
    return TSDB_CODE_OUT_OF_RANGE;
×
4451
  }
4452

4453
  if (IS_VAR_DATA_TYPE(valCol->type)) {
235,564,479!
4454
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
6,173✔
4455
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
6,173!
4456
    int32_t  oldDataSize = nextOffset - offsets[idx];
6,173✔
4457
    int32_t  bytesAdded = value->nData - oldDataSize;
6,173✔
4458

4459
    if (bytesAdded != 0) {
6,173!
4460
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
×
4461
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
×
4462
              tBufferGetSize(&valCol->data) - nextOffset);
×
4463
      valCol->data.size += bytesAdded;
×
4464

4465
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
×
4466
        offsets[i] += bytesAdded;
×
4467
      }
4468
    }
4469
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
6,173✔
4470
  } else {
4471
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, VALUE_GET_DATUM(value, valCol->type),
235,558,306!
4472
                        tDataTypes[valCol->type].bytes);
235,558,306!
4473
  }
4474
  return 0;
4475
}
4476

4477
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
477,049,775✔
4478
  if (idx < 0 || idx >= valCol->numOfValues) {
477,049,775!
4479
    return TSDB_CODE_OUT_OF_RANGE;
×
4480
  }
4481

4482
  value->type = valCol->type;
477,124,011✔
4483
  if (IS_VAR_DATA_TYPE(value->type)) {
477,124,011!
4484
    int32_t       offset, nextOffset;
4485
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
640,815✔
4486

4487
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
640,815!
4488
    if (idx == valCol->numOfValues - 1) {
656,975✔
4489
      nextOffset = tBufferGetSize(&valCol->data);
208,337✔
4490
    } else {
4491
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
448,638✔
4492
    }
4493
    value->nData = nextOffset - offset;
656,495✔
4494
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
656,495✔
4495
  } else {
4496
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
476,483,196✔
4497
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
952,966,392!
4498
  }
4499
  return 0;
477,139,691✔
4500
}
4501

4502
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
12,387✔
4503
  int32_t code;
4504

4505
  if (!(valCol->numOfValues > 0)) {
12,387!
4506
    return TSDB_CODE_INVALID_PARA;
×
4507
  }
4508

4509
  (*info) = (SValueColumnCompressInfo){
12,387✔
4510
      .cmprAlg = info->cmprAlg,
12,387✔
4511
      .type = valCol->type,
12,387✔
4512
  };
4513

4514
  // offset
4515
  if (IS_VAR_DATA_TYPE(valCol->type)) {
12,387!
4516
    SCompressInfo cinfo = {
3,274✔
4517
        .cmprAlg = info->cmprAlg,
3,274✔
4518
        .dataType = TSDB_DATA_TYPE_INT,
4519
        .originalSize = valCol->offsets.size,
3,274✔
4520
    };
4521

4522
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
3,274✔
4523
    if (code) return code;
3,275!
4524

4525
    info->offsetOriginalSize = cinfo.originalSize;
3,275✔
4526
    info->offsetCompressedSize = cinfo.compressedSize;
3,275✔
4527
  }
4528

4529
  // data
4530
  SCompressInfo cinfo = {
12,388✔
4531
      .cmprAlg = info->cmprAlg,
12,388✔
4532
      .dataType = valCol->type,
12,388✔
4533
      .originalSize = valCol->data.size,
12,388✔
4534
  };
4535

4536
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
12,388✔
4537
  if (code) return code;
12,390!
4538

4539
  info->dataOriginalSize = cinfo.originalSize;
12,390✔
4540
  info->dataCompressedSize = cinfo.compressedSize;
12,390✔
4541

4542
  return 0;
12,390✔
4543
}
4544

4545
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
845,942✔
4546
                               SBuffer *assist) {
4547
  int32_t code;
4548

4549
  tValueColumnClear(valCol);
845,942✔
4550
  valCol->type = info->type;
845,937✔
4551
  // offset
4552
  if (IS_VAR_DATA_TYPE(valCol->type)) {
1,245,736!
4553
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
399,528✔
4554

4555
    SCompressInfo cinfo = {
399,528✔
4556
        .dataType = TSDB_DATA_TYPE_INT,
4557
        .cmprAlg = info->cmprAlg,
399,528✔
4558
        .originalSize = info->offsetOriginalSize,
399,528✔
4559
        .compressedSize = info->offsetCompressedSize,
399,528✔
4560
    };
4561

4562
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
399,528✔
4563
    if (code) {
399,799!
4564
      return code;
×
4565
    }
4566
  } else {
4567
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
446,409✔
4568
  }
4569

4570
  // data
4571
  SCompressInfo cinfo = {
846,208✔
4572
      .dataType = valCol->type,
846,208✔
4573
      .cmprAlg = info->cmprAlg,
846,208✔
4574
      .originalSize = info->dataOriginalSize,
846,208✔
4575
      .compressedSize = info->dataCompressedSize,
846,208✔
4576
  };
4577

4578
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
846,208✔
4579
  if (code) {
846,214!
4580
    return code;
×
4581
  }
4582

4583
  return 0;
846,214✔
4584
}
4585

4586
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
12,390✔
4587
  int32_t code;
4588
  uint8_t fmtVer = 0;
12,390✔
4589

4590
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
24,780!
4591
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
24,780!
4592
  if ((code = tBufferPutI8(buffer, info->type))) return code;
24,780!
4593
  if (IS_VAR_DATA_TYPE(info->type)) {
12,390!
4594
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
6,550!
4595
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
6,550!
4596
  }
4597
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
24,780!
4598
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
24,780!
4599

4600
  return 0;
12,390✔
4601
}
4602

4603
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
846,180✔
4604
  int32_t code;
4605
  uint8_t fmtVer;
4606

4607
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
846,180!
4608
  if (fmtVer == 0) {
846,181!
4609
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
846,186!
4610
    if ((code = tBufferGetI8(reader, &info->type))) return code;
846,086!
4611
    if (IS_VAR_DATA_TYPE(info->type)) {
846,038!
4612
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
399,539!
4613
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
399,673!
4614
    } else {
4615
      info->offsetOriginalSize = 0;
446,499✔
4616
      info->offsetCompressedSize = 0;
446,499✔
4617
    }
4618
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
846,182!
4619
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
845,987!
4620
  } else {
4621
    return TSDB_CODE_INVALID_PARA;
×
4622
  }
4623

4624
  return 0;
845,891✔
4625
}
4626

4627
int32_t tCompressData(void          *input,       // input
6,255,500✔
4628
                      SCompressInfo *info,        // compress info
4629
                      void          *output,      // output
4630
                      int32_t        outputSize,  // output size
4631
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4632
) {
4633
  int32_t extraSizeNeeded;
4634
  int32_t code;
4635

4636
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
6,255,500!
4637
  if (!(outputSize >= extraSizeNeeded)) {
6,255,500!
4638
    return TSDB_CODE_INVALID_PARA;
×
4639
  }
4640

4641
  if (info->cmprAlg == NO_COMPRESSION) {
6,255,500!
4642
    (void)memcpy(output, input, info->originalSize);
×
4643
    info->compressedSize = info->originalSize;
×
4644
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
7,580,075!
4645
    SBuffer local;
4646

4647
    tBufferInit(&local);
4648
    if (buffer == NULL) {
1,321,601!
4649
      buffer = &local;
×
4650
    }
4651

4652
    if (info->cmprAlg == TWO_STAGE_COMP) {
1,321,601!
4653
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
1,324,358✔
4654
      if (code) {
1,324,358!
4655
        tBufferDestroy(&local);
4656
        return code;
×
4657
      }
4658
    }
4659

4660
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
2,646,176✔
4661
        input,                                                   // input
4662
        info->originalSize,                                      // input size
4663
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
1,321,601✔
4664
        output,                                                  // output
4665
        outputSize,                                              // output size
4666
        info->cmprAlg,                                           // compression algorithm
1,321,601✔
4667
        buffer->data,                                            // buffer
4668
        buffer->capacity                                         // buffer size
1,321,601✔
4669
    );
4670
    if (info->compressedSize < 0) {
1,324,575!
4671
      tBufferDestroy(&local);
4672
      return TSDB_CODE_COMPRESS_ERROR;
×
4673
    }
4674

4675
    tBufferDestroy(&local);
4676
  } else {
4677
    DEFINE_VAR(info->cmprAlg)
4,933,899✔
4678
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
4,933,899!
4679
      (void)memcpy(output, input, info->originalSize);
12✔
4680
      info->compressedSize = info->originalSize;
12✔
4681
      return 0;
12✔
4682
    }
4683
    SBuffer local;
4684

4685
    tBufferInit(&local);
4686
    if (buffer == NULL) {
4,933,887!
4687
      buffer = &local;
×
4688
    }
4689
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
4,933,887✔
4690

4691
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
9,868,952✔
4692
        input,                                                      // input
4693
        info->originalSize,                                         // input size
4694
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
4,933,912✔
4695
        output,                                                     // output
4696
        outputSize,                                                 // output size
4697
        info->cmprAlg,                                              // compression algorithm
4698
        buffer->data,                                               // buffer
4699
        buffer->capacity                                            // buffer size
4,933,912✔
4700
    );
4701
    if (info->compressedSize < 0) {
4,935,040!
4702
      tBufferDestroy(&local);
4703
      return TSDB_CODE_COMPRESS_ERROR;
×
4704
    }
4705

4706
    tBufferDestroy(&local);
4707
    // new col compress
4708
  }
4709

4710
  return 0;
6,259,615✔
4711
}
4712

4713
int32_t tDecompressData(void                *input,       // input
66,503,967✔
4714
                        const SCompressInfo *info,        // compress info
4715
                        void                *output,      // output
4716
                        int32_t              outputSize,  // output size
4717
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4718
) {
4719
  int32_t code;
4720

4721
  if (!(outputSize >= info->originalSize)) {
66,503,967!
4722
    return TSDB_CODE_INVALID_PARA;
×
4723
  }
4724

4725
  if (info->cmprAlg == NO_COMPRESSION) {
66,503,967!
4726
    if (!(info->compressedSize == info->originalSize)) {
×
4727
      return TSDB_CODE_INVALID_PARA;
×
4728
    }
4729
    (void)memcpy(output, input, info->compressedSize);
×
4730
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
94,124,115!
4731
    SBuffer local;
4732

4733
    tBufferInit(&local);
4734
    if (buffer == NULL) {
27,576,398!
4735
      buffer = &local;
×
4736
    }
4737

4738
    if (info->cmprAlg == TWO_STAGE_COMP) {
27,576,398!
4739
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
27,614,065✔
4740
      if (code) {
27,614,973!
4741
        tBufferDestroy(&local);
4742
        return code;
×
4743
      }
4744
    }
4745

4746
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
27,577,306✔
4747
        input,                                                  // input
4748
        info->compressedSize,                                   // inputSize
27,577,306✔
4749
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
27,577,306✔
4750
        output,                                                 // output
4751
        outputSize,                                             // output size
4752
        info->cmprAlg,                                          // compression algorithm
27,577,306✔
4753
        buffer->data,                                           // helper buffer
4754
        buffer->capacity                                        // extra buffer size
27,577,306✔
4755
    );
4756
    if (decompressedSize < 0) {
27,620,148!
4757
      tBufferDestroy(&local);
4758
      return TSDB_CODE_COMPRESS_ERROR;
×
4759
    }
4760

4761
    if (!(decompressedSize == info->originalSize)) {
27,620,148!
4762
      return TSDB_CODE_COMPRESS_ERROR;
×
4763
    }
4764
    tBufferDestroy(&local);
4765
  } else {
4766
    DEFINE_VAR(info->cmprAlg);
38,927,569✔
4767
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
38,927,569✔
4768
      (void)memcpy(output, input, info->compressedSize);
24✔
4769
      return 0;
24✔
4770
    }
4771
    SBuffer local;
4772

4773
    tBufferInit(&local);
4774
    if (buffer == NULL) {
38,927,545!
4775
      buffer = &local;
×
4776
    }
4777
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
38,927,545✔
4778
    if (code) {
38,928,499!
4779
      return code;
×
4780
    }
4781

4782
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
38,928,499✔
4783
        input,                                                  // input
4784
        info->compressedSize,                                   // inputSize
38,928,499✔
4785
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
38,928,499✔
4786
        output,                                                 // output
4787
        outputSize,                                             // output size
4788
        info->cmprAlg,                                          // compression algorithm
38,928,499✔
4789
        buffer->data,                                           // helper buffer
4790
        buffer->capacity                                        // extra buffer size
38,928,499✔
4791
    );
4792
    if (decompressedSize < 0) {
38,936,472!
4793
      tBufferDestroy(&local);
4794
      return TSDB_CODE_COMPRESS_ERROR;
×
4795
    }
4796

4797
    if (!(decompressedSize == info->originalSize)) {
38,936,472!
4798
      return TSDB_CODE_COMPRESS_ERROR;
×
4799
    }
4800
    tBufferDestroy(&local);
4801
  }
4802

4803
  return 0;
66,556,620✔
4804
}
4805

4806
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
6,256,046✔
4807
  int32_t code;
4808

4809
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
6,256,046✔
4810
  if (code) return code;
6,256,056!
4811

4812
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
6,256,056✔
4813
  if (code) return code;
6,257,373!
4814

4815
  output->size += info->compressedSize;
6,257,373✔
4816
  return 0;
6,257,373✔
4817
}
4818

4819
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
27,617,384✔
4820
  int32_t code;
4821

4822
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
27,617,384✔
4823
  if (code) return code;
27,609,418!
4824

4825
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
27,609,418✔
4826
  if (code) return code;
27,619,360!
4827

4828
  output->size += info->originalSize;
27,619,360✔
4829
  return 0;
27,619,360✔
4830
}
4831

4832
// handle all types, including var data
4833
void valueSetDatum(SValue *pVal, int8_t type, void *pDatum, uint32_t len) {
2,147,483,647✔
4834
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
2,147,483,647!
4835
    pVal->pData = pDatum;
×
4836
    pVal->nData = len;
×
4837
  } else {
4838
    switch (len) {
2,147,483,647!
4839
      case sizeof(uint8_t):
1,379,603,906✔
4840
        pVal->val = *(uint8_t *)pDatum;
1,379,603,906✔
4841
        break;
1,379,603,906✔
4842
      case sizeof(uint16_t):
713,684,897✔
4843
        pVal->val = *(uint16_t *)pDatum;
713,684,897✔
4844
        break;
713,684,897✔
4845
      case sizeof(uint32_t):
2,147,483,647✔
4846
        pVal->val = *(uint32_t *)pDatum;
2,147,483,647✔
4847
        break;
2,147,483,647✔
4848
      case sizeof(uint64_t):
2,147,483,647✔
4849
        pVal->val = *(uint64_t *)pDatum;
2,147,483,647✔
4850
        break;
2,147,483,647✔
4851
      default:
×
4852
        break;
×
4853
    }
4854
  }
4855
}
2,147,483,647✔
4856

4857
void valueCloneDatum(SValue *pDst, const SValue *pSrc, int8_t type) {
92,871,156✔
4858
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
92,871,156!
4859
    memcpy(pDst->pData, pSrc->pData, pSrc->nData);
1,227,138✔
4860
    pDst->nData = pSrc->nData;
1,227,138✔
4861
  } else {
4862
    pDst->val = pSrc->val;
91,644,018✔
4863
  }
4864
}
92,871,156✔
4865
void valueClearDatum(SValue *pVal, int8_t type) {
×
4866
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
4867
    taosMemoryFreeClear(pVal->pData);
×
4868
    pVal->nData = 0;
×
4869
  } else {
4870
    pVal->val = 0;
×
4871
  }
4872
}
×
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