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

taosdata / TDengine / #4585

25 Jul 2025 01:12AM UTC coverage: 59.161% (+0.08%) from 59.08%
#4585

push

travis-ci

web-flow
enh: refactor some tsdb log info (#32159)

145856 of 316723 branches covered (46.05%)

Branch coverage included in aggregate %.

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

254 existing lines in 53 files now uncovered.

220043 of 301752 relevant lines covered (72.92%)

18243809.17 hits per line

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

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

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

23
enum {
24
  BLOB_ROW_KV = 0,
25
  BLOB_ROW_TUPLE = 1,
26
};
27

28
static int32_t (*tColDataAppendValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData);
29
static int32_t (*tColDataUpdateValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward);
30

31
static int32_t tRowMergeWithBlobImpl(SArray *aRowP, STSchema *pTSchema, SBlobSet *pBlob, SBlobSet *pDstBlobSet,
32
                                     int32_t iStart, int32_t iEnd, int8_t flag);
33

34
static int32_t tRowBuildTupleWithBlob2(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
35
                                       SRow **ppRow, SBlobSet *pSrcBlobSet, SBlobSet *pDstBlobSet);
36

37
static int32_t tRowBuildKVRowWithBlob2(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
38
                                       SRow **ppRow, SBlobSet *pSrcBlob, SBlobSet *pDstBlobSet);
39
// ================================
40
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson);
41

42
// SRow ========================================================================
43
#define KV_FLG_LIT ((uint8_t)0x10)
44
#define KV_FLG_MID ((uint8_t)0x20)
45
#define KV_FLG_BIG ((uint8_t)0x40)
46

47
#define BIT_FLG_NONE  ((uint8_t)0x0)
48
#define BIT_FLG_NULL  ((uint8_t)0x1)
49
#define BIT_FLG_VALUE ((uint8_t)0x2)
50

51
#pragma pack(push, 1)
52
typedef struct {
53
  int16_t nCol;
54
  uint8_t idx[];  // uint8_t * | uint16_t * | uint32_t *
55
} SKVIdx;
56
#pragma pack(pop)
57

58
#define ROW_SET_BITMAP(PB, FLAG, IDX, VAL)      \
59
  do {                                          \
60
    switch (FLAG) {                             \
61
      case (HAS_NULL | HAS_NONE):               \
62
        SET_BIT1(PB, IDX, VAL);                 \
63
        break;                                  \
64
      case (HAS_VALUE | HAS_NONE):              \
65
        SET_BIT1(PB, IDX, (VAL) ? (VAL)-1 : 0); \
66
        break;                                  \
67
      case (HAS_VALUE | HAS_NULL):              \
68
        SET_BIT1(PB, IDX, (VAL)-1);             \
69
        break;                                  \
70
      case (HAS_VALUE | HAS_NULL | HAS_NONE):   \
71
        SET_BIT2(PB, IDX, VAL);                 \
72
        break;                                  \
73
      default:                                  \
74
        break;                                  \
75
    }                                           \
76
  } while (0)
77

78
static int32_t tPutPrimaryKeyIndex(uint8_t *p, const SPrimaryKeyIndex *index) {
611,495,820✔
79
  int32_t n = 0;
611,495,820✔
80
  n += tPutI8(p ? p + n : p, index->type);
611,495,820✔
81
  n += tPutU32v(p ? p + n : p, index->offset);
611,495,820✔
82
  return n;
611,495,820✔
83
}
84

85
static int32_t tGetPrimaryKeyIndex(uint8_t *p, SPrimaryKeyIndex *index) {
2,147,483,647✔
86
  int32_t n = 0;
2,147,483,647✔
87
  n += tGetI8(p + n, &index->type);
2,147,483,647!
88
  n += tGetU32v(p + n, &index->offset);
2,147,483,647!
89
  return n;
2,147,483,647✔
90
}
91

92
static FORCE_INLINE int32_t tRowBuildScanAddNone(SRowBuildScanInfo *sinfo, const STColumn *pTColumn) {
93
  if ((pTColumn->flags & COL_IS_KEY)) return TSDB_CODE_PAR_PRIMARY_KEY_IS_NONE;
×
94
  sinfo->numOfNone++;
2,147,483,647✔
95
  return 0;
2,147,483,647✔
96
}
97

98
static FORCE_INLINE int32_t tRowBuildScanAddNull(SRowBuildScanInfo *sinfo, const STColumn *pTColumn) {
99
  if ((pTColumn->flags & COL_IS_KEY)) return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
12✔
100
  sinfo->numOfNull++;
9,249,164✔
101
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
9,249,164✔
102
  sinfo->kvPayloadSize += tPutI16v(NULL, -pTColumn->colId);
9,249,164✔
103
  return 0;
9,249,164✔
104
}
105

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

109
  if (isPK) {
2,147,483,647✔
110
    sinfo->tupleIndices[sinfo->numOfPKs].type = colVal->value.type;
210,014,973✔
111
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
210,014,973✔
112
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
210,014,973!
113
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
210,014,973✔
114
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
210,014,973✔
115
    sinfo->numOfPKs++;
210,014,973✔
116
  }
117

118
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
2,147,483,647✔
119
  if (IS_VAR_DATA_TYPE(colVal->value.type)) {
2,147,483,647!
120
    if (sinfo->hasBlob && IS_STR_DATA_BLOB(colVal->value.type)) {
479,147,079!
121
      sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)     // size
×
122
                             + BSE_SEQUECE_SIZE;                     // value
×
123
      sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
×
124
                              + tPutU32v(NULL, colVal->value.nData)  // size
×
125
                              + BSE_SEQUECE_SIZE;                    // seq offset
×
126
    } else {
127
      sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)  // size
479,147,079✔
128
                             + colVal->value.nData;               // value
479,147,079✔
129

130
      sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)            // colId
479,147,079✔
131
                              + tPutU32v(NULL, colVal->value.nData)  // size
479,147,079✔
132
                              + colVal->value.nData;                 // value
479,147,079✔
133
    }
134
  } else {
135
    sinfo->kvPayloadSize += tPutI16v(NULL, colVal->cid)              // colId
2,147,483,647✔
136
                            + tDataTypes[colVal->value.type].bytes;  // value
2,147,483,647✔
137
  }
138
  sinfo->numOfValue++;
2,147,483,647✔
139
}
2,147,483,647✔
140

141
static int32_t tRowBuildScan(SArray *colVals, const STSchema *schema, SRowBuildScanInfo *sinfo) {
1,033,531,172✔
142
  int32_t  code = 0;
1,033,531,172✔
143
  int32_t  colValIndex = 1;
1,033,531,172✔
144
  int32_t  numOfColVals = TARRAY_SIZE(colVals);
1,033,531,172✔
145
  SColVal *colValArray = (SColVal *)TARRAY_DATA(colVals);
1,033,531,172✔
146

147
  if (!(numOfColVals > 0)) {
1,033,531,172!
148
    return TSDB_CODE_INVALID_PARA;
×
149
  }
150
  if (!(colValArray[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
1,033,531,172!
151
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
152
  }
153
  if (!(colValArray[0].value.type == TSDB_DATA_TYPE_TIMESTAMP)) {
1,033,531,172!
154
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
155
  }
156

157
  *sinfo = (SRowBuildScanInfo){.tupleFixedSize = schema->flen, .hasBlob = sinfo->hasBlob, .scanType = sinfo->scanType};
1,033,531,172✔
158

159
  // loop scan
160
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
161
    for (;;) {
162
      if (colValIndex >= numOfColVals) {
2,147,483,647✔
163
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
680!
164
        break;
340✔
165
      }
166

167
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647✔
168
        if (!(colValArray[colValIndex].value.type == schema->columns[i].type)) {
2,147,483,647!
169
          code = TSDB_CODE_INVALID_PARA;
×
170
          goto _exit;
×
171
        }
172

173
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {
2,147,483,647✔
174
          tRowBuildScanAddValue(sinfo, &colValArray[colValIndex], schema->columns + i);
2,147,483,647✔
175
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {
2,147,483,647✔
176
          if ((code = tRowBuildScanAddNull(sinfo, schema->columns + i))) goto _exit;
18,498,352✔
177
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {
2,147,483,647!
178
          if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
2,147,483,647!
179
        }
180

181
        colValIndex++;
2,147,483,647✔
182
        break;
2,147,483,647✔
183
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {
8,396,624✔
184
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
472!
185
        break;
236✔
186
      } else {  // skip useless value
187
        colValIndex++;
8,396,388✔
188
      }
189
    }
190
  }
191

192
  if (sinfo->numOfNone) {
1,033,531,160✔
193
    sinfo->flag |= HAS_NONE;
346,733,634✔
194
  }
195
  if (sinfo->numOfNull) {
1,033,531,160✔
196
    sinfo->flag |= HAS_NULL;
8,258,947✔
197
  }
198
  if (sinfo->numOfValue) {
1,033,531,160✔
199
    sinfo->flag |= HAS_VALUE;
994,306,934✔
200
  }
201

202
  // Tuple
203
  sinfo->tupleFlag = sinfo->flag;
1,033,531,160✔
204
  switch (sinfo->flag) {
1,033,531,160!
205
    case HAS_NONE:
42,793,669✔
206
    case HAS_NULL:
207
      sinfo->tupleBitmapSize = 0;
42,793,669✔
208
      sinfo->tupleFixedSize = 0;
42,793,669✔
209
      break;
42,793,669✔
210
    case HAS_VALUE:
684,326,042✔
211
      sinfo->tupleBitmapSize = 0;
684,326,042✔
212
      sinfo->tupleFixedSize = schema->flen;
684,326,042✔
213
      break;
684,326,042✔
214
    case (HAS_NONE | HAS_NULL):
18,392✔
215
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
18,392✔
216
      sinfo->tupleFixedSize = 0;
18,392✔
217
      break;
18,392✔
218
    case (HAS_NONE | HAS_VALUE):
311,451,794✔
219
    case (HAS_NULL | HAS_VALUE):
220
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
311,451,794✔
221
      sinfo->tupleFixedSize = schema->flen;
311,451,794✔
222
      break;
311,451,794✔
223
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
345,315✔
224
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
345,315✔
225
      sinfo->tupleFixedSize = schema->flen;
345,315✔
226
      break;
345,315✔
227
  }
228
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,241,614,284✔
229
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
208,819,848✔
230
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
208,819,848✔
231
  }
232
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
1,032,794,436✔
233
                        + sinfo->tuplePKSize      // primary keys
1,032,794,436✔
234
                        + sinfo->tupleBitmapSize  // bitmap
1,032,794,436✔
235
                        + sinfo->tupleFixedSize   // fixed part
1,032,794,436✔
236
                        + sinfo->tupleVarSize;    // var part
1,032,794,436✔
237

238
  // Key-Value
239
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
1,032,794,436!
240
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
1,033,402,308✔
241
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
1,033,402,308✔
UNCOV
242
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
243
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
4,879,509✔
244
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
4,879,509✔
245
  } else {
246
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
247
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
248
  }
249
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
1,240,551,070✔
250
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
207,808,600✔
251
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
207,808,600✔
252
  }
253
  sinfo->kvRowSize = sizeof(SRow)             // SRow
1,032,742,470✔
254
                     + sinfo->kvPKSize        // primary keys
1,032,742,470✔
255
                     + sinfo->kvIndexSize     // index array
1,032,742,470✔
256
                     + sinfo->kvPayloadSize;  // payload
1,032,742,470✔
257

258
_exit:
1,032,742,482✔
259
  return code;
1,032,742,482✔
260
}
261

262
static int32_t tRowBuildTupleRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
732,537,375✔
263
                                 SRow **ppRow) {
264
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
732,537,375✔
265
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
732,537,375!
266
  if (*ppRow == NULL) {
739,597,638!
267
    return terrno;
×
268
  }
269
  (*ppRow)->flag = sinfo->tupleFlag;
739,597,638✔
270
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
739,597,638✔
271
  (*ppRow)->sver = schema->version;
739,597,638✔
272
  (*ppRow)->len = sinfo->tupleRowSize;
739,597,638✔
273
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
739,597,638✔
274

275
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
739,597,638!
276
    return 0;
42,318,157✔
277
  }
278

279
  uint8_t *primaryKeys = (*ppRow)->data;
697,279,481✔
280
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
697,279,481✔
281
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
697,279,481✔
282
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
697,279,481✔
283

284
  // primary keys
285
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
907,391,267✔
286
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
213,383,442✔
287
  }
288

289
  // bitmap + fixed + varlen
290
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
694,007,825✔
291
  int32_t colValIndex = 1;
694,007,825✔
292
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
293
    for (;;) {
294
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647✔
295
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
16!
296
        break;
16✔
297
      }
298

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

303
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
304
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
98,513,517✔
305
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
98,513,517✔
306
            if (colValArray[colValIndex].value.nData) {
98,513,517!
307
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
99,913,336✔
308
              varlen += colValArray[colValIndex].value.nData;
99,913,336✔
309
            }
310
          } else {
311
            (void)memcpy(fixed + schema->columns[i].offset,
2,147,483,647✔
312
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
2,147,483,647!
313
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647✔
314
          }
315
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
8,146,532✔
316
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
8,108,670!
317
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
37,862!
318
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
339,718!
319
        }
320

321
        colValIndex++;
2,147,483,647✔
322
        break;
2,147,483,647✔
323
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
324
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
8!
325
        break;
8✔
326
      } else {
327
        colValIndex++;
×
328
      }
329
    }
330
  }
331

332
  return 0;
694,007,825✔
333
}
334

335
static int32_t addEmptyItemToBlobSet(SBlobSet *pBlobSet, int8_t type, uint64_t *pSeq) {
×
336
  SBlobItem item = {.type = type, .len = 0};
×
337
  uint64_t  seq = 0;
×
338
  int32_t   code = tBlobSetPush(pBlobSet, &item, &seq, 0);
×
339
  if (code != 0) return code;
×
340

341
  if (pSeq != NULL) {
×
342
    *pSeq = seq;
×
343
  }
344
  return 0;
×
345
}
346
static int32_t tRowBuildTupleWithBlob(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
×
347
                                      SRow **ppRow, SBlobSet *pBlobSet) {
348
  int32_t  code = 0;
×
349
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
×
350
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
×
351
  if (*ppRow == NULL) {
×
352
    return terrno;
×
353
  }
354
  (*ppRow)->flag = sinfo->tupleFlag;
×
355
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
×
356
  (*ppRow)->sver = schema->version;
×
357
  (*ppRow)->len = sinfo->tupleRowSize;
×
358
  (*ppRow)->ts = colValArray[0].value.val;
×
359

360
  if (((*ppRow)->flag) == 0) {
×
361
    return TSDB_CODE_INVALID_PARA;
×
362
  }
363
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
×
364
    code = addEmptyItemToBlobSet(pBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
365
    return code;
×
366
  }
367

368
  uint8_t *primaryKeys = (*ppRow)->data;
×
369
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
×
370
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
×
371
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
×
372
  uint8_t *start = varlen;
×
373

374
  // primary keys
375
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
×
376
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
×
377
  }
378

379
  // bitmap + fixed + varlen
380
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
×
381
  int32_t colValIndex = 1;
×
382
  int8_t  firstBlobCol = 1;
×
383
  for (int32_t i = 1; i < schema->numOfCols; i++) {
×
384
    for (;;) {
×
385
      if (colValIndex >= numOfColVals) {  // NONE
×
386
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
387
        break;
×
388
      }
389

390
      int8_t hasBlob = 0;
×
391
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
×
392
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
×
393
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_VALUE);
×
394

395
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
×
396
            if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
397
              hasBlob = 1;
×
398
            }
399
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
×
400
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
×
401
            if (colValArray[colValIndex].value.nData) {
×
402
              if (hasBlob == 0) {
×
403
                (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
×
404
                varlen += colValArray[colValIndex].value.nData;
×
405
              } else {
406
                uint64_t  seq = 0;
×
407
                SBlobItem item = {.seqOffsetInRow = varlen - (*ppRow)->data,
×
408
                                  .data = colValArray[colValIndex].value.pData,
×
409
                                  .len = colValArray[colValIndex].value.nData,
×
410
                                  .type = TSDB_DATA_BLOB_VALUE};
411
                code = tBlobSetPush(pBlobSet, &item, &seq, firstBlobCol);
×
412
                if (firstBlobCol == 1) {
×
413
                  firstBlobCol = 0;
×
414
                }
415
                if (code != 0) return code;
×
416
                varlen += tPutU64(varlen, seq);
×
417
              }
418
            } else {
419
              if (hasBlob) TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pBlobSet, TSDB_DATA_BLOB_EMPTY_VALUE, NULL));
×
420
            }
421
          } else {
422
            (void)memcpy(fixed + schema->columns[i].offset,
×
423
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
×
424
                         tDataTypes[schema->columns[i].type].bytes);
×
425
          }
426
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
×
427
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
×
428
          if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
429
            TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL));
×
430
          }
431
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
432
          if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
433
            TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL));
×
434
          }
435
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
436
        }
437

438
        colValIndex++;
×
439
        break;
×
440
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
441
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
442
        break;
×
443
      } else {
444
        colValIndex++;
×
445
      }
446
    }
447
  }
448

449
  if (((*ppRow)->flag) == 0) {
×
450
    return TSDB_CODE_INVALID_PARA;
×
451
  }
452

453
  return 0;
×
454
}
455

456
static int32_t tRowBuildTupleWithBlob2(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
×
457
                                       SRow **ppRow, SBlobSet *pSrcBlobSet, SBlobSet *pDstBlobSet) {
458
  int32_t  code = 0;
×
459
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
×
460
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->tupleRowSize);
×
461
  if (*ppRow == NULL) {
×
462
    return terrno;
×
463
  }
464
  (*ppRow)->flag = sinfo->tupleFlag;
×
465
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
×
466
  (*ppRow)->sver = schema->version;
×
467
  (*ppRow)->len = sinfo->tupleRowSize;
×
468
  (*ppRow)->ts = colValArray[0].value.val;
×
469

470
  if (((*ppRow)->flag) == 0) {
×
471
    return TSDB_CODE_INVALID_PARA;
×
472
  }
473
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
×
474
    code = addEmptyItemToBlobSet(pDstBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
475
    return code;
×
476
  }
477

478
  uint8_t *primaryKeys = (*ppRow)->data;
×
479
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
×
480
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
×
481
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
×
482
  uint8_t *start = varlen;
×
483

484
  // primary keys
485
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
×
486
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
×
487
  }
488

489
  // bitmap + fixed + varlen
490
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
×
491
  int32_t colValIndex = 1;
×
492
  for (int32_t i = 1; i < schema->numOfCols; i++) {
×
493
    for (;;) {
×
494
      if (colValIndex >= numOfColVals) {  // NONE
×
495
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
496
        break;
×
497
      }
498

499
      int8_t hasBlob = 0;
×
500
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
×
501
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
×
502
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_VALUE);
×
503

504
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
×
505
            if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
506
              hasBlob = 1;
×
507
            }
508
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
×
509
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
×
510
            if (colValArray[colValIndex].value.nData) {
×
511
              if (hasBlob == 0) {
×
512
                (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
×
513
                varlen += colValArray[colValIndex].value.nData;
×
514
              } else {
515
                uint64_t seq = 0;
×
516
                tGetU64(colValArray[colValIndex].value.pData, &seq);
×
517
                SBlobItem item = {0};
×
518

519
                code = tBlobSetGet(pSrcBlobSet, seq, &item);
×
520
                TAOS_CHECK_RETURN(code);
×
521

522
                code = tBlobSetPush(pDstBlobSet, &item, &seq, 0);
×
523
                TAOS_CHECK_RETURN(code);
×
524
                varlen += tPutU64(varlen, seq);
×
525
              }
526
            } else {
527
              if (hasBlob) TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pDstBlobSet, TSDB_DATA_BLOB_EMPTY_VALUE, NULL));
×
528
            }
529
          } else {
530
            (void)memcpy(fixed + schema->columns[i].offset,
×
531
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
×
532
                         tDataTypes[schema->columns[i].type].bytes);
×
533
          }
534
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
×
535
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
×
536
          if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
537
            TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pDstBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL));
×
538
          }
539
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
540
          if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
541
            TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pDstBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL));
×
542
          }
543
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
544
        }
545

546
        colValIndex++;
×
547
        break;
×
548
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
549
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
550
        break;
×
551
      } else {
552
        colValIndex++;
×
553
      }
554
    }
555
  }
556

557
  if (((*ppRow)->flag) == 0) {
×
558
    return TSDB_CODE_INVALID_PARA;
×
559
  }
560

561
  return 0;
×
562
}
563
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
564
  if (flag & KV_FLG_LIT) {
2,147,483,647✔
565
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
2,147,483,647✔
566
  } else if (flag & KV_FLG_MID) {
×
567
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
275,564✔
568
  } else {
569
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
×
570
  }
571
  indices->nCol++;
2,147,483,647✔
572
}
2,147,483,647✔
573

574
static int32_t tRowBuildKVRow(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema, SRow **ppRow) {
304,245,414✔
575
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
304,245,414✔
576

577
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
304,245,414!
578
  if (*ppRow == NULL) {
304,628,654!
579
    return terrno;
×
580
  }
581
  (*ppRow)->flag = sinfo->kvFlag;
304,628,654✔
582
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
304,628,654✔
583
  (*ppRow)->sver = schema->version;
304,628,654✔
584
  (*ppRow)->len = sinfo->kvRowSize;
304,628,654✔
585
  (*ppRow)->ts = VALUE_GET_TRIVIAL_DATUM(&colValArray[0].value);
304,628,654✔
586

587
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
304,628,654!
588
    return TSDB_CODE_INVALID_PARA;
×
589
  }
590

591
  uint8_t *primaryKeys = (*ppRow)->data;
304,664,298✔
592
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
304,664,298✔
593
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
304,664,298✔
594
  uint32_t payloadSize = 0;
304,664,298✔
595

596
  // primary keys
597
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
304,831,302✔
598
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
167,016✔
599
  }
600

601
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
304,664,286✔
602
  int32_t colValIndex = 1;
304,664,286✔
603
  for (int32_t i = 1; i < schema->numOfCols; i++) {
2,147,483,647✔
604
    for (;;) {
605
      if (colValIndex >= numOfColVals) {  // NONE
2,147,483,647✔
606
        break;
108✔
607
      }
608

609
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
2,147,483,647!
610
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
2,147,483,647✔
611
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
2,147,483,647!
612
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
2,147,483,647!
613
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
376,627,563✔
614
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
376,627,563✔
615
            if (colValArray[colValIndex].value.nData > 0) {
376,627,563!
616
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
383,713,430✔
617
                           colValArray[colValIndex].value.nData);
383,713,430✔
618
              payloadSize += colValArray[colValIndex].value.nData;
383,713,430✔
619
            }
620
          } else {
621
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
2,147,483,647✔
622
            (void)memcpy(payload + payloadSize,
2,147,483,647✔
623
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
2,147,483,647!
624
                         tDataTypes[schema->columns[i].type].bytes);
2,147,483,647!
625
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
2,147,483,647✔
626
          }
627
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
2,147,483,647✔
628
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
1,031,298✔
629
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
2,062,596✔
630
        }
631

632
        colValIndex++;
2,147,483,647✔
633
        break;
2,147,483,647✔
634
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
635
        break;
228✔
636
      } else {
637
        colValIndex++;
×
638
      }
639
    }
640
  }
641
  return 0;
304,664,286✔
642
}
643

644
static int32_t tRowBuildKVRowWithBlob(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
×
645
                                      SRow **ppRow, SBlobSet *ppBlobSet) {
646
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
×
647

648
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
×
649
  if (*ppRow == NULL) {
×
650
    return terrno;
×
651
  }
652
  (*ppRow)->flag = sinfo->kvFlag;
×
653
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
×
654
  (*ppRow)->sver = schema->version;
×
655
  (*ppRow)->len = sinfo->kvRowSize;
×
656
  (*ppRow)->ts = colValArray[0].value.val;
×
657

658
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
×
659
    return TSDB_CODE_INVALID_PARA;
×
660
  }
661

662
  if (((*ppRow)->flag) == 0) {
×
663
    return TSDB_CODE_INVALID_PARA;
×
664
  }
665

666
  uint8_t *primaryKeys = (*ppRow)->data;
×
667
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
×
668
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
×
669
  uint32_t payloadSize = 0;
×
670

671
  // primary keys
672
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
×
673
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
×
674
  }
675

676
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
×
677
  int32_t colValIndex = 1;
×
678
  int8_t  firstBlobCol = 1;
×
679
  for (int32_t i = 1; i < schema->numOfCols; i++) {
×
680
    for (;;) {
×
681
      if (colValIndex >= numOfColVals) {  // NONE
×
682
        break;
×
683
      }
684
      uint8_t hasBlob = 0;
×
685

686
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
×
687
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
×
688
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
×
689
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
×
690
            if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
691
              hasBlob = 1;
×
692
            }
693
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
×
694
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
×
695
            if (colValArray[colValIndex].value.nData > 0) {
×
696
              if (hasBlob == 0) {
×
697
                (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
×
698
                             colValArray[colValIndex].value.nData);
×
699
                payloadSize += colValArray[colValIndex].value.nData;
×
700
              } else {
701
                uint64_t  seq = 0;
×
702
                uint32_t  seqOffset = payloadSize + payload - (*ppRow)->data;
×
703
                SBlobItem item = {.seqOffsetInRow = seqOffset,
×
704
                                  .data = colValArray[colValIndex].value.pData,
×
705
                                  .len = colValArray[colValIndex].value.nData,
×
706
                                  .type = TSDB_DATA_BLOB_VALUE};
707
                int32_t   code = tBlobSetPush(ppBlobSet, &item, &seq, 0);
×
708
                if (code != 0) return code;
×
709
                payloadSize += tPutU64(payload + payloadSize, seq);
×
710
              }
711
            } else {
712
              if (hasBlob) {
×
713
                TAOS_CHECK_RETURN(addEmptyItemToBlobSet(ppBlobSet, TSDB_DATA_BLOB_EMPTY_VALUE, NULL));
×
714
              }
715
            }
716
          } else {
717
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
×
718
            (void)memcpy(payload + payloadSize, &colValArray[colValIndex].value.val,
×
719
                         tDataTypes[schema->columns[i].type].bytes);
×
720
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
×
721
          }
722
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
×
723
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
×
724
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
×
725
          if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
726
            TAOS_CHECK_RETURN(addEmptyItemToBlobSet(ppBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL));
×
727
          }
728
        }
729
        colValIndex++;
×
730
        break;
×
731
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
732
        break;
×
733
      } else {
734
        colValIndex++;
×
735
      }
736
    }
737
  }
738

739
  if (((*ppRow)->flag) == 0) {
×
740
    return TSDB_CODE_INVALID_PARA;
×
741
  }
742
  return 0;
×
743
}
744

745
static int32_t tRowBuildKVRowWithBlob2(SArray *aColVal, const SRowBuildScanInfo *sinfo, const STSchema *schema,
×
746
                                       SRow **ppRow, SBlobSet *pSrcBlobSet, SBlobSet *pDstBlobSet) {
747
  SColVal *colValArray = (SColVal *)TARRAY_DATA(aColVal);
×
748

749
  *ppRow = (SRow *)taosMemoryCalloc(1, sinfo->kvRowSize);
×
750
  if (*ppRow == NULL) {
×
751
    return terrno;
×
752
  }
753
  (*ppRow)->flag = sinfo->kvFlag;
×
754
  (*ppRow)->numOfPKs = sinfo->numOfPKs;
×
755
  (*ppRow)->sver = schema->version;
×
756
  (*ppRow)->len = sinfo->kvRowSize;
×
757
  (*ppRow)->ts = colValArray[0].value.val;
×
758

759
  if (!(sinfo->flag != HAS_NONE && sinfo->flag != HAS_NULL)) {
×
760
    return TSDB_CODE_INVALID_PARA;
×
761
  }
762

763
  if (((*ppRow)->flag) == 0) {
×
764
    return TSDB_CODE_INVALID_PARA;
×
765
  }
766

767
  uint8_t *primaryKeys = (*ppRow)->data;
×
768
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
×
769
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
×
770
  uint32_t payloadSize = 0;
×
771

772
  // primary keys
773
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
×
774
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->kvIndices + i);
×
775
  }
776

777
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
×
778
  int32_t colValIndex = 1;
×
779
  for (int32_t i = 1; i < schema->numOfCols; i++) {
×
780
    for (;;) {
×
781
      if (colValIndex >= numOfColVals) {  // NONE
×
782
        break;
×
783
      }
784
      uint8_t hasBlob = 0;
×
785

786
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
×
787
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
×
788
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
×
789
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
×
790
            if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
791
              hasBlob = 1;
×
792
            }
793
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
×
794
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
×
795
            if (colValArray[colValIndex].value.nData > 0) {
×
796
              if (hasBlob == 0) {
×
797
                (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
×
798
                             colValArray[colValIndex].value.nData);
×
799
                payloadSize += colValArray[colValIndex].value.nData;
×
800
              } else {
801
                uint64_t seq = 0;
×
802
                tGetU64(colValArray[colValIndex].value.pData, &seq);
×
803
                SBlobItem item = {0};
×
804

805
                int32_t code = tBlobSetGet(pSrcBlobSet, seq, &item);
×
806
                TAOS_CHECK_RETURN(code);
×
807

808
                code = tBlobSetPush(pDstBlobSet, &item, &seq, 0);
×
809
                TAOS_CHECK_RETURN(code);
×
810

811
                payloadSize += tPutU64(payload + payloadSize, seq);
×
812
              }
813
            } else {
814
              if (hasBlob) {
×
815
                TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pDstBlobSet, TSDB_DATA_BLOB_EMPTY_VALUE, NULL));
×
816
              }
817
            }
818
          } else {
819
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
×
820
            (void)memcpy(payload + payloadSize, &colValArray[colValIndex].value.val,
×
821
                         tDataTypes[schema->columns[i].type].bytes);
×
822
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
×
823
          }
824
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
×
825
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
×
826
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
×
827
          if (IS_STR_DATA_BLOB(schema->columns[i].type)) {
×
828
            TAOS_CHECK_RETURN(addEmptyItemToBlobSet(pDstBlobSet, TSDB_DATA_BLOB_NULL_VALUE, NULL));
×
829
          }
830
        }
831
        colValIndex++;
×
832
        break;
×
833
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
834
        break;
×
835
      } else {
836
        colValIndex++;
×
837
      }
838
    }
839
  }
840

841
  if (((*ppRow)->flag) == 0) {
×
842
    return TSDB_CODE_INVALID_PARA;
×
843
  }
844
  return 0;
×
845
}
846
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow, SRowBuildScanInfo *sinfo) {
1,033,403,139✔
847
  int32_t code;
848
  code = tRowBuildScan(aColVal, pTSchema, sinfo);
1,033,403,139✔
849
  if (code) return code;
1,037,795,232✔
850

851
  if (sinfo->tupleRowSize <= sinfo->kvRowSize) {
1,037,795,220✔
852
    code = tRowBuildTupleRow(aColVal, sinfo, pTSchema, ppRow);
734,232,021✔
853
  } else {
854
    code = tRowBuildKVRow(aColVal, sinfo, pTSchema, ppRow);
303,563,199✔
855
  }
856
  return code;
1,043,348,692✔
857
}
858

859
int32_t tBlobRowCreate(int64_t cap, int8_t type, SBlobSet **ppBlobRow) {
×
860
  int32_t    lino = 0;
×
861
  int32_t    code = 0;
×
862
  SBlobSet *p = taosMemCalloc(1, sizeof(SBlobSet));
×
863
  if (p == NULL) {
×
864
    return terrno;
×
865
  }
866

867
  p->type = type;
×
868
  p->pSeqTable = taosArrayInit(128, sizeof(SBlobValue));
×
869
  if (p->pSeqTable == NULL) {
×
870
    TAOS_CHECK_EXIT(terrno);
×
871
  }
872

873
  p->data = taosMemCalloc(1024, cap * sizeof(uint8_t));
×
874
  if (p->data == NULL) {
×
875
    TAOS_CHECK_EXIT(terrno);
×
876
  }
877

878
  p->pSeqToffset = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK);
×
879
  if (p->pSeqToffset == NULL) {
×
880
    TAOS_CHECK_EXIT(terrno);
×
881
  }
882

883
  p->pSet = taosArrayInit(4, sizeof(int32_t));
×
884
  if (p->pSet == NULL) {
×
885
    TAOS_CHECK_EXIT(terrno);
×
886
  }
887

888
  p->cap = cap;
×
889
  p->len = 0;
×
890
  p->seq = 1;
×
891

892
  *ppBlobRow = p;
×
893
_exit:
×
894
  if (code != 0) {
×
895
    taosHashCleanup(p->pSeqToffset);
×
896
    taosArrayDestroy(p->pSeqTable);
×
897
    taosArrayDestroy(p->pSet);
×
898

899
    taosMemoryFree(p->data);
×
900
    taosMemoryFree(p);
×
901
  }
902
  uDebug("create blob row %p", p);
×
903
  return code;
