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

taosdata / TDengine / #3621

22 Feb 2025 11:44AM UTC coverage: 2.037% (-61.5%) from 63.573%
#3621

push

travis-ci

web-flow
Merge pull request #29874 from taosdata/merge/mainto3.0

merge: from main to 3.0 branch

4357 of 287032 branches covered (1.52%)

Branch coverage included in aggregate %.

0 of 174 new or added lines in 18 files covered. (0.0%)

213359 existing lines in 469 files now uncovered.

7260 of 283369 relevant lines covered (2.56%)

23737.72 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

UNCOV
130
  sinfo->kvMaxOffset = sinfo->kvPayloadSize;
×
UNCOV
131
  if (IS_VAR_DATA_TYPE(colVal->value.type)) {
×
UNCOV
132
    sinfo->tupleVarSize += tPutU32v(NULL, colVal->value.nData)  // size
×
UNCOV
133
                           + colVal->value.nData;               // value
×
134

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

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

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

UNCOV
161
  *sinfo = (SRowBuildScanInfo){
×
UNCOV
162
      .tupleFixedSize = schema->flen,
×
163
  };
164

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

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

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

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

UNCOV
198
  if (sinfo->numOfNone) {
×
UNCOV
199
    sinfo->flag |= HAS_NONE;
×
200
  }
UNCOV
201
  if (sinfo->numOfNull) {
×
UNCOV
202
    sinfo->flag |= HAS_NULL;
×
203
  }
UNCOV
204
  if (sinfo->numOfValue) {
×
UNCOV
205
    sinfo->flag |= HAS_VALUE;
×
206
  }
207

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

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

UNCOV
264
_exit:
×
UNCOV
265
  return code;
×
266
}
267

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

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

UNCOV
282
  if (sinfo->tupleFlag == HAS_NONE || sinfo->tupleFlag == HAS_NULL) {
×
UNCOV
283
    return 0;
×
284
  }
285

UNCOV
286
  uint8_t *primaryKeys = (*ppRow)->data;
×
UNCOV
287
  uint8_t *bitmap = primaryKeys + sinfo->tuplePKSize;
×
UNCOV
288
  uint8_t *fixed = bitmap + sinfo->tupleBitmapSize;
×
UNCOV
289
  uint8_t *varlen = fixed + sinfo->tupleFixedSize;
×
290

291
  // primary keys
UNCOV
292
  for (int32_t i = 0; i < sinfo->numOfPKs; i++) {
×
UNCOV
293
    primaryKeys += tPutPrimaryKeyIndex(primaryKeys, sinfo->tupleIndices + i);
×
294
  }
295

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

UNCOV
306
      if (colValArray[colValIndex].cid == schema->columns[i].colId) {
×
UNCOV
307
        if (COL_VAL_IS_VALUE(&colValArray[colValIndex])) {  // value
×
UNCOV
308
          ROW_SET_BITMAP(bitmap, sinfo->tupleFlag, i - 1, BIT_FLG_VALUE);
×
309

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

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

UNCOV
338
  return 0;
×
339
}
340

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

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

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

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

UNCOV
369
  uint8_t *primaryKeys = (*ppRow)->data;
×
UNCOV
370
  SKVIdx  *indices = (SKVIdx *)(primaryKeys + sinfo->kvPKSize);
×
UNCOV
371
  uint8_t *payload = primaryKeys + sinfo->kvPKSize + sinfo->kvIndexSize;
×
UNCOV
372
  uint32_t payloadSize = 0;
×
373

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

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

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

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

UNCOV
419
  return 0;
×
420
}
421

UNCOV
422
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow) {
×
423
  int32_t           code;
424
  SRowBuildScanInfo sinfo;
425

UNCOV
426
  code = tRowBuildScan(aColVal, pTSchema, &sinfo);
×
UNCOV
427
  if (code) return code;
×
428

UNCOV
429
  if (sinfo.tupleRowSize <= sinfo.kvRowSize) {
×
UNCOV
430
    code = tRowBuildTupleRow(aColVal, &sinfo, pTSchema, ppRow);
×
431
  } else {
UNCOV
432
    code = tRowBuildKVRow(aColVal, &sinfo, pTSchema, ppRow);
×
433
  }
UNCOV
434
  return code;
×
435
}
436

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

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

UNCOV
461
  if (!infoSorted) {
×
462
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
463
  }
464

UNCOV
465
  int32_t code = 0;
×
UNCOV
466
  int32_t numOfRows = infos[0].bind->num;
×
467
  SArray *colValArray;
468
  SColVal colVal;
469

UNCOV
470
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
×
471
    return terrno;
×
472
  }
473

474
  SRowKey rowKey, lastRowKey;
UNCOV
475
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
UNCOV
476
    taosArrayClear(colValArray);
×
477

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

504
    SRow *row;
UNCOV
505
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
×
506
      goto _exit;
×
507
    }
508

UNCOV
509
    if ((taosArrayPush(rowArray, &row)) == NULL) {
×
510
      code = terrno;
×
511
      goto _exit;
×
512
    }
513

UNCOV
514
    if (pOrdered && pDupTs) {
×
UNCOV
515
      tRowGetKey(row, &rowKey);
×
UNCOV
516
      if (iRow == 0) {
×
UNCOV
517
        *pOrdered = true;
×
UNCOV
518
        *pDupTs = false;
×
519
      } else {
520
        // no more compare if we already get disordered or duplicate rows
UNCOV
521
        if (*pOrdered && !*pDupTs) {
×
UNCOV
522
          int32_t code = tRowKeyCompare(&rowKey, &lastRowKey);
×
UNCOV
523
          *pOrdered = (code >= 0);
×
UNCOV
524
          *pDupTs = (code == 0);
×
525
        }
526
      }
UNCOV
527
      lastRowKey = rowKey;
×
528
    }
529
  }
530

UNCOV
531
_exit:
×
UNCOV
532
  taosArrayDestroy(colValArray);
×
UNCOV
533
  return code;
×
534
}
535

UNCOV
536
int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
×
UNCOV
537
  if (!(iCol < pTSchema->numOfCols)) return TSDB_CODE_INVALID_PARA;
×
UNCOV
538
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
×
539

UNCOV
540
  STColumn *pTColumn = pTSchema->columns + iCol;
×
541

UNCOV
542
  if (iCol == 0) {
×
UNCOV
543
    pColVal->cid = pTColumn->colId;
×
UNCOV
544
    pColVal->value.type = pTColumn->type;
×
UNCOV
545
    pColVal->flag = CV_FLAG_VALUE;
×
UNCOV
546
    (void)memcpy(&pColVal->value.val, &pRow->ts, sizeof(TSKEY));
×
UNCOV
547
    return 0;
×
548
  }
549

UNCOV
550
  if (pRow->flag == HAS_NONE) {
×
UNCOV
551
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
UNCOV
552
    return 0;
×
553
  }
554

UNCOV
555
  if (pRow->flag == HAS_NULL) {
×
UNCOV
556
    *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
UNCOV
557
    return 0;
×
558
  }
559

560
  SPrimaryKeyIndex index;
UNCOV
561
  uint8_t         *data = pRow->data;
×
UNCOV
562
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
×
UNCOV
563
    data += tGetPrimaryKeyIndex(data, &index);
×
564
  }
565

UNCOV
566
  if (pRow->flag >> 4) {  // KV Row
×
UNCOV
567
    SKVIdx  *pIdx = (SKVIdx *)data;
×
UNCOV
568
    uint8_t *pv = NULL;
×
569

UNCOV
570
    if (pRow->flag & KV_FLG_LIT) {
×
UNCOV
571
      pv = pIdx->idx + pIdx->nCol;
×
UNCOV
572
    } else if (pRow->flag & KV_FLG_MID) {
×
UNCOV
573
      pv = pIdx->idx + (pIdx->nCol << 1);
×
574
    } else {
575
      pv = pIdx->idx + (pIdx->nCol << 2);
×
576
    }
577

UNCOV
578
    int16_t lidx = 0;
×
UNCOV
579
    int16_t ridx = pIdx->nCol - 1;
×
UNCOV
580
    while (lidx <= ridx) {
×
UNCOV
581
      int16_t  mid = (lidx + ridx) >> 1;
×
UNCOV
582
      uint8_t *pData = NULL;
×
UNCOV
583
      if (pRow->flag & KV_FLG_LIT) {
×
UNCOV
584
        pData = pv + ((uint8_t *)pIdx->idx)[mid];
×
UNCOV
585
      } else if (pRow->flag & KV_FLG_MID) {
×
UNCOV
586
        pData = pv + ((uint16_t *)pIdx->idx)[mid];
×
587
      } else {
588
        pData = pv + ((uint32_t *)pIdx->idx)[mid];
×
589
      }
590

591
      int16_t cid;
UNCOV
592
      pData += tGetI16v(pData, &cid);
×
593

UNCOV
594
      if (TABS(cid) == pTColumn->colId) {
×
UNCOV
595
        if (cid < 0) {
×
UNCOV
596
          *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
597
        } else {
UNCOV
598
          pColVal->cid = pTColumn->colId;
×
UNCOV
599
          pColVal->value.type = pTColumn->type;
×
UNCOV
600
          pColVal->flag = CV_FLAG_VALUE;
×
601

UNCOV
602
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
UNCOV
603
            pData += tGetU32v(pData, &pColVal->value.nData);
×
UNCOV
604
            if (pColVal->value.nData > 0) {
×
UNCOV
605
              pColVal->value.pData = pData;
×
606
            } else {
607
              pColVal->value.pData = NULL;
×
608
            }
609
          } else {
UNCOV
610
            (void)memcpy(&pColVal->value.val, pData, pTColumn->bytes);
×
611
          }
612
        }
UNCOV
613
        return 0;
×
UNCOV
614
      } else if (TABS(cid) < pTColumn->colId) {
×
UNCOV
615
        lidx = mid + 1;
×
616
      } else {
UNCOV
617
        ridx = mid - 1;
×
618
      }
619
    }
620

UNCOV
621
    *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
622
  } else {  // Tuple Row
UNCOV
623
    uint8_t *bitmap = data;
×
624
    uint8_t *fixed;
625
    uint8_t *varlen;
626
    uint8_t  bit;
627

UNCOV
628
    if (pRow->flag == HAS_VALUE) {
×
UNCOV
629
      fixed = bitmap;
×
UNCOV
630
      bit = BIT_FLG_VALUE;
×
UNCOV
631
    } else if (pRow->flag == (HAS_NONE | HAS_NULL | HAS_VALUE)) {
×
632
      fixed = BIT2_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
633
      bit = GET_BIT2(bitmap, iCol - 1);
×
634
    } else {
UNCOV
635
      fixed = BIT1_SIZE(pTSchema->numOfCols - 1) + bitmap;
×
UNCOV
636
      bit = GET_BIT1(bitmap, iCol - 1);
×
637

UNCOV
638
      if (pRow->flag == (HAS_NONE | HAS_VALUE)) {
×
UNCOV
639
        if (bit) bit++;
×
UNCOV
640
      } else if (pRow->flag == (HAS_NULL | HAS_VALUE)) {
×
UNCOV
641
        bit++;
×
642
      }
643
    }
UNCOV
644
    varlen = fixed + pTSchema->flen;
×
645

UNCOV
646
    if (bit == BIT_FLG_NONE) {
×
UNCOV
647
      *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
UNCOV
648
      return 0;
×
UNCOV
649
    } else if (bit == BIT_FLG_NULL) {
×
UNCOV
650
      *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
UNCOV
651
      return 0;
×
652
    }
653

UNCOV
654
    pColVal->cid = pTColumn->colId;
×
UNCOV
655
    pColVal->value.type = pTColumn->type;
×
UNCOV
656
    pColVal->flag = CV_FLAG_VALUE;
×
UNCOV
657
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
UNCOV
658
      pColVal->value.pData = varlen + *(int32_t *)(fixed + pTColumn->offset);
×
UNCOV
659
      pColVal->value.pData += tGetU32v(pColVal->value.pData, &pColVal->value.nData);
×
660
    } else {
UNCOV
661
      (void)memcpy(&pColVal->value.val, fixed + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
×
662
    }
663
  }
664

UNCOV
665
  return 0;
×
666
}
667

UNCOV
668
void tRowDestroy(SRow *pRow) {
×
UNCOV
669
  if (pRow) taosMemoryFree(pRow);
×
UNCOV
670
}
×
671

UNCOV
672
static int32_t tRowPCmprFn(const void *p1, const void *p2) {
×
673
  SRowKey key1, key2;
UNCOV
674
  tRowGetKey(*(SRow **)p1, &key1);
×
UNCOV
675
  tRowGetKey(*(SRow **)p2, &key2);
×
UNCOV
676
  return tRowKeyCompare(&key1, &key2);
×
677
}
UNCOV
678
static void    tRowPDestroy(SRow **ppRow) { tRowDestroy(*ppRow); }
×
UNCOV
679
static int32_t tRowMergeImpl(SArray *aRowP, STSchema *pTSchema, int32_t iStart, int32_t iEnd, int8_t flag) {
×
UNCOV
680
  int32_t code = 0;
×
681

UNCOV
682
  int32_t    nRow = iEnd - iStart;
×
UNCOV
683
  SRowIter **aIter = NULL;
×
UNCOV
684
  SArray    *aColVal = NULL;
×
UNCOV
685
  SRow      *pRow = NULL;
×
686

UNCOV
687
  aIter = taosMemoryCalloc(nRow, sizeof(SRowIter *));
×
UNCOV
688
  if (aIter == NULL) {
×
689
    code = terrno;
×
690
    goto _exit;
×
691
  }
692

UNCOV
693
  for (int32_t i = 0; i < nRow; i++) {
×
UNCOV
694
    SRow *pRowT = taosArrayGetP(aRowP, iStart + i);
×
695

UNCOV
696
    code = tRowIterOpen(pRowT, pTSchema, &aIter[i]);
×
UNCOV
697
    if (code) goto _exit;
×
698
  }
699

700
  // merge
UNCOV
701
  aColVal = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
×
UNCOV
702
  if (aColVal == NULL) {
×
703
    code = terrno;
×
704
    goto _exit;
×
705
  }
706

UNCOV
707
  for (int32_t iCol = 0; iCol < pTSchema->numOfCols; iCol++) {
×
UNCOV
708
    SColVal *pColVal = NULL;
×
UNCOV
709
    for (int32_t iRow = nRow - 1; iRow >= 0; --iRow) {
×
UNCOV
710
      SColVal *pColValT = tRowIterNext(aIter[iRow]);
×
UNCOV
711
      while (pColValT->cid < pTSchema->columns[iCol].colId) {
×
UNCOV
712
        pColValT = tRowIterNext(aIter[iRow]);
×
713
      }
714

715
      // todo: take strategy according to the flag
UNCOV
716
      if (COL_VAL_IS_VALUE(pColValT)) {
×
UNCOV
717
        pColVal = pColValT;
×
UNCOV
718
        break;
×
UNCOV
719
      } else if (COL_VAL_IS_NULL(pColValT)) {
×
UNCOV
720
        if (pColVal == NULL) {
×
UNCOV
721
          pColVal = pColValT;
×
722
        }
723
      }
724
    }
725

UNCOV
726
    if (pColVal) {
×
UNCOV
727
      if (taosArrayPush(aColVal, pColVal) == NULL) {
×
728
        code = terrno;
×
729
        goto _exit;
×
730
      }
731
    }
732
  }
733

734
  // build
UNCOV
735
  code = tRowBuild(aColVal, pTSchema, &pRow);
×
UNCOV
736
  if (code) goto _exit;
×
737

UNCOV
738
  taosArrayRemoveBatch(aRowP, iStart, nRow, (FDelete)tRowPDestroy);
×
UNCOV
739
  if (taosArrayInsert(aRowP, iStart, &pRow) == NULL) {
×
740
    code = terrno;
×
741
    goto _exit;
×
742
  }
743

UNCOV
744
_exit:
×
UNCOV
745
  if (aIter) {
×
UNCOV
746
    for (int32_t i = 0; i < nRow; i++) {
×
UNCOV
747
      tRowIterClose(&aIter[i]);
×
748
    }
UNCOV
749
    taosMemoryFree(aIter);
×
750
  }
UNCOV
751
  if (aColVal) taosArrayDestroy(aColVal);
×
UNCOV
752
  if (code) tRowDestroy(pRow);
×
UNCOV
753
  return code;
×
754
}
755

UNCOV
756
int32_t tRowSort(SArray *aRowP) {
×
UNCOV
757
  if (TARRAY_SIZE(aRowP) <= 1) return 0;
×
UNCOV
758
  int32_t code = taosArrayMSort(aRowP, tRowPCmprFn);
×
UNCOV
759
  if (code != TSDB_CODE_SUCCESS) {
×
760
    uError("taosArrayMSort failed caused by %d", code);
×
761
  }
UNCOV
762
  return code;
×
763
}
764

UNCOV
765
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, int8_t flag) {
×
UNCOV
766
  int32_t code = 0;
×
767

UNCOV
768
  int32_t iStart = 0;
×
UNCOV
769
  while (iStart < aRowP->size) {
×
770
    SRowKey key1;
UNCOV
771
    SRow   *row1 = (SRow *)taosArrayGetP(aRowP, iStart);
×
772

UNCOV
773
    tRowGetKey(row1, &key1);
×
774

UNCOV
775
    int32_t iEnd = iStart + 1;
×
UNCOV
776
    while (iEnd < aRowP->size) {
×
777
      SRowKey key2;
UNCOV
778
      SRow   *row2 = (SRow *)taosArrayGetP(aRowP, iEnd);
×
UNCOV
779
      tRowGetKey(row2, &key2);
×
780

UNCOV
781
      if (tRowKeyCompare(&key1, &key2) != 0) break;
×
782

783
      iEnd++;
×
784
    }
785

UNCOV
786
    if (iEnd - iStart > 1) {
×
UNCOV
787
      code = tRowMergeImpl(aRowP, pTSchema, iStart, iEnd, flag);
×
UNCOV
788
      if (code) return code;
×
789
    }
790

791
    // the array is also changing, so the iStart just ++ instead of iEnd
UNCOV
792
    iStart++;
×
793
  }
794

UNCOV
795
  return code;
×
796
}
797

798
// SRowIter ========================================
799
struct SRowIter {
800
  SRow     *pRow;
801
  STSchema *pTSchema;
802

803
  int32_t iTColumn;
804
  union {
805
    struct {  // kv
806
      int32_t iCol;
807
      SKVIdx *pIdx;
808
    };
809
    struct {  // tuple
810
      uint8_t *pb;
811
      uint8_t *pf;
812
    };
813
  };
814
  uint8_t *pv;
815
  SColVal  cv;
816
};
817

UNCOV
818
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) {
×
UNCOV
819
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
×
820

UNCOV
821
  int32_t code = 0;
×
822

UNCOV
823
  SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter));
×
UNCOV
824
  if (pIter == NULL) {
×
825
    code = terrno;
×
826
    goto _exit;
×
827
  }
828

UNCOV
829
  pIter->pRow = pRow;
×
UNCOV
830
  pIter->pTSchema = pTSchema;
×
UNCOV
831
  pIter->iTColumn = 0;
×
832

UNCOV
833
  if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit;
×
834

UNCOV
835
  uint8_t         *data = pRow->data;
×
836
  SPrimaryKeyIndex index;
UNCOV
837
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
×
UNCOV
838
    data += tGetPrimaryKeyIndex(data, &index);
×
839
  }
840

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

UNCOV
876
_exit:
×
UNCOV
877
  if (code) {
×
878
    *ppIter = NULL;
×
879
  } else {
UNCOV
880
    *ppIter = pIter;
×
881
  }
UNCOV
882
  return code;
×
883
}
884

UNCOV
885
void tRowIterClose(SRowIter **ppIter) {
×
UNCOV
886
  SRowIter *pIter = *ppIter;
×
UNCOV
887
  if (pIter) {
×
UNCOV
888
    taosMemoryFree(pIter);
×
889
  }
UNCOV
890
  *ppIter = NULL;
×
UNCOV
891
}
×
892

UNCOV
893
SColVal *tRowIterNext(SRowIter *pIter) {
×
UNCOV
894
  if (pIter->iTColumn >= pIter->pTSchema->numOfCols) {
×
UNCOV
895
    return NULL;
×
896
  }
897

UNCOV
898
  STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn;
×
899

900
  // timestamp
UNCOV
901
  if (0 == pIter->iTColumn) {
×
UNCOV
902
    pIter->cv.cid = pTColumn->colId;
×
UNCOV
903
    pIter->cv.value.type = pTColumn->type;
×
UNCOV
904
    pIter->cv.flag = CV_FLAG_VALUE;
×
UNCOV
905
    (void)memcpy(&pIter->cv.value.val, &pIter->pRow->ts, sizeof(TSKEY));
×
UNCOV
906
    goto _exit;
×
907
  }
908

UNCOV
909
  if (pIter->pRow->flag == HAS_NONE) {
×
UNCOV
910
    pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
UNCOV
911
    goto _exit;
×
912
  }
913

UNCOV
914
  if (pIter->pRow->flag == HAS_NULL) {
×
UNCOV
915
    pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
UNCOV
916
    goto _exit;
×
917
  }
918

UNCOV
919
  if (pIter->pRow->flag >> 4) {  // KV
×
UNCOV
920
    if (pIter->iCol < pIter->pIdx->nCol) {
×
921
      uint8_t *pData;
922

UNCOV
923
      if (pIter->pRow->flag & KV_FLG_LIT) {
×
UNCOV
924
        pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol];
×
UNCOV
925
      } else if (pIter->pRow->flag & KV_FLG_MID) {
×
UNCOV
926
        pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol];
×
927
      } else {
928
        pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol];
×
929
      }
930

931
      int16_t cid;
UNCOV
932
      pData += tGetI16v(pData, &cid);
×
933

UNCOV
934
      if (TABS(cid) == pTColumn->colId) {
×
UNCOV
935
        if (cid < 0) {
×
UNCOV
936
          pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
937
        } else {
UNCOV
938
          pIter->cv.cid = pTColumn->colId;
×
UNCOV
939
          pIter->cv.value.type = pTColumn->type;
×
UNCOV
940
          pIter->cv.flag = CV_FLAG_VALUE;
×
941

UNCOV
942
          if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
UNCOV
943
            pData += tGetU32v(pData, &pIter->cv.value.nData);
×
UNCOV
944
            if (pIter->cv.value.nData > 0) {
×
UNCOV
945
              pIter->cv.value.pData = pData;
×
946
            } else {
947
              pIter->cv.value.pData = NULL;
×
948
            }
949
          } else {
UNCOV
950
            (void)memcpy(&pIter->cv.value.val, pData, pTColumn->bytes);
×
951
          }
952
        }
953

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

UNCOV
988
      if (bv == BIT_FLG_NONE) {
×
UNCOV
989
        pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type);
×
UNCOV
990
        goto _exit;
×
UNCOV
991
      } else if (bv == BIT_FLG_NULL) {
×
UNCOV
992
        pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
×
UNCOV
993
        goto _exit;
×
994
      }
995
    }
996

997
    pIter->cv.cid = pTColumn->colId;
×
998
    pIter->cv.value.type = pTColumn->type;
×
999
    pIter->cv.flag = CV_FLAG_VALUE;
×
1000
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
×
1001
      uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset);
×
1002
      pData += tGetU32v(pData, &pIter->cv.value.nData);
×
1003
      if (pIter->cv.value.nData > 0) {
×
UNCOV
1004
        pIter->cv.value.pData = pData;
×
1005
      } else {
1006
        pIter->cv.value.pData = NULL;
×
1007
      }
1008
    } else {
UNCOV
1009
      (void)memcpy(&pIter->cv.value.val, pIter->pf + pTColumn->offset, TYPE_BYTES[pTColumn->type]);
×
1010
    }
1011
    goto _exit;
×
1012
  }
1013

UNCOV
1014
_exit:
×
UNCOV
1015
  pIter->iTColumn++;
×
UNCOV
1016
  return &pIter->cv;
×
1017
}
1018

UNCOV
1019
static int32_t tRowNoneUpsertColData(SColData *aColData, int32_t nColData, int32_t flag) {
×
UNCOV
1020
  int32_t code = 0;
×
1021

UNCOV
1022
  if (flag) return code;
×
1023

UNCOV
1024
  for (int32_t iColData = 0; iColData < nColData; iColData++) {
×
UNCOV
1025
    code = tColDataAppendValueImpl[aColData[iColData].flag][CV_FLAG_NONE](&aColData[iColData], NULL, 0);
×
UNCOV
1026
    if (code) return code;
×
1027
  }
1028

UNCOV
1029
  return code;
×
1030
}
UNCOV
1031
static int32_t tRowNullUpsertColData(SColData *aColData, int32_t nColData, STSchema *pSchema, int32_t flag) {
×
UNCOV
1032
  int32_t code = 0;
×
1033

UNCOV
1034
  int32_t   iColData = 0;
×
UNCOV
1035
  SColData *pColData = &aColData[iColData];
×
UNCOV
1036
  int32_t   iTColumn = 1;
×
UNCOV
1037
  STColumn *pTColumn = &pSchema->columns[iTColumn];
×
1038

UNCOV
1039
  while (pColData) {
×
UNCOV
1040
    if (pTColumn) {
×
UNCOV
1041
      if (pTColumn->colId == pColData->cid) {  // NULL
×
UNCOV
1042
        if (flag == 0) {
×
UNCOV
1043
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
1044
        } else {
UNCOV
1045
          code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
×
1046
        }
UNCOV
1047
        if (code) goto _exit;
×
1048

UNCOV
1049
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
UNCOV
1050
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
×
1051
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
1052
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1053
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1054
      } else {
1055
        pTColumn = (++iTColumn < pSchema->numOfCols) ? &pSchema->columns[iTColumn] : NULL;
×
1056
      }
1057
    } else {  // 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
    }
1061
  }
1062

UNCOV
1063
_exit:
×
UNCOV
1064
  return code;
×
1065
}
UNCOV
1066
static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData,
×
1067
                                      int32_t flag) {
UNCOV
1068
  int32_t code = 0;
×
1069

UNCOV
1070
  int32_t   iColData = 0;
×
UNCOV
1071
  SColData *pColData = &aColData[iColData];
×
UNCOV
1072
  int32_t   iTColumn = 1;
×
UNCOV
1073
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
×
1074

UNCOV
1075
  uint8_t         *pb = NULL, *pf = NULL, *pv = NULL;
×
1076
  SPrimaryKeyIndex index;
UNCOV
1077
  uint8_t         *data = pRow->data;
×
UNCOV
1078
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
×
UNCOV
1079
    data += tGetPrimaryKeyIndex(data, &index);
×
1080
  }
1081

UNCOV
1082
  switch (pRow->flag) {
×
UNCOV
1083
    case HAS_VALUE:
×
UNCOV
1084
      pf = data;  // TODO: fix here
×
UNCOV
1085
      pv = pf + pTSchema->flen;
×
UNCOV
1086
      break;
×
UNCOV
1087
    case (HAS_NULL | HAS_NONE):
×
UNCOV
1088
      pb = data;
×
UNCOV
1089
      break;
×
UNCOV
1090
    case (HAS_VALUE | HAS_NONE):
×
1091
    case (HAS_VALUE | HAS_NULL):
UNCOV
1092
      pb = data;
×
UNCOV
1093
      pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
×
UNCOV
1094
      pv = pf + pTSchema->flen;
×
UNCOV
1095
      break;
×
1096
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1097
      pb = data;
×
1098
      pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
×
1099
      pv = pf + pTSchema->flen;
×
1100
      break;
×
1101
    default:
×
1102
      return TSDB_CODE_INVALID_DATA_FMT;
×
1103
  }
1104

UNCOV
1105
  while (pColData) {
×
UNCOV
1106
    if (pTColumn) {
×
UNCOV
1107
      if (pTColumn->colId == pColData->cid) {
×
UNCOV
1108
        if (!(pTColumn->type == pColData->type)) {
×
1109
          return TSDB_CODE_INVALID_PARA;
×
1110
        }
UNCOV
1111
        if (pb) {
×
1112
          uint8_t bv;
UNCOV
1113
          switch (pRow->flag) {
×
UNCOV
1114
            case (HAS_NULL | HAS_NONE):
×
UNCOV
1115
              bv = GET_BIT1(pb, iTColumn - 1);
×
UNCOV
1116
              break;
×
UNCOV
1117
            case (HAS_VALUE | HAS_NONE):
×
UNCOV
1118
              bv = GET_BIT1(pb, iTColumn - 1);
×
UNCOV
1119
              if (bv) bv++;
×
UNCOV
1120
              break;
×
UNCOV
1121
            case (HAS_VALUE | HAS_NULL):
×
UNCOV
1122
              bv = GET_BIT1(pb, iTColumn - 1) + 1;
×
UNCOV
1123
              break;
×
1124
            case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
1125
              bv = GET_BIT2(pb, iTColumn - 1);
×
1126
              break;
×
1127
            default:
×
1128
              return TSDB_CODE_INVALID_DATA_FMT;
×
1129
          }
1130

UNCOV
1131
          if (bv == BIT_FLG_NONE) {
×
UNCOV
1132
            if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0)))
×
1133
              goto _exit;
×
UNCOV
1134
            goto _continue;
×
UNCOV
1135
          } else if (bv == BIT_FLG_NULL) {
×
UNCOV
1136
            if (flag == 0) {
×
UNCOV
1137
              code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
×
1138
            } else {
UNCOV
1139
              code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0, flag > 0);
×
1140
            }
UNCOV
1141
            if (code) goto _exit;
×
UNCOV
1142
            goto _continue;
×
1143
          }
1144
        }
1145

UNCOV
1146
        if (IS_VAR_DATA_TYPE(pColData->type)) {
×
UNCOV
1147
          uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset);
×
1148
          uint32_t nData;
UNCOV
1149
          pData += tGetU32v(pData, &nData);
×
UNCOV
1150
          if (flag == 0) {
×
UNCOV
1151
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData);
×
1152
          } else {
1153
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pData, nData, flag > 0);
×
1154
          }
UNCOV
1155
          if (code) goto _exit;
×
1156
        } else {
UNCOV
1157
          if (flag == 0) {
×
UNCOV
1158
            code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
×
UNCOV
1159
                                                                          TYPE_BYTES[pColData->type]);
×
1160
          } else {
UNCOV
1161
            code = tColDataUpdateValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, pf + pTColumn->offset,
×
UNCOV
1162
                                                                          TYPE_BYTES[pColData->type], flag > 0);
×
1163
          }
UNCOV
1164
          if (code) goto _exit;
×
1165
        }
1166

UNCOV
1167
      _continue:
×
UNCOV
1168
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
UNCOV
1169
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
UNCOV
1170
      } else if (pTColumn->colId > pColData->cid) {  // NONE
×
1171
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1172
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1173
      } else {
UNCOV
1174
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
1175
      }
1176
    } else {
UNCOV
1177
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
UNCOV
1178
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1179
    }
1180
  }
1181

UNCOV
1182
_exit:
×
UNCOV
1183
  return code;
×
1184
}
UNCOV
1185
static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
×
UNCOV
1186
  int32_t code = 0;
×
1187

UNCOV
1188
  uint8_t  *pv = NULL;
×
UNCOV
1189
  int32_t   iColData = 0;
×
UNCOV
1190
  SColData *pColData = &aColData[iColData];
×
UNCOV
1191
  int32_t   iTColumn = 1;
×
UNCOV
1192
  STColumn *pTColumn = &pTSchema->columns[iTColumn];
×
UNCOV
1193
  int32_t   iCol = 0;
×
1194

1195
  // primary keys
UNCOV
1196
  uint8_t         *data = pRow->data;
×
1197
  SPrimaryKeyIndex index;
UNCOV
1198
  for (int32_t i = 0; i < pRow->numOfPKs; i++) {
×
UNCOV
1199
    data += tGetPrimaryKeyIndex(data, &index);
×
1200
  }
1201

UNCOV
1202
  SKVIdx *pKVIdx = (SKVIdx *)data;
×
UNCOV
1203
  if (pRow->flag & KV_FLG_LIT) {
×
UNCOV
1204
    pv = pKVIdx->idx + pKVIdx->nCol;
×
UNCOV
1205
  } else if (pRow->flag & KV_FLG_MID) {
×
UNCOV
1206
    pv = pKVIdx->idx + (pKVIdx->nCol << 1);
×
1207
  } else if (pRow->flag & KV_FLG_BIG) {
×
1208
    pv = pKVIdx->idx + (pKVIdx->nCol << 2);
×
1209
  } else {
1210
    return TSDB_CODE_INVALID_PARA;
×
1211
  }
1212

UNCOV
1213
  while (pColData) {
×
UNCOV
1214
    if (pTColumn) {
×
UNCOV
1215
      if (pTColumn->colId == pColData->cid) {
×
UNCOV
1216
        while (iCol < pKVIdx->nCol) {
×
1217
          uint8_t *pData;
UNCOV
1218
          if (pRow->flag & KV_FLG_LIT) {
×
UNCOV
1219
            pData = pv + ((uint8_t *)pKVIdx->idx)[iCol];
×
UNCOV
1220
          } else if (pRow->flag & KV_FLG_MID) {
×
UNCOV
1221
            pData = pv + ((uint16_t *)pKVIdx->idx)[iCol];
×
1222
          } else if (pRow->flag & KV_FLG_BIG) {
×
1223
            pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
×
1224
          } else {
1225
            return TSDB_CODE_INVALID_DATA_FMT;
×
1226
          }
1227

1228
          int16_t cid;
UNCOV
1229
          pData += tGetI16v(pData, &cid);
×
1230

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

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

UNCOV
1264
      _continue:
×
UNCOV
1265
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
UNCOV
1266
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
UNCOV
1267
      } else if (pTColumn->colId > pColData->cid) {
×
1268
        if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
1269
        pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1270
      } else {
UNCOV
1271
        pTColumn = (++iTColumn < pTSchema->numOfCols) ? &pTSchema->columns[iTColumn] : NULL;
×
1272
      }
1273
    } else {
UNCOV
1274
      if (flag == 0 && (code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0))) goto _exit;
×
UNCOV
1275
      pColData = (++iColData < nColData) ? &aColData[iColData] : NULL;
×
1276
    }
1277
  }
1278

UNCOV
1279
_exit:
×
UNCOV
1280
  return code;
×
1281
}
1282
/* flag > 0: forward update
1283
 * flag == 0: append
1284
 * flag < 0: backward update
1285
 */
UNCOV
1286
int32_t tRowUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag) {
×
UNCOV
1287
  if (!(pRow->sver == pTSchema->version)) return TSDB_CODE_INVALID_PARA;
×
UNCOV
1288
  if (!(nColData > 0)) return TSDB_CODE_INVALID_PARA;
×
1289

UNCOV
1290
  if (pRow->flag == HAS_NONE) {
×
UNCOV
1291
    return tRowNoneUpsertColData(aColData, nColData, flag);
×
UNCOV
1292
  } else if (pRow->flag == HAS_NULL) {
×
UNCOV
1293
    return tRowNullUpsertColData(aColData, nColData, pTSchema, flag);
×
UNCOV
1294
  } else if (pRow->flag >> 4) {  // KV row
×
UNCOV
1295
    return tRowKVUpsertColData(pRow, pTSchema, aColData, nColData, flag);
×
1296
  } else {  // TUPLE row
UNCOV
1297
    return tRowTupleUpsertColData(pRow, pTSchema, aColData, nColData, flag);
×
1298
  }
1299
}
1300

UNCOV
1301
void tRowGetPrimaryKey(SRow *row, SRowKey *key) {
×
UNCOV
1302
  key->numOfPKs = row->numOfPKs;
×
1303

UNCOV
1304
  if (key->numOfPKs == 0) {
×
1305
    return;
×
1306
  }
1307

1308
  SPrimaryKeyIndex indices[TD_MAX_PK_COLS];
1309

UNCOV
1310
  uint8_t *data = row->data;
×
1311

UNCOV
1312
  for (int32_t i = 0; i < row->numOfPKs; i++) {
×
UNCOV
1313
    data += tGetPrimaryKeyIndex(data, &indices[i]);
×
1314
  }
1315

1316
  // primary keys
UNCOV
1317
  for (int32_t i = 0; i < row->numOfPKs; i++) {
×
UNCOV
1318
    key->pks[i].type = indices[i].type;
×
1319

UNCOV
1320
    uint8_t *tdata = data + indices[i].offset;
×
UNCOV
1321
    if (row->flag >> 4) {
×
UNCOV
1322
      tdata += tGetI16v(tdata, NULL);
×
1323
    }
1324

UNCOV
1325
    if (IS_VAR_DATA_TYPE(indices[i].type)) {
×
UNCOV
1326
      key->pks[i].pData = tdata;
×
UNCOV
1327
      key->pks[i].pData += tGetU32v(key->pks[i].pData, &key->pks[i].nData);
×
1328
    } else {
UNCOV
1329
      (void)memcpy(&key->pks[i].val, tdata, tDataTypes[indices[i].type].bytes);
×
1330
    }
1331
  }
1332
}
1333

1334
#define T_COMPARE_SCALAR_VALUE(TYPE, V1, V2)    \
1335
  do {                                          \
1336
    if (*(TYPE *)(V1) < *(TYPE *)(V2)) {        \
1337
      return -1;                                \
1338
    } else if (*(TYPE *)(V1) > *(TYPE *)(V2)) { \
1339
      return 1;                                 \
1340
    } else {                                    \
1341
      return 0;                                 \
1342
    }                                           \
1343
  } while (0)
1344

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

UNCOV
1387
  return 0;
×
1388
}
1389

1390
// NOTE:
1391
// set key->numOfPKs to 0 as the smallest key with ts
1392
// set key->numOfPKs to (TD_MAX_PK_COLS + 1) as the largest key with ts
UNCOV
1393
FORCE_INLINE int32_t tRowKeyCompare(const SRowKey *key1, const SRowKey *key2) {
×
UNCOV
1394
  if (key1->ts < key2->ts) {
×
UNCOV
1395
    return -1;
×
UNCOV
1396
  } else if (key1->ts > key2->ts) {
×
UNCOV
1397
    return 1;
×
1398
  }
1399

UNCOV
1400
  if (key1->numOfPKs == key2->numOfPKs) {
×
UNCOV
1401
    for (uint8_t iKey = 0; iKey < key1->numOfPKs; iKey++) {
×
UNCOV
1402
      int32_t ret = tValueCompare(&key1->pks[iKey], &key2->pks[iKey]);
×
UNCOV
1403
      if (ret) return ret;
×
1404
    }
1405
  } else if (key1->numOfPKs < key2->numOfPKs) {
×
1406
    return -1;
×
1407
  } else {
1408
    return 1;
×
1409
  }
1410

UNCOV
1411
  return 0;
×
1412
}
1413

UNCOV
1414
void tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc) {
×
UNCOV
1415
  pDst->ts = pSrc->ts;
×
UNCOV
1416
  pDst->numOfPKs = pSrc->numOfPKs;
×
1417

UNCOV
1418
  if (pSrc->numOfPKs > 0) {
×
UNCOV
1419
    for (int32_t i = 0; i < pSrc->numOfPKs; ++i) {
×
UNCOV
1420
      SValue *pVal = &pDst->pks[i];
×
UNCOV
1421
      pVal->type = pSrc->pks[i].type;
×
1422

UNCOV
1423
      if (IS_NUMERIC_TYPE(pVal->type)) {
×
UNCOV
1424
        pVal->val = pSrc->pks[i].val;
×
1425
      } else {
UNCOV
1426
        pVal->nData = pSrc->pks[i].nData;
×
UNCOV
1427
        (void)memcpy(pVal->pData, pSrc->pks[i].pData, pVal->nData);
×
1428
      }
1429
    }
1430
  }
UNCOV
1431
}
×
1432

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

UNCOV
1441
  return 0;
×
1442
}
UNCOV
1443
static int tTagValJsonCmprFn(const void *p1, const void *p2) {
×
UNCOV
1444
  return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
×
1445
}
1446

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

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

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

UNCOV
1540
static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
×
UNCOV
1541
  int32_t n = 0;
×
1542

1543
  // key
UNCOV
1544
  if (isJson) {
×
UNCOV
1545
    n += tPutCStr(p ? p + n : p, pTagVal->pKey);
×
1546
  } else {
UNCOV
1547
    n += tPutI16v(p ? p + n : p, pTagVal->cid);
×
1548
  }
1549

1550
  // type
UNCOV
1551
  n += tPutI8(p ? p + n : p, pTagVal->type);
×
1552

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

UNCOV
1562
  return n;
×
1563
}
UNCOV
1564
static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
×
UNCOV
1565
  int32_t n = 0;
×
1566

1567
  // key
UNCOV
1568
  if (isJson) {
×
UNCOV
1569
    n += tGetCStr(p + n, &pTagVal->pKey);
×
1570
  } else {
UNCOV
1571
    n += tGetI16v(p + n, &pTagVal->cid);
×
1572
  }
1573

1574
  // type
UNCOV
1575
  n += tGetI8(p + n, &pTagVal->type);
×
1576

1577
  // value
UNCOV
1578
  if (IS_VAR_DATA_TYPE(pTagVal->type)) {
×
UNCOV
1579
    n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
×
1580
  } else {
UNCOV
1581
    (void)memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
×
UNCOV
1582
    n += tDataTypes[pTagVal->type].bytes;
×
1583
  }
1584

UNCOV
1585
  return n;
×
1586
}
1587

UNCOV
1588
bool tTagIsJson(const void *pTag) { return (((const STag *)pTag)->flags & TD_TAG_JSON); }
×
1589

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

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

1605
  // sort
UNCOV
1606
  if (isJson) {
×
UNCOV
1607
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
×
1608
  } else {
UNCOV
1609
    taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
×
1610
  }
1611

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

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

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

UNCOV
1658
  return code;
×
1659

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

UNCOV
1664
void tTagFree(STag *pTag) {
×
UNCOV
1665
  if (pTag) taosMemoryFree(pTag);
×
UNCOV
1666
}
×
1667

UNCOV
1668
char *tTagValToData(const STagVal *value, bool isJson) {
×
UNCOV
1669
  if (!value) {
×
1670
    return NULL;
×
1671
  }
1672

UNCOV
1673
  char  *data = NULL;
×
UNCOV
1674
  int8_t typeBytes = 0;
×
UNCOV
1675
  if (isJson) {
×
UNCOV
1676
    typeBytes = CHAR_BYTES;
×
1677
  }
1678

UNCOV
1679
  if (IS_VAR_DATA_TYPE(value->type)) {
×
UNCOV
1680
    data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
×
UNCOV
1681
    if (data == NULL) {
×
1682
      return NULL;
×
1683
    }
1684

UNCOV
1685
    if (isJson) {
×
UNCOV
1686
      *data = value->type;
×
1687
    }
1688

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

UNCOV
1695
  return data;
×
1696
}
1697

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

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

UNCOV
1713
  if (isLarge) {
×
UNCOV
1714
    p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
×
1715
  } else {
UNCOV
1716
    p = (uint8_t *)&pTag->idx[pTag->nTag];
×
1717
  }
1718

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

UNCOV
1730
    int32_t nt = tGetTagVal(p + offset, &tv, isJson);
×
UNCOV
1731
    if (isJson) {
×
UNCOV
1732
      c = tTagValJsonCmprFn(pTagVal, &tv);
×
1733
    } else {
UNCOV
1734
      c = tTagValCmprFn(pTagVal, &tv);
×
1735
    }
1736

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

UNCOV
1749
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
×
UNCOV
1750
  return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
×
1751
}
1752

UNCOV
1753
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
×
1754

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

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

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

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

UNCOV
1787
  return code;
×
1788

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

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

UNCOV
1801
  pTSchema->numOfCols = numOfCols;
×
UNCOV
1802
  pTSchema->version = version;
×
1803

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

1819
  // other columns
UNCOV
1820
  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
×
UNCOV
1821
    SSchema  *pSchema = &aSchema[iCol];
×
UNCOV
1822
    STColumn *pTColumn = &pTSchema->columns[iCol];
×
1823

UNCOV
1824
    pTColumn->colId = pSchema->colId;
×
UNCOV
1825
    pTColumn->type = pSchema->type;
×
UNCOV
1826
    pTColumn->flags = pSchema->flags;
×
UNCOV
1827
    pTColumn->offset = pTSchema->flen;
×
1828

UNCOV
1829
    if (IS_VAR_DATA_TYPE(pSchema->type)) {
×
UNCOV
1830
      pTColumn->bytes = pSchema->bytes;
×
UNCOV
1831
      pTSchema->tlen += (TYPE_BYTES[pSchema->type] + pSchema->bytes);  // todo: remove
×
1832
    } else {
UNCOV
1833
      pTColumn->bytes = TYPE_BYTES[pSchema->type];
×
UNCOV
1834
      pTSchema->tlen += TYPE_BYTES[pSchema->type];  // todo: remove
×
1835
    }
1836

UNCOV
1837
    pTSchema->flen += TYPE_BYTES[pTColumn->type];
×
1838
  }
1839

1840
#if 1  // todo : remove this
UNCOV
1841
  pTSchema->tlen += (int32_t)TD_BITMAP_BYTES(numOfCols);
×
1842
#endif
1843

UNCOV
1844
  return pTSchema;
×
1845
}
1846

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

UNCOV
1854
  return 0;
×
1855
}
1856

UNCOV
1857
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid) {
×
UNCOV
1858
  STColumn tcol = {
×
1859
      .colId = cid,
1860
  };
1861

UNCOV
1862
  return taosbsearch(&tcol, pTSchema->columns, pTSchema->numOfCols, sizeof(STColumn), tTColumnCompare, TD_EQ);
×
1863
}
1864

1865
// SColData ========================================
UNCOV
1866
void tColDataDestroy(void *ph) {
×
UNCOV
1867
  if (ph) {
×
UNCOV
1868
    SColData *pColData = (SColData *)ph;
×
1869

UNCOV
1870
    tFree(pColData->pBitMap);
×
UNCOV
1871
    tFree(pColData->aOffset);
×
UNCOV
1872
    tFree(pColData->pData);
×
1873
  }
UNCOV
1874
}
×
1875

UNCOV
1876
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag) {
×
UNCOV
1877
  pColData->cid = cid;
×
UNCOV
1878
  pColData->type = type;
×
UNCOV
1879
  pColData->cflag = cflag;
×
UNCOV
1880
  tColDataClear(pColData);
×
UNCOV
1881
}
×
1882

UNCOV
1883
void tColDataClear(SColData *pColData) {
×
UNCOV
1884
  pColData->numOfNone = 0;
×
UNCOV
1885
  pColData->numOfNull = 0;
×
UNCOV
1886
  pColData->numOfValue = 0;
×
UNCOV
1887
  pColData->nVal = 0;
×
UNCOV
1888
  pColData->flag = 0;
×
UNCOV
1889
  pColData->nData = 0;
×
UNCOV
1890
}
×
1891

UNCOV
1892
void tColDataDeepClear(SColData *pColData) {
×
UNCOV
1893
  pColData->pBitMap = NULL;
×
UNCOV
1894
  pColData->aOffset = NULL;
×
UNCOV
1895
  pColData->pData = NULL;
×
1896

UNCOV
1897
  tColDataClear(pColData);
×
UNCOV
1898
}
×
1899

1900
static FORCE_INLINE int32_t tColDataPutValue(SColData *pColData, uint8_t *pData, uint32_t nData) {
UNCOV
1901
  int32_t code = 0;
×
1902

UNCOV
1903
  if (IS_VAR_DATA_TYPE(pColData->type)) {
×
UNCOV
1904
    code = tRealloc((uint8_t **)(&pColData->aOffset), ((int64_t)(pColData->nVal + 1)) << 2);
×
UNCOV
1905
    if (code) goto _exit;
×
UNCOV
1906
    pColData->aOffset[pColData->nVal] = pColData->nData;
×
1907

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

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

UNCOV
1952
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
UNCOV
1953
  code = tRealloc(&pColData->pBitMap, nBit);
×
UNCOV
1954
  if (code) return code;
×
1955

UNCOV
1956
  memset(pColData->pBitMap, 0, nBit);
×
UNCOV
1957
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
1958

UNCOV
1959
  pColData->flag |= HAS_VALUE;
×
UNCOV
1960
  pColData->numOfValue++;
×
1961

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

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

UNCOV
1986
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
UNCOV
1987
  code = tRealloc(&pColData->pBitMap, nBit);
×
UNCOV
1988
  if (code) return code;
×
1989

UNCOV
1990
  memset(pColData->pBitMap, 0, nBit);
×
UNCOV
1991
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
1992

UNCOV
1993
  pColData->flag |= HAS_NULL;
×
UNCOV
1994
  pColData->numOfNull++;
×
UNCOV
1995
  pColData->nVal++;
×
1996

UNCOV
1997
  return code;
×
1998
}
UNCOV
1999
static FORCE_INLINE int32_t tColDataAppendValue20(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2000
  int32_t code = 0;
×
2001

UNCOV
2002
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
UNCOV
2003
  code = tRealloc(&pColData->pBitMap, nBit);
×
UNCOV
2004
  if (code) return code;
×
2005

UNCOV
2006
  memset(pColData->pBitMap, 0, nBit);
×
UNCOV
2007
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
2008

UNCOV
2009
  pColData->flag |= HAS_VALUE;
×
UNCOV
2010
  pColData->numOfValue++;
×
2011

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

UNCOV
2026
  return tColDataPutValue(pColData, pData, nData);
×
2027
}
UNCOV
2028
static FORCE_INLINE int32_t tColDataAppendValue21(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2029
  int32_t code = 0;
×
2030

UNCOV
2031
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
UNCOV
2032
  code = tRealloc(&pColData->pBitMap, nBit);
×
UNCOV
2033
  if (code) return code;
×
2034

UNCOV
2035
  memset(pColData->pBitMap, 255, nBit);
×
UNCOV
2036
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2037

UNCOV
2038
  pColData->flag |= HAS_NONE;
×
UNCOV
2039
  pColData->numOfNone++;
×
UNCOV
2040
  pColData->nVal++;
×
2041

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

2052
  pColData->flag |= HAS_VALUE;
×
2053
  pColData->numOfValue++;
×
2054

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

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

2064
  tFree(pColData->pBitMap);
×
2065
  pColData->pBitMap = pBitMap;
×
2066

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

2081
  return tColDataPutValue(pColData, pData, nData);
×
2082
}
UNCOV
2083
static FORCE_INLINE int32_t tColDataAppendValue31(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2084
  int32_t code = 0;
×
2085

UNCOV
2086
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
UNCOV
2087
  if (code) return code;
×
2088

UNCOV
2089
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
UNCOV
2090
  pColData->numOfNone++;
×
UNCOV
2091
  pColData->nVal++;
×
2092

UNCOV
2093
  return code;
×
2094
}
UNCOV
2095
static FORCE_INLINE int32_t tColDataAppendValue32(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2096
  int32_t code = 0;
×
2097

UNCOV
2098
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
UNCOV
2099
  if (code) return code;
×
2100

UNCOV
2101
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
UNCOV
2102
  pColData->numOfNull++;
×
UNCOV
2103
  pColData->nVal++;
×
2104

UNCOV
2105
  return code;
×
2106
}
UNCOV
2107
static FORCE_INLINE int32_t tColDataAppendValue40(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2108
  pColData->numOfValue++;
×
UNCOV
2109
  return tColDataPutValue(pColData, pData, nData);
×
2110
}
UNCOV
2111
static FORCE_INLINE int32_t tColDataAppendValue41(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2112
  int32_t code = 0;
×
2113

UNCOV
2114
  pColData->flag |= HAS_NONE;
×
UNCOV
2115
  pColData->numOfNone++;
×
2116

UNCOV
2117
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
UNCOV
2118
  code = tRealloc(&pColData->pBitMap, nBit);
×
UNCOV
2119
  if (code) return code;
×
2120

UNCOV
2121
  memset(pColData->pBitMap, 255, nBit);
×
UNCOV
2122
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2123

UNCOV
2124
  return tColDataPutValue(pColData, NULL, 0);
×
2125
}
UNCOV
2126
static FORCE_INLINE int32_t tColDataAppendValue42(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2127
  int32_t code = 0;
×
2128

UNCOV
2129
  pColData->flag |= HAS_NULL;
×
UNCOV
2130
  pColData->numOfNull++;
×
2131

UNCOV
2132
  int32_t nBit = BIT1_SIZE(pColData->nVal + 1);
×
UNCOV
2133
  code = tRealloc(&pColData->pBitMap, nBit);
×
UNCOV
2134
  if (code) return code;
×
2135

UNCOV
2136
  memset(pColData->pBitMap, 255, nBit);
×
UNCOV
2137
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
2138

UNCOV
2139
  return tColDataPutValue(pColData, NULL, 0);
×
2140
}
UNCOV
2141
static FORCE_INLINE int32_t tColDataAppendValue50(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2142
  int32_t code = 0;
×
2143

UNCOV
2144
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
UNCOV
2145
  if (code) return code;
×
2146

UNCOV
2147
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
UNCOV
2148
  pColData->numOfValue++;
×
2149

UNCOV
2150
  return tColDataPutValue(pColData, pData, nData);
×
2151
}
UNCOV
2152
static FORCE_INLINE int32_t tColDataAppendValue51(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2153
  int32_t code = 0;
×
2154

UNCOV
2155
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
UNCOV
2156
  if (code) return code;
×
2157

UNCOV
2158
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
UNCOV
2159
  pColData->numOfNone++;
×
2160

UNCOV
2161
  return tColDataPutValue(pColData, NULL, 0);
×
2162
}
UNCOV
2163
static FORCE_INLINE int32_t tColDataAppendValue52(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2164
  int32_t code = 0;
×
2165

UNCOV
2166
  pColData->flag |= HAS_NULL;
×
UNCOV
2167
  pColData->numOfNull++;
×
2168

UNCOV
2169
  uint8_t *pBitMap = NULL;
×
UNCOV
2170
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
UNCOV
2171
  if (code) return code;
×
2172

UNCOV
2173
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
2174
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 0);
×
2175
  }
UNCOV
2176
  SET_BIT2_EX(pBitMap, pColData->nVal, 1);
×
2177

UNCOV
2178
  tFree(pColData->pBitMap);
×
UNCOV
2179
  pColData->pBitMap = pBitMap;
×
2180

UNCOV
2181
  return tColDataPutValue(pColData, NULL, 0);
×
2182
}
UNCOV
2183
static FORCE_INLINE int32_t tColDataAppendValue60(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2184
  int32_t code = 0;
×
2185

UNCOV
2186
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
UNCOV
2187
  if (code) return code;
×
UNCOV
2188
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 1);
×
UNCOV
2189
  pColData->numOfValue++;
×
2190

UNCOV
2191
  return tColDataPutValue(pColData, pData, nData);
×
2192
}
UNCOV
2193
static FORCE_INLINE int32_t tColDataAppendValue61(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2194
  int32_t code = 0;
×
2195

UNCOV
2196
  pColData->flag |= HAS_NONE;
×
UNCOV
2197
  pColData->numOfNone++;
×
2198

UNCOV
2199
  uint8_t *pBitMap = NULL;
×
UNCOV
2200
  code = tRealloc(&pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
UNCOV
2201
  if (code) return code;
×
2202

UNCOV
2203
  for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
2204
    SET_BIT2_EX(pBitMap, iVal, GET_BIT1(pColData->pBitMap, iVal) ? 2 : 1);
×
2205
  }
UNCOV
2206
  SET_BIT2_EX(pBitMap, pColData->nVal, 0);
×
2207

UNCOV
2208
  tFree(pColData->pBitMap);
×
UNCOV
2209
  pColData->pBitMap = pBitMap;
×
2210

UNCOV
2211
  return tColDataPutValue(pColData, NULL, 0);
×
2212
}
UNCOV
2213
static FORCE_INLINE int32_t tColDataAppendValue62(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2214
  int32_t code = 0;
×
2215

UNCOV
2216
  code = tRealloc(&pColData->pBitMap, BIT1_SIZE(pColData->nVal + 1));
×
UNCOV
2217
  if (code) return code;
×
UNCOV
2218
  SET_BIT1_EX(pColData->pBitMap, pColData->nVal, 0);
×
UNCOV
2219
  pColData->numOfNull++;
×
2220

UNCOV
2221
  return tColDataPutValue(pColData, NULL, 0);
×
2222
}
2223
static FORCE_INLINE int32_t tColDataAppendValue70(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2224
  int32_t code = 0;
×
2225

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

2231
  return tColDataPutValue(pColData, pData, nData);
×
2232
}
UNCOV
2233
static FORCE_INLINE int32_t tColDataAppendValue71(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
UNCOV
2234
  int32_t code = 0;
×
2235

UNCOV
2236
  code = tRealloc(&pColData->pBitMap, BIT2_SIZE(pColData->nVal + 1));
×
UNCOV
2237
  if (code) return code;
×
UNCOV
2238
  SET_BIT2_EX(pColData->pBitMap, pColData->nVal, 0);
×
UNCOV
2239
  pColData->numOfNone++;
×
2240

UNCOV
2241
  return tColDataPutValue(pColData, NULL, 0);
×
2242
}
2243
static FORCE_INLINE int32_t tColDataAppendValue72(SColData *pColData, uint8_t *pData, uint32_t nData) {
×
2244
  int32_t code = 0;
×
2245

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

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

2263
    //       VALUE                  NONE                     NULL
2264
};
UNCOV
2265
int32_t tColDataAppendValue(SColData *pColData, SColVal *pColVal) {
×
UNCOV
2266
  if (!(pColData->cid == pColVal->cid && pColData->type == pColVal->value.type)) {
×
2267
    return TSDB_CODE_INVALID_PARA;
×
2268
  }
UNCOV
2269
  return tColDataAppendValueImpl[pColData->flag][pColVal->flag](
×
UNCOV
2270
      pColData, IS_VAR_DATA_TYPE(pColData->type) ? pColVal->value.pData : (uint8_t *)&pColVal->value.val,
×
2271
      pColVal->value.nData);
2272
}
2273

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

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

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

UNCOV
2581
  if (tColDataUpdateValueImpl[pColData->flag][pColVal->flag] == NULL) return 0;
×
2582

UNCOV
2583
  return tColDataUpdateValueImpl[pColData->flag][pColVal->flag](
×
UNCOV
2584
      pColData, IS_VAR_DATA_TYPE(pColData->type) ? pColVal->value.pData : (uint8_t *)&pColVal->value.val,
×
2585
      pColVal->value.nData, forward);
2586
}
2587

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

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

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

UNCOV
2707
  *pColData = *pColDataFrom;
×
2708

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

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

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

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

UNCOV
2759
_exit:
×
UNCOV
2760
  return code;
×
2761
}
2762

UNCOV
2763
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist) {
×
2764
  int32_t code;
2765
  SBuffer local;
2766

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

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

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

2784
  tBufferInit(&local);
UNCOV
2785
  if (assist == NULL) {
×
2786
    assist = &local;
×
2787
  }
2788

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

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

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

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

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

2817
  // offset
UNCOV
2818
  if (IS_VAR_DATA_TYPE(colData->type)) {
×
UNCOV
2819
    info->offsetOriginalSize = sizeof(int32_t) * info->numOfData;
×
2820

UNCOV
2821
    SCompressInfo cinfo = {
×
2822
        .dataType = TSDB_DATA_TYPE_INT,
UNCOV
2823
        .cmprAlg = info->cmprAlg,
×
UNCOV
2824
        .originalSize = info->offsetOriginalSize,
×
2825
    };
2826

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

UNCOV
2833
    info->offsetCompressedSize = cinfo.compressedSize;
×
2834
  }
2835

2836
  // data
UNCOV
2837
  if (colData->nData > 0) {
×
UNCOV
2838
    info->dataOriginalSize = colData->nData;
×
2839

UNCOV
2840
    SCompressInfo cinfo = {
×
UNCOV
2841
        .dataType = colData->type,
×
UNCOV
2842
        .cmprAlg = info->cmprAlg,
×
UNCOV
2843
        .originalSize = info->dataOriginalSize,
×
2844
    };
2845

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

UNCOV
2852
    info->dataCompressedSize = cinfo.compressedSize;
×
2853
  }
2854

2855
  tBufferDestroy(&local);
UNCOV
2856
  return 0;
×
2857
}
2858

UNCOV
2859
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist) {
×
2860
  int32_t  code;
2861
  SBuffer  local;
UNCOV
2862
  uint8_t *data = (uint8_t *)input;
×
2863

2864
  tBufferInit(&local);
UNCOV
2865
  if (assist == NULL) {
×
2866
    assist = &local;
×
2867
  }
2868

UNCOV
2869
  tColDataClear(colData);
×
UNCOV
2870
  colData->cid = info->columnId;
×
UNCOV
2871
  colData->type = info->dataType;
×
UNCOV
2872
  colData->cflag = info->columnFlag;
×
UNCOV
2873
  colData->nVal = info->numOfData;
×
UNCOV
2874
  colData->flag = info->flag;
×
2875

UNCOV
2876
  if (info->flag == HAS_NONE || info->flag == HAS_NULL) {
×
UNCOV
2877
    goto _exit;
×
2878
  }
2879

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

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

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

UNCOV
2901
    data += cinfo.compressedSize;
×
2902
  }
2903

UNCOV
2904
  if (info->flag == (HAS_NONE | HAS_NULL)) {
×
UNCOV
2905
    goto _exit;
×
2906
  }
2907

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

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

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

UNCOV
2929
    data += cinfo.compressedSize;
×
2930
  }
2931

2932
  // data
UNCOV
2933
  if (info->dataOriginalSize > 0) {
×
UNCOV
2934
    colData->nData = info->dataOriginalSize;
×
2935

UNCOV
2936
    SCompressInfo cinfo = {
×
UNCOV
2937
        .cmprAlg = info->cmprAlg,
×
UNCOV
2938
        .dataType = colData->type,
×
UNCOV
2939
        .originalSize = info->dataOriginalSize,
×
UNCOV
2940
        .compressedSize = info->dataCompressedSize,
×
2941
    };
2942

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

UNCOV
2949
    code = tDecompressData(data, &cinfo, colData->pData, cinfo.originalSize, assist);
×
UNCOV
2950
    if (code) {
×
2951
      tBufferDestroy(&local);
2952
      return code;
×
2953
    }
2954

UNCOV
2955
    data += cinfo.compressedSize;
×
2956
  }
2957

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

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

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

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

UNCOV
3059
_exit:
×
UNCOV
3060
  return code;
×
3061
}
3062

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

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

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

UNCOV
3111
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
×
3112
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3113
      goto _exit;
×
3114
    }
3115

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

3141
_exit:
×
UNCOV
3142
  return code;
×
3143
}
3144

UNCOV
3145
int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos,
×
3146
                                checkWKBGeometryFn cgeos) {
UNCOV
3147
  int32_t code = 0;
×
3148

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

UNCOV
3155
  if (IS_VAR_DATA_TYPE(pColData->type)) {  // var-length data type
×
UNCOV
3156
    if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
×
UNCOV
3157
      code = igeos();
×
UNCOV
3158
      if (code) {
×
3159
        return code;
×
3160
      }
3161
    }
3162

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

UNCOV
3203
    if ((pColData->cflag & COL_IS_KEY) && !allValue) {
×
UNCOV
3204
      code = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
UNCOV
3205
      goto _exit;
×
3206
    }
3207

UNCOV
3208
    if (allValue) {
×
3209
      // optimize (todo)
UNCOV
3210
      for (int32_t i = 0; i < pBind->num; ++i) {
×
UNCOV
3211
        uint8_t *val = (uint8_t *)pBind->buffer + TYPE_BYTES[pColData->type] * i;
×
UNCOV
3212
        if (TSDB_DATA_TYPE_BOOL == pColData->type && *val > 1) {
×
UNCOV
3213
          *val = 1;
×
3214
        }
3215

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

3246
          code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, val, TYPE_BYTES[pColData->type]);
×
3247
        }
3248
      }
3249
    }
3250
  }
3251

3252
_exit:
×
UNCOV
3253
  return code;
×
3254
}
3255

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

UNCOV
3271
  if (!infoSorted) {
×
3272
    taosqsort_r(infos, numOfInfos, sizeof(SBindInfo), NULL, tBindInfoCompare);
×
3273
  }
3274

UNCOV
3275
  int32_t code = 0;
×
UNCOV
3276
  int32_t numOfRows = infos[0].bind->num;
×
3277
  SArray *colValArray, *bufArray;
3278
  SColVal colVal;
3279

UNCOV
3280
  if ((colValArray = taosArrayInit(numOfInfos, sizeof(SColVal))) == NULL) {
×
3281
    return terrno;
×
3282
  }
UNCOV
3283
  if ((bufArray = taosArrayInit(numOfInfos, sizeof(uint8_t *))) == NULL) {
×
3284
    taosArrayDestroy(colValArray);
×
3285
    return terrno;
×
3286
  }
UNCOV
3287
  for (int i = 0; i < numOfInfos; ++i) {
×
UNCOV
3288
    if (!taosArrayPush(bufArray, &infos[i].bind->buffer)) {
×
3289
      taosArrayDestroy(colValArray);
×
3290
      taosArrayDestroy(bufArray);
×
3291
      return terrno;
×
3292
    }
3293
  }
3294

3295
  SRowKey rowKey, lastRowKey;
UNCOV
3296
  for (int32_t iRow = 0; iRow < numOfRows; iRow++) {
×
UNCOV
3297
    taosArrayClear(colValArray);
×
3298

UNCOV
3299
    for (int32_t iInfo = 0; iInfo < numOfInfos; iInfo++) {
×
UNCOV
3300
      if (infos[iInfo].bind->is_null && infos[iInfo].bind->is_null[iRow]) {
×
3301
        if (infos[iInfo].bind->is_null[iRow] == 1) {
×
3302
          colVal = COL_VAL_NULL(infos[iInfo].columnId, infos[iInfo].type);
×
3303
        } else {
3304
          colVal = COL_VAL_NONE(infos[iInfo].columnId, infos[iInfo].type);
×
3305
        }
3306
      } else {
UNCOV
3307
        SValue value = {
×
UNCOV
3308
            .type = infos[iInfo].type,
×
3309
        };
UNCOV
3310
        if (IS_VAR_DATA_TYPE(infos[iInfo].type)) {
×
UNCOV
3311
          int32_t   length = infos[iInfo].bind->length[iRow];
×
UNCOV
3312
          uint8_t **data = &((uint8_t **)TARRAY_DATA(bufArray))[iInfo];
×
UNCOV
3313
          value.nData = length;
×
UNCOV
3314
          if (value.nData > pTSchema->columns[iInfo].bytes - VARSTR_HEADER_SIZE) {
×
3315
            code = TSDB_CODE_INVALID_PARA;
×
3316
            goto _exit;
×
3317
          }
UNCOV
3318
          value.pData = *data;
×
UNCOV
3319
          *data += length;
×
3320
          // value.pData = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow;
3321
        } else {
UNCOV
3322
          uint8_t *val = (uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bytes * iRow;
×
UNCOV
3323
          if (TSDB_DATA_TYPE_BOOL == value.type && *val > 1) {
×
3324
            *val = 1;
×
3325
          }
UNCOV
3326
          (void)memcpy(&value.val, val,
×
3327
                       /*(uint8_t *)infos[iInfo].bind->buffer + infos[iInfo].bind->buffer_length * iRow,*/
UNCOV
3328
                       infos[iInfo].bytes /*bind->buffer_length*/);
×
3329
        }
UNCOV
3330
        colVal = COL_VAL_VALUE(infos[iInfo].columnId, value);
×
3331
      }
UNCOV
3332
      if (taosArrayPush(colValArray, &colVal) == NULL) {
×
3333
        code = terrno;
×
3334
        goto _exit;
×
3335
      }
3336
    }
3337

3338
    SRow *row;
UNCOV
3339
    if ((code = tRowBuild(colValArray, pTSchema, &row))) {
×
3340
      goto _exit;
×
3341
    }
3342

UNCOV
3343
    if ((taosArrayPush(rowArray, &row)) == NULL) {
×
3344
      code = terrno;
×
3345
      goto _exit;
×
3346
    }
3347

UNCOV
3348
    if (pOrdered && pDupTs) {
×
UNCOV
3349
      tRowGetKey(row, &rowKey);
×
UNCOV
3350
      if (iRow == 0) {
×
UNCOV
3351
        *pOrdered = true;
×
UNCOV
3352
        *pDupTs = false;
×
3353
      } else {
3354
        // no more compare if we already get disordered or duplicate rows
UNCOV
3355
        if (*pOrdered && !*pDupTs) {
×
UNCOV
3356
          int32_t code = tRowKeyCompare(&rowKey, &lastRowKey);
×
UNCOV
3357
          *pOrdered = (code >= 0);
×
UNCOV
3358
          *pDupTs = (code == 0);
×
3359
        }
3360
      }
UNCOV
3361
      lastRowKey = rowKey;
×
3362
    }
3363
  }
3364

3365
_exit:
×
3366
  taosArrayDestroy(colValArray);
×
UNCOV
3367
  taosArrayDestroy(bufArray);
×
UNCOV
3368
  return code;
×
3369
}
3370

UNCOV
3371
static int32_t tColDataCopyRowCell(SColData *pFromColData, int32_t iFromRow, SColData *pToColData, int32_t iToRow) {
×
UNCOV
3372
  int32_t code = TSDB_CODE_SUCCESS;
×
3373

UNCOV
3374
  if (IS_VAR_DATA_TYPE(pToColData->type)) {
×
UNCOV
3375
    int32_t nData = (iFromRow < pFromColData->nVal - 1)
×
UNCOV
3376
                        ? pFromColData->aOffset[iFromRow + 1] - pFromColData->aOffset[iFromRow]
×
UNCOV
3377
                        : pFromColData->nData - pFromColData->aOffset[iFromRow];
×
UNCOV
3378
    if (iToRow == 0) {
×
UNCOV
3379
      pToColData->aOffset[iToRow] = 0;
×
3380
    }
3381

UNCOV
3382
    if (iToRow < pToColData->nVal - 1) {
×
UNCOV
3383
      pToColData->aOffset[iToRow + 1] = pToColData->aOffset[iToRow] + nData;
×
3384
    }
3385

UNCOV
3386
    (void)memcpy(pToColData->pData + pToColData->aOffset[iToRow], pFromColData->pData + pFromColData->aOffset[iFromRow],
×
3387
                 nData);
3388
  } else {
UNCOV
3389
    (void)memcpy(&pToColData->pData[TYPE_BYTES[pToColData->type] * iToRow],
×
UNCOV
3390
                 &pFromColData->pData[TYPE_BYTES[pToColData->type] * iFromRow], TYPE_BYTES[pToColData->type]);
×
3391
  }
UNCOV
3392
  return code;
×
3393
}
3394

UNCOV
3395
static int32_t tColDataCopyRowSingleCol(SColData *pFromColData, int32_t iFromRow, SColData *pToColData,
×
3396
                                        int32_t iToRow) {
UNCOV
3397
  int32_t code = TSDB_CODE_SUCCESS;
×
3398

UNCOV
3399
  switch (pFromColData->flag) {
×
UNCOV
3400
    case HAS_NONE:
×
3401
    case HAS_NULL:
UNCOV
3402
      break;
×
3403
    case (HAS_NULL | HAS_NONE): {
×
3404
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
3405
    } break;
×
UNCOV
3406
    case HAS_VALUE: {
×
UNCOV
3407
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
UNCOV
3408
    } break;
×
UNCOV
3409
    case (HAS_VALUE | HAS_NONE):
×
3410
    case (HAS_VALUE | HAS_NULL): {
UNCOV
3411
      SET_BIT1(pToColData->pBitMap, iToRow, GET_BIT1(pFromColData->pBitMap, iFromRow));
×
UNCOV
3412
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
UNCOV
3413
    } break;
×
3414
    case (HAS_VALUE | HAS_NULL | HAS_NONE): {
×
3415
      SET_BIT2(pToColData->pBitMap, iToRow, GET_BIT2(pFromColData->pBitMap, iFromRow));
×
3416
      TAOS_CHECK_RETURN(tColDataCopyRowCell(pFromColData, iFromRow, pToColData, iToRow));
×
3417
    } break;
×
3418
    default:
×
3419
      return -1;
×
3420
  }
3421

UNCOV
3422
  return code;
×
3423
}
3424

UNCOV
3425
static int32_t tColDataCopyRow(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t iToRow,
×
3426
                               int32_t nColData) {
UNCOV
3427
  int32_t code = TSDB_CODE_SUCCESS;
×
3428

UNCOV
3429
  for (int32_t i = 0; i < nColData; i++) {
×
UNCOV
3430
    code = tColDataCopyRowSingleCol(&aFromColData[i], iFromRow, &aToColData[i], iToRow);
×
UNCOV
3431
    if (code != TSDB_CODE_SUCCESS) {
×
3432
      return code;
×
3433
    }
3434
  }
3435

UNCOV
3436
  return code;
×
3437
}
3438

UNCOV
3439
static int32_t tColDataCopyRowAppend(SColData *aFromColData, int32_t iFromRow, SColData *aToColData, int32_t nColData) {
×
UNCOV
3440
  int32_t code = TSDB_CODE_SUCCESS;
×
3441

UNCOV
3442
  for (int32_t i = 0; i < nColData; i++) {
×
UNCOV
3443
    SColVal cv = {0};
×
UNCOV
3444
    code = tColDataGetValue(&aFromColData[i], iFromRow, &cv);
×
UNCOV
3445
    if (code != TSDB_CODE_SUCCESS) {
×
3446
      return code;
×
3447
    }
UNCOV
3448
    code = tColDataAppendValue(&aToColData[i], &cv);
×
UNCOV
3449
    if (code != TSDB_CODE_SUCCESS) {
×
3450
      return code;
×
3451
    }
3452
  }
3453

UNCOV
3454
  return code;
×
3455
}
3456

UNCOV
3457
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key) {
×
3458
  SColVal cv;
3459

UNCOV
3460
  key->ts = ((TSKEY *)aColData[0].pData)[iRow];
×
UNCOV
3461
  key->numOfPKs = 0;
×
3462

UNCOV
3463
  for (int i = 1; i < nColData; i++) {
×
UNCOV
3464
    if (aColData[i].cflag & COL_IS_KEY) {
×
UNCOV
3465
      tColDataGetValue4(&aColData[i], iRow, &cv);
×
UNCOV
3466
      key->pks[key->numOfPKs++] = cv.value;
×
3467
    } else {
UNCOV
3468
      break;
×
3469
    }
3470
  }
UNCOV
3471
}
×
3472

UNCOV
3473
static int32_t tColDataMergeSortMerge(SColData *aColData, int32_t start, int32_t mid, int32_t end, int32_t nColData) {
×
UNCOV
3474
  SColData *aDstColData = NULL;
×
UNCOV
3475
  int32_t   i = start, j = mid + 1, k = 0;
×
3476
  SRowKey   keyi, keyj;
3477

UNCOV
3478
  if (end > start) {
×
UNCOV
3479
    aDstColData = taosMemoryCalloc(1, sizeof(SColData) * nColData);
×
UNCOV
3480
    if (aDstColData == NULL) {
×
3481
      return terrno;
×
3482
    }
UNCOV
3483
    for (int c = 0; c < nColData; ++c) {
×
UNCOV
3484
      tColDataInit(&aDstColData[c], aColData[c].cid, aColData[c].type, aColData[c].cflag);
×
3485
    }
3486
  }
3487

UNCOV
3488
  tColDataArrGetRowKey(aColData, nColData, i, &keyi);
×
UNCOV
3489
  tColDataArrGetRowKey(aColData, nColData, j, &keyj);
×
UNCOV
3490
  while (i <= mid && j <= end) {
×
UNCOV
3491
    if (tRowKeyCompare(&keyi, &keyj) <= 0) {
×
UNCOV
3492
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
×
UNCOV
3493
      tColDataArrGetRowKey(aColData, nColData, i, &keyi);
×
3494
    } else {
UNCOV
3495
      TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
×
UNCOV
3496
      tColDataArrGetRowKey(aColData, nColData, j, &keyj);
×
3497
    }
3498
  }
3499

UNCOV
3500
  while (i <= mid) {
×
UNCOV
3501
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, i++, aDstColData, nColData));
×
3502
  }
3503

UNCOV
3504
  while (j <= end) {
×
UNCOV
3505
    TAOS_CHECK_RETURN(tColDataCopyRowAppend(aColData, j++, aDstColData, nColData));
×
3506
  }
3507

UNCOV
3508
  for (i = start, k = 0; i <= end; ++i, ++k) {
×
UNCOV
3509
    TAOS_CHECK_RETURN(tColDataCopyRow(aDstColData, k, aColData, i, nColData));
×
3510
  }
3511

UNCOV
3512
  if (aDstColData) {
×
UNCOV
3513
    for (int32_t i = 0; i < nColData; i++) {
×
UNCOV
3514
      tColDataDestroy(&aDstColData[i]);
×
3515
    }
UNCOV
3516
    taosMemoryFree(aDstColData);
×
3517
  }
3518

UNCOV
3519
  return TSDB_CODE_SUCCESS;
×
3520
}
3521

UNCOV
3522
static int32_t tColDataMergeSort(SColData *aColData, int32_t start, int32_t end, int32_t nColData) {
×
UNCOV
3523
  int32_t ret = TSDB_CODE_SUCCESS;
×
3524
  int32_t mid;
3525

UNCOV
3526
  if (start >= end) {
×
UNCOV
3527
    return TSDB_CODE_SUCCESS;
×
3528
  }
3529

UNCOV
3530
  mid = (start + end) / 2;
×
3531

UNCOV
3532
  ret = tColDataMergeSort(aColData, start, mid, nColData);
×
UNCOV
3533
  if (ret != TSDB_CODE_SUCCESS) {
×
3534
    return ret;
×
3535
  }
3536

UNCOV
3537
  ret = tColDataMergeSort(aColData, mid + 1, end, nColData);
×
UNCOV
3538
  if (ret != TSDB_CODE_SUCCESS) {
×
3539
    return ret;
×
3540
  }
3541

UNCOV
3542
  return tColDataMergeSortMerge(aColData, start, mid, end, nColData);
×
3543
}
3544

UNCOV
3545
static int32_t tColDataSort(SColData *aColData, int32_t nColData) {
×
UNCOV
3546
  int32_t nVal = aColData[0].nVal;
×
3547

UNCOV
3548
  if (nVal < 2) return TSDB_CODE_SUCCESS;
×
3549

UNCOV
3550
  return tColDataMergeSort(aColData, 0, nVal - 1, nColData);
×
3551
}
3552

UNCOV
3553
static int32_t tColDataMerge(SArray **colArr) {
×
UNCOV
3554
  int32_t code = 0;
×
UNCOV
3555
  SArray *src = *colArr;
×
UNCOV
3556
  SArray *dst = NULL;
×
3557

UNCOV
3558
  dst = taosArrayInit(taosArrayGetSize(src), sizeof(SColData));
×
UNCOV
3559
  if (dst == NULL) {
×
3560
    return terrno;
×
3561
  }
3562

UNCOV
3563
  for (int32_t i = 0; i < taosArrayGetSize(src); i++) {
×
UNCOV
3564
    SColData *srcCol = taosArrayGet(src, i);
×
3565

UNCOV
3566
    SColData *dstCol = taosArrayReserve(dst, 1);
×
UNCOV
3567
    if (dstCol == NULL) {
×
3568
      code = terrno;
×
3569
      goto _exit;
×
3570
    }
UNCOV
3571
    tColDataInit(dstCol, srcCol->cid, srcCol->type, srcCol->cflag);
×
3572
  }
3573

UNCOV
3574
  int32_t numRows = ((SColData *)TARRAY_DATA(src))->nVal;
×
3575
  SRowKey lastKey;
UNCOV
3576
  for (int32_t i = 0; i < numRows; i++) {
×
3577
    SRowKey key;
UNCOV
3578
    tColDataArrGetRowKey((SColData *)TARRAY_DATA(src), taosArrayGetSize(src), i, &key);
×
3579

UNCOV
3580
    if (i == 0 || tRowKeyCompare(&key, &lastKey) != 0) {  // append new row
×
UNCOV
3581
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
×
UNCOV
3582
        SColData *srcCol = taosArrayGet(src, j);
×
UNCOV
3583
        SColData *dstCol = taosArrayGet(dst, j);
×
3584

3585
        SColVal cv;
UNCOV
3586
        code = tColDataGetValue(srcCol, i, &cv);
×
UNCOV
3587
        if (code != TSDB_CODE_SUCCESS) {
×
3588
          goto _exit;
×
3589
        }
UNCOV
3590
        code = tColDataAppendValue(dstCol, &cv);
×
UNCOV
3591
        if (code) {
×
3592
          goto _exit;
×
3593
        }
3594
      }
UNCOV
3595
      lastKey = key;
×
3596
    } else {  // update existing row
UNCOV
3597
      for (int32_t j = 0; j < taosArrayGetSize(src); j++) {
×
UNCOV
3598
        SColData *srcCol = taosArrayGet(src, j);
×
UNCOV
3599
        SColData *dstCol = taosArrayGet(dst, j);
×
3600

3601
        SColVal cv;
UNCOV
3602
        code = tColDataGetValue(srcCol, i, &cv);
×
UNCOV
3603
        if (code != TSDB_CODE_SUCCESS) {
×
3604
          goto _exit;
×
3605
        }
UNCOV
3606
        code = tColDataUpdateValue(dstCol, &cv, true);
×
UNCOV
3607
        if (code) {
×
3608
          goto _exit;
×
3609
        }
3610
      }
3611
    }
3612
  }
3613

UNCOV
3614
_exit:
×
UNCOV
3615
  if (code) {
×
3616
    taosArrayDestroyEx(dst, tColDataDestroy);
×
3617
  } else {
UNCOV
3618
    taosArrayDestroyEx(src, tColDataDestroy);
×
UNCOV
3619
    *colArr = dst;
×
3620
  }
UNCOV
3621
  return code;
×
3622
}
3623

UNCOV
3624
int32_t tColDataSortMerge(SArray **arr) {
×
UNCOV
3625
  SArray   *colDataArr = *arr;
×
UNCOV
3626
  int32_t   nColData = TARRAY_SIZE(colDataArr);
×
UNCOV
3627
  SColData *aColData = (SColData *)TARRAY_DATA(colDataArr);
×
3628

UNCOV
3629
  if (!(aColData[0].type == TSDB_DATA_TYPE_TIMESTAMP)) {
×
3630
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3631
  }
UNCOV
3632
  if (!(aColData[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID)) {
×
3633
    return TSDB_CODE_PAR_INVALID_FIRST_COLUMN;
×
3634
  }
UNCOV
3635
  if (!(aColData[0].flag == HAS_VALUE)) {
×
3636
    return TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL;
×
3637
  }
3638

UNCOV
3639
  if (aColData[0].nVal <= 1) goto _exit;
×
3640

UNCOV
3641
  int8_t doSort = 0;
×
UNCOV
3642
  int8_t doMerge = 0;
×
3643
  // scan -------
3644
  SRowKey lastKey;
UNCOV
3645
  tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
×
UNCOV
3646
  for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
×
3647
    SRowKey key;
UNCOV
3648
    tColDataArrGetRowKey(aColData, nColData, iVal, &key);
×
3649

UNCOV
3650
    int32_t c = tRowKeyCompare(&lastKey, &key);
×
UNCOV
3651
    if (c < 0) {
×
UNCOV
3652
      lastKey = key;
×
UNCOV
3653
      continue;
×
3654
    } else if (c > 0) {
×
UNCOV
3655
      doSort = 1;
×
UNCOV
3656
      break;
×
3657
    } else {
3658
      doMerge = 1;
×
3659
    }
3660
  }
3661

3662
  // sort -------
UNCOV
3663
  if (doSort) {
×
UNCOV
3664
    TAOS_CHECK_RETURN(tColDataSort(aColData, nColData));
×
3665
  }
3666

UNCOV
3667
  if (doMerge != 1) {
×
UNCOV
3668
    tColDataArrGetRowKey(aColData, nColData, 0, &lastKey);
×
UNCOV
3669
    for (int32_t iVal = 1; iVal < aColData[0].nVal; ++iVal) {
×
3670
      SRowKey key;
UNCOV
3671
      tColDataArrGetRowKey(aColData, nColData, iVal, &key);
×
3672

UNCOV
3673
      int32_t c = tRowKeyCompare(&lastKey, &key);
×
UNCOV
3674
      if (c == 0) {
×
3675
        doMerge = 1;
×
3676
        break;
×
3677
      }
UNCOV
3678
      lastKey = key;
×
3679
    }
3680
  }
3681

3682
  // merge -------
UNCOV
3683
  if (doMerge) {
×
UNCOV
3684
    int32_t code = tColDataMerge(arr);
×
UNCOV
3685
    if (code) return code;
×
3686
  }
3687

UNCOV
3688
_exit:
×
UNCOV
3689
  return 0;
×
3690
}
3691

UNCOV
3692
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
×
UNCOV
3693
  int32_t code = 0;
×
3694

UNCOV
3695
  if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
×
UNCOV
3696
  if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
×
UNCOV
3697
  if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
×
UNCOV
3698
  if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
×
3699

3700
  // bitmap
UNCOV
3701
  switch (pColData->flag) {
×
UNCOV
3702
    case (HAS_NULL | HAS_NONE):
×
3703
    case (HAS_VALUE | HAS_NONE):
3704
    case (HAS_VALUE | HAS_NULL):
UNCOV
3705
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
×
UNCOV
3706
      if (code) return code;
×
UNCOV
3707
      break;
×
3708
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3709
      code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
×
3710
      if (code) return code;
×
3711
      break;
×
UNCOV
3712
    default:
×
UNCOV
3713
      break;
×
3714
  }
3715

3716
  // value
UNCOV
3717
  if (pColData->flag & HAS_VALUE) {
×
UNCOV
3718
    if (IS_VAR_DATA_TYPE(pColData->type)) {
×
UNCOV
3719
      code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
×
UNCOV
3720
      if (code) return code;
×
3721

UNCOV
3722
      code = tEncodeI32v(pEncoder, pColData->nData);
×
UNCOV
3723
      if (code) return code;
×
3724

UNCOV
3725
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
×
UNCOV
3726
      if (code) return code;
×
3727
    } else {
UNCOV
3728
      code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
×
UNCOV
3729
      if (code) return code;
×
3730
    }
3731
  }
3732

UNCOV
3733
  return code;
×
3734
}
3735

UNCOV
3736
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
×
UNCOV
3737
  int32_t code = 0;
×
3738

UNCOV
3739
  if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
×
UNCOV
3740
  if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
×
UNCOV
3741
  if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
×
UNCOV
3742
  if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
×
3743

UNCOV
3744
  if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
×
3745
    return TSDB_CODE_INVALID_PARA;
×
3746
  }
3747

3748
  // bitmap
UNCOV
3749
  switch (pColData->flag) {
×
UNCOV
3750
    case (HAS_NULL | HAS_NONE):
×
3751
    case (HAS_VALUE | HAS_NONE):
3752
    case (HAS_VALUE | HAS_NULL):
UNCOV
3753
      code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
×
UNCOV
3754
      if (code) return code;
×
UNCOV
3755
      break;
×
3756
    case (HAS_VALUE | HAS_NULL | HAS_NONE):
×
3757
      code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
×
3758
      if (code) return code;
×
3759
      break;
×
UNCOV
3760
    default:
×
UNCOV
3761
      break;
×
3762
  }
3763

3764
  // value
UNCOV
3765
  if (pColData->flag & HAS_VALUE) {
×
UNCOV
3766
    if (IS_VAR_DATA_TYPE(pColData->type)) {
×
UNCOV
3767
      code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
×
UNCOV
3768
      if (code) return code;
×
3769

UNCOV
3770
      code = tDecodeI32v(pDecoder, &pColData->nData);
×
UNCOV
3771
      if (code) return code;
×
3772

UNCOV
3773
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
×
UNCOV
3774
      if (code) return code;
×
3775
    } else {
UNCOV
3776
      pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
×
UNCOV
3777
      code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
×
UNCOV
3778
      if (code) return code;
×
3779
    }
3780
  }
UNCOV
3781
  pColData->cflag = 0;
×
3782

UNCOV
3783
  return code;
×
3784
}
3785

UNCOV
3786
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
×
UNCOV
3787
  int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
×
UNCOV
3788
  if (code) return code;
×
UNCOV
3789
  return tEncodeI8(pEncoder, pColData->cflag);
×
3790
}
3791

UNCOV
3792
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
×
UNCOV
3793
  int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
×
UNCOV
3794
  if (code) return code;
×
3795

UNCOV
3796
  code = tDecodeI8(pDecoder, &pColData->cflag);
×
UNCOV
3797
  return code;
×
3798
}
3799

UNCOV
3800
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
×
UNCOV
3801
  if (version == 0) {
×
3802
    return tEncodeColDataVersion0(pEncoder, pColData);
×
UNCOV
3803
  } else if (version == 1) {
×
UNCOV
3804
    return tEncodeColDataVersion1(pEncoder, pColData);
×
3805
  } else {
3806
    return TSDB_CODE_INVALID_PARA;
×
3807
  }
3808
}
3809

UNCOV
3810
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
×
UNCOV
3811
  if (version == 0) {
×
3812
    return tDecodeColDataVersion0(pDecoder, pColData);
×
UNCOV
3813
  } else if (version == 1) {
×
UNCOV
3814
    return tDecodeColDataVersion1(pDecoder, pColData);
×
3815
  } else {
3816
    return TSDB_CODE_INVALID_PARA;
×
3817
  }
3818
}
3819

UNCOV
3820
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow) { return tEncodeFixed(pEncoder, pRow, pRow->len); }
×
3821

UNCOV
3822
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
×
UNCOV
3823
  if (ppRow == NULL) {
×
3824
    return TSDB_CODE_INVALID_PARA;
×
3825
  }
3826

UNCOV
3827
  if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
×
3828
    return TSDB_CODE_OUT_OF_RANGE;
×
3829
  }
3830

UNCOV
3831
  SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
×
UNCOV
3832
  return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
×
3833
}
3834

3835
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
3836
  do {                                       \
3837
    (SUM) += (VAL);                          \
3838
    if ((MAX) < (VAL)) (MAX) = (VAL);        \
3839
    if ((MIN) > (VAL)) (MIN) = (VAL);        \
3840
  } while (0)
3841

UNCOV
3842
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
3843
                                             int16_t *numOfNull) {
UNCOV
3844
  *sum = 0;
×
UNCOV
3845
  *max = 0;
×
UNCOV
3846
  *min = 1;
×
UNCOV
3847
  *numOfNull = 0;
×
3848

3849
  int8_t val;
UNCOV
3850
  if (HAS_VALUE == pColData->flag) {
×
UNCOV
3851
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
3852
      val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
×
UNCOV
3853
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3854
    }
3855
  } else {
3856
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3857
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3858
        case 0:
×
3859
        case 1:
3860
          (*numOfNull)++;
×
3861
          break;
×
3862
        case 2:
×
3863
          val = ((int8_t *)pColData->pData)[iVal] ? 1 : 0;
×
3864
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3865
          break;
×
3866
        default:
×
3867
          break;
×
3868
      }
3869
    }
3870
  }
UNCOV
3871
}
×
3872

UNCOV
3873
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
3874
                                                int16_t *numOfNull) {
UNCOV
3875
  *sum = 0;
×
UNCOV
3876
  *max = INT8_MIN;
×
UNCOV
3877
  *min = INT8_MAX;
×
UNCOV
3878
  *numOfNull = 0;
×
3879

3880
  int8_t val;
UNCOV
3881
  if (HAS_VALUE == pColData->flag) {
×
UNCOV
3882
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
3883
      val = ((int8_t *)pColData->pData)[iVal];
×
UNCOV
3884
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3885
    }
3886
  } else {
3887
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3888
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3889
        case 0:
×
3890
        case 1:
3891
          (*numOfNull)++;
×
3892
          break;
×
3893
        case 2:
×
3894
          val = ((int8_t *)pColData->pData)[iVal];
×
3895
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3896
          break;
×
3897
        default:
×
3898
          break;
×
3899
      }
3900
    }
3901
  }
UNCOV
3902
}
×
3903

UNCOV
3904
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
3905
                                                     int16_t *numOfNull) {
UNCOV
3906
  *sum = 0;
×
UNCOV
3907
  *max = INT16_MIN;
×
UNCOV
3908
  *min = INT16_MAX;
×
UNCOV
3909
  *numOfNull = 0;
×
3910

3911
  int16_t val;
UNCOV
3912
  if (HAS_VALUE == pColData->flag) {
×
UNCOV
3913
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
3914
      val = ((int16_t *)pColData->pData)[iVal];
×
UNCOV
3915
      CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3916
    }
3917
  } else {
3918
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
3919
      switch (tColDataGetBitValue(pColData, iVal)) {
×
3920
        case 0:
×
3921
        case 1:
3922
          (*numOfNull)++;
×
3923
          break;
×
3924
        case 2:
×
3925
          val = ((int16_t *)pColData->pData)[iVal];
×
3926
          CALC_SUM_MAX_MIN(*sum, *max, *min, val);
×
3927
          break;
×
3928
        default:
×
3929
          break;
×
3930
      }
3931
    }
3932
  }
UNCOV
3933
}
×
3934

UNCOV
3935
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
3936
                                            int16_t *numOfNull) {
UNCOV
3937
  *sum = 0;
×
UNCOV
3938
  *max = INT32_MIN;
×
UNCOV
3939
  *min = INT32_MAX;
×
UNCOV
3940
  *numOfNull = 0;
×
3941

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

UNCOV
3966
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
3967
                                               int16_t *numOfNull) {
UNCOV
3968
  *sum = 0;
×
UNCOV
3969
  *max = INT64_MIN;
×
UNCOV
3970
  *min = INT64_MAX;
×
UNCOV
3971
  *numOfNull = 0;
×
3972

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

UNCOV
3997
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
3998
                                              int16_t *numOfNull) {
UNCOV
3999
  *(double *)sum = 0;
×
UNCOV
4000
  *(double *)max = -FLT_MAX;
×
UNCOV
4001
  *(double *)min = FLT_MAX;
×
UNCOV
4002
  *numOfNull = 0;
×
4003

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

UNCOV
4028
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
4029
                                               int16_t *numOfNull) {
UNCOV
4030
  *(double *)sum = 0;
×
UNCOV
4031
  *(double *)max = -DBL_MAX;
×
UNCOV
4032
  *(double *)min = DBL_MAX;
×
UNCOV
4033
  *numOfNull = 0;
×
4034

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

UNCOV
4059
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
4060
                                                 int16_t *numOfNull) {
UNCOV
4061
  *(uint64_t *)sum = 0;
×
UNCOV
4062
  *(uint64_t *)max = 0;
×
UNCOV
4063
  *(uint64_t *)min = UINT8_MAX;
×
UNCOV
4064
  *numOfNull = 0;
×
4065

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

UNCOV
4090
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
4091
                                                      int16_t *numOfNull) {
UNCOV
4092
  *(uint64_t *)sum = 0;
×
UNCOV
4093
  *(uint64_t *)max = 0;
×
UNCOV
4094
  *(uint64_t *)min = UINT16_MAX;
×
UNCOV
4095
  *numOfNull = 0;
×
4096

4097
  uint16_t val;
UNCOV
4098
  if (HAS_VALUE == pColData->flag) {
×
UNCOV
4099
    for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
UNCOV
4100
      val = ((uint16_t *)pColData->pData)[iVal];
×
UNCOV
4101
      CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)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 = ((uint16_t *)pColData->pData)[iVal];
×
4112
          CALC_SUM_MAX_MIN(*(uint64_t *)sum, *(uint64_t *)max, *(uint64_t *)min, val);
×
4113
          break;
×
4114
        default:
×
4115
          break;
×
4116
      }
4117
    }
4118
  }
UNCOV
4119
}
×
4120

UNCOV
4121
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
4122
                                             int16_t *numOfNull) {
UNCOV
4123
  *(uint64_t *)sum = 0;
×
UNCOV
4124
  *(uint64_t *)max = 0;
×
UNCOV
4125
  *(uint64_t *)min = UINT32_MAX;
×
UNCOV
4126
  *numOfNull = 0;
×
4127

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

UNCOV
4152
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
4153
                                                int16_t *numOfNull) {
UNCOV
4154
  *(uint64_t *)sum = 0;
×
UNCOV
4155
  *(uint64_t *)max = 0;
×
UNCOV
4156
  *(uint64_t *)min = UINT64_MAX;
×
UNCOV
4157
  *numOfNull = 0;
×
4158

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

UNCOV
4183
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
×
4184
                                                int16_t *numOfNull) {
UNCOV
4185
  *(uint64_t *)sum = 0;
×
UNCOV
4186
  *(uint64_t *)max = 0;
×
UNCOV
4187
  *(uint64_t *)min = 0;
×
UNCOV
4188
  *numOfNull = 0;
×
4189

UNCOV
4190
  switch (pColData->flag) {
×
4191
    case HAS_NONE:
×
4192
    case HAS_NULL:
4193
    case (HAS_NONE | HAS_NULL):
4194
      *numOfNull = pColData->nVal;
×
4195
      break;
×
UNCOV
4196
    case HAS_VALUE:
×
UNCOV
4197
      *numOfNull = 0;
×
UNCOV
4198
      break;
×
4199
    case (HAS_VALUE | HAS_NULL):
×
4200
    case (HAS_VALUE | HAS_NONE):
4201
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4202
        if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
×
4203
          (*numOfNull)++;
×
4204
        }
4205
      }
4206
      break;
×
4207
    case (HAS_VALUE | HAS_NONE | HAS_NULL):
×
4208
      for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
×
4209
        if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
×
4210
          (*numOfNull)++;
×
4211
        }
4212
      }
4213
      break;
×
4214
    default:
×
4215
      break;
×
4216
  }
UNCOV
4217
}
×
4218

4219
void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull) = {
4220
    NULL,
4221
    tColDataCalcSMABool,           // TSDB_DATA_TYPE_BOOL
4222
    tColDataCalcSMATinyInt,        // TSDB_DATA_TYPE_TINYINT
4223
    tColDataCalcSMATinySmallInt,   // TSDB_DATA_TYPE_SMALLINT
4224
    tColDataCalcSMAInt,            // TSDB_DATA_TYPE_INT
4225
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_BIGINT
4226
    tColDataCalcSMAFloat,          // TSDB_DATA_TYPE_FLOAT
4227
    tColDataCalcSMADouble,         // TSDB_DATA_TYPE_DOUBLE
4228
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARCHAR
4229
    tColDataCalcSMABigInt,         // TSDB_DATA_TYPE_TIMESTAMP
4230
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_NCHAR
4231
    tColDataCalcSMAUTinyInt,       // TSDB_DATA_TYPE_UTINYINT
4232
    tColDataCalcSMATinyUSmallInt,  // TSDB_DATA_TYPE_USMALLINT
4233
    tColDataCalcSMAUInt,           // TSDB_DATA_TYPE_UINT
4234
    tColDataCalcSMAUBigInt,        // TSDB_DATA_TYPE_UBIGINT
4235
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_JSON
4236
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_VARBINARY
4237
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_DECIMAL
4238
    tColDataCalcSMAVarType,        // TSDB_DATA_TYPE_BLOB
4239
    NULL,                          // TSDB_DATA_TYPE_MEDIUMBLOB
4240
    tColDataCalcSMAVarType         // TSDB_DATA_TYPE_GEOMETRY
4241
};
4242

4243
// SValueColumn ================================
UNCOV
4244
int32_t tValueColumnInit(SValueColumn *valCol) {
×
UNCOV
4245
  valCol->type = TSDB_DATA_TYPE_NULL;
×
UNCOV
4246
  valCol->numOfValues = 0;
×
UNCOV
4247
  tBufferInit(&valCol->data);
×
UNCOV
4248
  tBufferInit(&valCol->offsets);
×
UNCOV
4249
  return 0;
×
4250
}
4251

UNCOV
4252
void tValueColumnDestroy(SValueColumn *valCol) {
×
UNCOV
4253
  valCol->type = TSDB_DATA_TYPE_NULL;
×
UNCOV
4254
  valCol->numOfValues = 0;
×
UNCOV
4255
  tBufferDestroy(&valCol->data);
×
UNCOV
4256
  tBufferDestroy(&valCol->offsets);
×
UNCOV
4257
  return;
×
4258
}
4259

UNCOV
4260
void tValueColumnClear(SValueColumn *valCol) {
×
UNCOV
4261
  valCol->type = TSDB_DATA_TYPE_NULL;
×
UNCOV
4262
  valCol->numOfValues = 0;
×
UNCOV
4263
  tBufferClear(&valCol->data);
×
UNCOV
4264
  tBufferClear(&valCol->offsets);
×
UNCOV
4265
  return;
×
4266
}
4267

UNCOV
4268
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value) {
×
4269
  int32_t code;
4270

UNCOV
4271
  if (valCol->numOfValues == 0) {
×
UNCOV
4272
    valCol->type = value->type;
×
4273
  }
4274

UNCOV
4275
  if (!(value->type == valCol->type)) {
×
4276
    return TSDB_CODE_INVALID_PARA;
×
4277
  }
4278

UNCOV
4279
  if (IS_VAR_DATA_TYPE(value->type)) {
×
UNCOV
4280
    if ((code = tBufferPutI32(&valCol->offsets, tBufferGetSize(&valCol->data)))) {
×
4281
      return code;
×
4282
    }
UNCOV
4283
    if ((code = tBufferPut(&valCol->data, value->pData, value->nData))) {
×
4284
      return code;
×
4285
    }
4286
  } else {
UNCOV
4287
    code = tBufferPut(&valCol->data, &value->val, tDataTypes[value->type].bytes);
×
UNCOV
4288
    if (code) return code;
×
4289
  }
UNCOV
4290
  valCol->numOfValues++;
×
4291

UNCOV
4292
  return 0;
×
4293
}
4294

UNCOV
4295
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value) {
×
4296
  int32_t code;
4297

UNCOV
4298
  if (idx < 0 || idx >= valCol->numOfValues) {
×
4299
    return TSDB_CODE_OUT_OF_RANGE;
×
4300
  }
4301

UNCOV
4302
  if (IS_VAR_DATA_TYPE(valCol->type)) {
×
UNCOV
4303
    int32_t *offsets = (int32_t *)tBufferGetData(&valCol->offsets);
×
UNCOV
4304
    int32_t  nextOffset = (idx == valCol->numOfValues - 1) ? tBufferGetSize(&valCol->data) : offsets[idx + 1];
×
UNCOV
4305
    int32_t  oldDataSize = nextOffset - offsets[idx];
×
UNCOV
4306
    int32_t  bytesAdded = value->nData - oldDataSize;
×
4307

UNCOV
4308
    if (bytesAdded != 0) {
×
4309
      if ((code = tBufferEnsureCapacity(&valCol->data, tBufferGetSize(&valCol->data) + bytesAdded))) return code;
×
4310
      memmove(tBufferGetDataAt(&valCol->data, nextOffset + bytesAdded), tBufferGetDataAt(&valCol->data, nextOffset),
×
4311
              tBufferGetSize(&valCol->data) - nextOffset);
×
4312
      valCol->data.size += bytesAdded;
×
4313

4314
      for (int32_t i = idx + 1; i < valCol->numOfValues; i++) {
×
4315
        offsets[i] += bytesAdded;
×
4316
      }
4317
    }
UNCOV
4318
    return tBufferPutAt(&valCol->data, offsets[idx], value->pData, value->nData);
×
4319
  } else {
UNCOV
4320
    return tBufferPutAt(&valCol->data, idx * tDataTypes[valCol->type].bytes, &value->val,
×
UNCOV
4321
                        tDataTypes[valCol->type].bytes);
×
4322
  }
4323
  return 0;
4324
}
4325

UNCOV
4326
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value) {
×
UNCOV
4327
  if (idx < 0 || idx >= valCol->numOfValues) {
×
4328
    return TSDB_CODE_OUT_OF_RANGE;
×
4329
  }
4330

UNCOV
4331
  value->type = valCol->type;
×
UNCOV
4332
  if (IS_VAR_DATA_TYPE(value->type)) {
×
4333
    int32_t       offset, nextOffset;
UNCOV
4334
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * sizeof(offset), &valCol->offsets);
×
4335

UNCOV
4336
    TAOS_CHECK_RETURN(tBufferGetI32(&reader, &offset));
×
UNCOV
4337
    if (idx == valCol->numOfValues - 1) {
×
UNCOV
4338
      nextOffset = tBufferGetSize(&valCol->data);
×
4339
    } else {
UNCOV
4340
      TAOS_CHECK_RETURN(tBufferGetI32(&reader, &nextOffset));
×
4341
    }
UNCOV
4342
    value->nData = nextOffset - offset;
×
UNCOV
4343
    value->pData = (uint8_t *)tBufferGetDataAt(&valCol->data, offset);
×
4344
  } else {
UNCOV
4345
    SBufferReader reader = BUFFER_READER_INITIALIZER(idx * tDataTypes[value->type].bytes, &valCol->data);
×
UNCOV
4346
    TAOS_CHECK_RETURN(tBufferGet(&reader, tDataTypes[value->type].bytes, &value->val));
×
4347
  }
UNCOV
4348
  return 0;
×
4349
}
4350

UNCOV
4351
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist) {
×
4352
  int32_t code;
4353

UNCOV
4354
  if (!(valCol->numOfValues > 0)) {
×
4355
    return TSDB_CODE_INVALID_PARA;
×
4356
  }
4357

UNCOV
4358
  (*info) = (SValueColumnCompressInfo){
×
UNCOV
4359
      .cmprAlg = info->cmprAlg,
×
UNCOV
4360
      .type = valCol->type,
×
4361
  };
4362

4363
  // offset
UNCOV
4364
  if (IS_VAR_DATA_TYPE(valCol->type)) {
×
UNCOV
4365
    SCompressInfo cinfo = {
×
UNCOV
4366
        .cmprAlg = info->cmprAlg,
×
4367
        .dataType = TSDB_DATA_TYPE_INT,
UNCOV
4368
        .originalSize = valCol->offsets.size,
×
4369
    };
4370

UNCOV
4371
    code = tCompressDataToBuffer(valCol->offsets.data, &cinfo, output, assist);
×
UNCOV
4372
    if (code) return code;
×
4373

UNCOV
4374
    info->offsetOriginalSize = cinfo.originalSize;
×
UNCOV
4375
    info->offsetCompressedSize = cinfo.compressedSize;
×
4376
  }
4377

4378
  // data
UNCOV
4379
  SCompressInfo cinfo = {
×
UNCOV
4380
      .cmprAlg = info->cmprAlg,
×
UNCOV
4381
      .dataType = valCol->type,
×
UNCOV
4382
      .originalSize = valCol->data.size,
×
4383
  };
4384

UNCOV
4385
  code = tCompressDataToBuffer(valCol->data.data, &cinfo, output, assist);
×
UNCOV
4386
  if (code) return code;
×
4387

UNCOV
4388
  info->dataOriginalSize = cinfo.originalSize;
×
UNCOV
4389
  info->dataCompressedSize = cinfo.compressedSize;
×
4390

UNCOV
4391
  return 0;
×
4392
}
4393

UNCOV
4394
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *info, SValueColumn *valCol,
×
4395
                               SBuffer *assist) {
4396
  int32_t code;
4397

UNCOV
4398
  tValueColumnClear(valCol);
×
UNCOV
4399
  valCol->type = info->type;
×
4400
  // offset
UNCOV
4401
  if (IS_VAR_DATA_TYPE(valCol->type)) {
×
UNCOV
4402
    valCol->numOfValues = info->offsetOriginalSize / tDataTypes[TSDB_DATA_TYPE_INT].bytes;
×
4403

UNCOV
4404
    SCompressInfo cinfo = {
×
4405
        .dataType = TSDB_DATA_TYPE_INT,
UNCOV
4406
        .cmprAlg = info->cmprAlg,
×
UNCOV
4407
        .originalSize = info->offsetOriginalSize,
×
UNCOV
4408
        .compressedSize = info->offsetCompressedSize,
×
4409
    };
4410

UNCOV
4411
    code = tDecompressDataToBuffer(input, &cinfo, &valCol->offsets, assist);
×
UNCOV
4412
    if (code) {
×
4413
      return code;
×
4414
    }
4415
  } else {
UNCOV
4416
    valCol->numOfValues = info->dataOriginalSize / tDataTypes[valCol->type].bytes;
×
4417
  }
4418

4419
  // data
UNCOV
4420
  SCompressInfo cinfo = {
×
UNCOV
4421
      .dataType = valCol->type,
×
UNCOV
4422
      .cmprAlg = info->cmprAlg,
×
UNCOV
4423
      .originalSize = info->dataOriginalSize,
×
UNCOV
4424
      .compressedSize = info->dataCompressedSize,
×
4425
  };
4426

UNCOV
4427
  code = tDecompressDataToBuffer((char *)input + info->offsetCompressedSize, &cinfo, &valCol->data, assist);
×
UNCOV
4428
  if (code) {
×
4429
    return code;
×
4430
  }
4431

UNCOV
4432
  return 0;
×
4433
}
4434

UNCOV
4435
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *info, SBuffer *buffer) {
×
4436
  int32_t code;
UNCOV
4437
  uint8_t fmtVer = 0;
×
4438

UNCOV
4439
  if ((code = tBufferPutU8(buffer, fmtVer))) return code;
×
UNCOV
4440
  if ((code = tBufferPutI8(buffer, info->cmprAlg))) return code;
×
UNCOV
4441
  if ((code = tBufferPutI8(buffer, info->type))) return code;
×
UNCOV
4442
  if (IS_VAR_DATA_TYPE(info->type)) {
×
UNCOV
4443
    if ((code = tBufferPutI32v(buffer, info->offsetOriginalSize))) return code;
×
UNCOV
4444
    if ((code = tBufferPutI32v(buffer, info->offsetCompressedSize))) return code;
×
4445
  }
UNCOV
4446
  if ((code = tBufferPutI32v(buffer, info->dataOriginalSize))) return code;
×
UNCOV
4447
  if ((code = tBufferPutI32v(buffer, info->dataCompressedSize))) return code;
×
4448

UNCOV
4449
  return 0;
×
4450
}
4451

UNCOV
4452
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *info) {
×
4453
  int32_t code;
4454
  uint8_t fmtVer;
4455

UNCOV
4456
  if ((code = tBufferGetU8(reader, &fmtVer))) return code;
×
UNCOV
4457
  if (fmtVer == 0) {
×
UNCOV
4458
    if ((code = tBufferGetI8(reader, &info->cmprAlg))) return code;
×
UNCOV
4459
    if ((code = tBufferGetI8(reader, &info->type))) return code;
×
UNCOV
4460
    if (IS_VAR_DATA_TYPE(info->type)) {
×
UNCOV
4461
      if ((code = tBufferGetI32v(reader, &info->offsetOriginalSize))) return code;
×
UNCOV
4462
      if ((code = tBufferGetI32v(reader, &info->offsetCompressedSize))) return code;
×
4463
    } else {
UNCOV
4464
      info->offsetOriginalSize = 0;
×
UNCOV
4465
      info->offsetCompressedSize = 0;
×
4466
    }
UNCOV
4467
    if ((code = tBufferGetI32v(reader, &info->dataOriginalSize))) return code;
×
UNCOV
4468
    if ((code = tBufferGetI32v(reader, &info->dataCompressedSize))) return code;
×
4469
  } else {
4470
    return TSDB_CODE_INVALID_PARA;
×
4471
  }
4472

UNCOV
4473
  return 0;
×
4474
}
4475

UNCOV
4476
int32_t tCompressData(void          *input,       // input
×
4477
                      SCompressInfo *info,        // compress info
4478
                      void          *output,      // output
4479
                      int32_t        outputSize,  // output size
4480
                      SBuffer       *buffer       // assistant buffer provided by caller, can be NULL
4481
) {
4482
  int32_t extraSizeNeeded;
4483
  int32_t code;
4484

UNCOV
4485
  extraSizeNeeded = (info->cmprAlg == NO_COMPRESSION) ? info->originalSize : info->originalSize + COMP_OVERFLOW_BYTES;
×
UNCOV
4486
  if (!(outputSize >= extraSizeNeeded)) {
×
4487
    return TSDB_CODE_INVALID_PARA;
×
4488
  }
4489

UNCOV
4490
  if (info->cmprAlg == NO_COMPRESSION) {
×
4491
    (void)memcpy(output, input, info->originalSize);
×
4492
    info->compressedSize = info->originalSize;
×
UNCOV
4493
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
×
4494
    SBuffer local;
4495

4496
    tBufferInit(&local);
UNCOV
4497
    if (buffer == NULL) {
×
4498
      buffer = &local;
×
4499
    }
4500

UNCOV
4501
    if (info->cmprAlg == TWO_STAGE_COMP) {
×
UNCOV
4502
      code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
×
UNCOV
4503
      if (code) {
×
4504
        tBufferDestroy(&local);
4505
        return code;
×
4506
      }
4507
    }
4508

UNCOV
4509
    info->compressedSize = tDataTypes[info->dataType].compFunc(  //
×
4510
        input,                                                   // input
4511
        info->originalSize,                                      // input size
UNCOV
4512
        info->originalSize / tDataTypes[info->dataType].bytes,   // number of elements
×
4513
        output,                                                  // output
4514
        outputSize,                                              // output size
UNCOV
4515
        info->cmprAlg,                                           // compression algorithm
×
4516
        buffer->data,                                            // buffer
UNCOV
4517
        buffer->capacity                                         // buffer size
×
4518
    );
UNCOV
4519
    if (info->compressedSize < 0) {
×
4520
      tBufferDestroy(&local);
4521
      return TSDB_CODE_COMPRESS_ERROR;
×
4522
    }
4523

4524
    tBufferDestroy(&local);
4525
  } else {
UNCOV
4526
    DEFINE_VAR(info->cmprAlg)
×
UNCOV
4527
    if ((l1 == L1_UNKNOWN && l2 == L2_UNKNOWN) || (l1 == L1_DISABLED && l2 == L2_DISABLED)) {
×
4528
      (void)memcpy(output, input, info->originalSize);
×
4529
      info->compressedSize = info->originalSize;
×
4530
      return 0;
×
4531
    }
4532
    SBuffer local;
4533

4534
    tBufferInit(&local);
UNCOV
4535
    if (buffer == NULL) {
×
4536
      buffer = &local;
×
4537
    }
UNCOV
4538
    code = tBufferEnsureCapacity(buffer, extraSizeNeeded);
×
4539

UNCOV
4540
    info->compressedSize = tDataCompress[info->dataType].compFunc(  //
×
4541
        input,                                                      // input
4542
        info->originalSize,                                         // input size
UNCOV
4543
        info->originalSize / tDataTypes[info->dataType].bytes,      // number of elements
×
4544
        output,                                                     // output
4545
        outputSize,                                                 // output size
4546
        info->cmprAlg,                                              // compression algorithm
4547
        buffer->data,                                               // buffer
UNCOV
4548
        buffer->capacity                                            // buffer size
×
4549
    );
UNCOV
4550
    if (info->compressedSize < 0) {
×
4551
      tBufferDestroy(&local);
4552
      return TSDB_CODE_COMPRESS_ERROR;
×
4553
    }
4554

4555
    tBufferDestroy(&local);
4556
    // new col compress
4557
  }
4558

UNCOV
4559
  return 0;
×
4560
}
4561

UNCOV
4562
int32_t tDecompressData(void                *input,       // input
×
4563
                        const SCompressInfo *info,        // compress info
4564
                        void                *output,      // output
4565
                        int32_t              outputSize,  // output size
4566
                        SBuffer             *buffer       // assistant buffer provided by caller, can be NULL
4567
) {
4568
  int32_t code;
4569

UNCOV
4570
  if (!(outputSize >= info->originalSize)) {
×
4571
    return TSDB_CODE_INVALID_PARA;
×
4572
  }
4573

UNCOV
4574
  if (info->cmprAlg == NO_COMPRESSION) {
×
4575
    if (!(info->compressedSize == info->originalSize)) {
×
4576
      return TSDB_CODE_INVALID_PARA;
×
4577
    }
4578
    (void)memcpy(output, input, info->compressedSize);
×
UNCOV
4579
  } else if (info->cmprAlg == ONE_STAGE_COMP || info->cmprAlg == TWO_STAGE_COMP) {
×
4580
    SBuffer local;
4581

4582
    tBufferInit(&local);
UNCOV
4583
    if (buffer == NULL) {
×
4584
      buffer = &local;
×
4585
    }
4586

UNCOV
4587
    if (info->cmprAlg == TWO_STAGE_COMP) {
×
UNCOV
4588
      code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
×
UNCOV
4589
      if (code) {
×
4590
        tBufferDestroy(&local);
4591
        return code;
×
4592
      }
4593
    }
4594

UNCOV
4595
    int32_t decompressedSize = tDataTypes[info->dataType].decompFunc(
×
4596
        input,                                                  // input
UNCOV
4597
        info->compressedSize,                                   // inputSize
×
UNCOV
4598
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
×
4599
        output,                                                 // output
4600
        outputSize,                                             // output size
UNCOV
4601
        info->cmprAlg,                                          // compression algorithm
×
4602
        buffer->data,                                           // helper buffer
UNCOV
4603
        buffer->capacity                                        // extra buffer size
×
4604
    );
UNCOV
4605
    if (decompressedSize < 0) {
×
4606
      tBufferDestroy(&local);
4607
      return TSDB_CODE_COMPRESS_ERROR;
×
4608
    }
4609

UNCOV
4610
    if (!(decompressedSize == info->originalSize)) {
×
4611
      return TSDB_CODE_COMPRESS_ERROR;
×
4612
    }
4613
    tBufferDestroy(&local);
4614
  } else {
UNCOV
4615
    DEFINE_VAR(info->cmprAlg);
×
UNCOV
4616
    if (l1 == L1_DISABLED && l2 == L2_DISABLED) {
×
4617
      (void)memcpy(output, input, info->compressedSize);
×
4618
      return 0;
×
4619
    }
4620
    SBuffer local;
4621

4622
    tBufferInit(&local);
UNCOV
4623
    if (buffer == NULL) {
×
4624
      buffer = &local;
×
4625
    }
UNCOV
4626
    code = tBufferEnsureCapacity(buffer, info->originalSize + COMP_OVERFLOW_BYTES);
×
UNCOV
4627
    if (code) {
×
4628
      return code;
×
4629
    }
4630

UNCOV
4631
    int32_t decompressedSize = tDataCompress[info->dataType].decompFunc(
×
4632
        input,                                                  // input
UNCOV
4633
        info->compressedSize,                                   // inputSize
×
UNCOV
4634
        info->originalSize / tDataTypes[info->dataType].bytes,  // number of elements
×
4635
        output,                                                 // output
4636
        outputSize,                                             // output size
UNCOV
4637
        info->cmprAlg,                                          // compression algorithm
×
4638
        buffer->data,                                           // helper buffer
UNCOV
4639
        buffer->capacity                                        // extra buffer size
×
4640
    );
UNCOV
4641
    if (decompressedSize < 0) {
×
4642
      tBufferDestroy(&local);
4643
      return TSDB_CODE_COMPRESS_ERROR;
×
4644
    }
4645

UNCOV
4646
    if (!(decompressedSize == info->originalSize)) {
×
4647
      return TSDB_CODE_COMPRESS_ERROR;
×
4648
    }
4649
    tBufferDestroy(&local);
4650
  }
4651

UNCOV
4652
  return 0;
×
4653
}
4654

UNCOV
4655
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
×
4656
  int32_t code;
4657

UNCOV
4658
  code = tBufferEnsureCapacity(output, output->size + info->originalSize + COMP_OVERFLOW_BYTES);
×
UNCOV
4659
  if (code) return code;
×
4660

UNCOV
4661
  code = tCompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
×
UNCOV
4662
  if (code) return code;
×
4663

UNCOV
4664
  output->size += info->compressedSize;
×
UNCOV
4665
  return 0;
×
4666
}
4667

UNCOV
4668
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist) {
×
4669
  int32_t code;
4670

UNCOV
4671
  code = tBufferEnsureCapacity(output, output->size + info->originalSize);
×
UNCOV
4672
  if (code) return code;
×
4673

UNCOV
4674
  code = tDecompressData(input, info, tBufferGetDataEnd(output), output->capacity - output->size, assist);
×
UNCOV
4675
  if (code) return code;
×
4676

UNCOV
4677
  output->size += info->originalSize;
×
UNCOV
4678
  return 0;
×
4679
}
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