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

taosdata / TDengine / #3523

06 Nov 2024 02:29AM UTC coverage: 55.861% (-2.4%) from 58.216%
#3523

push

travis-ci

web-flow
Merge pull request #28551 from taosdata/feat/TS-5215-2

test(blob): testing & fixes for blob

106075 of 245834 branches covered (43.15%)

Branch coverage included in aggregate %.

0 of 15 new or added lines in 2 files covered. (0.0%)

17003 existing lines in 254 files now uncovered.

181910 of 269703 relevant lines covered (67.45%)

1527639.59 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

130
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
467,692,531✔
131
  if (IS_VAR_DATA_TYPE(colVal->value.type)) {
467,692,531!
132
    sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)  // size
72,563,137✔
133
                           + colVal->value.nData;               // value
72,563,137✔
134

135
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
72,563,137✔
136
                            + tPutU32v(NULL, colVal->value.nData)  // size
72,563,137✔
137
                            + colVal->value.nData;                 // value
72,563,137✔
138
  } else {
139
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)              // colId
395,129,394✔
140
                            + tDataTypes[colVal->value.type].bytes;  // value
395,129,394✔
141
  }
142
  sinfo->numOfValue++;
467,692,531✔
143
}
467,692,531✔
144

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

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

161
  *sinfo = (SRowBuildScanInfo){
92,460,440✔
162
      .tupleFixedSize = schema->flen,
92,460,440✔
163
  };
164

165
  // loop scan
166
  for (int32_t i = 1; i < schema->numOfCols; i++) {
643,171,031✔
167
    for (;;) {
168
      if (colValIndex >= numOfColVals) {
550,810,149✔
169
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
56!
170
        break;
28✔
171
      }
172

173
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
550,810,121✔
174
        if (!(colValArray[colValIndex].value.type == schema->columns[i].type)) {
550,710,625!
175
          code = TSDB_CODE_INVALID_PARA;
×
176
          goto _exit;
×
177
        }
178

179
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {
550,710,625✔
180
          tRowBuildScanAddValue(sinfo, &colValArray[colValIndex], schema->columns + i);
467,692,531✔
181
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {
83,018,094✔
182
          if ((code = tRowBuildScanAddNull(sinfo, schema->columns + i))) goto _exit;
16,993,024✔
183
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {
74,521,582!
184
          if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
150,194,096!
185
        }
186

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

198
  if (sinfo->numOfNone) {
92,460,378✔
199
    sinfo->flag |= HAS_NONE;
5,010,447✔
200
  }
201
  if (sinfo->numOfNull) {
92,460,378✔
202
    sinfo->flag |= HAS_NULL;
5,560,583✔
203
  }
204
  if (sinfo->numOfValue) {
92,460,378!
205
    sinfo->flag |= HAS_VALUE;
92,918,217✔
206
  }
207

208
  // Tuple
209
  sinfo->tupleFlag = sinfo->flag;
92,460,378✔
210
  switch (sinfo->flag) {
92,460,378!
211
    case HAS_NONE:
129,512✔
212
    case HAS_NULL:
213
      sinfo->tupleBitmapSize = 0;
129,512✔
214
      sinfo->tupleFixedSize = 0;
129,512✔
215
      break;
129,512✔
216
    case HAS_VALUE:
84,797,087✔
217
      sinfo->tupleBitmapSize = 0;
84,797,087✔
218
      sinfo->tupleFixedSize = schema->flen;
84,797,087✔
219
      break;
84,797,087✔
220
    case (HAS_NONE | HAS_NULL):
1,297✔
221
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
1,297✔
222
      sinfo->tupleFixedSize = 0;
1,297✔
223
      break;
1,297✔
224
    case (HAS_NONE | HAS_VALUE):
6,409,932✔
225
    case (HAS_NULL | HAS_VALUE):
226
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
6,409,932✔
227
      sinfo->tupleFixedSize = schema->flen;
6,409,932✔
228
      break;
6,409,932✔
229
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
2,014,719✔
230
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
2,014,719✔
231
      sinfo->tupleFixedSize = schema->flen;
2,014,719✔
232
      break;
2,014,719✔
233
  }
234
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
93,251,221✔
235
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
790,843✔
236
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
790,843✔
237
  }
238
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
92,460,378✔
239
                        + sinfo->tuplePKSize      // primary keys
92,460,378✔
240
                        + sinfo->tupleBitmapSize  // bitmap
92,460,378✔
241
                        + sinfo->tupleFixedSize   // fixed part
92,460,378✔
242
                        + sinfo->tupleVarSize;    // var part
92,460,378✔
243

244
  // Key-Value
245
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
92,460,378✔
246
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
90,022,984✔
247
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
90,022,984✔
248
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
2,437,394!
249
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
3,420,588✔
250
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
3,420,588✔
251
  } else {
252
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
253
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
254
  }
255
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
93,251,221✔
256
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
790,843✔
257
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
790,843✔
258
  }
259
  sinfo->kvRowSize = sizeof(SRow)             // SRow
92,460,378✔
260
                     + sinfo->kvPKSize        // primary keys
92,460,378✔
261
                     + sinfo->kvIndexSize     // index array
92,460,378✔
262
                     + sinfo->kvPayloadSize;  // payload
92,460,378✔
263

264
_exit:
92,460,440✔
265
  return code;
92,460,440✔
266
}
267

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

272
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
85,669,837✔
273
  if (*ppRow == NULL) {
85,815,632!
274
    return terrno;
×
275
  }
276
  (*ppRow)->flag = sinfo->tupleFlag;
85,881,577✔
277
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
85,881,577✔
278
  (*ppRow)->sver = schema->version;
85,881,577✔
279
  (*ppRow)->len = sinfo->tupleRowSize;
85,881,577✔
280
  (*ppRow)->ts = colValArray[0].value.val;
85,881,577✔
281

282
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
85,881,577✔
283
    return 0;
129,510✔
284
  }
285

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

291
  // primary keys
292
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
85,860,308✔
293
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
108,241✔
294
  }
295

296
  // bitmap + fixed + varlen
297
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
85,752,067✔
298
  int32_t colValIndex = 1;
85,752,067✔
299
  for (int32_t i = 1; i < schema->numOfCols; i++) {
515,281,961✔
300
    for (;;) {
301
      if (colValIndex >= numOfColVals) {  // NONE
429,810,039!
302
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
303
        break;
×
304
      }
305

306
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
429,810,039✔
307
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
429,529,894✔
308
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_VALUE);
428,485,323!
309

310
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
428,485,323!
311
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
64,421,488✔
312
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
64,421,488✔
313
            if (colValArray[colValIndex].value.nData) {
64,421,488!
314
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
64,909,740✔
315
              varlen += colValArray[colValIndex].value.nData;
64,909,740✔
316
            }
317
          } else {
318
            (void)memcpy(fixed + schema->columns[i].offset, &colValArray[colValIndex].value.val,
364,063,835✔
319
                         tDataTypes[schema->columns[i].type].bytes);
364,063,835✔
320
          }
321
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
1,044,571!
322
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
1,393,794!
323
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
324
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
27,971!
325
        }
326

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

338
  return 0;
85,752,067✔
339
}
340

341
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
342
  if (flag & KV_FLG_LIT) {
46,366,746✔
343
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
44,749,470✔
344
  } else if (flag & KV_FLG_MID) {
1,617,276!
345
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
1,606,908✔
346
  } else {
347
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
10,368✔
348
  }
349
  indices->nCol++;
46,366,746✔
350
}
46,366,746✔
351

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

355
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
7,405,873✔
356
  if (*ppRow == NULL) {
7,407,051✔
357
    return terrno;
17✔
358
  }
359
  (*ppRow)->flag = sinfo->kvFlag;
7,407,034✔
360
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
7,407,034✔
361
  (*ppRow)->sver = schema->version;
7,407,034✔
362
  (*ppRow)->len = sinfo->kvRowSize;
7,407,034✔
363
  (*ppRow)->ts = colValArray[0].value.val;
7,407,034✔
364

365
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
7,407,034!
366
    return TSDB_CODE_INVALID_PARA;
×
367
  }
368

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

374
  // primary keys
375
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
8,089,588✔
376
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
682,554✔
377
  }
378

379
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
7,407,034✔
380
  int32_t colValIndex = 1;
7,407,034✔
381
  for (int32_t i = 1; i < schema->numOfCols; i++) {
127,722,694✔
382
    for (;;) {
383
      if (colValIndex >= numOfColVals) {  // NONE
120,306,910✔
384
        break;
28✔
385
      }
386

387
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
120,306,882!
388
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
120,315,632✔
389
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
39,519,046✔
390
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
39,519,046!
391
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
7,850,733✔
392
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
7,850,733✔
393
            if (colValArray[colValIndex].value.nData > 0) {
7,850,733!
394
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
7,858,614✔
395
                           colValArray[colValIndex].value.nData);
7,858,614✔
396
            }
397
            payloadSize += colValArray[colValIndex].value.nData;
7,850,733✔
398
          } else {
399
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
31,668,313✔
400
            (void)memcpy(payload + payloadSize, &colValArray[colValIndex].value.val,
31,668,313✔
401
                         tDataTypes[schema->columns[i].type].bytes);
31,668,313✔
402
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
31,668,313✔
403
          }
404
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
80,796,586✔
405
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
6,847,700✔
406
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
13,695,400✔
407
        }
408

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

419
  return 0;
7,407,034✔
420
}
421

422
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
92,363,709✔
423
  int32_t           code;
424
  SRowBuildScanInfo sinfo;
425

426
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
92,363,709✔
427
  if (code) return code;
93,279,174✔
428

429
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
93,279,112✔
430
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
85,954,843✔
431
  } else {
432
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
7,324,269✔
433
  }
434
  return code;
93,183,372✔
435
}
436

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

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

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

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

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

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

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

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

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

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

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

521
  STColumn *pTColumn = pTSchema->columns + iCol;
221,766,505✔
522

523
  if (iCol == 0) {
221,766,505✔
524
    pColVal->cid = pTColumn->colId;
10,549,905✔
525
    pColVal->value.type = pTColumn->type;
10,549,905✔
526
    pColVal->flag = CV_FLAG_VALUE;
10,549,905✔
527
    (void)memcpy(&pColVal->value.val, &pRow->ts, sizeof(TSKEY));
10,549,905✔
528
    return 0;
10,549,905✔
529
  }
530

531
  if (pRow->flag == HAS_NONE) {
211,216,600✔
532
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,045✔
533
    return 0;
7,045✔
534
  }
535

536
  if (pRow->flag == HAS_NULL) {
211,209,555✔
537
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
65,393✔
538
    return 0;
65,393✔
539
  }
540

541
  SPrimaryKeyIndex index;
542
  uint8_t         *data = pRow->data;
211,144,162✔
543
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
246,984,408✔
544
    data += tGetPrimaryKeyIndex(data, &index);
35,840,246✔
545
  }
546

547
  if (pRow->flag >> 4) {  // KV Row
211,144,162✔
548
    SKVIdx  *pIdx = (SKVIdx *)data;
146,780,765✔
549
    uint8_t *pv = NULL;
146,780,765✔
550

551
    if (pRow->flag & KV_FLG_LIT) {
146,780,765!
552
      pv = pIdx->idx + pIdx->nCol;
147,108,132✔
UNCOV
553
    } else if (pRow->flag & KV_FLG_MID) {
×
554
      pv = pIdx->idx + (pIdx->nCol << 1);
31,241✔
555
    } else {
556
      pv = pIdx->idx + (pIdx->nCol << 2);
×
557
    }
558

559
    int16_t lidx = 0;
146,780,765✔
560
    int16_t ridx = pIdx->nCol - 1;
146,780,765✔
561
    while (lidx <= ridx) {
494,726,328✔
562
      int16_t  mid = (lidx + ridx) >> 1;
454,357,279✔
563
      uint8_t *pData = NULL;
454,357,279✔
564
      if (pRow->flag & KV_FLG_LIT) {
454,357,279✔
565
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
454,218,726✔
566
      } else if (pRow->flag & KV_FLG_MID) {
138,553!
567
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
138,553✔
568
      } else {
569
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
570
      }
571

572
      int16_t cid;
573
      pData += tGetI16v(pData, &cid);
454,357,279✔
574

575
      if (TABS(cid) == pTColumn->colId) {
454,357,279✔
576
        if (cid < 0) {
106,411,716✔
577
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
221,877✔
578
        } else {
579
          pColVal->cid = pTColumn->colId;
106,189,839✔
580
          pColVal->value.type = pTColumn->type;
106,189,839✔
581
          pColVal->flag = CV_FLAG_VALUE;
106,189,839✔
582

583
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
106,189,839!
584
            pData += tGetU32v(pData, &pColVal->value.nData);
13,907,834!
585
            if (pColVal->value.nData > 0) {
13,907,834!
586
              pColVal->value.pData = pData;
16,632,019✔
587
            } else {
588
              pColVal->value.pData = NULL;
×
589
            }
590
          } else {
591
            (void)memcpy(&pColVal->value.val, pData, pTColumn->bytes);
92,282,005✔
592
          }
593
        }
594
        return 0;
106,411,716✔
595
      } else if (TABS(cid) < pTColumn->colId) {
347,945,563✔
596
        lidx = mid + 1;
283,334,340✔
597
      } else {
598
        ridx = mid - 1;
64,611,223✔
599
      }
600
    }
601

602
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
40,369,049✔
603
  } else {  // Tuple Row
604
    uint8_t *bitmap = data;
64,363,397✔
605
    uint8_t *fixed;
606
    uint8_t *varlen;
607
    uint8_t  bit;
608

609
    if (pRow->flag == HAS_VALUE) {
64,363,397✔
610
      fixed = bitmap;
63,150,240✔
611
      bit = BIT_FLG_VALUE;
63,150,240✔
612
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
1,213,157!
613
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
614
      bit = GET_BIT2(bitmap, iCol - 1);
×
615
    } else {
616
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
1,213,157✔
617
      bit = GET_BIT1(bitmap, iCol - 1);
1,213,157✔
618

619
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
1,213,157✔
620
        if (bit) bit++;
39✔
621
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
1,213,118✔
622
        bit++;
372,108✔
623
      }
624
    }
625
    varlen = fixed + pTSchema->flen;
64,363,397✔
626

627
    if (bit == BIT_FLG_NONE) {
64,363,397✔
628
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
2✔
629
      return 0;
2✔
630
    } else if (bit == BIT_FLG_NULL) {
64,363,395✔
631
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
92,897✔
632
      return 0;
92,897✔
633
    }
634

635
    pColVal->cid = pTColumn->colId;
64,270,498✔
636
    pColVal->value.type = pTColumn->type;
64,270,498✔
637
    pColVal->flag = CV_FLAG_VALUE;
64,270,498✔
638
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
64,270,498!
639
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
2,089,429✔
640
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
4,178,858✔
641
    } else {
642
      (void)memcpy(&pColVal->value.val, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
62,181,069✔
643
    }
644
  }
645

646
  return 0;
104,639,547✔
647
}
648

649
void tRowDestroy(SRow *pRow) {
90,865,548✔
650
  if (pRow) taosMemoryFree(pRow);
90,865,548!
651
}
90,881,607✔
652

653
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
25,118,065✔
654
  SRowKey key1, key2;
655
  tRowGetKey(*(SRow **)p1, &key1);
25,118,065✔
656
  tRowGetKey(*(SRow **)p2, &key2);
25,118,065✔
657
  return tRowKeyCompare(&key1, &key2);
25,820,480✔
658
}
659
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
148✔
660
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
65✔
661
  int32_t code = 0;
65✔
662

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

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

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

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

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

688
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
268✔
689
    SColVal *pColVal = NULL;
203✔
690
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
231✔
691
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
223✔
692
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
245✔
693
        pColValT = tRowIterNext(aIter[iRow]);
22✔
694
      }
695

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

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

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

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

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

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

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

749
  int32_t iStart = 0;
13,617✔
750
  while (iStart < aRowP->size) {
4,822,672✔
751
    SRowKey key1;
752
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
4,772,397✔
753

754
    tRowGetKey(row1, &key1);
4,759,866✔
755

756
    int32_t iEnd = iStart + 1;
4,764,430✔
757
    while (iEnd < aRowP->size) {
4,767,843✔
758
      SRowKey key2;
759
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
4,721,861✔
760
      tRowGetKey(row2, &key2);
4,752,699✔
761

762
      if (tRowKeyCompare(&key1, &key2) != 0) break;
4,766,486✔
763

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

767
    if (iEnd - iStart > 1) {
4,809,055✔
768
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
65✔
769
      if (code) return code;
65!
770
    }
771

772
    // the array is also changing, so the iStart just ++ instead of iEnd
773
    iStart++;
4,809,055✔
774
  }
775

776
  return code;
50,275✔
777
}
778

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

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

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

802
  int32_t code = 0;
194,692✔
803

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

810
  pIter->pRow = pRow;
194,721✔
811
  pIter->pTSchema = pTSchema;
194,721✔
812
  pIter->iTColumn = 0;
194,721✔
813

814
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
194,721!
815

816
  uint8_t         *data = pRow->data;
194,716✔
817
  SPrimaryKeyIndex index;
818
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
194,751✔
819
    data += tGetPrimaryKeyIndex(data, &index);
35✔
820
  }
821

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

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

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

874
SColVal *tRowIterNext(SRowIter *pIter) {
4,861,760✔
875
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
4,861,760✔
876
    return NULL;
194,564✔
877
  }
878

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

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

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

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

900
  if (pIter->pRow->flag >> 4) {  // KV
4,472,525✔
901
    if (pIter->iCol < pIter->pIdx->nCol) {
4,464,808✔
902
      uint8_t *pData;
903

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

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

915
      if (TABS(cid) == pTColumn->colId) {
2,605,772✔
916
        if (cid < 0) {
2,605,683✔
917
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
15✔
918
        } else {
919
          pIter->cv.cid = pTColumn->colId;
2,605,668✔
920
          pIter->cv.value.type = pTColumn->type;
2,605,668✔
921
          pIter->cv.flag = CV_FLAG_VALUE;
2,605,668✔
922

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

935
        pIter->iCol++;
2,605,683✔
936
        goto _exit;
2,605,683✔
937
      } else if (TABS(cid) > pTColumn->colId) {
89✔
938
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
12✔
939
        goto _exit;
12✔
940
      } else {
941
        uError("unexpected column id %d, %d", cid, pTColumn->colId);
77!
942
        goto _exit;
×
943
      }
944
    } else {
945
      pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1,859,036✔
946
      goto _exit;
1,859,036✔
947
    }
948
  } else {  // Tuple
949
    uint8_t bv = BIT_FLG_VALUE;
7,717✔
950
    if (pIter->pb) {
7,717✔
951
      switch (pIter->pRow->flag) {
46!
UNCOV
952
        case (HAS_NULL | HAS_NONE):
×
UNCOV
953
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
×
UNCOV
954
          break;
×
955
        case (HAS_VALUE | HAS_NONE):
6✔
956
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
6✔
957
          if (bv) bv++;
6!
958
          break;
6✔
959
        case (HAS_VALUE | HAS_NULL):
40✔
960
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
40✔
961
          break;
40✔
962
        case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
963
          bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1);
×
964
          break;
×
965
        default:
×
966
          break;
×
967
      }
968

969
      if (bv == BIT_FLG_NONE) {
46!
UNCOV
970
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
UNCOV
971
        goto _exit;
×
972
      } else if (bv == BIT_FLG_NULL) {
46✔
973
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
10✔
974
        goto _exit;
10✔
975
      }
976
    }
977

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

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

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

1003
  if (flag) return code;
255!
1004

1005
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
3,187✔
1006
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
2,931✔
1007
    if (code) return code;
2,932!
1008
  }
1009

1010
  return code;
256✔
1011
}
1012
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
13,092✔
1013
  int32_t code = 0;
13,092✔
1014

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

1020
  while (pColData) {
127,948✔
1021
    if (pTColumn) {
114,891!
1022
      if (pTColumn->colId == pColData->cid) {  // NULL
114,891✔
1023
        if (flag == 0) {
114,873✔
1024
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
114,781✔
1025
        } else {
1026
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
92✔
1027
        }
1028
        if (code) goto _exit;
114,838!
1029

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

1044
_exit:
13,057✔
1045
  return code;
13,057✔
1046
}
1047
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
16,311,464✔
1048
                                      int32_t flag) {
1049
  int32_t code = 0;
16,311,464✔
1050

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

1056
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
16,311,464✔
1057
  SPrimaryKeyIndex index;
1058
  uint8_t         *data = pRow->data;
16,311,464✔
1059
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
19,846,269✔
1060
    data += tGetPrimaryKeyIndex(data, &index);
3,534,805✔
1061
  }
1062

1063
  switch (pRow->flag) {
16,311,464!
1064
    case HAS_VALUE:
16,315,076✔
1065
      pf = data;  // TODO: fix here
16,315,076✔
1066
      pv = pf + pTSchema->flen;
16,315,076✔
1067
      break;
16,315,076✔
1068
    case (HAS_NULL | HAS_NONE):
×
1069
      pb = data;
×
1070
      break;
×
1071
    case (HAS_VALUE | HAS_NONE):
484✔
1072
    case (HAS_VALUE | HAS_NULL):
1073
      pb = data;
484✔
1074
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
484✔
1075
      pv = pf + pTSchema->flen;
484✔
1076
      break;
484✔
1077
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1078
      pb = data;
×
1079
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1080
      pv = pf + pTSchema->flen;
×
1081
      break;
×
1082
    default:
×
1083
      return TSDB_CODE_INVALID_DATA_FMT;
×
1084
  }
1085

1086
  while (pColData) {
59,702,114✔
1087
    if (pTColumn) {
43,347,207✔
1088
      if (pTColumn->colId == pColData->cid) {
43,347,025!
1089
        if (!(pTColumn->type == pColData->type)) {
43,400,766!
1090
          return TSDB_CODE_INVALID_PARA;
×
1091
        }
1092
        if (pb) {
43,400,766✔
1093
          uint8_t bv;
1094
          switch (pRow->flag) {
1,205!
1095
            case (HAS_NULL | HAS_NONE):
×
1096
              bv = GET_BIT1(pb, iTColumn - 1);
×
1097
              break;
×
1098
            case (HAS_VALUE | HAS_NONE):
×
1099
              bv = GET_BIT1(pb, iTColumn - 1);
×
1100
              if (bv) bv++;
×
1101
              break;
×
1102
            case (HAS_VALUE | HAS_NULL):
1,205✔
1103
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
1,205✔
1104
              break;
1,205✔
1105
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1106
              bv = GET_BIT2(pb, iTColumn - 1);
×
1107
              break;
×
UNCOV
1108
            default:
×
UNCOV
1109
              return TSDB_CODE_INVALID_DATA_FMT;
×
1110
          }
1111

1112
          if (bv == BIT_FLG_NONE) {
1,205!
1113
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
×
1114
              goto _exit;
×
1115
            goto _continue;
×
1116
          } else if (bv == BIT_FLG_NULL) {
1,205✔
1117
            if (flag == 0) {
487✔
1118
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
478✔
1119
            } else {
1120
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
9✔
1121
            }
1122
            if (code) goto _exit;
489!
1123
            goto _continue;
489✔
1124
          }
1125
        }
1126

1127
        if (IS_VAR_DATA_TYPE(pColData->type)) {
44,368,045!
1128
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
825,346!
1129
          uint32_t nData;
1130
          pData += tGetU32v(pData, &nData);
825,346✔
1131
          if (flag == 0) {
825,346!
1132
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
962,442✔
1133
          } else {
1134
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1135
          }
1136
          if (code) goto _exit;
967,766!
1137
        } else {
1138
          if (flag == 0) {
42,574,933✔
1139
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
42,500,449✔
1140
                                                                          TYPE_BYTES[pColData->type]);
42,500,449✔
1141
          } else {
1142
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
74,484✔
1143
                                                                          TYPE_BYTES[pColData->type], flag > 0);
74,484✔
1144
          }
1145
          if (code) goto _exit;
42,471,858!
1146
        }
1147

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

1163
_exit:
16,354,907✔
1164
  return code;
16,354,907✔
1165
}
1166
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
361,148✔
1167
  int32_t code = 0;
361,148✔
1168

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

1176
  // primary keys
1177
  uint8_t         *data = pRow->data;
361,148✔
1178
  SPrimaryKeyIndex index;
1179
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
361,148!
UNCOV
1180
    data += tGetPrimaryKeyIndex(data, &index);
×
1181
  }
1182

1183
  SKVIdx *pKVIdx = (SKVIdx *)data;
361,148✔
1184
  if (pRow->flag & KV_FLG_LIT) {
361,148✔
1185
    pv = pKVIdx->idx + pKVIdx->nCol;
357,475✔
1186
  } else if (pRow->flag & KV_FLG_MID) {
3,673✔
1187
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
3,600✔
1188
  } else if (pRow->flag & KV_FLG_BIG) {
73!
1189
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1190
  } else {
1191
    return TSDB_CODE_INVALID_PARA;
73✔
1192
  }
1193

1194
  while (pColData) {
8,390,864✔
1195
    if (pTColumn) {
8,039,477!
1196
      if (pTColumn->colId == pColData->cid) {
8,039,477!
1197
        while (iCol < pKVIdx->nCol) {
8,039,964✔
1198
          uint8_t *pData;
1199
          if (pRow->flag & KV_FLG_LIT) {
4,765,202✔
1200
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
4,657,685✔
1201
          } else if (pRow->flag & KV_FLG_MID) {
107,517!
1202
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
107,517✔
1203
          } else if (pRow->flag & KV_FLG_BIG) {
×
1204
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1205
          } else {
1206
            return TSDB_CODE_INVALID_DATA_FMT;
×
1207
          }
1208

1209
          int16_t cid;
1210
          pData += tGetI16v(pData, &cid);
4,765,202✔
1211

1212
          if (TABS(cid) == pTColumn->colId) {
4,765,202!
1213
            if (cid < 0) {
4,766,681✔
1214
              if (flag == 0) {
53,252✔
1215
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
53,203✔
1216
              } else {
1217
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
49✔
1218
              }
1219
              if (code) goto _exit;
50,430!
1220
            } else {
1221
              uint32_t nData;
1222
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
4,713,429!
1223
                pData += tGetU32v(pData, &nData);
719,717✔
1224
              } else {
1225
                nData = 0;
3,993,712✔
1226
              }
1227
              if (flag == 0) {
4,713,429✔
1228
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
4,676,416✔
1229
              } else {
1230
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
37,013✔
1231
              }
1232
              if (code) goto _exit;
4,707,354!
1233
            }
1234
            iCol++;
4,757,784✔
1235
            goto _continue;
4,757,784✔
1236
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
×
1237
            break;
125✔
1238
          } else {
1239
            iCol++;
×
1240
          }
1241
        }
1242

1243
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
3,274,887!
1244

1245
      _continue:
3,274,096✔
1246
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
8,031,880✔
1247
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
8,031,880✔
1248
      } else if (pTColumn->colId > pColData->cid) {
×
1249
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1250
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1251
      } else {
1252
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
1253
      }
1254
    } else {
1255
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1256
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1257
    }
1258
  }
1259

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

1271
  if (pRow->flag == HAS_NONE) {
16,704,067✔
1272
    return tRowNoneUpsertColData(aColData, nColData, flag);
255✔
1273
  } else if (pRow->flag == HAS_NULL) {
16,703,812✔
1274
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
13,102✔
1275
  } else if (pRow->flag >> 4) {  // KV row
16,690,710✔
1276
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
361,038✔
1277
  } else {  // TUPLE row
1278
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
16,329,672✔
1279
  }
1280
}
1281

1282
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
71,211,560✔
1283
  key->numOfPKs = row->numOfPKs;
