tq.c 25.6 KB
Newer Older
H
refact  
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * 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
Shengliang Guan 已提交
14 15
 */

L
Liu Jicong 已提交
16
#include "tqInt.h"
L
Liu Jicong 已提交
17
#include "tqMetaStore.h"
L
Liu Jicong 已提交
18
#include "tcompare.h"
S
Shengliang Guan 已提交
19

L
Liu Jicong 已提交
20 21
// static
// read next version data
L
Liu Jicong 已提交
22
//
L
Liu Jicong 已提交
23
// send to fetch queue
L
Liu Jicong 已提交
24
//
L
Liu Jicong 已提交
25
// handle management message
L
Liu Jicong 已提交
26
//
L
Liu Jicong 已提交
27

L
Liu Jicong 已提交
28 29 30
int tqGroupSSize(const STqGroup* pGroup);
int tqTopicSSize();
int tqItemSSize();
L
Liu Jicong 已提交
31

L
Liu Jicong 已提交
32 33 34
void* tqSerializeListHandle(STqList* listHandle, void* ptr);
void* tqSerializeTopic(STqTopic* pTopic, void* ptr);
void* tqSerializeItem(STqMsgItem* pItem, void* ptr);
L
Liu Jicong 已提交
35

L
Liu Jicong 已提交
36 37
const void* tqDeserializeTopic(const void* pBytes, STqTopic* pTopic);
const void* tqDeserializeItem(const void* pBytes, STqMsgItem* pItem);
L
Liu Jicong 已提交
38

L
Liu Jicong 已提交
39 40
int tqInit() {
  int8_t old = atomic_val_compare_exchange_8(&tqMgmt.inited, 0, 1);
L
Liu Jicong 已提交
41
  if (old == 1) return 0;
L
Liu Jicong 已提交
42 43 44 45 46 47 48

  tqMgmt.timer = taosTmrInit(0, 0, 0, "TQ");
  return 0;
}

void tqCleanUp() {
  int8_t old = atomic_val_compare_exchange_8(&tqMgmt.inited, 1, 0);
L
Liu Jicong 已提交
49
  if (old == 0) return;
L
Liu Jicong 已提交
50 51 52 53
  taosTmrStop(tqMgmt.timer);
  taosTmrCleanUp(tqMgmt.timer);
}

L
Liu Jicong 已提交
54
STQ* tqOpen(const char* path, SWal* pWal, SMeta* pMeta, STqCfg* tqConfig, SMemAllocatorFactory* allocFac) {
L
Liu Jicong 已提交
55
  STQ* pTq = malloc(sizeof(STQ));
L
Liu Jicong 已提交
56
  if (pTq == NULL) {
L
Liu Jicong 已提交
57
    terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
L
Liu Jicong 已提交
58 59
    return NULL;
  }
H
Hongze Cheng 已提交
60
  pTq->path = strdup(path);
L
Liu Jicong 已提交
61
  pTq->tqConfig = tqConfig;
L
Liu Jicong 已提交
62 63
  pTq->pWal = pWal;
  pTq->pMeta = pMeta;
L
Liu Jicong 已提交
64
#if 0
L
Liu Jicong 已提交
65
  pTq->tqMemRef.pAllocatorFactory = allocFac;
L
Liu Jicong 已提交
66 67
  pTq->tqMemRef.pAllocator = allocFac->create(allocFac);
  if (pTq->tqMemRef.pAllocator == NULL) {
L
Liu Jicong 已提交
68
    // TODO: error code of buffer pool
L
Liu Jicong 已提交
69
  }
L
Liu Jicong 已提交
70
#endif
L
Liu Jicong 已提交
71
  pTq->tqMeta = tqStoreOpen(path, (FTqSerialize)tqSerializeConsumer, (FTqDeserialize)tqDeserializeConsumer, free, 0);
L
Liu Jicong 已提交
72
  if (pTq->tqMeta == NULL) {
L
Liu Jicong 已提交
73
    free(pTq);
L
Liu Jicong 已提交
74 75 76
#if 0
    allocFac->destroy(allocFac, pTq->tqMemRef.pAllocator);
#endif
L
Liu Jicong 已提交
77 78
    return NULL;
  }
L
Liu Jicong 已提交
79

L
Liu Jicong 已提交
80 81
  return pTq;
}
L
Liu Jicong 已提交
82

L
Liu Jicong 已提交
83
void tqClose(STQ* pTq) {
H
Hongze Cheng 已提交
84
  if (pTq) {
H
Hongze Cheng 已提交
85
    tfree(pTq->path);
H
Hongze Cheng 已提交
86 87
    free(pTq);
  }
L
Liu Jicong 已提交
88 89
  // TODO
}
L
Liu Jicong 已提交
90

L
Liu Jicong 已提交
91 92 93 94
static int tqProtoCheck(STqMsgHead* pMsg) {
  // TODO
  return pMsg->protoVer == 0;
}
L
Liu Jicong 已提交
95

L
Liu Jicong 已提交
96
static int tqAckOneTopic(STqTopic* pTopic, STqOneAck* pAck, STqQueryMsg** ppQuery) {
L
Liu Jicong 已提交
97
  // clean old item and move forward
L
Liu Jicong 已提交
98
  int32_t consumeOffset = pAck->consumeOffset;
L
Liu Jicong 已提交
99
  int     idx = consumeOffset % TQ_BUFFER_SIZE;
L
Liu Jicong 已提交
100 101
  ASSERT(pTopic->buffer[idx].content && pTopic->buffer[idx].executor);
  tfree(pTopic->buffer[idx].content);
L
Liu Jicong 已提交
102 103 104
  if (1 /* TODO: need to launch new query */) {
    STqQueryMsg* pNewQuery = malloc(sizeof(STqQueryMsg));
    if (pNewQuery == NULL) {
L
Liu Jicong 已提交
105
      terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
L
Liu Jicong 已提交
106 107
      return -1;
    }
L
Liu Jicong 已提交
108 109
    // TODO: lock executor
    // TODO: read from wal and assign to src
L
Liu Jicong 已提交
110 111 112 113 114
    /*pNewQuery->exec->executor = pTopic->buffer[idx].executor;*/
    /*pNewQuery->exec->src = 0;*/
    /*pNewQuery->exec->dest = &pTopic->buffer[idx];*/
    /*pNewQuery->next = *ppQuery;*/
    /**ppQuery = pNewQuery;*/
L
Liu Jicong 已提交
115
  }
L
Liu Jicong 已提交
116 117 118
  return 0;
}

