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

taosdata / TDengine / #5011

03 Apr 2026 03:59PM UTC coverage: 72.3% (+0.008%) from 72.292%
#5011

push

travis-ci

web-flow
merge: from main to 3.0 branch #35067

4053 of 5985 new or added lines in 68 files covered. (67.72%)

732 existing lines in 143 files now uncovered.

257430 of 356056 relevant lines covered (72.3%)

131834103.52 hits per line

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

72.74
/source/common/src/tdatablock.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 "tdatablock.h"
18
#include "tcompare.h"
19
#include "tglobal.h"
20
#include "tlog.h"
21
#include "tname.h"
22

23
#define MALLOC_ALIGN_BYTES 32
24

25
int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRows) {
2,147,483,647✔
26
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
27
    if (pColumnInfoData->reassigned) {
1,270,802,807✔
28
      int32_t totalSize = 0;
46,110✔
29
      for (int32_t row = 0; row < numOfRows; ++row) {
634,410✔
30
        char*   pColData = pColumnInfoData->pData + pColumnInfoData->varmeta.offset[row];
588,300✔
31
        int32_t colSize = calcStrBytesByType(pColumnInfoData->info.type, pColData);
588,300✔
32
        totalSize += colSize;
588,300✔
33
      }
34
      return totalSize;
46,110✔
35
    }
36
    return pColumnInfoData->varmeta.length;
1,272,638,651✔
37
  } else {
38
    if (pColumnInfoData->info.type == TSDB_DATA_TYPE_NULL) {
2,147,483,647✔
39
      return 0;
450,483✔
40
    } else {
41
      return pColumnInfoData->info.bytes * numOfRows;
2,147,483,647✔
42
    }
43
  }
44
}
45

46
int32_t colDataGetRowLength(const SColumnInfoData* pColumnInfoData, int32_t rowIdx) {
2,147,483,647✔
47
  if (colDataIsNull_s(pColumnInfoData, rowIdx)) {
2,147,483,647✔
48
    return 0;
×
49
  }
50

51
  if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
52
    return pColumnInfoData->info.bytes;
2,147,483,647✔
53
  } else {
54
    return calcStrBytesByType(pColumnInfoData->info.type, colDataGetData(pColumnInfoData, rowIdx));
1,755,996,338✔
55
  }
56
  // if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON) {
57
  //   return getJsonValueLen(colDataGetData(pColumnInfoData, rowIdx));
58
  // } else if (IS_STR_DATA_BLOB(pColumnInfoData->info.type)) {
59
  //   return blobDataTLen(colDataGetData(pColumnInfoData, rowIdx));
60
  // } else {
61
  //   return varDataTLen(colDataGetData(pColumnInfoData, rowIdx));
62
  // }
63
}
64

65
int32_t colDataGetFullLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRows) {
2,147,483,647✔
66
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
67
    return pColumnInfoData->varmeta.length + sizeof(int32_t) * numOfRows;
1,846,163,624✔
68
  } else {
69
    return ((pColumnInfoData->info.type == TSDB_DATA_TYPE_NULL) ? 0 : pColumnInfoData->info.bytes * numOfRows) +
2,147,483,647✔
70
           BitmapLen(numOfRows);
2,147,483,647✔
71
  }
72
}
73

74
int32_t getJsonValueLen(const char* data) {
8,433,830✔
75
  int32_t dataLen = 0;
8,433,830✔
76
  if (*data == TSDB_DATA_TYPE_NULL) {
8,433,830✔
77
    dataLen = CHAR_BYTES;
188,568✔
78
  } else if (*data == TSDB_DATA_TYPE_NCHAR) {
8,245,667✔
79
    dataLen = varDataTLen(data + CHAR_BYTES) + CHAR_BYTES;
3,513,798✔
80
  } else if (*data == TSDB_DATA_TYPE_DOUBLE) {
4,731,869✔
81
    dataLen = DOUBLE_BYTES + CHAR_BYTES;
449,611✔
82
  } else if (*data == TSDB_DATA_TYPE_BOOL) {
4,281,031✔
83
    dataLen = CHAR_BYTES + CHAR_BYTES;
124,880✔
84
  } else if (tTagIsJson(data)) {  // json string
4,156,556✔
85
    dataLen = ((STag*)(data))->len;
4,155,746✔
86
  } else {
87
    uError("Invalid data type:%d in Json", *data);
405✔
88
  }
89
  return dataLen;
8,434,235✔
90
}
91

92
static int32_t getDataLen(int32_t type, const char* pData) {
2,147,483,647✔
93
  int32_t dataLen = 0;
2,147,483,647✔
94
  if (type == TSDB_DATA_TYPE_JSON) {
2,147,483,647✔
95
    dataLen = getJsonValueLen(pData);
7,858,194✔
96
  } else if (IS_STR_DATA_BLOB(type)) {
2,147,483,647✔
97
    dataLen = blobDataTLen(pData);
1,861✔
98
  } else {
99
    dataLen = varDataTLen(pData);
2,147,483,647✔
100
  }
101
  return dataLen;
2,147,483,647✔
102
}
103

104
int32_t calcStrBytesByType(int8_t type, char* data) { return getDataLen(type, data); }
2,147,483,647✔
105

106
int32_t blockDataGetPagedColumnReservedBytes(const SColumnInfoData* pColumnInfoData) {
2,147,483,647✔
107
  return pColumnInfoData->info.bytes;
2,147,483,647✔
108
}
109

110
static int32_t checkAllocLen(SColumnInfoData* pColumnInfoData, char** pData, int32_t dataLen){
2,147,483,647✔
111
  SVarColAttr* pAttr = &pColumnInfoData->varmeta;
2,147,483,647✔
112
  char* buf = NULL;
2,147,483,647✔
113
  if (pAttr->allocLen < pAttr->length + dataLen) {
2,147,483,647✔
114
    uint32_t newSize = pAttr->allocLen;
2,147,483,647✔
115
    if (newSize <= 1) {
2,147,483,647✔
116
      newSize = 8;
1,291,851,319✔
117
    }
118

119
    while (newSize < pAttr->length + dataLen) {
2,147,483,647✔
120
      newSize = newSize * 1.5;
2,147,483,647✔
121
      if (newSize > UINT32_MAX) {
122
        return TSDB_CODE_OUT_OF_MEMORY;
123
      }
124
    }
125

126
    buf = taosMemoryRealloc(*pData, newSize);
2,147,483,647✔
127
    if (buf == NULL) {
2,147,483,647✔
128
      return terrno;
×
129
    }
130

131
    *pData = buf;
2,147,483,647✔
132
    pAttr->allocLen = newSize;
2,147,483,647✔
133
  }
134
  return 0;
2,147,483,647✔
135
}
136

137
static int32_t colDataSetValHelp(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull) {
2,147,483,647✔
138
  if (isNull || pData == NULL) {
2,147,483,647✔
139
    // There is a placehold for each NULL value of binary or nchar type.
140
    if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
141
      pColumnInfoData->varmeta.offset[rowIndex] = -1;  // it is a null value of VAR type.
774,315,365✔
142
    } else {
143
      colDataSetNull_f_s(pColumnInfoData, rowIndex);
2,147,483,647✔
144
    }
145

146
    pColumnInfoData->hasNull = true;
2,147,483,647✔
147
    return 0;
2,147,483,647✔
148
  }
149

150
  int32_t type = pColumnInfoData->info.type;
2,147,483,647✔
151
  if (IS_VAR_DATA_TYPE(type)) {
2,147,483,647✔
152
    int32_t dataLen = getDataLen(type, pData);
2,147,483,647✔
153
    if (pColumnInfoData->varmeta.offset[rowIndex] > 0) {
2,147,483,647✔
154
      pColumnInfoData->varmeta.length = pColumnInfoData->varmeta.offset[rowIndex];
23,136✔
155
    }
156

157
    bool overlap = false;
2,147,483,647✔
158
    uint64_t offset = 0;
2,147,483,647✔
159
    if ((uint64_t)pData >= (uint64_t)pColumnInfoData->pData && ((uint64_t)pData + dataLen) <= ((uint64_t)pColumnInfoData->pData + pColumnInfoData->varmeta.allocLen)) {
2,147,483,647✔
160
      overlap = true;
101,800,000✔
161
      offset = (uint64_t)pData - (uint64_t)pColumnInfoData->pData;
101,800,000✔
162
    }
163

164
    int32_t code = checkAllocLen(pColumnInfoData, &pColumnInfoData->pData, dataLen);
2,147,483,647✔
165
    if (code != TSDB_CODE_SUCCESS) {
2,147,483,647✔
166
      return code;
×
167
    }
168

169
    uint32_t len = pColumnInfoData->varmeta.length;
2,147,483,647✔
170
    pColumnInfoData->varmeta.offset[rowIndex] = len;
2,147,483,647✔
171

172
    (void)memmove(pColumnInfoData->pData + len, overlap ? (pColumnInfoData->pData + offset) : pData, dataLen);
2,147,483,647✔
173
    pColumnInfoData->varmeta.length += dataLen;
2,147,483,647✔
174
  } else {
175
    memcpy(pColumnInfoData->pData + pColumnInfoData->info.bytes * rowIndex, pData, pColumnInfoData->info.bytes);
2,147,483,647✔
176
    colDataClearNull_f(pColumnInfoData->nullbitmap, rowIndex);
2,147,483,647✔
177
  }
178

179
  return 0;
2,147,483,647✔
180
}
181

182
int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull) {
2,147,483,647✔
183
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
184
    pColumnInfoData->varmeta.offset[rowIndex] = -1;
2,147,483,647✔
185
  }
186

187
  return colDataSetValHelp(pColumnInfoData, rowIndex, pData, isNull);
2,147,483,647✔
188
}
189

190
int32_t colDataSetValOrCover(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull) {
2,147,483,647✔
191
  return colDataSetValHelp(pColumnInfoData, rowIndex, pData, isNull);
2,147,483,647✔
192
}
193

194
int32_t varColSetVarData(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pVarData, int32_t varDataLen,
1,500,652✔
195
                         bool isNull) {
196
  if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
1,500,652✔
197
    return TSDB_CODE_INVALID_PARA;
×
198
  }
199

200
  if (isNull || pVarData == NULL) {
1,500,652✔
UNCOV
201
    pColumnInfoData->varmeta.offset[rowIndex] = -1;  // it is a null value of VAR type.
×
202
    pColumnInfoData->hasNull = true;
×
203
    return TSDB_CODE_SUCCESS;
×
204
  }
205

206
  int32_t headerSize = IS_STR_DATA_BLOB(pColumnInfoData->info.type) ?
1,500,652✔
207
                         BLOBSTR_HEADER_SIZE : VARSTR_HEADER_SIZE;
208
  int32_t dataLen = headerSize + varDataLen;
1,500,652✔
209
  if (pColumnInfoData->varmeta.offset[rowIndex] > 0) {
1,500,652✔
210
    pColumnInfoData->varmeta.length = pColumnInfoData->varmeta.offset[rowIndex];
×
211
  }
212

213
  int32_t code = checkAllocLen(pColumnInfoData, &pColumnInfoData->pData, dataLen);
1,500,652✔
214
  if (code != TSDB_CODE_SUCCESS) {
1,500,652✔
215
    return code;
×
216
  }
217

218
  uint32_t len = pColumnInfoData->varmeta.length;
1,500,652✔
219
  pColumnInfoData->varmeta.offset[rowIndex] = len;
1,500,652✔
220

221
  if (IS_STR_DATA_BLOB(pColumnInfoData->info.type)) {
1,500,404✔
222
    (void)memmove(blobDataVal(pColumnInfoData->pData + len), pVarData, varDataLen);
2,608✔
223
    blobDataSetLen(pColumnInfoData->pData + len, varDataLen);
2,360✔
224

225
  } else {
226
    (void)memmove(varDataVal(pColumnInfoData->pData + len), pVarData, varDataLen);
1,498,044✔
227
    varDataSetLen(pColumnInfoData->pData + len, varDataLen);
1,498,292✔
228
  }
229
  pColumnInfoData->varmeta.length += dataLen;
1,500,652✔
230
  return TSDB_CODE_SUCCESS;
1,500,652✔
231
}
232

233
int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx,
×
234
                           const char* pData) {
235
  int32_t type = pColumnInfoData->info.type;
×
236
  if (IS_VAR_DATA_TYPE(type)) {
×
237
    pColumnInfoData->varmeta.offset[dstRowIdx] = pColumnInfoData->varmeta.offset[srcRowIdx];
×
238
    pColumnInfoData->reassigned = true;
×
239
  } else {
240
    memcpy(pColumnInfoData->pData + pColumnInfoData->info.bytes * dstRowIdx, pData, pColumnInfoData->info.bytes);
×
241
    colDataClearNull_f(pColumnInfoData->nullbitmap, dstRowIdx);
×
242
  }
243

244
  return 0;
×
245
}
246

247
static int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) {
503,951,327✔
248
  if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
503,951,327✔
249
    return TSDB_CODE_SUCCESS;
×
250
  }
251

252
  if (pColumnInfoData->varmeta.allocLen >= newSize) {
503,964,896✔
253
    return TSDB_CODE_SUCCESS;
×
254
  }
255

256
  uint32_t sizeTmp = pColumnInfoData->varmeta.allocLen;
503,960,700✔
257
  if (sizeTmp <= 1) {
503,956,219✔
258
    sizeTmp = 8;
44,064,896✔
259
  }
260
  while (sizeTmp < newSize) {
1,402,228,863✔
261
    sizeTmp = sizeTmp * 1.5;
898,272,644✔
262
    if (sizeTmp > UINT32_MAX) {
263
      return TSDB_CODE_OUT_OF_MEMORY;
264
    }
265
  }
266
  if (pColumnInfoData->varmeta.allocLen < newSize) {
503,956,219✔
267
    char* buf = taosMemoryRealloc(pColumnInfoData->pData, newSize);
503,954,669✔
268
    if (buf == NULL) {
503,941,632✔
269
      return terrno;
×
270
    }
271

272
    pColumnInfoData->pData = buf;
503,941,632✔
273
    pColumnInfoData->varmeta.allocLen = newSize;
503,945,734✔
274
  }
275

276
  return TSDB_CODE_SUCCESS;
503,945,078✔
277
}
278

279
int32_t doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t currentRow, const char* pData,
2,147,483,647✔
280
                            int32_t itemLen, int32_t numOfRows, bool trimValue) {
281
  if (pColumnInfoData->info.bytes < itemLen) {
2,147,483,647✔
282
    uWarn("column/tag actual data len %d is bigger than schema len %d, trim it:%d", itemLen,
×
283
          pColumnInfoData->info.bytes, trimValue);
284
    if (trimValue) {
×
285
      itemLen = pColumnInfoData->info.bytes;
×
286
    } else {
287
      return TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER;
×
288
    }
289
  }
290

291
  size_t   start = 1;
2,147,483,647✔
292
  int32_t  t = 0;
2,147,483,647✔
293
  int32_t  count = log(numOfRows) / log(2);
2,147,483,647✔
294
  uint32_t startOffset =
2,147,483,647✔
295
      (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) ? pColumnInfoData->varmeta.length : (currentRow * itemLen);
2,147,483,647✔
296

297
  // the first item
298
  memcpy(pColumnInfoData->pData + startOffset, pData, itemLen);
2,147,483,647✔
299

300
  while (t < count) {
2,147,483,647✔
301
    int32_t xlen = 1 << t;
2,147,483,647✔
302
    memcpy(pColumnInfoData->pData + start * itemLen + startOffset, pColumnInfoData->pData + startOffset,
2,147,483,647✔
303
           xlen * itemLen);
2,147,483,647✔
304
    t += 1;
2,147,483,647✔
305
    start += xlen;
2,147,483,647✔
306
  }
307

308
  // the tail part
309
  if (numOfRows > start) {
2,147,483,647✔
310
    memcpy(pColumnInfoData->pData + start * itemLen + startOffset, pColumnInfoData->pData + startOffset,
953,650,676✔
311
           (numOfRows - start) * itemLen);
953,588,160✔
312
  }
313

314
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
315
    for (int32_t i = 0; i < numOfRows; ++i) {
2,147,483,647✔
316
      pColumnInfoData->varmeta.offset[i + currentRow] = pColumnInfoData->varmeta.length + i * itemLen;
2,147,483,647✔
317
    }
318

319
    pColumnInfoData->varmeta.length += numOfRows * itemLen;
2,147,483,647✔
320
  }
321

322
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
323
}
324

325
int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows, uint32_t capacity,
2,147,483,647✔
326
                         bool trimValue) {
327
  int32_t len = pColumnInfoData->info.bytes;
2,147,483,647✔
328
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
329
    len = calcStrBytesByType(pColumnInfoData->info.type, (char*)pData);
2,147,483,647✔
330
    // if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON) {
331
    //   len = getJsonValueLen(pData);
332
    // } else if (IS_STR_DATA_BLOB(pColumnInfoData->info.type)) {
333
    //   len = blobDataTLen(pData);
334
    // } else {
335
    //   len = varDataTLen(pData);
336
    // }
337
    if (pColumnInfoData->varmeta.allocLen < (capacity * numOfRows * len + pColumnInfoData->varmeta.length)) {
2,147,483,647✔
338
      int32_t code = colDataReserve(pColumnInfoData, (capacity * numOfRows * len + pColumnInfoData->varmeta.length));
503,948,879✔
339
      if (code != TSDB_CODE_SUCCESS) {
503,942,294✔
340
        return code;
×
341
      }
342
    }
343
  }
344

345
  return doCopyNItems(pColumnInfoData, currentRow, pData, len, numOfRows, trimValue);
2,147,483,647✔
346
}
347

348
void colDataSetNItemsNull(SColumnInfoData* pColumnInfoData, uint32_t currentRow, uint32_t numOfRows) {
320,966,213✔
349
  pColumnInfoData->hasNull = true;
320,966,213✔
350

351
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
320,966,213✔
352
    memset(&pColumnInfoData->varmeta.offset[currentRow], -1, sizeof(int32_t) * numOfRows);
51,957,860✔
353
  } else {
354
    if (numOfRows < 16) {
269,008,353✔
355
      for (int32_t i = 0; i < numOfRows; ++i) {
125,153,634✔
356
        colDataSetNull_f(pColumnInfoData->nullbitmap, currentRow + i);
63,901,562✔
357
      }
358
    } else {
359
      int32_t i = 0;
207,756,281✔
360
      for (; i < numOfRows; ++i) {
207,756,281✔
361
        if (BitPos(currentRow + i)) {
207,756,281✔
362
          colDataSetNull_f(pColumnInfoData->nullbitmap, currentRow + i);
×
363
        } else {
364
          break;
207,756,281✔
365
        }
366
      }
367

368
      int32_t bytes = (numOfRows - i) / 8;
207,756,281✔
369
      memset(&BMCharPos(pColumnInfoData->nullbitmap, currentRow + i), 0xFF, bytes);
207,756,281✔
370
      i += bytes * 8;
207,756,281✔
371

372
      for (; i < numOfRows; ++i) {
207,756,281✔
373
        colDataSetNull_f(pColumnInfoData->nullbitmap, currentRow + i);
×
374
      }
375
    }
376
  }
377
}
320,966,213✔
378

379
int32_t colDataCopyAndReassign(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData,
1,313,383✔
380
                               uint32_t numOfRows) {
381
  int32_t code = colDataSetVal(pColumnInfoData, currentRow, pData, false);
1,313,383✔
382
  if (code) {
1,313,383✔
383
    return code;
×
384
  }
385

386
  if (numOfRows > 1) {
1,313,383✔
387
    int32_t* pOffset = pColumnInfoData->varmeta.offset;
755,912✔
388
    memset(&pOffset[currentRow + 1], pOffset[currentRow], sizeof(pOffset[0]) * (numOfRows - 1));
755,912✔
389
    pColumnInfoData->reassigned = true;
755,912✔
390
  }
391

392
  return code;
1,313,383✔
393
}
394

395
int32_t colDataCopyNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows,
1,987,232✔
396
                          bool isNull) {
397
  int32_t len = pColumnInfoData->info.bytes;
1,987,232✔
398
  if (isNull) {
1,987,232✔
399
    colDataSetNItemsNull(pColumnInfoData, currentRow, numOfRows);
4,908✔
400
    pColumnInfoData->hasNull = true;
4,908✔
401
    return 0;
4,908✔
402
  }
403

404
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
1,982,324✔
405
    return colDataCopyAndReassign(pColumnInfoData, currentRow, pData, numOfRows);
1,313,383✔
406
  } else {
407
    int32_t  colBytes = pColumnInfoData->info.bytes;
668,941✔
408
    int32_t  colOffset = currentRow * colBytes;
668,941✔
409
    uint32_t num = 1;
668,941✔
410

411
    void* pStart = pColumnInfoData->pData + colOffset;
668,941✔
412
    memcpy(pStart, pData, colBytes);
668,941✔
413
    colOffset += num * colBytes;
668,941✔
414

415
    while (num < numOfRows) {
1,687,648✔
416
      int32_t maxNum = num << 1;
1,018,707✔
417
      int32_t tnum = maxNum > numOfRows ? (numOfRows - num) : num;
1,018,707✔
418

419
      memcpy(pColumnInfoData->pData + colOffset, pStart, tnum * colBytes);
1,018,707✔
420
      colOffset += tnum * colBytes;
1,018,707✔
421
      num += tnum;
1,018,707✔
422
    }
423
  }
424

425
  return TSDB_CODE_SUCCESS;
668,941✔
426
}
427

428
static void doBitmapMerge(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, const SColumnInfoData* pSource,
712,932,691✔
429
                          int32_t numOfRow2) {
430
  if (numOfRow2 <= 0) return;
712,932,691✔
431

432
  uint32_t total = numOfRow1 + numOfRow2;
712,932,691✔
433

434
  uint32_t remindBits = BitPos(numOfRow1);
712,932,691✔
435
  uint32_t shiftBits = 8 - remindBits;
712,932,691✔
436

437
  if (remindBits == 0) {  // no need to shift bits of bitmap
712,932,691✔
438
    memcpy(pColumnInfoData->nullbitmap + BitmapLen(numOfRow1), pSource->nullbitmap, BitmapLen(numOfRow2));
387,730,739✔
439
    return;
387,725,371✔
440
  }
441

442
  uint8_t* p = (uint8_t*)pSource->nullbitmap;
325,201,952✔
443
  pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] &= (0B11111111 << shiftBits);  // clear remind bits
325,217,258✔
444
  pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] |= (p[0] >> remindBits);       // copy remind bits
325,223,616✔
445

446
  if (BitmapLen(numOfRow1) == BitmapLen(total)) {
325,225,826✔
447
    return;
90,187,207✔
448
  }
449

450
  int32_t len = BitmapLen(numOfRow2);
235,038,619✔
451
  int32_t i = 0;
235,038,619✔
452

453
  uint8_t* start = (uint8_t*)&pColumnInfoData->nullbitmap[BitmapLen(numOfRow1)];
235,038,619✔
454
  int32_t  overCount = BitmapLen(total) - BitmapLen(numOfRow1);
235,038,864✔
455
  memset(start, 0, overCount);
235,038,864✔
456
  while (i < len) {  // size limit of pSource->nullbitmap
2,147,483,647✔
457
    if (i >= 1) {
2,147,483,647✔
458
      start[i - 1] |= (p[i] >> remindBits);  // copy remind bits
2,147,483,647✔
459
    }
460

461
    if (i >= overCount) {  // size limit of pColumnInfoData->nullbitmap
2,147,483,647✔
462
      return;
125,907,451✔
463
    }
464

465
    start[i] |= (p[i] << shiftBits);  // copy shift bits
2,147,483,647✔
466
    i += 1;
2,147,483,647✔
467
  }
468
}
469

470
int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int32_t* capacity,
956,412,757✔
471
                        const SColumnInfoData* pSource, int32_t numOfRow2) {
472
  if (pColumnInfoData->info.type != pSource->info.type) {
956,412,757✔
473
    return TSDB_CODE_INVALID_PARA;
×
474
  }
475

476
  if (numOfRow2 == 0) {
956,412,596✔
477
    return TSDB_CODE_SUCCESS;
2,150✔
478
  }
479

480
  if (pSource->hasNull) {
956,410,446✔
481
    pColumnInfoData->hasNull = pSource->hasNull;
528,227,175✔
482
  }
483

484
  uint32_t finalNumOfRows = numOfRow1 + numOfRow2;
956,450,806✔
485
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
956,450,806✔
486
    // Handle the bitmap
487
    if (finalNumOfRows > (*capacity)) {
243,485,170✔
488
      char* p = taosMemoryRealloc(pColumnInfoData->varmeta.offset, sizeof(int32_t) * (numOfRow1 + numOfRow2));
182,193,864✔
489
      if (p == NULL) {
182,194,808✔
490
        return terrno;
×
491
      }
492

493
      *capacity = finalNumOfRows;
182,194,808✔
494
      pColumnInfoData->varmeta.offset = (int32_t*)p;
182,195,954✔
495
    }
496

497
    for (int32_t i = 0; i < numOfRow2; ++i) {
2,147,483,647✔
498
      if (pSource->varmeta.offset[i] == -1) {
2,147,483,647✔
499
        pColumnInfoData->varmeta.offset[i + numOfRow1] = -1;
2,147,483,647✔
500
      } else {
501
        pColumnInfoData->varmeta.offset[i + numOfRow1] = pSource->varmeta.offset[i] + pColumnInfoData->varmeta.length;
2,147,483,647✔
502
      }
503
    }
504

505
    // copy data
506
    uint32_t len = pSource->varmeta.length;
243,339,778✔
507
    uint32_t oldLen = pColumnInfoData->varmeta.length;
243,508,150✔
508
    if (pColumnInfoData->varmeta.allocLen < len + oldLen) {
243,509,166✔
509
      char* tmp = taosMemoryRealloc(pColumnInfoData->pData, len + oldLen);
180,911,973✔
510
      if (tmp == NULL) {
180,908,177✔
511
        return terrno;
×
512
      }
513

514
      pColumnInfoData->pData = tmp;
180,908,177✔
515
      pColumnInfoData->varmeta.allocLen = len + oldLen;
180,908,659✔
516
    }
517

518
    if (pColumnInfoData->pData && pSource->pData) {  // TD-20382
243,507,335✔
519
      memcpy(pColumnInfoData->pData + oldLen, pSource->pData, len);
227,559,657✔
520
    }
521
    pColumnInfoData->varmeta.length = len + oldLen;
243,493,669✔
522
  } else {
523
    if (finalNumOfRows > (*capacity)) {
712,940,504✔
524
      // all data may be null, when the pColumnInfoData->info.type == 0, bytes == 0;
525
      char* tmp = taosMemoryRealloc(pColumnInfoData->pData, finalNumOfRows * pColumnInfoData->info.bytes);
521,941,783✔
526
      if (tmp == NULL) {
521,922,264✔
527
        return terrno;
×
528
      }
529

530
      pColumnInfoData->pData = tmp;
521,922,264✔
531
      if (BitmapLen(numOfRow1) < BitmapLen(finalNumOfRows)) {
521,923,343✔
532
        char* btmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(finalNumOfRows));
473,865,225✔
533
        if (btmp == NULL) {
473,866,310✔
534
          return terrno;
×
535
        }
536
        uint32_t extend = BitmapLen(finalNumOfRows) - BitmapLen(numOfRow1);
473,866,310✔
537
        memset(btmp + BitmapLen(numOfRow1), 0, extend);
473,866,310✔
538
        pColumnInfoData->nullbitmap = btmp;
473,870,224✔
539
      }
540

541
      *capacity = finalNumOfRows;
521,936,807✔
542
    }
543

544
    doBitmapMerge(pColumnInfoData, numOfRow1, pSource, numOfRow2);
712,909,387✔
545

546
    if (pSource->pData) {
712,931,029✔
547
      int32_t offset = pColumnInfoData->info.bytes * numOfRow1;
712,938,827✔
548
      memcpy(pColumnInfoData->pData + offset, pSource->pData, pSource->info.bytes * numOfRow2);
712,937,561✔
549
    }
550
  }
551

552
  return TSDB_CODE_SUCCESS;
956,357,129✔
553
}
554

555
int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* pSource, int32_t numOfRows,
2,147,483,647✔
556
                      const SDataBlockInfo* pBlockInfo) {
557
  if (pColumnInfoData->info.type != pSource->info.type || (pBlockInfo != NULL && pBlockInfo->capacity < numOfRows)) {
2,147,483,647✔
558
    return TSDB_CODE_INVALID_PARA;
×
559
  }
560

561
  if (numOfRows <= 0) {
2,147,483,647✔
562
    return numOfRows;
73,005,311✔
563
  }
564

565
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
566
    int32_t newLen = pSource->varmeta.length;
1,665,714,786✔
567
    memcpy(pColumnInfoData->varmeta.offset, pSource->varmeta.offset, sizeof(int32_t) * numOfRows);
1,666,710,610✔
568
    if (pColumnInfoData->varmeta.allocLen < newLen) {
1,666,704,372✔
569
      char* tmp = taosMemoryRealloc(pColumnInfoData->pData, newLen);
1,091,212,615✔
570
      if (tmp == NULL) {
1,091,139,249✔
571
        return terrno;
×
572
      }
573

574
      pColumnInfoData->pData = tmp;
1,091,139,249✔
575
      pColumnInfoData->varmeta.allocLen = newLen;
1,091,146,756✔
576
    }
577

578
    pColumnInfoData->varmeta.length = newLen;
1,666,664,284✔
579
    if (pColumnInfoData->pData != NULL && pSource->pData != NULL) {
1,666,631,116✔
580
      memcpy(pColumnInfoData->pData, pSource->pData, newLen);
1,506,496,786✔
581
    }
582
  } else {
583
    memcpy(pColumnInfoData->nullbitmap, pSource->nullbitmap, BitmapLen(numOfRows));
2,147,483,647✔
584
    if (pSource->pData != NULL) {
2,147,483,647✔
585
      memcpy(pColumnInfoData->pData, pSource->pData, pSource->info.bytes * numOfRows);
2,147,483,647✔
586
    }
587
  }
588

589
  pColumnInfoData->hasNull = pSource->hasNull;
2,147,483,647✔
590
  int16_t slotId = pColumnInfoData->info.slotId;
2,147,483,647✔
591
  pColumnInfoData->info = pSource->info;
2,147,483,647✔
592
  pColumnInfoData->info.slotId = slotId;
2,147,483,647✔
593
  return 0;
2,147,483,647✔
594
}
595

596
int32_t colDataAssignNRows(SColumnInfoData* pDst, int32_t dstIdx, const SColumnInfoData* pSrc, int32_t srcIdx,
1,270,386,438✔
597
                           int32_t numOfRows) {
598
  if (pDst->info.type != pSrc->info.type || pDst->info.bytes != pSrc->info.bytes || pSrc->reassigned) {
1,270,386,438✔
599
    return TSDB_CODE_INVALID_PARA;
×
600
  }
601

602
  if (numOfRows <= 0) {
1,269,825,066✔
603
    return numOfRows;
×
604
  }
605

606
  if (IS_VAR_DATA_TYPE(pDst->info.type)) {
1,457,026,186✔
607
    int32_t allLen = 0;
187,201,626✔
608
    void*   srcAddr = NULL;
187,201,626✔
609
    if (pSrc->hasNull) {
187,201,626✔
610
      for (int32_t i = 0; i < numOfRows; ++i) {
237,763,230✔
611
        if (colDataIsNull_var(pSrc, srcIdx + i)) {
121,792,644✔
612
          pDst->varmeta.offset[dstIdx + i] = -1;
5,134,568✔
613
          pDst->hasNull = true;
5,134,568✔
614
          continue;
5,134,568✔
615
        }
616

617
        char* pData = colDataGetVarData(pSrc, srcIdx + i);
116,658,076✔
618
        if (NULL == srcAddr) {
116,658,076✔
619
          srcAddr = pData;
110,852,903✔
620
        }
621
        int32_t dataLen = calcStrBytesByType(pSrc->info.type, pData);
116,658,076✔
622
        // if (pSrc->info.type == TSDB_DATA_TYPE_JSON) {
623
        //   dataLen = getJsonValueLen(pData);
624
        // } else if (IS_STR_DATA_BLOB(pSrc->info.type)) {
625
        //   dataLen = blobDataTLen(pData);
626
        // } else {
627
        //   dataLen = varDataTLen(pData);
628
        // }
629
        pDst->varmeta.offset[dstIdx + i] = pDst->varmeta.length + allLen;
116,658,076✔
630
        allLen += dataLen;
116,657,570✔
631
      }
632
    } else {
633
      for (int32_t i = 0; i < numOfRows; ++i) {
352,303,019✔
634
        char*   pData = colDataGetVarData(pSrc, srcIdx + i);
281,072,485✔
635
        int32_t dataLen = 0;
281,072,485✔
636
        if (pSrc->info.type == TSDB_DATA_TYPE_JSON) {
281,072,485✔
637
          dataLen = getJsonValueLen(pData);
11,424✔
638
        } else if (IS_STR_DATA_BLOB(pSrc->info.type)) {
281,061,061✔
639
          dataLen = blobDataTLen(pData);
×
640
        } else {
641
          dataLen = varDataTLen(pData);
281,061,061✔
642
        }
643
        pDst->varmeta.offset[dstIdx + i] = pDst->varmeta.length + allLen;
281,072,485✔
644
        allLen += dataLen;
281,072,485✔
645
      }
646
    }
647

648
    if (allLen > 0) {
187,201,120✔
649
      // copy data
650
      if (pDst->varmeta.allocLen < pDst->varmeta.length + allLen) {
182,082,425✔
651
        char* tmp = taosMemoryRealloc(pDst->pData, pDst->varmeta.length + allLen);
177,199,099✔
652
        if (tmp == NULL) {
177,199,605✔
653
          return terrno;
×
654
        }
655

656
        pDst->pData = tmp;
177,199,605✔
657
        pDst->varmeta.allocLen = pDst->varmeta.length + allLen;
177,199,605✔
658
      }
659
      if (pSrc->hasNull) {
182,082,931✔
660
        memcpy(pDst->pData + pDst->varmeta.length, srcAddr, allLen);
110,852,903✔
661
      } else {
662
        memcpy(pDst->pData + pDst->varmeta.length, colDataGetVarData(pSrc, srcIdx), allLen);
71,230,028✔
663
      }
664
      pDst->varmeta.length = pDst->varmeta.length + allLen;
182,082,931✔
665
    }
666
  } else {
667
    if (pSrc->hasNull) {
1,083,200,884✔
668
      if (BitPos(dstIdx) == BitPos(srcIdx)) {
590,283,839✔
669
        for (int32_t i = 0; i < numOfRows; ++i) {
616,112,209✔
670
          if (0 == BitPos(dstIdx) && (i + (1 << NBIT) <= numOfRows)) {
471,974,796✔
671
            BMCharPos(pDst->nullbitmap, dstIdx + i) = BMCharPos(pSrc->nullbitmap, srcIdx + i);
84,898,669✔
672
            if (BMCharPos(pDst->nullbitmap, dstIdx + i)) {
84,892,355✔
673
              pDst->hasNull = true;
337,103✔
674
            }
675
            i += (1 << NBIT) - 1;
84,896,947✔
676
          } else {
677
            if (colDataIsNull_f(pSrc, srcIdx + i)) {
387,076,127✔
678
              colDataSetNull_f(pDst->nullbitmap, dstIdx + i);
8,778,764✔
679
              pDst->hasNull = true;
8,778,764✔
680
            } else {
681
              colDataClearNull_f(pDst->nullbitmap, dstIdx + i);
378,325,667✔
682
            }
683
          }
684
        }
685
      } else {
686
        for (int32_t i = 0; i < numOfRows; ++i) {
1,464,141,031✔
687
          if (colDataIsNull_f(pSrc, srcIdx + i)) {
1,018,001,493✔
688
            colDataSetNull_f(pDst->nullbitmap, dstIdx + i);
53,038,273✔
689
            pDst->hasNull = true;
53,038,273✔
690
          } else {
691
            colDataClearNull_f(pDst->nullbitmap, dstIdx + i);
964,966,090✔
692
          }
693
        }
694
      }
695
    }
696

697
    if (pSrc->pData != NULL) {
1,083,193,996✔
698
      memcpy(pDst->pData + pDst->info.bytes * dstIdx, pSrc->pData + pSrc->info.bytes * srcIdx,
1,083,191,126✔
699
             pDst->info.bytes * numOfRows);
1,083,191,768✔
700
    }
701
  }
702

703
  return 0;
1,270,382,420✔
704
}
705

706
size_t blockDataGetNumOfCols(const SSDataBlock* pBlock) { return taosArrayGetSize(pBlock->pDataBlock); }
2,147,483,647✔
707

708
size_t blockDataGetNumOfRows(const SSDataBlock* pBlock) { return pBlock->info.rows; }
1,288,636,721✔
709

710
int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock, int32_t tsColumnIndex) {
2,147,483,647✔
711
  if (pDataBlock == NULL || pDataBlock->info.rows <= 0 || pDataBlock->info.dataLoad == 0) {
2,147,483,647✔
712
    return 0;
47,509,097✔
713
  }
714

715
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
2,147,483,647✔
716
  if (numOfCols <= 0) {
2,147,483,647✔
717
    return 0;
82,226✔
718
  }
719

720
  int32_t index = (tsColumnIndex == -1) ? 0 : tsColumnIndex;
2,147,483,647✔
721

722
  SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, index);
2,147,483,647✔
723
  if (pColInfoData == NULL) {
2,147,483,647✔
724
    return 0;
×
725
  }
726

727
  if (pColInfoData->info.type != TSDB_DATA_TYPE_TIMESTAMP) {
2,147,483,647✔
728
    return 0;
2,147,483,647✔
729
  }
730

731
  TSKEY skey = *(TSKEY*)colDataGetData(pColInfoData, 0);
1,263,179,558✔
732
  TSKEY ekey = *(TSKEY*)colDataGetData(pColInfoData, (pDataBlock->info.rows - 1));
1,263,172,128✔
733

734
  pDataBlock->info.window.skey = TMIN(skey, ekey);
1,263,073,697✔
735
  pDataBlock->info.window.ekey = TMAX(skey, ekey);
1,263,188,764✔
736

737
  return 0;
1,263,198,108✔
738
}
739

740
int32_t blockDataUpdatePkRange(SSDataBlock* pDataBlock, int32_t pkColumnIndex, bool asc) {
754,607,079✔
741
  if (pDataBlock == NULL || pDataBlock->info.rows <= 0 || pDataBlock->info.dataLoad == 0 || pkColumnIndex == -1) {
754,607,079✔
742
    return 0;
674,374,714✔
743
  }
744

745
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
80,346,780✔
746
  if (numOfCols <= 0) {
80,340,945✔
747
    return -1;
×
748
  }
749

750
  SDataBlockInfo*  pInfo = &pDataBlock->info;
80,340,945✔
751
  SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, pkColumnIndex);
80,337,075✔
752
  if (pColInfoData == NULL) {
80,349,390✔
753
    return terrno;
×
754
  }
755

756
  if (!IS_NUMERIC_TYPE(pColInfoData->info.type) && (pColInfoData->info.type != TSDB_DATA_TYPE_VARCHAR)) {
80,349,390✔
757
    return 0;
×
758
  }
759

760
  void* skey = colDataGetData(pColInfoData, 0);
80,340,855✔
761
  void* ekey = colDataGetData(pColInfoData, (pInfo->rows - 1));
80,337,015✔
762

763
  int64_t val = 0;
80,329,125✔
764
  if (asc) {
80,329,125✔
765
    if (IS_NUMERIC_TYPE(pColInfoData->info.type)) {
67,682,069✔
766
      GET_TYPED_DATA(val, int64_t, pColInfoData->info.type, skey, typeGetTypeModFromColInfo(&pColInfoData->info));
42,370,904✔
767
      VALUE_SET_TRIVIAL_DATUM(&pInfo->pks[0], val);
42,345,479✔
768
      GET_TYPED_DATA(val, int64_t, pColInfoData->info.type, ekey, typeGetTypeModFromColInfo(&pColInfoData->info));
42,351,929✔
769
      VALUE_SET_TRIVIAL_DATUM(&pInfo->pks[1], val);
42,328,679✔
770
    } else {  // todo refactor
771
      memcpy(pInfo->pks[0].pData, varDataVal(skey), varDataLen(skey));
25,328,085✔
772
      pInfo->pks[0].nData = varDataLen(skey);
25,332,045✔
773

774
      memcpy(pInfo->pks[1].pData, varDataVal(ekey), varDataLen(ekey));
25,338,465✔
775
      pInfo->pks[1].nData = varDataLen(ekey);
25,337,820✔
776
    }
777
  } else {
778
    if (IS_NUMERIC_TYPE(pColInfoData->info.type)) {
12,647,056✔
779
      GET_TYPED_DATA(val, int64_t, pColInfoData->info.type, ekey, typeGetTypeModFromColInfo(&pColInfoData->info));
8,206,205✔
780
      VALUE_SET_TRIVIAL_DATUM(&pInfo->pks[0], val);
8,198,315✔
781
      GET_TYPED_DATA(val, int64_t, pColInfoData->info.type, skey, typeGetTypeModFromColInfo(&pColInfoData->info));
8,200,985✔
782
      VALUE_SET_TRIVIAL_DATUM(&pInfo->pks[1], val);
8,197,055✔
783
    } else {  // todo refactor
784
      memcpy(pInfo->pks[0].pData, varDataVal(ekey), varDataLen(ekey));
4,449,416✔
785
      pInfo->pks[0].nData = varDataLen(ekey);
4,452,671✔
786

787
      memcpy(pInfo->pks[1].pData, varDataVal(skey), varDataLen(skey));
4,450,736✔
788
      pInfo->pks[1].nData = varDataLen(skey);
4,452,026✔
789
    }
790
  }
791

792
  return 0;
80,314,260✔
793
}
794

795
int32_t blockDataMerge(SSDataBlock* pDest, const SSDataBlock* pSrc) {
220,049,772✔
796
  int32_t code = 0;
220,049,772✔
797
  int32_t capacity = pDest->info.capacity;
220,049,772✔
798
  size_t  numOfCols = taosArrayGetSize(pDest->pDataBlock);
220,060,002✔
799
  for (int32_t i = 0; i < numOfCols; ++i) {
1,147,727,574✔
800
    SColumnInfoData* pCol2 = taosArrayGet(pDest->pDataBlock, i);
927,660,525✔
801
    SColumnInfoData* pCol1 = taosArrayGet(pSrc->pDataBlock, i);
927,661,493✔
802
    if (pCol1 == NULL || pCol2 == NULL) {
927,706,416✔
803
      return terrno;
114✔
804
    }
805

806
    capacity = pDest->info.capacity;
927,710,664✔
807
    int32_t ret = colDataMergeCol(pCol2, pDest->info.rows, &capacity, pCol1, pSrc->info.rows);
927,713,746✔
808
    if (ret < 0) {  // error occurs
927,650,721✔
809
      code = ret;
×
810
      return code;
×
811
    }
812
  }
813

814
  pDest->info.capacity = capacity;
220,067,049✔
815
  pDest->info.rows += pSrc->info.rows;
220,067,049✔
816
  return code;
220,065,730✔
817
}
818

819
void blockDataTransform(SSDataBlock* pDest, const SSDataBlock* pSrc) {
7,030,142✔
820
  size_t  numOfCols = taosArrayGetSize(pDest->pDataBlock);
7,030,142✔
821
  size_t  numOfColsSrc = taosArrayGetSize(pSrc->pDataBlock);
7,034,726✔
822
  for (int32_t i = 0; i < numOfCols; ++i) {
21,340,103✔
823
    SColumnInfoData* pCol1 = taosArrayGet(pDest->pDataBlock, i);
14,304,282✔
824
    for (int32_t j = 0; j < numOfColsSrc; ++j) {
22,624,549✔
825
      SColumnInfoData* pCol2 = taosArrayGet(pSrc->pDataBlock, j);
22,623,673✔
826
      if (pCol1->info.colId == pCol2->info.colId) {
22,628,053✔
827
        TSWAP(*pCol1, *pCol2);
14,308,458✔
828
        break;
14,308,458✔
829
      }
830
    }
831
  }
832

833
  pDest->info.rows = pSrc->info.rows;
7,035,821✔
834
  pDest->info.capacity = pSrc->info.rows;
7,035,383✔
835
}
7,033,631✔
836

837
int32_t blockDataMergeNRows(SSDataBlock* pDest, const SSDataBlock* pSrc, int32_t srcIdx, int32_t numOfRows) {
11,326,313✔
838
  int32_t code = 0, lino = 0;
11,326,313✔
839
  if (pDest->info.rows + numOfRows > pDest->info.capacity) {
11,326,313✔
840
    uError("block capacity %d not enough to merge %d rows, currRows:%" PRId64, pDest->info.capacity, numOfRows, pDest->info.rows);
×
841
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_PARA);
×
842
  }
843

844
  size_t numOfCols = taosArrayGetSize(pDest->pDataBlock);
11,326,313✔
845
  for (int32_t i = 0; i < numOfCols; ++i) {
42,389,731✔
846
    SColumnInfoData* pCol2 = taosArrayGet(pDest->pDataBlock, i);
31,063,418✔
847
    TSDB_CHECK_NULL(pCol2, code, lino, _exit, terrno);
31,063,418✔
848
    SColumnInfoData* pCol1 = taosArrayGet(pSrc->pDataBlock, i);
31,063,418✔
849
    TSDB_CHECK_NULL(pCol1, code, lino, _exit, terrno);
31,063,418✔
850

851
    TAOS_CHECK_EXIT(colDataAssignNRows(pCol2, pDest->info.rows, pCol1, srcIdx, numOfRows));
31,063,418✔
852
  }
853

854
  pDest->info.rows += numOfRows;
11,326,313✔
855

856
_exit:
11,326,313✔
857

858
  if (code) {
11,326,313✔
859
    uError("%s failed at line %d since %s", __FUNCTION__, lino, tstrerror(code));
×
860
  }
861
  
862
  return code;
11,322,223✔
863
}
864

865
void blockDataShrinkNRows(SSDataBlock* pBlock, int32_t numOfRows) {
×
866
  if (numOfRows == 0) {
×
867
    return;
×
868
  }
869

870
  if (numOfRows >= pBlock->info.rows) {
×
871
    blockDataCleanup(pBlock);
×
872
    return;
×
873
  }
874

875
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
×
876
  for (int32_t i = 0; i < numOfCols; ++i) {
×
877
    SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, i);
×
878
    if (pCol == NULL) {
×
879
      continue;
×
880
    }
881

882
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
×
883
      pCol->varmeta.length = pCol->varmeta.offset[pBlock->info.rows - numOfRows];
×
884
      memset(pCol->varmeta.offset + pBlock->info.rows - numOfRows, 0, sizeof(*pCol->varmeta.offset) * numOfRows);
×
885
    } else {
886
      int32_t i = pBlock->info.rows - numOfRows;
×
887
      for (; i < pBlock->info.rows; ++i) {
×
888
        if (BitPos(i)) {
×
889
          colDataClearNull_f(pCol->nullbitmap, i);
×
890
        } else {
891
          break;
×
892
        }
893
      }
894

895
      int32_t bytes = (pBlock->info.rows - i) / 8;
×
896
      memset(&BMCharPos(pCol->nullbitmap, i), 0, bytes);
×
897
      i += bytes * 8;
×
898

899
      for (; i < pBlock->info.rows; ++i) {
×
900
        colDataClearNull_f(pCol->nullbitmap, i);
×
901
      }
902
    }
903
  }
904

905
  pBlock->info.rows -= numOfRows;
×
906
}
907

908
size_t blockDataGetSize(const SSDataBlock* pBlock) {
2,147,483,647✔
909
  size_t total = 0;
2,147,483,647✔
910
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
2,147,483,647✔
911
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
912
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
2,147,483,647✔
913
    if (pColInfoData == NULL) {
2,147,483,647✔
914
      continue;
×
915
    }
916

917
    total += colDataGetFullLength(pColInfoData, pBlock->info.rows);
2,147,483,647✔
918
  }
919

920
  return total;
2,147,483,647✔
921
}
922

923
// the number of tuples can be fit in one page.
924
// Actual data rows pluses the corresponding meta data must fit in one memory buffer of the given page size.
925
int32_t blockDataSplitRows(SSDataBlock* pBlock, bool hasVarCol, int32_t startIndex, int32_t* stopIndex,
55,471,707✔
926
                           int32_t pageSize) {
927
  size_t  numOfCols = taosArrayGetSize(pBlock->pDataBlock);
55,471,707✔
928
  int32_t numOfRows = pBlock->info.rows;
55,471,707✔
929

930
  int32_t bitmapChar = 1;
55,471,707✔
931

932
  size_t headerSize = sizeof(int32_t);
55,471,707✔
933
  size_t colHeaderSize = sizeof(int32_t) * numOfCols;
55,471,707✔
934

935
  // TODO speedup by checking if the whole page can fit in firstly.
936
  if (!hasVarCol) {
55,471,707✔
937
    size_t  rowSize = blockDataGetRowSize(pBlock);
×
938
    int32_t capacity = blockDataGetCapacityInRow(pBlock, pageSize, headerSize + colHeaderSize);
×
939
    if (capacity <= 0) {
×
940
      return terrno;
×
941
    }
942

943
    *stopIndex = startIndex + capacity - 1;
×
944
    if (*stopIndex >= numOfRows) {
×
945
      *stopIndex = numOfRows - 1;
×
946
    }
947

948
    return TSDB_CODE_SUCCESS;
×
949
  }
950
  // iterate the rows that can be fit in this buffer page
951
  int32_t size = (headerSize + colHeaderSize);
55,471,707✔
952
  for (int32_t j = startIndex; j < numOfRows; ++j) {
2,147,483,647✔
953
    for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
954
      SColumnInfoData* pColInfoData = TARRAY_GET_ELEM(pBlock->pDataBlock, i);
2,147,483,647✔
955
      if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
2,147,483,647✔
956
        if (pColInfoData->varmeta.offset[j] != -1) {
2,147,483,647✔
957
          char* p = colDataGetData(pColInfoData, j);
2,147,483,647✔
958
          if (IS_STR_DATA_BLOB(pColInfoData->info.type)) {
2,147,483,647✔
959
            size += blobDataTLen(p);
×
960
          } else {
961
            size += varDataTLen(p);
2,147,483,647✔
962
          }
963
        }
964

965
        size += sizeof(pColInfoData->varmeta.offset[0]);
2,147,483,647✔
966
      } else {
967
        size += pColInfoData->info.bytes;
2,147,483,647✔
968

969
        if (((j - startIndex) & 0x07) == 0) {
2,147,483,647✔
970
          size += 1;  // the space for null bitmap
2,147,483,647✔
971
        }
972
      }
973
    }
974

975
    if (size > pageSize) {  // pageSize must be able to hold one row
2,147,483,647✔
976
      *stopIndex = j - 1;
55,417,008✔
977
      if (*stopIndex < startIndex) {
55,417,008✔
978
        return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
979
      }
980

981
      return TSDB_CODE_SUCCESS;
55,417,008✔
982
    }
983
  }
984

985
  // all fit in
986
  *stopIndex = numOfRows - 1;
54,699✔
987
  return TSDB_CODE_SUCCESS;
54,699✔
988
}
989

990
int32_t blockDataExtractBlock(SSDataBlock* pBlock, int32_t startIndex, int32_t rowCount, SSDataBlock** pResBlock) {
62,499,880✔
991
  int32_t code = 0;
62,499,880✔
992
  QRY_PARAM_CHECK(pResBlock);
62,499,880✔
993

994
  if (pBlock == NULL || startIndex < 0 || rowCount > pBlock->info.rows || rowCount + startIndex > pBlock->info.rows) {
62,499,880✔
995
    return TSDB_CODE_INVALID_PARA;
×
996
  }
997

998
  SSDataBlock* pDst = NULL;
62,499,880✔
999
  code = createOneDataBlock(pBlock, false, &pDst);
62,499,880✔
1000
  if (code) {
62,499,880✔
1001
    return code;
×
1002
  }
1003

1004
  code = blockDataEnsureCapacity(pDst, rowCount);
62,499,880✔
1005
  if (code) {
62,499,880✔
1006
    blockDataDestroy(pDst);
×
1007
    return code;
×
1008
  }
1009

1010
  /* may have disorder varchar data, TODO
1011
    for (int32_t i = 0; i < numOfCols; ++i) {
1012
      SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i);
1013
      SColumnInfoData* pDstCol = taosArrayGet(pDst->pDataBlock, i);
1014

1015
      colDataAssignNRows(pDstCol, 0, pColData, startIndex, rowCount);
1016
    }
1017
  */
1018

1019
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
62,499,880✔
1020
  for (int32_t i = 0; i < numOfCols; ++i) {
885,689,970✔
1021
    SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i);
823,190,090✔
1022
    SColumnInfoData* pDstCol = taosArrayGet(pDst->pDataBlock, i);
823,190,672✔
1023
    if (pColData == NULL || pDstCol == NULL) {
823,190,090✔
1024
      continue;
×
1025
    }
1026

1027
    for (int32_t j = startIndex; j < (startIndex + rowCount); ++j) {
2,147,483,647✔
1028
      bool isNull = false;
2,147,483,647✔
1029
      if (pBlock->pBlockAgg == NULL) {
2,147,483,647✔
1030
        isNull = colDataIsNull_s(pColData, j);
2,147,483,647✔
1031
      } else {
1032
        isNull = colDataIsNull(pColData, pBlock->info.rows, j, &pBlock->pBlockAgg[i]);
×
1033
      }
1034

1035
      if (isNull) {
2,147,483,647✔
1036
        colDataSetNULL(pDstCol, j - startIndex);
2,147,483,647✔
1037
      } else {
1038
        char* p = colDataGetData(pColData, j);
2,147,483,647✔
1039
        code = colDataSetVal(pDstCol, j - startIndex, p, false);
2,147,483,647✔
1040
        if (code) {
2,147,483,647✔
1041
          break;
×
1042
        }
1043
      }
1044
    }
1045
  }
1046

1047
  pDst->info.rows = rowCount;
62,499,880✔
1048
  *pResBlock = pDst;
62,499,880✔
1049
  return code;
62,498,732✔
1050
}
1051

1052
/**
1053
 *
1054
 * +------------------+---------------------------------------------+
1055
 * |the number of rows|                    column #1                |
1056
 * |    (4 bytes)     |------------+-----------------------+--------+
1057
 * |                  | null bitmap| column length(4bytes) | values |
1058
 * +------------------+------------+-----------------------+--------+
1059
 * @param buf
1060
 * @param pBlock
1061
 * @return
1062
 */
1063
int32_t blockDataToBuf(char* buf, const SSDataBlock* pBlock) {
96,887,302✔
1064
  // write the number of rows
1065
  *(uint32_t*)buf = pBlock->info.rows;
96,887,302✔
1066

1067
  size_t  numOfCols = taosArrayGetSize(pBlock->pDataBlock);
96,887,275✔
1068
  int32_t numOfRows = pBlock->info.rows;
96,885,286✔
1069

1070
  char* pStart = buf + sizeof(uint32_t);
96,885,739✔
1071

1072
  for (int32_t i = 0; i < numOfCols; ++i) {
1,015,523,216✔
1073
    SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, i);
918,636,108✔
1074
    if (pCol == NULL) {
918,632,350✔
1075
      continue;
×
1076
    }
1077

1078
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
918,632,350✔
1079
      memcpy(pStart, pCol->varmeta.offset, numOfRows * sizeof(int32_t));
189,880,299✔
1080
      pStart += numOfRows * sizeof(int32_t);
189,880,565✔
1081
    } else {
1082
      memcpy(pStart, pCol->nullbitmap, BitmapLen(numOfRows));
728,752,651✔
1083
      pStart += BitmapLen(pBlock->info.rows);
728,754,808✔
1084
    }
1085

1086
    uint32_t dataSize = colDataGetLength(pCol, numOfRows);
918,637,314✔
1087

1088
    *(int32_t*)pStart = dataSize;
918,637,667✔
1089
    pStart += sizeof(int32_t);
918,637,948✔
1090

1091
    if (pCol->reassigned && IS_VAR_DATA_TYPE(pCol->info.type)) {
918,637,365✔
1092
      for (int32_t row = 0; row < numOfRows; ++row) {
×
1093
        char*   pColData = pCol->pData + pCol->varmeta.offset[row];
×
1094
        int32_t colSize = calcStrBytesByType(pCol->info.type, pColData);
×
1095
        // if (pCol->info.type == TSDB_DATA_TYPE_JSON) {
1096
        //   colSize = getJsonValueLen(pColData);
1097
        // } else if (IS_STR_DATA_BLOB(pCol->info.type)) {
1098
        //   colSize = blobDataTLen(pColData);
1099
        // } else {
1100
        //   colSize = varDataTLen(pColData);
1101
        // }
1102
        memcpy(pStart, pColData, colSize);
×
1103
        pStart += colSize;
×
1104
      }
1105
    } else {
1106
      if (dataSize != 0) {
918,637,051✔
1107
        // ubsan reports error if pCol->pData==NULL && dataSize==0
1108
        memcpy(pStart, pCol->pData, dataSize);
894,906,058✔
1109
      }
1110
      pStart += dataSize;
918,635,761✔
1111
    }
1112
  }
1113

1114
  return 0;
96,887,108✔
1115
}
1116

1117
int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) {
93,063,043✔
1118
  int32_t numOfRows = *(int32_t*)buf;
93,063,043✔
1119
  if (numOfRows == 0) {
93,063,556✔
1120
    return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
1121
  }
1122
  int32_t code = blockDataEnsureCapacity(pBlock, numOfRows);
93,063,556✔
1123
  if (code) {
93,065,017✔
1124
    return code;
×
1125
  }
1126

1127
  pBlock->info.rows = numOfRows;
93,065,017✔
1128
  size_t      numOfCols = taosArrayGetSize(pBlock->pDataBlock);
93,064,443✔
1129
  const char* pStart = buf + sizeof(uint32_t);
93,063,895✔
1130

1131
  for (int32_t i = 0; i < numOfCols; ++i) {
857,676,900✔
1132
    SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, i);
764,612,629✔
1133
    if (pCol == NULL) {
764,607,549✔
1134
      continue;
×
1135
    }
1136

1137
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
764,607,549✔
1138
      size_t metaSize = pBlock->info.rows * sizeof(int32_t);
146,579,247✔
1139
      memcpy(pCol->varmeta.offset, pStart, metaSize);
146,589,062✔
1140
      pStart += metaSize;
146,589,062✔
1141
    } else {
1142
      memcpy(pCol->nullbitmap, pStart, BitmapLen(pBlock->info.rows));
618,023,277✔
1143
      pStart += BitmapLen(pBlock->info.rows);
618,024,326✔
1144
    }
1145

1146
    int32_t colLength = *(int32_t*)pStart;
764,615,332✔
1147
    pStart += sizeof(int32_t);
764,615,403✔
1148

1149
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
764,613,963✔
1150
      if (pCol->varmeta.allocLen < colLength) {
146,585,758✔
1151
        char* tmp = taosMemoryRealloc(pCol->pData, colLength);
3,165,177✔
1152
        if (tmp == NULL) {
3,165,177✔
1153
          return terrno;
×
1154
        }
1155

1156
        pCol->pData = tmp;
3,165,177✔
1157
        pCol->varmeta.allocLen = colLength;
3,164,532✔
1158
      }
1159

1160
      pCol->varmeta.length = colLength;
146,588,417✔
1161
      if (pCol->varmeta.length > pCol->varmeta.allocLen) {
146,588,417✔
1162
        return TSDB_CODE_FAILED;
×
1163
      }
1164
    }
1165
    if (colLength != 0) {
764,611,745✔
1166
      // ubsan reports error if colLength==0 && pCol->pData == 0
1167
      memcpy(pCol->pData, pStart, colLength);
747,840,238✔
1168
    }
1169
    pStart += colLength;
764,611,745✔
1170
  }
1171

1172
  return TSDB_CODE_SUCCESS;
93,064,271✔
1173
}
1174

1175
static bool colDataIsNNull(const SColumnInfoData* pColumnInfoData, int32_t startIndex, uint32_t nRows) {
2,147,483,647✔
1176
  if (!pColumnInfoData->hasNull) {
2,147,483,647✔
1177
    return false;
×
1178
  }
1179

1180
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
2,147,483,647✔
1181
    for (int32_t i = startIndex; i < nRows; ++i) {
960,411,037✔
1182
      if (!colDataIsNull_var(pColumnInfoData, i)) {
960,412,036✔
1183
        return false;
729,238,715✔
1184
      }
1185
    }
1186
  } else {
1187
    if (pColumnInfoData->nullbitmap == NULL) {
2,147,483,647✔
1188
      return false;
×
1189
    }
1190

1191
    for (int32_t i = startIndex; i < nRows; ++i) {
2,147,483,647✔
1192
      if (!colDataIsNull_f(pColumnInfoData, i)) {
2,147,483,647✔
1193
        return false;
1,803,835,749✔
1194
      }
1195
    }
1196
  }
1197

1198
  return true;
464,425,919✔
1199
}
1200

1201
// todo remove this
1202
int32_t blockDataFromBuf1(SSDataBlock* pBlock, const char* buf, size_t capacity) {
292,301,481✔
1203
  pBlock->info.rows = *(int32_t*)buf;
292,301,481✔
1204
  pBlock->info.id.groupId = *(uint64_t*)(buf + sizeof(int32_t));
292,301,893✔
1205

1206
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
292,302,928✔
1207

1208
  const char* pStart = buf + sizeof(uint32_t) + sizeof(uint64_t);
292,302,750✔
1209

1210
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
1211
    SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, i);
2,147,483,647✔
1212
    if (pCol == NULL) {
2,147,483,647✔
1213
      continue;
×
1214
    }
1215

1216
    pCol->hasNull = true;
2,147,483,647✔
1217

1218
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
2,147,483,647✔
1219
      size_t metaSize = capacity * sizeof(int32_t);
856,417,970✔
1220
      memcpy(pCol->varmeta.offset, pStart, metaSize);
856,417,970✔
1221
      pStart += metaSize;
856,541,995✔
1222
    } else {
1223
      memcpy(pCol->nullbitmap, pStart, BitmapLen(capacity));
2,147,483,647✔
1224
      pStart += BitmapLen(capacity);
2,147,483,647✔
1225
    }
1226

1227
    int32_t colLength = *(int32_t*)pStart;
2,147,483,647✔
1228
    pStart += sizeof(int32_t);
2,147,483,647✔
1229

1230
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
2,147,483,647✔
1231
      if (pCol->varmeta.allocLen < colLength) {
856,535,651✔
1232
        char* tmp = taosMemoryRealloc(pCol->pData, colLength);
1,623,356✔
1233
        if (tmp == NULL) {
1,623,356✔
1234
          return terrno;
×
1235
        }
1236

1237
        pCol->pData = tmp;
1,623,356✔
1238
        pCol->varmeta.allocLen = colLength;
1,623,356✔
1239
      }
1240

1241
      pCol->varmeta.length = colLength;
856,546,476✔
1242
      if (pCol->varmeta.length > pCol->varmeta.allocLen) {
856,546,065✔
1243
        return TSDB_CODE_FAILED;
×
1244
      }
1245
    }
1246

1247
    if (colLength != 0 && !colDataIsNNull(pCol, 0, pBlock->info.rows)) {
2,147,483,647✔
1248
      memcpy(pCol->pData, pStart, colLength);
2,147,483,647✔
1249
    }
1250

1251
    pStart += blockDataGetPagedColumnReservedBytes(pCol) * capacity;
2,147,483,647✔
1252
  }
1253

1254
  return TSDB_CODE_SUCCESS;
292,303,714✔
1255
}
1256

1257
size_t blockDataGetRowSize(SSDataBlock* pBlock) {
2,147,483,647✔
1258
  if (pBlock->info.rowSize == 0) {
2,147,483,647✔
1259
    size_t rowSize = 0;
×
1260

1261
    size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
×
1262
    for (int32_t i = 0; i < numOfCols; ++i) {
×
1263
      SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
×
1264
      if (pColInfo == NULL) {
×
1265
        continue;
×
1266
      }
1267

1268
      rowSize += pColInfo->info.bytes;
×
1269
    }
1270

1271
    pBlock->info.rowSize = rowSize;
×
1272
  }
1273

1274
  return pBlock->info.rowSize;
2,147,483,647✔
1275
}
1276

1277
size_t blockDataGetSerialMetaSizeImpl(uint32_t numOfCols, bool internal) {
2,056,564,797✔
1278
  // | version | total length | total rows | blankFull | total columns | flag seg| block group id | column schema
1279
  // | each column length
1280
  // internal: | scanFlag baseGid |
1281
  return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) +
1282
         sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t) + 
2,056,564,797✔
1283
         (internal ? (sizeof(uint8_t) + sizeof(uint64_t) + numOfCols * sizeof(int16_t)) : 0);
2,056,564,797✔
1284
}
1285

1286
size_t blockDataGetSerialMetaSizeInternal(uint32_t numOfCols) {
113,219,188✔
1287
  return blockDataGetSerialMetaSizeImpl(numOfCols, true);
113,219,188✔
1288
}
1289

1290
/**
1291
 * @refitem blockDataToBuf for the meta size
1292
 * @param pBlock
1293
 * @return
1294
 */
1295
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
1,943,344,653✔
1296
  return blockDataGetSerialMetaSizeImpl(numOfCols, false);
1,943,344,653✔
1297
}
1298

1299
double blockDataGetSerialRowSize(const SSDataBlock* pBlock) {
10,660,505✔
1300
  double rowSize = 0;
10,660,505✔
1301

1302
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
10,660,505✔
1303
  for (int32_t i = 0; i < numOfCols; ++i) {
41,605,924✔
1304
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
30,944,493✔
1305
    if (pColInfo == NULL) {
30,944,180✔
1306
      continue;
×
1307
    }
1308

1309
    rowSize += pColInfo->info.bytes;
30,944,180✔
1310
    if (IS_VAR_DATA_TYPE(pColInfo->info.type)) {
30,944,180✔
1311
      rowSize += sizeof(int32_t);
2,299,454✔
1312
    } else {
1313
      rowSize += 1 / 8.0;  // one bit for each record
28,645,101✔
1314
    }
1315
  }
1316

1317
  return rowSize;
10,661,431✔
1318
}
1319

1320
typedef struct SSDataBlockSortHelper {
1321
  SArray*      orderInfo;  // SArray<SBlockOrderInfo>
1322
  SSDataBlock* pDataBlock;
1323
} SSDataBlockSortHelper;
1324

1325
int32_t dataBlockCompar(const void* p1, const void* p2, const void* param) {
2,147,483,647✔
1326
  const SSDataBlockSortHelper* pHelper = (const SSDataBlockSortHelper*)param;
2,147,483,647✔
1327

1328
  SSDataBlock* pDataBlock = pHelper->pDataBlock;
2,147,483,647✔
1329

1330
  int32_t left = *(int32_t*)p1;
2,147,483,647✔
1331
  int32_t right = *(int32_t*)p2;
2,147,483,647✔
1332

1333
  SArray* pInfo = pHelper->orderInfo;
2,147,483,647✔
1334

1335
  for (int32_t i = 0; i < pInfo->size; ++i) {
2,147,483,647✔
1336
    SBlockOrderInfo* pOrder = TARRAY_GET_ELEM(pInfo, i);
2,147,483,647✔
1337
    SColumnInfoData* pColInfoData = pOrder->pColData;  // TARRAY_GET_ELEM(pDataBlock->pDataBlock, pOrder->colIndex);
2,147,483,647✔
1338

1339
    if (pColInfoData->hasNull) {
2,147,483,647✔
1340
      bool leftNull = colDataIsNull(pColInfoData, pDataBlock->info.rows, left, NULL);
2,147,483,647✔
1341
      bool rightNull = colDataIsNull(pColInfoData, pDataBlock->info.rows, right, NULL);
2,147,483,647✔
1342
      if (leftNull && rightNull) {
2,147,483,647✔
1343
        continue;  // continue to next slot
2,147,483,647✔
1344
      }
1345

1346
      if (rightNull) {
2,147,483,647✔
1347
        return pOrder->nullFirst ? 1 : -1;
354,144,601✔
1348
      }
1349

1350
      if (leftNull) {
2,147,483,647✔
1351
        return pOrder->nullFirst ? -1 : 1;
1,019,759,344✔
1352
      }
1353
    }
1354

1355
    void* left1 = colDataGetData(pColInfoData, left);
2,147,483,647✔
1356
    void* right1 = colDataGetData(pColInfoData, right);
2,147,483,647✔
1357
    if (pColInfoData->info.type == TSDB_DATA_TYPE_JSON) {
2,147,483,647✔
1358
      if (tTagIsJson(left1) || tTagIsJson(right1)) {
141,624✔
1359
        terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
8,568✔
1360
        return 0;
8,568✔
1361
      }
1362
    }
1363

1364
    __compar_fn_t fn;
1365
    if (pOrder->compFn) {
2,147,483,647✔
1366
      fn = pOrder->compFn;
2,147,483,647✔
1367
    } else {
1368
      fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order);
×
1369
    }
1370

1371
    int ret = fn(left1, right1);
2,147,483,647✔
1372
    if (ret == 0) {
2,147,483,647✔
1373
      continue;
2,147,483,647✔
1374
    } else {
1375
      return ret;
2,147,483,647✔
1376
    }
1377
  }
1378

1379
  return 0;
2,147,483,647✔
1380
}
1381

1382
static void blockDataAssign(SColumnInfoData* pCols, const SSDataBlock* pDataBlock, const int32_t* index) {
22,551,870✔
1383
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
22,551,870✔
1384
  for (int32_t i = 0; i < numOfCols; ++i) {
99,113,119✔
1385
    SColumnInfoData* pDst = &pCols[i];
76,560,313✔
1386
    SColumnInfoData* pSrc = taosArrayGet(pDataBlock->pDataBlock, i);
76,558,797✔
1387
    if (pSrc == NULL) {
76,558,776✔
1388
      continue;
×
1389
    }
1390

1391
    if (IS_VAR_DATA_TYPE(pSrc->info.type)) {
76,558,776✔
1392
      if (pSrc->varmeta.length != 0) {
24,482,397✔
1393
        memcpy(pDst->pData, pSrc->pData, pSrc->varmeta.length);
23,820,798✔
1394
      }
1395
      pDst->varmeta.length = pSrc->varmeta.length;
24,482,145✔
1396

1397
      for (int32_t j = 0; j < pDataBlock->info.rows; ++j) {
2,147,483,647✔
1398
        pDst->varmeta.offset[j] = pSrc->varmeta.offset[index[j]];
2,147,483,647✔
1399
      }
1400
    } else {
1401
      for (int32_t j = 0; j < pDataBlock->info.rows; ++j) {
2,147,483,647✔
1402
        if (colDataIsNull_f(pSrc, index[j])) {
2,147,483,647✔
1403
          colDataSetNull_f_s(pDst, j);
2,147,483,647✔
1404
          continue;
2,147,483,647✔
1405
        }
1406
        memcpy(pDst->pData + j * pDst->info.bytes, pSrc->pData + index[j] * pDst->info.bytes, pDst->info.bytes);
2,147,483,647✔
1407
      }
1408
    }
1409
  }
1410
}
22,552,806✔
1411

1412
static int32_t createHelpColInfoData(const SSDataBlock* pDataBlock, SColumnInfoData** ppCols) {
22,552,275✔
1413
  int32_t code = 0;
22,552,275✔
1414
  int32_t rows = pDataBlock->info.capacity;
22,552,275✔
1415
  size_t  numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
22,552,806✔
1416
  int32_t i = 0;
22,552,401✔
1417

1418
  *ppCols = NULL;
22,552,401✔
1419

1420
  SColumnInfoData* pCols = taosMemoryCalloc(numOfCols, sizeof(SColumnInfoData));
22,552,401✔
1421
  if (pCols == NULL) {
22,552,806✔
1422
    return terrno;
×
1423
  }
1424

1425
  for (i = 0; i < numOfCols; ++i) {
99,111,803✔
1426
    SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, i);
76,560,338✔
1427
    if (pColInfoData == NULL) {
76,560,439✔
1428
      continue;
×
1429
    }
1430

1431
    pCols[i].info = pColInfoData->info;
76,560,439✔
1432
    if (IS_VAR_DATA_TYPE(pCols[i].info.type)) {
76,559,503✔
1433
      pCols[i].varmeta.offset = taosMemoryCalloc(rows, sizeof(int32_t));
24,481,597✔
1434
      pCols[i].pData = taosMemoryCalloc(1, pColInfoData->varmeta.length);
24,481,614✔
1435
      if (pCols[i].varmeta.offset == NULL || pCols[i].pData == NULL) {
24,482,145✔
UNCOV
1436
        code = terrno;
×
1437
        taosMemoryFree(pCols[i].varmeta.offset);
×
1438
        taosMemoryFree(pCols[i].pData);
×
1439
        goto _error;
×
1440
      }
1441

1442
      pCols[i].varmeta.length = pColInfoData->varmeta.length;
24,481,614✔
1443
      pCols[i].varmeta.allocLen = pCols[i].varmeta.length;
24,481,614✔
1444
    } else {
1445
      pCols[i].nullbitmap = taosMemoryCalloc(1, BitmapLen(rows));
52,078,168✔
1446
      pCols[i].pData = taosMemoryCalloc(rows, pCols[i].info.bytes);
52,078,168✔
1447
      if (pCols[i].nullbitmap == NULL || pCols[i].pData == NULL) {
52,077,763✔
1448
        code = terrno;
405✔
1449
        taosMemoryFree(pCols[i].nullbitmap);
×
1450
        taosMemoryFree(pCols[i].pData);
×
1451
        goto _error;
×
1452
      }
1453
    }
1454
  }
1455

1456
  *ppCols = pCols;
22,551,465✔
1457
  return code;
22,551,996✔
1458

1459
_error:
×
1460
  for (int32_t j = 0; j < i; ++j) {
×
1461
    colDataDestroy(&pCols[j]);
×
1462
  }
1463

1464
  taosMemoryFree(pCols);
×
1465
  return code;
×
1466
}
1467

1468
static void copyBackToBlock(SSDataBlock* pDataBlock, SColumnInfoData* pCols) {
22,552,275✔
1469
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
22,552,275✔
1470

1471
  for (int32_t i = 0; i < numOfCols; ++i) {
99,107,989✔
1472
    SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, i);
76,556,398✔
1473
    if (pColInfoData == NULL) {
76,558,691✔
1474
      continue;
×
1475
    }
1476

1477
    pColInfoData->info = pCols[i].info;
76,558,691✔
1478
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
76,557,629✔
1479
      taosMemoryFreeClear(pColInfoData->varmeta.offset);
24,481,083✔
1480
      pColInfoData->varmeta = pCols[i].varmeta;
24,480,160✔
1481
    } else {
1482
      taosMemoryFreeClear(pColInfoData->nullbitmap);
52,075,629✔
1483
      pColInfoData->nullbitmap = pCols[i].nullbitmap;
52,075,622✔
1484
    }
1485

1486
    taosMemoryFreeClear(pColInfoData->pData);
76,558,280✔
1487
    pColInfoData->pData = pCols[i].pData;
76,557,884✔
1488
  }
1489

1490
  taosMemoryFreeClear(pCols);
22,551,591✔
1491
}
22,548,389✔
1492

1493
static int32_t* createTupleIndex(size_t rows) {
22,552,779✔
1494
  int32_t* index = taosMemoryCalloc(rows, sizeof(int32_t));
22,552,779✔
1495
  if (index == NULL) {
22,553,310✔
1496
    return NULL;
×
1497
  }
1498

1499
  for (int32_t i = 0; i < rows; ++i) {
2,147,483,647✔
1500
    index[i] = i;
2,147,483,647✔
1501
  }
1502

1503
  return index;
22,553,310✔
1504
}
1505

1506
static void destroyTupleIndex(int32_t* index) { taosMemoryFreeClear(index); }
22,552,326✔
1507

1508
int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) {
23,994,901✔
1509
  if (pDataBlock->info.rows <= 1) {
23,994,901✔
1510
    return TSDB_CODE_SUCCESS;
1,441,591✔
1511
  }
1512

1513
  // Allocate the additional buffer.
1514
  uint32_t rows = pDataBlock->info.rows;
22,553,310✔
1515

1516
  bool sortColumnHasNull = false;
22,553,310✔
1517
  bool varTypeSort = false;
22,553,310✔
1518

1519
  for (int32_t i = 0; i < taosArrayGetSize(pOrderInfo); ++i) {
54,833,951✔
1520
    SBlockOrderInfo* pInfo = taosArrayGet(pOrderInfo, i);
32,280,641✔
1521
    if (pInfo == NULL) {
32,280,641✔
1522
      continue;
×
1523
    }
1524

1525
    SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, pInfo->slotId);
32,280,641✔
1526
    if (pColInfoData == NULL) {
32,280,641✔
1527
      continue;
×
1528
    }
1529

1530
    if (pColInfoData->hasNull) {
32,280,641✔
1531
      sortColumnHasNull = true;
32,260,987✔
1532
    }
1533

1534
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
32,280,641✔
1535
      varTypeSort = true;
18,299,441✔
1536
    }
1537
  }
1538

1539
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
22,553,310✔
1540

1541
  if (taosArrayGetSize(pOrderInfo) == 1 && (!sortColumnHasNull)) {
22,553,310✔
1542
    if (numOfCols == 1) {
16,762✔
1543
      if (!varTypeSort) {
×
1544
        SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, 0);
×
1545
        SBlockOrderInfo* pOrder = taosArrayGet(pOrderInfo, 0);
×
1546
        if (pColInfoData == NULL || pOrder == NULL) {
×
1547
          return terrno;
×
1548
        }
1549

1550
        int64_t p0 = taosGetTimestampUs();
×
1551

1552
        __compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order);
×
1553
        taosSort(pColInfoData->pData, pDataBlock->info.rows, pColInfoData->info.bytes, fn);
×
1554

1555
        int64_t p1 = taosGetTimestampUs();
×
1556
        uDebug("blockDataSort easy cost:%" PRId64 ", rows:%" PRId64 "\n", p1 - p0, pDataBlock->info.rows);
×
1557

1558
        return TSDB_CODE_SUCCESS;
×
1559
      } else {  // var data type
1560
      }
1561
    } else if (numOfCols == 2) {
1562
    }
1563
  }
1564

1565
  int32_t* index = createTupleIndex(rows);
22,553,310✔
1566
  if (index == NULL) {
22,552,779✔
1567
    return terrno;
×
1568
  }
1569

1570
  int64_t p0 = taosGetTimestampUs();
22,552,779✔
1571

1572
  SSDataBlockSortHelper helper = {.pDataBlock = pDataBlock, .orderInfo = pOrderInfo};
22,552,779✔
1573
  for (int32_t i = 0; i < taosArrayGetSize(helper.orderInfo); ++i) {
54,832,889✔
1574
    struct SBlockOrderInfo* pInfo = taosArrayGet(helper.orderInfo, i);
32,280,641✔
1575
    if (pInfo == NULL) {
32,280,641✔
1576
      continue;
×
1577
    }
1578

1579
    pInfo->pColData = taosArrayGet(pDataBlock->pDataBlock, pInfo->slotId);
32,280,641✔
1580
    if (pInfo->pColData == NULL) {
32,280,641✔
1581
      continue;
×
1582
    }
1583
    pInfo->compFn = getKeyComparFunc(pInfo->pColData->info.type, pInfo->order);
32,280,110✔
1584
  }
1585

1586
  terrno = 0;
22,552,779✔
1587
  taosqsort_r(index, rows, sizeof(int32_t), &helper, dataBlockCompar);
22,553,310✔
1588
  if (terrno) {
22,553,310✔
1589
    destroyTupleIndex(index);
504✔
1590
    return terrno;
504✔
1591
  }
1592

1593
  int64_t p1 = taosGetTimestampUs();
22,552,806✔
1594

1595
  SColumnInfoData* pCols = NULL;
22,552,806✔
1596
  int32_t          code = createHelpColInfoData(pDataBlock, &pCols);
22,552,275✔
1597
  if (code != 0) {
22,551,870✔
1598
    destroyTupleIndex(index);
×
1599
    return code;
×
1600
  }
1601

1602
  int64_t p2 = taosGetTimestampUs();
22,551,465✔
1603
  blockDataAssign(pCols, pDataBlock, index);
22,551,465✔
1604

1605
  int64_t p3 = taosGetTimestampUs();
22,551,189✔
1606
  copyBackToBlock(pDataBlock, pCols);
22,551,189✔
1607

1608
  int64_t p4 = taosGetTimestampUs();
22,549,040✔
1609
  uDebug("blockDataSort complex sort:%" PRId64 ", create:%" PRId64 ", assign:%" PRId64 ", copyback:%" PRId64
22,549,040✔
1610
         ", rows:%d\n",
1611
         p1 - p0, p2 - p1, p3 - p2, p4 - p3, rows);
1612

1613
  destroyTupleIndex(index);
22,549,040✔
1614
  return TSDB_CODE_SUCCESS;
22,552,353✔
1615
}
1616

1617
void blockDataCleanup(SSDataBlock* pDataBlock) {
2,147,483,647✔
1618
  if(pDataBlock == NULL) {
2,147,483,647✔
1619
    return;
60,256✔
1620
  }
1621
  blockDataEmpty(pDataBlock);
2,147,483,647✔
1622
  SDataBlockInfo* pInfo = &pDataBlock->info;
2,147,483,647✔
1623
  pInfo->id.uid = 0;
2,147,483,647✔
1624
  pInfo->id.groupId = 0;
2,147,483,647✔
1625
}
1626

1627
void blockDataEmpty(SSDataBlock* pDataBlock) {
2,147,483,647✔
1628
  if (pDataBlock == NULL) {
2,147,483,647✔
1629
    return;
733,782✔
1630
  }
1631
  SDataBlockInfo* pInfo = &pDataBlock->info;
2,147,483,647✔
1632
  if (pInfo->capacity == 0) {
2,147,483,647✔
1633
    return;
903,694,236✔
1634
  }
1635

1636
  taosMemoryFreeClear(pDataBlock->pBlockAgg);
2,147,483,647✔
1637

1638
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
2,147,483,647✔
1639
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
1640
    SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
2,147,483,647✔
1641
    if (p == NULL) {
2,147,483,647✔
1642
      continue;
×
1643
    }
1644

1645
    colInfoDataCleanup(p, pInfo->capacity);
2,147,483,647✔
1646
  }
1647

1648
  pInfo->rows = 0;
2,147,483,647✔
1649
  pInfo->dataLoad = 0;
2,147,483,647✔
1650
  pInfo->window.ekey = 0;
2,147,483,647✔
1651
  pInfo->window.skey = 0;
2,147,483,647✔
1652
}
1653

1654
void blockDataReset(SSDataBlock* pDataBlock) {
2,295,953✔
1655
  SDataBlockInfo* pInfo = &pDataBlock->info;
2,295,953✔
1656
  if (pInfo->capacity == 0) {
2,295,953✔
1657
    return;
×
1658
  }
1659

1660
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
2,295,953✔
1661
  for (int32_t i = 0; i < numOfCols; ++i) {
10,046,949✔
1662
    SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
7,750,996✔
1663
    if (p == NULL) {
7,750,996✔
1664
      continue;
×
1665
    }
1666

1667
    p->hasNull = false;
7,750,996✔
1668
    p->reassigned = false;
7,750,996✔
1669
    if (IS_VAR_DATA_TYPE(p->info.type)) {
7,750,996✔
1670
      p->varmeta.length = 0;
1,058,087✔
1671
    }
1672
  }
1673

1674
  pInfo->rows = 0;
2,295,953✔
1675
  pInfo->dataLoad = 0;
2,295,953✔
1676
  pInfo->window.ekey = 0;
2,295,953✔
1677
  pInfo->window.skey = 0;
2,295,953✔
1678
  pInfo->id.uid = 0;
2,295,953✔
1679
  pInfo->id.groupId = 0;
2,295,953✔
1680
}
1681

1682
/*
1683
 * NOTE: the type of the input column may be TSDB_DATA_TYPE_NULL, which is used to denote
1684
 * the all NULL value in this column. It is an internal representation of all NULL value column, and no visible to
1685
 * any users. The length of TSDB_DATA_TYPE_NULL is 0, and it is an special case.
1686
 */
1687
int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo* pBlockInfo, uint32_t numOfRows,
2,147,483,647✔
1688
                         bool clearPayload) {
1689
  if ((numOfRows <= 0) || (pBlockInfo && numOfRows <= pBlockInfo->capacity)) {
2,147,483,647✔
1690
    return TSDB_CODE_SUCCESS;
×
1691
  }
1692

1693
  int32_t existedRows = pBlockInfo ? pBlockInfo->rows : 0;
2,147,483,647✔
1694

1695
  if (IS_VAR_DATA_TYPE(pColumn->info.type)) {
2,147,483,647✔
1696
    char* tmp = taosMemoryRealloc(pColumn->varmeta.offset, sizeof(int32_t) * numOfRows);
2,147,483,647✔
1697
    if (tmp == NULL) {
2,147,483,647✔
1698
      return terrno;
×
1699
    }
1700

1701
    pColumn->varmeta.offset = (int32_t*)tmp;
2,147,483,647✔
1702
    memset(&pColumn->varmeta.offset[existedRows], 0, sizeof(int32_t) * (numOfRows - existedRows));
2,147,483,647✔
1703
  } else {
1704
    // prepare for the null bitmap
1705
    char* tmp = taosMemoryRealloc(pColumn->nullbitmap, BitmapLen(numOfRows));
2,147,483,647✔
1706
    if (tmp == NULL) {
2,147,483,647✔
1707
      return terrno;
×
1708
    }
1709

1710
    int32_t oldLen = BitmapLen(existedRows);
2,147,483,647✔
1711
    pColumn->nullbitmap = tmp;
2,147,483,647✔
1712
    memset(&pColumn->nullbitmap[oldLen], 0, BitmapLen(numOfRows) - oldLen);
2,147,483,647✔
1713
    if (pColumn->info.bytes == 0) {
2,147,483,647✔
1714
      return TSDB_CODE_INVALID_PARA;
×
1715
    }
1716

1717
    // here we employ the aligned malloc function, to make sure that the address of allocated memory is aligned
1718
    // to MALLOC_ALIGN_BYTES
1719
    tmp = taosMemoryMallocAlign(MALLOC_ALIGN_BYTES, numOfRows * pColumn->info.bytes);
2,147,483,647✔
1720
    if (tmp == NULL) {
2,147,483,647✔
1721
      return terrno;
×
1722
    }
1723
    // memset(tmp, 0, numOfRows * pColumn->info.bytes);
1724

1725
    // copy back the existed data
1726
    if (pColumn->pData != NULL) {
2,147,483,647✔
1727
      memcpy(tmp, pColumn->pData, existedRows * pColumn->info.bytes);
671,299,722✔
1728
      taosMemoryFreeClear(pColumn->pData);
671,315,493✔
1729
    }
1730

1731
    pColumn->pData = tmp;
2,147,483,647✔
1732

1733
    // check if the allocated memory is aligned to the requried bytes.
1734
#if defined LINUX
1735
    if ((((uint64_t)pColumn->pData) & (MALLOC_ALIGN_BYTES - 1)) != 0x0) {
2,147,483,647✔
1736
      return TSDB_CODE_FAILED;
×
1737
    }
1738
#endif
1739

1740
    if (clearPayload) {
2,147,483,647✔
1741
      memset(tmp + pColumn->info.bytes * existedRows, 0, pColumn->info.bytes * (numOfRows - existedRows));
2,147,483,647✔
1742
    }
1743
  }
1744

1745
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
1746
}
1747

1748
void colInfoDataCleanup(SColumnInfoData* pColumn, uint32_t numOfRows) {
2,147,483,647✔
1749
  pColumn->hasNull = false;
2,147,483,647✔
1750

1751
  if (IS_VAR_DATA_TYPE(pColumn->info.type)) {
2,147,483,647✔
1752
    pColumn->varmeta.length = 0;
2,147,483,647✔
1753
    if (pColumn->varmeta.offset != NULL) {
2,147,483,647✔
1754
      memset(pColumn->varmeta.offset, 0, sizeof(int32_t) * numOfRows);
2,147,483,647✔
1755
    }
1756
  } else {
1757
    if (pColumn->nullbitmap != NULL) {
2,147,483,647✔
1758
      memset(pColumn->nullbitmap, 0, BitmapLen(numOfRows));
2,147,483,647✔
1759
    }
1760
  }
1761
}
2,147,483,647✔
1762

1763
int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, uint32_t numOfRows, bool clearPayload) {
2,147,483,647✔
1764
  SDataBlockInfo info = {0};
2,147,483,647✔
1765
  return doEnsureCapacity(pColumn, &info, numOfRows, clearPayload);
2,147,483,647✔
1766
}
1767

1768
int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows) {
2,147,483,647✔
1769
  int32_t code = 0;
2,147,483,647✔
1770
  if (numOfRows == 0 || numOfRows <= pDataBlock->info.capacity) {
2,147,483,647✔
1771
    return TSDB_CODE_SUCCESS;
2,147,483,647✔
1772
  }
1773

1774
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
2,147,483,647✔
1775
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
1776
    SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
2,147,483,647✔
1777
    if (p == NULL) {
2,147,483,647✔
1778
      return terrno;
×
1779
    }
1780

1781
    code = doEnsureCapacity(p, &pDataBlock->info, numOfRows, false);
2,147,483,647✔
1782
    if (code) {
2,147,483,647✔
1783
      return code;
×
1784
    }
1785
  }
1786

1787
  pDataBlock->info.capacity = numOfRows;
2,147,483,647✔
1788
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
1789
}
1790

1791
void blockDataFreeRes(SSDataBlock* pBlock) {
2,147,483,647✔
1792
  if (pBlock == NULL) {
2,147,483,647✔
1793
    return;
44,884,489✔
1794
  }
1795

1796
  int32_t numOfOutput = taosArrayGetSize(pBlock->pDataBlock);
2,147,483,647✔
1797
  for (int32_t i = 0; i < numOfOutput; ++i) {
2,147,483,647✔
1798
    SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
2,147,483,647✔
1799
    if (pColInfoData == NULL) {
2,147,483,647✔
1800
      continue;
×
1801
    }
1802

1803
    colDataDestroy(pColInfoData);
2,147,483,647✔
1804
  }
1805

1806
  taosArrayDestroy(pBlock->pDataBlock);
2,147,483,647✔
1807
  pBlock->pDataBlock = NULL;
2,147,483,647✔
1808

1809
  taosMemoryFreeClear(pBlock->pBlockAgg);
2,147,483,647✔
1810
  memset(&pBlock->info, 0, sizeof(SDataBlockInfo));
2,147,483,647✔
1811
}
1812

1813
void blockDataFreeCols(SSDataBlock* pBlock) {
×
1814
  if (pBlock == NULL) {
×
1815
    return;
×
1816
  }
1817

1818
  int32_t numOfOutput = taosArrayGetSize(pBlock->pDataBlock);
×
1819
  for (int32_t i = 0; i < numOfOutput; ++i) {
×
1820
    SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
×
1821
    if (pColInfoData == NULL) {
×
1822
      continue;
×
1823
    }
1824

1825
    colDataDestroy(pColInfoData);
×
1826
  }
1827

1828
  taosMemoryFreeClear(pBlock->pBlockAgg);
×
1829
  memset(&pBlock->info, 0, sizeof(SDataBlockInfo));
×
1830
}
1831

1832
void blockDataDestroy(SSDataBlock* pBlock) {
2,147,483,647✔
1833
  if (pBlock == NULL) {
2,147,483,647✔
1834
    return;
357,372,687✔
1835
  }
1836

1837
  if (IS_VAR_DATA_TYPE(pBlock->info.pks[0].type)) {
2,147,483,647✔
1838
    taosMemoryFreeClear(pBlock->info.pks[0].pData);
13,501,960✔
1839
    taosMemoryFreeClear(pBlock->info.pks[1].pData);
13,510,885✔
1840
  }
1841

1842
  blockDataFreeRes(pBlock);
2,147,483,647✔
1843
  taosMemoryFreeClear(pBlock);
2,147,483,647✔
1844
}
1845

1846
// todo remove it
1847
int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src) {
×
1848
  int32_t code = 0;
×
1849

1850
  dst->info = src->info;
×
1851
  dst->info.pks[0].pData = NULL;
×
1852
  dst->info.pks[1].pData = NULL;
×
1853
  dst->info.rows = 0;
×
1854
  dst->info.capacity = 0;
×
1855

1856
  size_t numOfCols = taosArrayGetSize(src->pDataBlock);
×
1857
  for (int32_t i = 0; i < numOfCols; ++i) {
×
1858
    SColumnInfoData* p = taosArrayGet(src->pDataBlock, i);
×
1859
    if (p == NULL) {
×
1860
      return terrno;
×
1861
    }
1862

1863
    SColumnInfoData colInfo = {.hasNull = true, .info = p->info};
×
1864
    code = blockDataAppendColInfo(dst, &colInfo);
×
1865
    if (code) {
×
1866
      return code;
×
1867
    }
1868
  }
1869

1870
  code = blockDataEnsureCapacity(dst, src->info.rows);
×
1871
  if (code != TSDB_CODE_SUCCESS) {
×
1872
    return code;
×
1873
  }
1874

1875
  for (int32_t i = 0; i < numOfCols; ++i) {
×
1876
    SColumnInfoData* pDst = taosArrayGet(dst->pDataBlock, i);
×
1877
    SColumnInfoData* pSrc = taosArrayGet(src->pDataBlock, i);
×
1878
    if (pSrc == NULL || pDst == NULL || (pSrc->pData == NULL && (!IS_VAR_DATA_TYPE(pSrc->info.type)))) {
×
1879
      continue;
×
1880
    }
1881

1882
    int32_t ret = colDataAssign(pDst, pSrc, src->info.rows, &src->info);
×
1883
    if (ret < 0) {
×
1884
      return ret;
×
1885
    }
1886
  }
1887

1888
  uint32_t cap = dst->info.capacity;
×
1889
  dst->info = src->info;
×
1890
  dst->info.pks[0].pData = NULL;
×
1891
  dst->info.pks[1].pData = NULL;
×
1892
  dst->info.capacity = cap;
×
1893
  uTrace("%s,parName:%s, groupId:%"PRIu64, __FUNCTION__, dst->info.parTbName, dst->info.id.groupId)
×
1894
  return code;
×
1895
}
1896

1897
int32_t copyDataBlock(SSDataBlock* pDst, const SSDataBlock* pSrc) {
170,102,900✔
1898
  blockDataCleanup(pDst);
170,102,900✔
1899

1900
  int32_t code = blockDataEnsureCapacity(pDst, pSrc->info.rows);
170,101,898✔
1901
  if (code != TSDB_CODE_SUCCESS) {
170,106,173✔
1902
    return code;
×
1903
  }
1904

1905
  size_t numOfCols = taosArrayGetSize(pSrc->pDataBlock);
170,106,173✔
1906
  for (int32_t i = 0; i < numOfCols; ++i) {
1,275,650,904✔
1907
    SColumnInfoData* pDstCol = taosArrayGet(pDst->pDataBlock, i);
1,105,546,438✔
1908
    SColumnInfoData* pSrcCol = taosArrayGet(pSrc->pDataBlock, i);
1,105,936,214✔
1909
    if (pDstCol == NULL || pSrcCol == NULL) {
1,105,881,419✔
1910
      continue;
×
1911
    }
1912

1913
    int32_t ret = colDataAssign(pDstCol, pSrcCol, pSrc->info.rows, &pSrc->info);
1,105,881,419✔
1914
    if (ret < 0) {
1,105,496,211✔
1915
      code = ret;
×
1916
      return code;
×
1917
    }
1918
  }
1919

1920
  uint32_t cap = pDst->info.capacity;
170,104,466✔
1921

1922
  if (IS_VAR_DATA_TYPE(pDst->info.pks[0].type)) {
170,104,997✔
1923
    taosMemoryFreeClear(pDst->info.pks[0].pData);
305✔
1924
  }
1925

1926
  if (IS_VAR_DATA_TYPE(pDst->info.pks[1].type)) {
170,108,839✔
1927
    taosMemoryFreeClear(pDst->info.pks[1].pData);
214✔
1928
  }
1929

1930
  pDst->info = pSrc->info;
170,106,148✔
1931
  code = copyPkVal(&pDst->info, &pSrc->info);
170,107,998✔
1932
  if (code != TSDB_CODE_SUCCESS) {
170,105,068✔
1933
    uError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
1934
    return code;
×
1935
  }
1936

1937
  pDst->info.capacity = cap;
170,105,068✔
1938
  return code;
170,105,446✔
1939
}
1940

1941
int32_t blockCopyOneRow(const SSDataBlock* pDataBlock, int32_t rowIdx, SSDataBlock** pResBlock) {
×
1942
  QRY_PARAM_CHECK(pResBlock);
×
1943

1944
  if (pDataBlock == NULL) {
×
1945
    return TSDB_CODE_INVALID_PARA;
×
1946
  }
1947

1948
  SSDataBlock* pBlock = NULL;
×
1949
  int32_t      code = createDataBlock(&pBlock);
×
1950
  if (code) {
×
1951
    return code;
×
1952
  }
1953

1954
  pBlock->info = pDataBlock->info;
×
1955
  pBlock->info.pks[0].pData = NULL;
×
1956
  pBlock->info.pks[1].pData = NULL;
×
1957
  pBlock->info.rows = 0;
×
1958
  pBlock->info.capacity = 0;
×
1959

1960
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
×
1961
  for (int32_t i = 0; i < numOfCols; ++i) {
×
1962
    SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
×
1963
    if (p == NULL) {
×
1964
      blockDataDestroy(pBlock);
×
1965
      return terrno;
×
1966
    }
1967

1968
    SColumnInfoData colInfo = {.hasNull = true, .info = p->info};
×
1969
    code = blockDataAppendColInfo(pBlock, &colInfo);
×
1970
    if (code) {
×
1971
      blockDataDestroy(pBlock);
×
1972
      return code;
×
1973
    }
1974
  }
1975

1976
  code = blockDataEnsureCapacity(pBlock, 1);
×
1977
  if (code != TSDB_CODE_SUCCESS) {
×
1978
    blockDataDestroy(pBlock);
×
1979
    return code;
×
1980
  }
1981

1982
  for (int32_t i = 0; i < numOfCols; ++i) {
×
1983
    SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i);
×
1984
    SColumnInfoData* pSrc = taosArrayGet(pDataBlock->pDataBlock, i);
×
1985
    if (pDst == NULL || pSrc == NULL) {
×
1986
      blockDataDestroy(pBlock);
×
1987
      return terrno;
×
1988
    }
1989

1990
    bool  isNull = colDataIsNull(pSrc, pDataBlock->info.rows, rowIdx, NULL);
×
1991
    void* pData = NULL;
×
1992
    if (!isNull) {
×
1993
      pData = colDataGetData(pSrc, rowIdx);
×
1994
    }
1995

1996
    code = colDataSetVal(pDst, 0, pData, isNull);
×
1997
    if (code) {
×
1998
      blockDataDestroy(pBlock);
×
1999
      return code;
×
2000
    }
2001
  }
2002

2003
  pBlock->info.rows = 1;
×
2004

2005
  *pResBlock = pBlock;
×
2006
  return code;
×
2007
}
2008

2009
int32_t copyPkVal(SDataBlockInfo* pDst, const SDataBlockInfo* pSrc) {
1,919,534,992✔
2010
  int32_t code = TSDB_CODE_SUCCESS;
1,919,534,992✔
2011
  int32_t lino = 0;
1,919,534,992✔
2012
  if (!IS_VAR_DATA_TYPE(pSrc->pks[0].type)) {
1,919,534,992✔
2013
    return code;
1,912,724,114✔
2014
  }
2015

2016
  // prepare the pk buffer if needed
2017
  SValue* p = &pDst->pks[0];
6,990,592✔
2018

2019
  p->type = pSrc->pks[0].type;
7,022,832✔
2020
  p->pData = taosMemoryCalloc(1, pSrc->pks[0].nData);
7,021,452✔
2021
  QUERY_CHECK_NULL(p->pData, code, lino, _end, terrno);
7,019,487✔
2022

2023
  p->nData = pSrc->pks[0].nData;
7,020,162✔
2024
  memcpy(p->pData, pSrc->pks[0].pData, p->nData);
7,021,512✔
2025

2026
  p = &pDst->pks[1];
7,021,512✔
2027
  p->type = pSrc->pks[1].type;
7,024,152✔
2028
  p->pData = taosMemoryCalloc(1, pSrc->pks[1].nData);
7,022,127✔
2029
  QUERY_CHECK_NULL(p->pData, code, lino, _end, terrno);
7,018,842✔
2030

2031
  p->nData = pSrc->pks[1].nData;
7,018,167✔
2032
  memcpy(p->pData, pSrc->pks[1].pData, p->nData);
7,021,482✔
2033

2034
_end:
7,021,452✔
2035
  if (code != TSDB_CODE_SUCCESS) {
7,021,452✔
2036
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2037
  }
2038
  return code;
7,021,452✔
2039
}
2040

2041
int32_t createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData, SSDataBlock** pResBlock) {
1,749,329,464✔
2042
  int32_t code = 0, lino = 0;
1,749,329,464✔
2043
  QRY_PARAM_CHECK(pResBlock);
1,749,329,464✔
2044
  TSDB_CHECK_NULL(pDataBlock, code, lino, _exit, TSDB_CODE_INVALID_PARA);
1,749,593,820✔
2045

2046
  SSDataBlock* pDstBlock = NULL;
1,749,593,820✔
2047
  TAOS_CHECK_EXIT(createDataBlock(&pDstBlock));
1,749,454,143✔
2048

2049
  pDstBlock->info = pDataBlock->info;
1,749,353,032✔
2050
  pDstBlock->info.pks[0].pData = NULL;
1,749,390,071✔
2051
  pDstBlock->info.pks[1].pData = NULL;
1,749,633,660✔
2052

2053
  pDstBlock->info.rows = 0;
1,749,733,919✔
2054
  pDstBlock->info.capacity = 0;
1,749,723,046✔
2055
  pDstBlock->info.rowSize = 0;
1,749,714,479✔
2056
  pDstBlock->info.id = pDataBlock->info.id;
1,749,581,710✔
2057
  pDstBlock->info.blankFill = pDataBlock->info.blankFill;
1,749,728,192✔
2058

2059
  size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
1,749,544,242✔
2060
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
2061
    SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
2,147,483,647✔
2062
    if (p == NULL) {
2,147,483,647✔
2063
      blockDataDestroy(pDstBlock);
×
2064
      TSDB_CHECK_NULL(p, code, lino, _exit, terrno);
×
2065
    }
2066

2067
    SColumnInfoData colInfo = {.hasNull = true, .info = p->info};
2,147,483,647✔
2068
    code = blockDataAppendColInfo(pDstBlock, &colInfo);
2,147,483,647✔
2069
    if (code) {
2,147,483,647✔
2070
      blockDataDestroy(pDstBlock);
×
2071
      TAOS_CHECK_EXIT(code);
×
2072
    }
2073
  }
2074

2075
  code = copyPkVal(&pDstBlock->info, &pDataBlock->info);
1,749,764,142✔
2076
  if (code != TSDB_CODE_SUCCESS) {
1,749,532,560✔
2077
    blockDataDestroy(pDstBlock);
×
2078
    uError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
2079
    TAOS_CHECK_EXIT(code);
×
2080
  }
2081

2082
  if (copyData) {
1,749,532,560✔
2083
    code = blockDataEnsureCapacity(pDstBlock, pDataBlock->info.rows);
866,680,902✔
2084
    if (code != TSDB_CODE_SUCCESS) {
866,789,536✔
2085
      blockDataDestroy(pDstBlock);
×
2086
      TAOS_CHECK_EXIT(code);
×
2087
    }
2088

2089
    for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
2090
      SColumnInfoData* pDst = taosArrayGet(pDstBlock->pDataBlock, i);
2,147,483,647✔
2091
      SColumnInfoData* pSrc = taosArrayGet(pDataBlock->pDataBlock, i);
2,147,483,647✔
2092
      if (pDst == NULL) {
2,147,483,647✔
2093
        blockDataDestroy(pDstBlock);
×
2094
        uError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
2095
        TSDB_CHECK_NULL(pDst, code, lino, _exit, terrno);
×
2096
      }
2097

2098
      if (pSrc == NULL) {
2,147,483,647✔
2099
        blockDataDestroy(pDstBlock);
×
2100
        uError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
2101
        TSDB_CHECK_NULL(pSrc, code, lino, _exit, terrno);
×
2102
      }
2103

2104
      int32_t ret = colDataAssign(pDst, pSrc, pDataBlock->info.rows, &pDataBlock->info);
2,147,483,647✔
2105
      if (ret < 0) {
2,147,483,647✔
2106
        code = ret;
×
2107
        blockDataDestroy(pDstBlock);
×
2108
        TAOS_CHECK_EXIT(code);
×
2109
      }
2110
    }
2111

2112
    pDstBlock->info.rows = pDataBlock->info.rows;
866,900,908✔
2113
    pDstBlock->info.capacity = pDataBlock->info.rows;
866,797,085✔
2114
  }
2115

2116
  *pResBlock = pDstBlock;
1,749,663,969✔
2117

2118
_exit:
1,749,511,259✔
2119
  
2120
  return code;
1,749,667,120✔
2121
}
2122

2123
int32_t createOneDataBlockWithColArray(const SSDataBlock* pDataBlock, SArray* pColArray, SSDataBlock** pResBlock) {
117,672,341✔
2124
  int32_t      code = TSDB_CODE_SUCCESS;
117,672,341✔
2125
  int32_t      lino = 0;
117,672,341✔
2126
  SSDataBlock* pDstBlock = NULL;
117,672,341✔
2127

2128
  QRY_PARAM_CHECK(pResBlock);
117,692,459✔
2129
  QUERY_CHECK_NULL(pDataBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
117,708,128✔
2130

2131
  QUERY_CHECK_CODE(createDataBlock(&pDstBlock), lino, _return);
117,708,128✔
2132

2133
  pDstBlock->info = pDataBlock->info;
117,717,613✔
2134
  pDstBlock->info.pks[0].pData = NULL;
117,723,581✔
2135
  pDstBlock->info.pks[1].pData = NULL;
117,735,569✔
2136

2137
  pDstBlock->info.rows = 0;
117,743,627✔
2138
  pDstBlock->info.capacity = 0;
117,742,454✔
2139
  pDstBlock->info.rowSize = 0;
117,740,612✔
2140
  pDstBlock->info.id = pDataBlock->info.id;
117,725,018✔
2141
  pDstBlock->info.blankFill = pDataBlock->info.blankFill;
117,735,258✔
2142

2143
  for (int32_t i = 0; i < taosArrayGetSize(pColArray); ++i) {
478,298,261✔
2144
    SColIdSlotIdPair* pColPair = taosArrayGet(pColArray, i);
360,569,859✔
2145
    QUERY_CHECK_NULL(pColPair, code, lino, _return, terrno);
360,574,416✔
2146

2147
    SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, pColPair->vtbSlotId);
360,574,416✔
2148
    QUERY_CHECK_NULL(p, code, lino, _return, terrno);
360,567,471✔
2149

2150
    SColumnInfoData pColInfo = {.hasNull = true, .info = p->info};
360,567,471✔
2151
    pColInfo.info.colId = pColPair->orgColId;
360,575,817✔
2152
    QUERY_CHECK_CODE(blockDataAppendColInfo(pDstBlock, &pColInfo), lino, _return);
360,583,463✔
2153
  }
2154

2155
  *pResBlock = pDstBlock;
117,727,433✔
2156
  return code;
117,742,379✔
2157
_return:
×
2158
  uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2159
  blockDataDestroy(pDstBlock);
×
2160
  return code;
×
2161
}
2162

2163
// create a new data block based on the template block, and fill data from the source block according to the column mapping
2164
int32_t createOneDataBlockWithTwoBlock(const SSDataBlock* pSrcBlock, const SSDataBlock* pTemplateBlock, SArray* pColMap,
71,401,439✔
2165
                                       SSDataBlock** pResBlock) {
2166
  int32_t      code = TSDB_CODE_SUCCESS;
71,401,439✔
2167
  int32_t      lino = 0;
71,401,439✔
2168
  SSDataBlock* pDstBlock = NULL;
71,401,439✔
2169

2170
  QRY_PARAM_CHECK(pResBlock);
71,422,193✔
2171
  QUERY_CHECK_NULL(pSrcBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
71,440,406✔
2172
  QUERY_CHECK_NULL(pTemplateBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
71,440,406✔
2173
  QUERY_CHECK_NULL(pColMap, code, lino, _return, TSDB_CODE_INVALID_PARA);
71,440,406✔
2174

2175
  code = createOneDataBlock(pTemplateBlock, false, &pDstBlock);
71,440,406✔
2176
  QUERY_CHECK_CODE(code, lino, _return);
71,454,197✔
2177
  code = blockDataEnsureCapacity(pDstBlock, pSrcBlock->info.rows);
71,454,197✔
2178
  QUERY_CHECK_CODE(code, lino, _return);
71,456,081✔
2179

2180
  if (pSrcBlock->pBlockAgg) {
71,456,081✔
2181
    size_t num = taosArrayGetSize(pDstBlock->pDataBlock);
18,163,686✔
2182
    pDstBlock->pBlockAgg = taosMemoryCalloc(num, sizeof(SColumnDataAgg));
18,168,702✔
2183
    QUERY_CHECK_NULL(pDstBlock->pBlockAgg, code, lino, _return, terrno);
18,156,126✔
2184
    for (int i = 0; i < num; ++i) {
148,769,877✔
2185
      pDstBlock->pBlockAgg[i].colId = i;
130,531,110✔
2186
      pDstBlock->pBlockAgg[i].numOfNull = pSrcBlock->info.rows;
130,571,025✔
2187
    }
2188
  } else {
2189
    for (int32_t i = 0; i < taosArrayGetSize(pDstBlock->pDataBlock); ++i) {
684,035,610✔
2190
      SColumnInfoData* pDst = taosArrayGet(pDstBlock->pDataBlock, i);
630,734,920✔
2191
      QUERY_CHECK_NULL(pDst, code, lino, _return, terrno);
630,736,237✔
2192
      colDataSetNNULL(pDst, 0, pSrcBlock->info.rows);
630,736,237✔
2193
    }
2194
  }
2195

2196
  for (int32_t i = 0; i < taosArrayGetSize(pColMap); i++) {
309,146,362✔
2197
    SColIdSlotIdPair* pColPair = taosArrayGet(pColMap, i);
237,696,560✔
2198
    QUERY_CHECK_NULL(pColPair, code, lino, _return, terrno);
237,701,594✔
2199
    for (int32_t j = 0; j < taosArrayGetSize(pSrcBlock->pDataBlock); j++) {
1,152,776,249✔
2200
      SColumnInfoData* pSrcCol = taosArrayGet(pSrcBlock->pDataBlock, j);
915,001,188✔
2201
      QUERY_CHECK_NULL(pSrcCol, code, lino, _return, terrno);
915,094,236✔
2202
      if (pSrcCol->info.colId == pColPair->orgColId) {
915,094,236✔
2203
        SColumnInfoData* pDstCol = taosArrayGet(pDstBlock->pDataBlock, pColPair->vtbSlotId);
237,698,495✔
2204
        QUERY_CHECK_NULL(pDstCol, code, lino, _return, terrno);
237,698,486✔
2205
        if (pSrcBlock->pBlockAgg) {
237,698,486✔
2206
          (void)memcpy(&pDstBlock->pBlockAgg[pColPair->vtbSlotId], &pSrcBlock->pBlockAgg[j], sizeof(SColumnDataAgg));
50,133,810✔
2207
          pDstBlock->pBlockAgg[pColPair->vtbSlotId].numOfNull = 0;
50,130,039✔
2208
        } else {
2209
          QUERY_CHECK_CODE(colDataAssign(pDstCol, pSrcCol, (int32_t)pSrcBlock->info.rows, &pSrcBlock->info), lino, _return);
187,562,786✔
2210
        }
2211
      }
2212
    }
2213
  }
2214

2215
  pDstBlock->info.rows = pSrcBlock->info.rows;
71,437,817✔
2216
  pDstBlock->info.capacity = pSrcBlock->info.rows;
71,462,987✔
2217
  pDstBlock->info.window = pSrcBlock->info.window;
71,462,351✔
2218
  pDstBlock->info.dataLoad = pSrcBlock->info.dataLoad;
71,461,097✔
2219
  pDstBlock->info.scanFlag = pSrcBlock->info.scanFlag;
71,462,987✔
2220

2221
  *pResBlock = pDstBlock;
71,462,369✔
2222
  return code;
71,459,852✔
2223
_return:
×
2224
  uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2225
  blockDataDestroy(pDstBlock);
×
2226
  return code;
×
2227
}
2228

2229
int32_t createDataBlock(SSDataBlock** pResBlock) {
2,147,483,647✔
2230
  QRY_PARAM_CHECK(pResBlock);
2,147,483,647✔
2231
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
2,147,483,647✔
2232
  if (pBlock == NULL) {
2,147,483,647✔
2233
    return terrno;
×
2234
  }
2235

2236
  pBlock->pDataBlock = taosArrayInit(4, sizeof(SColumnInfoData));
2,147,483,647✔
2237
  if (pBlock->pDataBlock == NULL) {
2,147,483,647✔
2238
    int32_t code = terrno;
192✔
2239
    taosMemoryFree(pBlock);
×
2240
    return code;
×
2241
  }
2242

2243
  *pResBlock = pBlock;
2,147,483,647✔
2244
  return 0;
2,147,483,647✔
2245
}
2246

2247
int32_t blockDataAppendColInfo(SSDataBlock* pBlock, SColumnInfoData* pColInfoData) {
2,147,483,647✔
2248
  if (pBlock->pDataBlock == NULL) {
2,147,483,647✔
2249
    pBlock->pDataBlock = taosArrayInit(4, sizeof(SColumnInfoData));
45,363,170✔
2250
    if (pBlock->pDataBlock == NULL) {
45,339,074✔
2251
      return terrno;
×
2252
    }
2253
  }
2254

2255
  void* p = taosArrayPush(pBlock->pDataBlock, pColInfoData);
2,147,483,647✔
2256
  if (p == NULL) {
2,147,483,647✔
2257
    return terrno;
×
2258
  }
2259

2260
  // todo disable it temporarily
2261
  //  A S S E R T(pColInfoData->info.type != 0);
2262
  if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
2,147,483,647✔
2263
    pBlock->info.hasVarCol = true;
2,147,483,647✔
2264
  }
2265
  pBlock->info.rowSize += pColInfoData->info.bytes;
2,147,483,647✔
2266

2267
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
2268
}
2269

2270
SColumnInfoData createColumnInfoData(int16_t type, int32_t bytes, int16_t colId) {
2,147,483,647✔
2271
  SColumnInfoData col = {.hasNull = true};
2,147,483,647✔
2272
  col.info.colId = colId;
2,147,483,647✔
2273
  col.info.type = type;
2,147,483,647✔
2274
  col.info.bytes = bytes;
2,147,483,647✔
2275
  // if (type == TSDB_DATA_TYPE_BLOB || type == TSDB_DATA_TYPE_MEDIUMBLOB) {
2276
  //   col.info.bytes = TSDB_MAX_BLOB_LEN;
2277
  // }
2278
  return col;
2,147,483,647✔
2279
}
2280

2281
int32_t bdGetColumnInfoData(const SSDataBlock* pBlock, int32_t index, SColumnInfoData** pColInfoData) {
822,229,425✔
2282
  int32_t code = 0;
822,229,425✔
2283
  QRY_PARAM_CHECK(pColInfoData);
822,229,425✔
2284

2285
  if (index >= taosArrayGetSize(pBlock->pDataBlock)) {
822,231,001✔
2286
    return TSDB_CODE_INVALID_PARA;
×
2287
  }
2288

2289
  *pColInfoData = taosArrayGet(pBlock->pDataBlock, index);
822,230,004✔
2290
  if (*pColInfoData == NULL) {
822,231,000✔
2291
    code = terrno;
×
2292
  }
2293

2294
  return code;
822,231,248✔
2295
}
2296

2297
size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize, int32_t extraSize) {
41,195,140✔
2298
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
41,195,140✔
2299

2300
  int32_t payloadSize = pageSize - extraSize;
41,195,112✔
2301
  int32_t rowSize = pBlock->info.rowSize;
41,195,112✔
2302
  int32_t nRows = payloadSize / rowSize;
41,194,831✔
2303
  if (nRows < 1) {
41,194,831✔
2304
    uError("rows %d in page is too small, payloadSize:%d, rowSize:%d", nRows, payloadSize, rowSize);
×
2305
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
2306
    return -1;
×
2307
  }
2308

2309
  int32_t numVarCols = 0;
41,194,831✔
2310
  int32_t numFixCols = 0;
41,194,831✔
2311
  for (int32_t i = 0; i < numOfCols; ++i) {
214,523,925✔
2312
    SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, i);
173,327,858✔
2313
    if (pCol == NULL) {
173,329,597✔
2314
      return -1;
×
2315
    }
2316

2317
    if (IS_VAR_DATA_TYPE(pCol->info.type)) {
173,329,597✔
2318
      ++numVarCols;
22,163,692✔
2319
    } else {
2320
      ++numFixCols;
151,165,402✔
2321
    }
2322
  }
2323

2324
  // find the data payload whose size is greater than payloadSize
2325
  int result = -1;
41,196,067✔
2326
  int start = 1;
41,196,067✔
2327
  int end = nRows;
41,196,067✔
2328
  while (start <= end) {
379,737,855✔
2329
    int mid = start + (end - start) / 2;
338,541,788✔
2330
    // data size + var data type columns offset + fixed data type columns bitmap len
2331
    int midSize = rowSize * mid + numVarCols * sizeof(int32_t) * mid + numFixCols * BitmapLen(mid);
338,541,788✔
2332
    if (midSize > payloadSize) {
338,541,788✔
2333
      result = mid;
70,616,737✔
2334
      end = mid - 1;
70,616,737✔
2335
    } else {
2336
      start = mid + 1;
267,925,051✔
2337
    }
2338
  }
2339

2340
  int32_t newRows = (result != -1) ? result - 1 : nRows;
41,196,067✔
2341
  // the true value must be less than the value of nRows
2342
  if (newRows > nRows || newRows < 1) {
41,196,067✔
2343
    uError("invalid newRows:%d, nRows:%d", newRows, nRows);
6,016✔
2344
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
6,016✔
2345
    return -1;
×
2346
  }
2347

2348
  return newRows;
41,190,051✔
2349
}
2350

2351
void colDataDestroy(SColumnInfoData* pColData) {
2,147,483,647✔
2352
  if (!pColData) {
2,147,483,647✔
2353
    return;
143,889,564✔
2354
  }
2355

2356
  if (IS_VAR_DATA_TYPE(pColData->info.type)) {
2,147,483,647✔
2357
    taosMemoryFreeClear(pColData->varmeta.offset);
2,147,483,647✔
2358
    pColData->varmeta.allocLen = 0;
2,147,483,647✔
2359
    pColData->varmeta.length = 0;
2,147,483,647✔
2360
  } else {
2361
    taosMemoryFreeClear(pColData->nullbitmap);
2,147,483,647✔
2362
  }
2363

2364
  taosMemoryFreeClear(pColData->pData);
2,147,483,647✔
2365
}
2366

2367
static void doShiftBitmap(char* nullBitmap, size_t n, size_t total) {
144,184,246✔
2368
  int32_t len = BitmapLen(total);
144,184,246✔
2369

2370
  int32_t newLen = BitmapLen(total - n);
144,184,246✔
2371
  if (n % 8 == 0) {
144,184,246✔
2372
    (void)memmove(nullBitmap, nullBitmap + n / 8, newLen);
1,658,248✔
2373
  } else {
2374
    int32_t  tail = n % 8;
142,525,998✔
2375
    int32_t  i = 0;
142,525,998✔
2376
    uint8_t* p = (uint8_t*)nullBitmap;
142,525,998✔
2377

2378
    if (n < 8) {
142,525,998✔
2379
      while (i < len) {
99,421,932✔
2380
        uint8_t v = p[i];  // source bitmap value
92,963,802✔
2381
        p[i] = (v << tail);
92,963,802✔
2382

2383
        if (i < len - 1) {
92,963,802✔
2384
          uint8_t next = p[i + 1];
86,505,672✔
2385
          p[i] |= (next >> (8 - tail));
86,505,672✔
2386
        }
2387

2388
        i += 1;
92,963,802✔
2389
      }
2390
    } else if (n > 8) {
136,067,868✔
2391
      int32_t remain = (total % 8 != 0 && total % 8 <= tail) ? 1 : 0;
136,067,868✔
2392
      int32_t gap = len - newLen - remain;
136,067,868✔
2393
      while (i < newLen) {
1,068,893,131✔
2394
        uint8_t v = p[i + gap];
932,827,191✔
2395
        p[i] = (v << tail);
932,823,817✔
2396

2397
        if (i < newLen - 1 + remain) {
932,824,781✔
2398
          uint8_t next = p[i + gap + 1];
826,972,437✔
2399
          p[i] |= (next >> (8 - tail));
826,972,919✔
2400
        }
2401

2402
        i += 1;
932,825,263✔
2403
      }
2404
    }
2405
  }
2406
}
144,182,318✔
2407

2408
static int32_t colDataMoveVarData(SColumnInfoData* pColInfoData, size_t start, size_t end) {
×
2409
  int32_t dataOffset = -1;
×
2410
  int32_t dataLen = 0;
×
2411
  int32_t beigin = start;
×
2412
  while (beigin < end) {
×
2413
    int32_t offset = pColInfoData->varmeta.offset[beigin];
×
2414
    if (offset == -1) {
×
2415
      beigin++;
×
2416
      continue;
×
2417
    }
2418
    if (start != 0) {
×
2419
      pColInfoData->varmeta.offset[beigin] = dataLen;
×
2420
    }
2421
    char* data = pColInfoData->pData + offset;
×
2422
    if (dataOffset == -1) dataOffset = offset;  // mark the begin of data
×
2423
    int32_t type = pColInfoData->info.type;
×
2424
    if (type == TSDB_DATA_TYPE_JSON) {
×
2425
      dataLen += getJsonValueLen(data);
×
2426
    } else {
2427
      dataLen += varDataTLen(data);
×
2428
    }
2429
    beigin++;
×
2430
  }
2431

2432
  if (dataOffset > 0) {
×
2433
    (void)memmove(pColInfoData->pData, pColInfoData->pData + dataOffset, dataLen);
×
2434
  }
2435

2436
  (void)memmove(pColInfoData->varmeta.offset, &pColInfoData->varmeta.offset[start], (end - start) * sizeof(int32_t));
×
2437
  return dataLen;
×
2438
}
2439

2440
static void colDataTrimFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_t total) {
184,280,942✔
2441
  if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
184,280,942✔
2442
    // pColInfoData->varmeta.length = colDataMoveVarData(pColInfoData, n, total);
2443
    (void)memmove(pColInfoData->varmeta.offset, &pColInfoData->varmeta.offset[n], (total - n) * sizeof(int32_t));
40,097,178✔
2444

2445
    // clear the offset value of the unused entries.
2446
    memset(&pColInfoData->varmeta.offset[total - n], 0, n);
40,097,178✔
2447
  } else {
2448
    int32_t bytes = pColInfoData->info.bytes;
144,183,764✔
2449
    (void)memmove(pColInfoData->pData, ((char*)pColInfoData->pData + n * bytes), (total - n) * bytes);
144,183,764✔
2450
    doShiftBitmap(pColInfoData->nullbitmap, n, total);
144,183,764✔
2451
  }
2452
}
184,280,942✔
2453

2454
int32_t blockDataTrimFirstRows(SSDataBlock* pBlock, size_t n) {
92,405,312✔
2455
  if (n == 0) {
92,405,312✔
2456
    return TSDB_CODE_SUCCESS;
54,284,218✔
2457
  }
2458

2459
  if (pBlock->info.rows <= n) {
38,121,094✔
2460
    blockDataEmpty(pBlock);
668,220✔
2461
  } else {
2462
    size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
37,453,838✔
2463
    for (int32_t i = 0; i < numOfCols; ++i) {
221,734,780✔
2464
      SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
184,280,942✔
2465
      if (pColInfoData == NULL) {
184,280,942✔
2466
        return terrno;
×
2467
      }
2468

2469
      colDataTrimFirstNRows(pColInfoData, n, pBlock->info.rows);
184,280,942✔
2470
    }
2471

2472
    pBlock->info.rows -= n;
37,453,838✔
2473
  }
2474
  return TSDB_CODE_SUCCESS;
38,122,058✔
2475
}
2476

2477
static void colDataKeepFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_t total) {
32,020,095✔
2478
  if (n >= total || n == 0) return;
32,020,095✔
2479
  if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
32,021,252✔
2480
    if (pColInfoData->varmeta.length != 0) {
5,698,741✔
2481
      int32_t newLen = pColInfoData->varmeta.offset[n];
5,329,887✔
2482
      if (-1 == newLen) {
5,329,887✔
2483
        for (int i = n - 1; i >= 0; --i) {
3,384,540✔
2484
          newLen = pColInfoData->varmeta.offset[i];
3,383,476✔
2485
          if (newLen != -1) {
3,383,476✔
2486
            newLen += calcStrBytesByType(pColInfoData->info.type, pColInfoData->pData + newLen);
338,619✔
2487
            // if (pColInfoData->info.type == TSDB_DATA_TYPE_JSON) {
2488
            //   newLen += getJsonValueLen(pColInfoData->pData + newLen);
2489
            // } else if (IS_STR_DATA_BLOB(pColInfoData->info.type)) {
2490
            //   newLen += blobDataTLen(pColInfoData->pData + newLen);
2491
            // } else {
2492
            //   newLen += varDataTLen(pColInfoData->pData + newLen);
2493
            // }
2494
            break;
338,619✔
2495
          }
2496
        }
2497
      }
2498
      if (newLen <= -1) {
5,329,887✔
2499
        uFatal("colDataKeepFirstNRows: newLen:%d  old:%d", newLen, pColInfoData->varmeta.length);
1,064✔
2500
      } else {
2501
        pColInfoData->varmeta.length = newLen;
5,328,823✔
2502
      }
2503
    }
2504
    // pColInfoData->varmeta.length = colDataMoveVarData(pColInfoData, 0, n);
2505
    memset(&pColInfoData->varmeta.offset[n], 0, total - n);
5,699,846✔
2506
  }
2507
}
2508

2509
void blockDataKeepFirstNRows(SSDataBlock* pBlock, size_t n) {
51,877,791✔
2510
  if (n == 0) {
51,877,791✔
2511
    blockDataEmpty(pBlock);
7,040,766✔
2512
    return;
7,040,766✔
2513
  }
2514

2515
  if (pBlock->info.rows <= n) {
44,837,025✔
2516
    return;
35,648,574✔
2517
  } else {
2518
    size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
9,188,157✔
2519
    for (int32_t i = 0; i < numOfCols; ++i) {
41,205,929✔
2520
      SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
32,019,512✔
2521
      if (pColInfoData == NULL) {
32,020,739✔
2522
        continue;
×
2523
      }
2524

2525
      colDataKeepFirstNRows(pColInfoData, n, pBlock->info.rows);
32,020,739✔
2526
    }
2527

2528
    pBlock->info.rows = n;
9,186,417✔
2529
  }
2530
}
2531

2532
int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) {
1,338,216✔
2533
  int64_t tbUid = pBlock->info.id.uid;
1,338,216✔
2534
  int16_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
1,338,216✔
2535
  int16_t hasVarCol = pBlock->info.hasVarCol;
1,338,158✔
2536
  int64_t rows = pBlock->info.rows;
1,338,158✔
2537
  int32_t sz = taosArrayGetSize(pBlock->pDataBlock);
1,338,158✔
2538

2539
  int32_t tlen = 0;
1,338,158✔
2540
  tlen += taosEncodeFixedI64(buf, tbUid);
1,338,158✔
2541
  tlen += taosEncodeFixedI16(buf, numOfCols);
1,338,158✔
2542
  tlen += taosEncodeFixedI16(buf, hasVarCol);
2,676,316✔
2543
  tlen += taosEncodeFixedI64(buf, rows);
1,338,158✔
2544
  tlen += taosEncodeFixedI32(buf, sz);
1,338,158✔
2545
  for (int32_t i = 0; i < sz; i++) {
2,718,598✔
2546
    SColumnInfoData* pColData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
1,380,434✔
2547
    if (pColData == NULL) {
1,380,434✔
UNCOV
2548
      return terrno;
×
2549
    }
2550

2551
    tlen += taosEncodeFixedI16(buf, pColData->info.colId);
1,380,434✔
2552
    tlen += taosEncodeFixedI8(buf, pColData->info.type);
1,380,434✔
2553
    tlen += taosEncodeFixedI32(buf, pColData->info.bytes);
1,380,434✔
2554
    tlen += taosEncodeFixedBool(buf, pColData->hasNull);
1,380,434✔
2555

2556
    if (IS_VAR_DATA_TYPE(pColData->info.type)) {
1,380,434✔
2557
      tlen += taosEncodeBinary(buf, pColData->varmeta.offset, sizeof(int32_t) * rows);
27,236✔
2558
    } else {
2559
      tlen += taosEncodeBinary(buf, pColData->nullbitmap, BitmapLen(rows));
2,733,632✔
2560
    }
2561

2562
    int32_t len = colDataGetLength(pColData, rows);
1,380,434✔
2563
    tlen += taosEncodeFixedI32(buf, len);
1,380,440✔
2564

2565
    if (pColData->reassigned && IS_VAR_DATA_TYPE(pColData->info.type)) {
1,380,440✔
2566
      for (int32_t row = 0; row < rows; ++row) {
×
2567
        char*   pData = pColData->pData + pColData->varmeta.offset[row];
×
2568
        int32_t colSize = calcStrBytesByType(pColData->info.type, pData);
×
2569
        // if (pColData->info.type == TSDB_DATA_TYPE_JSON) {
2570
        //   colSize = getJsonValueLen(pData);
2571
        // } else if (IS_STR_DATA_BLOB(pColData->info.type)) {
2572
        //   colSize = blobDataTLen(pData);
2573
        // } else {
2574
        //   colSize = varDataTLen(pData);
2575
        // }
2576
        tlen += taosEncodeBinary(buf, pData, colSize);
×
2577
      }
2578
    } else {
2579
      tlen += taosEncodeBinary(buf, pColData->pData, len);
2,760,880✔
2580
    }
2581
  }
2582
  return tlen;
1,338,164✔
2583
}
2584

2585
void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock) {
791,702✔
2586
  int32_t sz = 0;
791,702✔
2587
  int16_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
791,702✔
2588

2589
  buf = taosDecodeFixedU64(buf, &pBlock->info.id.uid);
1,583,404✔
2590
  buf = taosDecodeFixedI16(buf, &numOfCols);
791,702✔
2591
  buf = taosDecodeFixedI16(buf, &pBlock->info.hasVarCol);
791,702✔
2592
  buf = taosDecodeFixedI64(buf, &pBlock->info.rows);
1,583,404✔
2593
  buf = taosDecodeFixedI32(buf, &sz);
791,702✔
2594

2595
  pBlock->pDataBlock = taosArrayInit(sz, sizeof(SColumnInfoData));
791,702✔
2596
  if (pBlock->pDataBlock == NULL) {
791,760✔
2597
    return NULL;
×
2598
  }
2599

2600
  for (int32_t i = 0; i < sz; i++) {
1,646,028✔
2601
    SColumnInfoData data = {0};
854,390✔
2602
    buf = taosDecodeFixedI16(buf, &data.info.colId);
854,390✔
2603
    buf = taosDecodeFixedI8(buf, &data.info.type);
854,390✔
2604
    buf = taosDecodeFixedI32(buf, &data.info.bytes);
854,390✔
2605
    buf = taosDecodeFixedBool(buf, &data.hasNull);
854,390✔
2606

2607
    if (IS_VAR_DATA_TYPE(data.info.type)) {
854,390✔
2608
      buf = taosDecodeBinary(buf, (void**)&data.varmeta.offset, pBlock->info.rows * sizeof(int32_t));
19,198✔
2609
    } else {
2610
      buf = taosDecodeBinary(buf, (void**)&data.nullbitmap, BitmapLen(pBlock->info.rows));
1,689,582✔
2611
    }
2612
    if (buf == NULL) {
854,390✔
2613
      uError("failed to decode null bitmap/offset, type:%d", data.info.type);
×
2614
      goto _error;
×
2615
    }
2616

2617
    int32_t len = 0;
854,390✔
2618
    buf = taosDecodeFixedI32(buf, &len);
854,390✔
2619
    buf = taosDecodeBinary(buf, (void**)&data.pData, len);
854,390✔
2620
    if (buf == NULL) {
854,442✔
2621
      uError("failed to decode data, type:%d", data.info.type);
×
2622
      goto _error;
×
2623
    }
2624
    if (IS_VAR_DATA_TYPE(data.info.type)) {
854,442✔
2625
      data.varmeta.length = len;
9,657✔
2626
      data.varmeta.allocLen = len;
9,657✔
2627
    }
2628

2629
    void* px = taosArrayPush(pBlock->pDataBlock, &data);
854,442✔
2630
    if (px == NULL) {
854,268✔
2631
      return NULL;
×
2632
    }
2633
  }
2634

2635
  return (void*)buf;
791,638✔
2636
_error:
×
2637
  for (int32_t i = 0; i < sz; ++i) {
×
2638
    SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
×
2639
    if (pColInfoData == NULL) {
×
2640
      break;
×
2641
    }
2642
    colDataDestroy(pColInfoData);
×
2643
  }
2644
  return NULL;
×
2645
}
2646

2647
static int32_t formatTimestamp(char* buf, size_t cap, int64_t val, int precision) {
70,896,059✔
2648
  time_t  tt;
19,051,577✔
2649
  int32_t ms = 0;
70,896,059✔
2650
  int32_t code = TSDB_CODE_SUCCESS;
70,896,059✔
2651
  int32_t lino = 0;
70,896,059✔
2652
  if (precision == TSDB_TIME_PRECISION_NANO) {
70,896,059✔
2653
    tt = (time_t)(val / 1000000000);
×
2654
    ms = val % 1000000000;
×
2655
  } else if (precision == TSDB_TIME_PRECISION_MICRO) {
70,896,059✔
2656
    tt = (time_t)(val / 1000000);
×
2657
    ms = val % 1000000;
×
2658
  } else {
2659
    tt = (time_t)(val / 1000);
70,896,059✔
2660
    ms = val % 1000;
70,896,059✔
2661
  }
2662

2663
  if (tt <= 0 && ms < 0) {
70,896,059✔
2664
    tt--;
×
2665
    if (precision == TSDB_TIME_PRECISION_NANO) {
×
2666
      ms += 1000000000;
×
2667
    } else if (precision == TSDB_TIME_PRECISION_MICRO) {
×
2668
      ms += 1000000;
×
2669
    } else {
2670
      ms += 1000;
×
2671
    }
2672
  }
2673
  struct tm ptm = {0};
70,896,059✔
2674
  if (taosLocalTime(&tt, &ptm, buf, cap, NULL) == NULL) {
70,896,059✔
2675
    code = TSDB_CODE_INTERNAL_ERROR;
×
2676
    TSDB_CHECK_CODE(code, lino, _end);
×
2677
  }
2678

2679
  size_t pos = taosStrfTime(buf, cap, "%Y-%m-%d %H:%M:%S", &ptm);
70,771,536✔
2680
  if (pos == 0) {
70,860,980✔
2681
    code = TSDB_CODE_OUT_OF_BUFFER;
×
2682
    TSDB_CHECK_CODE(code, lino, _end);
×
2683
  }
2684
  int32_t nwritten = 0;
70,860,980✔
2685
  if (precision == TSDB_TIME_PRECISION_NANO) {
70,860,980✔
2686
    nwritten = snprintf(buf + pos, cap - pos, ".%09d", ms);
×
2687
  } else if (precision == TSDB_TIME_PRECISION_MICRO) {
70,860,980✔
2688
    nwritten = snprintf(buf + pos, cap - pos, ".%06d", ms);
×
2689
  } else {
2690
    nwritten = snprintf(buf + pos, cap - pos, ".%03d", ms);
70,860,980✔
2691
  }
2692

2693
  if (nwritten >= cap - pos) {
70,860,980✔
2694
    code = TSDB_CODE_OUT_OF_BUFFER;
×
2695
    TSDB_CHECK_CODE(code, lino, _end);
×
2696
  }
2697

2698
_end:
70,860,980✔
2699
  if (code != TSDB_CODE_SUCCESS) {
70,860,980✔
2700
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2701
  }
2702
  return code;
70,843,127✔
2703
}
2704

2705
// for debug
2706
int32_t dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf, const char* taskIdStr, int64_t qId) {
3,042,691✔
2707
  int32_t lino = 0;
3,042,691✔
2708
  int32_t size = 2048 * 1024;
3,042,691✔
2709
  int32_t code = 0;
3,042,691✔
2710
  char*   dumpBuf = NULL;
3,042,691✔
2711
  char    pBuf[TD_TIME_STR_LEN] = {0};
3,042,691✔
2712
  int32_t rows = pDataBlock->info.rows;
3,042,691✔
2713
  int32_t len = 0;
3,042,691✔
2714

2715
  dumpBuf = taosMemoryCalloc(size, 1);
3,042,691✔
2716
  if (dumpBuf == NULL) {
3,042,559✔
2717
    return terrno;
×
2718
  }
2719

2720
  int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock);
3,042,559✔
2721
  len += tsnprintf(dumpBuf + len, size - len,
4,622,272✔
2722
                  "%" PRIx64 " %s %s|child id %d|group id:%" PRIx64 "|uid:%" PRId64 "|rows:%" PRId64
2723
                  "|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n",
2724
                  qId, taskIdStr, flag, pDataBlock->info.childId,
2725
                  pDataBlock->info.id.groupId, pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version,
2726
                  pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName);
3,042,559✔
2727
  if (len >= size - 1) {
3,042,691✔
2728
    goto _exit;
×
2729
  }
2730

2731
  for (int32_t j = 0; j < rows; j++) {
60,134,879✔
2732
    len += snprintf(dumpBuf + len, size - len, "%" PRIx64 " %s|", qId, flag);
57,120,436✔
2733
    if (len >= size - 1) {
57,120,436✔
2734
      goto _exit;
×
2735
    }
2736

2737
    for (int32_t k = 0; k < colNum; k++) {
224,952,999✔
2738
      SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k);
167,860,811✔
2739
      if (pColInfoData == NULL) {
167,824,417✔
2740
        code = terrno;
×
2741
        lino = __LINE__;
×
2742
        goto _exit;
×
2743
      }
2744

2745
      if (colDataIsNull(pColInfoData, rows, j, NULL) || !pColInfoData->pData) {
335,731,211✔
2746
        len += snprintf(dumpBuf + len, size - len, " %15s |", "NULL");
568,273✔
2747
        if (len >= size - 1) goto _exit;
568,273✔
2748
        continue;
568,273✔
2749
      }
2750

2751
      void* var = colDataGetData(pColInfoData, j);
167,297,700✔
2752
      switch (pColInfoData->info.type) {
167,297,455✔
2753
        case TSDB_DATA_TYPE_TIMESTAMP:
70,904,045✔
2754
          memset(pBuf, 0, sizeof(pBuf));
70,904,045✔
2755
          code = formatTimestamp(pBuf, sizeof(pBuf), *(uint64_t*)var, pColInfoData->info.precision);
70,904,045✔
2756
          if (code != TSDB_CODE_SUCCESS) {
70,870,880✔
2757
            TAOS_UNUSED(snprintf(pBuf, sizeof(pBuf), "NaN"));
×
2758
          }
2759
          len += snprintf(dumpBuf + len, size - len, " %25s |", pBuf);
70,870,880✔
2760
          if (len >= size - 1) goto _exit;
70,870,880✔
2761
          break;
70,870,880✔
2762
        case TSDB_DATA_TYPE_TINYINT:
980✔
2763
          len += snprintf(dumpBuf + len, size - len, " %15d |", *(int8_t*)var);
980✔
2764
          if (len >= size - 1) goto _exit;
980✔
2765
          break;
980✔
2766
        case TSDB_DATA_TYPE_UTINYINT:
×
2767
          len += snprintf(dumpBuf + len, size - len, " %15d |", *(uint8_t*)var);
×
2768
          if (len >= size - 1) goto _exit;
×
2769
          break;
×
2770
        case TSDB_DATA_TYPE_SMALLINT:
×
2771
          len += snprintf(dumpBuf + len, size - len, " %15d |", *(int16_t*)var);
×
2772
          if (len >= size - 1) goto _exit;
×
2773
          break;
×
2774
        case TSDB_DATA_TYPE_USMALLINT:
×
2775
          len += snprintf(dumpBuf + len, size - len, " %15d |", *(uint16_t*)var);
×
2776
          if (len >= size - 1) goto _exit;
×
2777
          break;
×
2778
        case TSDB_DATA_TYPE_INT:
25,643,657✔
2779
          len += snprintf(dumpBuf + len, size - len, " %15d |", *(int32_t*)var);
25,643,657✔
2780
          if (len >= size - 1) goto _exit;
25,643,657✔
2781
          break;
25,643,657✔
2782
        case TSDB_DATA_TYPE_UINT:
×
2783
          len += snprintf(dumpBuf + len, size - len, " %15u |", *(uint32_t*)var);
×
2784
          if (len >= size - 1) goto _exit;
×
2785
          break;
×
2786
        case TSDB_DATA_TYPE_BIGINT:
70,619,833✔
2787
          len += snprintf(dumpBuf + len, size - len, " %15" PRId64 " |", *(int64_t*)var);
70,619,833✔
2788
          if (len >= size - 1) goto _exit;
70,619,833✔
2789
          break;
70,619,833✔
2790
        case TSDB_DATA_TYPE_UBIGINT:
5,260✔
2791
          len += snprintf(dumpBuf + len, size - len, " %15" PRIu64 " |", *(uint64_t*)var);
5,260✔
2792
          if (len >= size - 1) goto _exit;
5,260✔
2793
          break;
5,260✔
2794
        case TSDB_DATA_TYPE_FLOAT:
×
2795
          len += snprintf(dumpBuf + len, size - len, " %15f |", *(float*)var);
×
2796
          if (len >= size - 1) goto _exit;
×
2797
          break;
×
2798
        case TSDB_DATA_TYPE_DOUBLE:
55,097✔
2799
          len += snprintf(dumpBuf + len, size - len, " %15f |", *(double*)var);
55,097✔
2800
          if (len >= size - 1) goto _exit;
55,097✔
2801
          break;
55,097✔
2802
        case TSDB_DATA_TYPE_BOOL:
1,554✔
2803
          len += snprintf(dumpBuf + len, size - len, " %15d |", *(bool*)var);
1,554✔
2804
          if (len >= size - 1) goto _exit;
1,554✔
2805
          break;
1,554✔
2806
        case TSDB_DATA_TYPE_VARCHAR:
575,243✔
2807
        case TSDB_DATA_TYPE_VARBINARY:
2808
        case TSDB_DATA_TYPE_GEOMETRY: {
2809
          memset(pBuf, 0, sizeof(pBuf));
575,243✔
2810
          char*   pData = colDataGetVarData(pColInfoData, j);
575,243✔
2811
          int32_t dataSize = TMIN(sizeof(pBuf), varDataLen(pData));
575,243✔
2812
          dataSize = TMIN(dataSize, 50);
575,243✔
2813
          memcpy(pBuf, varDataVal(pData), dataSize);
575,243✔
2814
          len += snprintf(dumpBuf + len, size - len, " %15s |", pBuf);
575,243✔
2815
          if (len >= size - 1) goto _exit;
575,243✔
2816
        } break;
575,243✔
2817
        case TSDB_DATA_TYPE_NCHAR: {
×
2818
          char*   pData = colDataGetVarData(pColInfoData, j);
×
2819
          int32_t dataSize = TMIN(sizeof(pBuf), varDataLen(pData));
×
2820
          memset(pBuf, 0, sizeof(pBuf));
×
2821
          code = taosUcs4ToMbs((TdUcs4*)varDataVal(pData), dataSize, pBuf, NULL);
×
2822
          if (code < 0) {
×
2823
            uError("func %s failed to convert to ucs charset since %s", __func__, tstrerror(code));
×
2824
            lino = __LINE__;
×
2825
            goto _exit;
×
2826
          } else {  // reset the length value
2827
            code = TSDB_CODE_SUCCESS;
×
2828
          }
2829
          len += snprintf(dumpBuf + len, size - len, " %15s |", pBuf);
×
2830
          if (len >= size - 1) goto _exit;
×
2831
        } break;
×
2832
        case TSDB_DATA_TYPE_MEDIUMBLOB:
×
2833
        case TSDB_DATA_TYPE_BLOB: {
2834
          memset(pBuf, 0, sizeof(pBuf));
×
2835
          char*   pData = colDataGetVarData(pColInfoData, j);
×
2836
          int32_t dataSize = TMIN(sizeof(pBuf), blobDataLen(pData));
×
2837
          dataSize = TMIN(dataSize, 50);
×
2838
          memcpy(pBuf, blobDataVal(pData), dataSize);
×
2839
          len += snprintf(dumpBuf + len, size - len, " %15s |", pBuf);
×
2840
          if (len >= size - 1) goto _exit;
×
2841
          break;
×
2842
        }
2843
      }
2844
    }
2845
    len += snprintf(dumpBuf + len, size - len, "%d\n", j);
57,092,188✔
2846
    if (len >= size - 1) goto _exit;
57,092,188✔
2847
  }
2848
  len += snprintf(dumpBuf + len, size - len, "%s |end\n", flag);
3,014,443✔
2849

2850
_exit:
3,014,443✔
2851
  if (code == TSDB_CODE_SUCCESS) {
3,014,443✔
2852
    *pDataBuf = dumpBuf;
3,042,592✔
2853
    dumpBuf = NULL;
3,042,592✔
2854
  } else {
2855
    uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
2856
    if (dumpBuf) {
×
2857
      taosMemoryFree(dumpBuf);
×
2858
    }
2859
  }
2860
  return code;
3,042,360✔
2861
}
2862

2863
int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDataBlock, const STSchema* pTSchema,
×
2864
                                    int64_t uid, int32_t vgId, tb_uid_t suid) {
2865
  SSubmitReq2* pReq = *ppReq;
×
2866
  SArray*      pVals = NULL;
×
2867
  int32_t      sz = 1;
×
2868
  int32_t      code = 0;
×
2869
  *ppReq = NULL;
×
2870
  terrno = 0;
×
2871

2872
  if (NULL == pReq) {
×
2873
    if (!(pReq = taosMemoryCalloc(1, sizeof(SSubmitReq2)))) {
×
2874
      code = terrno;
×
2875
      goto _end;
×
2876
    }
2877

2878
    if (!(pReq->aSubmitTbData = taosArrayInit(1, sizeof(SSubmitTbData)))) {
×
2879
      code = terrno;
×
2880
      goto _end;
×
2881
    }
2882
  }
2883

2884
  for (int32_t i = 0; i < sz; ++i) {
×
2885
    int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock);
×
2886
    int32_t rows = pDataBlock->info.rows;
×
2887

2888
    if (colNum <= 1) {  // invalid if only with TS col
×
2889
      continue;
×
2890
    }
2891

2892
    // the rsma result should has the same column number with schema.
2893
    if (colNum != pTSchema->numOfCols) {
×
2894
      uError("colNum %d is not equal to numOfCols %d", colNum, pTSchema->numOfCols);
×
2895
      code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
2896
      goto _end;
×
2897
    }
2898

2899
    SSubmitTbData tbData = {0};
×
2900

2901
    if (!(tbData.aRowP = taosArrayInit(rows, sizeof(SRow*)))) {
×
2902
      code = terrno;
×
2903
      goto _end;
×
2904
    }
2905

2906
    tbData.suid = suid;
×
2907
    tbData.uid = uid;
×
2908
    tbData.sver = pTSchema->version;
×
2909

2910
    if (!pVals && !(pVals = taosArrayInit(colNum, sizeof(SColVal)))) {
×
2911
      code = terrno;
×
2912
      taosArrayDestroy(tbData.aRowP);
×
2913
      goto _end;
×
2914
    }
2915

2916
    for (int32_t j = 0; j < rows; ++j) {  // iterate by row
×
2917

2918
      taosArrayClear(pVals);
×
2919

2920
      bool    isStartKey = false;
×
2921
      int32_t offset = 0;
×
2922
      for (int32_t k = 0; k < colNum; ++k) {  // iterate by column
×
2923
        SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k);
×
2924
        if (pColInfoData == NULL) {
×
2925
          return terrno;
×
2926
        }
2927

2928
        const STColumn* pCol = &pTSchema->columns[k];
×
2929
        void*           var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes);
×
2930

2931
        switch (pColInfoData->info.type) {
×
2932
          case TSDB_DATA_TYPE_TIMESTAMP:
×
2933
            if (pColInfoData->info.type != pCol->type) {
×
2934
              uError("colType:%d mismatch with sechma colType:%d", pColInfoData->info.type, pCol->type);
×
2935
              terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
2936
              return terrno;
×
2937
            }
2938
            if (!isStartKey) {
×
2939
              isStartKey = true;
×
2940
              if (PRIMARYKEY_TIMESTAMP_COL_ID != pCol->colId) {
×
2941
                uError("the first timestamp colId %d is not primary colId", pCol->colId);
×
2942
                terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
2943
                return terrno;
×
2944
              }
2945
              SValue val = {.type = pCol->type};
×
2946
              VALUE_SET_TRIVIAL_DATUM(&val, *(TSKEY*)var);
×
2947
              SColVal cv = COL_VAL_VALUE(pCol->colId, val);
×
2948
              void*   px = taosArrayPush(pVals, &cv);
×
2949
              if (px == NULL) {
×
2950
                return terrno;
×
2951
              }
2952

2953
            } else if (colDataIsNull_s(pColInfoData, j)) {
×
2954
              SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
×
2955
              void*   px = taosArrayPush(pVals, &cv);
×
2956
              if (px == NULL) {
×
2957
                return terrno;
×
2958
              }
2959
            } else {
2960
              SValue val = {.type = pCol->type};
×
2961
              VALUE_SET_TRIVIAL_DATUM(&val, *(int64_t*)var);
×
2962
              SColVal cv = COL_VAL_VALUE(pCol->colId, val);
×
2963
              void*   px = taosArrayPush(pVals, &cv);
×
2964
              if (px == NULL) {
×
2965
                return terrno;
×
2966
              }
2967
            }
2968
            break;
×
2969
          case TSDB_DATA_TYPE_NCHAR:
×
2970
          case TSDB_DATA_TYPE_VARBINARY:
2971
          case TSDB_DATA_TYPE_VARCHAR: {  // TSDB_DATA_TYPE_BINARY
2972
            if (pColInfoData->info.type != pCol->type) {
×
2973
              uError("colType:%d mismatch with sechma colType:%d", pColInfoData->info.type, pCol->type);
×
2974
              terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
2975
              return terrno;
×
2976
            }
2977
            if (colDataIsNull_s(pColInfoData, j)) {
×
2978
              SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
×
2979
              void*   px = taosArrayPush(pVals, &cv);
×
2980
              if (px == NULL) {
×
2981
                goto _end;
×
2982
              }
2983
            } else {
2984
              void*   data = colDataGetVarData(pColInfoData, j);
×
2985
              SValue  sv = (SValue){.type = pCol->type,
×
2986
                                    .nData = varDataLen(data),
×
2987
                                    .pData = (uint8_t*)varDataVal(data)};  // address copy, no value
×
2988
              SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
×
2989
              void*   px = taosArrayPush(pVals, &cv);
×
2990
              if (px == NULL) {
×
2991
                code = terrno;
×
2992
                goto _end;
×
2993
              }
2994
            }
2995
            break;
×
2996
          }
2997
          case TSDB_DATA_TYPE_DECIMAL:
×
2998
          case TSDB_DATA_TYPE_MEDIUMBLOB:
2999
          case TSDB_DATA_TYPE_BLOB:
3000
            uError("the column type %" PRIi16 " is defined but not implemented yet", pColInfoData->info.type);
×
3001
            terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3002
            return terrno;
×
3003
            break;
3004
          case TSDB_DATA_TYPE_JSON:
×
3005
            uError("the column type %" PRIi16 " is defined but not implemented yet", pColInfoData->info.type);
×
3006
            terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3007
            return terrno;
×
3008
            break;
3009
          default:
×
3010
            if (pColInfoData->info.type < TSDB_DATA_TYPE_MAX && pColInfoData->info.type > TSDB_DATA_TYPE_NULL) {
×
3011
              if (colDataIsNull_s(pColInfoData, j)) {
×
3012
                SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);  // should use pCol->type
×
3013
                void*   px = taosArrayPush(pVals, &cv);
×
3014
                if (px == NULL) {
×
3015
                  goto _end;
×
3016
                }
3017
              } else {
3018
                SValue sv = {.type = pCol->type};
×
3019
                if (pCol->type == pColInfoData->info.type) {
×
3020
                  valueSetDatum(&sv, sv.type, var, tDataTypes[pCol->type].bytes);
×
3021
                } else {
3022
                  /**
3023
                   *  1. sum/avg would convert to int64_t/uint64_t/double during aggregation
3024
                   *  2. below conversion may lead to overflow or loss, the app should select the right data type.
3025
                   */
3026
                  char tv[DATUM_MAX_SIZE] = {0};
×
3027
                  if (pColInfoData->info.type == TSDB_DATA_TYPE_FLOAT) {
×
3028
                    float v = 0;
×
3029
                    GET_TYPED_DATA(v, float, pColInfoData->info.type, var,
×
3030
                                   typeGetTypeModFromColInfo(&pColInfoData->info));
3031
                    SET_TYPED_DATA(&tv, pCol->type, v);
×
3032
                  } else if (pColInfoData->info.type == TSDB_DATA_TYPE_DOUBLE) {
×
3033
                    double v = 0;
×
3034
                    GET_TYPED_DATA(v, double, pColInfoData->info.type, var,
×
3035
                                   typeGetTypeModFromColInfo(&pColInfoData->info));
3036
                    SET_TYPED_DATA(&tv, pCol->type, v);
×
3037
                  } else if (IS_SIGNED_NUMERIC_TYPE(pColInfoData->info.type)) {
×
3038
                    int64_t v = 0;
×
3039
                    GET_TYPED_DATA(v, int64_t, pColInfoData->info.type, var,
×
3040
                                   typeGetTypeModFromColInfo(&pColInfoData->info));
3041
                    SET_TYPED_DATA(&tv, pCol->type, v);
×
3042
                  } else {
3043
                    uint64_t v = 0;
×
3044
                    GET_TYPED_DATA(v, uint64_t, pColInfoData->info.type, var,
×
3045
                                   typeGetTypeModFromColInfo(&pColInfoData->info));
3046
                    SET_TYPED_DATA(&tv, pCol->type, v);
×
3047
                  }
3048
                  valueSetDatum(&sv, sv.type, tv, tDataTypes[pCol->type].bytes);
×
3049
                }
3050
                SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
×
3051
                void*   px = taosArrayPush(pVals, &cv);
×
3052
                if (px == NULL) {
×
3053
                  code = terrno;
×
3054
                  goto _end;
×
3055
                }
3056
              }
3057
            } else {
3058
              uError("the column type %" PRIi16 " is undefined\n", pColInfoData->info.type);
×
3059
              terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3060
              return terrno;
×
3061
            }
3062
            break;
×
3063
        }
3064
      }
3065
      SRow*             pRow = NULL;
×
3066
      SRowBuildScanInfo sinfo = {0};
×
3067
      if ((code = tRowBuild(pVals, pTSchema, &pRow, &sinfo)) < 0) {
×
3068
        tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
×
3069
        goto _end;
×
3070
      }
3071

3072
      void* px = taosArrayPush(tbData.aRowP, &pRow);
×
3073
      if (px == NULL) {
×
3074
        code = terrno;
×
3075
        goto _end;
×
3076
      }
3077
    }
3078

3079
    void* px = taosArrayPush(pReq->aSubmitTbData, &tbData);
×
3080
    if (px == NULL) {
×
3081
      code = terrno;
×
3082
      goto _end;
×
3083
    }
3084
  }
3085

3086
_end:
×
3087
  taosArrayDestroy(pVals);
×
3088
  if (code != 0) {
×
3089
    if (pReq) {
×
3090
      tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
×
3091
      taosMemoryFreeClear(pReq);
×
3092
    }
3093
  } else {
3094
    *ppReq = pReq;
×
3095
  }
3096

3097
  return code;
×
3098
}
3099

3100
// Construct the child table name in the form of <ctbName>_<stbName>_<groupId> and store it in `ctbName`.
3101
int32_t buildCtbNameAddGroupId(const char* stbName, char* ctbName, uint64_t groupId, size_t cap) {
1,800✔
3102
  int32_t code = TSDB_CODE_SUCCESS;
1,800✔
3103
  int32_t lino = 0;
1,800✔
3104
  char    tmp[TSDB_TABLE_NAME_LEN] = {0};
1,800✔
3105

3106
  if (ctbName == NULL || cap < TSDB_TABLE_NAME_LEN) {
1,800✔
3107
    code = TSDB_CODE_INTERNAL_ERROR;
400✔
3108
    TSDB_CHECK_CODE(code, lino, _end);
400✔
3109
  }
3110

3111
  if (stbName == NULL) {
1,400✔
3112
    snprintf(tmp, TSDB_TABLE_NAME_LEN, "_%" PRIu64, groupId);
400✔
3113
  } else {
3114
    int32_t i = strlen(stbName) - 1;
1,000✔
3115
    for (; i >= 0; i--) {
37,600✔
3116
      if (stbName[i] == '.') {
36,800✔
3117
        break;
200✔
3118
      }
3119
    }
3120
    snprintf(tmp, TSDB_TABLE_NAME_LEN, "_%s_%" PRIu64, stbName + i + 1, groupId);
1,000✔
3121
  }
3122

3123
  ctbName[cap - strlen(tmp) - 1] = 0;  // put stbname + groupId to the end
1,400✔
3124
  size_t prefixLen = strlen(ctbName);
1,400✔
3125
  ctbName = strncat(ctbName, tmp, cap - prefixLen - 1);
1,400✔
3126

3127
  for (char* p = ctbName; *p; ++p) {
65,400✔
3128
    if (*p == '.') *p = '_';
64,000✔
3129
  }
3130

3131
_end:
1,400✔
3132
  if (code != TSDB_CODE_SUCCESS) {
1,800✔
3133
    uError("%s failed at line %d since %s, ctbName:%s", __func__, lino, tstrerror(code), ctbName);
400✔
3134
  }
3135
  return code;
1,800✔
3136
}
3137

3138
// auto stream subtable name starts with 't_', followed by the first segment of MD5 digest for group vals.
3139
// the total length is fixed to be 34 bytes.
3140
bool isAutoTableName(char* ctbName) { return (strlen(ctbName) == 34 && ctbName[0] == 't' && ctbName[1] == '_'); }
×
3141

3142
bool alreadyAddGroupId(char* ctbName, int64_t groupId) {
800✔
3143
  char tmp[64] = {0};
800✔
3144
  snprintf(tmp, sizeof(tmp), "%" PRIu64, groupId);
800✔
3145
  size_t len1 = strlen(ctbName);
800✔
3146
  size_t len2 = strlen(tmp);
800✔
3147
  if (len1 < len2) return false;
800✔
3148
  return memcmp(ctbName + len1 - len2, tmp, len2) == 0;
600✔
3149
}
3150

3151
int32_t buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId, char** pName) {
×
3152
  QRY_PARAM_CHECK(pName);
×
3153

3154
  char* pBuf = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + 1);
×
3155
  if (!pBuf) {
×
3156
    return terrno;
×
3157
  }
3158

3159
  int32_t code = buildCtbNameByGroupIdImpl(stbFullName, groupId, pBuf);
×
3160
  if (code != TSDB_CODE_SUCCESS) {
×
3161
    taosMemoryFree(pBuf);
×
3162
  } else {
3163
    *pName = pBuf;
×
3164
  }
3165

3166
  return code;
×
3167
}
3168

3169
int32_t buildCtbNameByGroupIdImpl(const char* stbFullName, uint64_t groupId, char* cname) {
×
3170
  if (stbFullName[0] == 0) {
×
3171
    return TSDB_CODE_INVALID_PARA;
×
3172
  }
3173

3174
  SArray* tags = taosArrayInit(0, sizeof(SSmlKv));
×
3175
  if (tags == NULL) {
×
3176
    return terrno;
×
3177
  }
3178

3179
  if (cname == NULL) {
×
3180
    taosArrayDestroy(tags);
×
3181
    return TSDB_CODE_INVALID_PARA;
×
3182
  }
3183

3184
  int8_t      type = TSDB_DATA_TYPE_UBIGINT;
×
3185
  const char* name = "group_id";
×
3186
  int32_t     len = strlen(name);
×
3187

3188
  SSmlKv pTag = {.key = name, .keyLen = len, .type = type, .u = groupId, .length = sizeof(uint64_t)};
×
3189
  void*  px = taosArrayPush(tags, &pTag);
×
3190
  if (px == NULL) {
×
3191
    return terrno;
×
3192
  }
3193

3194
  RandTableName rname = {
×
3195
      .tags = tags, .stbFullName = stbFullName, .stbFullNameLen = strlen(stbFullName), .ctbShortName = cname};
×
3196

3197
  int32_t code = buildChildTableName(&rname);
×
3198
  if (code != TSDB_CODE_SUCCESS) {
×
3199
    return code;
×
3200
  }
3201

3202
  taosArrayDestroy(tags);
×
3203
  if ((rname.ctbShortName && rname.ctbShortName[0]) == 0) {
×
3204
    return TSDB_CODE_INVALID_PARA;
×
3205
  }
3206

3207
  return code;
×
3208
}
3209

3210
int32_t buildSinkDestTableName(char* parTbName, const char* stbFullName, uint64_t gid, bool newSubTableRule,
×
3211
                               char** dstTableName) {
3212
  int32_t code = TSDB_CODE_SUCCESS;
×
3213
  int32_t lino = 0;
×
3214

3215
  if (parTbName[0]) {
×
3216
    if (newSubTableRule && !isAutoTableName(parTbName) && !alreadyAddGroupId(parTbName, gid) && gid != 0 &&
×
3217
        stbFullName) {
3218
      *dstTableName = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN);
×
3219
      TSDB_CHECK_NULL(*dstTableName, code, lino, _end, terrno);
×
3220

3221
      tstrncpy(*dstTableName, parTbName, TSDB_TABLE_NAME_LEN);
×
3222
      code = buildCtbNameAddGroupId(stbFullName, *dstTableName, gid, TSDB_TABLE_NAME_LEN);
×
3223
      TSDB_CHECK_CODE(code, lino, _end);
×
3224
    } else {
3225
      *dstTableName = taosStrdup(parTbName);
×
3226
      TSDB_CHECK_NULL(*dstTableName, code, lino, _end, terrno);
×
3227
    }
3228
  } else {
3229
    code = buildCtbNameByGroupId(stbFullName, gid, dstTableName);
×
3230
    TSDB_CHECK_CODE(code, lino, _end);
×
3231
  }
3232

3233
_end:
×
3234
  return code;
×
3235
}
3236

3237
static int32_t blockCheckSize(int64_t blockSize) {
2,147,483,647✔
3238
  int32_t code = 0;
2,147,483,647✔
3239
  if (blockSize <= 0 || blockSize >= INT32_MAX) {
2,147,483,647✔
3240
    code = TSDB_CODE_OUT_OF_BUFFER;
×
3241
    uError("block size:%" PRId64 ", limit %d since %s", blockSize, INT32_MAX, tstrerror(code));
×
3242
  }
3243
  return code;
2,147,483,647✔
3244
}
3245
// return length of encoded data, return -1 if failed
3246
int32_t blockEncodeImpl(const SSDataBlock* pBlock, char* data, size_t dataBuflen, int32_t numOfCols, bool internal) {
937,988,415✔
3247
  int32_t code = blockDataCheck(pBlock);
937,988,415✔
3248
  if (code != TSDB_CODE_SUCCESS) {
938,035,731✔
3249
    terrno = code;
792✔
3250
    return -1;
×
3251
  }
3252
  int64_t blockSize = 0;
938,034,939✔
3253

3254
  int32_t dataLen = 0;
938,034,939✔
3255

3256
  // todo extract method
3257
  int32_t* version = (int32_t*)data;
938,034,939✔
3258
  *version = BLOCK_VERSION_1;
938,034,939✔
3259
  data += sizeof(int32_t);
937,993,266✔
3260

3261
  int32_t* actualLen = (int32_t*)data;
937,974,000✔
3262
  data += sizeof(int32_t);
937,974,000✔
3263

3264
  int32_t* rows = (int32_t*)data;
938,007,889✔
3265
  *rows = pBlock->info.rows;
938,007,889✔
3266
  data += sizeof(int32_t);
938,048,805✔
3267
  if (*rows <= 0) {
938,065,315✔
3268
    uError("Invalid rows %d in block", *rows);
×
3269
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3270
    return -1;
×
3271
  }
3272

3273
  int32_t* cols = (int32_t*)data;
937,927,846✔
3274
  *cols = numOfCols;
937,927,846✔
3275
  data += sizeof(int32_t);
937,970,830✔
3276

3277
  // flag segment.
3278
  // the inital bit is for column info
3279
  int32_t* flagSegment = (int32_t*)data;
938,060,416✔
3280
  *flagSegment = (1 << 31);
938,060,416✔
3281

3282
  data += sizeof(int32_t);
938,051,929✔
3283

3284
  uint64_t* groupId = (uint64_t*)data;
937,993,852✔
3285
  data += sizeof(uint64_t);
937,993,852✔
3286

3287
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
3288
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
2,147,483,647✔
3289
    if (pColInfoData == NULL) {
2,147,483,647✔
3290
      return -1;
×
3291
    }
3292

3293
    *((int8_t*)data) = pColInfoData->info.type;
2,147,483,647✔
3294
    data += sizeof(int8_t);
2,147,483,647✔
3295

3296
    int32_t bytes = pColInfoData->info.bytes;
2,147,483,647✔
3297
    *((int32_t*)data) = bytes;
2,147,483,647✔
3298
    if (IS_DECIMAL_TYPE(pColInfoData->info.type)) {
2,147,483,647✔
3299
      fillBytesForDecimalType((int32_t*)data, pColInfoData->info.type, pColInfoData->info.precision,
57,501,775✔
3300
                              pColInfoData->info.scale);
57,519,927✔
3301
    }
3302
    data += sizeof(int32_t);
2,147,483,647✔
3303
  }
3304

3305
  int32_t* colSizes = (int32_t*)data;
938,054,055✔
3306
  data += numOfCols * sizeof(int32_t);
938,054,055✔
3307

3308
  dataLen = internal ? blockDataGetSerialMetaSizeInternal(numOfCols) : blockDataGetSerialMetaSize(numOfCols);
938,066,975✔
3309
  blockSize = dataLen;
938,077,620✔
3310

3311
  int32_t numOfRows = pBlock->info.rows;
938,077,620✔
3312
  for (int32_t col = 0; col < numOfCols; ++col) {
2,147,483,647✔
3313
    SColumnInfoData* pColRes = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, col);
2,147,483,647✔
3314
    if (pColRes == NULL) {
2,147,483,647✔
3315
      return -1;
×
3316
    }
3317

3318
    // copy the null bitmap
3319
    size_t metaSize = 0;
2,147,483,647✔
3320
    if (IS_VAR_DATA_TYPE(pColRes->info.type)) {
2,147,483,647✔
3321
      if (IS_STR_DATA_BLOB(pColRes->info.type)) {
1,037,176,163✔
3322
        metaSize = numOfRows * sizeof(int32_t);
46,714✔
3323
        if (dataLen + metaSize > dataBuflen) goto _exit;
46,714✔
3324
        memcpy(data, pColRes->varmeta.offset, metaSize);
46,714✔
3325
      } else {
3326
        metaSize = numOfRows * sizeof(int32_t);
1,038,665,835✔
3327
        if (dataLen + metaSize > dataBuflen) goto _exit;
1,038,665,835✔
3328
        memcpy(data, pColRes->varmeta.offset, metaSize);
1,038,665,835✔
3329
      }
3330
    } else {
3331
      metaSize = BitmapLen(numOfRows);
2,147,483,647✔
3332
      if (dataLen + metaSize > dataBuflen) goto _exit;
2,147,483,647✔
3333
      memcpy(data, pColRes->nullbitmap, metaSize);
2,147,483,647✔
3334
    }
3335

3336
    data += metaSize;
2,147,483,647✔
3337
    dataLen += metaSize;
2,147,483,647✔
3338
    blockSize += metaSize;
2,147,483,647✔
3339
    TAOS_CHECK_GOTO(blockCheckSize(blockSize), NULL, _exit);
2,147,483,647✔
3340

3341
    if (pColRes->reassigned && IS_VAR_DATA_TYPE(pColRes->info.type)) {
2,147,483,647✔
3342
      colSizes[col] = 0;
×
3343
      for (int32_t row = 0; row < numOfRows; ++row) {
×
3344
        char*   pColData = pColRes->pData + pColRes->varmeta.offset[row];
×
3345
        int32_t colSize = calcStrBytesByType(pColRes->info.type, pColData);
×
3346

3347
        colSizes[col] += colSize;
×
3348
        dataLen += colSize;
×
3349
        if (dataLen > dataBuflen) goto _exit;
×
3350

3351
        blockSize += colSize;
×
3352
        TAOS_CHECK_GOTO(blockCheckSize(blockSize), NULL, _exit);
×
3353

3354
        (void)memmove(data, pColData, colSize);
×
3355
        data += colSize;
×
3356
      }
3357
    } else {
3358
      colSizes[col] = colDataGetLength(pColRes, numOfRows);
2,147,483,647✔
3359
      dataLen += colSizes[col];
2,147,483,647✔
3360
      if (dataLen > dataBuflen) goto _exit;
2,147,483,647✔
3361

3362
      blockSize += colSizes[col];
2,147,483,647✔
3363
      TAOS_CHECK_GOTO(blockCheckSize(blockSize), NULL, _exit);
2,147,483,647✔
3364

3365
      if (pColRes->pData != NULL) {
2,147,483,647✔
3366
        (void)memmove(data, pColRes->pData, colSizes[col]);
2,147,483,647✔
3367
      }
3368
      data += colSizes[col];
2,147,483,647✔
3369
    }
3370

3371
    if (colSizes[col] <= 0 && !colDataIsNull_s(pColRes, 0) && pColRes->info.type != TSDB_DATA_TYPE_NULL) {
2,147,483,647✔
3372
      uWarn("Invalid colSize:%d colIdx:%d colType:%d while encoding block", colSizes[col], col, pColRes->info.type);
822✔
3373
      //terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
3374
      //return -1;
3375
    }
3376

3377
    colSizes[col] = htonl(colSizes[col]);
2,147,483,647✔
3378
    //    uError("blockEncode col bytes:%d, type:%d, size:%d, htonl size:%d", pColRes->info.bytes, pColRes->info.type,
3379
    //    htonl(colSizes[col]), colSizes[col]);
3380
  }
3381

3382
  bool* blankFill = (bool*)data;
938,098,773✔
3383
  *blankFill = pBlock->info.blankFill;
938,098,773✔
3384
  data += sizeof(bool);
938,088,372✔
3385

3386
  if (internal) {
938,117,744✔
3387
    uint8_t* scanFlag = (uint8_t*)data;
49,871,253✔
3388
    *scanFlag = pBlock->info.scanFlag;
49,871,253✔
3389
    data += sizeof(uint8_t);
49,871,514✔
3390

3391
    uint64_t* baseGid = (uint64_t*)data;
49,871,514✔
3392
    *baseGid = pBlock->info.id.baseGId;
49,871,514✔
3393
    data += sizeof(uint64_t);
49,871,514✔
3394

3395
    // Slot ids used only for virtual super table scan: each column's slotId here
3396
    // refers to the slot position in virtual super table's datablock.
3397
    for (int32_t i = 0; i < numOfCols; ++i) {
170,777,266✔
3398
      SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
120,906,604✔
3399
      if (pColInfoData == NULL) {
120,905,998✔
3400
        return -1;
×
3401
      }
3402

3403
      *((int16_t *)data) = pColInfoData->info.slotId;
120,905,998✔
3404
      data += sizeof(int16_t);
120,905,998✔
3405
    }
3406
  }
3407

3408
  *actualLen = dataLen;
938,117,153✔
3409
#ifndef NO_UNALIGNED_ACCESS
3410
  *groupId = pBlock->info.id.groupId;
938,048,680✔
3411
#else
3412
  taosSetPUInt64Aligned(groupId, &pBlock->info.id.groupId);
3413
#endif
3414
  if (dataLen > dataBuflen) goto _exit;
938,064,390✔
3415

3416
  return dataLen;
938,064,390✔
3417

3418
_exit:
×
3419
  uError("blockEncode dataLen:%d, dataBuflen:%zu", dataLen, dataBuflen);
×
3420
  terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3421
  return -1;
×
3422
}
3423

3424
// return length of encoded data, return -1 if failed
3425
int32_t blockEncodeInternal(const SSDataBlock* pBlock, char* data, size_t dataBuflen, int32_t numOfCols) {
49,871,039✔
3426
  return blockEncodeImpl(pBlock, data, dataBuflen, numOfCols, true);
49,871,039✔
3427
}
3428

3429

3430
// return length of encoded data, return -1 if failed
3431
int32_t blockEncode(const SSDataBlock* pBlock, char* data, size_t dataBuflen, int32_t numOfCols) {
888,129,125✔
3432
  return blockEncodeImpl(pBlock, data, dataBuflen, numOfCols, false);
888,129,125✔
3433
}
3434

3435
int32_t blockDecodeImpl(SSDataBlock* pBlock, const char* pData, const char** pEndPos, bool internal) {
629,450,643✔
3436
  const char* pStart = pData;
629,450,643✔
3437

3438
  int32_t version = *(int32_t*)pStart;
629,450,643✔
3439
  pStart += sizeof(int32_t);
629,452,101✔
3440

3441
  // total length sizeof(int32_t)
3442
  int32_t dataLen = *(int32_t*)pStart;
629,451,913✔
3443
  pStart += sizeof(int32_t);
629,450,997✔
3444

3445
  // total rows sizeof(int32_t)
3446
  int32_t numOfRows = *(int32_t*)pStart;
629,451,936✔
3447
  pStart += sizeof(int32_t);
629,453,022✔
3448
  if (numOfRows <= 0) {
629,449,804✔
3449
    uError("block decode numOfRows:%d error", numOfRows);
×
3450
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3451
    return terrno;
×
3452
  }
3453

3454
  // total columns sizeof(int32_t)
3455
  int32_t numOfCols = *(int32_t*)pStart;
629,449,804✔
3456
  pStart += sizeof(int32_t);
629,450,887✔
3457

3458
  // has column info segment
3459
  int32_t flagSeg = *(int32_t*)pStart;
629,451,659✔
3460
  int32_t hasColumnInfo = (flagSeg >> 31);
629,452,574✔
3461
  pStart += sizeof(int32_t);
629,452,574✔
3462

3463
  // group id sizeof(uint64_t)
3464
#ifndef NO_UNALIGNED_ACCESS
3465
  pBlock->info.id.groupId = *(uint64_t*)pStart;
629,452,124✔
3466
#else
3467
  taosSetPUInt64Aligned(&pBlock->info.id.groupId, (uint64_t*)pStart);
3468
#endif
3469
  pStart += sizeof(uint64_t);
629,453,734✔
3470

3471
  if (pBlock->pDataBlock == NULL) {
629,451,943✔
3472
    pBlock->pDataBlock = taosArrayInit_s(sizeof(SColumnInfoData), numOfCols);
31,221,631✔
3473
    if (pBlock->pDataBlock == NULL) {
31,221,631✔
3474
      return terrno;
×
3475
    }
3476
  }
3477

3478
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
3479
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
2,147,483,647✔
3480
    if (pColInfoData == NULL) {
2,147,483,647✔
3481
      return terrno;
×
3482
    }
3483

3484
    pColInfoData->info.type = *(int8_t*)pStart;
2,147,483,647✔
3485
    pStart += sizeof(int8_t);
2,147,483,647✔
3486

3487
    pColInfoData->info.bytes = *(int32_t*)pStart;
2,147,483,647✔
3488
    if (IS_DECIMAL_TYPE(pColInfoData->info.type)) {
2,147,483,647✔
3489
      extractDecimalTypeInfoFromBytes(&pColInfoData->info.bytes, &pColInfoData->info.precision,
55,838,538✔
3490
                                      &pColInfoData->info.scale);
3491
    }
3492
    pStart += sizeof(int32_t);
2,147,483,647✔
3493

3494
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
2,147,483,647✔
3495
      pBlock->info.hasVarCol = true;
716,124,588✔
3496
    }
3497
  }
3498

3499
  int32_t code = blockDataEnsureCapacity(pBlock, numOfRows);
629,453,559✔
3500
  if (code) {
629,454,535✔
3501
    return code;
×
3502
  }
3503

3504
  int32_t* colLen = (int32_t*)pStart;
629,454,535✔
3505
  pStart += sizeof(int32_t) * numOfCols;
629,454,535✔
3506

3507
  for (int32_t i = 0; i < numOfCols; ++i) {
2,147,483,647✔
3508
    int oneColsLen = htonl(colLen[i]);
2,147,483,647✔
3509
    if (oneColsLen < 0) {
2,147,483,647✔
3510
      uError("block decode colLen:%d error, colIdx:%d", oneColsLen, i);
×
3511
      terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3512
      return terrno;
×
3513
    }
3514

3515
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
2,147,483,647✔
3516
    if (pColInfoData == NULL) {
2,147,483,647✔
3517
      return terrno;
×
3518
    }
3519

3520
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
2,147,483,647✔
3521
      memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
716,122,057✔
3522
      pStart += sizeof(int32_t) * numOfRows;
716,122,556✔
3523

3524
      if (oneColsLen > 0 && pColInfoData->varmeta.allocLen < oneColsLen) {
716,123,394✔
3525
        char* tmp = taosMemoryRealloc(pColInfoData->pData, oneColsLen);
370,927,157✔
3526
        if (tmp == NULL) {
370,926,862✔
3527
          return terrno;
×
3528
        }
3529

3530
        pColInfoData->pData = tmp;
370,926,862✔
3531
        pColInfoData->varmeta.allocLen = oneColsLen;
370,927,405✔
3532
      }
3533

3534
      pColInfoData->varmeta.length = oneColsLen;
716,123,642✔
3535
    } else {
3536
      memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
2,147,483,647✔
3537
      pStart += BitmapLen(numOfRows);
2,147,483,647✔
3538
    }
3539

3540
    // TODO
3541
    // setting this flag to true temporarily so aggregate function on stable will
3542
    // examine NULL value for non-primary key column
3543
    pColInfoData->hasNull = true;
2,147,483,647✔
3544

3545
    if (oneColsLen > 0) {
2,147,483,647✔
3546
      memcpy(pColInfoData->pData, pStart, oneColsLen);
2,147,483,647✔
3547
    } else if (!colDataIsNull_s(pColInfoData, 0) && pColInfoData->info.type != TSDB_DATA_TYPE_NULL) {
108,848,010✔
3548
      uError("block decode colLen:%d error, colIdx:%d, type:%d", oneColsLen, i, pColInfoData->info.type);
×
3549
      terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3550
      return terrno;
×
3551
    }
3552

3553
    pStart += oneColsLen;
2,147,483,647✔
3554
  }
3555

3556
  bool blankFill = *(bool*)pStart;
629,450,586✔
3557
  pStart += sizeof(bool);
629,453,613✔
3558

3559
  if (internal && (pStart - pData) < dataLen) {
629,454,418✔
3560
    pBlock->info.scanFlag = *(uint8_t*)pStart;
78,616,372✔
3561
    pStart += sizeof(uint8_t);
78,616,804✔
3562

3563
    pBlock->info.id.baseGId = *(uint64_t*)pStart;
78,616,417✔
3564
    pStart += sizeof(uint64_t);
78,616,804✔
3565
  }
3566

3567
  if (internal && (pStart - pData) < dataLen) {
629,454,344✔
3568
    for (int32_t i = 0; i < numOfCols; ++i) {
274,710,376✔
3569
      SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
196,093,769✔
3570
      if (pColInfoData == NULL) {
196,093,980✔
3571
        return terrno;
×
3572
      }
3573

3574
      pColInfoData->info.slotId = *(int16_t*)pStart;
196,093,980✔
3575
      pStart += sizeof(int16_t);
196,093,980✔
3576
    }
3577
  }
3578

3579
  pBlock->info.dataLoad = 1;
629,454,147✔
3580
  pBlock->info.rows = numOfRows;
629,453,234✔
3581
  pBlock->info.blankFill = blankFill;
629,453,211✔
3582
  if (internal && (pStart - pData != dataLen)) {
629,454,186✔
3583
    uError("block decode msg len error, pStart:%p, pData:%p, dataLen:%d", pStart, pData, dataLen);
×
3584
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
3585
    return terrno;
×
3586
  }
3587

3588
  if (pEndPos != NULL) {
629,454,186✔
3589
    *pEndPos = pStart;
624,050,757✔
3590
  }
3591

3592
  code = blockDataCheck(pBlock);
629,455,169✔
3593
  if (code != TSDB_CODE_SUCCESS) {
629,452,768✔
3594
    terrno = code;
×
3595
    return code;
×
3596
  }
3597

3598
  return TSDB_CODE_SUCCESS;
629,452,956✔
3599
}
3600

3601
int32_t blockDecodeInternal(SSDataBlock* pBlock, const char* pData, const char** pEndPos) {
625,620,181✔
3602
  return blockDecodeImpl(pBlock, pData, pEndPos, true);
625,620,181✔
3603
}
3604
int32_t blockDecode(SSDataBlock* pBlock, const char* pData, const char** pEndPos) {
3,830,962✔
3605
  return blockDecodeImpl(pBlock, pData, pEndPos, false);
3,830,962✔
3606
}
3607

3608
int32_t trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList) {
105,587,235✔
3609
  //  int32_t totalRows = pBlock->info.rows;
3610
  int32_t code = 0;
105,587,235✔
3611
  int32_t bmLen = BitmapLen(totalRows);
105,587,235✔
3612
  char*   pBitmap = NULL;
105,587,235✔
3613
  int32_t maxRows = 0;
105,587,235✔
3614

3615
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
105,587,235✔
3616
  if (!pBoolList) {
105,587,762✔
3617
    for (int32_t i = 0; i < numOfCols; ++i) {
271,865,499✔
3618
      SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i);
225,486,993✔
3619
      // it is a reserved column for scalar function, and no data in this column yet.
3620
      if (pDst->pData == NULL) {
225,486,197✔
3621
        continue;
7,098,454✔
3622
      }
3623

3624
      int32_t numOfRows = 0;
218,391,416✔
3625
      if (IS_VAR_DATA_TYPE(pDst->info.type)) {
218,391,416✔
3626
        pDst->varmeta.length = 0;
34,257,026✔
3627
      } else {
3628
        memset(pDst->nullbitmap, 0, bmLen);
184,143,155✔
3629
      }
3630
    }
3631
    return code;
46,378,506✔
3632
  }
3633

3634
  for (int32_t i = 0; i < numOfCols; ++i) {
276,897,390✔
3635
    SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i);
217,682,085✔
3636
    // it is a reserved column for scalar function, and no data in this column yet.
3637
    if (pDst->pData == NULL || (IS_VAR_DATA_TYPE(pDst->info.type) && pDst->varmeta.length == 0)) {
217,688,881✔
3638
      continue;
6,509,707✔
3639
    }
3640

3641
    int32_t numOfRows = 0;
211,188,284✔
3642
    if (IS_VAR_DATA_TYPE(pDst->info.type)) {
255,247,191✔
3643
      int32_t j = 0;
44,060,987✔
3644
      int32_t oriLen = colDataGetLength(pDst, totalRows);
44,060,987✔
3645
      char * tmp = (char*)taosMemoryMalloc(oriLen);
44,059,680✔
3646
      if (tmp == NULL) {
44,053,652✔
3647
        return terrno;
×
3648
      }
3649
      pDst->varmeta.length = 0;
44,053,652✔
3650
      while (j < totalRows) {
2,147,483,647✔
3651
        if (pBoolList[j] == 0) {
2,147,483,647✔
3652
          j += 1;
2,147,483,647✔
3653
          continue;
2,147,483,647✔
3654
        }
3655

3656
        if (colDataIsNull_var(pDst, j)) {
2,147,483,647✔
3657
          colDataSetNull_var(pDst, numOfRows);
1,838,242,563✔
3658
        } else {
3659
          char*   p1 = colDataGetVarData(pDst, j);
2,147,483,647✔
3660
          int32_t len = calcStrBytesByType(pDst->info.type, p1);
2,147,483,647✔
3661
          memcpy(tmp + pDst->varmeta.length, p1, len);
2,147,483,647✔
3662
          pDst->varmeta.offset[numOfRows] = pDst->varmeta.length;
2,147,483,647✔
3663
          pDst->varmeta.length += len;
2,147,483,647✔
3664
        }
3665
        numOfRows += 1;
2,147,483,647✔
3666
        j += 1;
2,147,483,647✔
3667
      }
3668
      taosMemoryFree(pDst->pData);
44,058,992✔
3669
      pDst->pData = tmp;
44,059,679✔
3670
      pDst->varmeta.allocLen = oriLen;
44,060,017✔
3671
      if (maxRows < numOfRows) {
44,058,907✔
3672
        maxRows = numOfRows;
9,519,005✔
3673
      }
3674
    } else {
3675
      if (pBitmap == NULL) {
167,130,188✔
3676
        pBitmap = taosMemoryCalloc(1, bmLen);
57,950,936✔
3677
        if (pBitmap == NULL) {
57,950,396✔
3678
          return terrno;
×
3679
        }
3680
      }
3681

3682
      memcpy(pBitmap, pDst->nullbitmap, bmLen);
167,129,648✔
3683
      memset(pDst->nullbitmap, 0, bmLen);
167,130,425✔
3684

3685
      int32_t j = 0;
167,135,664✔
3686

3687
      switch (pDst->info.type) {
167,135,664✔
3688
        case TSDB_DATA_TYPE_BIGINT:
98,309,727✔
3689
        case TSDB_DATA_TYPE_UBIGINT:
3690
        case TSDB_DATA_TYPE_DOUBLE:
3691
        case TSDB_DATA_TYPE_TIMESTAMP:
3692
          while (j < totalRows) {
2,147,483,647✔
3693
            if (pBoolList[j] == 0) {
2,147,483,647✔
3694
              j += 1;
2,147,483,647✔
3695
              continue;
2,147,483,647✔
3696
            }
3697

3698
            if (BMIsNull(pBitmap, j)) {
2,147,483,647✔
3699
              colDataSetNull_f(pDst->nullbitmap, numOfRows);
1,972,517,582✔
3700
            } else {
3701
              ((int64_t*)pDst->pData)[numOfRows] = ((int64_t*)pDst->pData)[j];
2,147,483,647✔
3702
            }
3703
            numOfRows += 1;
2,147,483,647✔
3704
            j += 1;
2,147,483,647✔
3705
          }
3706
          break;
100,130,408✔
3707
        case TSDB_DATA_TYPE_FLOAT:
38,395,984✔
3708
        case TSDB_DATA_TYPE_INT:
3709
        case TSDB_DATA_TYPE_UINT:
3710
          while (j < totalRows) {
2,147,483,647✔
3711
            if (pBoolList[j] == 0) {
2,147,483,647✔
3712
              j += 1;
2,147,483,647✔
3713
              continue;
2,147,483,647✔
3714
            }
3715
            if (BMIsNull(pBitmap, j)) {
2,147,483,647✔
3716
              colDataSetNull_f(pDst->nullbitmap, numOfRows);
2,004,323,662✔
3717
            } else {
3718
              ((int32_t*)pDst->pData)[numOfRows] = ((int32_t*)pDst->pData)[j];
2,147,483,647✔
3719
            }
3720
            numOfRows += 1;
2,147,483,647✔
3721
            j += 1;
2,147,483,647✔
3722
          }
3723
          break;
38,950,264✔
3724
        case TSDB_DATA_TYPE_SMALLINT:
11,111,122✔
3725
        case TSDB_DATA_TYPE_USMALLINT:
3726
          while (j < totalRows) {
2,147,483,647✔
3727
            if (pBoolList[j] == 0) {
2,147,483,647✔
3728
              j += 1;
2,147,483,647✔
3729
              continue;
2,147,483,647✔
3730
            }
3731
            if (BMIsNull(pBitmap, j)) {
2,147,483,647✔
3732
              colDataSetNull_f(pDst->nullbitmap, numOfRows);
1,339,492,898✔
3733
            } else {
3734
              ((int16_t*)pDst->pData)[numOfRows] = ((int16_t*)pDst->pData)[j];
1,337,150,050✔
3735
            }
3736
            numOfRows += 1;
2,147,483,647✔
3737
            j += 1;
2,147,483,647✔
3738
          }
3739
          break;
11,148,277✔
3740
        case TSDB_DATA_TYPE_BOOL:
16,908,715✔
3741
        case TSDB_DATA_TYPE_TINYINT:
3742
        case TSDB_DATA_TYPE_UTINYINT:
3743
          while (j < totalRows) {
2,147,483,647✔
3744
            if (pBoolList[j] == 0) {
2,147,483,647✔
3745
              j += 1;
2,147,483,647✔
3746
              continue;
2,147,483,647✔
3747
            }
3748
            if (BMIsNull(pBitmap, j)) {
2,147,483,647✔
3749
              colDataSetNull_f(pDst->nullbitmap, numOfRows);
1,779,582,003✔
3750
            } else {
3751
              ((int8_t*)pDst->pData)[numOfRows] = ((int8_t*)pDst->pData)[j];
2,147,483,647✔
3752
            }
3753
            numOfRows += 1;
2,147,483,647✔
3754
            j += 1;
2,147,483,647✔
3755
          }
3756
          break;
16,994,700✔
3757
        case TSDB_DATA_TYPE_DECIMAL64:
2,410,776✔
3758
        case TSDB_DATA_TYPE_DECIMAL:
3759
          while (j < totalRows) {
1,275,197,976✔
3760
            if (pBoolList[j] == 0) {
1,272,854,784✔
3761
              j += 1;
459,909,745✔
3762
              continue;
459,909,745✔
3763
            }
3764
            if (BMIsNull(pBitmap, j)) {
812,966,543✔
3765
              colDataSetNull_f(pDst->nullbitmap, numOfRows);
472,680✔
3766
            } else {
3767
              memcpy(pDst->pData + numOfRows * pDst->info.bytes, pDst->pData + j * pDst->info.bytes, pDst->info.bytes);
812,533,799✔
3768
            }
3769
            numOfRows += 1;
812,877,455✔
3770
            j += 1;
812,877,455✔
3771
          }
3772
          break;
2,343,192✔
3773
        case TSDB_DATA_TYPE_BLOB:
×
3774
        case TSDB_DATA_TYPE_MEDIUMBLOB: {
3775
          // impl later
3776
          break;
×
3777
        }
3778
      }
3779
    }
3780

3781
    if (maxRows < numOfRows) {
211,176,610✔
3782
      maxRows = numOfRows;
49,686,749✔
3783
    }
3784
  }
3785

3786
  pBlock->info.rows = maxRows;
59,215,305✔
3787
  if (pBitmap != NULL) {
59,212,335✔
3788
    taosMemoryFree(pBitmap);
57,953,962✔
3789
  }
3790

3791
  return code;
59,211,584✔
3792
}
3793

3794
int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
888,519,539✔
3795
  return blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSize(pBlock);
888,519,539✔
3796
}
3797

3798
int32_t blockGetInternalEncodeSize(const SSDataBlock* pBlock) {
63,349,043✔
3799
  return blockDataGetSerialMetaSizeInternal(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSize(pBlock);
63,349,043✔
3800
}
3801

3802

3803
int32_t blockDataGetSortedRows(SSDataBlock* pDataBlock, SArray* pOrderInfo) {
78,030,939✔
3804
  if (!pDataBlock || !pOrderInfo) return 0;
78,030,939✔
3805
  for (int32_t i = 0; i < taosArrayGetSize(pOrderInfo); ++i) {
156,068,626✔
3806
    SBlockOrderInfo* pOrder = taosArrayGet(pOrderInfo, i);
78,034,795✔
3807
    if (pOrder == NULL) {
78,035,759✔
3808
      continue;
×
3809
    }
3810

3811
    pOrder->pColData = taosArrayGet(pDataBlock->pDataBlock, pOrder->slotId);
78,035,759✔
3812
    if (pOrder->pColData == NULL) {
78,035,277✔
3813
      continue;
×
3814
    }
3815

3816
    pOrder->compFn = getKeyComparFunc(pOrder->pColData->info.type, pOrder->order);
78,035,277✔
3817
  }
3818

3819
  SSDataBlockSortHelper sortHelper = {.orderInfo = pOrderInfo, .pDataBlock = pDataBlock};
78,033,831✔
3820

3821
  int32_t rowIdx = 0, nextRowIdx = 1;
78,035,277✔
3822
  for (; rowIdx < pDataBlock->info.rows && nextRowIdx < pDataBlock->info.rows; ++rowIdx, ++nextRowIdx) {
2,147,483,647✔
3823
    if (dataBlockCompar(&nextRowIdx, &rowIdx, &sortHelper) < 0) {
2,147,483,647✔
3824
      break;
26,090,409✔
3825
    }
3826
  }
3827

3828
  return nextRowIdx;
78,035,759✔
3829
}
3830

3831
#define BLOCK_DATA_CHECK_TRESSA(o)                      \
3832
  if (!(o)) {                                           \
3833
    uError("blockDataCheck failed! line:%d", __LINE__); \
3834
    return TSDB_CODE_INTERNAL_ERROR;                    \
3835
  }
3836
int32_t blockDataCheck(const SSDataBlock* pDataBlock) {
2,147,483,647✔
3837
  if (tsSafetyCheckLevel == TSDB_SAFETY_CHECK_LEVELL_NEVER || NULL == pDataBlock || pDataBlock->info.rows == 0) {
2,147,483,647✔
3838
    return TSDB_CODE_SUCCESS;
838,457,495✔
3839
  }
3840

3841
  BLOCK_DATA_CHECK_TRESSA(pDataBlock->info.rows > 0);
2,147,483,647✔
3842
  if (!pDataBlock->info.dataLoad) {
2,147,483,647✔
3843
    return TSDB_CODE_SUCCESS;
258,913,604✔
3844
  }
3845

3846
  bool    isVarType = false;
2,147,483,647✔
3847
  int32_t colLen = 0;
2,147,483,647✔
3848
  int32_t nextPos = 0;
2,147,483,647✔
3849
  int64_t checkRows = 0;
2,147,483,647✔
3850
  int64_t typeValue = 0;
2,147,483,647✔
3851
  int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock);
2,147,483,647✔
3852
  for (int32_t i = 0; i < colNum; ++i) {
2,147,483,647✔
3853
    SColumnInfoData* pCol = (SColumnInfoData*)taosArrayGet(pDataBlock->pDataBlock, i);
2,147,483,647✔
3854
    BLOCK_DATA_CHECK_TRESSA(pCol != NULL);
2,147,483,647✔
3855
    isVarType = IS_VAR_DATA_TYPE(pCol->info.type);
2,147,483,647✔
3856
    checkRows = pDataBlock->info.rows;
2,147,483,647✔
3857
    if (pCol->info.noData == true) continue;
2,147,483,647✔
3858

3859
    if (isVarType) {
2,147,483,647✔
3860
      BLOCK_DATA_CHECK_TRESSA(pCol->varmeta.offset);
2,147,483,647✔
3861
    } else {
3862
      BLOCK_DATA_CHECK_TRESSA(pCol->nullbitmap);
2,147,483,647✔
3863
    }
3864

3865
    nextPos = -1;
2,147,483,647✔
3866
    for (int64_t r = 0; r < checkRows; ++r) {
2,147,483,647✔
3867
      if (tsSafetyCheckLevel <= TSDB_SAFETY_CHECK_LEVELL_NORMAL) break;
2,147,483,647✔
3868
      if (!colDataIsNull_s(pCol, r)) {
120,583,296✔
3869
        BLOCK_DATA_CHECK_TRESSA(pCol->pData);
60,291,648✔
3870
        BLOCK_DATA_CHECK_TRESSA(pCol->varmeta.length <= pCol->varmeta.allocLen);
60,291,648✔
3871

3872
        if (isVarType) {
60,291,648✔
3873
          BLOCK_DATA_CHECK_TRESSA(pCol->varmeta.allocLen > 0);
50,243,040✔
3874
          BLOCK_DATA_CHECK_TRESSA(pCol->varmeta.offset[r] <= pCol->varmeta.length);
50,243,040✔
3875
          if (pCol->reassigned) {
50,243,040✔
3876
            BLOCK_DATA_CHECK_TRESSA(pCol->varmeta.offset[r] >= 0);
×
3877
          } else if (0 == r || nextPos == -1) {
50,243,040✔
3878
            nextPos = pCol->varmeta.offset[r];
182,040✔
3879
          } else {
3880
            BLOCK_DATA_CHECK_TRESSA(pCol->varmeta.offset[r] == nextPos);
50,061,000✔
3881
          }
3882

3883
          char*   pColData = pCol->pData + pCol->varmeta.offset[r];
50,243,040✔
3884
          int32_t colSize = 0;
50,243,040✔
3885
          if (pCol->info.type == TSDB_DATA_TYPE_JSON) {
50,243,040✔
3886
            colLen = getJsonValueLen(pColData);
×
3887
          } else if (IS_STR_DATA_BLOB(pCol->info.type)) {
50,243,040✔
3888
            colLen = blobDataTLen(pColData);
×
3889
          } else {
3890
            colLen = varDataTLen(pColData);
50,243,040✔
3891
          }
3892

3893
          if (pCol->info.type == TSDB_DATA_TYPE_JSON) {
50,243,040✔
3894
            BLOCK_DATA_CHECK_TRESSA(colLen >= CHAR_BYTES);
×
3895
          } else if (IS_STR_DATA_BLOB(pCol->info.type)) {
50,243,040✔
3896
            // check or not
3897
          } else {
3898
            BLOCK_DATA_CHECK_TRESSA(colLen >= VARSTR_HEADER_SIZE);
50,243,040✔
3899
          }
3900
          if (pCol->reassigned) {
50,243,040✔
3901
            BLOCK_DATA_CHECK_TRESSA((pCol->varmeta.offset[r] + colLen) <= pCol->varmeta.length);
×
3902
          } else {
3903
            nextPos += colLen;
50,243,040✔
3904
            BLOCK_DATA_CHECK_TRESSA(nextPos <= pCol->varmeta.length);
50,243,040✔
3905
          }
3906
          typeValue = *(char*)(pCol->pData + pCol->varmeta.offset[r] + colLen - 1);
50,243,040✔
3907
        } else {
3908
          if (TSDB_DATA_TYPE_FLOAT == pCol->info.type) {
10,048,608✔
3909
            float v = 0;
×
3910
            GET_TYPED_DATA(v, float, pCol->info.type, colDataGetNumData(pCol, r),
×
3911
                           typeGetTypeModFromColInfo(&pCol->info));
3912
          } else if (TSDB_DATA_TYPE_DOUBLE == pCol->info.type) {
10,048,608✔
3913
            double v = 0;
×
3914
            GET_TYPED_DATA(v, double, pCol->info.type, colDataGetNumData(pCol, r),
×
3915
                           typeGetTypeModFromColInfo(&pCol->info));
3916
          } else if (IS_DECIMAL_TYPE(pCol->info.type)) {
10,048,608✔
3917
            // SKIP for decimal types
3918
          } else {
3919
            GET_TYPED_DATA(typeValue, int64_t, pCol->info.type, colDataGetNumData(pCol, r),
10,048,608✔
3920
                           typeGetTypeModFromColInfo(&pCol->info));
3921
          }
3922
        }
3923
      }
3924
    }
3925
  }
3926
  return TSDB_CODE_SUCCESS;
2,147,483,647✔
3927
}
3928

3929
int32_t getFirstNotSmallerThanTSRowNum(const char* pts, int32_t startRow, int32_t numOfRows, TSKEY ts) {
25,639,626✔
3930
  int32_t rowNum = -1;
25,639,626✔
3931
  if (numOfRows < 7) {
25,639,626✔
3932
    for (int32_t i = startRow; i < numOfRows; ++i) {
1,573,220✔
3933
      if (ts <= *(TSKEY*)(pts + i * sizeof(TSKEY))) {
1,573,220✔
3934
        rowNum = i;
1,562,345✔
3935
        break;
1,562,345✔
3936
      }
3937
    }
3938
    return rowNum;
1,562,345✔
3939
  }
3940

3941
  int32_t left = startRow;
24,077,281✔
3942
  int32_t right = numOfRows - 1;
24,077,281✔
3943
  rowNum = -1;
24,077,281✔
3944

3945
  while (left <= right) {
167,441,430✔
3946
    int32_t mid = left + (right - left) / 2;
143,364,149✔
3947
    TSKEY midValue = *(TSKEY*)(pts + mid * sizeof(TSKEY));
143,364,149✔
3948

3949
    if (midValue >= ts) {
143,364,149✔
3950
      rowNum = mid;
143,359,371✔
3951
      right = mid - 1;
143,359,371✔
3952
    } else {
3953
      left = mid + 1;
4,778✔
3954
    }
3955
  }
3956

3957
  return rowNum;
24,077,281✔
3958
}
3959

3960
int32_t getFirstBiggerThanTSRowNum(const char* pts, int32_t startRow, int32_t numOfRows, TSKEY ts) {
25,639,727✔
3961
  if (ts == INT64_MAX) return -1;
25,639,727✔
3962
  int32_t rowNum = -1;
23,675,318✔
3963
  if (numOfRows < 7) {
23,675,318✔
3964
    for (int32_t i = 0; i < numOfRows; ++i) {
135,150✔
3965
      if (ts < *(TSKEY*)(pts + i * sizeof(TSKEY))) {
104,175✔
3966
        rowNum = i;
×
3967
        break;
×
3968
      }
3969
    }
3970
    return rowNum;
30,975✔
3971
  }
3972
  int32_t left = startRow;
23,644,343✔
3973
  int32_t right = numOfRows - 1;
23,644,343✔
3974
  rowNum = -1;
23,644,343✔
3975
  while (left <= right) {
189,145,817✔
3976
    int32_t mid = left + (right - left) / 2;
165,501,474✔
3977
    TSKEY midValue = *(TSKEY*)(pts + mid * sizeof(TSKEY));
165,501,474✔
3978

3979
    if (midValue > ts) {
165,501,474✔
3980
      rowNum = mid;
3,940✔
3981
      right = mid - 1;
3,940✔
3982
    } else {
3983
      left = mid + 1;
165,497,534✔
3984
    }
3985
  }
3986
  return rowNum;
23,644,343✔
3987
}
3988

3989
int32_t getFirstNotBiggerThanTSRowNum(const char* pts, int32_t numOfRows, TSKEY ts) {
×
3990
  int32_t rowNum = -1;
×
3991
  for (int32_t i = numOfRows - 1; i >= 0; --i) {
×
3992
    if (ts >= *(TSKEY*)(pts + i * sizeof(TSKEY))) {
×
3993
      rowNum = i;
×
3994
      break;
×
3995
    }
3996
  }
3997
  return rowNum;
×
3998
}
3999

4000
static int32_t resetVarDataOffset(int32_t* pOffset, int32_t numOfRows) {
47,331,997✔
4001
  int32_t offset = 0;
47,331,997✔
4002
  for (int32_t i = 0; i < numOfRows; ++i) {
94,621,160✔
4003
    if (pOffset[i] < 0) {
94,621,059✔
4004
      continue;
47,289,163✔
4005
    } else {
4006
      offset = pOffset[i];
47,331,896✔
4007
      break;
47,331,896✔
4008
    }
4009
  }
4010
  if (offset > 0) {
47,331,997✔
4011
    for (int32_t i = 0; i < numOfRows; ++i) {
151,690✔
4012
      if (pOffset[i] < 0) {
147,750✔
4013
        continue;
73,875✔
4014
      }
4015
      pOffset[i] -= offset;
73,875✔
4016
    }
4017
  }
4018
  return offset;
47,331,997✔
4019
}
4020

4021
void colDataGetOffsetAndLen(const SColumnInfoData* pColumnInfoData, int32_t numOfRows, int32_t startIndex,  int32_t endIndex, int32_t* pOffset, int32_t* pLen) {
106,575,240✔
4022
  *pOffset = 0;
106,575,240✔
4023
  *pLen = 0;
106,575,240✔
4024
  if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
106,575,240✔
4025
    for (int32_t row = startIndex; row <= endIndex; ++row) {
94,625,782✔
4026
      if (pColumnInfoData->varmeta.offset[row] >= 0) {
94,625,782✔
4027
        *pOffset = pColumnInfoData->varmeta.offset[row];
47,334,356✔
4028
        break;
47,334,356✔
4029
      }
4030
    }
4031
    if (endIndex + 1 < numOfRows) {
47,334,356✔
4032
      for (int32_t row = endIndex + 1; row < numOfRows; ++row) {
10,244✔
4033
        if (pColumnInfoData->varmeta.offset[row] >= 0) {
10,244✔
4034
          *pLen = pColumnInfoData->varmeta.offset[row] - *pOffset;
5,122✔
4035
          return;
5,122✔
4036
        }
4037
      }
4038
    }
4039
    *pLen = pColumnInfoData->varmeta.length - *pOffset;
47,329,234✔
4040
  } else {
4041
    if (pColumnInfoData->info.type == TSDB_DATA_TYPE_NULL) {
59,240,884✔
4042
      return;
×
4043
    } else {
4044
      *pOffset = pColumnInfoData->info.bytes * startIndex;
59,240,884✔
4045
      *pLen = pColumnInfoData->info.bytes * (endIndex - startIndex + 1);
59,240,884✔
4046
    }
4047
  }
4048
}
4049

4050
size_t blockDataGetSizeOfRows(const SSDataBlock* pBlock, int32_t startIndex, int32_t endIndex) {
25,982,950✔
4051
  size_t total = 0;
25,982,950✔
4052
  size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
25,982,950✔
4053
  for (int32_t i = 0; i < numOfCols; ++i) {
79,270,046✔
4054
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
53,287,096✔
4055
    if (pColInfoData == NULL) {
53,287,620✔
4056
      continue;
×
4057
    }
4058

4059
    int32_t colSize = 0;
53,287,620✔
4060
    int32_t offset = 0;
53,287,620✔
4061
    int32_t numOfRows = endIndex - startIndex + 1;
53,287,620✔
4062

4063
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
53,287,620✔
4064
      total += sizeof(int32_t) * numOfRows;
23,667,178✔
4065
    } else {
4066
      if (pColInfoData->info.type != TSDB_DATA_TYPE_NULL) {
29,620,442✔
4067
        total += (pColInfoData->info.bytes * numOfRows) + BitmapLen(numOfRows);
29,620,196✔
4068
      }
4069
    }
4070

4071
    colDataGetOffsetAndLen(pColInfoData, pBlock->info.rows, startIndex, endIndex, &offset, &colSize);
53,287,620✔
4072
    total += colSize;
53,287,620✔
4073
  }
4074

4075
  return total;
25,982,950✔
4076
}
4077

4078
int32_t blockGetEncodeSizeOfRows(const SSDataBlock* pBlock, int32_t startIndex, int32_t endIndex){
25,982,950✔
4079
  return blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSizeOfRows(pBlock, startIndex, endIndex);
25,982,950✔
4080
}
4081

4082
// return error code if failed
4083
// pLen: return length of encoded data
4084
int32_t blockEncodeAsRows(const SSDataBlock* pBlock, char* data, size_t dataBuflen, int32_t numOfCols, int32_t startIndex, 
25,982,950✔
4085
                          int32_t endIndex, int32_t* pLen) {
4086
  *pLen = 0;
25,982,950✔
4087
  int32_t code = blockDataCheck(pBlock);
25,982,950✔
4088
  if (code != TSDB_CODE_SUCCESS) {
25,982,950✔
4089
    return code;
×
4090
  }
4091

4092
  int32_t dataLen = 0;
25,982,950✔
4093

4094
  // todo extract method
4095
  int32_t* version = (int32_t*)data;
25,982,950✔
4096
  *version = BLOCK_VERSION_1;
25,982,950✔
4097
  data += sizeof(int32_t);
25,982,950✔
4098

4099
  int32_t* actualLen = (int32_t*)data;
25,982,950✔
4100
  data += sizeof(int32_t);
25,982,950✔
4101

4102
  int32_t* rows = (int32_t*)data;
25,982,950✔
4103
  *rows = pBlock->info.rows;
25,982,950✔
4104
  data += sizeof(int32_t);
25,982,950✔
4105
  if (*rows <= 0) {
25,982,950✔
4106
    uError("Invalid rows %d in block", *rows);
×
4107
    return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4108
  }
4109
  if(*rows <= endIndex) {
25,982,950✔
4110
    uError("Invalid endIdex %d, there is %d rows in block", endIndex, *rows);
×
4111
    return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4112
  }
4113
  int32_t realRows = endIndex - startIndex + 1;
25,982,950✔
4114
  *rows = realRows;
25,982,950✔
4115

4116
  int32_t* cols = (int32_t*)data;
25,982,950✔
4117
  *cols = numOfCols;
25,982,950✔
4118
  data += sizeof(int32_t);
25,982,950✔
4119

4120
  // flag segment.
4121
  // the inital bit is for column info
4122
  int32_t* flagSegment = (int32_t*)data;
25,982,950✔
4123
  *flagSegment = (1 << 31);
25,982,950✔
4124

4125
  data += sizeof(int32_t);
25,982,950✔
4126

4127
  uint64_t* groupId = (uint64_t*)data;
25,982,950✔
4128
  data += sizeof(uint64_t);
25,982,950✔
4129

4130
  for (int32_t i = 0; i < numOfCols; ++i) {
79,270,570✔
4131
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
53,287,620✔
4132
    if (pColInfoData == NULL) {
53,287,620✔
4133
      return terrno;
×
4134
    }
4135

4136
    *((int8_t*)data) = pColInfoData->info.type;
53,287,620✔
4137
    data += sizeof(int8_t);
53,287,620✔
4138

4139
    int32_t bytes = pColInfoData->info.bytes;
53,287,620✔
4140
    *((int32_t*)data) = bytes;
53,287,620✔
4141
    if (IS_DECIMAL_TYPE(pColInfoData->info.type)) {
53,287,620✔
4142
      fillBytesForDecimalType((int32_t*)data, pColInfoData->info.type, pColInfoData->info.precision,
×
4143
                              pColInfoData->info.scale);
×
4144
    }
4145
    data += sizeof(int32_t);
53,287,620✔
4146
  }
4147

4148
  int32_t* colSizes = (int32_t*)data;
25,982,950✔
4149
  data += numOfCols * sizeof(int32_t);
25,982,950✔
4150

4151
  dataLen = blockDataGetSerialMetaSize(numOfCols);
25,982,950✔
4152

4153
  int32_t numOfRows = pBlock->info.rows;
25,982,950✔
4154
  for (int32_t col = 0; col < numOfCols; ++col) {
79,270,570✔
4155
    SColumnInfoData* pColRes = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, col);
53,287,620✔
4156
    if (pColRes == NULL) {
53,287,620✔
4157
      return terrno;
×
4158
    }
4159

4160
    // copy the null bitmap
4161
    size_t metaSize = 0;
53,287,620✔
4162
    if (IS_VAR_DATA_TYPE(pColRes->info.type)) {
53,287,620✔
4163
      metaSize = realRows * sizeof(int32_t);
23,667,178✔
4164
      if(dataLen + metaSize > dataBuflen) goto _exit;
23,667,178✔
4165
      TAOS_UNUSED(memcpy(data, (char*)pColRes->varmeta.offset + (startIndex * sizeof(int32_t)), metaSize));
23,667,178✔
4166
      TAOS_UNUSED(resetVarDataOffset((int32_t*)data, realRows));
23,667,178✔
4167
    } else {
4168
      metaSize = BitmapLen(realRows);
29,620,442✔
4169
      if(dataLen + metaSize > dataBuflen) goto _exit;
29,620,442✔
4170
      for (int32_t j = 0; j < realRows; ++j) {
2,147,483,647✔
4171
        if (colDataIsNull_f(pColRes, j + startIndex)) {
2,147,483,647✔
4172
          colDataSetNull_f(data, j);
1,063,110✔
4173
        }
4174
      }
4175
    }
4176

4177
    data += metaSize;
53,287,373✔
4178
    dataLen += metaSize;
53,287,373✔
4179

4180
    int32_t skipOffset;
5,994,467✔
4181
    colDataGetOffsetAndLen(pColRes, numOfRows, startIndex, endIndex, &skipOffset, &colSizes[col]);
53,287,373✔
4182
    dataLen += colSizes[col];
53,287,373✔
4183
    if (dataLen > dataBuflen) goto _exit;
53,287,620✔
4184
    if (pColRes->pData != NULL) {
53,287,620✔
4185
      (void)memmove(data, pColRes->pData + skipOffset, colSizes[col]);
53,287,620✔
4186
    }
4187
    data += colSizes[col];
53,287,620✔
4188

4189
    if (colSizes[col] <= 0 && !colDataIsNull_s(pColRes, 0) && pColRes->info.type != TSDB_DATA_TYPE_NULL) {
53,287,373✔
4190
      uError("Invalid colSize:%d colIdx:%d colType:%d while encoding block", colSizes[col], col, pColRes->info.type);
×
4191
      return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4192
    }
4193
    
4194
    colSizes[col] = htonl(colSizes[col]);
53,287,373✔
4195
    //    uError("blockEncode col bytes:%d, type:%d, size:%d, htonl size:%d", pColRes->info.bytes, pColRes->info.type,
4196
    //    htonl(colSizes[col]), colSizes[col]);
4197
  }
4198

4199
  bool* blankFill = (bool*)data;
25,982,950✔
4200
  *blankFill = pBlock->info.blankFill;
25,982,950✔
4201
  data += sizeof(bool);
25,982,950✔
4202

4203
  *actualLen = dataLen;
25,982,950✔
4204
#ifndef NO_UNALIGNED_ACCESS
4205
  *groupId = pBlock->info.id.groupId;
25,982,950✔
4206
#else
4207
  taosSetPUInt64Aligned(groupId, &pBlock->info.id.groupId);
4208
#endif
4209
  if (dataLen > dataBuflen) goto _exit;
25,982,950✔
4210

4211
  *pLen = dataLen;
25,982,950✔
4212
  return TSDB_CODE_SUCCESS;
25,982,950✔
4213
_exit:
×
4214
  uError("blockEncode dataLen:%d, dataBuflen:%zu", dataLen, dataBuflen);
×
4215
  return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4216
}
4217

4218
int32_t getTsColDataOffset(SSDataBlock* pBlock, int32_t* colLen, int32_t numOfRows, int32_t tsColSlotId, int32_t* pOffset) {
25,639,823✔
4219
  *pOffset = 0;
25,639,823✔
4220
  for (int32_t i = 0; i <= tsColSlotId; ++i) {
51,444,412✔
4221
    int oneColsLen = htonl(colLen[i]);
25,804,584✔
4222
    if (oneColsLen < 0) {
25,804,584✔
4223
      uError("block decode colLen:%d error, colIdx:%d", oneColsLen, i);
×
4224
      terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4225
      return terrno;
×
4226
    }
4227

4228
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
25,804,584✔
4229
    if (pColInfoData == NULL) {
25,804,685✔
4230
      return terrno;
96✔
4231
    }
4232

4233
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
25,804,589✔
4234
      *pOffset += sizeof(int32_t) * numOfRows;
×
4235
    } else {
4236
      *pOffset += BitmapLen(numOfRows);
25,804,589✔
4237
    }
4238
    if (i != tsColSlotId) {
25,804,589✔
4239
      *pOffset += oneColsLen;
164,862✔
4240
    }
4241
  }
4242
  return TSDB_CODE_SUCCESS;
25,639,828✔
4243
}
4244

4245
int32_t blockSpecialDecodeLaterPart(SSDataBlock* pBlock, const char* pData, int32_t tsColSlotId, TSKEY start, TSKEY end) {
25,639,621✔
4246
  int32_t code = TSDB_CODE_SUCCESS;
25,639,621✔
4247

4248
  const char* pStart = pData;
25,639,621✔
4249

4250
  int32_t version = *(int32_t*)pStart;
25,639,621✔
4251
  pStart += sizeof(int32_t);
25,639,621✔
4252

4253
  // total length sizeof(int32_t)
4254
  int32_t dataLen = *(int32_t*)pStart;
25,639,374✔
4255
  pStart += sizeof(int32_t);
25,639,374✔
4256

4257
  // total rows sizeof(int32_t)
4258
  int32_t numOfRows = *(int32_t*)pStart;
25,639,621✔
4259
  pStart += sizeof(int32_t);
25,639,621✔
4260
  if (numOfRows <= 0) {
25,639,374✔
4261
    uError("block decode numOfRows:%d error", numOfRows);
×
4262
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4263
    return terrno;
×
4264
  }
4265

4266
  // total columns sizeof(int32_t)
4267
  int32_t numOfCols = *(int32_t*)pStart;
25,639,374✔
4268
  pStart += sizeof(int32_t);
25,639,374✔
4269

4270
  // has column info segment
4271
  int32_t flagSeg = *(int32_t*)pStart;
25,639,374✔
4272
  int32_t hasColumnInfo = (flagSeg >> 31);
25,639,374✔
4273
  pStart += sizeof(int32_t);
25,639,374✔
4274

4275
  // group id sizeof(uint64_t)
4276
#ifndef NO_UNALIGNED_ACCESS
4277
  pBlock->info.id.groupId = *(uint64_t*)pStart;
25,639,621✔
4278
#else
4279
  taosSetPUInt64Aligned(&pBlock->info.id.groupId, (uint64_t*)pStart);
4280
#endif
4281
  pStart += sizeof(uint64_t);
25,639,621✔
4282

4283
  if (pBlock->pDataBlock == NULL) {
25,639,621✔
4284
    pBlock->pDataBlock = taosArrayInit_s(sizeof(SColumnInfoData), numOfCols);
25,638,949✔
4285
    if (pBlock->pDataBlock == NULL) {
25,639,818✔
4286
      return terrno;
672✔
4287
    }
4288
  }
4289

4290
  for (int32_t i = 0; i < numOfCols; ++i) {
77,895,856✔
4291
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
52,255,745✔
4292
    if (pColInfoData == NULL) {
52,255,649✔
4293
      return terrno;
×
4294
    }
4295

4296
    pColInfoData->info.type = *(int8_t*)pStart;
52,255,649✔
4297
    pStart += sizeof(int8_t);
52,255,649✔
4298

4299
    pColInfoData->info.bytes = *(int32_t*)pStart;
52,255,649✔
4300
    if (IS_DECIMAL_TYPE(pColInfoData->info.type)) {
52,255,649✔
4301
      extractDecimalTypeInfoFromBytes(&pColInfoData->info.bytes, &pColInfoData->info.precision,
96✔
4302
                                      &pColInfoData->info.scale);
4303
    }
4304
    pStart += sizeof(int32_t);
52,256,038✔
4305

4306
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
52,256,038✔
4307
      pBlock->info.hasVarCol = true;
23,665,511✔
4308
    }
4309
  }
4310

4311
  int32_t* colLen = (int32_t*)pStart;
25,640,111✔
4312
  pStart += sizeof(int32_t) * numOfCols;
25,640,111✔
4313

4314
  int32_t tsLen = htonl(colLen[tsColSlotId]);
25,640,111✔
4315
  int32_t tsColOffset;
1,994,941✔
4316
  code = getTsColDataOffset(pBlock, colLen, numOfRows, tsColSlotId, &tsColOffset);
25,640,111✔
4317
  if (code) {
25,639,530✔
4318
    return code;
×
4319
  }
4320
  const char* pts = pStart + tsColOffset;
25,639,530✔
4321
  int32_t     firstRowNum = getFirstNotSmallerThanTSRowNum(pts, 0, numOfRows, start);
25,639,530✔
4322
  if (firstRowNum < 0) {
25,639,919✔
4323
    pBlock->info.rows = 0;
×
4324
    return TSDB_CODE_SUCCESS;
×
4325
  }
4326
  int32_t lastRowNumNext = getFirstBiggerThanTSRowNum(pts, firstRowNum, numOfRows, end);
25,639,919✔
4327
  if (lastRowNumNext < 0) {
25,639,328✔
4328
    lastRowNumNext = numOfRows;
25,638,641✔
4329
  } else if (lastRowNumNext == 0) {
687✔
4330
    pBlock->info.rows = 0;
×
4331
    return TSDB_CODE_SUCCESS;
×
4332
  }
4333

4334
  int32_t realRows = lastRowNumNext - firstRowNum;
25,639,328✔
4335
  int32_t leftRows = numOfRows - lastRowNumNext;
25,639,328✔
4336

4337
  code = blockDataEnsureCapacity(pBlock, realRows);
25,639,328✔
4338
  if (code) {
25,638,237✔
4339
    return code;
×
4340
  }
4341

4342
  for (int32_t i = 0; i < numOfCols; ++i) {
77,893,230✔
4343
    int32_t oneColsLen = htonl(colLen[i]);
52,251,528✔
4344
    int32_t offset = 0;
52,251,528✔
4345
    int32_t leftlen = 0;
52,251,528✔
4346
    if (oneColsLen < 0) {
52,251,528✔
4347
      uError("block decode colLen:%d error, colIdx:%d", oneColsLen, i);
×
4348
      terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4349
      return terrno;
×
4350
    }
4351

4352
    SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
52,251,528✔
4353
    if (pColInfoData == NULL) {
52,251,816✔
4354
      return terrno;
×
4355
    }
4356

4357
    if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
52,251,816✔
4358
      pStart += sizeof(int32_t) * firstRowNum;
23,662,474✔
4359
      memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * realRows);
23,662,228✔
4360
      pStart += sizeof(int32_t) * realRows;
23,662,228✔
4361

4362
      offset = resetVarDataOffset(pColInfoData->varmeta.offset, realRows);
23,662,228✔
4363
      if (leftRows > 0) {
23,665,607✔
4364
        for (int32_t j = 0; j < leftRows; ++j) {
39,597✔
4365
          if (*((int32_t*)pStart + j) != -1) {
38,809✔
4366
            leftlen = oneColsLen - *((int32_t*)pStart + j);
19,700✔
4367
          }
4368
        }
4369
      }
4370
      oneColsLen -= (offset + leftlen);
23,665,607✔
4371
      pStart += sizeof(int32_t) * leftRows;
23,665,607✔
4372

4373
      if (oneColsLen > 0 && pColInfoData->varmeta.allocLen < oneColsLen) {
23,665,607✔
4374
        char* tmp = taosMemoryRealloc(pColInfoData->pData, oneColsLen);
23,665,607✔
4375
        if (tmp == NULL) {
23,665,405✔
4376
          return terrno;
×
4377
        }
4378

4379
        pColInfoData->pData = tmp;
23,665,405✔
4380
        pColInfoData->varmeta.allocLen = oneColsLen;
23,665,405✔
4381
      }
4382

4383
      pColInfoData->varmeta.length = oneColsLen;
23,665,405✔
4384
    } else {
4385
      offset = oneColsLen / numOfRows * firstRowNum;
28,589,588✔
4386
      if (leftRows > 0) {
28,589,588✔
4387
        leftlen = oneColsLen / numOfRows * leftRows;
788✔
4388
      }
4389
      oneColsLen -= (offset + leftlen);
28,589,588✔
4390

4391
      memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(realRows));
28,589,588✔
4392
      for (int32_t j = 0; j < realRows; ++j) {
2,147,483,647✔
4393
        if (BMIsNull(pStart, j + firstRowNum)) {
2,147,483,647✔
4394
          colDataSetNull_f(pColInfoData->nullbitmap, j);
1,063,110✔
4395
        }
4396
      }
4397
      pStart += BitmapLen(numOfRows);
28,589,589✔
4398
    }
4399

4400
    pColInfoData->hasNull = true;
52,255,240✔
4401

4402
    if (oneColsLen > 0) {
52,255,240✔
4403
      pStart += offset;
52,255,836✔
4404
      memcpy(pColInfoData->pData, pStart, oneColsLen);
52,255,836✔
4405
    } else if (!colDataIsNull_s(pColInfoData, 0) && pColInfoData->info.type != TSDB_DATA_TYPE_NULL) {
×
4406
      uError("block decode colLen:%d error, colIdx:%d, type:%d", oneColsLen, i, pColInfoData->info.type);
×
4407
      terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4408
      return terrno;
×
4409
    }
4410

4411
    pStart += oneColsLen;
52,254,993✔
4412
    pStart += leftlen;
52,254,993✔
4413
  }
4414

4415
  bool blankFill = *(bool*)pStart;
25,641,702✔
4416
  pStart += sizeof(bool);
25,641,702✔
4417

4418
  pBlock->info.dataLoad = 1;
25,641,702✔
4419
  pBlock->info.rows = realRows;
25,641,702✔
4420
  pBlock->info.blankFill = blankFill;
25,641,702✔
4421
  if (pStart - pData != dataLen) {
25,641,702✔
4422
    uError("block decode msg len error, pStart:%p, pData:%p, dataLen:%d", pStart, pData, dataLen);
×
4423
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4424
    return terrno;
×
4425
  }
4426

4427
  code = blockDataCheck(pBlock);
25,641,702✔
4428
  if (code != TSDB_CODE_SUCCESS) {
25,639,242✔
4429
    terrno = code;
96✔
4430
    return code;
×
4431
  }
4432

4433
  return TSDB_CODE_SUCCESS;
25,639,146✔
4434
}
4435

4436
int32_t getStreamBlockTS(SSDataBlock* pBlock, int32_t tsColSlotId, int32_t row, TSKEY* ts) {
47,315,222✔
4437
  if (pBlock == NULL || ts == NULL) {
47,315,222✔
4438
    return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4439
  }
4440

4441
  if (pBlock->info.rows <= 0) {
47,315,222✔
4442
    return TSDB_CODE_SUCCESS;
×
4443
  }
4444
  int32_t cols = taosArrayGetSize(pBlock->pDataBlock);
47,315,222✔
4445
  if (tsColSlotId < 0 || tsColSlotId >= cols) {
47,315,222✔
4446
    uError("Invalid tsColSlotId %d, block has %d columns", tsColSlotId, cols);
×
4447
    return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4448
  }
4449

4450
  SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, tsColSlotId);
47,315,222✔
4451
  if (pColInfoData == NULL) {
47,315,222✔
4452
    return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
4453
  }
4454

4455
  *ts = *(TSKEY*)(pColInfoData->pData + row * sizeof(TSKEY));
47,315,222✔
4456
  return TSDB_CODE_SUCCESS;
47,315,222✔
4457
}
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