71,211,560✔
1284

1285
  if (key->numOfPKs == 0) {
71,211,560!
1286
    return;
×
1287
  }
1288

1289
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1290

1291
  uint8_t *data = row->data;
71,211,560✔
1292

1293
  for (int32_t i = 0; i < row->numOfPKs; i++) {
142,415,198✔
1294
    data += tGetPrimaryKeyIndex(data, &indices[i]);
71,212,454✔
1295
  }
1296

1297
  // primary keys
1298
  for (int32_t i = 0; i < row->numOfPKs; i++) {
142,405,733✔
1299
    key->pks[i].type = indices[i].type;
71,202,989✔
1300

1301
    uint8_t *tdata = data + indices[i].offset;
71,202,989✔
1302
    if (row->flag >> 4) {
71,202,989✔
1303
      tdata += tGetI16v(tdata, NULL);
370,991✔
1304
    }
1305

1306
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
71,202,989!
1307
      key->pks[i].pData = tdata;
116,861✔
1308
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
233,722!
1309
    } else {
1310
      (void)memcpy(&key->pks[i].val, tdata, tDataTypes[indices[i].type].bytes);
71,086,128✔
1311
    }
1312
  }
1313
}
1314

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

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

1368
  return 0;
×
1369
}
1370

1371
// NOTE:
1372
// set key->numOfPKs to 0 as the smallest key with ts
1373
// set key->numOfPKs to (TD_MAX_PK_COLS + 1) as the largest key with ts
1374
FORCE_INLINE int32_t tRowKeyCompare(const SRowKey *key1, const SRowKey *key2) {
279,823,778✔
1375
  if (key1->ts < key2->ts) {
310,411,975!
1376
    return -1;
100,225,930✔
1377
  } else if (key1->ts > key2->ts) {
210,186,045!
1378
    return 1;
211,109,647✔
1379
  }
1380

UNCOV
1381
  if (key1->numOfPKs == key2->numOfPKs) {
×
1382
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
2,382,899!
1383
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
1,383,814✔
1384
      if (ret) return ret;
1,383,814!
1385
    }
1386
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1387
    return -1;
×
1388
  } else {
1389
    return 1;
×
1390
  }
1391

1392
  return 0;
999,085✔
1393
}
1394

1395
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
3,395,692✔
1396
  pDst->ts = pSrc->ts;
3,395,692✔
1397
  pDst->numOfPKs = pSrc->numOfPKs;
3,395,692✔
1398

1399
  if (pSrc->numOfPKs > 0) {
3,395,692✔
1400
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
1,545,664✔
1401
      SValue *pVal = &pDst->pks[i];
772,832✔
1402
      pVal->type = pSrc->pks[i].type;
772,832✔
1403

1404
      if (IS_NUMERIC_TYPE(pVal->type)) {
772,832!
1405
        pVal->val = pSrc->pks[i].val;
772,690✔
1406
      } else {
1407
        pVal->nData = pSrc->pks[i].nData;
142✔
1408
        (void)memcpy(pVal->pData, pSrc->pks[i].pData, pVal->nData);
142✔
1409
      }
1410
    }
1411
  }
1412
}
3,395,692✔
1413

1414
// STag ========================================
1415
static int tTagValCmprFn(const void *p1, const void *p2) {
2,233,214✔
1416
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
2,233,214✔
1417
    return -1;
882,935✔
1418
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
1,350,279✔
1419
    return 1;
641,659✔
1420
  }
1421

1422
  return 0;
708,620✔
1423
}
1424
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
118✔
1425
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
118✔
1426
}
1427

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

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

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

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

1524
  // key
1525
  if (isJson) {
378,432✔
1526
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
744✔
1527
  } else {
1528
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
756,120✔
1529
  }
1530

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

1534
  // value
1535
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
378,432!
1536
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
254,934✔
1537
  } else {
1538
    p = p ? p + n : p;
250,965✔
1539
    n += tDataTypes[pTagVal->type].bytes;
250,965✔
1540
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
250,965✔
1541
  }
1542

1543
  return n;
378,432✔
1544
}
1545
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
2,042,689✔
1546
  int32_t n = 0;
2,042,689✔
1547

1548
  // key
1549
  if (isJson) {
2,042,689✔
1550
    n += tGetCStr(p + n, &pTagVal->pKey);
2,480!
1551
  } else {
1552
    n += tGetI16v(p + n, &pTagVal->cid);
4,082,898!
1553
  }
1554

1555
  // type
1556
  n += tGetI8(p + n, &pTagVal->type);
2,042,689!
1557

1558
  // value
1559
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
2,042,689!
1560
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
561,844!
1561
  } else {
1562
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
1,761,767✔
1563
    n += tDataTypes[pTagVal->type].bytes;
1,761,767✔
1564
  }
1565

1566
  return n;
2,042,689✔
1567
}
1568

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

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

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

1586
  // sort
1587
  if (isJson) {
62,627✔
1588
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
143✔
1589
  } else {
1590
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
62,484✔
1591
  }
1592

1593
  // get size
1594
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
251,840✔
1595
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
189,221✔
1596
  }
1597
  if (szTag <= INT8_MAX) {
62,619✔
1598
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
59,265✔
1599
  } else {
1600
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
3,354✔
1601
    isLarge = 1;
3,354✔
1602
  }
1603

1604
  // build tag
1605
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
62,619✔
1606
  if ((*ppTag) == NULL) {
62,630!
UNCOV
1607
    code = terrno;
×
1608
    goto _err;
×
1609
  }
1610
  (*ppTag)->flags = 0;
62,633✔
1611
  if (isJson) {
62,633✔
1612
    (*ppTag)->flags |= TD_TAG_JSON;
143✔
1613
  }
1614
  if (isLarge) {
62,633✔
1615
    (*ppTag)->flags |= TD_TAG_LARGE;
3,357✔
1616
  }
1617
  (*ppTag)->len = szTag;
62,633✔
1618
  (*ppTag)->nTag = nTag;
62,633✔
1619
  (*ppTag)->ver = version;
62,633✔
1620

1621
  if (isLarge) {
62,633✔
1622
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
3,357✔
1623
  } else {
1624
    p = (uint8_t *)&(*ppTag)->idx[nTag];
59,276✔
1625
  }
1626
  n = 0;
62,633✔
1627
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
251,863✔
1628
    if (isLarge) {
189,244✔
1629
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
41,409✔
1630
    } else {
1631
      (*ppTag)->idx[iTag] = n;
147,835✔
1632
    }
1633
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
189,244✔
1634
  }
1635
#ifdef TD_DEBUG_PRINT_TAG
1636
  debugPrintSTag(*ppTag, __func__, __LINE__);
1637
#endif
1638

1639
  return code;
62,619✔
1640

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

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

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

1654
  char  *data = NULL;
457,868✔
1655
  int8_t typeBytes = 0;
457,868✔
1656
  if (isJson) {
457,868✔
1657
    typeBytes = CHAR_BYTES;
10✔
1658
  }
1659

1660
  if (IS_VAR_DATA_TYPE(value->type)) {
457,868!
1661
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
72,259✔
1662
    if (data == NULL) {
72,331✔
1663
      return NULL;
3✔
1664
    }
1665

1666
    if (isJson) {
72,328✔
1667
      *data = value->type;
8✔
1668
    }
1669

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

1676
  return data;
457,937✔
1677
}
1678

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

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

1694
  if (isLarge) {
716,815✔
1695
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
484,367✔
1696
  } else {
1697
    p = (uint8_t *)&pTag->idx[pTag->nTag];
232,448✔
1698
  }
1699

1700
  pTagVal->type = TSDB_DATA_TYPE_NULL;
716,815✔
1701
  pTagVal->pData = NULL;
716,815✔
1702
  pTagVal->nData = 0;
716,815✔
1703
  while (lidx <= ridx) {
2,049,792✔
1704
    midx = (lidx + ridx) / 2;
2,041,352✔
1705
    if (isLarge) {
2,041,352✔
1706
      offset = ((int16_t *)pTag->idx)[midx];
1,575,078✔
1707
    } else {
1708
      offset = pTag->idx[midx];
466,274✔
1709
    }
1710

1711
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
2,041,352✔
1712
    if (isJson) {
2,041,651✔
1713
      c = tTagValJsonCmprFn(pTagVal, &tv);
16✔
1714
    } else {
1715
      c = tTagValCmprFn(pTagVal, &tv);
2,041,635✔
1716
    }
1717

1718
    if (c < 0) {
2,045,398✔
1719
      ridx = midx - 1;
692,703✔
1720
    } else if (c > 0) {
1,352,695✔
1721
      lidx = midx + 1;
640,274✔
1722
    } else {
1723
      (void)memcpy(pTagVal, &tv, sizeof(tv));
712,421✔
1724
      return true;
712,421✔
1725
    }
1726
  }
1727
  return false;
8,440✔
1728
}
1729

1730
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
182,946✔
1731
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
365,892✔
1732
}
1733

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

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

1743
  if (isLarge) {
617!
1744
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
×
1745
  } else {
1746
    p = (uint8_t *)&pTag->idx[pTag->nTag];
617✔
1747
  }
1748

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

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

1768
  return code;
617✔
1769

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

1774
// STSchema ========================================
1775
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
1,311,930✔
1776
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
1,311,930✔
1777
  if (pTSchema == NULL) {
1,312,125!
1778
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1779
    return NULL;
5✔
1780
  }
1781

1782
  pTSchema->numOfCols = numOfCols;
1,312,138✔
1783
  pTSchema->version = version;
1,312,138✔
1784

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

1800
  // other columns
1801
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
28,458,932✔
1802
    SSchema  *pSchema = &aSchema[iCol];
27,146,794✔
1803
    STColumn *pTColumn = &pTSchema->columns[iCol];
27,146,794✔
1804

1805
    pTColumn->colId = pSchema->colId;
27,146,794✔
1806
    pTColumn->type = pSchema->type;
27,146,794✔
1807
    pTColumn->flags = pSchema->flags;
27,146,794✔
1808
    pTColumn->offset = pTSchema->flen;
27,146,794✔
1809

1810
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
27,146,794!
1811
      pTColumn->bytes = pSchema->bytes;
4,128,371✔
1812
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
4,128,371✔
1813
    } else {
1814
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
23,018,423✔
1815
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
23,018,423✔
1816
    }
1817

1818
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
27,146,794✔
1819
  }
1820

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

1825
  return pTSchema;
1,312,138✔
1826
}
1827

1828
static int32_t tTColumnCompare(const void *p1, const void *p2) {
64,304✔
1829
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
64,304✔
1830
    return -1;
9,447✔
1831
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
54,857✔
1832
    return 1;
38,848✔
1833
  }
1834

1835
  return 0;
16,009✔
1836
}
1837

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

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

1846
// SColData ========================================
1847
void tColDataDestroy(void *ph) {
253,860✔
1848
  if (ph) {
253,860!
1849
    SColData *pColData = (SColData *)ph;
253,860✔
1850

1851
    tFree(pColData->pBitMap);
253,860✔
1852
    tFree(pColData->aOffset);
253,860✔
1853
    tFree(pColData->pData);
253,859✔
1854
  }
1855
}
253,866✔
1856

1857
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
309,160✔
1858
  pColData->cid = cid;
309,160✔
1859
  pColData->type = type;
309,160✔
1860
  pColData->cflag = cflag;
309,160✔
1861
  tColDataClear(pColData);
309,160✔
1862
}
309,164✔
1863

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

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

1878
  tColDataClear(pColData);
1,540✔
1879
}
1,540✔
1880

1881
static FORCE_INLINE int32_t tColDataPutValue(SColData *pColData, uint8_t *pData, uint32_t nData) {
1882
  int32_t code = 0;
90,857,921✔
1883

1884
  if (IS_VAR_DATA_TYPE(pColData->type)) {
90,121,509!
1885
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
1,316,711!
1886
    if (code) goto _exit;
1,942,103!
1887
    pColData->aOffset[pColData->nVal] = pColData->nData;
1,942,103✔
1888

1889
    if (nData) {
1,942,103!
1890
      code = tRealloc(&pColData->pData, pColData->nData + nData);
1,939,939!
1891
      if (code) goto _exit;
1,947,664!
1892
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
1,947,664✔
1893
      pColData->nData += nData;
1,947,664✔
1894
    }
1895
  } else {
1896
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
89,541,210!
1897
      return TSDB_CODE_INVALID_PARA;
×
1898
    }
1899
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
89,541,210!
1900
    if (code) goto _exit;
89,550,071!
1901
    if (pData) {
89,550,071!
1902
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
89,258,552✔
1903
    } else {
1904
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
291,519✔
1905
    }
1906
    pColData->nData += tDataTypes[pColData->type].bytes;
89,550,071✔
1907
  }
1908
  pColData->nVal++;
91,499,899✔
1909

1910
_exit:
91,499,899✔
1911
  return code;
91,499,899✔
1912
}
1913
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
89,914✔
1914
  pColData->flag = HAS_VALUE;
89,922✔
1915
  pColData->numOfValue++;
89,914✔
1916
  return tColDataPutValue(pColData, pData, nData);
89,936✔
1917
}
1918
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
39,076✔
1919
  pColData->flag = HAS_NONE;
39,076✔
1920
  pColData->numOfNone++;
39,076✔
1921
  pColData->nVal++;
39,076✔
1922
  return 0;
39,076✔
1923
}
1924
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,177✔
1925
  pColData->flag = HAS_NULL;
1,179✔
1926
  pColData->numOfNull++;
1,179✔
1927
  pColData->nVal++;
1,179✔
1928
  return 0;
1,177✔
1929
}
1930
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
241✔
1931
  int32_t code = 0;
241✔
1932

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

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

1940
  pColData->flag |= HAS_VALUE;
241✔
1941
  pColData->numOfValue++;
241✔
1942

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

1957
  return tColDataPutValue(pColData, pData, nData);
242✔
1958
}
1959
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
4,540,801✔
1960
  pColData->nVal++;
4,540,801✔
1961
  pColData->numOfNone++;
4,540,801✔
1962
  return 0;
4,540,801✔
1963
}
1964
static FORCE_INLINE int32_t tColDataAppendValue12(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
1965
  int32_t code = 0;
×
1966

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

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

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

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

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

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

1990
  pColData->flag |= HAS_VALUE;
216✔
1991
  pColData->numOfValue++;
216✔
1992

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

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

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

2016
  memset(pColData->pBitMap, 255, nBit);
×
2017
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2018

2019
  pColData->flag |= HAS_NONE;
×
2020
  pColData->numOfNone++;
×
2021
  pColData->nVal++;
×
2022

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

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

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

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

2045
  tFree(pColData->pBitMap);
×
2046
  pColData->pBitMap = pBitMap;
×
2047

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

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

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

2070
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2071
  pColData->numOfNone++;
×
2072
  pColData->nVal++;
×
2073

2074
  return code;
×
2075
}
2076
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2077
  int32_t code = 0;
×
2078

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

2082
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
2083
  pColData->numOfNull++;
×
2084
  pColData->nVal++;
×
2085

2086
  return code;
×
2087
}
2088
static FORCE_INLINE int32_t tColDataAppendValue40(SColData *pColData, uint8_t *pData, uint32_t nData) {
90,525,619✔
2089
  pColData->numOfValue++;
90,525,619✔
2090
  return tColDataPutValue(pColData, pData, nData);
91,167,124✔
2091
}
2092
static FORCE_INLINE int32_t tColDataAppendValue41(SColData *pColData, uint8_t *pData, uint32_t nData) {
81✔
2093
  int32_t code = 0;
81✔
2094

2095
  pColData->flag |= HAS_NONE;
81✔
2096
  pColData->numOfNone++;
81✔
2097

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

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

2105
  return tColDataPutValue(pColData, NULL, 0);
81✔
2106
}
2107
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
523✔
2108
  int32_t code = 0;
524✔
2109

2110
  pColData->flag |= HAS_NULL;
524✔
2111
  pColData->numOfNull++;
524✔
2112

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

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

2120
  return tColDataPutValue(pColData, NULL, 0);
524✔
2121
}
2122
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
39,992✔
2123
  int32_t code = 0;
39,993✔
2124

2125
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
39,992!
2126
  if (code) return code;
40,021!
2127

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

2131
  return tColDataPutValue(pColData, pData, nData);
40,409✔
2132
}
2133
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
58,393✔
2134
  int32_t code = 0;
58,393✔
2135

2136
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
58,393!
2137
  if (code) return code;
58,393!
2138

2139
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
58,393✔
2140
  pColData->numOfNone++;
58,393✔
2141

2142
  return tColDataPutValue(pColData, NULL, 0);
58,404✔
2143
}
2144
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
1✔
2145
  int32_t code = 0;
1✔
2146

2147
  pColData->flag |= HAS_NULL;
1✔
2148
  pColData->numOfNull++;
1✔
2149

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

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

2159
  tFree(pColData->pBitMap);
1!
2160
  pColData->pBitMap = pBitMap;
1!
2161

2162
  return tColDataPutValue(pColData, NULL, 0);
1✔
2163
}
2164
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
19,167✔
2165
  int32_t code = 0;
19,176✔
2166

2167
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
19,176!
2168
  if (code) return code;
19,160!
2169
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
19,160!
2170
  pColData->numOfValue++;
19,160!
2171

2172
  return tColDataPutValue(pColData, pData, nData);
19,198✔
2173
}
2174
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
1✔
2175
  int32_t code = 0;
1✔
2176

2177
  pColData->flag |= HAS_NONE;
1✔
2178
  pColData->numOfNone++;
1✔
2179

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

2184
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
7✔
2185
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
6✔
2186
  }
2187
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
1!
2188

2189
  tFree(pColData->pBitMap);
1!
2190
  pColData->pBitMap = pBitMap;
1!
2191

2192
  return tColDataPutValue(pColData, NULL, 0);
1✔
2193
}
2194
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
18,229✔
2195
  int32_t code = 0;
18,257✔
2196

2197
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
18,257!
2198
  if (code) return code;
18,317!
2199
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
18,317!
2200
  pColData->numOfNull++;
18,317!
2201

2202
  return tColDataPutValue(pColData, NULL, 0);
18,294✔
2203
}
2204
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2205
  int32_t code = 0;
×
2206

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

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

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

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

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

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

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

2255
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
6✔
2256
  pColData->numOfNone--;
6✔
2257
  pColData->nVal--;
6✔
2258
  if (pColData->numOfNone) {
6!
2259
    return tColDataAppendValue10(pColData, pData, nData);
×
2260
  } else {
2261
    pColData->flag = 0;
6✔
2262
    return tColDataAppendValue00(pColData, pData, nData);
6✔
2263
  }
2264
}
2265
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2266
  pColData->numOfNone--;
×
2267
  pColData->nVal--;
×
2268
  if (pColData->numOfNone) {
×
2269
    return tColDataAppendValue12(pColData, pData, nData);
×
2270
  } else {
2271
    pColData->flag = 0;
×
2272
    return tColDataAppendValue02(pColData, pData, nData);
×
2273
  }
2274
  return 0;
2275
}
2276
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
2✔
2277
  if (forward) {
2!
2278
    pColData->numOfNull--;
2✔
2279
    pColData->nVal--;
2✔
2280
    if (pColData->numOfNull) {
2!
2281
      return tColDataAppendValue20(pColData, pData, nData);
×
2282
    } else {
2283
      pColData->flag = 0;
2!
2284
      return tColDataAppendValue00(pColData, pData, nData);
2✔
2285
    }
2286
  }
2287
  return 0;
×
2288
}
2289
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2290
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
2291
    pColData->numOfNone--;
×
2292
    pColData->nVal--;
×
2293
    if (pColData->numOfNone) {
×
2294
      return tColDataAppendValue30(pColData, pData, nData);
×
2295
    } else {
2296
      pColData->flag = HAS_NULL;
×
2297
      return tColDataAppendValue20(pColData, pData, nData);
×
2298
    }
2299
  } else if (forward) {  // NULL ==> VALUE
×
2300
    pColData->numOfNull--;
×
2301
    pColData->nVal--;
×
2302
    if (pColData->numOfNull) {
×
2303
      return tColDataAppendValue30(pColData, pData, nData);
×
2304
    } else {
2305
      pColData->flag = HAS_NONE;
×
2306
      return tColDataAppendValue10(pColData, pData, nData);
×
2307
    }
2308
  }
2309
  return 0;
×
2310
}
2311
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2312
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
×
2313
    pColData->numOfNone--;
×
2314
    pColData->numOfNull++;
×
2315
    if (pColData->numOfNone) {
×
2316
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
2317
    } else {
2318
      pColData->flag = HAS_NULL;
×
2319
    }
2320
  }
2321
  return 0;
×
2322
}
2323
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
105,380✔
2324
  if (forward) {  // VALUE ==> VALUE
105,380!
2325
    pColData->nVal--;
105,389✔
2326
    if (IS_VAR_DATA_TYPE(pColData->type)) {
105,389!
2327
      pColData->nData = pColData->aOffset[pColData->nVal];
4,603✔
2328
    } else {
2329
      pColData->nData -= TYPE_BYTES[pColData->type];
100,786✔
2330
    }
2331
    return tColDataPutValue(pColData, pData, nData);
105,433✔
2332
  }
2333
  return 0;
×
2334
}
2335
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3✔
2336
  if (forward) {  // VALUE ==> NULL
3!
2337
    pColData->numOfValue--;
3✔
2338
    pColData->nVal--;
3✔
2339
    if (pColData->numOfValue) {
3✔
2340
      if (IS_VAR_DATA_TYPE(pColData->type)) {
1!
2341
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2342
      } else {
2343
        pColData->nData -= TYPE_BYTES[pColData->type];
1✔
2344
      }
2345
      return tColDataAppendValue42(pColData, pData, nData);
1✔
2346
    } else {
2347
      pColData->flag = 0;
2✔
2348
      pColData->nData = 0;
2✔
2349
      return tColDataAppendValue02(pColData, pData, nData);
2✔
2350
    }
2351
  }
2352
  return 0;
×
2353
}
2354
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
21✔
2355
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
21!
2356
    pColData->numOfNone--;
×
2357
    pColData->nVal--;
×
2358
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
×
2359
      pColData->nData -= TYPE_BYTES[pColData->type];
×
2360
    }
2361
    if (pColData->numOfNone) {
×
2362
      return tColDataAppendValue50(pColData, pData, nData);
×
2363
    } else {
2364
      pColData->flag = HAS_VALUE;
×
2365
      return tColDataAppendValue40(pColData, pData, nData);
×
2366
    }
2367
  } else if (forward) {  // VALUE ==> VALUE
21!
2368
    pColData->nVal--;
21✔
2369
    if (IS_VAR_DATA_TYPE(pColData->type)) {
21!
2370
      pColData->nData = pColData->aOffset[pColData->nVal];
4✔
2371
    } else {
2372
      pColData->nData -= TYPE_BYTES[pColData->type];
17✔
2373
    }
2374
    return tColDataPutValue(pColData, pData, nData);
21✔
2375
  }
2376
  return 0;
×
2377
}
2378
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
2379
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
×
2380
    pColData->numOfNone--;
×
2381
    pColData->nVal--;
×
2382
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
×
2383
      pColData->nData -= TYPE_BYTES[pColData->type];
×
2384
    }
2385
    if (pColData->numOfNone) {
×
2386
      return tColDataAppendValue52(pColData, pData, nData);
×
2387
    } else {
2388
      pColData->flag = HAS_VALUE;
×
2389
      return tColDataAppendValue42(pColData, pData, nData);
×
2390
    }
2391
  } else if (forward) {  // VALUE ==> NULL
×
2392
    pColData->numOfValue--;
×
2393
    pColData->nVal--;
×
2394
    if (pColData->numOfValue) {
×
2395
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
2396
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2397
      } else {
2398
        pColData->nData -= TYPE_BYTES[pColData->type];
×
2399
      }
2400
      return tColDataAppendValue52(pColData, pData, nData);
×
2401
    } else {
2402
      pColData->flag = HAS_NONE;
×
2403
      pColData->nData = 0;
×
2404
      return tColDataAppendValue12(pColData, pData, nData);
×
2405
    }
2406
  }
2407
  return 0;
×
2408
}
2409
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
20✔
2410
  if (forward) {
20!
2411
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
20✔
2412
      pColData->numOfNull--;
9✔
2413
      pColData->nVal--;
9✔
2414
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
9!
2415
        pColData->nData -= TYPE_BYTES[pColData->type];
6✔
2416
      }
2417
      if (pColData->numOfNull) {
9!
2418
        return tColDataAppendValue60(pColData, pData, nData);
9✔
2419
      } else {
2420
        pColData->flag = HAS_VALUE;
×
2421
        return tColDataAppendValue40(pColData, pData, nData);
×
2422
      }
2423
    } else {  // VALUE ==> VALUE
2424
      pColData->nVal--;
11✔
2425
      if (IS_VAR_DATA_TYPE(pColData->type)) {
11!
2426
        pColData->nData = pColData->aOffset[pColData->nVal];
×
2427
      } else {
2428
        pColData->nData -= TYPE_BYTES[pColData->type];
11✔
2429
      }
2430
      return tColDataPutValue(pColData, pData, nData);
11✔
2431
    }
2432
  }
2433
  return 0;
×
2434
}
2435
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
106✔
2436
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
106!
2437
    pColData->numOfValue--;
28✔
2438
    pColData->nVal--;
28✔
2439
    if (pColData->numOfValue) {
28!
2440
      if (IS_VAR_DATA_TYPE(pColData->type)) {
28!
2441
        pColData->nData = pColData->aOffset[pColData->nVal];
1✔
2442
      } else {
2443
        pColData->nData -= TYPE_BYTES[pColData->type];
27✔
2444
      }
2445
      return tColDataAppendValue62(pColData, pData, nData);
28✔
2446
    } else {
2447
      pColData->flag = HAS_NULL;
×
2448
      pColData->nData = 0;
×
2449
      return tColDataAppendValue20(pColData, pData, nData);
×
2450
    }
2451
  }
2452
  return 0;
78✔
2453
}
2454
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
1✔
2455
  int32_t code = 0;
1✔
2456

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

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

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

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

2569
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
413,828✔
2570
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
413,828✔
2571
}
413,828✔
2572
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
453,554✔
2573
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
453,554✔
2574
}
453,554✔
2575
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
×
2576
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
2577
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
×
2578
    case 0:
×
2579
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
×
2580
      break;
×
2581
    case 1:
×
2582
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
×
2583
      break;
×
2584
    default:
×
2585
      break;
×
2586
  }
2587
}
×
2588
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
66,904,189✔
2589
  SValue value = {.type = pColData->type};
66,941,415✔
2590
  if (IS_VAR_DATA_TYPE(pColData->type)) {
66,940,325!
2591
    if (iVal + 1 < pColData->nVal) {
1,267,687!
2592
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
1,322,696✔
2593
    } else {
2594
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
2595
    }
2596
    value.pData = pColData->pData + pColData->aOffset[iVal];
1,267,687✔
2597
  } else {
2598
    (void)memcpy(&value.val, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
65,673,728✔
2599
                 tDataTypes[pColData->type].bytes);
65,673,728✔
2600
  }
2601
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
66,941,415✔
2602
}
37,226✔
2603
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
52,935✔
2604
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
2605
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
52,935!
2606
    case 0:
35,487✔
2607
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
35,487✔
2608
      break;
35,487✔
2609
    case 1:
17,448✔
2610
      tColDataGetValue4(pColData, iVal, pColVal);
2611
      break;
17,448✔
2612
    default:
×
2613
      break;
×
2614
  }
2615
}
52,935✔
2616
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
30,098✔
2617
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
2618
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
30,098!
2619
    case 0:
10,364✔
2620
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10,364✔
2621
      break;
10,364✔
2622
    case 1:
19,748✔
2623
      tColDataGetValue4(pColData, iVal, pColVal);
2624
      break;
19,748✔
2625
    default:
×
2626
      break;
×
2627
  }
2628
}
30,098✔
UNCOV
2629
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
×
2630
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
UNCOV
2631
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
×
UNCOV
2632
    case 0:
×
UNCOV
2633
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
×
UNCOV
2634
      break;
×
UNCOV
2635
    case 1:
×
UNCOV
2636
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
×
UNCOV
2637
      break;
×
UNCOV
2638
    case 2:
×
2639
      tColDataGetValue4(pColData, iVal, pColVal);
UNCOV
2640
      break;
×
2641
    default:
×
2642
      break;
×
2643
  }
UNCOV
2644
}
×
2645
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
2646
    NULL,               // 0
2647
    tColDataGetValue1,  // HAS_NONE
2648
    tColDataGetValue2,  // HAS_NULL
2649
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
2650
    tColDataGetValue4,  // HAS_VALUE
2651
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
2652
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
2653
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
2654
};
2655
void tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
67,806,080✔
2656
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
67,806,080✔
2657
}
68,150,314✔
2658

2659
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
252,806✔
2660
  switch (pColData->flag) {
252,806!
2661
    case HAS_NONE:
×
2662
      return 0;
×
2663
    case HAS_NULL:
×
2664
      return 1;
×
2665
    case (HAS_NULL | HAS_NONE):
×
2666
      return GET_BIT1(pColData->pBitMap, iVal);
×
2667
    case HAS_VALUE:
×
2668
      return 2;
×
2669
    case (HAS_VALUE | HAS_NONE):
147,077✔
2670
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
147,077✔
2671
    case (HAS_VALUE | HAS_NULL):
105,729✔
2672
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
105,729✔
UNCOV
2673
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
UNCOV
2674
      return GET_BIT2(pColData->pBitMap, iVal);
×
2675
    default:
×
2676
      return 0;
×
2677
  }
2678
}
2679

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

2683
  *pColData = *pColDataFrom;
18✔
2684

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

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

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

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

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

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

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

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

2756
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
82,296!
2757
    return 0;
752✔
2758
  }
2759

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

2765
  // bitmap
2766
  if (colData->flag != HAS_VALUE) {
81,544✔
2767
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
984✔
2768
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
1✔
2769
    } else {
2770
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
983✔
2771
    }
2772

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

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

2785
    info->bitmapCompressedSize = cinfo.compressedSize;
985✔
2786
  }
2787

2788
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
81,545!
2789
    tBufferDestroy(&local);
2790
    return 0;
×
2791
  }
2792

2793
  // offset
2794
  if (IS_VAR_DATA_TYPE(colData->type)) {
81,545!
2795
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
9,689✔
2796

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

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

2809
    info->offsetCompressedSize = cinfo.compressedSize;
9,677✔
2810
  }
2811

2812
  // data
2813
  if (colData->nData > 0) {
81,533✔
2814
    info->dataOriginalSize = colData->nData;
81,532✔
2815

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

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

2828
    info->dataCompressedSize = cinfo.compressedSize;
81,558✔
2829
  }
2830

2831
  tBufferDestroy(&local);
2832
  return 0;
81,559✔
2833
}
2834

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

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

2845
  tColDataClear(colData);
160,930✔
2846
  colData->cid = info->columnId;
160,921✔
2847
  colData->type = info->dataType;
160,921✔
2848
  colData->cflag = info->columnFlag;
160,921✔
2849
  colData->nVal = info->numOfData;
160,921✔
2850
  colData->flag = info->flag;
160,921✔
2851

2852
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
160,921✔
2853
    goto _exit;
16,459✔
2854
  }
2855

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

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

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

2877
    data += cinfo.compressedSize;
706✔
2878
  }
2879

2880
  if (info->flag == (HAS_NONE | HAS_NULL)) {
144,461!
2881
    goto _exit;
×
2882
  }
2883

2884
  // offset
2885
  if (info->offsetOriginalSize > 0) {
144,461✔
2886
    SCompressInfo cinfo = {
20,340✔
2887
        .cmprAlg = info->cmprAlg,
20,340✔
2888
        .dataType = TSDB_DATA_TYPE_INT,
2889
        .originalSize = info->offsetOriginalSize,
20,340✔
2890
        .compressedSize = info->offsetCompressedSize,
20,340✔
2891
    };
2892

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

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

2905
    data += cinfo.compressedSize;
20,341✔
2906
  }
2907

2908
  // data
2909
  if (info->dataOriginalSize > 0) {
144,462!
2910
    colData->nData = info->dataOriginalSize;
144,462✔
2911

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

2919
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
144,462!
2920
    if (code) {
144,460✔
2921
      tBufferDestroy(&local);
2922
      return code;
5✔
2923
    }
2924

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

2931
    data += cinfo.compressedSize;
144,438✔
2932
  }
2933

UNCOV
2934
_exit:
×
2935
  switch (colData->flag) {
160,897✔
2936
    case HAS_NONE:
16,012✔
2937
      colData->numOfNone = colData->nVal;
16,012✔
2938
      break;
16,012✔
2939
    case HAS_NULL:
448✔
2940
      colData->numOfNull = colData->nVal;
448✔
2941
      break;
448✔
2942
    case HAS_VALUE:
143,728✔
2943
      colData->numOfValue = colData->nVal;
143,728✔
2944
      break;
143,728✔
2945
    default:
709✔
2946
      for (int32_t i = 0; i < colData->nVal; i++) {
209,061✔
2947
        uint8_t bitValue = tColDataGetBitValue(colData, i);
208,352✔
2948
        if (bitValue == 0) {
208,352✔
2949
          colData->numOfNone++;
69,917✔
2950
        } else if (bitValue == 1) {
138,435✔
2951
          colData->numOfNull++;
47,978✔
2952
        } else {
2953
          colData->numOfValue++;
90,457✔
2954
        }
2955
      }
2956
  }
2957
  tBufferDestroy(&local);
2958
  return 0;
160,897✔
2959
}
2960

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

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

3012
    if (allValue) {
182✔
3013
      // optimize (todo)
3014
      for (int32_t i = 0; i < nRows; ++i) {
243✔
3015
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
142✔
3016
      }
3017
    } else if (allNull) {
81✔
3018
      // optimize (todo)
3019
      for (int32_t i = 0; i < nRows; ++i) {
237✔
3020
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
157✔
3021
        if (code) goto _exit;
157!
3022
      }
3023
    } else {
3024
      for (int32_t i = 0; i < nRows; ++i) {
8✔
3025
        if (colDataIsNull_f(lengthOrbitmap, i)) {
7✔
3026
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
6✔
3027
          if (code) goto _exit;
6!
3028
        } else {
3029
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
1✔
3030
        }
3031
      }
3032
    }
3033
  }
3034

3035
_exit:
1✔
3036
  return code;
217✔
3037
}
3038

3039
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen) {
1,049✔
3040
  int32_t code = 0;
1,049✔
3041

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

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

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

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

3107
_exit:
27✔
3108
  return code;
1,077✔
3109
}
3110

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3358
  return code;
149✔
3359
}
3360

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

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

3372
  return code;
31✔
3373
}
3374

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

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

3387
  return code;
31✔
3388
}
3389

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

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

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

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

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

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

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

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

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

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

3452
  return TSDB_CODE_SUCCESS;
9✔
3453
}
3454

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3615
_exit:
82✔
3616
  return 0;
119✔
3617
}
3618

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

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

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

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

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

3658
  return n;
2,390✔
3659
}
3660

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

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

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

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

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

3702
  return n;
56✔
3703
}
3704

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

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

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

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

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

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

3751
  int8_t val;
3752
  if (HAS_VALUE == pColData->flag) {
457!
3753
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
86,181✔
3754
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
85,724✔
3755
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
85,724✔
3756
    }
3757
  } else {
3758
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3759
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3760
        case 0:
×
3761
        case 1:
3762
          (*numOfNull)++;
×
3763
          break;
×
3764
        case 2:
×
3765
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
×
3766
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3767
          break;
×
3768
        default:
×
3769
          break;
×
3770
      }
3771
    }
3772
  }
3773
}
457✔
3774

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

3782
  int8_t val;
3783
  if (HAS_VALUE == pColData->flag) {
493!
3784
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
205,577✔
3785
      val = ((int8_t *)pColData->pData)[iVal];
205,084✔
3786
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
205,084✔
3787
    }
3788
  } else {
3789
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3790
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3791
        case 0:
×
3792
        case 1:
3793
          (*numOfNull)++;
×
3794
          break;
×
3795
        case 2:
×
3796
          val = ((int8_t *)pColData->pData)[iVal];
×
3797
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3798
          break;
×
3799
        default:
×
3800
          break;
×
3801
      }
3802
    }
3803
  }
3804
}
493✔
3805

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

3813
  int16_t val;
3814
  if (HAS_VALUE == pColData->flag) {
493!
3815
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
205,577✔
3816
      val = ((int16_t *)pColData->pData)[iVal];
205,084✔
3817
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
205,084✔
3818
    }
3819
  } else {
3820
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3821
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3822
        case 0:
×
3823
        case 1:
3824
          (*numOfNull)++;
×
3825
          break;
×
3826
        case 2:
×
3827
          val = ((int16_t *)pColData->pData)[iVal];
×
3828
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3829
          break;
×
3830
        default:
×
3831
          break;
×
3832
      }
3833
    }
3834
  }
3835
}
493✔
3836

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

3844
  int32_t val;
3845
  if (HAS_VALUE == pColData->flag) {
8,365✔
3846
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
25,573,623✔
3847
      val = ((int32_t *)pColData->pData)[iVal];
25,565,259✔
3848
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
25,565,259✔
3849
    }
3850
  } else {
3851
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
106✔
3852
      switch (tColDataGetBitValue(pColData, iVal)) {
105!
3853
        case 0:
95✔
3854
        case 1:
3855
          (*numOfNull)++;
95✔
3856
          break;
95✔
3857
        case 2:
10✔
3858
          val = ((int32_t *)pColData->pData)[iVal];
10✔
3859
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
10!
3860
          break;
10✔
3861
        default:
×
3862
          break;
×
3863
      }
3864
    }
3865
  }
3866
}
8,365✔
3867

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

3875
  int64_t val;
3876
  if (HAS_VALUE == pColData->flag) {
2,161✔
3877
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,854,344✔
3878
      val = ((int64_t *)pColData->pData)[iVal];
3,852,195✔
3879
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
3,852,195✔
3880
    }
3881
  } else {
3882
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
44,244✔
3883
      switch (tColDataGetBitValue(pColData, iVal)) {
44,232!
3884
        case 0:
36,848✔
3885
        case 1:
3886
          (*numOfNull)++;
36,848✔
3887
          break;
36,848✔
3888
        case 2:
7,384✔
3889
          val = ((int64_t *)pColData->pData)[iVal];
7,384✔
3890
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
7,384✔
3891
          break;
7,384✔
3892
        default:
×
3893
          break;
×
3894
      }
3895
    }
3896
  }
3897
}
2,161✔
3898

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

3906
  float val;
3907
  if (HAS_VALUE == pColData->flag) {
460✔
3908
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
86,393✔
3909
      val = ((float *)pColData->pData)[iVal];
85,934✔
3910
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
85,934✔
3911
    }
3912
  } else {
3913
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
106✔
3914
      switch (tColDataGetBitValue(pColData, iVal)) {
105!
3915
        case 0:
95✔
3916
        case 1:
3917
          (*numOfNull)++;
95✔
3918
          break;
95✔
3919
        case 2:
10✔
3920
          val = ((float *)pColData->pData)[iVal];
10✔
3921
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
10!
3922
          break;
10✔
3923
        default:
×
3924
          break;
×
3925
      }
3926
    }
3927
  }
3928
}
460✔
3929

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

3937
  double val;
3938
  if (HAS_VALUE == pColData->flag) {
459!
3939
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
86,203✔
3940
      val = ((double *)pColData->pData)[iVal];
85,744✔
3941
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
85,744✔
3942
    }
3943
  } else {
3944
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3945
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3946
        case 0:
×
3947
        case 1:
3948
          (*numOfNull)++;
×
3949
          break;
×
3950
        case 2:
×
3951
          val = ((double *)pColData->pData)[iVal];
×
3952
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
×
3953
          break;
×
3954
        default:
×
3955
          break;
×
3956
      }
3957
    }
3958
  }
3959
}
459✔
3960

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

3968
  uint8_t val;
3969
  if (HAS_VALUE == pColData->flag) {
493!
3970
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
205,577✔
3971
      val = ((uint8_t *)pColData->pData)[iVal];
205,084✔
3972
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
205,084✔
3973
    }
3974
  } else {
3975
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3976
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3977
        case 0:
×
3978
        case 1:
3979
          (*numOfNull)++;
×
3980
          break;
×
3981
        case 2:
×
3982
          val = ((uint8_t *)pColData->pData)[iVal];
×
3983
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
3984
          break;
×
3985
        default:
×
3986
          break;
×
3987
      }
3988
    }
3989
  }
3990
}
493✔
3991

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

3999
  uint16_t val;
4000
  if (HAS_VALUE == pColData->flag) {
493!
4001
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
205,577✔
4002
      val = ((uint16_t *)pColData->pData)[iVal];
205,084✔
4003
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
205,084✔
4004
    }
4005
  } else {
4006
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4007
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4008
        case 0:
×
4009
        case 1:
4010
          (*numOfNull)++;
×
4011
          break;
×
4012
        case 2:
×
4013
          val = ((uint16_t *)pColData->pData)[iVal];
×
4014
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4015
          break;
×
4016
        default:
×
4017
          break;
×
4018
      }
4019
    }
4020
  }
4021
}
493✔
4022

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

4030
  uint32_t val;
4031
  if (HAS_VALUE == pColData->flag) {
493!
4032
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
205,577✔
4033
      val = ((uint32_t *)pColData->pData)[iVal];
205,084✔
4034
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
205,084✔
4035
    }
4036
  } else {
4037
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4038
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4039
        case 0:
×
4040
        case 1:
4041
          (*numOfNull)++;
×
4042
          break;
×
4043
        case 2:
×
4044
          val = ((uint32_t *)pColData->pData)[iVal];
×
4045
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4046
          break;
×
4047
        default:
×
4048
          break;
×
4049
      }
4050
    }
4051
  }
4052
}
493✔
4053

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

4061
  uint64_t val;
4062
  if (HAS_VALUE == pColData->flag) {
493!
4063
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
205,577✔
4064
      val = ((uint64_t *)pColData->pData)[iVal];
205,084✔
4065
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
205,084✔
4066
    }
4067
  } else {
4068
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4069
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4070
        case 0:
×
4071
        case 1:
4072
          (*numOfNull)++;
×
4073
          break;
×
4074
        case 2:
×
4075
          val = ((uint64_t *)pColData->pData)[iVal];
×
4076
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4077
          break;
×
4078
        default:
×
4079
          break;
×
4080
      }
4081
    }
4082
  }
4083
}
493✔
4084

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

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

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

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

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

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

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

4173
  if (valCol->numOfValues == 0) {
4,696✔
4174
    valCol->type = value->type;
48✔
4175
  }
4176

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

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

4194
  return 0;
4,696✔
4195
}
4196

4197
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
3,532,997✔
4198
  int32_t code;
4199

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

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

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

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

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

4233
  value->type = valCol->type;
7,176,588✔
4234
  if (IS_VAR_DATA_TYPE(value->type)) {
7,176,588!
4235
    int32_t       offset, nextOffset;
4236
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
58✔
4237

4238
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
58!
4239
    if (idx == valCol->numOfValues - 1) {
58!
4240
      nextOffset = tBufferGetSize(&valCol->data);
58✔
4241
    } else {
4242
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
×
4243
    }
4244
    value->nData = nextOffset - offset;
58✔
4245
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
58✔
4246
  } else {
4247
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
7,176,530✔
4248
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, &value->val));
14,353,060!
4249
  }
4250
  return 0;
7,176,588✔
4251
}
4252

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

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

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

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

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

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

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

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

4290
  info->dataOriginalSize = cinfo.originalSize;
48✔
4291
  info->dataCompressedSize = cinfo.compressedSize;
48✔
4292

4293
  return 0;
48✔
4294
}
4295

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

4300
  tValueColumnClear(valCol);
342✔
4301
  valCol->type = info->type;
342✔
4302
  // offset
4303
  if (IS_VAR_DATA_TYPE(valCol->type)) {
348!
4304
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
6✔
4305

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

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

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

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

4334
  return 0;
342✔
4335
}
4336

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

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

4351
  return 0;
48✔
4352
}
4353

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

4358
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
342!
4359
  if (fmtVer == 0) {
342!
4360
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
342!
4361
    if ((code = tBufferGetI8(reader, &info->type))) return code;
342!
4362
    if (IS_VAR_DATA_TYPE(info->type)) {
342!
4363
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
6!
4364
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
6!
4365
    } else {
4366
      info->offsetOriginalSize = 0;
336✔
4367
      info->offsetCompressedSize = 0;
336✔
4368
    }
4369
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
342!
4370
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
342!
4371
  } else {
4372
    return TSDB_CODE_INVALID_PARA;
×
4373
  }
4374

4375
  return 0;
342✔
4376
}
4377

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

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

4392
  if (info->cmprAlg == NO_COMPRESSION) {
143,919!
4393
    (void)memcpy(output, input, info->originalSize);
×
4394
    info->compressedSize = info->originalSize;
×
4395
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
162,374!
4396
    SBuffer local;
4397

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

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

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

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

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

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

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

4461
  return 0;
143,935✔
4462
}
4463

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

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

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

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

4489
    if (info->cmprAlg == TWO_STAGE_COMP) {
189,789!
4490
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
189,822✔
4491
      if (code) {
189,826✔
4492
        tBufferDestroy(&local);
4493
        return code;
1✔
4494
      }
4495
    }
4496

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

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

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

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

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

4554
  return 0;
508,540✔
4555
}
4556

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

4560
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
143,911✔
4561
  if (code) return code;
143,910!
4562

4563
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
143,910✔
4564
  if (code) return code;
143,924!
4565

4566
  output->size += info->compressedSize;
143,924✔
4567
  return 0;
143,924✔
4568
}
4569

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

4573
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
189,807✔
4574
  if (code) return code;
189,830✔
4575

4576
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
189,818✔
4577
  if (code) return code;
189,797✔
4578

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

© 2026 Coveralls, Inc