L
Liu Jicong 已提交
119
static int tqAck(STqGroup* pGroup, STqAcks* pAcks) {
L
Liu Jicong 已提交
120
  int32_t    ackNum = pAcks->ackNum;
L
Liu Jicong 已提交
121
  STqOneAck* acks = pAcks->acks;
L
Liu Jicong 已提交
122
  // double ptr for acks and list
L
Liu Jicong 已提交
123 124 125 126
  int          i = 0;
  STqList*     node = pGroup->head;
  int          ackCnt = 0;
  STqQueryMsg* pQuery = NULL;
L
Liu Jicong 已提交
127
  while (i < ackNum && node->next) {
L
Liu Jicong 已提交
128
    if (acks[i].topicId == node->next->topic.topicId) {
L
Liu Jicong 已提交
129
      ackCnt++;
L
Liu Jicong 已提交
130 131
      tqAckOneTopic(&node->next->topic, &acks[i], &pQuery);
    } else if (acks[i].topicId < node->next->topic.topicId) {
L
Liu Jicong 已提交
132 133 134
      i++;
    } else {
      node = node->next;
L
Liu Jicong 已提交
135 136
    }
  }
L
Liu Jicong 已提交
137 138
  if (pQuery) {
    // post message
L
Liu Jicong 已提交
139 140 141
  }
  return ackCnt;
}
L
Liu Jicong 已提交
142

L
Liu Jicong 已提交
143
static int tqCommitGroup(STqGroup* pGroup) {
L
Liu Jicong 已提交
144
  // persist modification into disk
L
Liu Jicong 已提交
145 146 147
  return 0;
}

L
Liu Jicong 已提交
148
int tqCreateGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId, STqGroup** ppGroup) {
L
Liu Jicong 已提交
149
  // create in disk
L
Liu Jicong 已提交
150 151
  STqGroup* pGroup = (STqGroup*)malloc(sizeof(STqGroup));
  if (pGroup == NULL) {
L
Liu Jicong 已提交
152
    // TODO
L
Liu Jicong 已提交
153 154
    return -1;
  }
L
Liu Jicong 已提交
155 156
  *ppGroup = pGroup;
  memset(pGroup, 0, sizeof(STqGroup));
L
Liu Jicong 已提交
157

L
Liu Jicong 已提交
158
  pGroup->topicList = tdListNew(sizeof(STqTopic));
L
Liu Jicong 已提交
159
  if (pGroup->topicList == NULL) {
L
Liu Jicong 已提交
160 161 162 163 164
    free(pGroup);
    return -1;
  }
  *ppGroup = pGroup;

L
Liu Jicong 已提交
165 166 167
  return 0;
}

L
Liu Jicong 已提交
168 169 170 171 172
STqGroup* tqOpenGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) {
  STqGroup* pGroup = tqHandleGet(pTq->tqMeta, cId);
  if (pGroup == NULL) {
    int code = tqCreateGroup(pTq, topicId, cgId, cId, &pGroup);
    if (code < 0) {
L
Liu Jicong 已提交
173
      // TODO
L
Liu Jicong 已提交
174 175
      return NULL;
    }
L
Liu Jicong 已提交
176
    tqHandleMovePut(pTq->tqMeta, cId, pGroup);
L
Liu Jicong 已提交
177
  }
L
Liu Jicong 已提交
178
  ASSERT(pGroup);
L
Liu Jicong 已提交
179

L
Liu Jicong 已提交
180
  return pGroup;
L
Liu Jicong 已提交
181
}
L
Liu Jicong 已提交
182

L
Liu Jicong 已提交
183 184 185 186
int tqCloseGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) {
  // TODO
  return 0;
}
L
Liu Jicong 已提交
187

L
Liu Jicong 已提交
188
int tqDropGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) {
L
Liu Jicong 已提交
189
  // delete from disk
L
Liu Jicong 已提交
190 191 192
  return 0;
}

L
Liu Jicong 已提交
193 194 195
static int tqFetch(STqGroup* pGroup, STqConsumeRsp** pRsp) {
  STqList* pHead = pGroup->head;
  STqList* pNode = pHead;
L
Liu Jicong 已提交
196
  int      totSize = 0;
L
Liu Jicong 已提交
197
  int      numOfMsgs = 0;
L
Liu Jicong 已提交
198
  // TODO: make it a macro
L
Liu Jicong 已提交
199
  int sizeLimit = 4 * 1024;
L
Liu Jicong 已提交
200 201 202 203

  void* ptr = realloc(*pRsp, sizeof(STqConsumeRsp) + sizeLimit);
  if (ptr == NULL) {
    terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
L
Liu Jicong 已提交
204 205
    return -1;
  }
L
Liu Jicong 已提交
206 207 208
  *pRsp = ptr;
  STqMsgContent* buffer = (*pRsp)->msgs;

L
Liu Jicong 已提交
209 210
  // iterate the list to get msgs of all topics
  // until all topic iterated or msgs over sizeLimit
L
Liu Jicong 已提交
211 212 213 214 215 216
  while (pNode->next) {
    pNode = pNode->next;
    STqTopic* pTopic = &pNode->topic;
    int       idx = pTopic->nextConsumeOffset % TQ_BUFFER_SIZE;
    if (pTopic->buffer[idx].content != NULL && pTopic->buffer[idx].offset == pTopic->nextConsumeOffset) {
      totSize += pTopic->buffer[idx].size;
L
Liu Jicong 已提交
217
      if (totSize > sizeLimit) {
L
Liu Jicong 已提交
218
        void* ptr = realloc(*pRsp, sizeof(STqConsumeRsp) + totSize);
L
Liu Jicong 已提交
219
        if (ptr == NULL) {
L
Liu Jicong 已提交
220 221
          totSize -= pTopic->buffer[idx].size;
          terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
L
Liu Jicong 已提交
222
          // return msgs already copied
L
Liu Jicong 已提交
223 224
          break;
        }
L
Liu Jicong 已提交
225 226
        *pRsp = ptr;
        break;
L
Liu Jicong 已提交
227
      }
L
Liu Jicong 已提交
228
      *((int64_t*)buffer) = pTopic->topicId;
L
Liu Jicong 已提交
229
      buffer = POINTER_SHIFT(buffer, sizeof(int64_t));
L
Liu Jicong 已提交
230
      *((int64_t*)buffer) = pTopic->buffer[idx].size;
L
Liu Jicong 已提交
231
      buffer = POINTER_SHIFT(buffer, sizeof(int64_t));
L
Liu Jicong 已提交
232 233 234
      memcpy(buffer, pTopic->buffer[idx].content, pTopic->buffer[idx].size);
      buffer = POINTER_SHIFT(buffer, pTopic->buffer[idx].size);
      numOfMsgs++;
L
Liu Jicong 已提交
235
      if (totSize > sizeLimit) {
L
Liu Jicong 已提交
236 237 238 239
        break;
      }
    }
  }
L
Liu Jicong 已提交
240 241
  (*pRsp)->bodySize = totSize;
  return numOfMsgs;
L
Liu Jicong 已提交
242 243
}

L
Liu Jicong 已提交
244
STqGroup* tqGetGroup(STQ* pTq, int64_t clientId) { return tqHandleGet(pTq->tqMeta, clientId); }
L
Liu Jicong 已提交
245

L
Liu Jicong 已提交
246 247 248 249 250 251 252 253 254 255 256
int tqSendLaunchQuery(STqMsgItem* bufItem, int64_t offset) {
  if (tqQueryExecuting(bufItem->status)) {
    return 0;
  }
  bufItem->status = 1;
  // load data from wal or buffer pool
  // put into exec
  // send exec into non blocking queue
  // when query finished, put into buffer pool
  return 0;
}
L
Liu Jicong 已提交
257

L
Liu Jicong 已提交
258
/*int tqMoveOffsetToNext(TqGroupHandle* gHandle) {*/
L
Liu Jicong 已提交
259
/*return 0;*/
L
Liu Jicong 已提交
260 261
/*}*/

L
Liu Jicong 已提交
262 263 264
int tqPushMsg(STQ* pTq, void* p, int64_t version) {
  // add reference
  // judge and launch new query
L
Liu Jicong 已提交
265 266 267
  return 0;
}

L
Liu Jicong 已提交
268
int tqCommit(STQ* pTq) {
L
Liu Jicong 已提交
269
  // do nothing
L
Liu Jicong 已提交
270 271 272
  return 0;
}

L
Liu Jicong 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
int tqBufferSetOffset(STqTopic* pTopic, int64_t offset) {
  int code;
  memset(pTopic->buffer, 0, sizeof(pTopic->buffer));
  // launch query
  for (int i = offset; i < offset + TQ_BUFFER_SIZE; i++) {
    int pos = i % TQ_BUFFER_SIZE;
    code = tqSendLaunchQuery(&pTopic->buffer[pos], offset);
    if (code < 0) {
      // TODO: error handling
    }
  }
  // set offset
  pTopic->nextConsumeOffset = offset;
  pTopic->floatingCursor = offset;
  return 0;
}

STqTopic* tqFindTopic(STqGroup* pGroup, int64_t topicId) {
  // TODO
  return NULL;
}

int tqSetCursor(STQ* pTq, STqSetCurReq* pMsg) {
  int       code;
  int64_t   clientId = pMsg->head.clientId;
  int64_t   topicId = pMsg->topicId;
  int64_t   offset = pMsg->offset;
  STqGroup* gHandle = tqGetGroup(pTq, clientId);
  if (gHandle == NULL) {
    // client not connect
    return -1;
  }
  STqTopic* topicHandle = tqFindTopic(gHandle, topicId);
  if (topicHandle == NULL) {
    return -1;
  }
  if (pMsg->offset == topicHandle->nextConsumeOffset) {
    return 0;
  }
  // TODO: check log last version

  code = tqBufferSetOffset(topicHandle, offset);
  if (code < 0) {
    // set error code
    return -1;
  }

L
Liu Jicong 已提交
320 321 322
  return 0;
}

L
Liu Jicong 已提交
323 324
// temporary
int tqProcessCMsg(STQ* pTq, STqConsumeReq* pMsg, STqRspHandle* pRsp) {
L
Liu Jicong 已提交
325 326 327 328 329 330
  int64_t   clientId = pMsg->head.clientId;
  STqGroup* pGroup = tqGetGroup(pTq, clientId);
  if (pGroup == NULL) {
    terrno = TSDB_CODE_TQ_GROUP_NOT_SET;
    return -1;
  }
L
Liu Jicong 已提交
331 332 333 334 335 336 337
  pGroup->rspHandle.handle = pRsp->handle;
  pGroup->rspHandle.ahandle = pRsp->ahandle;

  return 0;
}

int tqConsume(STQ* pTq, SRpcMsg* pReq, SRpcMsg** pRsp) {
L
Liu Jicong 已提交
338 339 340
  STqConsumeReq* pMsg = pReq->pCont;
  int64_t        clientId = pMsg->head.clientId;
  STqGroup*      pGroup = tqGetGroup(pTq, clientId);
L
Liu Jicong 已提交
341 342 343 344 345 346 347 348 349 350 351
  if (pGroup == NULL) {
    terrno = TSDB_CODE_TQ_GROUP_NOT_SET;
    return -1;
  }

  SList* topicList = pGroup->topicList;

  int totSize = 0;
  int numOfMsgs = 0;
  int sizeLimit = 4096;

L
Liu Jicong 已提交
352 353
  STqConsumeRsp* pCsmRsp = (*pRsp)->pCont;
  void*          ptr = realloc((*pRsp)->pCont, sizeof(STqConsumeRsp) + sizeLimit);
L
Liu Jicong 已提交
354 355 356 357 358 359 360 361 362 363
  if (ptr == NULL) {
    terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
    return -1;
  }
  (*pRsp)->pCont = ptr;

  SListIter iter;
  tdListInitIter(topicList, &iter, TD_LIST_FORWARD);

  STqMsgContent* buffer = NULL;
L
Liu Jicong 已提交
364
  SArray*        pArray = taosArrayInit(0, sizeof(void*));
L
Liu Jicong 已提交
365

L
Liu Jicong 已提交
366 367 368 369
  SListNode* pn;
  while ((pn = tdListNext(&iter)) != NULL) {
    STqTopic*   pTopic = *(STqTopic**)pn->data;
    int         idx = pTopic->floatingCursor % TQ_BUFFER_SIZE;
L
Liu Jicong 已提交
370 371
    STqMsgItem* pItem = &pTopic->buffer[idx];
    if (pItem->content != NULL && pItem->offset == pTopic->floatingCursor) {
L
Liu Jicong 已提交
372 373
      if (pItem->status == TQ_ITEM_READY) {
        // if has data
L
Liu Jicong 已提交
374 375 376 377 378 379 380 381 382 383 384 385
        totSize += pTopic->buffer[idx].size;
        if (totSize > sizeLimit) {
          void* ptr = realloc((*pRsp)->pCont, sizeof(STqConsumeRsp) + totSize);
          if (ptr == NULL) {
            totSize -= pTopic->buffer[idx].size;
            terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
            // return msgs already copied
            break;
          }
          (*pRsp)->pCont = ptr;
          break;
        }
L
Liu Jicong 已提交
386
        *((int64_t*)buffer) = htobe64(pTopic->topicId);
L
Liu Jicong 已提交
387
        buffer = POINTER_SHIFT(buffer, sizeof(int64_t));
L
Liu Jicong 已提交
388
        *((int64_t*)buffer) = htobe64(pTopic->buffer[idx].size);
L
Liu Jicong 已提交
389 390 391 392 393 394 395
        buffer = POINTER_SHIFT(buffer, sizeof(int64_t));
        memcpy(buffer, pTopic->buffer[idx].content, pTopic->buffer[idx].size);
        buffer = POINTER_SHIFT(buffer, pTopic->buffer[idx].size);
        numOfMsgs++;
        if (totSize > sizeLimit) {
          break;
        }
L
Liu Jicong 已提交
396 397
      } else if (pItem->status == TQ_ITEM_PROCESS) {
        // if not have data but in process
L
Liu Jicong 已提交
398

L
Liu Jicong 已提交
399 400
      } else if (pItem->status == TQ_ITEM_EMPTY) {
        // if not have data and not in process
L
Liu Jicong 已提交
401
        int32_t old = atomic_val_compare_exchange_32(&pItem->status, TQ_ITEM_EMPTY, TQ_ITEM_PROCESS);
L
Liu Jicong 已提交
402
        if (old != TQ_ITEM_EMPTY) {
L
Liu Jicong 已提交
403 404 405 406 407 408 409 410 411 412
          continue;
        }
        pItem->offset = pTopic->floatingCursor;
        taosArrayPush(pArray, &pItem);
      } else {
        ASSERT(0);
      }
    }
  }

L
Liu Jicong 已提交
413 414 415 416 417 418 419 420 421 422 423
  if (numOfMsgs > 0) {
    // set code and other msg
    rpcSendResponse(*pRsp);
  } else {
    // most recent data has been fetched

    // enable timer for blocking wait
    // once new data written when waiting, launch query and rsp
  }

  // fetched a num of msgs, rpc response
L
Liu Jicong 已提交
424
  for (int i = 0; i < pArray->size; i++) {
L
Liu Jicong 已提交
425 426
    STqMsgItem* pItem = taosArrayGet(pArray, i);

L
Liu Jicong 已提交
427
    // read from wal
L
Liu Jicong 已提交
428 429
    void* raw = NULL;
    /*int code = pTq->tqLogReader->logRead(, &raw, pItem->offset);*/
L
Liu Jicong 已提交
430 431
    /*int code = pTq->tqLogHandle->logRead(pItem->pTopic->logReader, &raw, pItem->offset);*/
    /*if (code < 0) {*/
L
Liu Jicong 已提交
432
    // TODO: error
L
Liu Jicong 已提交
433
    /*}*/
L
Liu Jicong 已提交
434 435
    // get msgType
    // if submitblk
L
Liu Jicong 已提交
436 437 438
    pItem->executor->assign(pItem->executor->runtimeEnv, raw);
    SSDataBlock* content = pItem->executor->exec(pItem->executor->runtimeEnv);
    pItem->content = content;
L
Liu Jicong 已提交
439
    // if other type, send just put into buffer
L
Liu Jicong 已提交
440
    /*pItem->content = raw;*/
L
Liu Jicong 已提交
441 442 443 444

    int32_t old = atomic_val_compare_exchange_32(&pItem->status, TQ_ITEM_PROCESS, TQ_ITEM_READY);
    ASSERT(old == TQ_ITEM_PROCESS);
  }
L
Liu Jicong 已提交
445
  taosArrayDestroy(pArray);
L
Liu Jicong 已提交
446 447 448 449 450

  return 0;
}

#if 0
L
Liu Jicong 已提交
451
int tqConsume(STQ* pTq, STqConsumeReq* pMsg) {
L
Liu Jicong 已提交
452
  if (!tqProtoCheck((STqMsgHead*)pMsg)) {
L
Liu Jicong 已提交
453
    // proto version invalid
L
Liu Jicong 已提交
454 455
    return -1;
  }
L
Liu Jicong 已提交
456 457 458
  int64_t   clientId = pMsg->head.clientId;
  STqGroup* pGroup = tqGetGroup(pTq, clientId);
  if (pGroup == NULL) {
L
Liu Jicong 已提交
459
    // client not connect
L
Liu Jicong 已提交
460 461
    return -1;
  }
L
Liu Jicong 已提交
462
  if (pMsg->acks.ackNum != 0) {
L
Liu Jicong 已提交
463
    if (tqAck(pGroup, &pMsg->acks) != 0) {
L
Liu Jicong 已提交
464
      // ack not success
L
Liu Jicong 已提交
465 466 467 468
      return -1;
    }
  }

L
Liu Jicong 已提交
469
  STqConsumeRsp* pRsp = (STqConsumeRsp*)pMsg;
L
Liu Jicong 已提交
470

L
Liu Jicong 已提交
471
  if (tqFetch(pGroup, (void**)&pRsp->msgs) <= 0) {
L
Liu Jicong 已提交
472
    // fetch error
L
Liu Jicong 已提交
473 474 475
    return -1;
  }

L
Liu Jicong 已提交
476
  // judge and launch new query
L
Liu Jicong 已提交
477 478 479 480
  /*if (tqSendLaunchQuery(gHandle)) {*/
  // launch query error
  /*return -1;*/
  /*}*/
L
Liu Jicong 已提交
481 482
  return 0;
}
L
Liu Jicong 已提交
483
#endif
L
Liu Jicong 已提交
484

L
Liu Jicong 已提交
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
int tqSerializeConsumer(const STqConsumerHandle* pConsumer, STqSerializedHead** ppHead) {
  int32_t num = taosArrayGetSize(pConsumer->topics);
  int32_t sz = sizeof(STqSerializedHead) + sizeof(int64_t) * 2 + TSDB_TOPIC_FNAME_LEN + num * (sizeof(int64_t) + TSDB_TOPIC_FNAME_LEN);
  if (sz > (*ppHead)->ssize) {
    void* tmpPtr = realloc(*ppHead, sz);
    if (tmpPtr == NULL) {
      free(*ppHead);
      return -1;
    }
    *ppHead = tmpPtr;
    (*ppHead)->ssize = sz;
  }

  void* ptr = (*ppHead)->content;
  *(int64_t*)ptr = pConsumer->consumerId;
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
  *(int64_t*)ptr = pConsumer->epoch;
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
  memcpy(ptr, pConsumer->topics, TSDB_TOPIC_FNAME_LEN);
  ptr = POINTER_SHIFT(ptr, TSDB_TOPIC_FNAME_LEN);
  *(int32_t*)ptr = num;
  ptr = POINTER_SHIFT(ptr, sizeof(int32_t));
  for (int32_t i = 0; i < num; i++) {
    STqTopicHandle* pTopic = taosArrayGet(pConsumer->topics, i);
    memcpy(ptr, pTopic->topicName, TSDB_TOPIC_FNAME_LEN);
    ptr = POINTER_SHIFT(ptr, TSDB_TOPIC_FNAME_LEN);
    *(int64_t*)ptr = pTopic->committedOffset;
    POINTER_SHIFT(ptr, sizeof(int64_t));
  }
  
  return 0;
}

const void* tqDeserializeConsumer(const STqSerializedHead* pHead, STqConsumerHandle** ppConsumer) {
  STqConsumerHandle* pConsumer = *ppConsumer;
  const void* ptr = pHead->content;
  pConsumer->consumerId = *(int64_t*)ptr;
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
  pConsumer->epoch = *(int64_t*)ptr;
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
  memcpy(pConsumer->cgroup, ptr, TSDB_TOPIC_FNAME_LEN);
  ptr = POINTER_SHIFT(ptr, TSDB_TOPIC_FNAME_LEN);
  int32_t sz = *(int32_t*)ptr;
  ptr = POINTER_SHIFT(ptr, sizeof(int32_t));
  pConsumer->topics = taosArrayInit(sz, sizeof(STqTopicHandle));
  for (int32_t i = 0; i < sz; i++) {
    /*STqTopicHandle* topicHandle = */
    /*taosArrayPush(pConsumer->topics, );*/
  }
  return NULL;
}

#if 0
L
Liu Jicong 已提交
538
int tqSerializeGroup(const STqGroup* pGroup, STqSerializedHead** ppHead) {
L
Liu Jicong 已提交
539
  // calculate size
L
Liu Jicong 已提交
540
  int sz = tqGroupSSize(pGroup) + sizeof(STqSerializedHead);
L
Liu Jicong 已提交
541
  if (sz > (*ppHead)->ssize) {
L
Liu Jicong 已提交
542
    void* tmpPtr = realloc(*ppHead, sz);
L
Liu Jicong 已提交
543
    if (tmpPtr == NULL) {
L
Liu Jicong 已提交
544
      free(*ppHead);
L
Liu Jicong 已提交
545
      // TODO: memory err
L
Liu Jicong 已提交
546 547 548 549
      return -1;
    }
    *ppHead = tmpPtr;
    (*ppHead)->ssize = sz;
L
Liu Jicong 已提交
550
  }
L
Liu Jicong 已提交
551
  void* ptr = (*ppHead)->content;
L
Liu Jicong 已提交
552
  // do serialization
L
Liu Jicong 已提交
553
  *(int64_t*)ptr = pGroup->clientId;
L
Liu Jicong 已提交
554
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
L
Liu Jicong 已提交
555
  *(int64_t*)ptr = pGroup->cgId;
L
Liu Jicong 已提交
556
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
L
Liu Jicong 已提交
557
  *(int32_t*)ptr = pGroup->topicNum;
558
  ptr = POINTER_SHIFT(ptr, sizeof(int32_t));
L
Liu Jicong 已提交
559 560
  if (pGroup->topicNum > 0) {
    tqSerializeListHandle(pGroup->head, ptr);
L
Liu Jicong 已提交
561 562 563 564
  }
  return 0;
}

L
Liu Jicong 已提交
565 566
void* tqSerializeListHandle(STqList* listHandle, void* ptr) {
  STqList* node = listHandle;
567
  ASSERT(node != NULL);
L
Liu Jicong 已提交
568
  while (node) {
L
Liu Jicong 已提交
569
    ptr = tqSerializeTopic(&node->topic, ptr);
L
Liu Jicong 已提交
570 571
    node = node->next;
  }
572
  return ptr;
L
Liu Jicong 已提交
573
}
574

L
Liu Jicong 已提交
575 576
void* tqSerializeTopic(STqTopic* pTopic, void* ptr) {
  *(int64_t*)ptr = pTopic->nextConsumeOffset;
L
Liu Jicong 已提交
577
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
L
Liu Jicong 已提交
578
  *(int64_t*)ptr = pTopic->topicId;
L
Liu Jicong 已提交
579
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
L
Liu Jicong 已提交
580 581 582 583
  /**(int32_t*)ptr = pTopic->head;*/
  /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
  /**(int32_t*)ptr = pTopic->tail;*/
  /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
L
Liu Jicong 已提交
584
  for (int i = 0; i < TQ_BUFFER_SIZE; i++) {
L
Liu Jicong 已提交
585
    ptr = tqSerializeItem(&pTopic->buffer[i], ptr);
L
Liu Jicong 已提交
586
  }
587
  return ptr;
L
Liu Jicong 已提交
588 589
}

L
Liu Jicong 已提交
590
void* tqSerializeItem(STqMsgItem* bufItem, void* ptr) {
L
Liu Jicong 已提交
591 592
  // TODO: do we need serialize this?
  // mainly for executor
593
  return ptr;
L
Liu Jicong 已提交
594 595
}

L
Liu Jicong 已提交
596 597 598
const void* tqDeserializeGroup(const STqSerializedHead* pHead, STqGroup** ppGroup) {
  STqGroup*   gHandle = *ppGroup;
  const void* ptr = pHead->content;
L
Liu Jicong 已提交
599
  gHandle->clientId = *(int64_t*)ptr;
600 601 602 603 604 605 606
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
  gHandle->cgId = *(int64_t*)ptr;
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
  gHandle->ahandle = NULL;
  gHandle->topicNum = *(int32_t*)ptr;
  ptr = POINTER_SHIFT(ptr, sizeof(int32_t));
  gHandle->head = NULL;
L
Liu Jicong 已提交
607
  STqList* node = gHandle->head;
L
Liu Jicong 已提交
608 609
  for (int i = 0; i < gHandle->topicNum; i++) {
    if (gHandle->head == NULL) {
L
Liu Jicong 已提交
610
      if ((node = malloc(sizeof(STqList))) == NULL) {
L
Liu Jicong 已提交
611
        // TODO: error
612 613
        return NULL;
      }
L
Liu Jicong 已提交
614
      node->next = NULL;
L
Liu Jicong 已提交
615
      ptr = tqDeserializeTopic(ptr, &node->topic);
616 617
      gHandle->head = node;
    } else {
L
Liu Jicong 已提交
618
      node->next = malloc(sizeof(STqList));
L
Liu Jicong 已提交
619 620
      if (node->next == NULL) {
        // TODO: error
621 622 623
        return NULL;
      }
      node->next->next = NULL;
L
Liu Jicong 已提交
624
      ptr = tqDeserializeTopic(ptr, &node->next->topic);
625 626 627 628
      node = node->next;
    }
  }
  return ptr;
L
Liu Jicong 已提交
629
}
630

L
Liu Jicong 已提交
631
const void* tqDeserializeTopic(const void* pBytes, STqTopic* topic) {
632
  const void* ptr = pBytes;
L
Liu Jicong 已提交
633
  topic->nextConsumeOffset = *(int64_t*)ptr;
634
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
L
Liu Jicong 已提交
635
  topic->topicId = *(int64_t*)ptr;
636
  ptr = POINTER_SHIFT(ptr, sizeof(int64_t));
L
Liu Jicong 已提交
637 638 639 640
  /*topic->head = *(int32_t*)ptr;*/
  /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
  /*topic->tail = *(int32_t*)ptr;*/
  /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
L
Liu Jicong 已提交
641
  for (int i = 0; i < TQ_BUFFER_SIZE; i++) {
L
Liu Jicong 已提交
642
    ptr = tqDeserializeItem(ptr, &topic->buffer[i]);
643 644
  }
  return ptr;
L
Liu Jicong 已提交
645 646
}

L
Liu Jicong 已提交
647
const void* tqDeserializeItem(const void* pBytes, STqMsgItem* bufItem) { return pBytes; }
L
Liu Jicong 已提交
648

L
Liu Jicong 已提交
649
// TODO: make this a macro
L
Liu Jicong 已提交
650
int tqGroupSSize(const STqGroup* gHandle) {
L
Liu Jicong 已提交
651 652
  return sizeof(int64_t) * 2  // cId + cgId
         + sizeof(int32_t)    // topicNum
L
Liu Jicong 已提交
653
         + gHandle->topicNum * tqTopicSSize();
L
Liu Jicong 已提交
654
}
655

L
Liu Jicong 已提交
656
// TODO: make this a macro
L
Liu Jicong 已提交
657
int tqTopicSSize() {
L
Liu Jicong 已提交
658 659
  return sizeof(int64_t) * 2    // nextConsumeOffset + topicId
         + sizeof(int32_t) * 2  // head + tail
L
Liu Jicong 已提交
660
         + TQ_BUFFER_SIZE * tqItemSSize();
L
Liu Jicong 已提交
661
}
662

L
Liu Jicong 已提交
663
int tqItemSSize() {
L
Liu Jicong 已提交
664 665
  // TODO: do this need serialization?
  // mainly for executor
L
Liu Jicong 已提交
666 667
  return 0;
}
L
Liu Jicong 已提交
668
#endif
669

S
Shengliang 已提交
670 671
int32_t tqProcessConsumeReq(STQ* pTq, SRpcMsg* pMsg) {
  SMqConsumeReq*   pReq = pMsg->pCont;
L
Liu Jicong 已提交
672
  SRpcMsg          rpcMsg;
L
Liu Jicong 已提交
673 674
  int64_t          reqId = pReq->reqId;
  int64_t          consumerId = pReq->consumerId;
L
Liu Jicong 已提交
675 676
  int64_t          reqOffset = pReq->offset;
  int64_t          fetchOffset = reqOffset;
L
Liu Jicong 已提交
677
  int64_t          blockingTime = pReq->blockingTime;
L
Liu Jicong 已提交
678

L
Liu Jicong 已提交
679 680
  int              rspLen = 0;

L
Liu Jicong 已提交
681
  STqConsumerHandle* pConsumer = tqHandleGet(pTq->tqMeta, consumerId);
L
Liu Jicong 已提交
682
  int                sz = taosArrayGetSize(pConsumer->topics);
L
Liu Jicong 已提交
683

L
Liu Jicong 已提交
684 685
  for (int i = 0; i < sz; i++) {
    STqTopicHandle* pTopic = taosArrayGet(pConsumer->topics, i);
L
Liu Jicong 已提交
686 687 688 689
    //TODO: support multiple topic in one req
    if (strcmp(pTopic->topicName, pReq->topic) != 0) {
      continue;
    }
L
Liu Jicong 已提交
690

L
Liu Jicong 已提交
691 692 693
  if (fetchOffset == -1) {
    fetchOffset = pTopic->committedOffset + 1;
  }
L
Liu Jicong 已提交
694 695 696
    int8_t pos;
    int8_t skip = 0;
    SWalHead* pHead;
L
Liu Jicong 已提交
697
    while (1) {
L
Liu Jicong 已提交
698 699 700 701 702 703 704 705 706 707 708 709
      pos = fetchOffset % TQ_BUFFER_SIZE;
      skip = atomic_val_compare_exchange_8(&pTopic->buffer.output[pos].status, 0, 1);
      if (skip == 1) {
        // do nothing
        break;
      }
      if (walReadWithHandle(pTopic->pReadhandle, fetchOffset) < 0) {
        // check err
        atomic_store_8(&pTopic->buffer.output[pos].status, 0);
        skip = 1;
        break;
      }
L
Liu Jicong 已提交
710
      // read until find TDMT_VND_SUBMIT
L
Liu Jicong 已提交
711 712 713 714
      pHead = pTopic->pReadhandle->pHead;
      if (pHead->head.msgType == TDMT_VND_SUBMIT) {
        break;
      }
L
Liu Jicong 已提交
715
      if (walReadWithHandle(pTopic->pReadhandle, fetchOffset) < 0) {
L
Liu Jicong 已提交
716 717 718
        atomic_store_8(&pTopic->buffer.output[pos].status, 0);
        skip = 1;
        break;
L
Liu Jicong 已提交
719
      }
L
Liu Jicong 已提交
720 721
      atomic_store_8(&pTopic->buffer.output[pos].status, 0);
      fetchOffset++;
L
Liu Jicong 已提交
722
    }
L
Liu Jicong 已提交
723
    if (skip == 1) continue;
L
Liu Jicong 已提交
724
    SSubmitMsg* pCont = (SSubmitMsg*)&pHead->head.body;
L
Liu Jicong 已提交
725
    qTaskInfo_t task = pTopic->buffer.output[pos].task;
L
Liu Jicong 已提交
726

L
Liu Jicong 已提交
727
    qSetStreamInput(task, pCont);
L
Liu Jicong 已提交
728

L
Liu Jicong 已提交
729 730 731 732 733 734 735 736 737
    //SArray<SSDataBlock>
    SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock));
    while (1) {
      SSDataBlock* pDataBlock;
      uint64_t     ts;
      if (qExecTask(task, &pDataBlock, &ts) < 0) {
        break;
      }
      if (pDataBlock != NULL) {
L
Liu Jicong 已提交
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
        SMqTbData tbData = {
          .uid = pDataBlock->info.uid,
          .numOfCols = pDataBlock->info.numOfCols,
          .numOfRows = pDataBlock->info.rows,
        };
        for (int i = 0; i < pDataBlock->info.numOfCols; i++) {
          SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, i);
          int32_t sz = pColData->info.bytes * pDataBlock->info.rows;
          SMqColData colData = {
            .bytes = pColData->info.bytes,
            .colId = pColData->info.colId,
            .type = pColData->info.type,
          };
          memcpy(colData.data, pColData->pData, colData.bytes * pDataBlock->info.rows);
          memcpy(&tbData.colData[i], &colData, sz);
        }
        /*pDataBlock->info.*/
L
Liu Jicong 已提交
755 756 757 758 759 760 761 762 763 764 765 766
        taosArrayPush(pRes, pDataBlock);
      } else {
        break;
      }
    }

    atomic_store_8(&pTopic->buffer.output[pos].status, 0);

    if (taosArrayGetSize(pRes) == 0) {
      taosArrayDestroy(pRes);
      fetchOffset++;
      continue;
767
    }
L
Liu Jicong 已提交
768 769 770

    pTopic->buffer.output[pos].dst = pRes;
    if (pTopic->buffer.firstOffset == -1 || pReq->offset < pTopic->buffer.firstOffset) {
L
Liu Jicong 已提交
771
      pTopic->buffer.firstOffset = pReq->offset;
L
Liu Jicong 已提交
772
    }
L
Liu Jicong 已提交
773
    if (pTopic->buffer.lastOffset == -1 || pReq->offset > pTopic->buffer.lastOffset) {
L
Liu Jicong 已提交
774
      pTopic->buffer.lastOffset = pReq->offset;
L
Liu Jicong 已提交
775
    }
L
Liu Jicong 已提交
776
    // put output into rsp
L
Liu Jicong 已提交
777 778 779 780
    SMqConsumeRsp rsp = {
      .consumerId = consumerId,
      .numOfTopics = 1
    };
L
Liu Jicong 已提交
781
  }
L
Liu Jicong 已提交
782 783 784 785

  return 0;
}

L
Liu Jicong 已提交
786 787 788
int32_t tqProcessSetConnReq(STQ* pTq, char* msg) {
  SMqSetCVgReq req;
  tDecodeSMqSetCVgReq(msg, &req);
L
Liu Jicong 已提交
789 790 791 792
  STqConsumerHandle* pConsumer = calloc(sizeof(STqConsumerHandle), 1);
  if (pConsumer == NULL) {
    return -1;
  }
L
Liu Jicong 已提交
793 794
  strcpy(pConsumer->cgroup, req.cgroup);
  pConsumer->topics = taosArrayInit(0, sizeof(STqTopicHandle));
L
Liu Jicong 已提交
795

L
Liu Jicong 已提交
796 797 798 799 800
  STqTopicHandle* pTopic = calloc(sizeof(STqTopicHandle), 1);
  if (pTopic == NULL) {
    free(pConsumer);
    return -1;
  }
L
Liu Jicong 已提交
801
  strcpy(pTopic->topicName, req.topicName);
L
Liu Jicong 已提交
802 803 804
  pTopic->sql = strdup(req.sql);
  pTopic->logicalPlan = strdup(req.logicalPlan);
  pTopic->physicalPlan = strdup(req.physicalPlan);
805

L
Liu Jicong 已提交
806 807
  pTopic->buffer.firstOffset = -1;
  pTopic->buffer.lastOffset = -1;
L
Liu Jicong 已提交
808 809 810
  pTopic->pReadhandle = walOpenReadHandle(pTq->pWal);
  if (pTopic->pReadhandle == NULL) {
  }
L
Liu Jicong 已提交
811 812
  for (int i = 0; i < TQ_BUFFER_SIZE; i++) {
    pTopic->buffer.output[i].status = 0;
L
Liu Jicong 已提交
813
    STqReadHandle* pReadHandle = tqInitSubmitMsgScanner(pTq->pMeta);
L
fix tq  
Liu Jicong 已提交
814
    pTopic->buffer.output[i].task = qCreateStreamExecTaskInfo(req.qmsg, pReadHandle);
L
Liu Jicong 已提交
815
  }
L
Liu Jicong 已提交
816
  taosArrayPush(pConsumer->topics, pTopic);
L
Liu Jicong 已提交
817
  terrno = TSDB_CODE_SUCCESS;
L
Liu Jicong 已提交
818 819 820
  return 0;
}

L
Liu Jicong 已提交
821
STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) {
822 823 824 825 826
  STqReadHandle* pReadHandle = malloc(sizeof(STqReadHandle));
  if (pReadHandle == NULL) {
    return NULL;
  }
  pReadHandle->pMeta = pMeta;
L
Liu Jicong 已提交
827
  pReadHandle->pMsg = NULL;
828
  pReadHandle->ver = -1;
L
Liu Jicong 已提交
829
  pReadHandle->pColIdList = NULL;
L
Liu Jicong 已提交
830
  return pReadHandle;
831 832
}

L
Liu Jicong 已提交
833 834 835 836 837 838 839
void tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitMsg* pMsg, int64_t ver) {
  pReadHandle->pMsg = pMsg;
  tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter);
  pReadHandle->ver = ver;
  memset(&pReadHandle->blkIter, 0, sizeof(SSubmitBlkIter));
}

840
bool tqNextDataBlock(STqReadHandle* pHandle) {
L
Liu Jicong 已提交
841 842
  while (tGetSubmitMsgNext(&pHandle->msgIter, &pHandle->pBlock) >= 0) {
    if (pHandle->tbUid == pHandle->pBlock->uid) return true;
843
  }
L
Liu Jicong 已提交
844
  return false;
845 846 847
}

int tqRetrieveDataBlockInfo(STqReadHandle* pHandle, SDataBlockInfo* pBlockInfo) {
L
Liu Jicong 已提交
848 849 850
  /*int32_t         sversion = pHandle->pBlock->sversion;*/
  /*SSchemaWrapper* pSchema = metaGetTableSchema(pHandle->pMeta, pHandle->pBlock->uid, sversion, false);*/
  pBlockInfo->numOfCols = taosArrayGetSize(pHandle->pColIdList);
851 852 853 854
  pBlockInfo->rows = pHandle->pBlock->numOfRows;
  pBlockInfo->uid = pHandle->pBlock->uid;
  return 0;
}
L
Liu Jicong 已提交
855

L
Liu Jicong 已提交
856
SArray* tqRetrieveDataBlock(STqReadHandle* pHandle) {
L
Liu Jicong 已提交
857
  int32_t         sversion = pHandle->pBlock->sversion;
858
  SSchemaWrapper* pSchemaWrapper = metaGetTableSchema(pHandle->pMeta, pHandle->pBlock->uid, sversion, true);
L
Liu Jicong 已提交
859 860
  STSchema*       pTschema = metaGetTbTSchema(pHandle->pMeta, pHandle->pBlock->uid, sversion);
  SArray*         pArray = taosArrayInit(pSchemaWrapper->nCols, sizeof(SColumnInfoData));
861 862 863 864
  if (pArray == NULL) {
    return NULL;
  }
  SColumnInfoData colInfo;
L
Liu Jicong 已提交
865
  int             sz = pSchemaWrapper->nCols * pSchemaWrapper->pSchema->bytes;
866 867 868 869 870 871 872 873 874
  colInfo.pData = malloc(sz);
  if (colInfo.pData == NULL) {
    return NULL;
  }

  SMemRow row;
  int32_t kvIdx;
  while ((row = tGetSubmitBlkNext(&pHandle->blkIter)) != NULL) {
    for (int i = 0; i < pTschema->numOfCols && kvIdx < pTschema->numOfCols; i++) {
L
Liu Jicong 已提交
875 876
      // TODO: filter out unused column
      STColumn* pCol = schemaColAt(pTschema, i);
877
      void* val = tdGetMemRowDataOfColEx(row, pCol->colId, pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset, &kvIdx);
L
Liu Jicong 已提交
878
      // TODO: handle varlen
879 880 881 882 883 884
      memcpy(POINTER_SHIFT(colInfo.pData, pCol->offset), val, pCol->bytes);
    }
  }
  taosArrayPush(pArray, &colInfo);
  return pArray;
}