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

taosdata / TDengine / #4513

17 Jul 2025 02:02AM UTC coverage: 31.359% (-31.1%) from 62.446%
#4513

push

travis-ci

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

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

68541 of 301034 branches covered (22.77%)

Branch coverage included in aggregate %.

117356 of 291771 relevant lines covered (40.22%)

602262.98 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

122
  if (isPK) {
733✔
123
    sinfo->tupleIndices[sinfo->numOfPKs].type = colVal->value.type;
×
124
    sinfo->tupleIndices[sinfo->numOfPKs].offset =
×
125
        IS_VAR_DATA_TYPE(pTColumn->type) ? sinfo->tupleVarSize + sinfo->tupleFixedSize : pTColumn->offset;
×
126
    sinfo->kvIndices[sinfo->numOfPKs].type = colVal->value.type;
×
127
    sinfo->kvIndices[sinfo->numOfPKs].offset = sinfo->kvPayloadSize;
×
128
    sinfo->numOfPKs++;
×
129
  }
130

131
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
733✔
132
  if (IS_VAR_DATA_TYPE(colVal->value.type)) {
733!
133
    sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)  // size
212✔
134
                           + colVal->value.nData;               // value
212✔
135

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

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

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

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

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

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

181
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {
733!
182
          tRowBuildScanAddValue(sinfo, &colValArray[colValIndex], schema->columns + i);
733!
183
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {
×
184
          if ((code = tRowBuildScanAddNull(sinfo, schema->columns + i))) goto _exit;
×
185
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {
×
186
          if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
×
187
        }
188

189
        colValIndex++;
733✔
190
        break;
733✔
191
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {
×
192
        if ((code = tRowBuildScanAddNone(sinfo, schema->columns + i))) goto _exit;
×
193
        break;
×
194
      } else {  // skip useless value
195
        colValIndex++;
×
196
      }
197
    }
198
  }
199

200
  if (sinfo->numOfNone) {
261!
201
    sinfo->flag |= HAS_NONE;
×
202
  }
203
  if (sinfo->numOfNull) {
261!
204
    sinfo->flag |= HAS_NULL;
×
205
  }
206
  if (sinfo->numOfValue) {
261!
207
    sinfo->flag |= HAS_VALUE;
261✔
208
  }
209

210
  // Tuple
211
  sinfo->tupleFlag = sinfo->flag;
261✔
212
  switch (sinfo->flag) {
261!
213
    case HAS_NONE:
×
214
    case HAS_NULL:
215
      sinfo->tupleBitmapSize = 0;
×
216
      sinfo->tupleFixedSize = 0;
×
217
      break;
×
218
    case HAS_VALUE:
261✔
219
      sinfo->tupleBitmapSize = 0;
261✔
220
      sinfo->tupleFixedSize = schema->flen;
261✔
221
      break;
261✔
222
    case (HAS_NONE | HAS_NULL):
×
223
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
×
224
      sinfo->tupleFixedSize = 0;
×
225
      break;
×
226
    case (HAS_NONE | HAS_VALUE):
×
227
    case (HAS_NULL | HAS_VALUE):
228
      sinfo->tupleBitmapSize = BIT1_SIZE(schema->numOfCols - 1);
×
229
      sinfo->tupleFixedSize = schema->flen;
×
230
      break;
×
231
    case (HAS_NONE | HAS_NULL | HAS_VALUE):
×
232
      sinfo->tupleBitmapSize = BIT2_SIZE(schema->numOfCols - 1);
×
233
      sinfo->tupleFixedSize = schema->flen;
×
234
      break;
×
235
  }
236
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
261!
237
    sinfo->tupleIndices[i].offset += sinfo->tupleBitmapSize;
×
238
    sinfo->tuplePKSize += tPutPrimaryKeyIndex(NULL, sinfo->tupleIndices + i);
×
239
  }
240
  sinfo->tupleRowSize = sizeof(SRow)              // SRow
261✔
241
                        + sinfo->tuplePKSize      // primary keys
261✔
242
                        + sinfo->tupleBitmapSize  // bitmap
261✔
243
                        + sinfo->tupleFixedSize   // fixed part
261✔
244
                        + sinfo->tupleVarSize;    // var part
261✔
245

246
  // Key-Value
247
  if (sinfo->kvMaxOffset <= UINT8_MAX) {
261!
248
    sinfo->kvFlag = (KV_FLG_LIT | sinfo->flag);
261✔
249
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint8_t);
261✔
250
  } else if (sinfo->kvMaxOffset <= UINT16_MAX) {
×
251
    sinfo->kvFlag = (KV_FLG_MID | sinfo->flag);
×
252
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint16_t);
×
253
  } else {
254
    sinfo->kvFlag = (KV_FLG_BIG | sinfo->flag);
×
255
    sinfo->kvIndexSize = sizeof(SKVIdx) + (sinfo->numOfNull + sinfo->numOfValue) * sizeof(uint32_t);
×
256
  }
257
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
261!
258
    sinfo->kvIndices[i].offset += sinfo->kvIndexSize;
×
259
    sinfo->kvPKSize += tPutPrimaryKeyIndex(NULL, sinfo->kvIndices + i);
×
260
  }
261
  sinfo->kvRowSize = sizeof(SRow)             // SRow
261✔
262
                     + sinfo->kvPKSize        // primary keys
261✔
263
                     + sinfo->kvIndexSize     // index array
261✔
264
                     + sinfo->kvPayloadSize;  // payload
261✔
265

266
_exit:
261✔
267
  return code;
261✔
268
}
269

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

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

284
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
261!
285
    return 0;
×
286
  }
287

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

293
  // primary keys
294
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
261!
295
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
×
296
  }
297

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

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

312
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
733!
313
            *(int32_t *)(fixed + schema->columns[i].offset) = varlen - fixed - sinfo->tupleFixedSize;
212✔
314
            varlen += tPutU32v(varlen, colValArray[colValIndex].value.nData);
212✔
315
            if (colValArray[colValIndex].value.nData) {
212!
316
              (void)memcpy(varlen, colValArray[colValIndex].value.pData, colValArray[colValIndex].value.nData);
212✔
317
              varlen += colValArray[colValIndex].value.nData;
212✔
318
            }
319
          } else {
320
            (void)memcpy(fixed + schema->columns[i].offset,
521✔
321
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
521!
322
                         tDataTypes[schema->columns[i].type].bytes);
521!
323
          }
324
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
×
325
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NULL);
×
326
        } else if (COL_VAL_IS_NONE(&colValArray[colValIndex])) {  // NONE
×
327
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
328
        }
329

330
        colValIndex++;
733✔
331
        break;
733✔
332
      } else if (colValArray[colValIndex].cid > schema->columns[i].colId) {  // NONE
×
333
        ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_NONE);
×
334
        break;
×
335
      } else {
336
        colValIndex++;
×
337
      }
338
    }
339
  }
340

341
  return 0;
261✔
342
}
343

344
static FORCE_INLINE void tRowBuildKVRowSetIndex(uint8_t flag, SKVIdx *indices, uint32_t offset) {
345
  if (flag & KV_FLG_LIT) {
×
346
    ((uint8_t *)indices->idx)[indices->nCol] = (uint8_t)offset;
×
347
  } else if (flag & KV_FLG_MID) {
×
348
    ((uint16_t *)indices->idx)[indices->nCol] = (uint16_t)offset;
×
349
  } else {
350
    ((uint32_t *)indices->idx)[indices->nCol] = (uint32_t)offset;
×
351
  }
352
  indices->nCol++;
×
353
}
×
354

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

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

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

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

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

382
  int32_t numOfColVals = TARRAY_SIZE(aColVal);
×
383
  int32_t colValIndex = 1;
×
384
  for (int32_t i = 1; i < schema->numOfCols; i++) {
×
385
    for (;;) {
386
      if (colValIndex >= numOfColVals) {  // NONE
×
387
        break;
×
388
      }
389

390
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
×
391
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
×
392
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
×
393
          if (IS_VAR_DATA_TYPE(schema->columns[i].type)) {
×
394
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
×
395
            payloadSize += tPutU32v(payload + payloadSize, colValArray[colValIndex].value.nData);
×
396
            if (colValArray[colValIndex].value.nData > 0) {
×
397
              (void)memcpy(payload + payloadSize, colValArray[colValIndex].value.pData,
×
398
                           colValArray[colValIndex].value.nData);
×
399
            }
400
            payloadSize += colValArray[colValIndex].value.nData;
×
401
          } else {
402
            payloadSize += tPutI16v(payload + payloadSize, colValArray[colValIndex].cid);
×
403
            (void)memcpy(payload + payloadSize,
×
404
                         VALUE_GET_DATUM(&colValArray[colValIndex].value, schema->columns[i].type),
×
405
                         tDataTypes[schema->columns[i].type].bytes);
×
406
            payloadSize += tDataTypes[schema->columns[i].type].bytes;
×
407
          }
408
        } else if (COL_VAL_IS_NULL(&colValArray[colValIndex])) {  // NULL
×
409
          tRowBuildKVRowSetIndex(sinfo->kvFlag, indices, payloadSize);
×
410
          payloadSize += tPutI16v(payload + payloadSize, -schema->columns[i].colId);
×
411
        }
412

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

423
  return 0;
×
424
}
425

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

430
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
261✔
431
  if (code) return code;
261!
432

433
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
261!
434
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
261✔
435
  } else {
436
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
×
437
  }
438
  return code;
261✔
439
}
440

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

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

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

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

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

478
  SRowKey rowKey, lastRowKey;
479
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
480
    taosArrayClear(colValArray);
×
481

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

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

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

519
    if (pOrdered && pDupTs) {
×
520
      tRowGetKey(row, &rowKey);
×
521
      if (iRow == 0) {
×
522
        *pOrdered = true;
×
523
        *pDupTs = false;
×
524
      } else {
525
        if (*pOrdered) {
×
526
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
×
527
          *pOrdered = (res >= 0);
×
528
          if (!*pDupTs) {
×
529
            *pDupTs = (res == 0);
×
530
          }
531
        }
532
      }
533
      lastRowKey = rowKey;
×
534
    }
535
  }
536

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

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

546
  STColumn *pTColumn = pTSchema->columns + iCol;
12,058✔
547

548
  if (iCol == 0) {
12,058✔
549
    pColVal->cid = pTColumn->colId;
360✔
550
    pColVal->value.type = pTColumn->type;
360✔
551
    pColVal->flag = CV_FLAG_VALUE;
360✔
552
    VALUE_SET_TRIVIAL_DATUM(&pColVal->value, pRow->ts);
360✔
553
    return 0;
360✔
554
  }
555

556
  if (pRow->flag == HAS_NONE) {
11,698!
557
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
558
    return 0;
×
559
  }
560

561
  if (pRow->flag == HAS_NULL) {
11,698!
562
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
563
    return 0;
×
564
  }
565

566
  SPrimaryKeyIndex index;
567
  uint8_t         *data = pRow->data;
11,698✔
568
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
11,698!
569
    data += tGetPrimaryKeyIndex(data, &index);
×
570
  }
571

572
  if (pRow->flag >> 4) {  // KV Row
11,698!
573
    SKVIdx  *pIdx = (SKVIdx *)data;
×
574
    uint8_t *pv = NULL;
×
575

576
    if (pRow->flag & KV_FLG_LIT) {
×
577
      pv = pIdx->idx + pIdx->nCol;
×
578
    } else if (pRow->flag & KV_FLG_MID) {
×
579
      pv = pIdx->idx + (pIdx->nCol << 1);
×
580
    } else {
581
      pv = pIdx->idx + (pIdx->nCol << 2);
×
582
    }
583

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

597
      int16_t cid;
598
      pData += tGetI16v(pData, &cid);
×
599

600
      if (TABS(cid) == pTColumn->colId) {
×
601
        if (cid < 0) {
×
602
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
603
        } else {
604
          pColVal->cid = pTColumn->colId;
×
605
          pColVal->value.type = pTColumn->type;
×
606
          pColVal->flag = CV_FLAG_VALUE;
×
607

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

627
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
628
  } else {  // Tuple Row
629
    uint8_t *bitmap = data;
11,698✔
630
    uint8_t *fixed;
631
    uint8_t *varlen;
632
    uint8_t  bit;
633

634
    if (pRow->flag == HAS_VALUE) {
11,698!
635
      fixed = bitmap;
11,700✔
636
      bit = BIT_FLG_VALUE;
11,700✔
637
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
×
638
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
639
      bit = GET_BIT2(bitmap, iCol - 1);
×
640
    } else {
641
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
642
      bit = GET_BIT1(bitmap, iCol - 1);
×
643

644
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
×
645
        if (bit) bit++;
×
646
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
×
647
        bit++;
×
648
      }
649
    }
650
    varlen = fixed + pTSchema->flen;
11,698✔
651

652
    if (bit == BIT_FLG_NONE) {
11,698!
653
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
654
      return 0;
×
655
    } else if (bit == BIT_FLG_NULL) {
11,698!
656
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
657
      return 0;
×
658
    }
659

660
    pColVal->cid = pTColumn->colId;
11,698✔
661
    pColVal->value.type = pTColumn->type;
11,698✔
662
    pColVal->flag = CV_FLAG_VALUE;
11,698✔
663
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
11,698!
664
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
250✔
665
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
500!
666
    } else {
667
      valueSetDatum(&pColVal->value, pTColumn->type, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
11,448✔
668
    }
669
  }
670

671
  return 0;
11,702✔
672
}
673

674
void tRowDestroy(SRow *pRow) {
261✔
675
  if (pRow) taosMemoryFree(pRow);
261!
676
}
261✔
677

678
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
×
679
  SRowKey key1, key2;
680
  tRowGetKey(*(SRow **)p1, &key1);
×
681
  tRowGetKey(*(SRow **)p2, &key2);
×
682
  return tRowKeyCompare(&key1, &key2);
×
683
}
684
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
×
685
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
×
686
  int32_t code = 0;
×
687

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

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

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

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

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

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

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

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

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

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

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

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

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

774
  int32_t iStart = 0;
×
775
  while (iStart < aRowP->size) {
×
776
    SRowKey key1;
777
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
×
778

779
    tRowGetKey(row1, &key1);
×
780

781
    int32_t iEnd = iStart + 1;
×
782
    while (iEnd < aRowP->size) {
×
783
      SRowKey key2;
784
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
×
785
      tRowGetKey(row2, &key2);
×
786

787
      if (tRowKeyCompare(&key1, &key2) != 0) break;
×
788

789
      iEnd++;
×
790
    }
791

792
    if (iEnd - iStart > 1) {
×
793
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
×
794
      if (code) return code;
×
795
    }
796

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

801
  return code;
×
802
}
803

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

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

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

827
  int32_t code = 0;
×
828

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

835
  pIter->pRow = pRow;
×
836
  pIter->pTSchema = pTSchema;
×
837
  pIter->iTColumn = 0;
×
838

839
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
×
840

841
  uint8_t         *data = pRow->data;
×
842
  SPrimaryKeyIndex index;
843
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
×
844
    data += tGetPrimaryKeyIndex(data, &index);
×
845
  }
846

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

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

891
void tRowIterClose(SRowIter **ppIter) {
×
892
  SRowIter *pIter = *ppIter;
×
893
  if (pIter) {
×
894
    taosMemoryFree(pIter);
×
895
  }
896
  *ppIter = NULL;
×
897
}
×
898

899
SColVal *tRowIterNext(SRowIter *pIter) {
×
900
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
×
901
    return NULL;
×
902
  }
903

904
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
×
905

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

915
  if (pIter->pRow->flag == HAS_NONE) {
×
916
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
917
    goto _exit;
×
918
  }
919

920
  if (pIter->pRow->flag == HAS_NULL) {
×
921
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
922
    goto _exit;
×
923
  }
924

925
  if (pIter->pRow->flag >> 4) {  // KV
×
926
    if (pIter->iCol < pIter->pIdx->nCol) {
×
927
      uint8_t *pData;
928

929
      if (pIter->pRow->flag & KV_FLG_LIT) {
×
930
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
×
931
      } else if (pIter->pRow->flag & KV_FLG_MID) {
×
932
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
×
933
      } else {
934
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
935
      }
936

937
      int16_t cid;
938
      pData += tGetI16v(pData, &cid);
×
939

940
      if (TABS(cid) == pTColumn->colId) {
×
941
        if (cid < 0) {
×
942
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
943
        } else {
944
          pIter->cv.cid = pTColumn->colId;
×
945
          pIter->cv.value.type = pTColumn->type;
×
946
          pIter->cv.flag = CV_FLAG_VALUE;
×
947

948
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
949
            pData += tGetU32v(pData, &pIter->cv.value.nData);
×
950
            if (pIter->cv.value.nData > 0) {
×
951
              pIter->cv.value.pData = pData;
×
952
            } else {
953
              pIter->cv.value.pData = NULL;
×
954
            }
955
          } else {
956
            valueSetDatum(&pIter->cv.value, pTColumn->type, pData, pTColumn->bytes);
×
957
          }
958
        }
959

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

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

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

1020
_exit:
×
1021
  pIter->iTColumn++;
×
1022
  return &pIter->cv;
×
1023
}
1024

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

1028
  if (flag) return code;
×
1029

1030
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
×
1031
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
×
1032
    if (code) return code;
×
1033
  }
1034

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

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

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

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

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

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

1081
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
261✔
1082
  SPrimaryKeyIndex index;
1083
  uint8_t         *data = pRow->data;
261✔
1084
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
261!
1085
    data += tGetPrimaryKeyIndex(data, &index);
×
1086
  }
1087

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

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

1137
          if (bv == BIT_FLG_NONE) {
×
1138
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
×
1139
              goto _exit;
×
1140
            goto _continue;
×
1141
          } else if (bv == BIT_FLG_NULL) {
×
1142
            if (flag == 0) {
×
1143
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
1144
            } else {
1145
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
×
1146
            }
1147
            if (code) goto _exit;
×
1148
            goto _continue;
×
1149
          }
1150
        }
1151

1152
        if (IS_VAR_DATA_TYPE(pColData->type)) {
945!
1153
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
212!
1154
          uint32_t nData;
1155
          pData += tGetU32v(pData, &nData);
212✔
1156
          if (flag == 0) {
212!
1157
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
212✔
1158
          } else {
1159
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1160
          }
1161
          if (code) goto _exit;
212!
1162
        } else {
1163
          if (flag == 0) {
521!
1164
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
521✔
1165
                                                                          TYPE_BYTES[pColData->type]);
521✔
1166
          } else {
1167
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
×
1168
                                                                          TYPE_BYTES[pColData->type], flag > 0);
×
1169
          }
1170
          if (code) goto _exit;
521!
1171
        }
1172

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

1188
_exit:
261✔
1189
  return code;
261✔
1190
}
1191
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
×
1192
  int32_t code = 0;
×
1193

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

1201
  // primary keys
1202
  uint8_t         *data = pRow->data;
×
1203
  SPrimaryKeyIndex index;
1204
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
×
1205
    data += tGetPrimaryKeyIndex(data, &index);
×
1206
  }
1207

1208
  SKVIdx *pKVIdx = (SKVIdx *)data;
×
1209
  if (pRow->flag & KV_FLG_LIT) {
×
1210
    pv = pKVIdx->idx + pKVIdx->nCol;
×
1211
  } else if (pRow->flag & KV_FLG_MID) {
×
1212
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
×
1213
  } else if (pRow->flag & KV_FLG_BIG) {
×
1214
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1215
  } else {
1216
    return TSDB_CODE_INVALID_PARA;
×
1217
  }
1218

1219
  while (pColData) {
×
1220
    if (pTColumn) {
×
1221
      if (pTColumn->colId == pColData->cid) {
×
1222
        while (iCol < pKVIdx->nCol) {
×
1223
          uint8_t *pData;
1224
          if (pRow->flag & KV_FLG_LIT) {
×
1225
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
×
1226
          } else if (pRow->flag & KV_FLG_MID) {
×
1227
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
×
1228
          } else if (pRow->flag & KV_FLG_BIG) {
×
1229
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1230
          } else {
1231
            return TSDB_CODE_INVALID_DATA_FMT;
×
1232
          }
1233

1234
          int16_t cid;
1235
          pData += tGetI16v(pData, &cid);
×
1236

1237
          if (TABS(cid) == pTColumn->colId) {
×
1238
            if (cid < 0) {
×
1239
              if (flag == 0) {
×
1240
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
1241
              } else {
1242
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
×
1243
              }
1244
              if (code) goto _exit;
×
1245
            } else {
1246
              uint32_t nData;
1247
              if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
1248
                pData += tGetU32v(pData, &nData);
×
1249
              } else {
1250
                nData = 0;
×
1251
              }
1252
              if (flag == 0) {
×
1253
                code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
×
1254
              } else {
1255
                code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1256
              }
1257
              if (code) goto _exit;
×
1258
            }
1259
            iCol++;
×
1260
            goto _continue;
×
1261
          } else if (TABS(cid) > pTColumn->colId) {  // NONE
×
1262
            break;
×
1263
          } else {
1264
            iCol++;
×
1265
          }
1266
        }
1267

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

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

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

1296
  if (pRow->flag == HAS_NONE) {
261!
1297
    return tRowNoneUpsertColData(aColData, nColData, flag);
×
1298
  } else if (pRow->flag == HAS_NULL) {
261!
1299
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
×
1300
  } else if (pRow->flag >> 4) {  // KV row
261!
1301
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
×
1302
  } else {  // TUPLE row
1303
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
261✔
1304
  }
1305
}
1306

1307
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
×
1308
  key->numOfPKs = row->numOfPKs;
×
1309

1310
  if (key->numOfPKs == 0) {
×
1311
    return;
×
1312
  }
1313

1314
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1315

1316
  uint8_t *data = row->data;
×
1317

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

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

1326
    uint8_t *tdata = data + indices[i].offset;
×
1327
    if (row->flag >> 4) {
×
1328
      tdata += tGetI16v(tdata, NULL);
×
1329
    }
1330

1331
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
×
1332
      key->pks[i].pData = tdata;
×
1333
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
×
1334
    } else {
1335
      valueSetDatum(key->pks + i, indices[i].type, tdata, tDataTypes[indices[i].type].bytes);
×
1336
    }
1337
  }
1338
}
1339

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

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

1393
  return 0;
×
1394
}
1395

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

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

1417
  return 0;
×
1418
}
1419

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

1424
  if (pSrc->numOfPKs > 0) {
19,107!
1425
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
×
1426
      SValue *pVal = &pDst->pks[i];
×
1427
      pVal->type = pSrc->pks[i].type;
×
1428

1429
      valueCloneDatum(pVal, pSrc->pks + i, pVal->type);
×
1430
    }
1431
  }
1432
}
19,107✔
1433

1434
// STag ========================================
1435
static int tTagValCmprFn(const void *p1, const void *p2) {
3,485✔
1436
  if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
3,485!
1437
    return -1;
×
1438
  } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
3,485!
1439
    return 1;
×
1440
  }
1441

1442
  return 0;
3,485✔
1443
}
1444
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
752✔
1445
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
752✔
1446
}
1447

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

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

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

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

1544
  // key
1545
  if (isJson) {
112✔
1546
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
64✔
1547
  } else {
1548
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
160✔
1549
  }
1550

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

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

1563
  return n;
112✔
1564
}
1565
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
4,237✔
1566
  int32_t n = 0;
4,237✔
1567

1568
  // key
1569
  if (isJson) {
4,237✔
1570
    n += tGetCStr(p + n, &pTagVal->pKey);
1,504!
1571
  } else {
1572
    n += tGetI16v(p + n, &pTagVal->cid);
6,970!
1573
  }
1574

1575
  // type
1576
  n += tGetI8(p + n, &pTagVal->type);
4,237!
1577

1578
  // value
1579
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
4,237!
1580
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
1,268!
1581
  } else {
1582
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
3,603✔
1583
    n += tDataTypes[pTagVal->type].bytes;
3,603✔
1584
  }
1585

1586
  return n;
4,237✔
1587
}
1588

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

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

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

1606
  // sort
1607
  if (isJson) {
48✔
1608
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
8✔
1609
  } else {
1610
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
40✔
1611
  }
1612

1613
  // get size
1614
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
104✔
1615
    szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
56✔
1616
  }
1617
  if (szTag <= INT8_MAX) {
48!
1618
    szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
48✔
1619
  } else {
1620
    szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
×
1621
    isLarge = 1;
×
1622
  }
1623

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

1641
  if (isLarge) {
48!
1642
    p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
×
1643
  } else {
1644
    p = (uint8_t *)&(*ppTag)->idx[nTag];
48✔
1645
  }
1646
  n = 0;
48✔
1647
  for (int16_t iTag = 0; iTag < nTag; iTag++) {
104✔
1648
    if (isLarge) {
56!
1649
      ((int16_t *)(*ppTag)->idx)[iTag] = n;
×
1650
    } else {
1651
      (*ppTag)->idx[iTag] = n;
56✔
1652
    }
1653
    n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
56✔
1654
  }
1655
#ifdef TD_DEBUG_PRINT_TAG
1656
  debugPrintSTag(*ppTag, __func__, __LINE__);
1657
#endif
1658

1659
  return code;
48✔
1660

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

1665
void tTagFree(STag *pTag) {
33✔
1666
  if (pTag) taosMemoryFree(pTag);
33!
1667
}
33✔
1668

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

1674
  char  *data = NULL;
3,433✔
1675
  int8_t typeBytes = 0;
3,433✔
1676
  if (isJson) {
3,433✔
1677
    typeBytes = CHAR_BYTES;
584✔
1678
  }
1679

1680
  if (IS_VAR_DATA_TYPE(value->type)) {
3,433!
1681
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
431!
1682
    if (data == NULL) {
430!
1683
      return NULL;
×
1684
    }
1685

1686
    if (isJson) {
430✔
1687
      *data = value->type;
424✔
1688
    }
1689

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

1696
  return data;
3,432✔
1697
}
1698

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

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

1714
  if (isLarge) {
4,069!
1715
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
×
1716
  } else {
1717
    p = (uint8_t *)&pTag->idx[pTag->nTag];
4,069✔
1718
  }
1719

1720
  pTagVal->type = TSDB_DATA_TYPE_NULL;
4,069✔
1721
  pTagVal->pData = NULL;
4,069✔
1722
  pTagVal->nData = 0;
4,069✔
1723
  while (lidx <= ridx) {
4,229!
1724
    midx = (lidx + ridx) / 2;
4,229✔
1725
    if (isLarge) {
4,229!
1726
      offset = ((int16_t *)pTag->idx)[midx];
×
1727
    } else {
1728
      offset = pTag->idx[midx];
4,229✔
1729
    }
1730

1731
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
4,229✔
1732
    if (isJson) {
4,229✔
1733
      c = tTagValJsonCmprFn(pTagVal, &tv);
744✔
1734
    } else {
1735
      c = tTagValCmprFn(pTagVal, &tv);
3,485✔
1736
    }
1737

1738
    if (c < 0) {
4,229!
1739
      ridx = midx - 1;
×
1740
    } else if (c > 0) {
4,229✔
1741
      lidx = midx + 1;
160✔
1742
    } else {
1743
      (void)memcpy(pTagVal, &tv, sizeof(tv));
4,069✔
1744
      return true;
4,069✔
1745
    }
1746
  }
1747
  return false;
×
1748
}
1749

1750
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
176✔
1751
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
352✔
1752
}
1753

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

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

1763
  if (isLarge) {
4!
1764
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
×
1765
  } else {
1766
    p = (uint8_t *)&pTag->idx[pTag->nTag];
4✔
1767
  }
1768

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

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

1788
  return code;
4✔
1789

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

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

1802
  pTSchema->numOfCols = numOfCols;
10,584✔
1803
  pTSchema->version = version;
10,584✔
1804

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

1822
  // other columns
1823
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
22,773✔
1824
    SSchema  *pSchema = &aSchema[iCol];
12,189✔
1825
    STColumn *pTColumn = &pTSchema->columns[iCol];
12,189✔
1826

1827
    pTColumn->colId = pSchema->colId;
12,189✔
1828
    pTColumn->type = pSchema->type;
12,189✔
1829
    pTColumn->flags = pSchema->flags;
12,189✔
1830
    pTColumn->offset = pTSchema->flen;
12,189✔
1831

1832
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
12,189!
1833
      pTColumn->bytes = pSchema->bytes;
612✔
1834
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
612✔
1835
    } else {
1836
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
11,577✔
1837
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
11,577✔
1838
    }
1839

1840
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
12,189✔
1841
  }
1842

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

1847
  return pTSchema;
10,584✔
1848
}
1849

1850
static int32_t tTColumnCompare(const void *p1, const void *p2) {
×
1851
  if (((STColumn *)p1)->colId < ((STColumn *)p2)->colId) {
×
1852
    return -1;
×
1853
  } else if (((STColumn *)p1)->colId > ((STColumn *)p2)->colId) {
×
1854
    return 1;
×
1855
  }
1856

1857
  return 0;
×
1858
}
1859

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

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

1868
// SColData ========================================
1869
void tColDataDestroy(void *ph) {
2,712✔
1870
  if (ph) {
2,712!
1871
    SColData *pColData = (SColData *)ph;
2,712✔
1872

1873
    tFree(pColData->pBitMap);
2,712!
1874
    tFree(pColData->aOffset);
2,712!
1875
    tFree(pColData->pData);
2,712!
1876
  }
1877
}
2,712✔
1878

1879
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
2,763✔
1880
  pColData->cid = cid;
2,763✔
1881
  pColData->type = type;
2,763✔
1882
  pColData->cflag = cflag;
2,763✔
1883
  tColDataClear(pColData);
2,763✔
1884
}
2,764✔
1885

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

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

1900
  tColDataClear(pColData);
×
1901
}
×
1902

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

1906
  if (IS_VAR_DATA_TYPE(pColData->type)) {
521!
1907
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
212!
1908
    if (code) goto _exit;
212!
1909
    pColData->aOffset[pColData->nVal] = pColData->nData;
212✔
1910

1911
    if (nData) {
212!
1912
      code = tRealloc(&pColData->pData, pColData->nData + nData);
212!
1913
      if (code) goto _exit;
212!
1914
      (void)memcpy(pColData->pData + pColData->nData, pData, nData);
212✔
1915
      pColData->nData += nData;
212✔
1916
    }
1917
  } else {
1918
    if (!(pColData->nData == tDataTypes[pColData->type].bytes * pColData->nVal)) {
521!
1919
      return TSDB_CODE_INVALID_PARA;
×
1920
    }
1921
    code = tRealloc(&pColData->pData, pColData->nData + tDataTypes[pColData->type].bytes);
521!
1922
    if (code) goto _exit;
521!
1923
    if (pData) {
521!
1924
      (void)memcpy(pColData->pData + pColData->nData, pData, TYPE_BYTES[pColData->type]);
521✔
1925
    } else {
1926
      memset(pColData->pData + pColData->nData, 0, TYPE_BYTES[pColData->type]);
×
1927
    }
1928
    pColData->nData += tDataTypes[pColData->type].bytes;
521✔
1929
  }
1930
  pColData->nVal++;
733✔
1931

1932
_exit:
733✔
1933
  return code;
733✔
1934
}
1935
static FORCE_INLINE int32_t tColDataAppendValue00(SColData *pColData, uint8_t *pData, uint32_t nData) {
89✔
1936
  pColData->flag = HAS_VALUE;
89✔
1937
  pColData->numOfValue++;
89✔
1938
  return tColDataPutValue(pColData, pData, nData);
89✔
1939
}
1940
static FORCE_INLINE int32_t tColDataAppendValue01(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
1941
  pColData->flag = HAS_NONE;
×
1942
  pColData->numOfNone++;
×
1943
  pColData->nVal++;
×
1944
  return 0;
×
1945
}
1946
static FORCE_INLINE int32_t tColDataAppendValue02(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
1947
  pColData->flag = HAS_NULL;
×
1948
  pColData->numOfNull++;
×
1949
  pColData->nVal++;
×
1950
  return 0;
×
1951
}
1952
static FORCE_INLINE int32_t tColDataAppendValue10(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
1953
  int32_t code = 0;
×
1954

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

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

1962
  pColData->flag |= HAS_VALUE;
×
1963
  pColData->numOfValue++;
×
1964

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

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

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

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

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

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

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

2009
  memset(pColData->pBitMap, 0, nBit);
×
2010
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
2011

2012
  pColData->flag |= HAS_VALUE;
×
2013
  pColData->numOfValue++;
×
2014

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

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

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

2038
  memset(pColData->pBitMap, 255, nBit);
×
2039
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2040

2041
  pColData->flag |= HAS_NONE;
×
2042
  pColData->numOfNone++;
×
2043
  pColData->nVal++;
×
2044

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

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

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

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

2067
  tFree(pColData->pBitMap);
×
2068
  pColData->pBitMap = pBitMap;
×
2069

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

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

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

2092
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2093
  pColData->numOfNone++;
×
2094
  pColData->nVal++;
×
2095

2096
  return code;
×
2097
}
2098
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2099
  int32_t code = 0;
×
2100

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

2104
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
2105
  pColData->numOfNull++;
×
2106
  pColData->nVal++;
×
2107

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

2117
  pColData->flag |= HAS_NONE;
×
2118
  pColData->numOfNone++;
×
2119

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

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

2127
  return tColDataPutValue(pColData, NULL, 0);
×
2128
}
2129
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2130
  int32_t code = 0;
×
2131

2132
  pColData->flag |= HAS_NULL;
×
2133
  pColData->numOfNull++;
×
2134

2135
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
2136
  code = tRealloc(&pColData->pBitMap, nBit);
×
2137
  if (code) return code;
×
2138

2139
  memset(pColData->pBitMap, 255, nBit);
×
2140
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2141

2142
  return tColDataPutValue(pColData, NULL, 0);
×
2143
}
2144
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2145
  int32_t code = 0;
×
2146

2147
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
2148
  if (code) return code;
×
2149

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

2153
  return tColDataPutValue(pColData, pData, nData);
×
2154
}
2155
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2156
  int32_t code = 0;
×
2157

2158
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
2159
  if (code) return code;
×
2160

2161
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2162
  pColData->numOfNone++;
×
2163

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

2169
  pColData->flag |= HAS_NULL;
×
2170
  pColData->numOfNull++;
×
2171

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

2176
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
2177
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
×
2178
  }
2179
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
×
2180

2181
  tFree(pColData->pBitMap);
×
2182
  pColData->pBitMap = pBitMap;
×
2183

2184
  return tColDataPutValue(pColData, NULL, 0);
×
2185
}
2186
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2187
  int32_t code = 0;
×
2188

2189
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
2190
  if (code) return code;
×
2191
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
2192
  pColData->numOfValue++;
×
2193

2194
  return tColDataPutValue(pColData, pData, nData);
×
2195
}
2196
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2197
  int32_t code = 0;
×
2198

2199
  pColData->flag |= HAS_NONE;
×
2200
  pColData->numOfNone++;
×
2201

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

2206
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
2207
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
×
2208
  }
2209
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
×
2210

2211
  tFree(pColData->pBitMap);
×
2212
  pColData->pBitMap = pBitMap;
×
2213

2214
  return tColDataPutValue(pColData, NULL, 0);
×
2215
}
2216
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2217
  int32_t code = 0;
×
2218

2219
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
2220
  if (code) return code;
×
2221
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2222
  pColData->numOfNull++;
×
2223

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

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

2234
  return tColDataPutValue(pColData, pData, nData);
×
2235
}
2236
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2237
  int32_t code = 0;
×
2238

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

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

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

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

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

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

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

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

2583
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
×
2584

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

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

2684
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal) {
×
2685
  switch (pColData->flag) {
×
2686
    case HAS_NONE:
×
2687
      return 0;
×
2688
    case HAS_NULL:
×
2689
      return 1;
×
2690
    case (HAS_NULL | HAS_NONE):
×
2691
      return GET_BIT1(pColData->pBitMap, iVal);
×
2692
    case HAS_VALUE:
×
2693
      return 2;
×
2694
    case (HAS_VALUE | HAS_NONE):
×
2695
      return (GET_BIT1(pColData->pBitMap, iVal)) ? 2 : 0;
×
2696
    case (HAS_VALUE | HAS_NULL):
×
2697
      return GET_BIT1(pColData->pBitMap, iVal) + 1;
×
2698
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
2699
      return GET_BIT2(pColData->pBitMap, iVal);
×
2700
    default:
×
2701
      return 0;
×
2702
  }
2703
}
2704

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

2708
  *pColData = *pColDataFrom;
×
2709

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

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

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

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

2760
_exit:
×
2761
  return code;
×
2762
}
2763

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

2768
  if (!(colData->nVal > 0)) {
88!
2769
    return TSDB_CODE_INVALID_PARA;
×
2770
  }
2771

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

2781
  if (colData->flag == HAS_NONE || colData->flag == HAS_NULL) {
88!
2782
    return 0;
×
2783
  }
2784

2785
  tBufferInit(&local);
2786
  if (assist == NULL) {
89!
2787
    assist = &local;
×
2788
  }
2789

2790
  // bitmap
2791
  if (colData->flag != HAS_VALUE) {
89!
2792
    if (colData->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
×
2793
      info->bitmapOriginalSize = BIT2_SIZE(colData->nVal);
×
2794
    } else {
2795
      info->bitmapOriginalSize = BIT1_SIZE(colData->nVal);
×
2796
    }
2797

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

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

2810
    info->bitmapCompressedSize = cinfo.compressedSize;
×
2811
  }
2812

2813
  if (colData->flag == (HAS_NONE | HAS_NULL)) {
89!
2814
    tBufferDestroy(&local);
2815
    return 0;
×
2816
  }
2817

2818
  // offset
2819
  if (IS_VAR_DATA_TYPE(colData->type)) {
89!
2820
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
17✔
2821

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

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

2834
    info->offsetCompressedSize = cinfo.compressedSize;
17✔
2835
  }
2836

2837
  // data
2838
  if (colData->nData > 0) {
89!
2839
    info->dataOriginalSize = colData->nData;
89✔
2840

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

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

2853
    info->dataCompressedSize = cinfo.compressedSize;
89✔
2854
  }
2855

2856
  tBufferDestroy(&local);
2857
  return 0;
89✔
2858
}
2859

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

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

2870
  tColDataClear(colData);
2,673✔
2871
  colData->cid = info->columnId;
2,675✔
2872
  colData->type = info->dataType;
2,675✔
2873
  colData->cflag = info->columnFlag;
2,675✔
2874
  colData->nVal = info->numOfData;
2,675✔
2875
  colData->flag = info->flag;
2,675✔
2876

2877
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
2,675!
2878
    goto _exit;
×
2879
  }
2880

2881
  // bitmap
2882
  if (info->bitmapOriginalSize > 0) {
2,675!
2883
    SCompressInfo cinfo = {
×
2884
        .dataType = TSDB_DATA_TYPE_TINYINT,
2885
        .cmprAlg = info->cmprAlg,
×
2886
        .originalSize = info->bitmapOriginalSize,
×
2887
        .compressedSize = info->bitmapCompressedSize,
×
2888
    };
2889

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

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

2902
    data += cinfo.compressedSize;
×
2903
  }
2904

2905
  if (info->flag == (HAS_NONE | HAS_NULL)) {
2,675!
2906
    goto _exit;
×
2907
  }
2908

2909
  // offset
2910
  if (info->offsetOriginalSize > 0) {
2,675!
2911
    SCompressInfo cinfo = {
×
2912
        .cmprAlg = info->cmprAlg,
×
2913
        .dataType = TSDB_DATA_TYPE_INT,
2914
        .originalSize = info->offsetOriginalSize,
×
2915
        .compressedSize = info->offsetCompressedSize,
×
2916
    };
2917

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

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

2930
    data += cinfo.compressedSize;
×
2931
  }
2932

2933
  // data
2934
  if (info->dataOriginalSize > 0) {
2,675✔
2935
    colData->nData = info->dataOriginalSize;
2,674✔
2936

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

2944
    code = tRealloc((uint8_t **)&colData->pData, cinfo.originalSize);
2,674!
2945
    if (code) {
2,675!
2946
      tBufferDestroy(&local);
2947
      return code;
×
2948
    }
2949

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

2956
    data += cinfo.compressedSize;
2,672✔
2957
  }
2958

2959
_exit:
1✔
2960
  switch (colData->flag) {
2,673!
2961
    case HAS_NONE:
×
2962
      colData->numOfNone = colData->nVal;
×
2963
      break;
×
2964
    case HAS_NULL:
×
2965
      colData->numOfNull = colData->nVal;
×
2966
      break;
×
2967
    case HAS_VALUE:
2,674✔
2968
      colData->numOfValue = colData->nVal;
2,674✔
2969
      break;
2,674✔
2970
    default:
×
2971
      for (int32_t i = 0; i < colData->nVal; i++) {
×
2972
        uint8_t bitValue = tColDataGetBitValue(colData, i);
×
2973
        if (bitValue == 0) {
×
2974
          colData->numOfNone++;
×
2975
        } else if (bitValue == 1) {
×
2976
          colData->numOfNull++;
×
2977
        } else {
2978
          colData->numOfValue++;
×
2979
        }
2980
      }
2981
  }
2982
  tBufferDestroy(&local);
2983
  return 0;
2,673✔
2984
}
2985

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

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

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

3060
_exit:
×
3061
  return code;
×
3062
}
3063

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

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

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

3115
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
×
3116
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3117
      goto _exit;
×
3118
    }
3119

3120
    if (allValue) {
×
3121
      // optimize (todo)
3122
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3123
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
×
3124
            pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
×
3125
      }
3126
    } else if (allNull) {
×
3127
      // optimize (todo)
3128
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3129
        code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3130
        if (code) goto _exit;
×
3131
      }
3132
    } else {
3133
      for (int32_t i = 0; i < pBind->num; ++i) {
×
3134
        if (pBind->is_null[i]) {
×
3135
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
3136
          if (code) goto _exit;
×
3137
        } else {
3138
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
×
3139
              pColData, (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i, pBind->buffer_length);
×
3140
        }
3141
      }
3142
    }
3143
  }
3144

3145
_exit:
×
3146
  return code;
×
3147
}
3148

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

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

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

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

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

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

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

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

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

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

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

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

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

3309
  SRowKey rowKey, lastRowKey;
3310
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
3311
    taosArrayClear(colValArray);
×
3312

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

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

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

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

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

3383
    if (pOrdered && pDupTs) {
×
3384
      tRowGetKey(row, &rowKey);
×
3385
      if (iRow == 0) {
×
3386
        *pOrdered = true;
×
3387
        *pDupTs = false;
×
3388
      } else {
3389
        if (*pOrdered) {
×
3390
          int32_t res = tRowKeyCompare(&rowKey, &lastRowKey);
×
3391
          *pOrdered = (res >= 0);
×
3392
          if (!*pDupTs) {
×
3393
            *pDupTs = (res == 0);
×
3394
          }
3395
        }
3396
      }
3397
      lastRowKey = rowKey;
×
3398
    }
3399
  }
3400
_exit:
×
3401
  taosArrayDestroy(colValArray);
×
3402
  taosArrayDestroy(bufArray);
×
3403
  return code;
×
3404
}
3405

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

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

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

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

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

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

3477
  return code;
×
3478
}
3479

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

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

3491
  return code;
×
3492
}
3493

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

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

3509
  return code;
×
3510
}
3511

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

3515
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
×
3516
  key->numOfPKs = 0;
×
3517

3518
  for (int i = 1; i < nColData; i++) {
×
3519
    if (aColData[i].cflag & COL_IS_KEY) {
×
3520
      tColDataGetValue4(&aColData[i], iRow, &cv);
×
3521
      key->pks[key->numOfPKs++] = cv.value;
×
3522
    } else {
3523
      break;
×
3524
    }
3525
  }
3526
}
×
3527

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

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

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

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

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

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

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

3574
  return TSDB_CODE_SUCCESS;
×
3575
}
3576

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

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

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

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

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

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

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

3603
  if (nVal < 2) return TSDB_CODE_SUCCESS;
×
3604

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

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

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

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

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

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

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

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

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

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

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

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

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

3696
  int8_t doSort = 0;
×
3697
  int8_t doMerge = 0;
×
3698
  // scan -------
3699
  SRowKey lastKey;
3700
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
×
3701
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
×
3702
    SRowKey key;
3703
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
×
3704

3705
    int32_t c = tRowKeyCompare(&lastKey, &key);
×
3706
    if (c < 0) {
×
3707
      lastKey = key;
×
3708
      continue;
×
3709
    } else if (c > 0) {
×
3710
      doSort = 1;
×
3711
      break;
×
3712
    } else {
3713
      doMerge = 1;
×
3714
    }
3715
  }
3716

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

3722
  if (doMerge != 1) {
×
3723
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
×
3724
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
×
3725
      SRowKey key;
3726
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
×
3727

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

3737
  // merge -------
3738
  if (doMerge) {
×
3739
    int32_t code = tColDataMerge(arr);
×
3740
    if (code) return code;
×
3741
  }
3742

3743
_exit:
×
3744
  return 0;
×
3745
}
3746

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

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

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

3771
  // value
3772
  if (pColData->flag & HAS_VALUE) {
×
3773
    if (IS_VAR_DATA_TYPE(pColData->type)) {
×
3774
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
×
3775
      if (code) return code;
×
3776

3777
      code = tEncodeI32v(pEncoder, pColData->nData);
×
3778
      if (code) return code;
×
3779

3780
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
×
3781
      if (code) return code;
×
3782
    } else {
3783
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
×
3784
      if (code) return code;
×
3785
    }
3786
  }
3787

3788
  return code;
×
3789
}
3790

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

3794
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
×
3795
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
×
3796
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
×
3797
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
×
3798

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

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

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

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

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

3838
  return code;
×
3839
}
3840

3841
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
×
3842
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
×
3843
  if (code) return code;
×
3844
  return tEncodeI8(pEncoder, pColData->cflag);
×
3845
}
3846

3847
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
×
3848
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
×
3849
  if (code) return code;
×
3850

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

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

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

3875
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow) { return tEncodeFixed(pEncoder, pRow, pRow->len); }
1,044✔
3876

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

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

3886
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
2,091✔
3887
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
4,182!
3888
}
3889

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

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

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

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

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

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

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

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

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

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

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

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

4065
  float val;
4066
  if (HAS_VALUE == pColData->flag) {
×
4067
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4068
      val = ((float *)pColData->pData)[iVal];
×
4069
      CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
×
4070
    }
4071
  } else {
4072
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4073
      switch (tColDataGetBitValue(pColData, iVal)) {
×
4074
        case 0:
×
4075
        case 1:
4076
          (*numOfNull)++;
×
4077
          break;
×
4078
        case 2:
×
4079
          val = ((float *)pColData->pData)[iVal];
×
4080
          CALC_SUM_MAX_MIN(*(double *)sum, *(double *)max, *(double *)min, val);
×
4081
          break;
×
4082
        default:
×
4083
          break;
×
4084
      }
4085
    }
4086
  }
4087
}
×
4088

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4422
  if (valCol->numOfValues == 0) {
×
4423
    valCol->type = value->type;
×
4424
  }
4425

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

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

4443
  return 0;
×
4444
}
4445

4446
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
×
4447
  int32_t code;
4448

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

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

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

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

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

4482
  value->type = valCol->type;
×
4483
  if (IS_VAR_DATA_TYPE(value->type)) {
×
4484
    int32_t       offset, nextOffset;
4485
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
×
4486

4487
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
×
4488
    if (idx == valCol->numOfValues - 1) {
×
4489
      nextOffset = tBufferGetSize(&valCol->data);
×
4490
    } else {
4491
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
×
4492
    }
4493
    value->nData = nextOffset - offset;
×
4494
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
×
4495
  } else {
4496
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
×
4497
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, VALUE_GET_DATUM(value, value->type)));
×
4498
  }
4499
  return 0;
×
4500
}
4501

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

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

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

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

4522
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
×
4523
    if (code) return code;
×
4524

4525
    info->offsetOriginalSize = cinfo.originalSize;
×
4526
    info->offsetCompressedSize = cinfo.compressedSize;
×
4527
  }
4528

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

4536
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
×
4537
  if (code) return code;
×
4538

4539
  info->dataOriginalSize = cinfo.originalSize;
×
4540
  info->dataCompressedSize = cinfo.compressedSize;
×
4541

4542
  return 0;
×
4543
}
4544

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

4549
  tValueColumnClear(valCol);
×
4550
  valCol->type = info->type;
×
4551
  // offset
4552
  if (IS_VAR_DATA_TYPE(valCol->type)) {
×
4553
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
×
4554

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

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

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

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

4583
  return 0;
×
4584
}
4585

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

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

4600
  return 0;
×
4601
}
4602

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

4607
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
×
4608
  if (fmtVer == 0) {
×
4609
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
×
4610
    if ((code = tBufferGetI8(reader, &info->type))) return code;
×
4611
    if (IS_VAR_DATA_TYPE(info->type)) {
×
4612
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
×
4613
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
×
4614
    } else {
4615
      info->offsetOriginalSize = 0;
×
4616
      info->offsetCompressedSize = 0;
×
4617
    }
4618
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
×
4619
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
×
4620
  } else {
4621
    return TSDB_CODE_INVALID_PARA;
×
4622
  }
4623

4624
  return 0;
×
4625
}
4626

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

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

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

4647
    tBufferInit(&local);
4648
    if (buffer == NULL) {
79!
4649
      buffer = &local;
×
4650
    }
4651

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

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

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

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

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

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

4710
  return 0;
275✔
4711
}
4712

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

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

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

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

4738
    if (info->cmprAlg == TWO_STAGE_COMP) {
24,367!
4739
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
24,389✔
4740
      if (code) {
24,389!
4741
        tBufferDestroy(&local);
4742
        return code;
×
4743
      }
4744
    }
4745

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

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

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

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

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

4803
  return 0;
41,707✔
4804
}
4805

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

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

4812
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
274✔
4813
  if (code) return code;
275!
4814

4815
  output->size += info->compressedSize;
275✔
4816
  return 0;
275✔
4817
}
4818

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

4822
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
24,386!
4823
  if (code) return code;
24,385!
4824

4825
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
24,385✔
4826
  if (code) return code;
24,387!
4827

4828
  output->size += info->originalSize;
24,387✔
4829
  return 0;
24,387✔
4830
}
4831

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

4857
void valueCloneDatum(SValue *pDst, const SValue *pSrc, int8_t type) {
×
4858
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
4859
    memcpy(pDst->pData, pSrc->pData, pSrc->nData);
×
4860
    pDst->nData = pSrc->nData;
×
4861
  } else {
4862
    pDst->val = pSrc->val;
×
4863
  }
4864
}
×
4865
void valueClearDatum(SValue *pVal, int8_t type) {
×
4866
  if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_DECIMAL) {
×
4867
    taosMemoryFreeClear(pVal->pData);
×
4868
    pVal->nData = 0;
×
4869
  } else {
4870
    pVal->val = 0;
×
4871
  }
4872
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc