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

#define _DEFAULT_SOURCE
S
slguan 已提交
17
#include "tdataformat.h"
S
Shengliang Guan 已提交
18
#include "tcoding.h"
S
log  
Shengliang Guan 已提交
19
#include "tlog.h"
H
more  
hzcheng 已提交
20

21
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
C
Cary Xu 已提交
22
#if 0
H
TD-1438  
Hongze Cheng 已提交
23
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
24
                               int limit2, int tRows, bool forceSetNull);
C
Cary Xu 已提交
25
#endif
L
Liu Jicong 已提交
26
int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
L
Liu Jicong 已提交
27
  int spaceNeeded = pCol->bytes * maxPoints;
S
Shengliang Guan 已提交
28
  if (IS_VAR_DATA_TYPE(pCol->type)) {
L
Liu Jicong 已提交
29
    spaceNeeded += sizeof(VarDataOffsetT) * maxPoints;
L
Liu Jicong 已提交
30
  }
C
Cary Xu 已提交
31
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
32 33 34 35
  int32_t nBitmapBytes = (int32_t)TD_BITMAP_BYTES(maxPoints);
  spaceNeeded += (int)nBitmapBytes;
  // TODO: Currently, the compression of bitmap parts is affiliated to the column data parts, thus allocate 1 more
  // TYPE_BYTES as to comprise complete TYPE_BYTES. Otherwise, invalid read/write would be triggered.
36 37
  // spaceNeeded += TYPE_BYTES[pCol->type]; // the bitmap part is append as a single part since 2022.04.03, thus remove
  // the additional space
C
Cary Xu 已提交
38
#endif
C
Cary Xu 已提交
39

S
Shengliang Guan 已提交
40
  if (pCol->spaceSize < spaceNeeded) {
wafwerar's avatar
wafwerar 已提交
41
    void *ptr = taosMemoryRealloc(pCol->pData, spaceNeeded);
S
Shengliang Guan 已提交
42 43
    if (ptr == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)spaceNeeded, strerror(errno));
L
Liu Jicong 已提交
44
      return -1;
L
Liu Jicong 已提交
45 46 47
    } else {
      pCol->pData = ptr;
      pCol->spaceSize = spaceNeeded;
48 49
    }
  }
C
Cary Xu 已提交
50
#ifdef TD_SUPPORT_BITMAP
51

C
Cary Xu 已提交
52 53 54 55
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
    pCol->dataOff = POINTER_SHIFT(pCol->pBitmap, nBitmapBytes);
  } else {
C
Cary Xu 已提交
56
    pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
L
Liu Jicong 已提交
57
  }
C
Cary Xu 已提交
58 59 60 61
#else
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->dataOff = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
  }
C
Cary Xu 已提交
62
#endif
L
Liu Jicong 已提交
63
  return 0;
64 65
}

H
hzcheng 已提交
66 67 68
/**
 * Duplicate the schema and return a new object
 */
H
Hongze Cheng 已提交
69
STSchema *tdDupSchema(const STSchema *pSchema) {
S
Shengliang Guan 已提交
70
  int       tlen = sizeof(STSchema) + sizeof(STColumn) * schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
71
  STSchema *tSchema = (STSchema *)taosMemoryMalloc(tlen);
H
hzcheng 已提交
72 73
  if (tSchema == NULL) return NULL;

H
Hongze Cheng 已提交
74
  memcpy((void *)tSchema, (void *)pSchema, tlen);
H
hzcheng 已提交
75 76 77 78

  return tSchema;
}

H
TD-27  
hzcheng 已提交
79 80 81
/**
 * Encode a schema to dst, and return the next pointer
 */
H
TD-353  
Hongze Cheng 已提交
82 83 84 85
int tdEncodeSchema(void **buf, STSchema *pSchema) {
  int tlen = 0;
  tlen += taosEncodeFixedI32(buf, schemaVersion(pSchema));
  tlen += taosEncodeFixedI32(buf, schemaNCols(pSchema));
H
TD-166  
hzcheng 已提交
86

H
TD-27  
hzcheng 已提交
87 88
  for (int i = 0; i < schemaNCols(pSchema); i++) {
    STColumn *pCol = schemaColAt(pSchema, i);
H
TD-353  
Hongze Cheng 已提交
89
    tlen += taosEncodeFixedI8(buf, colType(pCol));
C
Cary Xu 已提交
90
    tlen += taosEncodeFixedI8(buf, colSma(pCol));
H
TD-353  
Hongze Cheng 已提交
91
    tlen += taosEncodeFixedI16(buf, colColId(pCol));
92
    tlen += taosEncodeFixedI16(buf, colBytes(pCol));
H
TD-27  
hzcheng 已提交
93 94
  }

H
TD-353  
Hongze Cheng 已提交
95
  return tlen;
H
TD-27  
hzcheng 已提交
96 97 98 99 100
}

/**
 * Decode a schema from a binary.
 */
H
TD-353  
Hongze Cheng 已提交
101
void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
S
Shengliang Guan 已提交
102 103
  int             version = 0;
  int             numOfCols = 0;
H
TD-353  
Hongze Cheng 已提交
104
  STSchemaBuilder schemaBuilder;
H
TD-27  
hzcheng 已提交
105

H
TD-353  
Hongze Cheng 已提交
106 107
  buf = taosDecodeFixedI32(buf, &version);
  buf = taosDecodeFixedI32(buf, &numOfCols);
H
TD-27  
hzcheng 已提交
108

H
Hongze Cheng 已提交
109 110
  if (tdInitTSchemaBuilder(&schemaBuilder, version) < 0) return NULL;

H
TD-353  
Hongze Cheng 已提交
111
  for (int i = 0; i < numOfCols; i++) {
112
    col_type_t  type = 0;
C
Cary Xu 已提交
113
    int8_t      sma = TSDB_BSMA_TYPE_NONE;
114 115
    col_id_t    colId = 0;
    col_bytes_t bytes = 0;
H
TD-353  
Hongze Cheng 已提交
116
    buf = taosDecodeFixedI8(buf, &type);
C
Cary Xu 已提交
117
    buf = taosDecodeFixedI8(buf, &sma);
H
TD-353  
Hongze Cheng 已提交
118
    buf = taosDecodeFixedI16(buf, &colId);
119
    buf = taosDecodeFixedI32(buf, &bytes);
C
Cary Xu 已提交
120
    if (tdAddColToSchema(&schemaBuilder, type, sma, colId, bytes) < 0) {
H
Hongze Cheng 已提交
121 122 123
      tdDestroyTSchemaBuilder(&schemaBuilder);
      return NULL;
    }
H
TD-27  
hzcheng 已提交
124 125
  }

H
TD-353  
Hongze Cheng 已提交
126
  *pRSchema = tdGetSchemaFromBuilder(&schemaBuilder);
H
Hongze Cheng 已提交
127
  tdDestroyTSchemaBuilder(&schemaBuilder);
H
TD-353  
Hongze Cheng 已提交
128
  return buf;
H
Hongze Cheng 已提交
129 130
}

C
Cary Xu 已提交
131
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
132 133 134
  if (pBuilder == NULL) return -1;

  pBuilder->tCols = 256;
wafwerar's avatar
wafwerar 已提交
135
  pBuilder->columns = (STColumn *)taosMemoryMalloc(sizeof(STColumn) * pBuilder->tCols);
H
Hongze Cheng 已提交
136 137 138 139 140 141 142 143
  if (pBuilder->columns == NULL) return -1;

  tdResetTSchemaBuilder(pBuilder, version);
  return 0;
}

void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder) {
wafwerar's avatar
wafwerar 已提交
144
    taosMemoryFreeClear(pBuilder->columns);
H
Hongze Cheng 已提交
145 146 147
  }
}

C
Cary Xu 已提交
148
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
149 150 151
  pBuilder->nCols = 0;
  pBuilder->tlen = 0;
  pBuilder->flen = 0;
T
Tao Liu 已提交
152
  pBuilder->vlen = 0;
H
Hongze Cheng 已提交
153 154 155
  pBuilder->version = version;
}

C
Cary Xu 已提交
156
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t sma, col_id_t colId, col_bytes_t bytes) {
157
  if (!isValidDataType(type)) return -1;
H
Hongze Cheng 已提交
158 159 160

  if (pBuilder->nCols >= pBuilder->tCols) {
    pBuilder->tCols *= 2;
wafwerar's avatar
wafwerar 已提交
161
    STColumn *columns = (STColumn *)taosMemoryRealloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
T
tickduan 已提交
162 163
    if (columns == NULL) return -1;
    pBuilder->columns = columns;
H
Hongze Cheng 已提交
164 165 166 167 168
  }

  STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
  colSetType(pCol, type);
  colSetColId(pCol, colId);
C
Cary Xu 已提交
169
  colSetSma(pCol, sma);
H
Hongze Cheng 已提交
170 171 172
  if (pBuilder->nCols == 0) {
    colSetOffset(pCol, 0);
  } else {
S
Shengliang Guan 已提交
173
    STColumn *pTCol = &(pBuilder->columns[pBuilder->nCols - 1]);
H
Hongze Cheng 已提交
174 175 176 177 178
    colSetOffset(pCol, pTCol->offset + TYPE_BYTES[pTCol->type]);
  }

  if (IS_VAR_DATA_TYPE(type)) {
    colSetBytes(pCol, bytes);
T
Tao Liu 已提交
179 180
    pBuilder->tlen += (TYPE_BYTES[type] + bytes);
    pBuilder->vlen += bytes - sizeof(VarDataLenT);
H
Hongze Cheng 已提交
181 182 183
  } else {
    colSetBytes(pCol, TYPE_BYTES[type]);
    pBuilder->tlen += TYPE_BYTES[type];
T
Tao Liu 已提交
184
    pBuilder->vlen += TYPE_BYTES[type];
H
Hongze Cheng 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  }

  pBuilder->nCols++;
  pBuilder->flen += TYPE_BYTES[type];

  ASSERT(pCol->offset < pBuilder->flen);

  return 0;
}

STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder->nCols <= 0) return NULL;

  int tlen = sizeof(STSchema) + sizeof(STColumn) * pBuilder->nCols;

wafwerar's avatar
wafwerar 已提交
200
  STSchema *pSchema = (STSchema *)taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
201 202 203 204 205 206
  if (pSchema == NULL) return NULL;

  schemaVersion(pSchema) = pBuilder->version;
  schemaNCols(pSchema) = pBuilder->nCols;
  schemaTLen(pSchema) = pBuilder->tlen;
  schemaFLen(pSchema) = pBuilder->flen;
T
Tao Liu 已提交
207
  schemaVLen(pSchema) = pBuilder->vlen;
H
Hongze Cheng 已提交
208

C
Cary Xu 已提交
209
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
210
  schemaTLen(pSchema) += (int)TD_BITMAP_BYTES(schemaNCols(pSchema));
C
Cary Xu 已提交
211 212
#endif

H
Hongze Cheng 已提交
213 214
  memcpy(schemaColAt(pSchema, 0), pBuilder->columns, sizeof(STColumn) * pBuilder->nCols);

H
TD-27  
hzcheng 已提交
215 216 217
  return pSchema;
}

C
Cary Xu 已提交
218
#if 0
H
hzcheng 已提交
219 220 221
/**
 * Initialize a data row
 */
H
TD-90  
Hongze Cheng 已提交
222 223 224 225
void tdInitDataRow(SDataRow row, STSchema *pSchema) {
  dataRowSetLen(row, TD_DATA_ROW_HEAD_SIZE + schemaFLen(pSchema));
  dataRowSetVersion(row, schemaVersion(pSchema));
}
H
hzcheng 已提交
226

C
Cary Xu 已提交
227 228
SDataRow tdNewDataRowFromSchema(STSchema *pSchema) {
  int32_t size = dataRowMaxBytesFromSchema(pSchema);
H
hzcheng 已提交
229

wafwerar's avatar
wafwerar 已提交
230
  SDataRow row = taosMemoryMalloc(size);
C
Cary Xu 已提交
231
  if (row == NULL) return NULL;
H
hzcheng 已提交
232

C
Cary Xu 已提交
233 234 235
  tdInitDataRow(row, pSchema);
  return row;
}
H
hzcheng 已提交
236

H
hzcheng 已提交
237 238 239
/**
 * Free the SDataRow object
 */
C
Cary Xu 已提交
240
void tdFreeDataRow(SDataRow row) {
wafwerar's avatar
wafwerar 已提交
241
  if (row) taosMemoryFree(row);
C
Cary Xu 已提交
242
}
C
Cary Xu 已提交
243

C
Cary Xu 已提交
244
SDataRow tdDataRowDup(SDataRow row) {
wafwerar's avatar
wafwerar 已提交
245
  SDataRow trow = taosMemoryMalloc(dataRowLen(row));
C
Cary Xu 已提交
246
  if (trow == NULL) return NULL;
H
hzcheng 已提交
247

C
Cary Xu 已提交
248 249 250
  dataRowCpy(trow, row);
  return trow;
}
C
Cary Xu 已提交
251 252

SMemRow tdMemRowDup(SMemRow row) {
wafwerar's avatar
wafwerar 已提交
253
  SMemRow trow = taosMemoryMalloc(memRowTLen(row));
H
hzcheng 已提交
254 255
  if (trow == NULL) return NULL;

C
Cary Xu 已提交
256
  memRowCpy(trow, row);
H
hzcheng 已提交
257
  return trow;
H
hzcheng 已提交
258
}
C
Cary Xu 已提交
259
#endif
C
Cary Xu 已提交
260

261
void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) {
H
TD-166  
hzcheng 已提交
262 263 264
  pDataCol->type = colType(pCol);
  pDataCol->colId = colColId(pCol);
  pDataCol->bytes = colBytes(pCol);
S
Shengliang Guan 已提交
265
  pDataCol->offset = colOffset(pCol) + 0;  // TD_DATA_ROW_HEAD_SIZE;
H
TD-166  
hzcheng 已提交
266 267 268

  pDataCol->len = 0;
}
H
Hongze Cheng 已提交
269
// value from timestamp should be TKEY here instead of TSKEY
L
Liu Jicong 已提交
270
int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints) {
H
TD-166  
hzcheng 已提交
271 272
  ASSERT(pCol != NULL && value != NULL);

K
kailixu 已提交
273 274 275
  if (isAllRowsNull(pCol)) {
    if (isNull(value, pCol->type)) {
      // all null value yet, just return
L
Liu Jicong 已提交
276
      return 0;
K
kailixu 已提交
277 278
    }

S
Shengliang Guan 已提交
279
    if (tdAllocMemForCol(pCol, maxPoints) < 0) return -1;
K
kailixu 已提交
280 281
    if (numOfRows > 0) {
      // Find the first not null value, fill all previouse values as NULL
L
Liu Jicong 已提交
282
      dataColSetNEleNull(pCol, numOfRows);
K
kailixu 已提交
283 284 285
    }
  }

H
Hongze Cheng 已提交
286 287 288 289 290 291 292
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    // set offset
    pCol->dataOff[numOfRows] = pCol->len;
    // Copy data
    memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, varDataTLen(value));
    // Update the length
    pCol->len += varDataTLen(value);
H
TD-166  
hzcheng 已提交
293
  } else {
H
Haojun Liao 已提交
294
    ASSERT(pCol->len == TYPE_BYTES[pCol->type] * numOfRows);
H
Hongze Cheng 已提交
295 296
    memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, pCol->bytes);
    pCol->len += pCol->bytes;
H
TD-166  
hzcheng 已提交
297
  }
L
Liu Jicong 已提交
298 299 300 301 302 303 304 305 306
  return 0;
}

static FORCE_INLINE const void *tdGetColDataOfRowUnsafe(SDataCol *pCol, int row) {
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    return POINTER_SHIFT(pCol->pData, pCol->dataOff[row]);
  } else {
    return POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * row);
  }
H
TD-166  
hzcheng 已提交
307 308
}

H
TD-166  
hzcheng 已提交
309
bool isNEleNull(SDataCol *pCol, int nEle) {
S
Shengliang Guan 已提交
310
  if (isAllRowsNull(pCol)) return true;
311
  for (int i = 0; i < nEle; ++i) {
L
Liu Jicong 已提交
312
    if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
H
TD-166  
hzcheng 已提交
313
  }
H
Hongze Cheng 已提交
314
  return true;
H
TD-166  
hzcheng 已提交
315 316
}

317
static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) {
H
TD-90  
Hongze Cheng 已提交
318 319 320
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->dataOff[index] = pCol->len;
    char *ptr = POINTER_SHIFT(pCol->pData, pCol->len);
321
    setVardataNull(ptr, pCol->type);
H
TD-90  
Hongze Cheng 已提交
322 323 324 325 326 327 328
    pCol->len += varDataTLen(ptr);
  } else {
    setNull(POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * index), pCol->type, pCol->bytes);
    pCol->len += TYPE_BYTES[pCol->type];
  }
}

329
static void dataColSetNEleNull(SDataCol *pCol, int nEle) {
H
TD-90  
Hongze Cheng 已提交
330 331
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->len = 0;
332
    for (int i = 0; i < nEle; ++i) {
H
TD-90  
Hongze Cheng 已提交
333 334 335 336 337
      dataColSetNullAt(pCol, i);
    }
  } else {
    setNullN(pCol->pData, pCol->type, pCol->bytes, nEle);
    pCol->len = TYPE_BYTES[pCol->type] * nEle;
H
TD-166  
hzcheng 已提交
338 339 340
  }
}

C
Cary Xu 已提交
341
void *dataColSetOffset(SDataCol *pCol, int nEle) {
H
TD-166  
hzcheng 已提交
342 343
  ASSERT(((pCol->type == TSDB_DATA_TYPE_BINARY) || (pCol->type == TSDB_DATA_TYPE_NCHAR)));

H
Hongze Cheng 已提交
344
  void *tptr = pCol->pData;
H
TD-166  
hzcheng 已提交
345
  // char *tptr = (char *)(pCol->pData);
H
TD-166  
hzcheng 已提交
346

H
TD-166  
hzcheng 已提交
347
  VarDataOffsetT offset = 0;
348
  for (int i = 0; i < nEle; ++i) {
H
TD-166  
hzcheng 已提交
349
    pCol->dataOff[i] = offset;
H
TD-166  
hzcheng 已提交
350
    offset += varDataTLen(tptr);
H
hzcheng 已提交
351
    tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
352
  }
C
Cary Xu 已提交
353
  return POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
354 355
}

L
Liu Jicong 已提交
356
SDataCols *tdNewDataCols(int maxCols, int maxRows) {
wafwerar's avatar
wafwerar 已提交
357
  SDataCols *pCols = (SDataCols *)taosMemoryCalloc(1, sizeof(SDataCols));
H
Haojun Liao 已提交
358
  if (pCols == NULL) {
S
Shengliang Guan 已提交
359
    uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCols), strerror(errno));
H
Haojun Liao 已提交
360 361
    return NULL;
  }
H
TD-34  
hzcheng 已提交
362

H
Hongze Cheng 已提交
363
  pCols->maxPoints = maxRows;
L
Liu Jicong 已提交
364 365 366
  pCols->maxCols = maxCols;
  pCols->numOfRows = 0;
  pCols->numOfCols = 0;
H
Hongze Cheng 已提交
367 368

  if (maxCols > 0) {
wafwerar's avatar
wafwerar 已提交
369
    pCols->cols = (SDataCol *)taosMemoryCalloc(maxCols, sizeof(SDataCol));
H
Hongze Cheng 已提交
370 371 372 373 374 375
    if (pCols->cols == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols,
             strerror(errno));
      tdFreeDataCols(pCols);
      return NULL;
    }
376
#if 0  // no need as calloc used
L
Liu Jicong 已提交
377
    int i;
S
Shengliang Guan 已提交
378
    for (i = 0; i < maxCols; i++) {
L
Liu Jicong 已提交
379
      pCols->cols[i].spaceSize = 0;
L
Liu Jicong 已提交
380
      pCols->cols[i].len = 0;
L
Liu Jicong 已提交
381 382 383
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
    }
384
#endif
H
Hongze Cheng 已提交
385 386
  }

H
TD-34  
hzcheng 已提交
387 388 389
  return pCols;
}

H
Hongze Cheng 已提交
390
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
391 392
  int i;
  int oldMaxCols = pCols->maxCols;
L
Liu Jicong 已提交
393
  if (schemaNCols(pSchema) > oldMaxCols) {
H
Hongze Cheng 已提交
394
    pCols->maxCols = schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
395
    void *ptr = (SDataCol *)taosMemoryRealloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
L
Liu Jicong 已提交
396 397
    if (ptr == NULL) return -1;
    pCols->cols = ptr;
398
    for (i = oldMaxCols; i < pCols->maxCols; ++i) {
399 400
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
401
      pCols->cols[i].pBitmap = NULL;
L
Liu Jicong 已提交
402
      pCols->cols[i].spaceSize = 0;
403
    }
L
Liu Jicong 已提交
404
  }
405 406 407
#if 0
  tdResetDataCols(pCols); // redundant loop to reset len/blen to 0, already reset in following dataColInit(...)
#endif
H
Hongze Cheng 已提交
408

409
  pCols->numOfRows = 0;
H
TD-34  
hzcheng 已提交
410 411
  pCols->numOfCols = schemaNCols(pSchema);

412
  for (i = 0; i < schemaNCols(pSchema); ++i) {
413
    dataColInit(pCols->cols + i, schemaColAt(pSchema, i), pCols->maxPoints);
H
TD-34  
hzcheng 已提交
414
  }
S
Shengliang Guan 已提交
415

H
Hongze Cheng 已提交
416
  return 0;
H
TD-34  
hzcheng 已提交
417 418
}

H
Hongze Cheng 已提交
419
SDataCols *tdFreeDataCols(SDataCols *pCols) {
420
  int i;
H
TD-34  
hzcheng 已提交
421
  if (pCols) {
S
Shengliang Guan 已提交
422
    if (pCols->cols) {
423
      int maxCols = pCols->maxCols;
424
      for (i = 0; i < maxCols; ++i) {
425
        SDataCol *pCol = &pCols->cols[i];
wafwerar's avatar
wafwerar 已提交
426
        taosMemoryFreeClear(pCol->pData);
427
      }
wafwerar's avatar
wafwerar 已提交
428
      taosMemoryFree(pCols->cols);
429 430
      pCols->cols = NULL;
    }
wafwerar's avatar
wafwerar 已提交
431
    taosMemoryFree(pCols);
H
TD-34  
hzcheng 已提交
432
  }
H
Hongze Cheng 已提交
433
  return NULL;
H
TD-34  
hzcheng 已提交
434 435
}

C
Cary Xu 已提交
436
#if 0
H
TD-100  
hzcheng 已提交
437
SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
L
Liu Jicong 已提交
438
  SDataCols *pRet = tdNewDataCols(pDataCols->maxCols, pDataCols->maxPoints);
H
TD-100  
hzcheng 已提交
439 440 441 442
  if (pRet == NULL) return NULL;

  pRet->numOfCols = pDataCols->numOfCols;
  pRet->sversion = pDataCols->sversion;
H
Haojun Liao 已提交
443
  if (keepData) pRet->numOfRows = pDataCols->numOfRows;
H
TD-100  
hzcheng 已提交
444 445 446

  for (int i = 0; i < pDataCols->numOfCols; i++) {
    pRet->cols[i].type = pDataCols->cols[i].type;
C
Cary Xu 已提交
447
    pRet->cols[i].bitmap = pDataCols->cols[i].bitmap;
H
TD-100  
hzcheng 已提交
448 449 450
    pRet->cols[i].colId = pDataCols->cols[i].colId;
    pRet->cols[i].bytes = pDataCols->cols[i].bytes;
    pRet->cols[i].offset = pDataCols->cols[i].offset;
H
TD-166  
hzcheng 已提交
451 452

    if (keepData) {
L
Liu Jicong 已提交
453
      if (pDataCols->cols[i].len > 0) {
S
Shengliang Guan 已提交
454
        if (tdAllocMemForCol(&pRet->cols[i], pRet->maxPoints) < 0) {
L
Liu Jicong 已提交
455 456 457
          tdFreeDataCols(pRet);
          return NULL;
        }
L
Liu Jicong 已提交
458
        pRet->cols[i].len = pDataCols->cols[i].len;
H
Hongze Cheng 已提交
459
        memcpy(pRet->cols[i].pData, pDataCols->cols[i].pData, pDataCols->cols[i].len);
H
Hongze Cheng 已提交
460
        if (IS_VAR_DATA_TYPE(pRet->cols[i].type)) {
L
Liu Jicong 已提交
461 462
          int dataOffSize = sizeof(VarDataOffsetT) * pDataCols->maxPoints;
          memcpy(pRet->cols[i].dataOff, pDataCols->cols[i].dataOff, dataOffSize);
H
Hongze Cheng 已提交
463
        }
H
TD-166  
hzcheng 已提交
464 465
      }
    }
H
TD-100  
hzcheng 已提交
466 467 468 469
  }

  return pRet;
}
C
Cary Xu 已提交
470
#endif
H
TD-100  
hzcheng 已提交
471

H
TD-34  
hzcheng 已提交
472
void tdResetDataCols(SDataCols *pCols) {
B
Bomin Zhang 已提交
473 474
  if (pCols != NULL) {
    pCols->numOfRows = 0;
475
    for (int i = 0; i < pCols->maxCols; ++i) {
B
Bomin Zhang 已提交
476 477
      dataColReset(pCols->cols + i);
    }
H
TD-34  
hzcheng 已提交
478 479
  }
}
C
Cary Xu 已提交
480
#if 0
481
static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) {
H
TD-1548  
Hongze Cheng 已提交
482
  ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < dataRowKey(row));
H
TD-166  
hzcheng 已提交
483

C
Cary Xu 已提交
484
  int rcol = 0;
H
TD-90  
Hongze Cheng 已提交
485 486
  int dcol = 0;

487
  while (dcol < pCols->numOfCols) {
488
    bool setCol = 0;
489 490 491 492 493
    SDataCol *pDataCol = &(pCols->cols[dcol]);
    if (rcol >= schemaNCols(pSchema)) {
      dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
      dcol++;
      continue;
H
TD-90  
Hongze Cheng 已提交
494
    }
H
TD-166  
hzcheng 已提交
495

496 497 498
    STColumn *pRowCol = schemaColAt(pSchema, rcol);
    if (pRowCol->colId == pDataCol->colId) {
      void *value = tdGetRowDataOfCol(row, pRowCol->type, pRowCol->offset + TD_DATA_ROW_HEAD_SIZE);
499
      if(!isNull(value, pDataCol->type)) setCol = 1;
500 501 502 503 504 505
      dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints);
      dcol++;
      rcol++;
    } else if (pRowCol->colId < pDataCol->colId) {
      rcol++;
    } else {
506
      if(forceSetNull || setCol) {
507
        dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
C
Cary Xu 已提交
508
      }
509
      dcol++;
C
Cary Xu 已提交
510 511 512 513 514
    }
  }
  pCols->numOfRows++;
}

C
Cary Xu 已提交
515
static void tdAppendKVRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) {
C
Cary Xu 已提交
516 517 518 519 520
  ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < kvRowKey(row));

  int rcol = 0;
  int dcol = 0;

521 522 523
  int nRowCols = kvRowNCols(row);

  while (dcol < pCols->numOfCols) {
524
    bool setCol = 0;
525 526 527 528 529
    SDataCol *pDataCol = &(pCols->cols[dcol]);
    if (rcol >= nRowCols || rcol >= schemaNCols(pSchema)) {
      dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
      ++dcol;
      continue;
C
Cary Xu 已提交
530 531
    }

532 533 534 535
    SColIdx *colIdx = kvRowColIdxAt(row, rcol);

    if (colIdx->colId == pDataCol->colId) {
      void *value = tdGetKvRowDataOfCol(row, colIdx->offset);
536
      if(!isNull(value, pDataCol->type)) setCol = 1;
537 538 539 540 541 542
      dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints);
      ++dcol;
      ++rcol;
    } else if (colIdx->colId < pDataCol->colId) {
      ++rcol;
    } else {
543
      if(forceSetNull || setCol) {
C
Cary Xu 已提交
544
        dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
H
TD-1548  
Hongze Cheng 已提交
545
      }
546
      ++dcol;
H
TD-90  
Hongze Cheng 已提交
547
    }
H
TD-34  
hzcheng 已提交
548
  }
H
Haojun Liao 已提交
549
  pCols->numOfRows++;
H
TD-34  
hzcheng 已提交
550
}
H
TD-166  
hzcheng 已提交
551

552
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) {
C
Cary Xu 已提交
553
  if (isDataRow(row)) {
554
    tdAppendDataRowToDataCol(memRowDataBody(row), pSchema, pCols, forceSetNull);
C
Cary Xu 已提交
555
  } else if (isKvRow(row)) {
C
Cary Xu 已提交
556
    tdAppendKVRowToDataCol(memRowKvBody(row), pSchema, pCols, forceSetNull);
C
Cary Xu 已提交
557 558 559 560 561
  } else {
    ASSERT(0);
  }
}

562
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset, bool forceSetNull) {
H
Haojun Liao 已提交
563
  ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
H
TD-166  
hzcheng 已提交
564
  ASSERT(target->numOfCols == source->numOfCols);
H
Hongze Cheng 已提交
565 566 567 568 569
  int offset = 0;

  if (pOffset == NULL) {
    pOffset = &offset;
  }
H
TD-100  
hzcheng 已提交
570

H
TD-166  
hzcheng 已提交
571
  SDataCols *pTarget = NULL;
H
TD-100  
hzcheng 已提交
572

573
  if ((target->numOfRows == 0) || (dataColsKeyLast(target) < dataColsKeyAtRow(source, *pOffset))) {  // No overlap
H
Hongze Cheng 已提交
574
    ASSERT(target->numOfRows + rowsToMerge <= target->maxPoints);
H
TD-166  
hzcheng 已提交
575 576
    for (int i = 0; i < rowsToMerge; i++) {
      for (int j = 0; j < source->numOfCols; j++) {
577
        if (source->cols[j].len > 0 || target->cols[j].len > 0) {
H
Hongze Cheng 已提交
578
          dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i + (*pOffset)), target->numOfRows,
H
Hongze Cheng 已提交
579 580
                           target->maxPoints);
        }
H
TD-166  
hzcheng 已提交
581
      }
H
Haojun Liao 已提交
582
      target->numOfRows++;
H
TD-166  
hzcheng 已提交
583
    }
L
lichuang 已提交
584
    (*pOffset) += rowsToMerge;
H
TD-166  
hzcheng 已提交
585 586 587 588 589
  } else {
    pTarget = tdDupDataCols(target, true);
    if (pTarget == NULL) goto _err;

    int iter1 = 0;
H
Hongze Cheng 已提交
590
    tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, pOffset, source->numOfRows,
591
                       pTarget->numOfRows + rowsToMerge, forceSetNull);
H
TD-166  
hzcheng 已提交
592
  }
H
TD-100  
hzcheng 已提交
593 594 595 596 597 598 599 600

  tdFreeDataCols(pTarget);
  return 0;

_err:
  tdFreeDataCols(pTarget);
  return -1;
}
H
TD-100  
hzcheng 已提交
601

H
TD-1438  
Hongze Cheng 已提交
602 603
// src2 data has more priority than src1
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
604
                               int limit2, int tRows, bool forceSetNull) {
H
TD-100  
hzcheng 已提交
605
  tdResetDataCols(target);
H
TD-521  
Hongze Cheng 已提交
606
  ASSERT(limit1 <= src1->numOfRows && limit2 <= src2->numOfRows);
H
TD-100  
hzcheng 已提交
607

H
Haojun Liao 已提交
608
  while (target->numOfRows < tRows) {
H
TD-521  
Hongze Cheng 已提交
609
    if (*iter1 >= limit1 && *iter2 >= limit2) break;
H
TD-100  
hzcheng 已提交
610

H
TD-1548  
Hongze Cheng 已提交
611 612 613 614 615 616
    TSKEY key1 = (*iter1 >= limit1) ? INT64_MAX : dataColsKeyAt(src1, *iter1);
    TKEY  tkey1 = (*iter1 >= limit1) ? TKEY_NULL : dataColsTKeyAt(src1, *iter1);
    TSKEY key2 = (*iter2 >= limit2) ? INT64_MAX : dataColsKeyAt(src2, *iter2);
    TKEY  tkey2 = (*iter2 >= limit2) ? TKEY_NULL : dataColsTKeyAt(src2, *iter2);

    ASSERT(tkey1 == TKEY_NULL || (!TKEY_IS_DELETED(tkey1)));
H
TD-100  
hzcheng 已提交
617

H
TD-1438  
Hongze Cheng 已提交
618
    if (key1 < key2) {
H
TD-100  
hzcheng 已提交
619 620
      for (int i = 0; i < src1->numOfCols; i++) {
        ASSERT(target->cols[i].type == src1->cols[i].type);
621
        if (src1->cols[i].len > 0 || target->cols[i].len > 0) {
H
Hongze Cheng 已提交
622 623 624
          dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfRows,
                           target->maxPoints);
        }
H
TD-100  
hzcheng 已提交
625 626
      }

H
Haojun Liao 已提交
627
      target->numOfRows++;
H
TD-100  
hzcheng 已提交
628
      (*iter1)++;
H
TD-1548  
Hongze Cheng 已提交
629 630 631 632
    } else if (key1 >= key2) {
      if ((key1 > key2) || (key1 == key2 && !TKEY_IS_DELETED(tkey2))) {
        for (int i = 0; i < src2->numOfCols; i++) {
          ASSERT(target->cols[i].type == src2->cols[i].type);
L
Liu Jicong 已提交
633
          if (src2->cols[i].len > 0 && !isNull(src2->cols[i].pData, src2->cols[i].type)) {
H
TD-1548  
Hongze Cheng 已提交
634 635
            dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfRows,
                             target->maxPoints);
L
Liu Jicong 已提交
636 637 638
          } else if(!forceSetNull && key1 == key2 && src1->cols[i].len > 0) {
            dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfRows,
                             target->maxPoints);
639 640
          } else if(target->cols[i].len > 0) {
            dataColSetNullAt(&target->cols[i], target->numOfRows);
H
TD-1548  
Hongze Cheng 已提交
641
          }
H
Hongze Cheng 已提交
642
        }
H
Hongze Cheng 已提交
643
        target->numOfRows++;
H
TD-100  
hzcheng 已提交
644
      }
H
TD-100  
hzcheng 已提交
645

H
TD-100  
hzcheng 已提交
646
      (*iter2)++;
H
TD-1438  
Hongze Cheng 已提交
647
      if (key1 == key2) (*iter1)++;
H
TD-100  
hzcheng 已提交
648
    }
H
Hongze Cheng 已提交
649 650

    ASSERT(target->numOfRows <= target->maxPoints);
H
TD-100  
hzcheng 已提交
651
  }
H
Hongze Cheng 已提交
652
}
C
Cary Xu 已提交
653
#endif
H
Hongze Cheng 已提交
654

H
Hongze Cheng 已提交
655
SKVRow tdKVRowDup(SKVRow row) {
wafwerar's avatar
wafwerar 已提交
656
  SKVRow trow = taosMemoryMalloc(kvRowLen(row));
H
Hongze Cheng 已提交
657 658
  if (trow == NULL) return NULL;

H
Hongze Cheng 已提交
659
  kvRowCpy(trow, row);
H
Hongze Cheng 已提交
660 661 662
  return trow;
}

S
Shengliang Guan 已提交
663 664 665
static int compareColIdx(const void *a, const void *b) {
  const SColIdx *x = (const SColIdx *)a;
  const SColIdx *y = (const SColIdx *)b;
B
Bomin Zhang 已提交
666 667 668 669 670 671 672 673 674
  if (x->colId > y->colId) {
    return 1;
  }
  if (x->colId < y->colId) {
    return -1;
  }
  return 0;
}

S
Shengliang Guan 已提交
675
void tdSortKVRowByColIdx(SKVRow row) { qsort(kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), compareColIdx); }
B
Bomin Zhang 已提交
676

H
TD-90  
Hongze Cheng 已提交
677 678 679 680
int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
  SColIdx *pColIdx = NULL;
  SKVRow   row = *orow;
  SKVRow   nrow = NULL;
S
Shengliang Guan 已提交
681
  void    *ptr = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_GE);
H
TD-90  
Hongze Cheng 已提交
682

683
  if (ptr == NULL || ((SColIdx *)ptr)->colId > colId) {  // need to add a column value to the row
C
Cary Xu 已提交
684
    int diff = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type];
685 686 687 688
    int nRowLen = kvRowLen(row) + sizeof(SColIdx) + diff;
    int oRowCols = kvRowNCols(row);

    ASSERT(diff > 0);
wafwerar's avatar
wafwerar 已提交
689
    nrow = taosMemoryMalloc(nRowLen);
H
TD-90  
Hongze Cheng 已提交
690 691
    if (nrow == NULL) return -1;

692 693
    kvRowSetLen(nrow, nRowLen);
    kvRowSetNCols(nrow, oRowCols + 1);
H
TD-90  
Hongze Cheng 已提交
694

695 696
    memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * oRowCols);
    memcpy(kvRowValues(nrow), kvRowValues(row), kvRowValLen(row));
H
TD-90  
Hongze Cheng 已提交
697

698 699 700
    pColIdx = kvRowColIdxAt(nrow, oRowCols);
    pColIdx->colId = colId;
    pColIdx->offset = kvRowValLen(row);
H
TD-90  
Hongze Cheng 已提交
701

702
    memcpy(kvRowColVal(nrow, pColIdx), value, diff);  // copy new value
H
TD-90  
Hongze Cheng 已提交
703

704
    tdSortKVRowByColIdx(nrow);
H
TD-90  
Hongze Cheng 已提交
705 706

    *orow = nrow;
wafwerar's avatar
wafwerar 已提交
707
    taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
708 709 710 711 712
  } else {
    ASSERT(((SColIdx *)ptr)->colId == colId);
    if (IS_VAR_DATA_TYPE(type)) {
      void *pOldVal = kvRowColVal(row, (SColIdx *)ptr);

S
Shengliang Guan 已提交
713
      if (varDataTLen(value) == varDataTLen(pOldVal)) {  // just update the column value in place
H
TD-90  
Hongze Cheng 已提交
714
        memcpy(pOldVal, value, varDataTLen(value));
715 716
      } else {  // need to reallocate the memory
        int16_t nlen = kvRowLen(row) + (varDataTLen(value) - varDataTLen(pOldVal));
H
TD-90  
Hongze Cheng 已提交
717
        ASSERT(nlen > 0);
wafwerar's avatar
wafwerar 已提交
718
        nrow = taosMemoryMalloc(nlen);
H
TD-90  
Hongze Cheng 已提交
719
        if (nrow == NULL) return -1;
H
TD-90  
Hongze Cheng 已提交
720 721 722 723

        kvRowSetLen(nrow, nlen);
        kvRowSetNCols(nrow, kvRowNCols(row));

724 725 726 727 728 729 730 731
        int zsize = sizeof(SColIdx) * kvRowNCols(row) + ((SColIdx *)ptr)->offset;
        memcpy(kvRowColIdx(nrow), kvRowColIdx(row), zsize);
        memcpy(kvRowColVal(nrow, ((SColIdx *)ptr)), value, varDataTLen(value));
        // Copy left value part
        int lsize = kvRowLen(row) - TD_KV_ROW_HEAD_SIZE - zsize - varDataTLen(pOldVal);
        if (lsize > 0) {
          memcpy(POINTER_SHIFT(nrow, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(value)),
                 POINTER_SHIFT(row, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(pOldVal)), lsize);
H
TD-90  
Hongze Cheng 已提交
732 733
        }

734 735 736 737 738
        for (int i = 0; i < kvRowNCols(nrow); i++) {
          pColIdx = kvRowColIdxAt(nrow, i);

          if (pColIdx->offset > ((SColIdx *)ptr)->offset) {
            pColIdx->offset = pColIdx->offset - varDataTLen(pOldVal) + varDataTLen(value);
H
TD-90  
Hongze Cheng 已提交
739 740 741 742
          }
        }

        *orow = nrow;
wafwerar's avatar
wafwerar 已提交
743
        taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
744 745 746 747 748 749 750
      }
    } else {
      memcpy(kvRowColVal(row, (SColIdx *)ptr), value, TYPE_BYTES[type]);
    }
  }

  return 0;
H
Hongze Cheng 已提交
751 752
}

H
TD-353  
Hongze Cheng 已提交
753
int tdEncodeKVRow(void **buf, SKVRow row) {
H
Hongze Cheng 已提交
754
  // May change the encode purpose
H
TD-353  
Hongze Cheng 已提交
755 756 757 758 759 760
  if (buf != NULL) {
    kvRowCpy(*buf, row);
    *buf = POINTER_SHIFT(*buf, kvRowLen(row));
  }

  return kvRowLen(row);
H
Hongze Cheng 已提交
761 762
}

H
Hongze Cheng 已提交
763 764
void *tdDecodeKVRow(void *buf, SKVRow *row) {
  *row = tdKVRowDup(buf);
H
TD-353  
Hongze Cheng 已提交
765
  if (*row == NULL) return NULL;
H
Hongze Cheng 已提交
766
  return POINTER_SHIFT(buf, kvRowLen(*row));
H
Hongze Cheng 已提交
767 768
}

H
Hongze Cheng 已提交
769
int tdInitKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
770 771
  pBuilder->tCols = 128;
  pBuilder->nCols = 0;
wafwerar's avatar
wafwerar 已提交
772
  pBuilder->pColIdx = (SColIdx *)taosMemoryMalloc(sizeof(SColIdx) * pBuilder->tCols);
H
Hongze Cheng 已提交
773 774 775
  if (pBuilder->pColIdx == NULL) return -1;
  pBuilder->alloc = 1024;
  pBuilder->size = 0;
wafwerar's avatar
wafwerar 已提交
776
  pBuilder->buf = taosMemoryMalloc(pBuilder->alloc);
H
Hongze Cheng 已提交
777
  if (pBuilder->buf == NULL) {
wafwerar's avatar
wafwerar 已提交
778
    taosMemoryFree(pBuilder->pColIdx);
H
Hongze Cheng 已提交
779 780 781 782 783
    return -1;
  }
  return 0;
}

H
Hongze Cheng 已提交
784
void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder) {
wafwerar's avatar
wafwerar 已提交
785 786
  taosMemoryFreeClear(pBuilder->pColIdx);
  taosMemoryFreeClear(pBuilder->buf);
H
Hongze Cheng 已提交
787 788
}

H
Hongze Cheng 已提交
789
void tdResetKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
790 791 792 793
  pBuilder->nCols = 0;
  pBuilder->size = 0;
}

H
Hongze Cheng 已提交
794
SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) {
C
Cary Xu 已提交
795
  int tlen = sizeof(SColIdx) * pBuilder->nCols + pBuilder->size;
H
Hongze Cheng 已提交
796 797
  if (tlen == 0) return NULL;

H
Hongze Cheng 已提交
798 799
  tlen += TD_KV_ROW_HEAD_SIZE;

wafwerar's avatar
wafwerar 已提交
800
  SKVRow row = taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
801 802
  if (row == NULL) return NULL;

H
Hongze Cheng 已提交
803
  kvRowSetNCols(row, pBuilder->nCols);
H
Hongze Cheng 已提交
804
  kvRowSetLen(row, tlen);
H
Hongze Cheng 已提交
805

H
Hongze Cheng 已提交
806 807
  memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols);
  memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size);
H
Hongze Cheng 已提交
808 809

  return row;
810
}
C
Cary Xu 已提交
811
#if 0
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2) {
#if 0
  ASSERT(memRowKey(row1) == memRowKey(row2));
  ASSERT(schemaVersion(pSchema1) == memRowVersion(row1));
  ASSERT(schemaVersion(pSchema2) == memRowVersion(row2));
  ASSERT(schemaVersion(pSchema1) >= schemaVersion(pSchema2));
#endif

  SArray *stashRow = taosArrayInit(pSchema1->numOfCols, sizeof(SColInfo));
  if (stashRow == NULL) {
    return NULL;
  }

  SMemRow  pRow = buffer;
  SDataRow dataRow = memRowDataBody(pRow);
  memRowSetType(pRow, SMEM_ROW_DATA);
  dataRowSetVersion(dataRow, schemaVersion(pSchema1));  // use latest schema version
  dataRowSetLen(dataRow, (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pSchema1->flen));

C
Cary Xu 已提交
831
  TDRowLenT dataLen = 0, kvLen = TD_MEM_ROW_KV_HEAD_SIZE;
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896

  int32_t  i = 0;  // row1
  int32_t  j = 0;  // row2
  int32_t  nCols1 = schemaNCols(pSchema1);
  int32_t  nCols2 = schemaNCols(pSchema2);
  SColInfo colInfo = {0};
  int32_t  kvIdx1 = 0, kvIdx2 = 0;

  while (i < nCols1) {
    STColumn *pCol = schemaColAt(pSchema1, i);
    void *    val1 = tdGetMemRowDataOfColEx(row1, pCol->colId, pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset, &kvIdx1);
    // if val1 != NULL, use val1;
    if (val1 != NULL && !isNull(val1, pCol->type)) {
      tdAppendColVal(dataRow, val1, pCol->type, pCol->offset);
      kvLen += tdGetColAppendLen(SMEM_ROW_KV, val1, pCol->type);
      setSColInfo(&colInfo, pCol->colId, pCol->type, val1);
      taosArrayPush(stashRow, &colInfo);
      ++i;  // next col
      continue;
    }

    void *val2 = NULL;
    while (j < nCols2) {
      STColumn *tCol = schemaColAt(pSchema2, j);
      if (tCol->colId < pCol->colId) {
        ++j;
        continue;
      }
      if (tCol->colId == pCol->colId) {
        val2 = tdGetMemRowDataOfColEx(row2, tCol->colId, tCol->type, TD_DATA_ROW_HEAD_SIZE + tCol->offset, &kvIdx2);
      } else if (tCol->colId > pCol->colId) {
        // set NULL
      }
      break;
    }  // end of while(j<nCols2)
    if (val2 == NULL) {
      val2 = (void *)getNullValue(pCol->type);
    }
    tdAppendColVal(dataRow, val2, pCol->type, pCol->offset);
    if (!isNull(val2, pCol->type)) {
      kvLen += tdGetColAppendLen(SMEM_ROW_KV, val2, pCol->type);
      setSColInfo(&colInfo, pCol->colId, pCol->type, val2);
      taosArrayPush(stashRow, &colInfo);
    }

    ++i;  // next col
  }

  dataLen = memRowTLen(pRow);

  if (kvLen < dataLen) {
    // scan stashRow and generate SKVRow
    memset(buffer, 0, sizeof(dataLen));
    SMemRow tRow = buffer;
    memRowSetType(tRow, SMEM_ROW_KV);
    SKVRow kvRow = (SKVRow)memRowKvBody(tRow);
    int16_t nKvNCols = (int16_t) taosArrayGetSize(stashRow);
    kvRowSetLen(kvRow, (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nKvNCols));
    kvRowSetNCols(kvRow, nKvNCols);
    memRowSetKvVersion(tRow, pSchema1->version);

    int32_t toffset = 0;
    int16_t k;
    for (k = 0; k < nKvNCols; ++k) {
      SColInfo *pColInfo = taosArrayGet(stashRow, k);
897 898
      tdAppendKvColVal(kvRow, pColInfo->colVal, true, pColInfo->colId, pColInfo->colType, toffset);
      toffset += sizeof(SColIdx);
899 900 901 902 903 904
    }
    ASSERT(kvLen == memRowTLen(tRow));
  }
  taosArrayDestroy(stashRow);
  return buffer;
}
C
Cary Xu 已提交
905
#endif