×
904
}
905
int32_t tBlobRowPush(SBlobSet *pBlobRow, SBlobItem *pItem, uint64_t *seq, int8_t nextRow) {
×
906
  if (pBlobRow == NULL || pItem == NULL || seq == NULL) {
×
907
    return TSDB_CODE_INVALID_PARA;
×
908
  }
909
  uTrace("push blob %p, seqOffsetInRow %d, dataLen %d, nextRow %d", pBlobRow, pItem->seqOffsetInRow, pItem->len,
×
910
         nextRow);
911
  int32_t  lino = 0;
×
912
  int32_t  code = 0;
×
913
  uint64_t offset;
914
  uint32_t len = pItem->len;
×
915
  uint8_t *data = pItem->data;
×
916
  int32_t  dataOffset = pItem->seqOffsetInRow;
×
917

918
  uint64_t tlen = pBlobRow->len + len;
×
919
  if (tlen > pBlobRow->cap) {
×
920
    int64_t cap = pBlobRow->cap;
×
921
    // opt later
922
    do {
923
      cap = cap * 2;
×
924
    } while (tlen > cap);
×
925

926
    uint8_t *data = taosMemRealloc(pBlobRow->data, cap);
×
927
    if (data == NULL) {
×
928
      return terrno;
×
929
    }
930
    pBlobRow->data = data;
×
931
    pBlobRow->cap = cap;
×
932
  }
933
  if (len > 0) {
×
934
    (void)memcpy(pBlobRow->data + pBlobRow->len, data, len);
×
935
  }
936

937
  offset = pBlobRow->len;
×
938
  pBlobRow->len += len;
×
939

940
  pBlobRow->seq++;
×
941
  *seq = pBlobRow->seq;
×
942

943
  SBlobValue value = {.offset = offset, .len = len, .dataOffset = dataOffset, .nextRow = nextRow};
×
944
  if (taosArrayPush(pBlobRow->pSeqTable, &value) == NULL) {
×
945
    TAOS_CHECK_EXIT(terrno);
×
946
  }
947

948
  int32_t sz = taosArrayGetSize(pBlobRow->pSeqTable);
×
949
  code = taosHashPut(pBlobRow->pSeqToffset, seq, sizeof(int64_t), &sz, sizeof(int32_t));
×
950
  if (code != 0) {
×
951
    TAOS_CHECK_EXIT(code);
×
952
  }
953

954
_exit:
×
955
  return code;
×
956
}
957
int32_t tBlobRowUpdate(SBlobSet *pBlobRow, uint64_t seq, SBlobItem *pItem) {
×
958
  int32_t code = 0;
×
959
  return code;
×
960
  if (pBlobRow == NULL || pItem == NULL) {
961
    return TSDB_CODE_INVALID_PARA;
962
  }
963
  if (pBlobRow->pSeqToffset == NULL || pBlobRow->pSeqTable == NULL) {
964
    return TSDB_CODE_INVALID_PARA;
965
  }
966

967
  return code;
968
}
969
int32_t tBlobRowGet(SBlobSet *pBlobRow, uint64_t seq, SBlobItem *pItem) {
×
970
  if (pBlobRow == NULL || pItem == NULL) {
×
971
    return TSDB_CODE_INVALID_PARA;
×
972
  }
973
  if (pBlobRow->pSeqToffset == NULL || pBlobRow->pSeqTable == NULL) {
×
974
    return TSDB_CODE_INVALID_PARA;
×
975
  }
976

977
  int32_t code = 0;
×
978
  int32_t len = 0;
×
979
  int32_t dataOffset = 0;
×
980
  int8_t  nextRow = 0;
×
981

982
  int32_t *offset = (int32_t *)taosHashGet(pBlobRow->pSeqToffset, &seq, sizeof(int64_t));
×
983
  if (offset == NULL) {
×
984
    return TSDB_CODE_INVALID_PARA;
×
985
  }
986

987
  SBlobValue *value = taosArrayGet(pBlobRow->pSeqTable, *offset - 1);
×
988
  if (value == NULL) {
×
989
    return TSDB_CODE_INVALID_PARA;
×
990
  }
991

992
  len = value->len;
×
993
  dataOffset = value->dataOffset;
×
994
  nextRow = value->nextRow;
×
995

996
  pItem->seqOffsetInRow = dataOffset + pBlobRow->data - (uint8_t *)pBlobRow;
×
997
  pItem->len = len;
×
998
  pItem->data = pBlobRow->data + value->offset;
×
999

1000
  return code;
×
1001
}
1002

1003
int32_t tBlobRowSize(SBlobSet *pBlobRow) {
×
1004
  if (pBlobRow == NULL) return 0;
×
1005
  return taosArrayGetSize(pBlobRow->pSeqTable);
×
1006
}
1007
int32_t tBlobRowEnd(SBlobSet *pBlobRow) {
×
1008
  if (pBlobRow == NULL) return 0;
×
1009
  int32_t sz = taosArrayGetSize(pBlobRow->pSeqTable);
×
1010
  if (taosArrayPush(pBlobRow->pSet, &sz) == NULL) {
×
1011
    return terrno;
×
1012
  }
1013
  return 0;
×
1014
}
1015
int32_t tBlobRowRebuild(SBlobSet *p, int32_t sRow, int32_t nrow, SBlobSet **pDst) {
×
1016
  int32_t code = 0;
×
1017

1018
  code = tBlobRowCreate(p->cap, p->type, pDst);
×
1019
  if (code != 0) {
×
1020
    return code;
×
1021
  }
1022

1023
  SBlobSet *pBlobRow = *pDst;
×
1024
  if (p->pSeqToffset == NULL || p->pSeqTable == NULL || p->data == NULL) {
×
1025
    return TSDB_CODE_INVALID_PARA;
×
1026
  }
1027

1028
  uint64_t seq = 0;
×
1029
  int32_t  count = 0;
×
1030
  for (int32_t i = sRow; i < taosArrayGetSize(p->pSeqTable); i++) {
×
1031
    SBlobValue *pValue = taosArrayGet(p->pSeqTable, i);
×
1032
    uint8_t    *data = p->data + pValue->offset;
×
1033
    int32_t     len = pValue->len;
×
1034

1035
    SBlobItem item = {.data = data, .len = len, .seqOffsetInRow = pValue->dataOffset};
×
1036

1037
    code = tBlobRowPush(pBlobRow, &item, &seq, pValue->nextRow);
×
1038
    count++;
×
1039
    if (count >= nrow) {
×
1040
      break;
×
1041
    }
1042
  }
1043

1044
  return code;
×
1045
}
1046

1047
int32_t tBlobRowDestroy(SBlobSet *pBlobRow) {
×
1048
  if (pBlobRow == NULL) return 0;
×
1049
  int32_t code = 0;
×
1050
  uTrace("destroy blob row, seqTable size %p", pBlobRow);
×
1051
  taosMemoryFree(pBlobRow->data);
×
1052
  taosArrayDestroy(pBlobRow->pSeqTable);
×
1053
  taosHashCleanup(pBlobRow->pSeqToffset);
×
1054
  taosArrayDestroy(pBlobRow->pSet);
×
1055
  taosMemoryFree(pBlobRow);
×
1056
  return code;
×
1057
}
1058
int32_t tBlobRowClear(SBlobSet *pBlobRow) {
×
1059
  if (pBlobRow == NULL) return 0;
×
1060
  int32_t code = 0;
×
1061
  uTrace("clear blob row, seqTable size %p", pBlobRow);
×
1062
  taosArrayClear(pBlobRow->pSeqTable);
×
1063
  taosHashClear(pBlobRow->pSeqToffset);
×
1064
  pBlobRow->len = 0;
×
1065
  pBlobRow->seq = 1;
×
1066
  return code;
×
1067
}
1068

1069
int32_t tRowBuildWithBlob(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow, SBlobSet *pBlobSet,
×
1070
                          SRowBuildScanInfo *sinfo) {
1071
  int32_t code;
1072

1073
  code = tRowBuildScan(aColVal, pTSchema, sinfo);
×
1074
  if (code) return code;
×
1075

1076
  if (sinfo->tupleRowSize <= sinfo->kvRowSize) {
×
1077
    code = tRowBuildTupleWithBlob(aColVal, sinfo, pTSchema, ppRow, pBlobSet);
×
1078
  } else {
1079
    code = tRowBuildKVRowWithBlob(aColVal, sinfo, pTSchema, ppRow, pBlobSet);
×
1080
  }
1081

1082
  return code;
×
1083
}
1084

1085
int32_t tRowBuildWithBlob2(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow, SBlobSet *pSrcBlobSet,
×
1086
                           SBlobSet *pDstBlobSet, SRowBuildScanInfo *sinfo) {
1087
  int32_t code;
1088

1089
  code = tRowBuildScan(aColVal, pTSchema, sinfo);
×
1090
  if (code) return code;
×
1091

1092
  if (sinfo->tupleRowSize <= sinfo->kvRowSize) {
×
1093
    code = tRowBuildTupleWithBlob2(aColVal, sinfo, pTSchema, ppRow, pSrcBlobSet, pDstBlobSet);
×
1094
  } else {
1095
    code = tRowBuildKVRowWithBlob2(aColVal, sinfo, pTSchema, ppRow, pSrcBlobSet, pDstBlobSet);
×
1096
  }
1097

1098
  return code;
×
1099
}
1100

1101
int32_t tBlobSetCreate(int64_t cap, int8_t type, SBlobSet **ppBlobSet) {
1✔
1102
  int32_t    lino = 0;
1✔
1103
  int32_t    code = 0;
1✔
1104
  SBlobSet  *p = taosMemCalloc(1, sizeof(SBlobSet));
1✔
1105
  if (p == NULL) {
1!
1106
    return terrno;
×
1107
  }
1108

1109
  p->type = type;
1✔
1110
  p->pSeqTable = taosArrayInit(128, sizeof(SBlobValue));
1✔
1111
  if (p->pSeqTable == NULL) {
1!
1112
    TAOS_CHECK_EXIT(terrno);
×
1113
  }
1114

1115
  p->data = taosMemCalloc(1024, cap * sizeof(uint8_t));
1✔
1116
  if (p->data == NULL) {
1!
1117
    TAOS_CHECK_EXIT(terrno);
×
1118
  }
1119

1120
  p->pSeqToffset = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK);
1✔
1121
  if (p->pSeqToffset == NULL) {
1!
1122
    TAOS_CHECK_EXIT(terrno);
×
1123
  }
1124

1125
  p->pSet = taosArrayInit(4, sizeof(int32_t));
1✔
1126
  if (p->pSet == NULL) {
1!
1127
    TAOS_CHECK_EXIT(terrno);
×
1128
  }
1129

1130
  p->cap = cap;
1✔
1131
  p->len = 0;
1✔
1132
  p->seq = 1;
1✔
1133

1134
  *ppBlobSet = p;
1✔
1135
_exit:
1✔
1136
  if (code != 0) {
1!
1137
    taosHashCleanup(p->pSeqToffset);
×
1138
    taosArrayDestroy(p->pSeqTable);
×
1139
    taosArrayDestroy(p->pSet);
×
1140

1141
    taosMemoryFree(p->data);
×
1142
    taosMemoryFree(p);
×
1143
  }
1144
  uDebug("create blob row %p", p);
1!
1145
  return code;
1✔
1146
}
1147
int32_t tBlobSetPush(SBlobSet *pBlobSet, SBlobItem *pItem, uint64_t *seq, int8_t nextRow) {
10✔
1148
  if (pBlobSet == NULL || pItem == NULL || seq == NULL) {
10!
1149
    return TSDB_CODE_INVALID_PARA;
×
1150
  }
1151
  uTrace("push blob %p, seqOffsetInRow %d, dataLen %d, nextRow %d", pBlobSet, pItem->seqOffsetInRow, pItem->len,
10!
1152
         nextRow);
1153
  int32_t  lino = 0;
10✔
1154
  int32_t  code = 0;
10✔
1155
  uint64_t offset;
1156
  uint32_t len = pItem->len;
10✔
1157
  uint8_t *data = pItem->data;
10✔
1158
  int32_t  dataOffset = pItem->seqOffsetInRow;
10✔
1159

1160
  uint64_t tlen = pBlobSet->len + len;
10✔
1161
  if (tlen > pBlobSet->cap) {
10!
1162
    int64_t cap = pBlobSet->cap;
×
1163
    // opt later
1164
    do {
1165
      cap = cap * 2;
×
1166
    } while (tlen > cap);
×
1167

1168
    uint8_t *data = taosMemRealloc(pBlobSet->data, cap);
×
1169
    if (data == NULL) {
×
1170
      return terrno;
×
1171
    }
1172
    pBlobSet->data = data;
×
1173
    pBlobSet->cap = cap;
×
1174
  }
1175
  if (len > 0) {
10!
1176
    (void)memcpy(pBlobSet->data + pBlobSet->len, data, len);
10✔
1177
  }
1178

1179
  offset = pBlobSet->len;
10✔
1180
  pBlobSet->len += len;
10✔
1181

1182
  pBlobSet->seq++;
10✔
1183
  *seq = pBlobSet->seq;
10✔
1184

1185
  SBlobValue value = {.offset = offset, .len = len, .dataOffset = dataOffset, .nextRow = nextRow, .type = pItem->type};
10✔
1186
  if (taosArrayPush(pBlobSet->pSeqTable, &value) == NULL) {
20!
1187
    TAOS_CHECK_EXIT(terrno);
×
1188
  }
1189

1190
  int32_t sz = taosArrayGetSize(pBlobSet->pSeqTable);
10✔
1191
  code = taosHashPut(pBlobSet->pSeqToffset, seq, sizeof(int64_t), &sz, sizeof(int32_t));
10✔
1192
  if (code != 0) {
10!
1193
    TAOS_CHECK_EXIT(code);
×
1194
  }
1195

1196
_exit:
10✔
1197
  return code;
10✔
1198
}
1199

1200
void tBlobSetSwap(SBlobSet *p1, SBlobSet *p2) {
×
1201
  SBlobSet t = {0};
×
1202

1203
  memcpy(&t, p1, sizeof(SBlobSet));
×
1204

1205
  memcpy(p1, p2, sizeof(SBlobSet));
×
1206
  memcpy(p2, &t, sizeof(SBlobSet));
×
1207
}
×
1208

1209
int32_t tBlobSetUpdate(SBlobSet *pBlobSet, uint64_t seq, SBlobItem *pItem) {
×
1210
  int32_t code = 0;
×
1211
  return code;
×
1212
  if (pBlobSet == NULL || pItem == NULL) {
1213
    return TSDB_CODE_INVALID_PARA;
1214
  }
1215
  if (pBlobSet->pSeqToffset == NULL || pBlobSet->pSeqTable == NULL) {
1216
    return TSDB_CODE_INVALID_PARA;
1217
  }
1218

1219
  return code;
1220
}
1221
int32_t tBlobSetGet(SBlobSet *pBlobSet, uint64_t seq, SBlobItem *pItem) {
×
1222
  if (pBlobSet == NULL || pItem == NULL) {
×
1223
    return TSDB_CODE_INVALID_PARA;
×
1224
  }
1225
  if (pBlobSet->pSeqToffset == NULL || pBlobSet->pSeqTable == NULL) {
×
1226
    return TSDB_CODE_INVALID_PARA;
×
1227
  }
1228

1229
  int32_t code = 0;
×
1230
  int32_t len = 0;
×
1231
  int32_t dataOffset = 0;
×
1232
  int8_t  nextRow = 0;
×
1233

1234
  int32_t *offset = (int32_t *)taosHashGet(pBlobSet->pSeqToffset, &seq, sizeof(int64_t));
×
1235
  if (offset == NULL) {
×
1236
    return TSDB_CODE_INVALID_PARA;
×
1237
  }
1238

1239
  SBlobValue *value = taosArrayGet(pBlobSet->pSeqTable, *offset - 1);
×
1240
  if (value == NULL) {
×
1241
    return TSDB_CODE_INVALID_PARA;
×
1242
  }
1243

1244
  len = value->len;
×
1245
  dataOffset = value->dataOffset;
×
1246
  nextRow = value->nextRow;
×
1247

1248
  pItem->seqOffsetInRow = value->dataOffset;
×
1249
  pItem->len = len;
×
1250
  pItem->data = pBlobSet->data + value->offset;
×
1251
  pItem->type = value->type;
×
1252

1253
  return code;
×
1254
}
1255

1256
int32_t tBlobSetSize(SBlobSet *pBlobSet) {
17,057,320✔
1257
  if (pBlobSet == NULL) return 0;
17,057,320!
1258
  return taosArrayGetSize(pBlobSet->pSeqTable);
×
1259
}
1260

1261
int32_t tBlobSetDestroy(SBlobSet *pBlobSet) {
61,332✔
1262
  if (pBlobSet == NULL) return 0;
61,332!
1263
  int32_t code = 0;
×
1264
  uTrace("destroy blob row, seqTable size %p", pBlobSet);
×
1265
  taosMemoryFree(pBlobSet->data);
×
1266
  taosArrayDestroy(pBlobSet->pSeqTable);
1✔
1267
  taosHashCleanup(pBlobSet->pSeqToffset);
1✔
1268
  taosArrayDestroy(pBlobSet->pSet);
1✔
1269
  taosMemoryFree(pBlobSet);
1!
1270
  return code;
1✔
1271
}
1272
int32_t tBlobSetClear(SBlobSet *pBlobSet) {
×
1273
  if (pBlobSet == NULL) return 0;
×
1274
  int32_t code = 0;
×
1275
  uTrace("clear blob row, seqTable size %p", pBlobSet);
×
1276
  taosArrayClear(pBlobSet->pSeqTable);
×
1277
  taosHashClear(pBlobSet->pSeqToffset);
×
1278
  pBlobSet->len = 0;
×
1279
  pBlobSet->seq = 1;
×
1280
  return code;
×
1281
}
1282

1283
static int32_t tBindInfoCompare(const void *p1, const void *p2, const void *param) {
37✔
1284
  if (((SBindInfo *)p1)->columnId < ((SBindInfo *)p2)->columnId) {
37✔
1285
    return -1;
7✔
1286
  } else if (((SBindInfo *)p1)->columnId > ((SBindInfo *)p2)->columnId) {
30!
1287
    return 1;
30✔
1288
  }
1289
  return 0;
×
1290
}
1291

1292
/* build rows to `rowArray` from bind
1293
 * `infos` is the bind information array
1294
 * `numOfInfos` is the number of bind information
1295
 * `infoSorted` is whether the bind information is sorted by column id
1296
 * `pTSchema` is the schema of the table
1297
 * `rowArray` is the array to store the rows
1298
 * `pOrdered` is the pointer to store ordered
1299
 * `pDupTs` is the pointer to store duplicateTs
1300
 */
1301
int32_t tRowBuildFromBind(SBindInfo *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
5,628✔
1302
                          SArray *rowArray, bool *pOrdered, bool *pDupTs) {
1303
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
5,628!
1304
    return TSDB_CODE_INVALID_PARA;
×
1305
  }
1306

1307
  if (!infoSorted) {
5,630!
1308
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
1309
  }
1310

1311
  int32_t code = 0;
5,630✔
1312
  int32_t numOfRows = infos[0].bind->num;
5,630✔
1313
  SArray *colValArray;
1314
  SColVal colVal;
1315

1316
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
5,630!
1317
    return terrno;
×
1318
  }
1319

1320
  SRowKey rowKey, lastRowKey;
1321
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
65,945✔
1322
    taosArrayClear(colValArray);
62,230✔
1323

1324
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
731,173✔
1325
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
679,586✔
1326
        colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
32✔
1327
      } else {
1328
        SValue value = {
679,554✔
1329
            .type = infos[iInfo].type,
679,554✔
1330
        };
1331
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
679,554!
1332
          value.nData = infos[iInfo].bind->length[iRow];
200,350✔
1333
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
200,350!
1334
            code = TSDB_CODE_INVALID_PARA;
×
1335
            goto _exit;
×
1336
          }
1337
          value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
200,350✔
1338
        } else {
1339
          valueSetDatum(&value, infos[iInfo].type,
479,204✔
1340
                        (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,
479,204✔
1341
                        infos[iInfo].bind->buffer_length);
479,204✔
1342
        }
1343
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
693,218✔
1344
      }
1345
      if (taosArrayPush(colValArray, &colVal) == NULL) {
669,178!
1346
        code = terrno;
×
1347
        goto _exit;
×
1348
      }
1349
    }
1350

1351
    SRow             *row;
1352
    SRowBuildScanInfo sinfo = {0};
51,587✔
1353
    if ((code = tRowBuild(colValArray, pTSchema, &row, &sinfo))) {
51,587!
1354
      goto _exit;
×
1355
    }
1356

1357
    if ((taosArrayPush(rowArray, &row)) == NULL) {
60,324!
1358
      code = terrno;
×
1359
      goto _exit;
×
1360
    }
1361

1362
    if (pOrdered && pDupTs) {
60,324!
1363
      tRowGetKey(row, &rowKey);
121,054!
1364
      if (iRow == 0) {
60,517✔
1365
        *pOrdered = true;
5,629✔
1366
        *pDupTs = false;
5,629✔
1367
      } else {
1368
        if (*pOrdered) {
54,888!
1369
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
54,966✔
1370
          *pOrdered = (res >= 0);
54,966✔
1371
          if (!*pDupTs) {
54,966!
1372
            *pDupTs = (res == 0);
54,980✔
1373
          }
1374
        }
1375
      }
1376
      lastRowKey = rowKey;
60,517✔
1377
    }
1378
  }
1379

1380
_exit:
3,715✔
1381
  taosArrayDestroy(colValArray);
3,715✔
1382
  return code;
5,628✔
1383
}
1384

1385
int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
2,147,483,647✔
1386
  if (!(iCol < pTSchema->numOfCols)) return TSDB_CODE_INVALID_PARA;
2,147,483,647!
1387
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
2,147,483,647!
1388

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

1391
  if (iCol == 0) {
2,147,483,647✔
1392
    pColVal->cid = pTColumn->colId;
11,422,697✔
1393
    pColVal->value.type = pTColumn->type;
11,422,697✔
1394
    pColVal->flag = CV_FLAG_VALUE;
11,422,697✔
1395
    VALUE_SET_TRIVIAL_DATUM(&pColVal->value, pRow->ts);
11,422,697✔
1396
    return 0;
11,422,697✔
1397
  }
1398

1399
  if (pRow->flag == HAS_NONE) {
2,147,483,647✔
1400
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
609,068✔
1401
    return 0;
609,068✔
1402
  }
1403

1404
  if (pRow->flag == HAS_NULL) {
2,147,483,647✔
1405
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
1,045,964✔
1406
    return 0;
1,045,964✔
1407
  }
1408

1409
  SPrimaryKeyIndex index;
1410
  uint8_t         *data = pRow->data;
2,147,483,647✔
1411
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
2,147,483,647✔
1412
    data += tGetPrimaryKeyIndex(data, &index);
23,093,935✔
1413
  }
1414

1415
  if (pRow->flag >> 4) {  // KV Row
2,147,483,647✔
1416
    SKVIdx  *pIdx = (SKVIdx *)data;
2,147,483,647✔
1417
    uint8_t *pv = NULL;
2,147,483,647✔
1418

1419
    if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
1420
      pv = pIdx->idx + pIdx->nCol;
2,147,483,647✔
1421
    } else if (pRow->flag & KV_FLG_MID) {
61,233,236!
1422
      pv = pIdx->idx + (pIdx->nCol << 1);
129,184,487✔
1423
    } else {
1424
      pv = pIdx->idx + (pIdx->nCol << 2);
×
1425
    }
1426

1427
    int16_t lidx = 0;
2,147,483,647✔
1428
    int16_t ridx = pIdx->nCol - 1;
2,147,483,647✔
1429
    while (lidx <= ridx) {
2,147,483,647✔
1430
      int16_t  mid = (lidx + ridx) >> 1;
2,147,483,647✔
1431
      uint8_t *pData = NULL;
2,147,483,647✔
1432
      if (pRow->flag & KV_FLG_LIT) {
2,147,483,647✔
1433
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
2,147,483,647✔
1434
      } else if (pRow->flag & KV_FLG_MID) {
539,268,840!
1435
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
539,363,531✔
1436
      } else {
1437
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
1438
      }
1439

1440
      int16_t cid;
1441
      pData += tGetI16v(pData, &cid);
2,147,483,647✔
1442

1443
      if (TABS(cid) == pTColumn->colId) {
2,147,483,647✔
1444
        if (cid < 0) {
2,147,483,647✔
1445
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
3,680,949✔
1446
        } else {
1447
          pColVal->cid = pTColumn->colId;
2,147,483,647✔
1448
          pColVal->value.type = pTColumn->type;
2,147,483,647✔
1449
          pColVal->flag = CV_FLAG_VALUE;
2,147,483,647✔
1450

1451
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
2,147,483,647!
1452
            int8_t isBlob = IS_STR_DATA_BLOB(pTColumn->type) ? 1 : 0;
660,704,801!
1453

1454
            pData += tGetU32v(pData, &pColVal->value.nData);
660,704,801!
1455
            if (pColVal->value.nData > 0) {
660,704,801!
1456
              pColVal->value.pData = pData;
896,220,888✔
1457
            } else {
1458
              pColVal->value.pData = NULL;
×
1459
            }
1460
            if (isBlob == 1) {
660,704,801!
1461
              pData += BSE_SEQUECE_SIZE;  // skip seq
×
1462
            }
1463
          } else {
1464
            valueSetDatum(&pColVal->value, pTColumn->type, pData, pTColumn->bytes);
2,147,483,647✔
1465
          }
1466
        }
1467
        return 0;
2,147,483,647✔
1468
      } else if (TABS(cid) < pTColumn->colId) {
2,147,483,647✔
1469
        lidx = mid + 1;
2,147,483,647✔
1470
      } else {
1471
        ridx = mid - 1;
2,064,085,199✔
1472
      }
1473
    }
1474

1475
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
1,485,030,759✔
1476
  } else {  // Tuple Row
1477
    uint8_t *bitmap = data;
780,533,801✔
1478
    uint8_t *fixed;
1479
    uint8_t *varlen;
1480
    uint8_t  bit;
1481

1482
    if (pRow->flag == HAS_VALUE) {
780,533,801✔
1483
      fixed = bitmap;
671,544,222✔
1484
      bit = BIT_FLG_VALUE;
671,544,222✔
1485
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
108,989,579!
1486
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
1487
      bit = GET_BIT2(bitmap, iCol - 1);
×
1488
    } else {
1489
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
108,989,579✔
1490
      bit = GET_BIT1(bitmap, iCol - 1);
108,989,579✔
1491

1492
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
108,989,579✔
1493
        if (bit) bit++;
17,483✔
1494
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
108,972,096✔
1495
        bit++;
40,234,921✔
1496
      }
1497
    }
1498
    varlen = fixed + pTSchema->flen;
780,533,801✔
1499

1500
    if (bit == BIT_FLG_NONE) {
780,533,801✔
1501
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
7,183✔
1502
      return 0;
7,183✔
1503
    } else if (bit == BIT_FLG_NULL) {
780,526,618✔
1504
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
12,671,915✔
1505
      return 0;
12,671,915✔
1506
    }
1507

1508
    pColVal->cid = pTColumn->colId;
767,854,703✔
1509
    pColVal->value.type = pTColumn->type;
767,854,703✔
1510
    pColVal->flag = CV_FLAG_VALUE;
767,854,703✔
1511
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
767,854,703!
1512
      int8_t isBlob = IS_STR_DATA_BLOB(pTColumn->type) ? 1 : 0;
161,867,603!
1513
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
161,867,603✔
1514
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
323,735,206✔
1515
      // TODO(yhDeng): support tuple
1516
      //  if (isBlob) pColVal->value.pData += sizeof(uint64_t);  // skip seq
1517
      //  }
1518
    } else {
1519
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
605,987,100✔
1520
    }
1521
  }
1522

1523
  return 0;
2,147,483,647✔
1524
}
1525

1526
void tRowDestroy(SRow *pRow) {
685,864,744✔
1527
  if (pRow) taosMemoryFree(pRow);
685,864,744!
1528
}
685,904,961✔
1529

1530
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
284,946,577✔
1531
  SRowKey key1, key2;
1532
  tRowGetKey(*(SRow **)p1, &key1);
569,893,154✔
1533
  tRowGetKey(*(SRow **)p2, &key2);
549,998,974✔
1534
  return tRowKeyCompare(&key1, &key2);
285,000,953✔
1535
}
1536
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
90,458✔
1537

1538
static SColVal* tRowFindColumnValue(SRowIter *iter, int32_t targetCid) {
60,330✔
1539
  SColVal* pColVal = tRowIterNext(iter);
60,330✔
1540
  while (pColVal != NULL && pColVal->cid < targetCid) {
60,391!
1541
    pColVal = tRowIterNext(iter);
61✔
1542
  }
1543
  return pColVal;
60,330✔
1544
}
1545

1546
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, ERowMergeStrategy strategy) {
30,040✔
1547
  int32_t code = 0;
30,040✔
1548

1549
  int32_t    nRow = iEnd - iStart;
30,040✔
1550
  SRowIter **aIter = NULL;
30,040✔
1551
  SArray    *aColVal = NULL;
30,040✔
1552
  SRow      *pRow = NULL;
30,040✔
1553
  uint8_t    hasBlob = 0;
30,040✔
1554
  aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
30,040!
1555
  if (aIter == NULL) {
30,040!
1556
    code = terrno;
×
1557
    goto _exit;
×
1558
  }
1559

1560
  for (int32_t i = 0; i < nRow; i++) {
120,498✔
1561
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
90,458✔
1562

1563
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
90,458✔
1564
    if (code) goto _exit;
90,458!
1565
  }
1566

1567
  // merge
1568
  aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
30,040✔
1569
  if (aColVal == NULL) {
30,040!
1570
    code = terrno;
×
1571
    goto _exit;
×
1572
  }
1573

1574
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
90,290✔
1575
    int32_t targetCid = pTSchema->columns[iCol].colId;
60,250✔
1576
    SColVal *pColVal = NULL;
60,250✔
1577

1578
    switch (strategy) {
60,250✔
1579
      case KEEP_CONSISTENCY:
60,010✔
1580
        if (nRow > 0)
60,010!
1581
          pColVal = tRowFindColumnValue(aIter[nRow - 1], targetCid);
60,010✔
1582
        break;
60,010✔
1583

1584
      default:  // default using PREFER_NON_NULL strategy
240✔
1585
      case PREFER_NON_NULL:
1586
        for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
346✔
1587
          SColVal *pColValT = tRowFindColumnValue(aIter[iRow], targetCid);
320✔
1588

1589
          if (COL_VAL_IS_VALUE(pColValT)) {
320✔
1590
            pColVal = pColValT;
214✔
1591
            break;
214✔
1592
          } else if (pColVal == NULL) {
106✔
1593
            pColVal = pColValT;
54✔
1594
          }
1595
        }
1596
        break;
240✔
1597
    }
1598

1599
    if (pColVal) {
60,250!
1600
      if (taosArrayPush(aColVal, pColVal) == NULL) {
60,250!
1601
        code = terrno;
×
1602
        goto _exit;
×
1603
      }
1604
    }
1605
  }
1606

1607
  // build
1608
  SRowBuildScanInfo sinfo = {0};
30,040✔
1609
  code = tRowBuild(aColVal, pTSchema, &pRow, &sinfo);
30,040✔
1610

1611
  if (code) goto _exit;
30,040!
1612

1613
  taosArrayRemoveBatch(aRowP, iStart, nRow, (FDelete)tRowPDestroy);
30,040✔
1614
  if (taosArrayInsert(aRowP, iStart, &pRow) == NULL) {
30,040!
1615
    code = terrno;
×
1616
    goto _exit;
×
1617
  }
1618

1619
_exit:
30,040✔
1620
  if (aIter) {
30,040!
1621
    for (int32_t i = 0; i < nRow; i++) {
120,498✔
1622
      tRowIterClose(&aIter[i]);
90,458✔
1623
    }
1624
    taosMemoryFree(aIter);
30,040!
1625
  }
1626
  if (aColVal) taosArrayDestroy(aColVal);
30,040!
1627
  if (code) tRowDestroy(pRow);
30,040!
1628
  return code;
30,040✔
1629
}
1630
static int32_t tBlobSetTransferTo(SBlobSet *pSrc, SBlobSet *pDst, SColVal *pVal) {
×
1631
  int32_t code = 0;
×
1632
  int32_t lino = 0;
×
1633
  if (COL_VAL_IS_NULL(pVal) || pVal->value.pData == NULL) {
×
1634
    int8_t type = COL_VAL_IS_NULL(pVal) ? TSDB_DATA_BLOB_NULL_VALUE : TSDB_DATA_BLOB_EMPTY_VALUE;
×
1635
    code = addEmptyItemToBlobSet(pDst, type, NULL);
×
1636
    TAOS_CHECK_GOTO(code, &lino, _error);
×
1637
  } else {
1638
    uint64_t seq = 0;
×
1639
    tGetU64(pVal->value.pData, &seq);
×
1640

1641
    SBlobItem item = {0};
×
1642
    code = tBlobSetGet(pSrc, seq, &item);
×
1643
    TAOS_CHECK_GOTO(code, &lino, _error);
×
1644

1645
    code = tBlobSetPush(pDst, &item, &seq, 1);
×
1646
    TAOS_CHECK_GOTO(code, &lino, _error);
×
1647
    tPutU64(pVal->value.pData, seq);
×
1648
  }
1649

1650
_error:
×
1651
  return code;
×
1652
}
1653

1654
static int32_t tRowRebuildBlob(SArray *aRowP, STSchema *pTSchema, SBlobSet *pBlob) {
×
1655
  int32_t code = 0;
×
1656
  int32_t   nRow = TARRAY_SIZE(aRowP);
×
1657
  int32_t   lino = 0;
×
1658
  SBlobSet *pTempBlob = NULL;
×
1659

1660
  SArray *aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
×
1661
  if (aColVal == NULL) {
×
1662
    TAOS_CHECK_RETURN(code = terrno);
×
1663
  }
1664

1665
  SRowIter **aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
×
1666
  if (aIter == NULL) {
×
1667
    TAOS_CHECK_RETURN(code = terrno);
×
1668
  }
1669

1670
  for (int32_t i = 0; i < nRow; i++) {
×
1671
    SRow *pRowT = taosArrayGetP(aRowP, 0 + i);
×
1672
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
×
1673
    TAOS_CHECK_GOTO(code, &lino, _error);
×
1674
  }
1675
  for (int32_t i = 0; i < nRow; i++) {
×
1676
    SColVal *pColVal = tRowIterNext(aIter[i]);
×
1677
    do {
1678
      if (COL_VAL_IS_VALUE(pColVal) || COL_VAL_IS_NULL(pColVal)) {
×
1679
        if (IS_STR_DATA_BLOB(pColVal->value.type)) {
×
1680
          if (taosArrayPush(aColVal, pColVal) == NULL) {
×
1681
            code = terrno;
×
1682
            TAOS_CHECK_GOTO(code, &lino, _error);
×
1683
          }
1684
          break;
×
1685
        }
1686
      }
1687
    } while ((pColVal = tRowIterNext(aIter[i])) != NULL);
×
1688
  }
1689

1690
  code = tBlobSetCreate(pBlob->cap, pBlob->type, &pTempBlob);
×
1691
  TAOS_CHECK_GOTO(code, &lino, _error);
×
1692

1693
  for (int32_t i = 0; i < taosArrayGetSize(aColVal); i++) {
×
1694
    uint64_t seq = 0;
×
1695
    SColVal *pVal = taosArrayGet(aColVal, i);
×
1696
    code = tBlobSetTransferTo(pBlob, pTempBlob, pVal);
×
1697
    TAOS_CHECK_GOTO(code, &lino, _error);
×
1698
  }
1699

1700
  tBlobSetSwap(pBlob, pTempBlob);
×
1701

1702
_error:
×
1703
  if (code != 0) {
×
1704
    uError("tRowRebuildBlob failed at line %d, code %d", code, lino);
×
1705
  }
1706

1707
  if (aIter) {
×
1708
    for (int32_t i = 0; i < nRow; i++) {
×
1709
      tRowIterClose(&aIter[i]);
×
1710
    }
1711
    taosMemoryFree(aIter);
×
1712
  }
1713
  if (aColVal) {
×
1714
    taosArrayDestroy(aColVal);
×
1715
  }
1716
  tBlobSetDestroy(pTempBlob);
×
1717
  return code;
×
1718
}
1719

1720
static int32_t tRowMergeAndRebuildBlob(SArray *aRowP, STSchema *pTSchema, SBlobSet *pBlob) {
×
1721
  int32_t code = 0;
×
1722

1723
  int32_t   lino = 0;
×
1724
  SBlobSet *pTempBlobSet = NULL;
×
1725
  int32_t   size = taosArrayGetSize(aRowP);
×
1726
  if (size <= 1) {
×
1727
    return code;
×
1728
  }
1729
  int32_t colBlobIdx = 0;
×
1730
  for (int32_t i = 0; i < pTSchema->numOfCols; i++) {
×
1731
    if (IS_STR_DATA_BLOB(pTSchema->columns[i].type)) {
×
1732
      colBlobIdx = i;
×
1733
      break;
×
1734
    }
1735
  }
1736

1737
  code = tBlobSetCreate(pBlob->cap, pBlob->type, &pTempBlobSet);
×
1738
  int32_t iStart = 0;
×
1739
  while (iStart < aRowP->size) {
×
1740
    SRowKey key1;
1741
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
×
1742

1743
    tRowGetKey(row1, &key1);
×
1744

1745
    int32_t iEnd = iStart + 1;
×
1746
    while (iEnd < aRowP->size) {
×
1747
      SRowKey key2;
1748
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
×
1749
      tRowGetKey(row2, &key2);
×
1750

1751
      if (tRowKeyCompare(&key1, &key2) != 0) break;
×
1752

1753
      iEnd++;
×
1754
    }
1755

1756
    if (iEnd - iStart > 1) {
×
1757
      code = tRowMergeWithBlobImpl(aRowP, pTSchema, pBlob, pTempBlobSet, iStart, iEnd, 0);
×
1758
      TAOS_CHECK_GOTO(code, &lino, _error);
×
1759
    } else {
1760
      SColVal colVal = {0};
×
1761
      code = tRowGet(row1, pTSchema, colBlobIdx, &colVal);
×
1762
      TAOS_CHECK_GOTO(code, &lino, _error);
×
1763

1764
      code = tBlobSetTransferTo(pBlob, pTempBlobSet, &colVal);
×
1765
      TAOS_CHECK_GOTO(code, &lino, _error);
×
1766
    }
1767
    // the array is also changing, so the iStart just ++ instead of iEnd
1768
    iStart++;
×
1769
  }
1770
_error:
×
1771
  tBlobSetSwap(pBlob, pTempBlobSet);
×
1772
  tBlobSetDestroy(pTempBlobSet);
×
1773
  return code;
×
1774
}
1775

1776
static int32_t tRowMergeWithBlobImpl(SArray *aRowP, STSchema *pTSchema, SBlobSet *pBlob, SBlobSet *pDstBlob,
×
1777
                                     int32_t iStart, int32_t iEnd, int8_t flag) {
1778
  int32_t code = 0;
×
1779
  int32_t    lino = 0;
×
1780
  int32_t    nRow = iEnd - iStart;
×
1781
  SRowIter **aIter = NULL;
×
1782
  SArray    *aColVal = NULL;
×
1783
  SRow      *pRow = NULL;
×
1784

1785
  aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
×
1786
  if (aColVal == NULL) {
×
1787
    code = terrno;
×
1788
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
1789
  }
1790

1791
  aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
×
1792
  if (aIter == NULL) {
×
1793
    code = terrno;
×
1794
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
1795
  }
1796

1797
  for (int32_t i = 0; i < nRow; i++) {
×
1798
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
×
1799
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
×
1800
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
1801
  }
1802
  // merge
1803

1804
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
×
1805
    SColVal  *pColVal = NULL;
×
1806
    STColumn *pCol = pTSchema->columns + iCol;
×
1807

1808
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
×
1809
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
×
1810
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
×
1811
        pColValT = tRowIterNext(aIter[iRow]);
×
1812
      }
1813
      // todo: take strategy according to the flag
1814
      if (COL_VAL_IS_VALUE(pColValT)) {
×
1815
        pColVal = pColValT;
×
1816
        break;
×
1817
      } else if (COL_VAL_IS_NULL(pColValT)) {
×
1818
        if (pColVal == NULL) {
×
1819
          pColVal = pColValT;
×
1820
        }
1821
      }
1822
    }
1823

1824
    if (pColVal) {
×
1825
      if (taosArrayPush(aColVal, pColVal) == NULL) {
×
1826
        code = terrno;
×
1827
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
1828
      }
1829
    }
1830
  }
1831

1832
  // build
1833

1834
  SRowBuildScanInfo sinfo = {.hasBlob = 1};
×
1835
  code = tRowBuildWithBlob2(aColVal, pTSchema, &pRow, pBlob, pDstBlob, &sinfo);
×
1836
  TAOS_CHECK_GOTO(code, &lino, _exit);
×
1837

1838
  taosArrayRemoveBatch(aRowP, iStart, nRow, (FDelete)tRowPDestroy);
×
1839
  if (taosArrayInsert(aRowP, iStart, &pRow) == NULL) {
×
1840
    code = terrno;
×
1841
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
1842
  }
1843

1844
_exit:
×
1845
  if (aIter) {
×
1846
    for (int32_t i = 0; i < nRow; i++) {
×
1847
      tRowIterClose(&aIter[i]);
×
1848
    }
1849
    taosMemoryFree(aIter);
×
1850
  }
1851
  if (aColVal) taosArrayDestroy(aColVal);
×
1852
  if (code) tRowDestroy(pRow);
×
1853

1854
  return code;
×
1855
}
1856

1857
int32_t tRowSort(SArray *aRowP) {
40,569✔
1858
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
40,569✔
1859
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
40,566✔
1860
  if (code != TSDB_CODE_SUCCESS) {
40,564!
1861
    uError("taosArrayMSort failed caused by %d", code);
×
1862
  }
1863
  return code;
40,564✔
1864
}
1865

1866
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, ERowMergeStrategy strategy) {
40,598✔
1867
  int32_t code = 0;
40,598✔
1868

1869
  int32_t iStart = 0;
40,598✔
1870
  while (iStart < aRowP->size) {
40,689,204!
1871
    SRowKey key1;
1872
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
40,709,278✔
1873

1874
    tRowGetKey(row1, &key1);
81,293,896✔
1875

1876
    int32_t iEnd = iStart + 1;
40,644,872✔
1877
    while (iEnd < aRowP->size) {
40,671,718!
1878
      SRowKey key2;
1879
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
40,679,800✔
1880
      tRowGetKey(row2, &key2);
81,283,480✔
1881

1882
      if (tRowKeyCompare(&key1, &key2) != 0) break;
40,683,534✔
1883

1884
      iEnd++;
26,846✔
1885
    }
1886

1887
    if (iEnd - iStart > 1) {
40,648,606✔
1888
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, strategy);
30,040✔
1889
      if (code) return code;
30,040!
1890
    }
1891

1892
    // the array is also changing, so the iStart just ++ instead of iEnd
1893
    iStart++;
40,648,606✔
1894
  }
1895

UNCOV
1896
  return code;
×
1897
}
1898

1899
int32_t tRowSortWithBlob(SArray *aRowP, STSchema *pTSchema, SBlobSet *pBlobSet) {
×
1900
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
×
1901
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
×
1902
  if (code != TSDB_CODE_SUCCESS) {
×
1903
    uError("taosArrayMSort failed caused by %d", code);
×
1904
    return code;
×
1905
  }
1906
  return code;
×
1907
}
1908

1909
int8_t tRowNeedDoMerge(SArray *aRowP) {
×
1910
  if (aRowP == NULL || aRowP->size <= 1) return 0;
×
1911

1912
  int8_t  doMerge = 0;
×
1913
  int32_t iStart = 0;
×
1914
  while (iStart < aRowP->size) {
×
1915
    SRowKey key1;
1916
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
×
1917

1918
    tRowGetKey(row1, &key1);
×
1919

1920
    int32_t iEnd = iStart + 1;
×
1921
    while (iEnd < aRowP->size) {
×
1922
      SRowKey key2;
1923
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
×
1924
      tRowGetKey(row2, &key2);
×
1925

1926
      if (tRowKeyCompare(&key1, &key2) != 0) break;
×
1927

1928
      iEnd++;
×
1929
    }
1930

1931
    if (iEnd - iStart > 1) {
×
1932
      doMerge = 1;
×
1933
      break;
×
1934
    }
1935
    iStart++;
×
1936
  }
1937
  return doMerge;
×
1938
}
1939

1940
int32_t tRowMergeWithBlob(SArray *aRowP, STSchema *pTSchema, SBlobSet *pBlobSet, int8_t flag) {
×
1941
  int32_t code = 0;
×
1942

1943
  int8_t doMerge = tRowNeedDoMerge(aRowP);
×
1944
  if (!doMerge) {
×
1945
    code = tRowRebuildBlob(aRowP, pTSchema, pBlobSet);
×
1946
  } else {
1947
    code = tRowRebuildBlob(aRowP, pTSchema, pBlobSet);
×
1948
    TAOS_CHECK_RETURN(code);
×
1949

1950
    code = tRowMergeAndRebuildBlob(aRowP, pTSchema, pBlobSet);
×
1951
  }
1952
  return code;
×
1953
}
1954

1955
// SRowIter ========================================
1956
struct SRowIter {
1957
  SRow     *pRow;
1958
  STSchema *pTSchema;
1959

1960
  int32_t iTColumn;
1961
  union {
1962
    struct {  // kv
1963
      int32_t iCol;
1964
      SKVIdx *pIdx;
1965
    };
1966
    struct {  // tuple
1967
      uint8_t *pb;
1968
      uint8_t *pf;
1969
    };
1970
  };
1971
  uint8_t *pv;
1972
  SColVal  cv;
1973
};
1974

1975
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) {
402,432✔
1976
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
402,432!
1977

1978
  int32_t code = 0;
402,432✔
1979

1980
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
402,432!
1981
  if (pIter == NULL) {
402,784!
1982
    code = terrno;
×
1983
    goto _exit;
×
1984
  }
1985

1986
  pIter->pRow = pRow;
402,784✔
1987
  pIter->pTSchema = pTSchema;
402,784✔
1988
  pIter->iTColumn = 0;
402,784✔
1989

1990
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
402,784✔
1991

1992
  uint8_t         *data = pRow->data;
399,798✔
1993
  SPrimaryKeyIndex index;
1994
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
424,995✔
1995
    data += tGetPrimaryKeyIndex(data, &index);
25,210✔
1996
  }
1997

1998
  if (pRow->flag >> 4) {
399,785✔
1999
    pIter->iCol = 0;
305,114✔
2000
    pIter->pIdx = (SKVIdx *)data;
305,114✔
2001
    if (pRow->flag & KV_FLG_LIT) {
305,114✔
2002
      pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol;
301,201✔
2003
    } else if (pRow->flag & KV_FLG_MID) {
3,913✔
2004
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1);  // * sizeof(uint16_t)
3,900✔
2005
    } else {
2006
      pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2);  // * sizeof(uint32_t)
13✔
2007
    }
2008
  } else {
2009
    switch (pRow->flag) {
94,671!
2010
      case (HAS_NULL | HAS_NONE):
1✔
2011
        pIter->pb = data;
1✔
2012
        break;
1✔
2013
      case HAS_VALUE:
93,408✔
2014
        pIter->pf = data;
93,408✔
2015
        pIter->pv = pIter->pf + pTSchema->flen;
93,408✔
2016
        break;
93,408✔
2017
      case (HAS_VALUE | HAS_NONE):
1,249✔
2018
      case (HAS_VALUE | HAS_NULL):
2019
        pIter->pb = data;
1,249✔
2020
        pIter->pf = data + BIT1_SIZE(pTSchema->numOfCols - 1);
1,249✔
2021
        pIter->pv = pIter->pf + pTSchema->flen;
1,249✔
2022
        break;
1,249✔
2023
      case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2024
        pIter->pb = data;
×
2025
        pIter->pf = data + BIT2_SIZE(pTSchema->numOfCols - 1);
×
2026
        pIter->pv = pIter->pf + pTSchema->flen;
×
2027
        break;
×
2028
      default:
13✔
2029
        break;
13✔
2030
    }
2031
  }
2032

2033
_exit:
402,771✔
2034
  if (code) {
402,771!
2035
    *ppIter = NULL;
×
2036
  } else {
2037
    *ppIter = pIter;
402,771✔
2038
  }
2039
  return code;
402,771✔
2040
}
2041

2042
void tRowIterClose(SRowIter **ppIter) {
402,290✔
2043
  SRowIter *pIter = *ppIter;
402,290✔
2044
  if (pIter) {
402,290!
2045
    taosMemoryFree(pIter);
402,293!
2046
  }
2047
  *ppIter = NULL;
402,783✔
2048
}
402,783✔
2049

2050
SColVal *tRowIterNext(SRowIter *pIter) {
7,920,188✔
2051
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
7,920,188✔
2052
    return NULL;
304,907✔
2053
  }
2054

2055
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
7,615,281✔
2056

2057
  // timestamp
2058
  if (0 == pIter->iTColumn) {
7,615,281✔
2059
    pIter->cv.cid = pTColumn->colId;
342,290✔
2060
    pIter->cv.value.type = pTColumn->type;
342,290✔
2061
    pIter->cv.flag = CV_FLAG_VALUE;
342,290✔
2062
    VALUE_SET_TRIVIAL_DATUM(&pIter->cv.value, pIter->pRow->ts);
342,290✔
2063
    goto _exit;
342,290✔
2064
  }
2065

2066
  if (pIter->pRow->flag == HAS_NONE) {
7,272,991✔
2067
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
47,561✔
2068
    goto _exit;
47,561✔
2069
  }
2070

2071
  if (pIter->pRow->flag == HAS_NULL) {
7,225,430✔
2072
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
3,151✔
2073
    goto _exit;
3,151✔
2074
  }
2075

2076
  if (pIter->pRow->flag >> 4) {  // KV
7,222,279✔
2077
    if (pIter->iCol < pIter->pIdx->nCol) {
7,184,996✔
2078
      uint8_t *pData;
2079

2080
      if (pIter->pRow->flag & KV_FLG_LIT) {
4,112,340✔
2081
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
3,995,475✔
2082
      } else if (pIter->pRow->flag & KV_FLG_MID) {
116,865!
2083
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
117,000✔
2084
      } else {
2085
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
2086
      }
2087

2088
      int16_t cid;
2089
      pData += tGetI16v(pData, &cid);
4,112,340✔
2090

2091
      if (TABS(cid) == pTColumn->colId) {
4,112,340!
2092
        if (cid < 0) {
4,114,906✔
2093
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
7,365✔
2094
        } else {
2095
          pIter->cv.cid = pTColumn->colId;
4,107,541✔
2096
          pIter->cv.value.type = pTColumn->type;
4,107,541✔
2097
          pIter->cv.flag = CV_FLAG_VALUE;
4,107,541✔
2098

2099
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
4,107,541!
2100
            pData += tGetU32v(pData, &pIter->cv.value.nData);
640,514!
2101
            if (pIter->cv.value.nData > 0) {
640,514!
2102
              pIter->cv.value.pData = pData;
646,259✔
2103
            } else {
2104
              pIter->cv.value.pData = NULL;
×
2105
              // if (IS_STR_DATA_BLOB(pTColumn->type)) {
2106
              //   pIter->cv.value.pData = pData;
2107
              // }
2108
            }
2109
          } else {
2110
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
3,467,027✔
2111
          }
2112
        }
2113

2114
        pIter->iCol++;
4,124,197✔
2115
        goto _exit;
4,124,197✔
2116
      } else if (TABS(cid) > pTColumn->colId) {
×
2117
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
94✔
2118
        goto _exit;
94✔
2119
      } else {
2120
        uError("unexpected column id %d, %d", cid, pTColumn->colId);
×
2121
        goto _exit;
×
2122
      }
2123
    } else {
2124
      pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
3,072,656✔
2125
      goto _exit;
3,072,656✔
2126
    }
2127
  } else {  // Tuple
2128
    uint8_t bv = BIT_FLG_VALUE;
37,283✔
2129
    if (pIter->pb) {
37,283✔
2130
      switch (pIter->pRow->flag) {
5,405!
2131
        case (HAS_NULL | HAS_NONE):
3✔
2132
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
3✔
2133
          break;
3✔
2134
        case (HAS_VALUE | HAS_NONE):
12✔
2135
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1);
12✔
2136
          if (bv) bv++;
12!
2137
          break;
12✔
2138
        case (HAS_VALUE | HAS_NULL):
5,390✔
2139
          bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1;
5,390✔
2140
          break;
5,390✔
2141
        case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2142
          bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1);
×
2143
          break;
×
2144
        default:
×
2145
          break;
×
2146
      }
2147

2148
      if (bv == BIT_FLG_NONE) {
5,405✔
2149
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
3✔
2150
        goto _exit;
3✔
2151
      } else if (bv == BIT_FLG_NULL) {
5,402✔
2152
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
685✔
2153
        goto _exit;
685✔
2154
      }
2155
    }
2156

2157
    pIter->cv.cid = pTColumn->colId;
36,595✔
2158
    pIter->cv.value.type = pTColumn->type;
36,595✔
2159
    pIter->cv.flag = CV_FLAG_VALUE;
36,595✔
2160
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
15,724!
2161
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
×
2162
      pData += tGetU32v(pData, &pIter->cv.value.nData);
×
2163
      if (pIter->cv.value.nData > 0) {
×
2164
        pIter->cv.value.pData = pData;
1,124✔
2165
      } else {
2166
        pIter->cv.value.pData = NULL;
×
2167
        // if (IS_STR_DATA_BLOB(pTColumn->type)) {
2168
        //   pIter->cv.value.pData = pData;
2169
        // }
2170
      }
2171
    } else {
2172
      valueSetDatum(&pIter->cv.value, pTColumn->type, pIter->pf + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
57,466✔
2173
    }
2174
    goto _exit;
58,594✔
2175
  }
2176

2177
_exit:
7,649,231✔
2178
  pIter->iTColumn++;
7,649,231✔
2179
  return &pIter->cv;
7,649,231✔
2180
}
2181

2182
static int32_t tRowNoneUpsertColData(SColData *aColData, int32_t nColData, int32_t flag) {
8,602✔
2183
  int32_t code = 0;
8,602✔
2184

2185
  if (flag) return code;
8,602✔
2186

2187
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
72,982✔
2188
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
67,949✔
2189
    if (code) return code;
67,944!
2190
  }
2191

2192
  return code;
5,033✔
2193
}
2194
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
179,678✔
2195
  int32_t code = 0;
179,678✔
2196

2197
  int32_t   iColData = 0;
179,678✔
2198
  SColData *pColData = &aColData[iColData];
179,678✔
2199
  int32_t   iTColumn = 1;
179,678✔
2200
  STColumn *pTColumn = &pSchema->columns[iTColumn];
179,678✔
2201

2202
  while (pColData) {
737,307✔
2203
    if (pTColumn) {
557,627!
2204
      if (pTColumn->colId == pColData->cid) {  // NULL
557,627!
2205
        if (flag == 0) {
557,635✔
2206
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
557,495✔
2207
        } else {
2208
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
140✔
2209
        }
2210
        if (code) goto _exit;
557,637!
2211

2212
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
557,637✔
2213
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
557,637✔
2214
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
2215
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
2216
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
2217
      } else {
2218
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
×
2219
      }
2220
    } else {  // NONE
2221
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
2222
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
2223
    }
2224
  }
2225

2226
_exit:
179,680✔
2227
  return code;
179,680✔
2228
}
2229
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
1,039,412,861✔
2230
                                      int32_t flag) {
2231
  int32_t code = 0;
1,039,412,861✔
2232

2233
  int32_t   iColData = 0;
1,039,412,861✔
2234
  SColData *pColData = &aColData[iColData];
1,039,412,861✔
2235
  int32_t   iTColumn = 1;
1,039,412,861✔
2236
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
1,039,412,861✔
2237

2238
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
1,039,412,861✔
2239
  SPrimaryKeyIndex index;
2240
  uint8_t         *data = pRow->data;
1,039,412,861✔
2241
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
1,276,564,840✔
2242
    data += tGetPrimaryKeyIndex(data, &index);
237,183,319✔
2243
  }
2244

2245
  switch (pRow->flag) {
1,039,381,521!
2246
    case HAS_VALUE:
1,029,672,772✔
2247
      pf = data;  // TODO: fix here
1,029,672,772✔
2248
      pv = pf + pTSchema->flen;
1,029,672,772✔
2249
      break;
1,029,672,772✔
2250
    case (HAS_NULL | HAS_NONE):
1,296✔
2251
      pb = data;
1,296✔
2252
      break;
1,296✔
2253
    case (HAS_VALUE | HAS_NONE):
10,006,521✔
2254
    case (HAS_VALUE | HAS_NULL):
2255
      pb = data;
10,006,521✔
2256
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
10,006,521✔
2257
      pv = pf + pTSchema->flen;
10,006,521✔
2258
      break;
10,006,521✔
2259
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2260
      pb = data;
×
2261
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
2262
      pv = pf + pTSchema->flen;
×
2263
      break;
×
2264
    default:
×
2265
      return TSDB_CODE_INVALID_DATA_FMT;
×
2266
  }
2267

2268
  while (pColData) {
2,147,483,647✔
2269
    if (pTColumn) {
2,147,483,647✔
2270
      if (pTColumn->colId == pColData->cid) {
2,147,483,647!
2271
        if (!(pTColumn->type == pColData->type)) {
2,147,483,647!
2272
          return TSDB_CODE_INVALID_PARA;
×
2273
        }
2274
        if (pb) {
2,147,483,647✔
2275
          uint8_t bv;
2276
          switch (pRow->flag) {
51,303,434!
2277
            case (HAS_NULL | HAS_NONE):
25,920✔
2278
              bv = GET_BIT1(pb, iTColumn - 1);
25,920✔
2279
              break;
25,920✔
2280
            case (HAS_VALUE | HAS_NONE):
296,620✔
2281
              bv = GET_BIT1(pb, iTColumn - 1);
296,620✔
2282
              if (bv) bv++;
296,620✔
2283
              break;
296,620✔
2284
            case (HAS_VALUE | HAS_NULL):
50,979,406✔
2285
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
50,979,406✔
2286
              break;
50,979,406✔
2287
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2288
              bv = GET_BIT2(pb, iTColumn - 1);
×
2289
              break;
×
2290
            default:
1,488✔
2291
              return TSDB_CODE_INVALID_DATA_FMT;
1,488✔
2292
          }
2293

2294
          if (bv == BIT_FLG_NONE) {
51,301,946✔
2295
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
49,302!
2296
              goto _exit;
×
2297
            goto _continue;
49,287✔
2298
          } else if (bv == BIT_FLG_NULL) {
51,252,644✔
2299
            if (flag == 0) {
13,068,984✔
2300
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
13,066,874✔
2301
            } else {
2302
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
2,110✔
2303
            }
2304
            if (code) goto _exit;
13,070,927!
2305
            goto _continue;
13,070,927✔
2306
          }
2307
        }
2308

2309
        if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
2310
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
82,859,107!
2311
          uint32_t nData;
2312
          pData += tGetU32v(pData, &nData);
82,859,107✔
2313
          if (flag == 0) {
82,859,107!
2314
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
86,843,384✔
2315
          } else {
2316
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
2317
          }
2318
          if (code) goto _exit;
87,517,582!
2319
        } else {
2320
          if (flag == 0) {
2,147,483,647✔
2321
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
2,147,483,647✔
2322
                                                                          TYPE_BYTES[pColData->type]);
2,147,483,647✔
2323
          } else {
2324
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
3,176,533✔
2325
                                                                          TYPE_BYTES[pColData->type], flag > 0);
3,176,533✔
2326
          }
2327
          if (code) goto _exit;
2,147,483,647!
2328
        }
2329

2330
      _continue:
2,147,483,647✔
2331
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
2,147,483,647✔
2332
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
2,147,483,647✔
2333
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
2334
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
2335
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
2336
      } else {
2337
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
2338
      }
2339
    } else {
2340
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
20,711!
2341
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
20,711✔
2342
    }
2343
  }
2344

2345
_exit:
1,044,003,146✔
2346
  return code;
1,044,003,146✔
2347
}
2348
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
5,678,237✔
2349
  int32_t code = 0;
5,678,237✔
2350

2351
  uint8_t  *pv = NULL;
5,678,237✔
2352
  int32_t   iColData = 0;
5,678,237✔
2353
  SColData *pColData = &aColData[iColData];
5,678,237✔
2354
  int32_t   iTColumn = 1;
5,678,237✔
2355
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
5,678,237✔
2356
  int32_t   iCol = 0;
5,678,237✔
2357

2358
  // primary keys
2359
  uint8_t         *data = pRow->data;
5,678,237✔
2360
  SPrimaryKeyIndex index;
2361
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
5,928,438✔
2362
    data += tGetPrimaryKeyIndex(data, &index);
250,221✔
2363
  }
2364

2365
  SKVIdx *pKVIdx = (SKVIdx *)data;
5,678,217✔
2366
  if (pRow->flag & KV_FLG_LIT) {
5,678,217✔
2367
    pv = pKVIdx->idx + pKVIdx->nCol;
5,630,585✔
2368
  } else if (pRow->flag & KV_FLG_MID) {
47,632!
2369
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
52,017✔
2370
  } else if (pRow->flag & KV_FLG_BIG) {
×
2371
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
2372
  } else {
2373
    return TSDB_CODE_INVALID_PARA;
×
2374
  }
2375

2376
  while (pColData) {
97,703,055✔
2377
    if (pTColumn) {
92,019,223!
2378
      if (pTColumn->colId == pColData->cid) {
92,019,223✔
2379
        while (iCol < pKVIdx->nCol) {
92,017,179✔
2380
          uint8_t *pData;
2381
          if (pRow->flag & KV_FLG_LIT) {
60,147,739✔
2382
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
58,645,320✔
2383
          } else if (pRow->flag & KV_FLG_MID) {
1,502,419!
2384
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
1,502,463✔
2385
          } else if (pRow->flag & KV_FLG_BIG) {
×
2386
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
2387
          } else {
2388
            return TSDB_CODE_INVALID_DATA_FMT;
×
2389
          }
2390

2391
          int16_t cid;
2392
          pData += tGetI16v(pData, &cid);
60,147,783✔
2393

2394
          if (TABS(cid) == pTColumn->colId) {
60,147,783✔
2395
            if (cid < 0) {
28,429,364✔
2396
              if (flag == 0) {
6,802,387✔
2397
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
6,790,319✔
2398
              } else {
2399
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
12,068✔
2400
              }
2401
              if (code) goto _exit;
6,416,942!
2402
            } else {
2403
              uint32_t nData;
2404
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
21,626,977!
2405
                pData += tGetU32v(pData, &nData);
4,059,450✔
2406
              } else {
2407
                nData = 0;
17,567,527✔
2408
              }
2409
              if (flag == 0) {
21,626,977!
2410
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
21,735,722✔
2411
              } else {
2412
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
2413
              }
2414
              if (code) goto _exit;
22,013,944!
2415
            }
2416
            iCol++;
28,430,886✔
2417
            goto _continue;
28,430,886✔
2418
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
31,718,419✔
2419
            break;
31,689,361✔
2420
          } else {
2421
            iCol++;
29,058✔
2422
          }
2423
        }
2424

2425
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
63,558,801!
2426

2427
      _continue:
63,558,465✔
2428
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
91,989,351✔
2429
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
91,989,351✔
2430
      } else if (pTColumn->colId > pColData->cid) {
31,102!
2431
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
2432
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
2433
      } else {
2434
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
31,102!
2435
      }
2436
    } else {
2437
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
2438
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
2439
    }
2440
  }
2441

2442
_exit:
5,683,832✔
2443
  return code;
5,683,832✔
2444
}
2445
/* flag > 0: forward update
2446
 * flag == 0: append
2447
 * flag < 0: backward update
2448
 */
2449
int32_t tRowUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
1,045,217,558✔
2450
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
1,045,217,558!
2451
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
1,045,217,558!
2452

2453
  if (pRow->flag == HAS_NONE) {
1,045,217,558✔
2454
    return tRowNoneUpsertColData(aColData, nColData, flag);
8,602✔
2455
  } else if (pRow->flag == HAS_NULL) {
1,045,208,956✔
2456
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
179,679✔
2457
  } else if (pRow->flag >> 4) {  // KV row
1,045,029,277✔
2458
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
5,677,880✔
2459
  } else {  // TUPLE row
2460
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
1,039,351,397✔
2461
  }
2462
}
2463

2464
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
2,147,483,647✔
2465
  key->numOfPKs = row->numOfPKs;
2,147,483,647✔
2466

2467
  if (key->numOfPKs == 0) {
2,147,483,647!
2468
    return;
×
2469
  }
2470

2471
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
2472

2473
  uint8_t *data = row->data;
2,147,483,647✔
2474

2475
  for (int32_t i = 0; i < row->numOfPKs; i++) {
2,147,483,647✔
2476
    data += tGetPrimaryKeyIndex(data, &indices[i]);
2,147,483,647✔
2477
  }
2478

2479
  // primary keys
2480
  for (int32_t i = 0; i < row->numOfPKs; i++) {
2,147,483,647✔
2481
    key->pks[i].type = indices[i].type;
2,147,483,647✔
2482

2483
    uint8_t *tdata = data + indices[i].offset;
2,147,483,647✔
2484
    if (row->flag >> 4) {
2,147,483,647✔
2485
      tdata += tGetI16v(tdata, NULL);
6,969,187✔
2486
    }
2487

2488
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
2,147,483,647!
2489
      key->pks[i].pData = tdata;
1,183,726✔
2490
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
2,367,452✔
2491
    } else {
2492
      valueSetDatum(key->pks + i, indices[i].type, tdata, tDataTypes[indices[i].type].bytes);
2,147,483,647✔
2493
    }
2494
  }
2495
}
2496

2497
#define T_COMPARE_SCALAR_VALUE(TYPE, V1, V2)    \
2498
  do {                                          \
2499
    if (*(TYPE *)(V1) < *(TYPE *)(V2)) {        \
2500
      return -1;                                \
2501
    } else if (*(TYPE *)(V1) > *(TYPE *)(V2)) { \
2502
      return 1;                                 \
2503
    } else {                                    \
2504
      return 0;                                 \
2505
    }                                           \
2506
  } while (0)
2507

2508
int32_t tValueCompare(const SValue *tv1, const SValue *tv2) {
48,464,173✔
2509
  switch (tv1->type) {
48,464,173!
2510
    case TSDB_DATA_TYPE_BOOL:
×
2511
    case TSDB_DATA_TYPE_TINYINT:
2512
      T_COMPARE_SCALAR_VALUE(int8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
2513
    case TSDB_DATA_TYPE_SMALLINT:
×
2514
      T_COMPARE_SCALAR_VALUE(int16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
2515
    case TSDB_DATA_TYPE_INT:
746,975✔
2516
      T_COMPARE_SCALAR_VALUE(int32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
746,975✔
2517
    case TSDB_DATA_TYPE_BIGINT:
45,678,164✔
2518
    case TSDB_DATA_TYPE_TIMESTAMP:
2519
      T_COMPARE_SCALAR_VALUE(int64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
45,678,164!
2520
    case TSDB_DATA_TYPE_FLOAT:
×
2521
      T_COMPARE_SCALAR_VALUE(float, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
2522
    case TSDB_DATA_TYPE_DOUBLE:
×
2523
      T_COMPARE_SCALAR_VALUE(double, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
2524
    case TSDB_DATA_TYPE_UTINYINT:
×
2525
      T_COMPARE_SCALAR_VALUE(uint8_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
2526
    case TSDB_DATA_TYPE_USMALLINT:
×
2527
      T_COMPARE_SCALAR_VALUE(uint16_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
×
2528
    case TSDB_DATA_TYPE_UINT:
528,902✔
2529
      T_COMPARE_SCALAR_VALUE(uint32_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
528,902✔
2530
    case TSDB_DATA_TYPE_UBIGINT:
537,243✔
2531
      T_COMPARE_SCALAR_VALUE(uint64_t, &VALUE_GET_TRIVIAL_DATUM(tv1), &VALUE_GET_TRIVIAL_DATUM(tv2));
537,243✔
2532
    case TSDB_DATA_TYPE_GEOMETRY:
975,176✔
2533
    case TSDB_DATA_TYPE_BINARY: {
2534
      int32_t ret = strncmp((const char *)tv1->pData, (const char *)tv2->pData, TMIN(tv1->nData, tv2->nData));
975,176✔
2535
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
975,176✔
2536
    }
2537
    case TSDB_DATA_TYPE_NCHAR: {
×
2538
      int32_t ret = taosUcs4Compare((TdUcs4 *)tv1->pData, (TdUcs4 *)tv2->pData,
×
2539
                                    tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
2540
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
2541
    }
2542
    case TSDB_DATA_TYPE_VARBINARY: {
×
2543
      int32_t ret = memcmp(tv1->pData, tv2->pData, tv1->nData < tv2->nData ? tv1->nData : tv2->nData);
×
2544
      return ret ? ret : (tv1->nData < tv2->nData ? -1 : (tv1->nData > tv2->nData ? 1 : 0));
×
2545
    }
2546
    default:
×
2547
      break;
×
2548
  }
2549

2550
  return 0;
×
2551
}
2552

2553
// NOTE:
2554
// set key->numOfPKs to 0 as the smallest key with ts
2555
// set key->numOfPKs to (TD_MAX_PK_COLS + 1) as the largest key with ts
2556
FORCE_INLINE int32_t tRowKeyCompare(const SRowKey *key1, const SRowKey *key2) {
2,147,483,647✔
2557
  if (key1->ts < key2->ts) {
2,147,483,647!
2558
    return -1;
2,147,483,647✔
2559
  } else if (key1->ts > key2->ts) {
2,147,483,647!
2560
    return 1;
2,147,483,647✔
2561
  }
2562

2563
  if (key1->numOfPKs == key2->numOfPKs) {
76,037,690!
2564
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
111,471,234!
2565
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
48,462,667✔
2566
      if (ret) return ret;
48,458,659!
2567
    }
2568
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
2569
    return -1;
9✔
2570
  } else {
2571
    return 1;
×
2572
  }
2573

2574
  return 0;
63,008,567✔
2575
}
2576

2577
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
736,039,899✔
2578
  pDst->ts = pSrc->ts;
736,039,899✔
2579
  pDst->numOfPKs = pSrc->numOfPKs;
736,039,899✔
2580

2581
  if (pSrc->numOfPKs > 0) {
736,039,899✔
2582
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
62,710,674✔
2583
      SValue *pVal = &pDst->pks[i];
31,144,046✔
2584
      pVal->type = pSrc->pks[i].type;
31,144,046✔
2585

2586
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
31,144,046✔
2587
    }
2588
  }
2589
}
736,462,815✔
2590

2591
// STag ========================================
2592
static int tTagValCmprFn(const void *p1, const void *p2) {
216,975,029✔
2593
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
216,975,029✔
2594
    return -1;
74,851,585✔
2595
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
142,123,444✔
2596
    return 1;
77,852,565✔
2597
  }
2598

2599
  return 0;
64,270,879✔
2600
}
2601
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
21,691✔
2602
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
21,691✔
2603
}
2604

2605
#ifdef TD_DEBUG_PRINT_TAG
2606
static void debugPrintTagVal(int8_t type, const void *val, int32_t vlen, const char *tag, int32_t ln) {
2607
  switch (type) {
2608
    case TSDB_DATA_TYPE_VARBINARY:
2609
    case TSDB_DATA_TYPE_JSON:
2610
    case TSDB_DATA_TYPE_VARCHAR:
2611
    case TSDB_DATA_TYPE_NCHAR:
2612
    case TSDB_DATA_TYPE_GEOMETRY: {
2613
      char tmpVal[32] = {0};
2614
      tstrncpy(tmpVal, val, vlen > 31 ? 31 : vlen);
2615
      printf("%s:%d type:%d vlen:%d, val:\"%s\"\n", tag, ln, (int32_t)type, vlen, tmpVal);
2616
    } break;
2617
    case TSDB_DATA_TYPE_FLOAT:
2618
      printf("%s:%d type:%d vlen:%d, val:%f\n", tag, ln, (int32_t)type, vlen, *(float *)val);
2619
      break;
2620
    case TSDB_DATA_TYPE_DOUBLE:
2621
      printf("%s:%d type:%d vlen:%d, val:%lf\n", tag, ln, (int32_t)type, vlen, *(double *)val);
2622
      break;
2623
    case TSDB_DATA_TYPE_BOOL:
2624
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
2625
      break;
2626
    case TSDB_DATA_TYPE_TINYINT:
2627
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
2628
      break;
2629
    case TSDB_DATA_TYPE_SMALLINT:
2630
      printf("%s:%d type:%d vlen:%d, val:%" PRIi16 "\n", tag, ln, (int32_t)type, vlen, *(int16_t *)val);
2631
      break;
2632
    case TSDB_DATA_TYPE_INT:
2633
      printf("%s:%d type:%d vlen:%d, val:%" PRIi32 "\n", tag, ln, (int32_t)type, vlen, *(int32_t *)val);
2634
      break;
2635
    case TSDB_DATA_TYPE_BIGINT:
2636
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
2637
      break;
2638
    case TSDB_DATA_TYPE_TIMESTAMP:
2639
      printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
2640
      break;
2641
    case TSDB_DATA_TYPE_UTINYINT:
2642
      printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
2643
      break;
2644
    case TSDB_DATA_TYPE_USMALLINT:
2645
      printf("%s:%d type:%d vlen:%d, val:%" PRIu16 "\n", tag, ln, (int32_t)type, vlen, *(uint16_t *)val);
2646
      break;
2647
    case TSDB_DATA_TYPE_UINT:
2648
      printf("%s:%d type:%d vlen:%d, val:%" PRIu32 "\n", tag, ln, (int32_t)type, vlen, *(uint32_t *)val);
2649
      break;
2650
    case TSDB_DATA_TYPE_UBIGINT:
2651
      printf("%s:%d type:%d vlen:%d, val:%" PRIu64 "\n", tag, ln, (int32_t)type, vlen, *(uint64_t *)val);
2652
      break;
2653
    case TSDB_DATA_TYPE_NULL:
2654
      printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
2655
      break;
2656
    default:
2657
      break;
2658
  }
2659
}
2660

2661
void debugPrintSTag(STag *pTag, const char *tag, int32_t ln) {
2662
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
2663
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
2664
  uint8_t *p = NULL;
2665
  int16_t  offset = 0;
2666

2667
  if (isLarge) {
2668
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
2669
  } else {
2670
    p = (uint8_t *)&pTag->idx[pTag->nTag];
2671
  }
2672
  printf("%s:%d >>> STAG === %s:%s, len: %d, nTag: %d, sver:%d\n", tag, ln, isJson ? "json" : "normal",
2673
         isLarge ? "large" : "small", (int32_t)pTag->len, (int32_t)pTag->nTag, pTag->ver);
2674
  for (uint16_t n = 0; n < pTag->nTag; ++n) {
2675
    if (isLarge) {
2676
      offset = ((int16_t *)pTag->idx)[n];
2677
    } else {
2678
      offset = pTag->idx[n];
2679
    }
2680
    STagVal tagVal = {0};
2681
    if (isJson) {
2682
      tagVal.pKey = (char *)POINTER_SHIFT(p, offset);
2683
    } else {
2684
      tagVal.cid = *(int16_t *)POINTER_SHIFT(p, offset);
2685
    }
2686
    printf("%s:%d loop[%d-%d] offset=%d\n", __func__, __LINE__, (int32_t)pTag->nTag, (int32_t)n, (int32_t)offset);
2687
    tGetTagVal(p + offset, &tagVal, isJson);
2688
    if (IS_VAR_DATA_TYPE(tagVal.type)) {
2689
      debugPrintTagVal(tagVal.type, tagVal.pData, tagVal.nData, __func__, __LINE__);
2690
    } else {
2691
      debugPrintTagVal(tagVal.type, &tagVal.i64, tDataTypes[tagVal.type].bytes, __func__, __LINE__);
2692
    }
2693
  }
2694
  printf("\n");
2695
}
2696
#endif
2697

2698
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
471,784✔
2699
  int32_t n = 0;
471,784✔
2700

2701
  // key
2702
  if (isJson) {
471,784✔
2703
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
1,264✔
2704
  } else {
2705
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
942,304✔
2706
  }
2707

2708
  // type
2709
  n += tPutI8(p ? p + n : p, pTagVal->type);
471,784✔
2710

2711
  // value
2712
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
471,784!
2713
    n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
310,988✔
2714
  } else {
2715
    p = p ? p + n : p;
316,290✔
2716
    n += tDataTypes[pTagVal->type].bytes;
316,290✔
2717
    if (p) (void)memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
316,290✔
2718
  }
2719

2720
  return n;
471,784✔
2721
}
2722
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
213,331,621✔
2723
  int32_t n = 0;
213,331,621✔
2724

2725
  // key
2726
  if (isJson) {
213,331,621✔
2727
    n += tGetCStr(p + n, &pTagVal->pKey);
45,888!
2728
  } else {
2729
    n += tGetI16v(p + n, &pTagVal->cid);
426,617,354!
2730
  }
2731

2732
  // type
2733
  n += tGetI8(p + n, &pTagVal->type);
213,331,621!
2734

2735
  // value
2736
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
213,331,621!
2737
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
69,617,010!
2738
  } else {
2739
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
178,523,116✔
2740
    n += tDataTypes[pTagVal->type].bytes;
178,523,116✔
2741
  }
2742

2743
  return n;
213,331,621✔
2744
}
2745

2746
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
45,556✔
2747

2748
bool tTagIsJsonNull(void *data) {
7,785✔
2749
  STag  *pTag = (STag *)data;
7,785✔
2750
  int8_t isJson = tTagIsJson(pTag);
7,785✔
2751
  if (!isJson) return false;
7,785✔
2752
  return ((STag *)data)->nTag == 0;
3,560✔
2753
}
2754

2755
int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
125,898✔
2756
  int32_t  code = 0;
125,898✔
2757
  uint8_t *p = NULL;
125,898✔
2758
  int16_t  n = 0;
125,898✔
2759
  int16_t  nTag = taosArrayGetSize(pArray);
125,898✔
2760
  int32_t  szTag = 0;
125,932✔
2761
  int8_t   isLarge = 0;
125,932✔
2762

2763
  // sort
2764
  if (isJson) {
125,932✔
2765
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
184✔
2766
  } else {
2767
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
125,748✔
2768
  }
2769

2770
  // get size
2771
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
361,870✔
2772
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
235,930✔
2773
  }
2774
  if (szTag <= INT8_MAX) {
125,940✔
2775
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
122,536✔
2776
  } else {
2777
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
3,404✔
2778
    isLarge = 1;
3,404✔
2779
  }
2780

2781
  // build tag
2782
  (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
125,940!
2783
  if ((*ppTag) == NULL) {
125,970!
2784
    code = terrno;
×
2785
    goto _err;
×
2786
  }
2787
  (*ppTag)->flags = 0;
125,970✔
2788
  if (isJson) {
125,970✔
2789
    (*ppTag)->flags |= TD_TAG_JSON;
184✔
2790
  }
2791
  if (isLarge) {
125,970✔
2792
    (*ppTag)->flags |= TD_TAG_LARGE;
3,424✔
2793
  }
2794
  (*ppTag)->len = szTag;
125,970✔
2795
  (*ppTag)->nTag = nTag;
125,970✔
2796
  (*ppTag)->ver = version;
125,970✔
2797

2798
  if (isLarge) {
125,970✔
2799
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
3,424✔
2800
  } else {
2801
    p = (uint8_t *)&(*ppTag)->idx[nTag];
122,546✔
2802
  }
2803
  n = 0;
125,970✔
2804
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
362,048✔
2805
    if (isLarge) {
236,060✔
2806
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
40,015✔
2807
    } else {
2808
      (*ppTag)->idx[iTag] = n;
196,045✔
2809
    }
2810
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
236,060✔
2811
  }
2812
#ifdef TD_DEBUG_PRINT_TAG
2813
  debugPrintSTag(*ppTag, __func__, __LINE__);
2814
#endif
2815

2816
  return code;
125,988✔
2817

2818
_err:
×
2819
  return code;
×
2820
}
2821

2822
void tTagFree(STag *pTag) {
50,199✔
2823
  if (pTag) taosMemoryFree(pTag);
50,199!
2824
}
50,199✔
2825

2826
char *tTagValToData(const STagVal *value, bool isJson) {
16,889,069✔
2827
  if (!value) {
16,889,069!
2828
    return NULL;
×
2829
  }
2830

2831
  char  *data = NULL;
16,889,069✔
2832
  int8_t typeBytes = 0;
16,889,069✔
2833
  if (isJson) {
16,889,069✔
2834
    typeBytes = CHAR_BYTES;
12,353✔
2835
  }
2836

2837
  if (IS_VAR_DATA_TYPE(value->type)) {
16,889,069!
2838
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
4,554,650!
2839
    if (data == NULL) {
4,555,855!
2840
      return NULL;
×
2841
    }
2842

2843
    if (isJson) {
4,555,855✔
2844
      *data = value->type;
8,382✔
2845
    }
2846

2847
    varDataLen(data + typeBytes) = value->nData;
4,555,855✔
2848
    (void)memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
4,555,855✔
2849
  } else {
2850
    data = ((char *)&(value->i64)) - typeBytes;  // json with type
12,334,419✔
2851
  }
2852

2853
  return data;
16,890,274✔
2854
}
2855

2856
bool tTagGet(const STag *pTag, STagVal *pTagVal) {
63,553,568✔
2857
  if (!pTag || !pTagVal) {
63,553,568!
2858
    return false;
×
2859
  }
2860

2861
  int16_t  lidx = 0;
63,881,386✔
2862
  int16_t  ridx = pTag->nTag - 1;
63,881,386✔
2863
  int16_t  midx;
2864
  uint8_t *p;
2865
  int8_t   isJson = pTag->flags & TD_TAG_JSON;
63,881,386✔
2866
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
63,881,386✔
2867
  int16_t  offset;
2868
  STagVal  tv;
2869
  int      c;
2870

2871
  if (isLarge) {
63,881,386✔
2872
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
59,132,427✔
2873
  } else {
2874
    p = (uint8_t *)&pTag->idx[pTag->nTag];
4,748,959✔
2875
  }
2876

2877
  pTagVal->type = TSDB_DATA_TYPE_NULL;
63,881,386✔
2878
  pTagVal->pData = NULL;
63,881,386✔
2879
  pTagVal->nData = 0;
63,881,386✔
2880
  while (lidx <= ridx) {
216,138,002✔
2881
    midx = (lidx + ridx) / 2;
214,164,879✔
2882
    if (isLarge) {
214,164,879✔
2883
      offset = ((int16_t *)pTag->idx)[midx];
189,570,549✔
2884
    } else {
2885
      offset = pTag->idx[midx];
24,594,330✔
2886
    }
2887

2888
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
214,164,879✔
2889
    if (isJson) {
217,544,321✔
2890
      c = tTagValJsonCmprFn(pTagVal, &tv);
21,523✔
2891
    } else {
2892
      c = tTagValCmprFn(pTagVal, &tv);
217,522,798✔
2893
    }
2894

2895
    if (c < 0) {
219,701,147✔
2896
      ridx = midx - 1;
74,489,092✔
2897
    } else if (c > 0) {
145,212,055✔
2898
      lidx = midx + 1;
77,767,524✔
2899
    } else {
2900
      (void)memcpy(pTagVal, &tv, sizeof(tv));
67,444,531✔
2901
      return true;
67,444,531✔
2902
    }
2903
  }
2904
  return false;
1,973,123✔
2905
}
2906

2907
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
786,197✔
2908
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
1,572,394✔
2909
}
2910

2911
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
30,898,697✔
2912

2913
int32_t tTagToValArray(const STag *pTag, SArray **ppArray) {
1,349✔
2914
  int32_t  code = 0;
1,349✔
2915
  uint8_t *p = NULL;
1,349✔
2916
  STagVal  tv = {0};
1,349✔
2917
  int8_t   isLarge = pTag->flags & TD_TAG_LARGE;
1,349✔
2918
  int16_t  offset = 0;
1,349✔
2919

2920
  if (isLarge) {
1,349✔
2921
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
23✔
2922
  } else {
2923
    p = (uint8_t *)&pTag->idx[pTag->nTag];
1,326✔
2924
  }
2925

2926
  (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
1,349✔
2927
  if (*ppArray == NULL) {
1,349!
2928
    code = terrno;
×
2929
    goto _err;
×
2930
  }
2931

2932
  for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
2,815✔
2933
    if (isLarge) {
1,466✔
2934
      offset = ((int16_t *)pTag->idx)[iTag];
29✔
2935
    } else {
2936
      offset = pTag->idx[iTag];
1,437✔
2937
    }
2938
    int32_t nt = tGetTagVal(p + offset, &tv, pTag->flags & TD_TAG_JSON);
1,466✔
2939
    if (taosArrayPush(*ppArray, &tv) == NULL) {
2,932!
2940
      code = terrno;
×
2941
      goto _err;
×
2942
    }
2943
  }
2944

2945
  return code;
1,349✔
2946

2947
_err:
×
2948
  return code;
×
2949
}
2950

2951
// STSchema ========================================
2952
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
14,580,301✔
2953
  STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
14,580,301!
2954
  if (pTSchema == NULL) {
14,616,522!
2955
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
2956
    return NULL;
×
2957
  }
2958

2959
  pTSchema->numOfCols = numOfCols;
14,616,522✔
2960
  pTSchema->version = version;
14,616,522✔
2961

2962
  // timestamp column
2963
  if (!(aSchema[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
14,616,522!
2964
    terrno = TSDB_CODE_INVALID_PARA;
×
2965
    taosMemoryFree(pTSchema);
×
2966
    return NULL;
×
2967
  }
2968
  if (!(aSchema[0].colId == PRIMARYKEY_TIMESTAMP_COL_ID)) {
14,616,522!
2969
    terrno = TSDB_CODE_INVALID_PARA;
×
2970
    taosMemoryFree(pTSchema);
×
2971
    return NULL;
×
2972
  }
2973
  pTSchema->columns[0].colId = aSchema[0].colId;
14,616,522✔
2974
  pTSchema->columns[0].type = aSchema[0].type;
14,616,522✔
2975
  pTSchema->columns[0].flags = aSchema[0].flags;
14,616,522✔
2976
  pTSchema->columns[0].bytes = TYPE_BYTES[aSchema[0].type];
14,616,522✔
2977
  pTSchema->columns[0].offset = -1;
14,616,522✔
2978

2979
  // other columns
2980
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
190,418,984✔
2981
    SSchema  *pSchema = &aSchema[iCol];
175,802,462✔
2982
    STColumn *pTColumn = &pTSchema->columns[iCol];
175,802,462✔
2983

2984
    pTColumn->colId = pSchema->colId;
175,802,462✔
2985
    pTColumn->type = pSchema->type;
175,802,462✔
2986
    pTColumn->flags = pSchema->flags;
175,802,462✔
2987
    pTColumn->offset = pTSchema->flen;
175,802,462✔
2988

2989
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
175,802,462!
2990
      pTColumn->bytes = pSchema->bytes;
28,067,468✔
2991
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
28,067,468✔
2992
    } else {
2993
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
147,734,994✔
2994
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
147,734,994✔
2995
    }
2996

2997
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
175,802,462✔
2998
  }
2999

3000
#if 1  // todo : remove this
3001
  pTSchema->tlen += (int32_t)TD_BITMAP_BYTES(numOfCols);
14,616,522✔
3002
#endif
3003

3004
  return pTSchema;
14,616,522✔
3005
}
3006

3007
static int32_t tTColumnCompare(const void *p1, const void *p2) {
13,122,334✔
3008
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
13,122,334✔
3009
    return -1;
2,005,381✔
3010
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
11,116,953✔
3011
    return 1;
7,861,498✔
3012
  }
3013

3014
  return 0;
3,255,455✔
3015
}
3016

3017
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid) {
3,257,458✔
3018
  STColumn tcol = {
3,257,458✔
3019
      .colId = cid,
3020
  };
3021

3022
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
3,257,458✔
3023
}
3024

3025
// SColData ========================================
3026
void tColDataDestroy(void *ph) {
22,584,203✔
3027
  if (ph) {
22,584,203!
3028
    SColData *pColData = (SColData *)ph;
22,584,346✔
3029

3030
    tFree(pColData->pBitMap);
22,584,346!
3031
    tFree(pColData->aOffset);
22,584,510✔
3032
    tFree(pColData->pData);
22,584,535!
3033
  }
3034
}
22,584,963✔
3035

3036
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
22,905,723✔
3037
  pColData->cid = cid;
22,905,723✔
3038
  pColData->type = type;
22,905,723✔
3039
  pColData->cflag = cflag;
22,905,723✔
3040
  tColDataClear(pColData);
22,905,723✔
3041
}
22,908,465✔
3042

3043
void tColDataClear(SColData *pColData) {
47,620,390✔
3044
  pColData->numOfNone = 0;
47,620,390✔
3045
  pColData->numOfNull = 0;
47,620,390✔
3046
  pColData->numOfValue = 0;
47,620,390✔
3047
  pColData->nVal = 0;
47,620,390✔
3048
  pColData->flag = 0;
47,620,390✔
3049
  pColData->nData = 0;
47,620,390✔
3050
}
47,620,390✔
3051

3052
void tColDataDeepClear(SColData *pColData) {
189,774✔
3053
  pColData->pBitMap = NULL;
189,774✔
3054
  pColData->aOffset = NULL;
189,774✔
3055
  pColData->pData = NULL;
189,774✔
3056

3057
  tColDataClear(pColData);
189,774✔
3058
}
189,797✔
3059

3060
static FORCE_INLINE int32_t tColDataPutValue(SColData *pColData, uint8_t *pData, uint32_t nData) {
3061
  int32_t  code = 0;
2,147,483,647✔
3062
  uint32_t cvtNData = sizeof(uint64_t);
2,147,483,647✔
3063
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
3064
    // TODO
3065
    if (IS_STR_DATA_BLOB(pColData->type)) {
128,597,266!
3066
      code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
×
3067
      if (code) goto _exit;
×
3068
      pColData->aOffset[pColData->nVal] = pColData->nData;
×
3069

3070
      if (nData) {
×
3071
        code = tRealloc(&pColData->pData, pColData->nData + BSE_SEQUECE_SIZE);
×
3072
        if (code) goto _exit;
×
3073
        (void)memcpy(pColData->pData + pColData->nData, pData, BSE_SEQUECE_SIZE);
×
3074
        pColData->nData += BSE_SEQUECE_SIZE;
×
3075
      } else {
3076
        // uint64_t zero = 0;
3077
        // (void)memcpy(pColData->pData + pColData->nData, &zero, BSE_SEQUECE_SIZE);
3078
        // pColData->nData += BSE_SEQUECE_SIZE;
3079
      }
3080

3081
    } else {
3082
      code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
149,913,957!
3083
      if (code) goto _exit;
150,060,594!
3084
      pColData->aOffset[pColData->nVal] = pColData->nData;
150,060,594✔
3085

3086
      if (nData) {
150,060,594!
3087
        code = tRealloc(&pColData->pData, pColData->nData + nData);
144,355,722!
3088
        if (code) goto _exit;
144,975,636!
3089
        (void)memcpy(pColData->pData + pColData->nData, pData, nData);
144,975,636✔
3090
        pColData->nData += nData;
144,975,636✔
3091
      }
3092
    }
3093
  } else {
3094
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
2,147,483,647!
3095
      return TSDB_CODE_INVALID_PARA;
×
3096
    }
3097
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
2,147,483,647!
3098
    if (code) goto _exit;
2,147,483,647!
3099
    if (pData) {
2,147,483,647!
3100
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
2,147,483,647✔
3101
    } else {
3102
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
45,943,981✔
3103
    }
3104
    pColData->nData += tDataTypes[pColData->type].bytes;
2,147,483,647✔
3105
  }
3106
  pColData->nVal++;
2,147,483,647✔
3107

3108
_exit:
2,147,483,647✔
3109
  return code;
2,147,483,647✔
3110
}
3111
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,667,584✔
3112
  pColData->flag = HAS_VALUE;
2,667,744✔
3113
  pColData->numOfValue++;
2,667,584✔
3114
  return tColDataPutValue(pColData, pData, nData);
2,669,621✔
3115
}
3116
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
209,118✔
3117
  pColData->flag = HAS_NONE;
209,118✔
3118
  pColData->numOfNone++;
209,118✔
3119
  pColData->nVal++;
209,118✔
3120
  return 0;
209,118✔
3121
}
3122
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
42,117✔
3123
  pColData->flag = HAS_NULL;
42,178✔
3124
  pColData->numOfNull++;
42,178✔
3125
  pColData->nVal++;
42,178✔
3126
  return 0;
42,117✔
3127
}
3128
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,481✔
3129
  int32_t code = 0;
2,481✔
3130

3131
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
2,481✔
3132
  code = tRealloc(&pColData->pBitMap, nBit);
2,481!
3133
  if (code) return code;
2,480!
3134

3135
  memset(pColData->pBitMap, 0, nBit);
2,480✔
3136
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
2,480!
3137

3138
  pColData->flag |= HAS_VALUE;
2,480✔
3139
  pColData->numOfValue++;
2,480✔
3140

3141
  if (pColData->nVal) {
2,480!
3142
    if (IS_VAR_DATA_TYPE(pColData->type)) {
2,479!
3143
      if (IS_STR_DATA_BLOB(pColData->type)) {
266!
3144
        int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
3145
        code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
3146
        if (code) return code;
×
3147
        memset(pColData->aOffset, 0, nOffset);
×
3148

3149
      } else {
3150
        int32_t nOffset = sizeof(int32_t) * pColData->nVal;
268✔
3151
        code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
268!
3152
        if (code) return code;
267!
3153
        memset(pColData->aOffset, 0, nOffset);
267✔
3154
      }
3155
    } else {
3156
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
2,213✔
3157
      code = tRealloc(&pColData->pData, pColData->nData);
2,213!
3158
      if (code) return code;
2,215!
3159
      memset(pColData->pData, 0, pColData->nData);
2,215✔
3160
    }
3161
  }
3162

3163
  return tColDataPutValue(pColData, pData, nData);
2,483✔
3164
}
3165
static FORCE_INLINE int32_t tColDataAppendValue11(SColData *pColData, uint8_t *pData, uint32_t nData) {
86,415,949✔
3166
  pColData->nVal++;
86,415,949✔
3167
  pColData->numOfNone++;
86,415,949✔
3168
  return 0;
86,415,949✔
3169
}
3170
static FORCE_INLINE int32_t tColDataAppendValue12(SColData *pColData, uint8_t *pData, uint32_t nData) {
483✔
3171
  int32_t code = 0;
483✔
3172

3173
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
483✔
3174
  code = tRealloc(&pColData->pBitMap, nBit);
483!
3175
  if (code) return code;
483!
3176

3177
  memset(pColData->pBitMap, 0, nBit);
483✔
3178
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
483!
3179

3180
  pColData->flag |= HAS_NULL;
483✔
3181
  pColData->numOfNull++;
483✔
3182
  pColData->nVal++;
483✔
3183

3184
  return code;
483✔
3185
}
3186
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
15,833✔
3187
  int32_t code = 0;
15,833✔
3188

3189
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
15,833✔
3190
  code = tRealloc(&pColData->pBitMap, nBit);
15,833!
3191
  if (code) return code;
15,833!
3192

3193
  memset(pColData->pBitMap, 0, nBit);
15,833✔
3194
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
15,833!
3195

3196
  pColData->flag |= HAS_VALUE;
15,833✔
3197
  pColData->numOfValue++;
15,833✔
3198

3199
  if (pColData->nVal) {
15,833!
3200
    if (IS_VAR_DATA_TYPE(pColData->type)) {
16,667!
3201
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
835✔
3202
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
835!
3203
      if (code) return code;
834!
3204
      if (!IS_STR_DATA_BLOB(pColData->type)) {
834!
3205
        memset(pColData->aOffset, 0, nOffset);
834✔
3206
      }
3207
    } else {
3208
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
14,998✔
3209
      code = tRealloc(&pColData->pData, pColData->nData);
14,998!
3210
      if (code) return code;
14,998!
3211
      memset(pColData->pData, 0, pColData->nData);
14,998✔
3212
    }
3213
  }
3214

3215
  return tColDataPutValue(pColData, pData, nData);
15,833✔
3216
}
3217
static FORCE_INLINE int32_t tColDataAppendValue21(SColData *pColData, uint8_t *pData, uint32_t nData) {
10,080✔
3218
  int32_t code = 0;
10,080✔
3219

3220
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
10,080✔
3221
  code = tRealloc(&pColData->pBitMap, nBit);
10,080✔
3222
  if (code) return code;
10,080!
3223

3224
  memset(pColData->pBitMap, 255, nBit);
10,080✔
3225
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
10,080!
3226

3227
  pColData->flag |= HAS_NONE;
10,080✔
3228
  pColData->numOfNone++;
10,080✔
3229
  pColData->nVal++;
10,080✔
3230

3231
  return code;
10,080✔
3232
}
3233
static FORCE_INLINE int32_t tColDataAppendValue22(SColData *pColData, uint8_t *pData, uint32_t nData) {
7,488,004✔
3234
  pColData->nVal++;
7,488,004✔
3235
  pColData->numOfNull++;
7,488,004✔
3236
  return 0;
7,488,004✔
3237
}
3238
static FORCE_INLINE int32_t tColDataAppendValue30(SColData *pColData, uint8_t *pData, uint32_t nData) {
5✔
3239
  int32_t code = 0;
5✔
3240

3241
  pColData->flag |= HAS_VALUE;
5✔
3242
  pColData->numOfValue++;
5✔
3243

3244
  uint8_t *pBitMap = NULL;
5✔
3245
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
5!
3246
  if (code) return code;
5!
3247

3248
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
1,005!
3249
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal));
1,000!
3250
  }
3251
  SET_BIT2_EX(pBitMap, pColData->nVal, 2);
5!
3252

3253
  tFree(pColData->pBitMap);
5!
3254
  pColData->pBitMap = pBitMap;
5✔
3255

3256
  if (pColData->nVal) {
5!
3257
    if (IS_VAR_DATA_TYPE(pColData->type)) {
5!
3258
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
3259
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
3260
      if (code) return code;
×
3261
      memset(pColData->aOffset, 0, nOffset);
×
3262
    } else {
3263
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
5✔
3264
      code = tRealloc(&pColData->pData, pColData->nData);
5!
3265
      if (code) return code;
5!
3266
      memset(pColData->pData, 0, pColData->nData);
5✔
3267
    }
3268
  }
3269

3270
  return tColDataPutValue(pColData, pData, nData);
5✔
3271
}
3272
static FORCE_INLINE int32_t tColDataAppendValue31(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,989,820✔
3273
  int32_t code = 0;
1,989,820✔
3274

3275
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,989,820!
3276
  if (code) return code;
1,989,820!
3277

3278
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
1,989,820✔
3279
  pColData->numOfNone++;
1,989,820✔
3280
  pColData->nVal++;
1,989,820✔
3281

3282
  return code;
1,989,820✔
3283
}
3284
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
7,500✔
3285
  int32_t code = 0;
7,500✔
3286

3287
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
7,500✔
3288
  if (code) return code;
7,501!
3289

3290
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
7,501!
3291
  pColData->numOfNull++;
7,501✔
3292
  pColData->nVal++;
7,501✔
3293

3294
  return code;
7,501✔
3295
}
3296
static FORCE_INLINE int32_t tColDataAppendValue40(SColData *pColData, uint8_t *pData, uint32_t nData) {
2,147,483,647✔
3297
  pColData->numOfValue++;
2,147,483,647✔
3298
  return tColDataPutValue(pColData, pData, nData);
2,147,483,647✔
3299
}
3300
static FORCE_INLINE int32_t tColDataAppendValue41(SColData *pColData, uint8_t *pData, uint32_t nData) {
123,528✔
3301
  int32_t code = 0;
123,528✔
3302

3303
  pColData->flag |= HAS_NONE;
123,528✔
3304
  pColData->numOfNone++;
123,528✔
3305

3306
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
123,528✔
3307
  code = tRealloc(&pColData->pBitMap, nBit);
123,528✔
3308
  if (code) return code;
123,556!
3309

3310
  memset(pColData->pBitMap, 255, nBit);
123,556✔
3311
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
123,556✔
3312

3313
  return tColDataPutValue(pColData, NULL, 0);
123,544✔
3314
}
3315
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
150,014✔
3316
  int32_t code = 0;
154,261✔
3317

3318
  pColData->flag |= HAS_NULL;
154,261✔
3319
  pColData->numOfNull++;
154,261✔
3320

3321
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
154,261✔
3322
  code = tRealloc(&pColData->pBitMap, nBit);
154,017✔
3323
  if (code) return code;
154,264!
3324

3325
  memset(pColData->pBitMap, 255, nBit);
154,264✔
3326
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
154,264!
3327

3328
  return tColDataPutValue(pColData, NULL, 0);
154,267✔
3329
}
3330
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
1,967,026✔
3331
  int32_t code = 0;
1,968,628✔
3332

3333
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
1,968,626!
3334
  if (code) return code;
1,968,916!
3335

3336
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
1,968,916!
3337
  pColData->numOfValue++;
1,968,916!
3338

3339
  return tColDataPutValue(pColData, pData, nData);
1,971,251✔
3340
}
3341
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
13,680,598✔
3342
  int32_t code = 0;
13,680,598✔
3343

3344
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
13,680,598!
3345
  if (code) return code;
13,680,558!
3346

3347
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
13,680,558✔
3348
  pColData->numOfNone++;
13,680,558✔
3349

3350
  return tColDataPutValue(pColData, NULL, 0);
13,682,573✔
3351
}
3352
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
12,467✔
3353
  int32_t code = 0;
12,467✔
3354

3355
  pColData->flag |= HAS_NULL;
12,467✔
3356
  pColData->numOfNull++;
12,467✔
3357

3358
  uint8_t *pBitMap = NULL;
12,467✔
3359
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
12,467!
3360
  if (code) return code;
12,467!
3361

3362
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,766,495!
3363
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
3,754,028!
3364
  }
3365
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
12,467!
3366

3367
  tFree(pColData->pBitMap);
12,467!
3368
  pColData->pBitMap = pBitMap;
12,467!
3369

3370
  return tColDataPutValue(pColData, NULL, 0);
12,467✔
3371
}
3372
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
343,046,887✔
3373
  int32_t code = 0;
343,049,315✔
3374

3375
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
343,048,995!
3376
  if (code) return code;
343,479,601!
3377
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
343,479,601!
3378
  pColData->numOfValue++;
343,479,601✔
3379

3380
  return tColDataPutValue(pColData, pData, nData);
344,116,822✔
3381
}
3382
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
25,894✔
3383
  int32_t code = 0;
25,894✔
3384

3385
  pColData->flag |= HAS_NONE;
25,894✔
3386
  pColData->numOfNone++;
25,894✔
3387

3388
  uint8_t *pBitMap = NULL;
25,894✔
3389
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
25,894!
3390
  if (code) return code;
25,894!
3391

3392
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
3,383,304✔
3393
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
3,357,410✔
3394
  }
3395
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
25,894✔
3396

3397
  tFree(pColData->pBitMap);
25,894!
3398
  pColData->pBitMap = pBitMap;
25,894✔
3399

3400
  return tColDataPutValue(pColData, NULL, 0);
25,894✔
3401
}
3402
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
22,173,993✔
3403
  int32_t code = 0;
22,185,233✔
3404

3405
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
22,182,098!
3406
  if (code) return code;
22,187,529!
3407
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
22,187,529✔
3408
  pColData->numOfNull++;
22,187,529✔
3409

3410
  return tColDataPutValue(pColData, NULL, 0);
22,194,665✔
3411
}
3412
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
659,502✔
3413
  int32_t code = 0;
659,502✔
3414

3415
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
659,502!
3416
  if (code) return code;
659,502!
3417
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 2);
659,502!
3418
  pColData->numOfValue++;
659,502!
3419

3420
  return tColDataPutValue(pColData, pData, nData);
659,502✔
3421
}
3422
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
4,459,571✔
3423
  int32_t code = 0;
4,459,571✔
3424

3425
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
4,459,571!
3426
  if (code) return code;
4,459,571!
3427
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 0);
4,459,571✔
3428
  pColData->numOfNone++;
4,459,571!
3429

3430
  return tColDataPutValue(pColData, NULL, 0);
4,459,571✔
3431
}
3432
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
563,204✔
3433
  int32_t code = 0;
563,204✔
3434

3435
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
563,204!
3436
  if (code) return code;
563,204!
3437
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 1);
563,204!
3438
  pColData->numOfNull++;
563,204!
3439

3440
  return tColDataPutValue(pColData, NULL, 0);
563,204✔
3441
}
3442
static int32_t (*tColDataAppendValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData) = {
3443
    {tColDataAppendValue00, tColDataAppendValue01, tColDataAppendValue02},  // 0
3444
    {tColDataAppendValue10, tColDataAppendValue11, tColDataAppendValue12},  // HAS_NONE
3445
    {tColDataAppendValue20, tColDataAppendValue21, tColDataAppendValue22},  // HAS_NULL
3446
    {tColDataAppendValue30, tColDataAppendValue31, tColDataAppendValue32},  // HAS_NULL|HAS_NONE
3447
    {tColDataAppendValue40, tColDataAppendValue41, tColDataAppendValue42},  // HAS_VALUE
3448
    {tColDataAppendValue50, tColDataAppendValue51, tColDataAppendValue52},  // HAS_VALUE|HAS_NONE
3449
    {tColDataAppendValue60, tColDataAppendValue61, tColDataAppendValue62},  // HAS_VALUE|HAS_NULL
3450
    {tColDataAppendValue70, tColDataAppendValue71, tColDataAppendValue72},  // HAS_VALUE|HAS_NULL|HAS_NONE
3451

3452
    //       VALUE                  NONE                     NULL
3453
};
3454

3455
static FORCE_INLINE int32_t tColDataPutValueBlob(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
3456
  int32_t  code = 0;
10✔
3457
  uint8_t  buf[sizeof(uint64_t) + 1] = {0};
10✔
3458
  uint64_t seq = 0;
10✔
3459

3460
  int32_t offset = 0;
10✔
3461
  if (IS_STR_DATA_BLOB(pColData->type)) {
×
3462
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
10!
3463
    if (code) goto _exit;
10!
3464
    pColData->aOffset[pColData->nVal] = pColData->nData;
10✔
3465
    if (nData) {
10!
3466
      SBlobItem item = {.seqOffsetInRow = seq, .len = nData, .data = pData, .type = TSDB_DATA_BLOB_VALUE};
10✔
3467
      code = tBlobSetPush(pArg, &item, &seq, 0);
10✔
3468
      if (code != 0) return code;
10!
3469

3470
      offset = tPutU64(buf, seq);
10!
3471
      code = tRealloc(&pColData->pData, pColData->nData + offset);
10!
3472
      if (code != 0) return code;
10!
3473
      memcpy(pColData->pData + pColData->nData, buf, offset);
10✔
3474
      pColData->nData += offset;
10✔
3475
    } else {
3476
      int8_t type = pData ? TSDB_DATA_BLOB_EMPTY_VALUE : TSDB_DATA_BLOB_NULL_VALUE;
×
3477
      code = addEmptyItemToBlobSet(pArg, type, NULL);
×
3478
    }
3479
  }
3480
  pColData->nVal++;
10✔
3481

3482
_exit:
10✔
3483
  return code;
10✔
3484
}
3485

3486
static FORCE_INLINE int32_t tColDataAppendValueBlob00(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
1✔
3487
  pColData->flag = HAS_VALUE;
1✔
3488
  pColData->numOfValue++;
1!
3489
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
1✔
3490
}
3491
static FORCE_INLINE int32_t tColDataAppendValueBlob01(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3492
  pColData->flag = HAS_NONE;
×
3493
  pColData->numOfNone++;
×
3494
  pColData->nVal++;
×
3495
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3496
}
3497
static FORCE_INLINE int32_t tColDataAppendValueBlob02(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3498
  pColData->flag = HAS_NULL;
×
3499
  pColData->numOfNull++;
×
3500
  pColData->nVal++;
×
3501
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3502
}
3503
static FORCE_INLINE int32_t tColDataAppendValueBlob10(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3504
  int32_t code = 0;
×
3505

3506
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
3507
  code = tRealloc(&pColData->pBitMap, nBit);
×
3508
  if (code) return code;
×
3509

3510
  memset(pColData->pBitMap, 0, nBit);
×
3511
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
3512

3513
  pColData->flag |= HAS_VALUE;
×
3514
  pColData->numOfValue++;
×
3515

3516
  if (pColData->nVal) {
×
3517
    if (IS_VAR_DATA_TYPE(pColData->type)) {
×
3518
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
3519
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
3520
      if (code) return code;
×
3521
      memset(pColData->aOffset, 0, nOffset);
×
3522
    } else {
3523
      pColData->nData = tDataTypes[pColData->type].bytes * pColData->nVal;
×
3524
      code = tRealloc(&pColData->pData, pColData->nData);
×
3525
      if (code) return code;
×
3526
      memset(pColData->pData, 0, pColData->nData);
×
3527
    }
3528
  }
3529

3530
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
×
3531
}
3532
static FORCE_INLINE int32_t tColDataAppendValueBlob11(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3533
  pColData->nVal++;
×
3534
  pColData->numOfNone++;
×
3535
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3536
}
3537
static FORCE_INLINE int32_t tColDataAppendValueBlob12(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3538
  int32_t code = 0;
×
3539

3540
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
3541
  code = tRealloc(&pColData->pBitMap, nBit);
×
3542
  if (code) return code;
×
3543

3544
  memset(pColData->pBitMap, 0, nBit);
×
3545
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
3546

3547
  pColData->flag |= HAS_NULL;
×
3548
  pColData->numOfNull++;
×
3549
  pColData->nVal++;
×
3550
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3551
}
3552
static FORCE_INLINE int32_t tColDataAppendValueBlob20(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3553
  int32_t code = 0;
×
3554

3555
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
3556
  code = tRealloc(&pColData->pBitMap, nBit);
×
3557
  if (code) return code;
×
3558

3559
  memset(pColData->pBitMap, 0, nBit);
×
3560
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
3561

3562
  pColData->flag |= HAS_VALUE;
×
3563
  pColData->numOfValue++;
×
3564

3565
  if (pColData->nVal) {
×
3566
    if (IS_STR_DATA_BLOB(pColData->type)) {
×
3567
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
3568
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
3569
      if (code) return code;
×
3570
      memset(pColData->aOffset, 0, nOffset);
×
3571
    } else {
3572
      return TSDB_CODE_INVALID_MSG;
×
3573
    }
3574
  }
3575

3576
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
×
3577
}
3578
static FORCE_INLINE int32_t tColDataAppendValueBlob21(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3579
  int32_t code = 0;
×
3580

3581
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
3582
  code = tRealloc(&pColData->pBitMap, nBit);
×
3583
  if (code) return code;
×
3584

3585
  memset(pColData->pBitMap, 255, nBit);
×
3586
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
3587

3588
  pColData->flag |= HAS_NONE;
×
3589
  pColData->numOfNone++;
×
3590
  pColData->nVal++;
×
3591
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3592
}
3593
static FORCE_INLINE int32_t tColDataAppendValueBlob22(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3594
  pColData->nVal++;
×
3595
  pColData->numOfNull++;
×
3596
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3597
}
3598
static FORCE_INLINE int32_t tColDataAppendValueBlob30(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3599
  int32_t code = 0;
×
3600

3601
  pColData->flag |= HAS_VALUE;
×
3602
  pColData->numOfValue++;
×
3603

3604
  uint8_t *pBitMap = NULL;
×
3605
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
3606
  if (code) return code;
×
3607

3608
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3609
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal));
×
3610
  }
3611
  SET_BIT2_EX(pBitMap, pColData->nVal, 2);
×
3612

3613
  tFree(pColData->pBitMap);
×
3614
  pColData->pBitMap = pBitMap;
×
3615

3616
  if (pColData->nVal) {
×
3617
    if (IS_STR_DATA_BLOB(pColData->type)) {
×
3618
      int32_t nOffset = sizeof(int32_t) * pColData->nVal;
×
3619
      code = tRealloc((uint8_t **)(&pColData->aOffset), nOffset);
×
3620
      if (code) return code;
×
3621
      memset(pColData->aOffset, 0, nOffset);
×
3622
    } else {
3623
      return TSDB_CODE_INVALID_MSG;
×
3624
    }
3625
  }
3626

3627
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
×
3628
}
3629
static FORCE_INLINE int32_t tColDataAppendValueBlob31(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3630
  int32_t code = 0;
×
3631

3632
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
3633
  if (code) return code;
×
3634

3635
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
3636
  pColData->numOfNone++;
×
3637
  pColData->nVal++;
×
3638

3639
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3640
}
3641
static FORCE_INLINE int32_t tColDataAppendValueBlob32(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3642
  int32_t code = 0;
×
3643

3644
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
3645
  if (code) return code;
×
3646

3647
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
3648
  pColData->numOfNull++;
×
3649
  pColData->nVal++;
×
3650
  return addEmptyItemToBlobSet(pArg, TSDB_DATA_BLOB_NULL_VALUE, NULL);
×
3651
}
3652
static FORCE_INLINE int32_t tColDataAppendValueBlob40(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
9✔
3653
  pColData->numOfValue++;
9!
3654
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
9✔
3655
}
3656
static FORCE_INLINE int32_t tColDataAppendValueBlob41(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3657
  int32_t code = 0;
×
3658

3659
  pColData->flag |= HAS_NONE;
×
3660
  pColData->numOfNone++;
×
3661

3662
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
3663
  code = tRealloc(&pColData->pBitMap, nBit);
×
3664
  if (code) return code;
×
3665

3666
  memset(pColData->pBitMap, 255, nBit);
×
3667
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
3668

3669
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3670
}
3671
static FORCE_INLINE int32_t tColDataAppendValueBlob42(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3672
  int32_t code = 0;
×
3673

3674
  pColData->flag |= HAS_NULL;
×
3675
  pColData->numOfNull++;
×
3676

3677
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
3678
  code = tRealloc(&pColData->pBitMap, nBit);
×
3679
  if (code) return code;
×
3680

3681
  memset(pColData->pBitMap, 255, nBit);
×
3682
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
3683

3684
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3685
}
3686
static FORCE_INLINE int32_t tColDataAppendValueBlob50(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3687
  int32_t code = 0;
×
3688

3689
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
3690
  if (code) return code;
×
3691

3692
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
3693
  pColData->numOfValue++;
×
3694

3695
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
×
3696
}
3697
static FORCE_INLINE int32_t tColDataAppendValueBlob51(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3698
  int32_t code = 0;
×
3699

3700
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
3701
  if (code) return code;
×
3702

3703
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
3704
  pColData->numOfNone++;
×
3705

3706
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3707
}
3708
static FORCE_INLINE int32_t tColDataAppendValueBlob52(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3709
  int32_t code = 0;
×
3710

3711
  pColData->flag |= HAS_NULL;
×
3712
  pColData->numOfNull++;
×
3713

3714
  uint8_t *pBitMap = NULL;
×
3715
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
3716
  if (code) return code;
×
3717

3718
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3719
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
×
3720
  }
3721
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
×
3722

3723
  tFree(pColData->pBitMap);
×
3724
  pColData->pBitMap = pBitMap;
×
3725

3726
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3727
}
3728
static FORCE_INLINE int32_t tColDataAppendValueBlob60(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3729
  int32_t code = 0;
×
3730

3731
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
3732
  if (code) return code;
×
3733
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
3734
  pColData->numOfValue++;
×
3735

3736
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
×
3737
}
3738
static FORCE_INLINE int32_t tColDataAppendValueBlob61(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3739
  int32_t code = 0;
×
3740

3741
  pColData->flag |= HAS_NONE;
×
3742
  pColData->numOfNone++;
×
3743

3744
  uint8_t *pBitMap = NULL;
×
3745
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
3746
  if (code) return code;
×
3747

3748
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3749
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
×
3750
  }
3751
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
×
3752

3753
  tFree(pColData->pBitMap);
×
3754
  pColData->pBitMap = pBitMap;
×
3755

3756
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3757
}
3758
static FORCE_INLINE int32_t tColDataAppendValueBlob62(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3759
  int32_t code = 0;
×
3760

3761
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
3762
  if (code) return code;
×
3763
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
3764
  pColData->numOfNull++;
×
3765

3766
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3767
}
3768
static FORCE_INLINE int32_t tColDataAppendValueBlob70(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3769
  int32_t code = 0;
×
3770

3771
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
3772
  if (code) return code;
×
3773
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 2);
×
3774
  pColData->numOfValue++;
×
3775

3776
  return tColDataPutValueBlob(pArg, pColData, pData, nData);
×
3777
}
3778
static FORCE_INLINE int32_t tColDataAppendValueBlob71(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3779
  int32_t code = 0;
×
3780

3781
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
3782
  if (code) return code;
×
3783
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 0);
×
3784
  pColData->numOfNone++;
×
3785

3786
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3787
}
3788
static FORCE_INLINE int32_t tColDataAppendValueBlob72(void *pArg, SColData *pColData, uint8_t *pData, uint32_t nData) {
×
3789
  int32_t code = 0;
×
3790

3791
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
3792
  if (code) return code;
×
3793
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 1);
×
3794
  pColData->numOfNull++;
×
3795

3796
  return tColDataPutValueBlob(pArg, pColData, NULL, 0);
×
3797
}
3798

3799
static int32_t (*tColDataAppendValueBlobImpl[8][3])(void *pDst, SColData *pColData, uint8_t *pData, uint32_t nData) = {
3800
    {tColDataAppendValueBlob00, tColDataAppendValueBlob01, tColDataAppendValueBlob02},  // 0
3801
    {tColDataAppendValueBlob10, tColDataAppendValueBlob11, tColDataAppendValueBlob12},  // HAS_NONE
3802
    {tColDataAppendValueBlob20, tColDataAppendValueBlob21, tColDataAppendValueBlob22},  // HAS_NULL
3803
    {tColDataAppendValueBlob30, tColDataAppendValueBlob31, tColDataAppendValueBlob32},  // HAS_NULL|HAS_NONE
3804
    {tColDataAppendValueBlob40, tColDataAppendValueBlob41, tColDataAppendValueBlob42},  // HAS_VALUE
3805
    {tColDataAppendValueBlob50, tColDataAppendValueBlob51, tColDataAppendValueBlob52},  // HAS_VALUE|HAS_NONE
3806
    {tColDataAppendValueBlob60, tColDataAppendValueBlob61, tColDataAppendValueBlob62},  // HAS_VALUE|HAS_NULL
3807
    {tColDataAppendValueBlob70, tColDataAppendValueBlob71, tColDataAppendValueBlob72}   // HAS_VALUE|HAS_NULL|HAS_NONE
3808
    //       VALUE                  NONE                     NULL
3809
};
3810
int32_t tColDataAppendValue(SColData *pColData, SColVal *pColVal) {
2,147,483,647✔
3811
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) {
2,147,483,647!
3812
    return TSDB_CODE_INVALID_PARA;
×
3813
  }
3814
  return tColDataAppendValueImpl[pColData->flag][pColVal->flag](
2,147,483,647✔
3815
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData);
2,147,483,647!
3816
}
3817

3818
static FORCE_INLINE int32_t tColDataUpdateValue10(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
10✔
3819
  pColData->numOfNone--;
10✔
3820
  pColData->nVal--;
10✔
3821
  if (pColData->numOfNone) {
10!
3822
    return tColDataAppendValue10(pColData, pData, nData);
×
3823
  } else {
3824
    pColData->flag = 0;
10✔
3825
    return tColDataAppendValue00(pColData, pData, nData);
10✔
3826
  }
3827
}
3828
static FORCE_INLINE int32_t tColDataUpdateValue12(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
24✔
3829
  pColData->numOfNone--;
24✔
3830
  pColData->nVal--;
24✔
3831
  if (pColData->numOfNone) {
24!
3832
    return tColDataAppendValue12(pColData, pData, nData);
×
3833
  } else {
3834
    pColData->flag = 0;
24✔
3835
    return tColDataAppendValue02(pColData, pData, nData);
24✔
3836
  }
3837
  return 0;
3838
}
3839
static FORCE_INLINE int32_t tColDataUpdateValue20(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
150✔
3840
  if (forward) {
150!
3841
    pColData->numOfNull--;
150✔
3842
    pColData->nVal--;
150✔
3843
    if (pColData->numOfNull) {
150!
3844
      return tColDataAppendValue20(pColData, pData, nData);
×
3845
    } else {
3846
      pColData->flag = 0;
150✔
3847
      return tColDataAppendValue00(pColData, pData, nData);
150✔
3848
    }
3849
  }
3850
  return 0;
×
3851
}
3852
static FORCE_INLINE int32_t tColDataUpdateValue30(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
×
3853
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
×
3854
    pColData->numOfNone--;
×
3855
    pColData->nVal--;
×
3856
    if (pColData->numOfNone) {
×
3857
      return tColDataAppendValue30(pColData, pData, nData);
×
3858
    } else {
3859
      pColData->flag = HAS_NULL;
×
3860
      return tColDataAppendValue20(pColData, pData, nData);
×
3861
    }
3862
  } else if (forward) {  // NULL ==> VALUE
×
3863
    pColData->numOfNull--;
×
3864
    pColData->nVal--;
×
3865
    if (pColData->numOfNull) {
×
3866
      return tColDataAppendValue30(pColData, pData, nData);
×
3867
    } else {
3868
      pColData->flag = HAS_NONE;
×
3869
      return tColDataAppendValue10(pColData, pData, nData);
×
3870
    }
3871
  }
3872
  return 0;
×
3873
}
3874
static FORCE_INLINE int32_t tColDataUpdateValue32(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
80✔
3875
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
80!
3876
    pColData->numOfNone--;
80✔
3877
    pColData->numOfNull++;
80✔
3878
    if (pColData->numOfNone) {
80!
3879
      SET_BIT1(pColData->pBitMap, pColData->nVal - 1, 1);
×
3880
    } else {
3881
      pColData->flag = HAS_NULL;
80✔
3882
    }
3883
  }
3884
  return 0;
80✔
3885
}
3886
static FORCE_INLINE int32_t tColDataUpdateValue40(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
60,612,972✔
3887
  if (forward) {  // VALUE ==> VALUE
60,612,972!
3888
    pColData->nVal--;
60,613,524✔
3889
    if (IS_VAR_DATA_TYPE(pColData->type)) {
60,613,524!
3890
      pColData->nData = pColData->aOffset[pColData->nVal];
2,598,829✔
3891
    } else {
3892
      pColData->nData -= TYPE_BYTES[pColData->type];
58,014,695✔
3893
    }
3894
    return tColDataPutValue(pColData, pData, nData);
60,702,514✔
3895
  }
3896
  return 0;
×
3897
}
3898
static FORCE_INLINE int32_t tColDataUpdateValue42(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
4,040✔
3899
  if (forward) {  // VALUE ==> NULL
4,040!
3900
    pColData->numOfValue--;
4,040✔
3901
    pColData->nVal--;
4,040✔
3902
    if (pColData->numOfValue) {
4,040✔
3903
      if (IS_VAR_DATA_TYPE(pColData->type)) {
4,003!
3904
        pColData->nData = pColData->aOffset[pColData->nVal];
800✔
3905
      } else {
3906
        pColData->nData -= TYPE_BYTES[pColData->type];
3,203✔
3907
      }
3908
      return tColDataAppendValue42(pColData, pData, nData);
4,002✔
3909
    } else {
3910
      pColData->flag = 0;
37✔
3911
      pColData->nData = 0;
37✔
3912
      return tColDataAppendValue02(pColData, pData, nData);
37✔
3913
    }
3914
  }
3915
  return 0;
×
3916
}
3917
static FORCE_INLINE int32_t tColDataUpdateValue50(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
32,711✔
3918
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> VALUE
32,711✔
3919
    pColData->numOfNone--;
4,477✔
3920
    pColData->nVal--;
4,477✔
3921
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
4,477!
3922
      pColData->nData -= TYPE_BYTES[pColData->type];
3,581✔
3923
    }
3924
    if (pColData->numOfNone) {
4,477✔
3925
      return tColDataAppendValue50(pColData, pData, nData);
1,600✔
3926
    } else {
3927
      pColData->flag = HAS_VALUE;
2,877✔
3928
      return tColDataAppendValue40(pColData, pData, nData);
2,878✔
3929
    }
3930
  } else if (forward) {  // VALUE ==> VALUE
28,234!
3931
    pColData->nVal--;
28,234✔
3932
    if (IS_VAR_DATA_TYPE(pColData->type)) {
28,234!
3933
      pColData->nData = pColData->aOffset[pColData->nVal];
4,040✔
3934
    } else {
3935
      pColData->nData -= TYPE_BYTES[pColData->type];
24,194✔
3936
    }
3937
    return tColDataPutValue(pColData, pData, nData);
28,234✔
3938
  }
3939
  return 0;
×
3940
}
3941
static FORCE_INLINE int32_t tColDataUpdateValue52(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
244✔
3942
  if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NONE ==> NULL
244!
3943
    pColData->numOfNone--;
244✔
3944
    pColData->nVal--;
244✔
3945
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
244!
3946
      pColData->nData -= TYPE_BYTES[pColData->type];
196✔
3947
    }
3948
    if (pColData->numOfNone) {
244!
3949
      return tColDataAppendValue52(pColData, pData, nData);
×
3950
    } else {
3951
      pColData->flag = HAS_VALUE;
244!
3952
      return tColDataAppendValue42(pColData, pData, nData);
244✔
3953
    }
3954
  } else if (forward) {  // VALUE ==> NULL
×
3955
    pColData->numOfValue--;
×
3956
    pColData->nVal--;
×
3957
    if (pColData->numOfValue) {
×
3958
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
3959
        pColData->nData = pColData->aOffset[pColData->nVal];
×
3960
      } else {
3961
        pColData->nData -= TYPE_BYTES[pColData->type];
×
3962
      }
3963
      return tColDataAppendValue52(pColData, pData, nData);
×
3964
    } else {
3965
      pColData->flag = HAS_NONE;
×
3966
      pColData->nData = 0;
×
3967
      return tColDataAppendValue12(pColData, pData, nData);
×
3968
    }
3969
  }
3970
  return 0;
×
3971
}
3972
static FORCE_INLINE int32_t tColDataUpdateValue60(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
26,225✔
3973
  if (forward) {
26,225!
3974
    if (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 0) {  // NULL ==> VALUE
26,226✔
3975
      pColData->numOfNull--;
18,360✔
3976
      pColData->nVal--;
18,360✔
3977
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
18,360!
3978
        pColData->nData -= TYPE_BYTES[pColData->type];
14,577✔
3979
      }
3980
      if (pColData->numOfNull) {
18,360✔
3981
        return tColDataAppendValue60(pColData, pData, nData);
2,107✔
3982
      } else {
3983
        pColData->flag = HAS_VALUE;
16,252✔
3984
        return tColDataAppendValue40(pColData, pData, nData);
16,254✔
3985
      }
3986
    } else {  // VALUE ==> VALUE
3987
      pColData->nVal--;
7,866✔
3988
      if (IS_VAR_DATA_TYPE(pColData->type)) {
7,866!
3989
        pColData->nData = pColData->aOffset[pColData->nVal];
1,902✔
3990
      } else {
3991
        pColData->nData -= TYPE_BYTES[pColData->type];
5,964✔
3992
      }
3993
      return tColDataPutValue(pColData, pData, nData);
7,868✔
3994
    }
3995
  }
3996
  return 0;
×
3997
}
3998
static FORCE_INLINE int32_t tColDataUpdateValue62(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
19,935✔
3999
  if (forward && (GET_BIT1(pColData->pBitMap, pColData->nVal - 1) == 1)) {  // VALUE ==> NULL
19,935!
4000
    pColData->numOfValue--;
8,105✔
4001
    pColData->nVal--;
8,105✔
4002
    if (pColData->numOfValue) {
8,105!
4003
      if (IS_VAR_DATA_TYPE(pColData->type)) {
8,105!
4004
        pColData->nData = pColData->aOffset[pColData->nVal];
1,762✔
4005
      } else {
4006
        pColData->nData -= TYPE_BYTES[pColData->type];
6,343✔
4007
      }
4008
      return tColDataAppendValue62(pColData, pData, nData);
8,105✔
4009
    } else {
4010
      pColData->flag = HAS_NULL;
×
4011
      pColData->nData = 0;
×
4012
      return tColDataAppendValue20(pColData, pData, nData);
×
4013
    }
4014
  }
4015
  return 0;
11,830✔
4016
}
4017
static FORCE_INLINE int32_t tColDataUpdateValue70(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
322✔
4018
  int32_t code = 0;
322✔
4019

4020
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
322✔
4021
  if (bv == 0) {  // NONE ==> VALUE
322✔
4022
    pColData->numOfNone--;
320✔
4023
    pColData->nVal--;
320✔
4024
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
320!
4025
      pColData->nData -= TYPE_BYTES[pColData->type];
256✔
4026
    }
4027
    if (pColData->numOfNone) {
320!
4028
      return tColDataAppendValue70(pColData, pData, nData);
×
4029
    } else {
4030
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
16,960✔
4031
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
16,640✔
4032
      }
4033
      pColData->flag = (HAS_VALUE | HAS_NULL);
320!
4034
      return tColDataAppendValue60(pColData, pData, nData);
320✔
4035
    }
4036
  } else if (bv == 1) {  // NULL ==> VALUE
2!
4037
    if (forward) {
2!
4038
      pColData->numOfNull--;
2✔
4039
      pColData->nVal--;
2✔
4040
      if (!IS_VAR_DATA_TYPE(pColData->type)) {
2!
4041
        pColData->nData -= TYPE_BYTES[pColData->type];
2✔
4042
      }
4043
      if (pColData->numOfNull) {
2!
4044
        return tColDataAppendValue70(pColData, pData, nData);
×
4045
      } else {
4046
        for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
6✔
4047
          SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) ? 1 : 0);
4✔
4048
        }
4049
        pColData->flag = (HAS_VALUE | HAS_NONE);
2!
4050
        return tColDataAppendValue50(pColData, pData, nData);
2✔
4051
      }
4052
    }
4053
  } else if (bv == 2) {  // VALUE ==> VALUE
×
4054
    if (forward) {
×
4055
      pColData->nVal--;
×
4056
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
4057
        pColData->nData = pColData->aOffset[pColData->nVal];
×
4058
      } else {
4059
        pColData->nData -= TYPE_BYTES[pColData->type];
×
4060
      }
4061
      return tColDataPutValue(pColData, pData, nData);
×
4062
    }
4063
  } else {
4064
    return TSDB_CODE_INVALID_PARA;
×
4065
  }
4066
  return 0;
×
4067
}
4068
static int32_t tColDataUpdateValue72(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
3,135✔
4069
  uint8_t bv = GET_BIT2(pColData->pBitMap, pColData->nVal - 1);
3,135✔
4070
  if (bv == 0) {  // NONE ==> NULL
3,135!
4071
    pColData->numOfNone--;
3,135✔
4072
    pColData->nVal--;
3,135✔
4073
    if (!IS_VAR_DATA_TYPE(pColData->type)) {
3,135!
4074
      pColData->nData -= TYPE_BYTES[pColData->type];
2,172✔
4075
    }
4076
    if (pColData->numOfNone) {
3,135!
4077
      return tColDataAppendValue72(pColData, pData, nData);
×
4078
    } else {
4079
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
100,311✔
4080
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal) - 1);
97,176✔
4081
      }
4082
      pColData->flag = (HAS_VALUE | HAS_NULL);
3,135!
4083
      return tColDataAppendValue62(pColData, pData, nData);
3,136✔
4084
    }
4085
  } else if (bv == 2 && forward) {  // VALUE ==> NULL
×
4086
    pColData->numOfValue--;
×
4087
    pColData->nVal--;
×
4088
    if (pColData->numOfValue) {
×
4089
      if (IS_VAR_DATA_TYPE(pColData->type)) {
×
4090
        pColData->nData = pColData->aOffset[pColData->nVal];
×
4091
      } else {
4092
        pColData->nData -= TYPE_BYTES[pColData->type];
×
4093
      }
4094
      return tColDataAppendValue72(pColData, pData, nData);
×
4095
    } else {
4096
      for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
×
4097
        SET_BIT1(pColData->pBitMap, iVal, GET_BIT2(pColData->pBitMap, iVal));
×
4098
      }
4099
      pColData->flag = (HAS_NULL | HAS_NONE);
×
4100
      pColData->nData = 0;
×
4101
      return tColDataAppendValue32(pColData, pData, nData);
×
4102
    }
4103
  }
4104
  return 0;
×
4105
}
4106
static FORCE_INLINE int32_t tColDataUpdateNothing(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) {
14,852✔
4107
  return 0;
14,852✔
4108
}
4109
static int32_t (*tColDataUpdateValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward) = {
4110
    {NULL, NULL, NULL},                                                     // 0
4111
    {tColDataUpdateValue10, tColDataUpdateNothing, tColDataUpdateValue12},  // HAS_NONE
4112
    {tColDataUpdateValue20, tColDataUpdateNothing, tColDataUpdateNothing},  // HAS_NULL
4113
    {tColDataUpdateValue30, tColDataUpdateNothing, tColDataUpdateValue32},  // HAS_NULL|HAS_NONE
4114
    {tColDataUpdateValue40, tColDataUpdateNothing, tColDataUpdateValue42},  // HAS_VALUE
4115
    {tColDataUpdateValue50, tColDataUpdateNothing, tColDataUpdateValue52},  // HAS_VALUE|HAS_NONE
4116
    {tColDataUpdateValue60, tColDataUpdateNothing, tColDataUpdateValue62},  // HAS_VALUE|HAS_NULL
4117
    {tColDataUpdateValue70, tColDataUpdateNothing, tColDataUpdateValue72},  // HAS_VALUE|HAS_NULL|HAS_NONE
4118

4119
    //    VALUE             NONE        NULL
4120
};
4121
int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward) {
58,744,737✔
4122
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) return TSDB_CODE_INVALID_PARA;
58,744,737!
4123
  if (!(pColData->nVal > 0)) return TSDB_CODE_INVALID_PARA;
58,746,650!
4124

4125
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
58,746,650!
4126

4127
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
58,746,650✔
4128
      pColData, VALUE_GET_DATUM(&pColVal->value, pColData->type), pColVal->value.nData, forward);
58,746,650!
4129
}
4130

4131
static FORCE_INLINE void tColDataGetValue1(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NONE
127,480,693✔
4132
  *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
127,480,693✔
4133
}
127,480,693✔
4134
static FORCE_INLINE void tColDataGetValue2(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_NULL
3,400,351✔
4135
  *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
3,400,351✔
4136
}
3,400,351✔
4137
static FORCE_INLINE void tColDataGetValue3(SColData *pColData, int32_t iVal,
9,021✔
4138
                                           SColVal *pColVal) {  // HAS_NULL|HAS_NONE
4139
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
9,021!
4140
    case 0:
821✔
4141
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
821✔
4142
      break;
821✔
4143
    case 1:
8,200✔
4144
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
8,200✔
4145
      break;
8,200✔
4146
    default:
×
4147
      break;
×
4148
  }
4149
}
9,021✔
4150
static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SColVal *pColVal) {  // HAS_VALUE
2,147,483,647✔
4151
  SValue value = {.type = pColData->type};
2,147,483,647✔
4152
  if (IS_VAR_DATA_TYPE(pColData->type)) {
2,147,483,647!
4153
    if (iVal + 1 < pColData->nVal) {
263,476,145!
4154
      value.nData = pColData->aOffset[iVal + 1] - pColData->aOffset[iVal];
274,462,516✔
4155
    } else {
4156
      value.nData = pColData->nData - pColData->aOffset[iVal];
×
4157
    }
4158
    value.pData = pColData->pData + pColData->aOffset[iVal];
263,476,145✔
4159
  } else {
4160
    valueSetDatum(&value, pColData->type, pColData->pData + tDataTypes[pColData->type].bytes * iVal,
2,147,483,647✔
4161
                  tDataTypes[pColData->type].bytes);
2,147,483,647✔
4162
  }
4163
  *pColVal = COL_VAL_VALUE(pColData->cid, value);
2,147,483,647✔
4164
}
197,825,221✔
4165
static FORCE_INLINE void tColDataGetValue5(SColData *pColData, int32_t iVal,
9,736,114✔
4166
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NONE
4167
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
9,736,114!
4168
    case 0:
4,926,665✔
4169
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
4,926,665✔
4170
      break;
4,926,665✔
4171
    case 1:
4,956,494✔
4172
      tColDataGetValue4(pColData, iVal, pColVal);
4173
      break;
5,000,095✔
4174
    default:
×
4175
      break;
×
4176
  }
4177
}
9,779,715✔
4178
static FORCE_INLINE void tColDataGetValue6(SColData *pColData, int32_t iVal,
219,085,743✔
4179
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL
4180
  switch (GET_BIT1(pColData->pBitMap, iVal)) {
219,085,743!
4181
    case 0:
27,664,340✔
4182
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
27,664,340✔
4183
      break;
27,664,340✔
4184
    case 1:
191,827,757✔
4185
      tColDataGetValue4(pColData, iVal, pColVal);
4186
      break;
192,825,094✔
4187
    default:
×
4188
      break;
×
4189
  }
4190
}
220,083,080✔
4191
static FORCE_INLINE void tColDataGetValue7(SColData *pColData, int32_t iVal,
22✔
4192
                                           SColVal *pColVal) {  // HAS_VALUE|HAS_NULL|HAS_NONE
4193
  switch (GET_BIT2(pColData->pBitMap, iVal)) {
22!
4194
    case 0:
10✔
4195
      *pColVal = COL_VAL_NONE(pColData->cid, pColData->type);
10✔
4196
      break;
10✔
4197
    case 1:
10✔
4198
      *pColVal = COL_VAL_NULL(pColData->cid, pColData->type);
10✔
4199
      break;
10✔
4200
    case 2:
2!
4201
      tColDataGetValue4(pColData, iVal, pColVal);
4202
      break;
2✔
4203
    default:
×
4204
      break;
×
4205
  }
4206
}
22✔
4207
static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal *pColVal) = {
4208
    NULL,               // 0
4209
    tColDataGetValue1,  // HAS_NONE
4210
    tColDataGetValue2,  // HAS_NULL
4211
    tColDataGetValue3,  // HAS_NULL | HAS_NONE
4212
    tColDataGetValue4,  // HAS_VALUE
4213
    tColDataGetValue5,  // HAS_VALUE | HAS_NONE
4214
    tColDataGetValue6,  // HAS_VALUE | HAS_NULL
4215
    tColDataGetValue7   // HAS_VALUE | HAS_NULL | HAS_NONE
4216
};
4217
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
2,147,483,647✔
4218
  if (iVal < 0 || iVal >= pColData->nVal ||
2,147,483,647!
4219
      (pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
2,147,483,647!
4220
    return TSDB_CODE_INVALID_PARA;
×
4221
  }
4222
  tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
2,147,483,647✔
4223
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
4224
}
4225

4226
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
651,686,191✔
4227
  switch (pColData->flag) {
651,686,191!
4228
    case HAS_NONE:
×
4229
      return 0;
×
4230
    case HAS_NULL:
×
4231
      return 1;
×
4232
    case (HAS_NULL | HAS_NONE):
9,000✔
4233
      return GET_BIT1(pColData->pBitMap, iVal);
9,000✔
4234
    case HAS_VALUE:
×
4235
      return 2;
×
4236
    case (HAS_VALUE | HAS_NONE):
10,756,175✔
4237
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
10,756,175✔
4238
    case (HAS_VALUE | HAS_NULL):
640,932,076✔
4239
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
640,932,076✔
4240
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
44✔
4241
      return GET_BIT2(pColData->pBitMap, iVal);
44✔
4242
    default:
×
4243
      return 0;
×
4244
  }
4245
}
4246

4247
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg) {
3,348✔
4248
  int32_t code = 0;
3,348✔
4249

4250
  *pColData = *pColDataFrom;
3,348✔
4251

4252
  // bitmap
4253
  switch (pColData->flag) {
3,348!
4254
    case (HAS_NULL | HAS_NONE):
77✔
4255
    case (HAS_VALUE | HAS_NONE):
4256
    case (HAS_VALUE | HAS_NULL):
4257
      pColData->pBitMap = xMalloc(arg, BIT1_SIZE(pColData->nVal));
77✔
4258
      if (pColData->pBitMap == NULL) {
77!
4259
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4260
        goto _exit;
×
4261
      }
4262
      (void)memcpy(pColData->pBitMap, pColDataFrom->pBitMap, BIT1_SIZE(pColData->nVal));
77✔
4263
      break;
77✔
4264
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
4265
      pColData->pBitMap = xMalloc(arg, BIT2_SIZE(pColData->nVal));
×
4266
      if (pColData->pBitMap == NULL) {
×
4267
        code = TSDB_CODE_OUT_OF_MEMORY;
×
4268
        goto _exit;
×
4269
      }
4270
      (void)memcpy(pColData->pBitMap, pColDataFrom->pBitMap, BIT2_SIZE(pColData->nVal));
×
4271
      break;
×
4272
    default:
3,271✔
4273
      pColData->pBitMap = NULL;
3,271✔
4274
      break;
3,271✔
4275
  }
4276

4277
  // offset
4278
  if (IS_VAR_DATA_TYPE(pColData->type) && (pColData->flag & HAS_VALUE)) {
3,348!
4279
    pColData->aOffset = xMalloc(arg, pColData->nVal << 2);
524✔
4280
    if (pColData->aOffset == NULL) {
524!
4281
      code = TSDB_CODE_OUT_OF_MEMORY;
×
4282
      goto _exit;
×
4283
    }
4284
    (void)memcpy(pColData->aOffset, pColDataFrom->aOffset, pColData->nVal << 2);
524✔
4285
  } else {
4286
    pColData->aOffset = NULL;
2,824✔
4287
  }
4288

4289
  // value
4290
  if (pColData->nData) {
3,348✔
4291
    pColData->pData = xMalloc(arg, pColData->nData);
3,197✔
4292
    if (pColData->pData == NULL) {
3,197!
4293
      code = TSDB_CODE_OUT_OF_MEMORY;
×
4294
      goto _exit;
×
4295
    }
4296

4297
    (void)memcpy(pColData->pData, pColDataFrom->pData, pColData->nData);
3,197✔
4298
  } else {
4299
    pColData->pData = NULL;
151✔
4300
  }
4301

4302
_exit:
3,348✔
4303
  return code;
3,348✔
4304
}
4305

4306
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
2,331,669✔
4307
  int32_t code;
4308
  SBuffer local;
4309

4310
  if (!(colData->nVal > 0)) {
2,331,669!
4311
    return TSDB_CODE_INVALID_PARA;
×
4312
  }
4313

4314
  (*info) = (SColDataCompressInfo){
2,331,669✔
4315
      .cmprAlg = info->cmprAlg,
2,331,669✔
4316
      .columnFlag = colData->cflag,
2,331,669✔
4317
      .flag = colData->flag,
2,331,669✔
4318
      .dataType = colData->type,
2,331,669✔
4319
      .columnId = colData->cid,
2,331,669✔
4320
      .numOfData = colData->nVal,
2,331,669✔
4321
  };
4322

4323
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
2,331,669!
4324
    return 0;
15,451✔
4325
  }
4326

4327
  tBufferInit(&local);
4328
  if (assist == NULL) {
2,316,218!
4329
    assist = &local;
×
4330
  }
4331

4332
  // bitmap
4333
  if (colData->flag != HAS_VALUE) {
2,316,218✔
4334
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
268,775✔
4335
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
34,909✔
4336
    } else {
4337
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
233,866✔
4338
    }
4339

4340
    SCompressInfo cinfo = {
268,775✔
4341
        .dataType = TSDB_DATA_TYPE_TINYINT,
4342
        .cmprAlg = info->cmprAlg,
268,775✔
4343
        .originalSize = info->bitmapOriginalSize,
268,775✔
4344
    };
4345

4346
    code = tCompressDataToBuffer(colData->pBitMap, &cinfo, output, assist);
268,775✔
4347
    if (code) {
268,838!
4348
      tBufferDestroy(&local);
4349
      return code;
×
4350
    }
4351

4352
    info->bitmapCompressedSize = cinfo.compressedSize;
268,838✔
4353
  }
4354

4355
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
2,316,281✔
4356
    tBufferDestroy(&local);
4357
    return 0;
10,477✔
4358
  }
4359

4360
  // offset
4361
  if (IS_VAR_DATA_TYPE(colData->type)) {
2,305,804!
4362
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
120,168✔
4363

4364
    SCompressInfo cinfo = {
120,168✔
4365
        .dataType = TSDB_DATA_TYPE_INT,
4366
        .cmprAlg = info->cmprAlg,
120,168✔
4367
        .originalSize = info->offsetOriginalSize,
120,168✔
4368
    };
4369

4370
    code = tCompressDataToBuffer(colData->aOffset, &cinfo, output, assist);
120,168✔
4371
    if (code) {
120,116!
4372
      tBufferDestroy(&local);
4373
      return code;
×
4374
    }
4375

4376
    info->offsetCompressedSize = cinfo.compressedSize;
120,116✔
4377
  }
4378

4379
  // data
4380
  if (colData->nData > 0) {
2,305,752!
4381
    info->dataOriginalSize = colData->nData;
2,305,763✔
4382

4383
    SCompressInfo cinfo = {
2,305,763✔
4384
        .dataType = colData->type,
2,305,763✔
4385
        .cmprAlg = info->cmprAlg,
2,305,763✔
4386
        .originalSize = info->dataOriginalSize,
2,305,763✔
4387
    };
4388

4389
    code = tCompressDataToBuffer(colData->pData, &cinfo, output, assist);
2,305,763✔
4390
    if (code) {
2,306,081!
4391
      tBufferDestroy(&local);
4392
      return code;
×
4393
    }
4394

4395
    info->dataCompressedSize = cinfo.compressedSize;
2,306,081✔
4396
  }
4397

4398
  tBufferDestroy(&local);
4399
  return 0;
2,306,070✔
4400
}
4401

4402
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
20,897,268✔
4403
  int32_t  code;
4404
  SBuffer  local;
4405
  uint8_t *data = (uint8_t *)input;
20,897,268✔
4406

4407
  tBufferInit(&local);
4408
  if (assist == NULL) {
20,897,268!
4409
    assist = &local;
×
4410
  }
4411

4412
  tColDataClear(colData);
20,897,268✔
4413
  colData->cid = info->columnId;
20,895,526✔
4414
  colData->type = info->dataType;
20,895,526✔
4415
  colData->cflag = info->columnFlag;
20,895,526✔
4416
  colData->nVal = info->numOfData;
20,895,526✔
4417
  colData->flag = info->flag;
20,895,526✔
4418

4419
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
20,895,526✔
4420
    goto _exit;
3,584,246✔
4421
  }
4422

4423
  // bitmap
4424
  if (info->bitmapOriginalSize > 0) {
17,311,280✔
4425
    SCompressInfo cinfo = {
1,209,751✔
4426
        .dataType = TSDB_DATA_TYPE_TINYINT,
4427
        .cmprAlg = info->cmprAlg,
1,209,751✔
4428
        .originalSize = info->bitmapOriginalSize,
1,209,751✔
4429
        .compressedSize = info->bitmapCompressedSize,
1,209,751✔
4430
    };
4431

4432
    code = tRealloc(&colData->pBitMap, cinfo.originalSize);
1,209,751!
4433
    if (code) {
1,209,170!
4434
      tBufferDestroy(&local);
4435
      return code;
×
4436
    }
4437

4438
    code = tDecompressData(data, &cinfo, colData->pBitMap, cinfo.originalSize, assist);
1,209,170✔
4439
    if (code) {
1,209,376!
4440
      tBufferDestroy(&local);
4441
      return code;
×
4442
    }
4443

4444
    data += cinfo.compressedSize;
1,209,376✔
4445
  }
4446

4447
  if (info->flag == (HAS_NONE | HAS_NULL)) {
17,310,905✔
4448
    goto _exit;
484✔
4449
  }
4450

4451
  // offset
4452
  if (info->offsetOriginalSize > 0) {
17,310,421✔
4453
    SCompressInfo cinfo = {
2,753,924✔
4454
        .cmprAlg = info->cmprAlg,
2,753,924✔
4455
        .dataType = TSDB_DATA_TYPE_INT,
4456
        .originalSize = info->offsetOriginalSize,
2,753,924✔
4457
        .compressedSize = info->offsetCompressedSize,
2,753,924✔
4458
    };
4459

4460
    code = tRealloc((uint8_t **)&colData->aOffset, cinfo.originalSize);
2,753,924!
4461
    if (code) {
2,754,146!
4462
      tBufferDestroy(&local);
4463
      return code;
×
4464
    }
4465

4466
    code = tDecompressData(data, &cinfo, colData->aOffset, cinfo.originalSize, assist);
2,754,146✔
4467
    if (code) {
2,753,890!
4468
      tBufferDestroy(&local);
4469
      return code;
×
4470
    }
4471

4472
    data += cinfo.compressedSize;
2,753,890✔
4473
  }
4474

4475
  // data
4476
  if (info->dataOriginalSize > 0) {
17,310,387✔
4477
    colData->nData = info->dataOriginalSize;
17,309,538✔
4478

4479
    SCompressInfo cinfo = {
17,309,538✔
4480
        .cmprAlg = info->cmprAlg,
17,309,538✔
4481
        .dataType = colData->type,
17,309,538✔
4482
        .originalSize = info->dataOriginalSize,
17,309,538✔
4483
        .compressedSize = info->dataCompressedSize,
17,309,538✔
4484
    };
4485

4486
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
17,309,538!
4487
    if (code) {
17,310,461!
4488
      tBufferDestroy(&local);
4489
      return code;
×
4490
    }
4491

4492
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
17,310,461✔
4493
    if (code) {
17,309,793!
4494
      tBufferDestroy(&local);
4495
      return code;
×
4496
    }
4497

4498
    data += cinfo.compressedSize;
17,309,793✔
4499
  }
4500

4501
_exit:
849✔
4502
  switch (colData->flag) {
20,895,372✔
4503
    case HAS_NONE:
3,257,624✔
4504
      colData->numOfNone = colData->nVal;
3,257,624✔
4505
      break;
3,257,624✔
4506
    case HAS_NULL:
330,259✔
4507
      colData->numOfNull = colData->nVal;
330,259✔
4508
      break;
330,259✔
4509
    case HAS_VALUE:
16,099,965✔
4510
      colData->numOfValue = colData->nVal;
16,099,965✔
4511
      break;
16,099,965✔
4512
    default:
1,207,524✔
4513
      for (int32_t i = 0; i < colData->nVal; i++) {
380,236,422✔
4514
        uint8_t bitValue = tColDataGetBitValue(colData, i);
379,034,529✔
4515
        if (bitValue == 0) {
379,028,898✔
4516
          colData->numOfNone++;
5,219,652✔
4517
        } else if (bitValue == 1) {
373,809,246✔
4518
          colData->numOfNull++;
75,488,531✔
4519
        } else {
4520
          colData->numOfValue++;
298,320,715✔
4521
        }
4522
      }
4523
  }
4524
  tBufferDestroy(&local);
4525
  return 0;
20,889,741✔
4526
}
4527

4528
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
98✔
4529
                                    char *data) {
4530
  int32_t code = 0;
98✔
4531
  if (data == NULL) {
98✔
4532
    if (pColData->cflag & COL_IS_KEY) {
4!
4533
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4534
    } else {
4535
      for (int32_t i = 0; i < nRows; ++i) {
8✔
4536
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
4✔
4537
      }
4538
    }
4539
    goto _exit;
4✔
4540
  }
4541

4542
  if (IS_VAR_DATA_TYPE(type)) {  // var-length data type
94!
4543
    if (!IS_STR_DATA_BLOB(type)) {
3!
4544
      for (int32_t i = 0; i < nRows; ++i) {
7✔
4545
        int32_t offset = *((int32_t *)lengthOrbitmap + i);
4✔
4546
        if (offset == -1) {
4!
4547
          if (pColData->cflag & COL_IS_KEY) {
×
4548
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4549
            goto _exit;
×
4550
          }
4551
          if ((code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0))) {
×
4552
            goto _exit;
×
4553
          }
4554
        } else {
4555
          if (varDataTLen(data + offset) > bytes) {
4!
4556
            uError("var data length invalid, varDataTLen(data + offset):%d > bytes:%d", (int)varDataTLen(data + offset),
×
4557
                   bytes);
4558
            code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4559
            goto _exit;
×
4560
          }
4561
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)varDataVal(data + offset),
4✔
4562
                                                                        varDataLen(data + offset));
4✔
4563
        }
4564
      }
4565
    } else {
4566
      for (int32_t i = 0; i < nRows; ++i) {
×
4567
        int32_t offset = *((int32_t *)lengthOrbitmap + i);
×
4568
        if (offset == -1) {
×
4569
          if (pColData->cflag & COL_IS_KEY) {
×
4570
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4571
            goto _exit;
×
4572
          }
4573
          if ((code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0))) {
×
4574
            goto _exit;
×
4575
          }
4576
        } else {
4577
          if (blobDataTLen(data + offset) > TSDB_MAX_BLOB_LEN) {
×
4578
            uError("var data length invalid, varDataTLen(data + offset):%d > bytes:%d",
×
4579
                   (int)blobDataTLen(data + offset), bytes);
4580
            code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4581
            goto _exit;
×
4582
          }
4583
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)blobDataVal(data + offset),
×
4584
                                                                        blobDataLen(data + offset));
×
4585
        }
4586
      }
4587
    }
4588
  } else {  // fixed-length data type
4589
    bool allValue = true;
91✔
4590
    bool allNull = true;
91✔
4591
    for (int32_t i = 0; i < nRows; ++i) {
264✔
4592
      if (!colDataIsNull_f(lengthOrbitmap, i)) {
173✔
4593
        allNull = false;
16✔
4594
      } else {
4595
        allValue = false;
157✔
4596
      }
4597
    }
4598
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
91!
4599
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4600
      goto _exit;
×
4601
    }
4602

4603
    if (allValue) {
91✔
4604
      // optimize (todo)
4605
      for (int32_t i = 0; i < nRows; ++i) {
27✔
4606
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
16✔
4607
      }
4608
    } else if (allNull) {
80!
4609
      // optimize (todo)
4610
      for (int32_t i = 0; i < nRows; ++i) {
237✔
4611
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
157✔
4612
        if (code) goto _exit;
157!
4613
      }
4614
    } else {
4615
      for (int32_t i = 0; i < nRows; ++i) {
×
4616
        if (colDataIsNull_f(lengthOrbitmap, i)) {
×
4617
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
4618
          if (code) goto _exit;
×
4619
        } else {
4620
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, (uint8_t *)data + bytes * i, bytes);
×
4621
        }
4622
      }
4623
    }
4624
  }
4625

4626
_exit:
×
4627
  return code;
98✔
4628
}
4629

4630
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
1,197,206✔
4631
                               checkWKBGeometryFn cgeos) {
4632
  int32_t code = 0;
1,197,206✔
4633

4634
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
1,197,206!
4635
    if (!(pColData->type == pBind->buffer_type)) {
1,196,571!
4636
      return TSDB_CODE_INVALID_PARA;
×
4637
    }
4638
  }
4639

4640
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
1,197,206!
4641
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
42,305✔
4642
      code = igeos();
3✔
4643
      if (code) {
3!
4644
        return code;
×
4645
      }
4646
    }
4647
    for (int32_t i = 0; i < pBind->num; ++i) {
95,690✔
4648
      if (pBind->is_null && pBind->is_null[i]) {
53,606✔
4649
        if (pColData->cflag & COL_IS_KEY) {
573!
4650
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4651
          goto _exit;
×
4652
        }
4653
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
573✔
4654
        if (code) goto _exit;
571!
4655
      } else if (pBind->length[i] > buffMaxLen) {
53,033!
4656
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4657
      } else {
4658
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
53,033✔
4659
          code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]);
5✔
4660
          if (code) {
5✔
4661
            uError("stmt col[%d] bind geometry wrong format", i);
1!
4662
            goto _exit;
1✔
4663
          }
4664
        }
4665
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
53,032✔
4666
            pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
53,032✔
4667
      }
4668
    }
4669
  } else {  // fixed-length data type
4670
    bool allValue;
4671
    bool allNull;
4672
    if (pBind->is_null) {
1,154,901✔
4673
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
80,402✔
4674
      allNull = (same && pBind->is_null[0] != 0);
80,402!
4675
      allValue = (same && pBind->is_null[0] == 0);
80,402✔
4676
    } else {
4677
      allNull = false;
1,074,499✔
4678
      allValue = true;
1,074,499✔
4679
    }
4680

4681
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
1,154,901!
4682
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4683
      goto _exit;
×
4684
    }
4685

4686
    if (allValue) {
1,154,901✔
4687
      // optimize (todo)
4688
      for (int32_t i = 0; i < pBind->num; ++i) {
252,265,800✔
4689
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
251,330,250✔
4690
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
251,330,250✔
4691
      }
4692
    } else if (allNull) {
15,937✔
4693
      // optimize (todo)
4694
      for (int32_t i = 0; i < pBind->num; ++i) {
124✔
4695
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
62✔
4696
        if (code) goto _exit;
62!
4697
      }
4698
    } else {
4699
      for (int32_t i = 0; i < pBind->num; ++i) {
15,875!
4700
        if (pBind->is_null[i]) {
×
4701
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
4702
          if (code) goto _exit;
×
4703
        } else {
4704
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
×
4705
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
×
4706
        }
4707
      }
4708
    }
4709
  }
4710

4711
_exit:
15,875✔
4712
  return code;
993,572✔
4713
}
4714

4715
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
350✔
4716
                                checkWKBGeometryFn cgeos) {
4717
  int32_t code = 0;
350✔
4718

4719
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
350!
4720
    if (!(pColData->type == pBind->buffer_type)) {
350!
4721
      return TSDB_CODE_INVALID_PARA;
×
4722
    }
4723
  }
4724

4725
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
493!
4726
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
143✔
4727
      code = igeos();
15✔
4728
      if (code) {
15!
4729
        return code;
×
4730
      }
4731
    }
4732

4733
    uint8_t *buf = pBind->buffer;
143✔
4734
    for (int32_t i = 0; i < pBind->num; ++i) {
559✔
4735
      if (pBind->is_null && pBind->is_null[i]) {
416✔
4736
        if (pColData->cflag & COL_IS_KEY) {
2!
4737
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4738
          goto _exit;
×
4739
        }
4740
        if (pBind->is_null[i] == 1) {
2!
4741
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
2✔
4742
          if (code) goto _exit;
2!
4743
        } else {
4744
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
4745
          if (code) goto _exit;
×
4746
        }
4747
      } else if (pBind->length[i] > buffMaxLen) {
414!
4748
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4749
      } else {
4750
        if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
414✔
4751
          code = cgeos(buf, pBind->length[i]);
19✔
4752
          if (code) {
19!
4753
            uError("stmt2 col[%d] bind geometry wrong format", i);
×
4754
            goto _exit;
×
4755
          }
4756
        }
4757
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);
414✔
4758
        buf += pBind->length[i];
414✔
4759
      }
4760
    }
4761
  } else {  // fixed-length data type
4762
    bool allValue;
4763
    bool allNull;
4764
    bool allNone;
4765
    if (pBind->is_null) {
207✔
4766
      bool same = (memcmp(pBind->is_null, pBind->is_null + 1, pBind->num - 1) == 0);
2✔
4767
      allNull = (same && pBind->is_null[0] == 1);
2!
4768
      allNone = (same && pBind->is_null[0] > 1);
2!
4769
      allValue = (same && pBind->is_null[0] == 0);
2!
4770
    } else {
4771
      allNull = false;
205✔
4772
      allNone = false;
205✔
4773
      allValue = true;
205✔
4774
    }
4775

4776
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
207!
4777
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4778
      goto _exit;
×
4779
    }
4780

4781
    if (allValue) {
207!
4782
      // optimize (todo)
4783
      for (int32_t i = 0; i < pBind->num; ++i) {
654✔
4784
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
447✔
4785
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
447!
4786
          *val = 1;
1✔
4787
        }
4788

4789
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
447✔
4790
      }
4791
    } else if (allNull) {
×
4792
      // optimize (todo)
4793
      for (int32_t i = 0; i < pBind->num; ++i) {
×
4794
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
4795
        if (code) goto _exit;
×
4796
      }
4797
    } else if (allNone) {
×
4798
      // optimize (todo)
4799
      for (int32_t i = 0; i < pBind->num; ++i) {
×
4800
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
4801
        if (code) goto _exit;
×
4802
      }
4803
    } else {
4804
      for (int32_t i = 0; i < pBind->num; ++i) {
×
4805
        if (pBind->is_null[i]) {
×
4806
          if (pBind->is_null[i] == 1) {
×
4807
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
4808
            if (code) goto _exit;
×
4809
          } else {
4810
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0);
×
4811
            if (code) goto _exit;
×
4812
          }
4813
        } else {
4814
          uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
4815
          if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
4816
            *val = 1;
×
4817
          }
4818

4819
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
4820
        }
4821
      }
4822
    }
4823
  }
4824

4825
_exit:
×
4826
  return code;
350✔
4827
}
4828
int32_t tColDataAddValueByBind2WithBlob(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen,
1✔
4829
                                        SBlobSet *pBlobSet) {
4830
  int32_t code = 0;
1✔
4831

4832
  if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
1!
4833
    if (!(pColData->type == pBind->buffer_type)) {
1!
4834
      return TSDB_CODE_INVALID_PARA;
×
4835
    }
4836
  }
4837

4838
  if (IS_STR_DATA_BLOB(pColData->type)) {  // var-length data type
1!
4839
    uint8_t *buf = pBind->buffer;
1✔
4840
    for (int32_t i = 0; i < pBind->num; ++i) {
11✔
4841
      if (pBind->is_null && pBind->is_null[i]) {
10!
4842
        if (pColData->cflag & COL_IS_KEY) {
×
4843
          code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
4844
          goto _exit;
×
4845
        }
4846
        if (pBind->is_null[i] == 1) {
×
4847
          code = tColDataAppendValueBlobImpl[pColData->flag][CV_FLAG_NULL](pBlobSet, pColData, NULL, 0);
×
4848
          if (code) goto _exit;
×
4849
        } else {
4850
          code = tColDataAppendValueBlobImpl[pColData->flag][CV_FLAG_NONE](pBlobSet, pColData, NULL, 0);
×
4851
          if (code) goto _exit;
×
4852
        }
4853
      } else if (pBind->length[i] > buffMaxLen) {
10!
4854
        return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4855
      } else {
4856
        code = tColDataAppendValueBlobImpl[pColData->flag][CV_FLAG_VALUE](pBlobSet, pColData, buf, pBind->length[i]);
10✔
4857
        buf += pBind->length[i];
10✔
4858
      }
4859
    }
4860
  }
4861
_exit:
1✔
4862
  return code;
1✔
4863
}
4864

4865
/* build rows to `rowArray` from bind
4866
 * `infos` is the bind information array
4867
 * `numOfInfos` is the number of bind information
4868
 * `infoSorted` is whether the bind information is sorted by column id
4869
 * `pTSchema` is the schema of the table
4870
 * `rowArray` is the array to store the rows
4871
 * `pOrdered` is the pointer to store ordered
4872
 * `pDupTs` is the pointer to store duplicateTs
4873
 */
4874
int32_t tRowBuildFromBind2(SBindInfo2 *infos, int32_t numOfInfos, SSHashObj *parsedCols, bool infoSorted,
7,497✔
4875
                           const STSchema *pTSchema, SArray *rowArray, bool *pOrdered, bool *pDupTs) {
4876
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
7,497!
4877
    return TSDB_CODE_INVALID_PARA;
×
4878
  }
4879
  int8_t hasBlob = schemaHasBlob(pTSchema);
7,501✔
4880
  if (!infoSorted) {
7,501✔
4881
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo2), NULL, tBindInfoCompare);
7✔
4882
  }
4883

4884
  int32_t code = 0;
7,501✔
4885
  int32_t numOfRows = infos[0].bind->num;
7,501✔
4886
  SArray *colValArray, *bufArray;
4887
  SColVal colVal;
4888
  int32_t numOfFixedValue = 0;
7,501✔
4889

4890
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
7,501!
4891
    return terrno;
×
4892
  }
4893
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
7,496✔
4894
    taosArrayDestroy(colValArray);
2✔
4895
    return terrno;
×
4896
  }
4897
  for (int i = 0; i < numOfInfos; ++i) {
117,484✔
4898
    if (parsedCols) {
109,983✔
4899
      SColVal *pParsedVal = tSimpleHashGet(parsedCols, &infos[i].columnId, sizeof(int16_t));
132✔
4900
      if (pParsedVal) {
132✔
4901
        continue;
24✔
4902
      }
4903
    }
4904
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
219,925!
4905
      taosArrayDestroy(colValArray);
×
4906
      taosArrayDestroy(bufArray);
×
4907
      return terrno;
×
4908
    }
4909
  }
4910

4911
  SRowKey rowKey, lastRowKey;
4912
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
253,554✔
4913
    taosArrayClear(colValArray);
250,496✔
4914

4915
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
1,375,387✔
4916
      if (parsedCols) {
1,113,572✔
4917
        SColVal *pParsedVal = tSimpleHashGet(parsedCols, &infos[iInfo].columnId, sizeof(int16_t));
132✔
4918
        if (pParsedVal) {
132!
4919
          numOfFixedValue++;
×
4920
          colVal = *pParsedVal;
×
4921

4922
          if (taosArrayPush(colValArray, &colVal) == NULL) {
24!
4923
            if (IS_VAR_DATA_TYPE(pParsedVal->value.type)) {
×
4924
              taosMemoryFree(colVal.value.pData);
×
4925
            }
4926
            code = terrno;
×
4927
            goto _exit;
1✔
4928
          }
4929
          continue;
24✔
4930
        }
4931
      }
4932

4933
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
1,118,018✔
4934
        if (infos[iInfo].bind->is_null[iRow] == 1) {
2!
4935
          if (iInfo == 0) {
2✔
4936
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
1✔
4937
            goto _exit;
1✔
4938
          }
4939
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
1✔
4940
        } else {
4941
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
4942
        }
4943
      } else {
4944
        SValue value = {
1,118,016✔
4945
            .type = infos[iInfo].type,
1,118,016✔
4946
        };
4947
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
1,118,016!
4948
          if (IS_STR_DATA_BLOB(infos[iInfo].type)) {
85,793!
4949
            int32_t   length = infos[iInfo].bind->length[iRow];
×
4950
            uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo - numOfFixedValue];
×
4951
            value.nData = length;
×
4952
            if (value.nData > (TSDB_MAX_BLOB_LEN - BLOBSTR_HEADER_SIZE)) {
×
4953
              code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4954
              uError("stmt bind param[%d] length:%d  greater than type maximum lenght: %d", iInfo,
×
4955
                     value.nData + (uint32_t)(BLOBSTR_HEADER_SIZE), infos[iInfo].bytes);
4956
              goto _exit;
×
4957
            }
4958
            value.pData = *data;
×
4959
            *data += length;
×
4960
          } else {
4961
            int32_t   length = infos[iInfo].bind->length[iRow];
85,793✔
4962
            uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo - numOfFixedValue];
85,793✔
4963
            value.nData = length;
85,793✔
4964
            if (value.nData > infos[iInfo].bytes - VARSTR_HEADER_SIZE) {
85,793!
4965
              code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
4966
              uError("stmt bind param[%d] length:%d  greater than type maximum lenght: %d", iInfo,
×
4967
                     value.nData + (uint32_t)(VARSTR_HEADER_SIZE), infos[iInfo].bytes);
4968
              goto _exit;
×
4969
            }
4970
            value.pData = *data;
85,793✔
4971
            *data += length;
85,793✔
4972
          }
4973
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
4974
        } else {
4975
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
1,032,223✔
4976
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
1,032,223✔
4977
            *val = 1;
1✔
4978
          }
4979
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
1,032,223✔
4980
        }
4981
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
1,137,897✔
4982
      }
4983
      if (taosArrayPush(colValArray, &colVal) == NULL) {
1,125,032!
4984
        code = terrno;
×
4985
        goto _exit;
×
4986
      }
4987
    }
4988

4989
    SRow *row;
4990

4991
    if (hasBlob == 0) {
261,815✔
4992
      SRowBuildScanInfo sinfo = {0};
247,124✔
4993
      if ((code = tRowBuild(colValArray, pTSchema, &row, &sinfo))) {
247,124!
4994
        goto _exit;
×
4995
      }
4996
    } else {
4997
      SRowBuildScanInfo sinfo = {.hasBlob = 1, .scanType = ROW_BUILD_UPDATE};
14,691✔
4998
      if ((code = tRowBuildWithBlob(colValArray, pTSchema, &row, NULL, &sinfo))) {
14,691!
4999
        goto _exit;
×
5000
      }
5001
    }
5002

5003
    if ((taosArrayPush(rowArray, &row)) == NULL) {
246,087!
5004
      code = terrno;
×
5005
      goto _exit;
×
5006
    }
5007

5008
    if (pOrdered && pDupTs) {
246,087!
5009
      tRowGetKey(row, &rowKey);
492,310✔
5010
      if (iRow == 0) {
246,121✔
5011
        *pOrdered = true;
7,500✔
5012
        *pDupTs = false;
7,500✔
5013
      } else {
5014
        if (*pOrdered) {
238,621!
5015
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
238,673✔
5016
          *pOrdered = (res >= 0);
238,673✔
5017
          if (!*pDupTs) {
238,673!
5018
            *pDupTs = (res == 0);
238,706✔
5019
          }
5020
        }
5021
      }
5022
      lastRowKey = rowKey;
246,121✔
5023
    }
5024
  }
5025
_exit:
3,058✔
5026
  if (code != 0) {
3,059✔
5027
    uError("tRowBuildFromBind2 failed, code=%d", code);
1!
5028
  }
5029
  taosArrayDestroy(colValArray);
3,059✔
5030
  taosArrayDestroy(bufArray);
7,497✔
5031
  return code;
7,501✔
5032
}
5033
/* build rows to `rowArray` from bind
5034
 * `infos` is the bind information array
5035
 * `numOfInfos` is the number of bind information
5036
 * `infoSorted` is whether the bind information is sorted by column id
5037
 * `pTSchema` is the schema of the table
5038
 * `rowArray` is the array to store the rows
5039
 * `pOrdered` is the pointer to store ordered
5040
 * `pDupTs` is the pointer to store duplicateTs
5041
 */
5042
int32_t tRowBuildFromBind2WithBlob(SBindInfo2 *infos, int32_t numOfInfos, bool infoSorted, const STSchema *pTSchema,
×
5043
                                   SArray *rowArray, bool *pOrdered, bool *pDupTs, SBlobSet *pBlobSet) {
5044
  if (infos == NULL || numOfInfos <= 0 || numOfInfos > pTSchema->numOfCols || pTSchema == NULL || rowArray == NULL) {
×
5045
    return TSDB_CODE_INVALID_PARA;
×
5046
  }
5047
  int8_t hasBlob = schemaHasBlob(pTSchema);
×
5048
  if (!infoSorted) {
×
5049
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo2), NULL, tBindInfoCompare);
×
5050
  }
5051

5052
  int32_t code = 0;
×
5053
  int32_t numOfRows = infos[0].bind->num;
×
5054
  SArray *colValArray, *bufArray;
5055
  SColVal colVal;
5056

5057
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
×
5058
    return terrno;
×
5059
  }
5060
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
×
5061
    taosArrayDestroy(colValArray);
×
5062
    return terrno;
×
5063
  }
5064
  for (int i = 0; i < numOfInfos; ++i) {
×
5065
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
×
5066
      taosArrayDestroy(colValArray);
×
5067
      taosArrayDestroy(bufArray);
×
5068
      return terrno;
×
5069
    }
5070
  }
5071

5072
  SRowKey rowKey, lastRowKey;
5073
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
5074
    taosArrayClear(colValArray);
×
5075

5076
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
×
5077
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
×
5078
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
5079
          if (iInfo == 0) {
×
5080
            code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
5081
            goto _exit;
×
5082
          }
5083
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
5084
        } else {
5085
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
5086
        }
5087
      } else {
5088
        SValue value = {
×
5089
            .type = infos[iInfo].type,
×
5090
        };
5091
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
×
5092
          if (IS_STR_DATA_BLOB(infos[iInfo].type)) {
×
5093
            int32_t   length = infos[iInfo].bind->length[iRow];
×
5094
            uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
×
5095
            value.nData = length;
×
5096
            if (value.nData > (TSDB_MAX_BLOB_LEN - BLOBSTR_HEADER_SIZE)) {
×
5097
              code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
5098
              uError("stmt bind param[%d] length:%d  greater than type maximum lenght: %d", iInfo, value.nData,
×
5099
                     pTSchema->columns[infos[iInfo].columnId - 1].bytes);
5100
              goto _exit;
×
5101
            }
5102
            value.pData = *data;
×
5103
            *data += length;
×
5104
          } else {
5105
            int32_t   length = infos[iInfo].bind->length[iRow];
×
5106
            uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
×
5107
            value.nData = length;
×
5108
            if (value.nData > pTSchema->columns[infos[iInfo].columnId - 1].bytes - VARSTR_HEADER_SIZE) {
×
5109
              code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
5110
              uError("stmt bind param[%d] length:%d  greater than type maximum lenght: %d", iInfo, value.nData,
×
5111
                     pTSchema->columns[infos[iInfo].columnId - 1].bytes);
5112
              goto _exit;
×
5113
            }
5114
            value.pData = *data;
×
5115
            *data += length;
×
5116
          }
5117

5118
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
5119
        } else {
5120
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
×
5121
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
×
5122
            *val = 1;
×
5123
          }
5124
          valueSetDatum(&value, infos[iInfo].type, val, infos[iInfo].bytes);
×
5125
        }
5126
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
×
5127
      }
5128
      if (taosArrayPush(colValArray, &colVal) == NULL) {
×
5129
        code = terrno;
×
5130
        goto _exit;
×
5131
      }
5132
    }
5133

5134
    SRow *row;
5135

5136
    if (hasBlob == 0) {
×
5137
      SRowBuildScanInfo sinfo = {0};
×
5138
      if ((code = tRowBuild(colValArray, pTSchema, &row, &sinfo))) {
×
5139
        goto _exit;
×
5140
      }
5141
    } else {
5142
      SRowBuildScanInfo sinfo = {.hasBlob = 1, .scanType = ROW_BUILD_UPDATE};
×
5143
      if ((code = tRowBuildWithBlob(colValArray, pTSchema, &row, pBlobSet, &sinfo))) {
×
5144
        goto _exit;
×
5145
      }
5146
    }
5147

5148
    if ((taosArrayPush(rowArray, &row)) == NULL) {
×
5149
      code = terrno;
×
5150
      goto _exit;
×
5151
    }
5152

5153
    if (pOrdered && pDupTs) {
×
5154
      tRowGetKey(row, &rowKey);
×
5155
      if (iRow == 0) {
×
5156
        *pOrdered = true;
×
5157
        *pDupTs = false;
×
5158
      } else {
5159
        if (*pOrdered) {
×
5160
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
×
5161
          *pOrdered = (res >= 0);
×
5162
          if (!*pDupTs) {
×
5163
            *pDupTs = (res == 0);
×
5164
          }
5165
        }
5166
      }
5167
      lastRowKey = rowKey;
×
5168
    }
5169
  }
5170
_exit:
×
5171
  taosArrayDestroy(colValArray);
×
5172
  taosArrayDestroy(bufArray);
×
5173
  return code;
×
5174
}
5175

5176
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
32✔
5177
  int32_t code = TSDB_CODE_SUCCESS;
32✔
5178

5179
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
32!
5180
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
×
5181
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
×
5182
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
×
5183
    if (iToRow == 0) {
×
5184
      pToColData->aOffset[iToRow] = 0;
×
5185
    }
5186

5187
    if (iToRow < pToColData->nVal - 1) {
×
5188
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
×
5189
    }
5190

5191
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
×
5192
                 nData);
5193
  } else {
5194
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
32✔
5195
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
32✔
5196
  }
5197
  return code;
32✔
5198
}
5199

5200
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
32✔
5201
                                        int32_t iToRow) {
5202
  int32_t code = TSDB_CODE_SUCCESS;
32✔
5203
  int     bit_val = 0;
32✔
5204

5205
  switch (pFromColData->flag) {
32!
5206
    case HAS_NONE: {
×
5207
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
5208
    } break;
×
5209
    case HAS_NULL: {
×
5210
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
×
5211
    } break;
×
5212
    case (HAS_NULL | HAS_NONE): {
×
5213
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
5214
      if (0 == bit_val)
×
5215
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
5216
      else
5217
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
×
5218
    } break;
×
5219
    case HAS_VALUE: {
32✔
5220
      ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
32!
5221
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
32!
5222
    } break;
32✔
5223
    case (HAS_VALUE | HAS_NONE): {
×
5224
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
5225
      if (0 == bit_val)
×
5226
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NONE);
×
5227
      else
5228
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
×
5229
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
5230
    } break;
×
5231
    case (HAS_VALUE | HAS_NULL): {
×
5232
      bit_val = GET_BIT1(pFromColData->pBitMap, iFromRow);
×
5233
      if (0 == bit_val)
×
5234
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_NULL);
×
5235
      else
5236
        ROW_SET_BITMAP(pToColData->pBitMap, pToColData->flag, iToRow, BIT_FLG_VALUE);
×
5237
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
5238
    } break;
×
5239
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
5240
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
5241
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
5242
    } break;
×
5243
    default:
×
5244
      return -1;
×
5245
  }
5246

5247
  return code;
32✔
5248
}
5249

5250
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
16✔
5251
                               int32_t nColData) {
5252
  int32_t code = TSDB_CODE_SUCCESS;
16✔
5253

5254
  for (int32_t i = 0; i < nColData; i++) {
48✔
5255
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
32✔
5256
    if (code != TSDB_CODE_SUCCESS) {
32!
5257
      return code;
×
5258
    }
5259
  }
5260

5261
  return code;
16✔
5262
}
5263

5264
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
16✔
5265
  int32_t code = TSDB_CODE_SUCCESS;
16✔
5266

5267
  for (int32_t i = 0; i < nColData; i++) {
48✔
5268
    SColVal cv = {0};
32✔
5269
    code = tColDataGetValue(&aFromColData[i], iFromRow, &cv);
32✔
5270
    if (code != TSDB_CODE_SUCCESS) {
32!
5271
      return code;
×
5272
    }
5273
    code = tColDataAppendValue(&aToColData[i], &cv);
32✔
5274
    if (code != TSDB_CODE_SUCCESS) {
32!
5275
      return code;
×
5276
    }
5277
  }
5278

5279
  return code;
16✔
5280
}
5281

5282
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
206,834,333✔
5283
  SColVal cv;
5284

5285
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
206,834,333✔
5286
  key->numOfPKs = 0;
206,834,333✔
5287

5288
  for (int i = 1; i < nColData; i++) {
206,834,363!
5289
    if (aColData[i].cflag & COL_IS_KEY) {
208,186,832✔
5290
      tColDataGetValue4(&aColData[i], iRow, &cv);
30✔
5291
      key->pks[key->numOfPKs++] = cv.value;
30✔
5292
    } else {
5293
      break;
208,186,802✔
5294
    }
5295
  }
5296
}
206,834,333✔
5297

5298
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
5✔
5299
  SColData *aDstColData = NULL;
5✔
5300
  int32_t   i = start, j = mid + 1, k = 0;
5✔
5301
  SRowKey   keyi, keyj;
5302

5303
  if (end > start) {
5!
5304
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
5!
5305
    if (aDstColData == NULL) {
5!
5306
      return terrno;
×
5307
    }
5308
    for (int c = 0; c < nColData; ++c) {
15✔
5309
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
10✔
5310
    }
5311
  }
5312

5313
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
5✔
5314
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
5✔
5315
  while (i <= mid && j <= end) {
15✔
5316
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
10✔
5317
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
7!
5318
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
7✔
5319
    } else {
5320
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
3!
5321
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
3✔
5322
    }
5323
  }
5324

5325
  while (i <= mid) {
7✔
5326
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
2!
5327
  }
5328

5329
  while (j <= end) {
9✔
5330
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
4!
5331
  }
5332

5333
  for (i = start, k = 0; i <= end; ++i, ++k) {
21✔
5334
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
16!
5335
  }
5336

5337
  if (aDstColData) {
5!
5338
    for (int32_t i = 0; i < nColData; i++) {
15✔
5339
      tColDataDestroy(&aDstColData[i]);
10✔
5340
    }
5341
    taosMemoryFree(aDstColData);
5!
5342
  }
5343

5344
  return TSDB_CODE_SUCCESS;
5✔
5345
}
5346

5347
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
11✔
5348
  int32_t ret = TSDB_CODE_SUCCESS;
11✔
5349
  int32_t mid;
5350

5351
  if (start >= end) {
11✔
5352
    return TSDB_CODE_SUCCESS;
6✔
5353
  }
5354

5355
  mid = (start + end) / 2;
5✔
5356

5357
  ret = tColDataMergeSort(aColData, start, mid, nColData);
5✔
5358
  if (ret != TSDB_CODE_SUCCESS) {
5!
5359
    return ret;
×
5360
  }
5361

5362
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
5✔
5363
  if (ret != TSDB_CODE_SUCCESS) {
5!
5364
    return ret;
×
5365
  }
5366

5367
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
5✔
5368
}
5369

5370
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
1✔
5371
  int32_t nVal = aColData[0].nVal;
1✔
5372

5373
  if (nVal < 2) return TSDB_CODE_SUCCESS;
1!
5374

5375
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
1✔
5376
}
5377

5378
static int32_t tColDataMerge(SArray **colArr) {
1✔
5379
  int32_t code = 0;
1✔
5380
  SArray *src = *colArr;
1✔
5381
  SArray *dst = NULL;
1✔
5382

5383
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
1✔
5384
  if (dst == NULL) {
1!
5385
    return terrno;
×
5386
  }
5387

5388
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
3✔
5389
    SColData *srcCol = taosArrayGet(src, i);
2✔
5390

5391
    SColData *dstCol = taosArrayReserve(dst, 1);
2✔
5392
    if (dstCol == NULL) {
2!
5393
      code = terrno;
×
5394
      goto _exit;
×
5395
    }
5396
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
2✔
5397
  }
5398

5399
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
1✔
5400
  SRowKey lastKey;
5401
  for (int32_t i = 0; i < numRows; i++) {
7✔
5402
    SRowKey key;
5403
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
6✔
5404

5405
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
11✔
5406
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
6✔
5407
        SColData *srcCol = taosArrayGet(src, j);
4✔
5408
        SColData *dstCol = taosArrayGet(dst, j);
4✔
5409

5410
        SColVal cv;
5411
        code = tColDataGetValue(srcCol, i, &cv);
4✔
5412
        if (code != TSDB_CODE_SUCCESS) {
4!
5413
          goto _exit;
×
5414
        }
5415
        code = tColDataAppendValue(dstCol, &cv);
4✔
5416
        if (code) {
4!
5417
          goto _exit;
×
5418
        }
5419
      }
5420
      lastKey = key;
2✔
5421
    } else {  // update existing row
5422
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
12✔
5423
        SColData *srcCol = taosArrayGet(src, j);
8✔
5424
        SColData *dstCol = taosArrayGet(dst, j);
8✔
5425

5426
        SColVal cv;
5427
        code = tColDataGetValue(srcCol, i, &cv);
8✔
5428
        if (code != TSDB_CODE_SUCCESS) {
8!
5429
          goto _exit;
×
5430
        }
5431
        code = tColDataUpdateValue(dstCol, &cv, true);
8✔
5432
        if (code) {
8!
5433
          goto _exit;
×
5434
        }
5435
      }
5436
    }
5437
  }
5438

5439
_exit:
1✔
5440
  if (code) {
1!
5441
    taosArrayDestroyEx(dst, tColDataDestroy);
×
5442
  } else {
5443
    taosArrayDestroyEx(src, tColDataDestroy);
1✔
5444
    *colArr = dst;
1✔
5445
  }
5446
  return code;
1✔
5447
}
5448

5449
int32_t tColDataSortMerge(SArray **arr) {
41,196✔
5450
  SArray   *colDataArr = *arr;
41,196✔
5451
  int32_t   nColData = TARRAY_SIZE(colDataArr);
41,196✔
5452
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
41,196✔
5453

5454
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
41,196!
5455
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
5456
  }
5457
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
41,196!
5458
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
5459
  }
5460
  if (!(aColData[0].flag == HAS_VALUE)) {
41,196!
5461
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
5462
  }
5463

5464
  if (aColData[0].nVal <= 1) goto _exit;
41,196✔
5465

5466
  int8_t doSort = 0;
41,134✔
5467
  int8_t doMerge = 0;
41,134✔
5468
  // scan -------
5469
  SRowKey lastKey;
5470
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
41,134✔
5471
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
106,451,609!
5472
    SRowKey key;
5473
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
108,089,857✔
5474

5475
    int32_t c = tRowKeyCompare(&lastKey, &key);
106,410,457✔
5476
    if (c < 0) {
106,410,457✔
5477
      lastKey = key;
106,228,844✔
5478
      continue;
106,228,844✔
5479
    } else if (c > 0) {
181,613✔
5480
      doSort = 1;
1✔
5481
      break;
1✔
5482
    } else {
5483
      doMerge = 1;
181,612✔
5484
    }
5485
  }
5486

5487
  // sort -------
5488
  if (doSort) {
×
5489
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
1!
5490
  }
5491

5492
  if (doMerge != 1) {
1,502,052✔
5493
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
41,174✔
5494
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
106,318,776!
5495
      SRowKey key;
5496
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
107,738,478✔
5497

5498
      int32_t c = tRowKeyCompare(&lastKey, &key);
106,277,605✔
5499
      if (c == 0) {
106,277,605✔
5500
        doMerge = 1;
1✔
5501
        break;
1✔
5502
      }
5503
      lastKey = key;
106,277,604✔
5504
    }
5505
  }
5506

5507
  // merge -------
5508
  if (doMerge) {
41,177✔
5509
    int32_t code = tColDataMerge(arr);
1✔
5510
    if (code) return code;
1!
5511
  }
5512

5513
_exit:
41,177✔
5514
  return 0;
41,239✔
5515
}
5516

5517
int32_t tColDataSortMergeWithBlob(SArray **arr, SBlobSet *pBlob) {
×
5518
  SArray   *colDataArr = *arr;
×
5519
  int32_t   nColData = TARRAY_SIZE(colDataArr);
×
5520
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
×
5521

5522
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
×
5523
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
5524
  }
5525
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
×
5526
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
5527
  }
5528
  if (!(aColData[0].flag == HAS_VALUE)) {
×
5529
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
5530
  }
5531

5532
  if (aColData[0].nVal <= 1) goto _exit;
×
5533

5534
  int8_t doSort = 0;
×
5535
  int8_t doMerge = 0;
×
5536
  // scan -------
5537
  SRowKey lastKey;
5538
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
×
5539
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
×
5540
    SRowKey key;
5541
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
×
5542

5543
    int32_t c = tRowKeyCompare(&lastKey, &key);
×
5544
    if (c < 0) {
×
5545
      lastKey = key;
×
5546
      continue;
×
5547
    } else if (c > 0) {
×
5548
      doSort = 1;
×
5549
      break;
×
5550
    } else {
5551
      doMerge = 1;
×
5552
    }
5553
  }
5554
  if (doMerge || doSort) {
×
5555
    return TSDB_CODE_BLOB_NOT_SUPPORT;
×
5556
  }
5557
  // sort -------
5558
  if (doSort) {
×
5559
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
×
5560
  }
5561

5562
  if (doMerge != 1) {
×
5563
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
×
5564
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
×
5565
      SRowKey key;
5566
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
×
5567

5568
      int32_t c = tRowKeyCompare(&lastKey, &key);
×
5569
      if (c == 0) {
×
5570
        doMerge = 1;
×
5571
        break;
×
5572
      }
5573
      lastKey = key;
×
5574
    }
5575
  }
5576

5577
  // merge -------
5578
  if (doMerge) {
×
5579
    int32_t code = tColDataMerge(arr);
×
5580
    if (code) return code;
×
5581
  }
5582

5583
_exit:
×
5584
  return 0;
×
5585
}
5586

5587
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
255,878✔
5588
  int32_t code = 0;
255,878✔
5589

5590
  if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
511,756!
5591
  if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
511,756!
5592
  if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
511,756!
5593
  if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
511,756!
5594

5595
  // bitmap
5596
  switch (pColData->flag) {
255,878!
5597
    case (HAS_NULL | HAS_NONE):
94✔
5598
    case (HAS_VALUE | HAS_NONE):
5599
    case (HAS_VALUE | HAS_NULL):
5600
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
94✔
5601
      if (code) return code;
94!
5602
      break;
94✔
5603
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
5604
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
5605
      if (code) return code;
×
5606
      break;
×
5607
    default:
255,784✔
5608
      break;
255,784✔
5609
  }
5610

5611
  // value
5612
  if (pColData->flag & HAS_VALUE) {
255,878✔
5613
    if (IS_VAR_DATA_TYPE(pColData->type)) {
255,614!
5614
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
1,468✔
5615
      if (code) return code;
1,468!
5616

5617
      code = tEncodeI32v(pEncoder, pColData->nData);
1,468✔
5618
      if (code) return code;
1,468!
5619

5620
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
1,468✔
5621
      if (code) return code;
1,468!
5622
    } else {
5623
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
254,146✔
5624
      if (code) return code;
254,146!
5625
    }
5626
  }
5627

5628
  return code;
255,878✔
5629
}
5630

5631
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
7,855✔
5632
  int32_t code = 0;
7,855✔
5633

5634
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
15,710!
5635
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
15,712!
5636
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
15,711!
5637
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
15,707!
5638

5639
  if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
7,853!
5640
    return TSDB_CODE_INVALID_PARA;
×
5641
  }
5642

5643
  // bitmap
5644
  switch (pColData->flag) {
7,853!
5645
    case (HAS_NULL | HAS_NONE):
158✔
5646
    case (HAS_VALUE | HAS_NONE):
5647
    case (HAS_VALUE | HAS_NULL):
5648
      code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
158!
5649
      if (code) return code;
158!
5650
      break;
158✔
5651
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
5652
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
5653
      if (code) return code;
×
5654
      break;
×
5655
    default:
7,695✔
5656
      break;
7,695✔
5657
  }
5658

5659
  // value
5660
  if (pColData->flag & HAS_VALUE) {
7,853✔
5661
    if (IS_VAR_DATA_TYPE(pColData->type)) {
7,540!
5662
      code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
1,046!
5663
      if (code) return code;
1,046!
5664

5665
      code = tDecodeI32v(pDecoder, &pColData->nData);
1,046✔
5666
      if (code) return code;
1,050!
5667

5668
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
1,050!
5669
      if (code) return code;
1,050!
5670
    } else {
5671
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
6,494✔
5672
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
6,494!
5673
      if (code) return code;
6,494!
5674
    }
5675
  }
5676
  pColData->cflag = 0;
7,857✔
5677

5678
  return code;
7,857✔
5679
}
5680

5681
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
255,883✔
5682
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
255,883✔
5683
  if (code) return code;
255,878!
5684
  return tEncodeI8(pEncoder, pColData->cflag);
511,756✔
5685
}
5686

5687
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
7,856✔
5688
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
7,856✔
5689
  if (code) return code;
7,857!
5690

5691
  code = tDecodeI8(pDecoder, &pColData->cflag);
7,857✔
5692
  return code;
7,855✔
5693
}
5694

5695
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
255,885✔
5696
  if (version == 0) {
255,885!
5697
    return tEncodeColDataVersion0(pEncoder, pColData);
×
5698
  } else if (version == 1) {
255,885!
5699
    return tEncodeColDataVersion1(pEncoder, pColData);
255,888✔
5700
  } else {
5701
    return TSDB_CODE_INVALID_PARA;
×
5702
  }
5703
}
5704

5705
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
7,855✔
5706
  if (version == 0) {
7,855!
5707
    return tDecodeColDataVersion0(pDecoder, pColData);
×
5708
  } else if (version == 1) {
7,855!
5709
    return tDecodeColDataVersion1(pDecoder, pColData);
7,856✔
5710
  } else {
5711
    return TSDB_CODE_INVALID_PARA;
×
5712
  }
5713
}
5714

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

5717
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
1,092,194,110✔
5718
  if (ppRow == NULL) {
1,092,194,110!
5719
    return TSDB_CODE_INVALID_PARA;
×
5720
  }
5721

5722
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
1,092,194,110!
5723
    return TSDB_CODE_OUT_OF_RANGE;
×
5724
  }
5725

5726
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
1,092,194,110✔
5727
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
2,147,483,647!
5728
}
5729

5730
int32_t tEncodeBlobSet(SEncoder *pEncoder, SBlobSet *pRow) {
2✔
5731
  int32_t code = 0;
2✔
5732
  int32_t lino = 0;
2✔
5733
  uint8_t compressed = 0;
2✔
5734
  int32_t compressSize = 0;
2✔
5735
  char   *p = NULL;
2✔
5736

5737
  TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pRow->type));
4!
5738
  TAOS_CHECK_EXIT(tEncodeI64(pEncoder, pRow->len));
4!
5739

5740
  int32_t nSeq = taosArrayGetSize(pRow->pSeqTable);
2✔
5741
  TAOS_CHECK_EXIT(tEncodeI32(pEncoder, nSeq));
2!
5742

5743
  // if (pRow->type) {
5744
  void *pIter = taosHashIterate(pRow->pSeqToffset, NULL);
2✔
5745
  while (pIter) {
22✔
5746
    uint64_t seq = *(uint64_t *)taosHashGetKey(pIter, NULL);
20✔
5747
    int32_t  idx = *(int32_t *)pIter;
20✔
5748
    TAOS_CHECK_EXIT(tEncodeU64(pEncoder, seq));
20!
5749
    TAOS_CHECK_EXIT(tEncodeI32(pEncoder, idx));
20!
5750

5751
    pIter = taosHashIterate(pRow->pSeqToffset, pIter);
20✔
5752
  }
5753
  //}
5754
  for (int32_t i = 0; i < nSeq; i++) {
22✔
5755
    SBlobValue *p = taosArrayGet(pRow->pSeqTable, i);
20✔
5756
    TAOS_CHECK_EXIT(tEncodeU64(pEncoder, p->offset));
40!
5757
    TAOS_CHECK_EXIT(tEncodeU32(pEncoder, p->len));
40!
5758
    TAOS_CHECK_EXIT(tEncodeU32(pEncoder, p->dataOffset));
40!
5759
    TAOS_CHECK_EXIT(tEncodeI8(pEncoder, p->nextRow));
40!
5760
    TAOS_CHECK_EXIT(tEncodeI8(pEncoder, p->type));
40!
5761
  }
5762

5763
  TAOS_CHECK_EXIT(tEncodeFixed(pEncoder, pRow->data, pRow->len));
4!
5764

5765
_exit:
2✔
5766
  return code;
2✔
5767
}
5768

5769
int32_t tDecodeBlobSet(SDecoder *pDecoder, SBlobSet **pBlobSet) {
×
5770
  int32_t    code = 0;
×
5771
  int32_t    lino = 0;
×
5772
  int32_t    nSeq = 0;
×
5773
  uint8_t    compressd = 0;
×
5774
  int32_t    compressSize = 0;
×
5775
  SBlobSet  *pBlob = taosMemCalloc(1, sizeof(SBlobSet));
×
5776
  if (pBlob == NULL) {
×
5777
    TAOS_CHECK_EXIT(terrno);
×
5778
  }
5779
  TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pBlob->type));
×
5780
  TAOS_CHECK_EXIT(tDecodeI64(pDecoder, &pBlob->len));
×
5781

5782
  TAOS_CHECK_EXIT(tDecodeI32(pDecoder, &nSeq));
×
5783

5784
  // if (pBlob->type) {
5785
  pBlob->pSeqToffset = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK);
×
5786
  if (pBlob->pSeqToffset == NULL) {
×
5787
    TAOS_CHECK_EXIT(terrno);
×
5788
  }
5789
  for (int32_t i = 0; i < nSeq; i++) {
×
5790
    uint64_t seq;
5791
    int32_t  idx;
5792
    TAOS_CHECK_EXIT(tDecodeU64(pDecoder, &seq));
×
5793
    TAOS_CHECK_EXIT(tDecodeI32(pDecoder, &idx));
×
5794

5795
    code = taosHashPut(pBlob->pSeqToffset, &seq, sizeof(seq), &idx, sizeof(idx));
×
5796
    TAOS_CHECK_EXIT(code);
×
5797
  }
5798
  //}
5799

5800
  pBlob->pSeqTable = taosArrayInit(nSeq, sizeof(SBlobValue));
×
5801
  if (pBlob->pSeqTable == NULL) {
×
5802
    TAOS_CHECK_EXIT(terrno);
×
5803
  }
5804

5805
  for (int32_t i = 0; i < nSeq; i++) {
×
5806
    SBlobValue value;
5807
    TAOS_CHECK_EXIT(tDecodeU64(pDecoder, &value.offset));
×
5808
    TAOS_CHECK_EXIT(tDecodeU32(pDecoder, &value.len));
×
5809
    TAOS_CHECK_EXIT(tDecodeU32(pDecoder, &value.dataOffset));
×
5810
    TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &value.nextRow));
×
5811
    TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &value.type));
×
5812
    if (taosArrayPush(pBlob->pSeqTable, &value) == NULL) {
×
5813
      TAOS_CHECK_EXIT(terrno);
×
5814
    }
5815
  }
5816

5817
  pBlob->data = taosMemCalloc(1, pBlob->len);
×
5818
  if (pBlob->data == NULL) {
×
5819
    TAOS_CHECK_EXIT(terrno);
×
5820
  }
5821

5822
  TAOS_CHECK_EXIT(tDecodeFixed(pDecoder, pBlob->data, pBlob->len));
×
5823
  *pBlobSet = pBlob;
×
5824

5825
  uInfo("decode blob len:%d", (int32_t)(pBlob->len));
×
5826

5827
_exit:
×
5828
  if (code != 0) {
×
5829
    if (pBlob != NULL) {
×
5830
      taosMemoryFree(pBlob->data);
×
5831
      taosArrayDestroy(pBlob->pSeqTable);
×
5832
      taosMemoryFree(pBlob);
×
5833
    }
5834
  }
5835
  return code;
×
5836
}
5837

5838
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
5839
  do {                                       \
5840
    (SUM) += (VAL);                          \
5841
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
5842
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
5843
  } while (0)
5844

5845
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, SColumnDataAgg *pAggs) {
10,387✔
5846
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
10,387✔
5847
  int16_t *numOfNull = &pAggs->numOfNull;
10,387✔
5848
  *sum = 0;
10,387✔
5849
  *max = 0;
10,387✔
5850
  *min = 1;
10,387✔
5851
  *numOfNull = 0;
10,387✔
5852

5853
  int8_t val;
5854
  if (HAS_VALUE == pColData->flag) {
10,387✔
5855
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
15,082,923✔
5856
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
15,073,535✔
5857
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
15,073,535✔
5858
    }
5859
  } else {
5860
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,846,719✔
5861
      switch (tColDataGetBitValue(pColData, iVal)) {
2,845,720!
5862
        case 0:
142,891✔
5863
        case 1:
5864
          (*numOfNull)++;
142,891✔
5865
          break;
142,891✔
5866
        case 2:
2,702,884✔
5867
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
2,702,884✔
5868
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
2,702,884✔
5869
          break;
2,702,884✔
5870
        default:
×
5871
          break;
×
5872
      }
5873
    }
5874
  }
5875
}
10,387✔
5876

5877
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, SColumnDataAgg *pAggs) {
10,410✔
5878
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
10,410✔
5879
  int16_t *numOfNull = &pAggs->numOfNull;
10,410✔
5880
  *sum = 0;
10,410✔
5881
  *max = INT8_MIN;
10,410✔
5882
  *min = INT8_MAX;
10,410✔
5883
  *numOfNull = 0;
10,410✔
5884

5885
  int8_t val;
5886
  if (HAS_VALUE == pColData->flag) {
10,410✔
5887
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
15,141,497✔
5888
      val = ((int8_t *)pColData->pData)[iVal];
15,132,097✔
5889
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
15,132,097✔
5890
    }
5891
  } else {
5892
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,860,160✔
5893
      switch (tColDataGetBitValue(pColData, iVal)) {
2,859,150!
5894
        case 0:
152,327✔
5895
        case 1:
5896
          (*numOfNull)++;
152,327✔
5897
          break;
152,327✔
5898
        case 2:
2,706,823✔
5899
          val = ((int8_t *)pColData->pData)[iVal];
2,706,823✔
5900
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
2,706,823✔
5901
          break;
2,706,823✔
5902
        default:
×
5903
          break;
×
5904
      }
5905
    }
5906
  }
5907
}
10,410✔
5908

5909
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, SColumnDataAgg *pAggs) {
10,401✔
5910
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
10,401✔
5911
  int16_t *numOfNull = &pAggs->numOfNull;
10,401✔
5912
  *sum = 0;
10,401✔
5913
  *max = INT16_MIN;
10,401✔
5914
  *min = INT16_MAX;
10,401✔
5915
  *numOfNull = 0;
10,401✔
5916

5917
  int16_t val;
5918
  if (HAS_VALUE == pColData->flag) {
10,401✔
5919
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
15,141,807✔
5920
      val = ((int16_t *)pColData->pData)[iVal];
15,132,405✔
5921
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
15,132,405✔
5922
    }
5923
  } else {
5924
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,848,149✔
5925
      switch (tColDataGetBitValue(pColData, iVal)) {
2,847,150!
5926
        case 0:
142,242✔
5927
        case 1:
5928
          (*numOfNull)++;
142,242✔
5929
          break;
142,242✔
5930
        case 2:
2,704,908✔
5931
          val = ((int16_t *)pColData->pData)[iVal];
2,704,908✔
5932
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
2,704,908✔
5933
          break;
2,704,908✔
5934
        default:
×
5935
          break;
×
5936
      }
5937
    }
5938
  }
5939
}
10,401✔
5940

5941
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, SColumnDataAgg *pAggs) {
332,016✔
5942
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
332,016✔
5943
  int16_t *numOfNull = &pAggs->numOfNull;
332,016✔
5944
  *sum = 0;
332,016✔
5945
  *max = INT32_MIN;
332,016✔
5946
  *min = INT32_MAX;
332,016✔
5947
  *numOfNull = 0;
332,016✔
5948

5949
  int32_t val;
5950
  if (HAS_VALUE == pColData->flag) {
332,016✔
5951
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
1,069,955,859✔
5952
      val = ((int32_t *)pColData->pData)[iVal];
1,069,658,874✔
5953
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
1,069,658,874✔
5954
    }
5955
  } else {
5956
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
96,371,938✔
5957
      switch (tColDataGetBitValue(pColData, iVal)) {
96,364,054!
5958
        case 0:
5,660,351✔
5959
        case 1:
5960
          (*numOfNull)++;
5,660,351✔
5961
          break;
5,660,351✔
5962
        case 2:
90,728,827✔
5963
          val = ((int32_t *)pColData->pData)[iVal];
90,728,827✔
5964
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
90,728,827✔
5965
          break;
90,728,827✔
5966
        default:
×
5967
          break;
×
5968
      }
5969
    }
5970
  }
5971
}
304,869✔
5972

5973
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, SColumnDataAgg *pAggs) {
203,064✔
5974
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
203,064✔
5975
  int16_t *numOfNull = &pAggs->numOfNull;
203,064✔
5976
  *sum = 0;
203,064✔
5977
  *max = INT64_MIN;
203,064✔
5978
  *min = INT64_MAX;
203,064✔
5979
  *numOfNull = 0;
203,064✔
5980

5981
  int64_t val;
5982
  if (HAS_VALUE == pColData->flag) {
203,064✔
5983
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
484,418,465✔
5984
      val = ((int64_t *)pColData->pData)[iVal];
484,221,119✔
5985
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
484,221,119✔
5986
    }
5987
  } else {
5988
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
18,861,148✔
5989
      switch (tColDataGetBitValue(pColData, iVal)) {
18,855,430!
5990
        case 0:
1,873,688✔
5991
        case 1:
5992
          (*numOfNull)++;
1,873,688✔
5993
          break;
1,873,688✔
5994
        case 2:
16,981,742✔
5995
          val = ((int64_t *)pColData->pData)[iVal];
16,981,742✔
5996
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
16,981,742✔
5997
          break;
16,981,742✔
5998
        default:
×
5999
          break;
×
6000
      }
6001
    }
6002
  }
6003
}
203,064✔
6004

6005
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, SColumnDataAgg *pAggs) {
339,450✔
6006
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
339,450✔
6007
  int16_t *numOfNull = &pAggs->numOfNull;
339,450✔
6008
  *(double *)sum = 0;
339,450✔
6009
  *(double *)max = -FLT_MAX;
339,450✔
6010
  *(double *)min = FLT_MAX;
339,450✔
6011
  *numOfNull = 0;
339,450✔
6012

6013
  float val;
6014
  if (HAS_VALUE == pColData->flag) {
339,450✔
6015
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
1,361,259,532✔
6016
      val = ((float *)pColData->pData)[iVal];
1,360,921,094✔
6017
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
1,360,921,094✔
6018
    }
6019
  } else {
6020
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,858,622✔
6021
      switch (tColDataGetBitValue(pColData, iVal)) {
2,857,675!
6022
        case 0:
152,566✔
6023
        case 1:
6024
          (*numOfNull)++;
152,566✔
6025
          break;
152,566✔
6026
        case 2:
2,705,159✔
6027
          val = ((float *)pColData->pData)[iVal];
2,705,159✔
6028
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
2,705,159✔
6029
          break;
2,705,159✔
6030
        default:
×
6031
          break;
×
6032
      }
6033
    }
6034
  }
6035
}
339,385✔
6036

6037
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, SColumnDataAgg *pAggs) {
11,692✔
6038
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
11,692✔
6039
  int16_t *numOfNull = &pAggs->numOfNull;
11,692✔
6040
  *(double *)sum = 0;
11,692✔
6041
  *(double *)max = -DBL_MAX;
11,692✔
6042
  *(double *)min = DBL_MAX;
11,692✔
6043
  *numOfNull = 0;
11,692✔
6044

6045
  double val;
6046
  if (HAS_VALUE == pColData->flag) {
11,692✔
6047
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
22,418,692✔
6048
      val = ((double *)pColData->pData)[iVal];
22,408,011✔
6049
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
22,408,011✔
6050
    }
6051
  } else {
6052
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,859,239✔
6053
      switch (tColDataGetBitValue(pColData, iVal)) {
2,858,204!
6054
        case 0:
152,440✔
6055
        case 1:
6056
          (*numOfNull)++;
152,440✔
6057
          break;
152,440✔
6058
        case 2:
2,705,832✔
6059
          val = ((double *)pColData->pData)[iVal];
2,705,832✔
6060
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
2,705,832✔
6061
          break;
2,705,832✔
6062
        default:
×
6063
          break;
×
6064
      }
6065
    }
6066
  }
6067
}
11,716✔
6068

6069
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, SColumnDataAgg *pAggs) {
7,618✔
6070
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
7,618✔
6071
  int16_t *numOfNull = &pAggs->numOfNull;
7,618✔
6072
  *(uint64_t *)sum = 0;
7,618✔
6073
  *(uint64_t *)max = 0;
7,618✔
6074
  *(uint64_t *)min = UINT8_MAX;
7,618✔
6075
  *numOfNull = 0;
7,618✔
6076

6077
  uint8_t val;
6078
  if (HAS_VALUE == pColData->flag) {
7,618✔
6079
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
14,703,142✔
6080
      val = ((uint8_t *)pColData->pData)[iVal];
14,696,523✔
6081
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
14,696,523✔
6082
    }
6083
  } else {
6084
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,848,149✔
6085
      switch (tColDataGetBitValue(pColData, iVal)) {
2,847,150!
6086
        case 0:
142,081✔
6087
        case 1:
6088
          (*numOfNull)++;
142,081✔
6089
          break;
142,081✔
6090
        case 2:
2,705,069✔
6091
          val = ((uint8_t *)pColData->pData)[iVal];
2,705,069✔
6092
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
2,705,069✔
6093
          break;
2,705,069✔
6094
        default:
×
6095
          break;
×
6096
      }
6097
    }
6098
  }
6099
}
7,618✔
6100

6101
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, SColumnDataAgg *pAggs) {
7,618✔
6102
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
7,618✔
6103
  int16_t *numOfNull = &pAggs->numOfNull;
7,618✔
6104
  *(uint64_t *)sum = 0;
7,618✔
6105
  *(uint64_t *)max = 0;
7,618✔
6106
  *(uint64_t *)min = UINT16_MAX;
7,618✔
6107
  *numOfNull = 0;
7,618✔
6108

6109
  uint16_t val;
6110
  if (HAS_VALUE == pColData->flag) {
7,618✔
6111
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
14,703,473✔
6112
      val = ((uint16_t *)pColData->pData)[iVal];
14,696,854✔
6113
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
14,696,854✔
6114
    }
6115
  } else {
6116
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,848,149✔
6117
      switch (tColDataGetBitValue(pColData, iVal)) {
2,847,150!
6118
        case 0:
142,158✔
6119
        case 1:
6120
          (*numOfNull)++;
142,158✔
6121
          break;
142,158✔
6122
        case 2:
2,704,992✔
6123
          val = ((uint16_t *)pColData->pData)[iVal];
2,704,992✔
6124
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
2,704,992✔
6125
          break;
2,704,992✔
6126
        default:
×
6127
          break;
×
6128
      }
6129
    }
6130
  }
6131
}
7,618✔
6132

6133
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, SColumnDataAgg *pAggs) {
7,618✔
6134
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
7,618✔
6135
  int16_t *numOfNull = &pAggs->numOfNull;
7,618✔
6136
  *(uint64_t *)sum = 0;
7,618✔
6137
  *(uint64_t *)max = 0;
7,618✔
6138
  *(uint64_t *)min = UINT32_MAX;
7,618✔
6139
  *numOfNull = 0;
7,618✔
6140

6141
  uint32_t val;
6142
  if (HAS_VALUE == pColData->flag) {
7,618✔
6143
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
14,702,767✔
6144
      val = ((uint32_t *)pColData->pData)[iVal];
14,696,148✔
6145
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
14,696,148✔
6146
    }
6147
  } else {
6148
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,848,149✔
6149
      switch (tColDataGetBitValue(pColData, iVal)) {
2,847,150!
6150
        case 0:
142,281✔
6151
        case 1:
6152
          (*numOfNull)++;
142,281✔
6153
          break;
142,281✔
6154
        case 2:
2,704,869✔
6155
          val = ((uint32_t *)pColData->pData)[iVal];
2,704,869✔
6156
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
2,704,869✔
6157
          break;
2,704,869✔
6158
        default:
×
6159
          break;
×
6160
      }
6161
    }
6162
  }
6163
}
7,618✔
6164

6165
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, SColumnDataAgg *pAggs) {
7,618✔
6166
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
7,618✔
6167
  int16_t *numOfNull = &pAggs->numOfNull;
7,618✔
6168
  *(uint64_t *)sum = 0;
7,618✔
6169
  *(uint64_t *)max = 0;
7,618✔
6170
  *(uint64_t *)min = UINT64_MAX;
7,618✔
6171
  *numOfNull = 0;
7,618✔
6172

6173
  uint64_t val;
6174
  if (HAS_VALUE == pColData->flag) {
7,618✔
6175
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
14,700,521✔
6176
      val = ((uint64_t *)pColData->pData)[iVal];
14,693,902✔
6177
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
14,693,902✔
6178
    }
6179
  } else {
6180
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
2,848,149✔
6181
      switch (tColDataGetBitValue(pColData, iVal)) {
2,847,150!
6182
        case 0:
142,364✔
6183
        case 1:
6184
          (*numOfNull)++;
142,364✔
6185
          break;
142,364✔
6186
        case 2:
2,704,786✔
6187
          val = ((uint64_t *)pColData->pData)[iVal];
2,704,786✔
6188
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
2,704,786✔
6189
          break;
2,704,786✔
6190
        default:
×
6191
          break;
×
6192
      }
6193
    }
6194
  }
6195
}
7,618✔
6196

6197
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, SColumnDataAgg *pAggs) {
26,424✔
6198
  int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
26,424✔
6199
  int16_t *numOfNull = &pAggs->numOfNull;
26,424✔
6200
  *(uint64_t *)sum = 0;
26,424✔
6201
  *(uint64_t *)max = 0;
26,424✔
6202
  *(uint64_t *)min = 0;
26,424✔
6203
  *numOfNull = 0;
26,424✔
6204

6205
  switch (pColData->flag) {
26,424!
6206
    case HAS_NONE:
×
6207
    case HAS_NULL:
6208
    case (HAS_NONE | HAS_NULL):
6209
      *numOfNull = pColData->nVal;
×
6210
      break;
×
6211
    case HAS_VALUE:
24,415✔
6212
      *numOfNull = 0;
24,415✔
6213
      break;
24,415✔
6214
    case (HAS_VALUE | HAS_NULL):
2,010✔
6215
    case (HAS_VALUE | HAS_NONE):
6216
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
5,708,310✔
6217
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
5,706,300✔
6218
          (*numOfNull)++;
293,984✔
6219
        }
6220
      }
6221
      break;
2,010✔
6222
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
6223
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
6224
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
6225
          (*numOfNull)++;
×
6226
        }
6227
      }
6228
      break;
×
6229
    default:
×
6230
      break;
×
6231
  }
6232
}
26,424✔
6233

6234
#define CALC_DECIMAL_SUM_MAX_MIN(TYPE, pSumOp, pCompOp, pColData, pSum, pMax, pMin)                   \
6235
  do {                                                                                                \
6236
    if (decimal128AddCheckOverflow((Decimal *)pSum, pVal, DECIMAL_WORD_NUM(TYPE))) *pOverflow = true; \
6237
    pSumOp->add(pSum, pVal, DECIMAL_WORD_NUM(TYPE));                                                  \
6238
    if (pCompOp->gt(pVal, pMax, DECIMAL_WORD_NUM(TYPE))) {                                            \
6239
      *(pMax) = *pVal;                                                                                \
6240
    }                                                                                                 \
6241
    if (pCompOp->lt(pVal, pMin, DECIMAL_WORD_NUM(TYPE))) {                                            \
6242
      *(pMin) = *pVal;                                                                                \
6243
    }                                                                                                 \
6244
  } while (0)
6245

6246
static FORCE_INLINE void tColDataCalcSMADecimal64Type(SColData *pColData, SColumnDataAgg *pAggs) {
693✔
6247
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum;
693✔
6248
  Decimal64  *pMax = (Decimal64 *)pAggs->decimal128Max, *pMin = (Decimal64 *)pAggs->decimal128Min;
693✔
6249
  uint8_t    *pOverflow = &pAggs->overflow;
693✔
6250
  *pSum = DECIMAL128_ZERO;
693✔
6251
  *pMax = DECIMAL64_MIN;
693✔
6252
  *pMin = DECIMAL64_MAX;
693✔
6253
  pAggs->numOfNull = 0;
693✔
6254
  pAggs->colId |= DECIMAL_AGG_FLAG;
693✔
6255

6256
  Decimal64         *pVal = NULL;
693✔
6257
  const SDecimalOps *pSumOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
693✔
6258
  const SDecimalOps *pCompOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
693✔
6259
  if (HAS_VALUE == pColData->flag) {
693✔
6260
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
2,204,567✔
6261
      pVal = ((Decimal64 *)pColData->pData) + iVal;
2,203,885✔
6262
      CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
2,203,885!
6263
    }
6264
  } else {
6265
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
12,012✔
6266
      switch (tColDataGetBitValue(pColData, iVal)) {
12,000!
6267
        case 0:
3,885✔
6268
        case 1:
6269
          pAggs->numOfNull++;
3,885✔
6270
          break;
3,885✔
6271
        case 2:
8,115✔
6272
          pVal = ((Decimal64 *)pColData->pData) + iVal;
8,115✔
6273
          CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pSumOps, pCompOps, pColData, pSum, pMax, pMin);
8,115!
6274
          break;
8,115✔
6275
        default:
×
6276
          break;
×
6277
      }
6278
    }
6279
  }
6280
}
694✔
6281

6282
static FORCE_INLINE void tColDataCalcSMADecimal128Type(SColData *pColData, SColumnDataAgg *pAggs) {
717✔
6283
  Decimal128 *pSum = (Decimal128 *)pAggs->decimal128Sum, *pMax = (Decimal128 *)pAggs->decimal128Max,
717✔
6284
             *pMin = (Decimal128 *)pAggs->decimal128Min;
717✔
6285
  uint8_t *pOverflow = &pAggs->overflow;
717✔
6286
  *pSum = DECIMAL128_ZERO;
717✔
6287
  *pMax = DECIMAL128_MIN;
717✔
6288
  *pMin = DECIMAL128_MAX;
717✔
6289
  pAggs->numOfNull = 0;
717✔
6290
  pAggs->colId |= DECIMAL_AGG_FLAG;
717✔
6291

6292
  Decimal128        *pVal = NULL;
717✔
6293
  const SDecimalOps *pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
717✔
6294
  if (HAS_VALUE == pColData->flag) {
717✔
6295
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
2,205,864✔
6296
      pVal = ((Decimal128 *)pColData->pData) + iVal;
2,205,276✔
6297
      CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
2,205,276!
6298
    }
6299
  } else {
6300
    for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
36,036✔
6301
      switch (tColDataGetBitValue(pColData, iVal)) {
36,000!
6302
        case 0:
11,412✔
6303
        case 1:
6304
          pAggs->numOfNull++;
11,412✔
6305
          break;
11,412✔
6306
        case 2:
24,588✔
6307
          pVal = ((Decimal128 *)pColData->pData) + iVal;
24,588✔
6308
          CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pOps, pColData, pSum, pMax, pMin);
24,588✔
6309
          break;
24,588✔
6310
        default:
×
6311
          break;
×
6312
      }
6313
    }
6314
  }
6315
}
624✔
6316

6317
void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAgg *pAggs) = {
6318
    NULL,
6319
    tColDataCalcSMABool,            // TSDB_DATA_TYPE_BOOL
6320
    tColDataCalcSMATinyInt,         // TSDB_DATA_TYPE_TINYINT
6321
    tColDataCalcSMATinySmallInt,    // TSDB_DATA_TYPE_SMALLINT
6322
    tColDataCalcSMAInt,             // TSDB_DATA_TYPE_INT
6323
    tColDataCalcSMABigInt,          // TSDB_DATA_TYPE_BIGINT
6324
    tColDataCalcSMAFloat,           // TSDB_DATA_TYPE_FLOAT
6325
    tColDataCalcSMADouble,          // TSDB_DATA_TYPE_DOUBLE
6326
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_VARCHAR
6327
    tColDataCalcSMABigInt,          // TSDB_DATA_TYPE_TIMESTAMP
6328
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_NCHAR
6329
    tColDataCalcSMAUTinyInt,        // TSDB_DATA_TYPE_UTINYINT
6330
    tColDataCalcSMATinyUSmallInt,   // TSDB_DATA_TYPE_USMALLINT
6331
    tColDataCalcSMAUInt,            // TSDB_DATA_TYPE_UINT
6332
    tColDataCalcSMAUBigInt,         // TSDB_DATA_TYPE_UBIGINT
6333
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_JSON
6334
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_VARBINARY
6335
    tColDataCalcSMADecimal128Type,  // TSDB_DATA_TYPE_DECIMAL
6336
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_BLOB
6337
    NULL,                           // TSDB_DATA_TYPE_MEDIUMBLOB
6338
    tColDataCalcSMAVarType,         // TSDB_DATA_TYPE_GEOMETRY
6339
    tColDataCalcSMADecimal64Type,   // TSDB_DATA_TYPE_DECIMAL64
6340
};
6341

6342
// SValueColumn ================================
6343
int32_t tValueColumnInit(SValueColumn *valCol) {
20,168,833✔
6344
  valCol->type = TSDB_DATA_TYPE_NULL;
20,168,833✔
6345
  valCol->numOfValues = 0;
20,168,833✔
6346
  tBufferInit(&valCol->data);
20,168,833✔
6347
  tBufferInit(&valCol->offsets);
20,168,833✔
6348
  return 0;
20,168,833✔
6349
}
6350

6351
void tValueColumnDestroy(SValueColumn *valCol) {
47,411,869✔
6352
  valCol->type = TSDB_DATA_TYPE_NULL;
47,411,869✔
6353
  valCol->numOfValues = 0;
47,411,869✔
6354
  tBufferDestroy(&valCol->data);
47,411,869✔
6355
  tBufferDestroy(&valCol->offsets);
47,412,030✔
6356
  return;
47,412,017✔
6357
}
6358

6359
void tValueColumnClear(SValueColumn *valCol) {
22,675,842✔
6360
  valCol->type = TSDB_DATA_TYPE_NULL;
22,675,842✔
6361
  valCol->numOfValues = 0;
22,675,842✔
6362
  tBufferClear(&valCol->data);
22,675,842✔
6363
  tBufferClear(&valCol->offsets);
22,675,842✔
6364
  return;
22,675,842✔
6365
}
6366

6367
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
940,912✔
6368
  int32_t code;
6369

6370
  if (valCol->numOfValues == 0) {
940,912✔
6371
    valCol->type = value->type;
10,742✔
6372
  }
6373

6374
  if (!(value->type == valCol->type)) {
940,912!
6375
    return TSDB_CODE_INVALID_PARA;
×
6376
  }
6377

6378
  if (IS_VAR_DATA_TYPE(value->type)) {
940,912!
6379
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
13,986!
6380
      return code;
×
6381
    }
6382
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
13,986!
6383
      return code;
×
6384
    }
6385
  } else {
6386
    code = tBufferPut(&valCol->data, VALUE_GET_DATUM(value, value->type), tDataTypes[value->type].bytes);
933,919!
6387
    if (code) return code;
933,920!
6388
  }
6389
  valCol->numOfValues++;
940,913✔
6390

6391
  return 0;
940,913✔
6392
}
6393

6394
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
236,774,663✔
6395
  int32_t code;
6396

6397
  if (idx < 0 || idx >= valCol->numOfValues) {
236,774,663!
6398
    return TSDB_CODE_OUT_OF_RANGE;
×
6399
  }
6400

6401
  if (IS_VAR_DATA_TYPE(valCol->type)) {
236,798,298!
UNCOV
6402
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
×
UNCOV
6403
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
×
UNCOV
6404
    int32_t  oldDataSize = nextOffset - offsets[idx];
×
UNCOV
6405
    int32_t  bytesAdded = value->nData - oldDataSize;
×
6406

UNCOV
6407
    if (bytesAdded != 0) {
×
6408
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
72!
6409
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
36✔
6410
              tBufferGetSize(&valCol->data) - nextOffset);
36✔
6411
      valCol->data.size += bytesAdded;
36✔
6412

6413
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
36!
6414
        offsets[i] += bytesAdded;
×
6415
      }
6416
    }
UNCOV
6417
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
×
6418
  } else {
6419
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, VALUE_GET_DATUM(value, valCol->type),
236,853,019!
6420
                        tDataTypes[valCol->type].bytes);
236,853,019✔
6421
  }
6422
  return 0;
6423
}
6424

6425
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
479,026,115✔
6426
  if (idx < 0 || idx >= valCol->numOfValues) {
479,026,115!
6427
    return TSDB_CODE_OUT_OF_RANGE;
×
6428
  }
6429

6430
  value->type = valCol->type;
479,107,502✔
6431
  if (IS_VAR_DATA_TYPE(value->type)) {
479,107,502!
6432
    int32_t       offset, nextOffset;
6433
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
337,818✔
6434

6435
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
337,818!
6436
    if (idx == valCol->numOfValues - 1) {
515,984✔
6437
      nextOffset = tBufferGetSize(&valCol->data);
156,119✔
6438
    } else {
6439
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
359,865✔
6440
    }
6441
    value->nData = nextOffset - offset;
515,804✔
6442
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
515,804✔
6443
  } else {
6444
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
478,769,684✔
6445
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
957,539,368!
6446
  }
6447
  return 0;
479,285,488✔
6448
}
6449

6450
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
10,740✔
6451
  int32_t code;
6452

6453
  if (!(valCol->numOfValues > 0)) {
10,740!
6454
    return TSDB_CODE_INVALID_PARA;
×
6455
  }
6456

6457
  (*info) = (SValueColumnCompressInfo){
10,740✔
6458
      .cmprAlg = info->cmprAlg,
10,740✔
6459
      .type = valCol->type,
10,740✔
6460
  };
6461

6462
  // offset
6463
  if (IS_VAR_DATA_TYPE(valCol->type)) {
10,740!
6464
    SCompressInfo cinfo = {
2,386✔
6465
        .cmprAlg = info->cmprAlg,
2,386✔
6466
        .dataType = TSDB_DATA_TYPE_INT,
6467
        .originalSize = valCol->offsets.size,
2,386✔
6468
    };
6469

6470
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
2,386✔
6471
    if (code) return code;
2,388!
6472

6473
    info->offsetOriginalSize = cinfo.originalSize;
2,388✔
6474
    info->offsetCompressedSize = cinfo.compressedSize;
2,388✔
6475
  }
6476

6477
  // data
6478
  SCompressInfo cinfo = {
10,742✔
6479
      .cmprAlg = info->cmprAlg,
10,742✔
6480
      .dataType = valCol->type,
10,742✔
6481
      .originalSize = valCol->data.size,
10,742✔
6482
  };
6483

6484
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
10,742✔
6485
  if (code) return code;
10,742!
6486

6487
  info->dataOriginalSize = cinfo.originalSize;
10,742✔
6488
  info->dataCompressedSize = cinfo.compressedSize;
10,742✔
6489

6490
  return 0;
10,742✔
6491
}
6492

6493
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
564,682✔
6494
                               SBuffer *assist) {
6495
  int32_t code;
6496

6497
  tValueColumnClear(valCol);
564,682✔
6498
  valCol->type = info->type;
564,727✔
6499
  // offset
6500
  if (IS_VAR_DATA_TYPE(valCol->type)) {
746,979!
6501
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
182,138✔
6502

6503
    SCompressInfo cinfo = {
182,138✔
6504
        .dataType = TSDB_DATA_TYPE_INT,
6505
        .cmprAlg = info->cmprAlg,
182,138✔
6506
        .originalSize = info->offsetOriginalSize,
182,138✔
6507
        .compressedSize = info->offsetCompressedSize,
182,138✔
6508
    };
6509

6510
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
182,138✔
6511
    if (code) {
182,252!
6512
      return code;
×
6513
    }
6514
  } else {
6515
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
382,589✔
6516
  }
6517

6518
  // data
6519
  SCompressInfo cinfo = {
564,841✔
6520
      .dataType = valCol->type,
564,841✔
6521
      .cmprAlg = info->cmprAlg,
564,841✔
6522
      .originalSize = info->dataOriginalSize,
564,841✔
6523
      .compressedSize = info->dataCompressedSize,
564,841✔
6524
  };
6525

6526
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
564,841✔
6527
  if (code) {
564,915!
6528
    return code;
×
6529
  }
6530

6531
  return 0;
564,915✔
6532
}
6533

6534
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
10,742✔
6535
  int32_t code;
6536
  uint8_t fmtVer = 0;
10,742✔
6537

6538
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
21,484!
6539
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
21,484!
6540
  if ((code = tBufferPutI8(buffer, info->type))) return code;
21,484!
6541
  if (IS_VAR_DATA_TYPE(info->type)) {
10,742!
6542
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
4,774!
6543
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
4,774!
6544
  }
6545
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
21,484!
6546
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
21,484!
6547

6548
  return 0;
10,742✔
6549
}
6550

6551
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
564,800✔
6552
  int32_t code;
6553
  uint8_t fmtVer;
6554

6555
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
564,800!
6556
  if (fmtVer == 0) {
564,797!
6557
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
564,803!
6558
    if ((code = tBufferGetI8(reader, &info->type))) return code;
564,721!
6559
    if (IS_VAR_DATA_TYPE(info->type)) {
564,654!
6560
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
182,108!
6561
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
182,144!
6562
    } else {
6563
      info->offsetOriginalSize = 0;
382,546✔
6564
      info->offsetCompressedSize = 0;
382,546✔
6565
    }
6566
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
564,687!
6567
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
564,687!
6568
  } else {
6569
    return TSDB_CODE_INVALID_PARA;
×
6570
  }
6571

6572
  return 0;
564,665✔
6573
}
6574

6575
int32_t tCompressData(void          *input,       // input
5,205,363✔
6576
                      SCompressInfo *info,        // compress info
6577
                      void          *output,      // output
6578
                      int32_t        outputSize,  // output size
6579
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
6580
) {
6581
  int32_t extraSizeNeeded;
6582
  int32_t code;
6583

6584
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
5,205,363✔
6585
  if (!(outputSize >= extraSizeNeeded)) {
5,205,363!
6586
    return TSDB_CODE_INVALID_PARA;
×
6587
  }
6588

6589
  if (info->cmprAlg == NO_COMPRESSION) {
5,205,363✔
6590
    (void)memcpy(output, input, info->originalSize);
244✔
6591
    info->compressedSize = info->originalSize;
244✔
6592
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
6,334,638✔
6593
    SBuffer local;
6594

6595
    tBufferInit(&local);
6596
    if (buffer == NULL) {
1,129,188!
6597
      buffer = &local;
×
6598
    }
6599

6600
    if (info->cmprAlg == TWO_STAGE_COMP) {
1,129,188!
6601
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
1,129,263✔
6602
      if (code) {
1,129,263!
6603
        tBufferDestroy(&local);
6604
        return code;
×
6605
      }
6606
    }
6607

6608
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
2,258,707✔
6609
        input,                                                   // input
6610
        info->originalSize,                                      // input size
6611
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
1,129,188✔
6612
        output,                                                  // output
6613
        outputSize,                                              // output size
6614
        info->cmprAlg,                                           // compression algorithm
1,129,188✔
6615
        buffer->data,                                            // buffer
6616
        buffer->capacity                                         // buffer size
1,129,188✔
6617
    );
6618
    if (info->compressedSize < 0) {
1,129,519!
6619
      tBufferDestroy(&local);
6620
      return TSDB_CODE_COMPRESS_ERROR;
×
6621
    }
6622

6623
    tBufferDestroy(&local);
6624
  } else {
6625
    DEFINE_VAR(info->cmprAlg)
4,075,931✔
6626
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
4,075,931!
6627
      (void)memcpy(output, input, info->originalSize);
12✔
6628
      info->compressedSize = info->originalSize;
12✔
6629
      return 0;
12✔
6630
    }
6631
    SBuffer local;
6632

6633
    tBufferInit(&local);
6634
    if (buffer == NULL) {
4,075,919!
6635
      buffer = &local;
×
6636
    }
6637
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
4,075,919✔
6638

6639
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
8,152,383✔
6640
        input,                                                      // input
6641
        info->originalSize,                                         // input size
6642
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
4,075,921✔
6643
        output,                                                     // output
6644
        outputSize,                                                 // output size
6645
        info->cmprAlg,                                              // compression algorithm
6646
        buffer->data,                                               // buffer
6647
        buffer->capacity                                            // buffer size
4,075,921✔
6648
    );
6649
    if (info->compressedSize < 0) {
4,076,462!
6650
      tBufferDestroy(&local);
6651
      return TSDB_CODE_COMPRESS_ERROR;
×
6652
    }
6653

6654
    tBufferDestroy(&local);
6655
    // new col compress
6656
  }
6657

6658
  return 0;
5,206,225✔
6659
}
6660

6661
int32_t tDecompressData(void                *input,       // input
70,209,029✔
6662
                        const SCompressInfo *info,        // compress info
6663
                        void                *output,      // output
6664
                        int32_t              outputSize,  // output size
6665
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
6666
) {
6667
  int32_t code;
6668

6669
  if (!(outputSize >= info->originalSize)) {
70,209,029!
6670
    return TSDB_CODE_INVALID_PARA;
×
6671
  }
6672

6673
  if (info->cmprAlg == NO_COMPRESSION) {
70,209,029✔
6674
    if (!(info->compressedSize == info->originalSize)) {
244!
6675
      return TSDB_CODE_INVALID_PARA;
×
6676
    }
6677
    (void)memcpy(output, input, info->compressedSize);
244✔
6678
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
99,908,535!
6679
    SBuffer local;
6680

6681
    tBufferInit(&local);
6682
    if (buffer == NULL) {
29,656,999!
6683
      buffer = &local;
×
6684
    }
6685

6686
    if (info->cmprAlg == TWO_STAGE_COMP) {
29,656,999!
6687
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
29,695,607✔
6688
      if (code) {
29,696,438!
6689
        tBufferDestroy(&local);
6690
        return code;
×
6691
      }
6692
    }
6693

6694
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
29,657,830✔
6695
        input,                                                  // input
6696
        info->compressedSize,                                   // inputSize
29,657,830✔
6697
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
29,657,830✔
6698
        output,                                                 // output
6699
        outputSize,                                             // output size
6700
        info->cmprAlg,                                          // compression algorithm
29,657,830✔
6701
        buffer->data,                                           // helper buffer
6702
        buffer->capacity                                        // extra buffer size
29,657,830✔
6703
    );
6704
    if (decompressedSize < 0) {
29,699,750!
6705
      tBufferDestroy(&local);
6706
      return TSDB_CODE_COMPRESS_ERROR;
×
6707
    }
6708

6709
    if (!(decompressedSize == info->originalSize)) {
29,699,750!
6710
      return TSDB_CODE_COMPRESS_ERROR;
×
6711
    }
6712
    tBufferDestroy(&local);
6713
  } else {
6714
    DEFINE_VAR(info->cmprAlg);
40,551,786✔
6715
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
40,551,786✔
6716
      (void)memcpy(output, input, info->compressedSize);
18✔
6717
      return 0;
18✔
6718
    }
6719
    SBuffer local;
6720

6721
    tBufferInit(&local);
6722
    if (buffer == NULL) {
40,551,768!
6723
      buffer = &local;
×
6724
    }
6725
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
40,551,768✔
6726
    if (code) {
40,552,228!
6727
      return code;
×
6728
    }
6729

6730
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
40,552,228✔
6731
        input,                                                  // input
6732
        info->compressedSize,                                   // inputSize
40,552,228✔
6733
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
40,552,228✔
6734
        output,                                                 // output
6735
        outputSize,                                             // output size
6736
        info->cmprAlg,                                          // compression algorithm
40,552,228✔
6737
        buffer->data,                                           // helper buffer
6738
        buffer->capacity                                        // extra buffer size
40,552,228✔
6739
    );
6740
    if (decompressedSize < 0) {
40,559,530!
6741
      tBufferDestroy(&local);
6742
      return TSDB_CODE_COMPRESS_ERROR;
×
6743
    }
6744

6745
    if (!(decompressedSize == info->originalSize)) {
40,559,530!
6746
      return TSDB_CODE_COMPRESS_ERROR;
×
6747
    }
6748
    tBufferDestroy(&local);
6749
  }
6750

6751
  return 0;
70,259,524✔
6752
}
6753

6754
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
5,205,292✔
6755
  int32_t code;
6756

6757
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
5,205,292✔
6758
  if (code) return code;
5,205,297!
6759

6760
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
5,205,297✔
6761
  if (code) return code;
5,205,864!
6762

6763
  output->size += info->compressedSize;
5,205,864✔
6764
  return 0;
5,205,864✔
6765
}
6766

6767
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
29,696,133✔
6768
  int32_t code;
6769

6770
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
29,696,133✔
6771
  if (code) return code;
29,691,938!
6772

6773
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
29,691,938✔
6774
  if (code) return code;
29,698,494!
6775

6776
  output->size += info->originalSize;
29,698,494✔
6777
  return 0;
29,698,494✔
6778
}
6779

6780
// handle all types, including var data
6781
void valueSetDatum(SValue *pVal, int8_t type, void *pDatum, uint32_t len) {
2,147,483,647✔
6782
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
2,147,483,647!
6783
    pVal->pData = pDatum;
×
6784
    pVal->nData = len;
×
6785
  } else {
6786
    switch (len) {
2,147,483,647!
6787
      case sizeof(uint8_t):
1,572,727,213✔
6788
        pVal->val = *(uint8_t *)pDatum;
1,572,727,213✔
6789
        break;
1,572,727,213✔
6790
      case sizeof(uint16_t):
890,999,785✔
6791
        pVal->val = *(uint16_t *)pDatum;
890,999,785✔
6792
        break;
890,999,785✔
6793
      case sizeof(uint32_t):
2,147,483,647✔
6794
        pVal->val = *(uint32_t *)pDatum;
2,147,483,647✔
6795
        break;
2,147,483,647✔
6796
      case sizeof(uint64_t):
2,147,483,647✔
6797
        pVal->val = *(uint64_t *)pDatum;
2,147,483,647✔
6798
        break;
2,147,483,647✔
6799
      default:
×
6800
        break;
×
6801
    }
6802
  }
6803
}
2,147,483,647✔
6804

6805
void valueCloneDatum(SValue *pDst, const SValue *pSrc, int8_t type) {
82,638,602✔
6806
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
82,638,602!
6807
    memcpy(pDst->pData, pSrc->pData, pSrc->nData);
887,190✔
6808
    pDst->nData = pSrc->nData;
887,190✔
6809
  } else {
6810
    pDst->val = pSrc->val;
81,751,412✔
6811
  }
6812
}
82,638,602✔
6813
void valueClearDatum(SValue *pVal, int8_t type) {
×
6814
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
6815
    taosMemoryFreeClear(pVal->pData);
×
6816
    pVal->nData = 0;
×
6817
  } else {
6818
    pVal->val = 0;
×
6819
  }
6820
}
×
6821

6822
int8_t schemaHasBlob(const STSchema *pSchema) {
8,546,301✔
6823
  if (pSchema == NULL) {
8,546,301!
6824
    return 0;
×
6825
  }
6826
  for (int i = 0; i < pSchema->numOfCols; ++i) {
64,959,681✔
6827
    if (IS_STR_DATA_BLOB(pSchema->columns[i].type)) {
56,413,381!
6828
      return 1;
1✔
6829
    }
6830
  }
6831
  return 0;
8,546,300✔
6832
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc