tqRead.c 9.3 KB
Newer Older
L
Liu Jicong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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/>.
 */

H
Hongze Cheng 已提交
16
#include "tq.h"
L
Liu Jicong 已提交
17

L
Liu Jicong 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead** ppHeadWithCkSum) {
  int32_t code = 0;
  taosThreadMutexLock(&pHandle->pWalReader->mutex);
  int64_t offset = *fetchOffset;

  while (1) {
    if (walFetchHead(pHandle->pWalReader, offset, *ppHeadWithCkSum) < 0) {
      tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", pHandle->consumerId,
              pHandle->epoch, TD_VID(pTq->pVnode), offset);
      *fetchOffset = offset - 1;
      code = -1;
      goto END;
    }

    if ((*ppHeadWithCkSum)->head.msgType == TDMT_VND_SUBMIT) {
      code = walFetchBody(pHandle->pWalReader, ppHeadWithCkSum);

      if (code < 0) {
        ASSERT(0);
        *fetchOffset = offset;
        code = -1;
        goto END;
      }
      *fetchOffset = offset;
      code = 0;
      goto END;
    } else {
      code = walSkipFetchBody(pHandle->pWalReader, *ppHeadWithCkSum);
      if (code < 0) {
        ASSERT(0);
        *fetchOffset = offset;
        code = -1;
        goto END;
      }
      offset++;
    }
  }
END:
  taosThreadMutexUnlock(&pHandle->pWalReader->mutex);
  return code;
}

L
Liu Jicong 已提交
60
STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) {
wafwerar's avatar
wafwerar 已提交
61
  STqReadHandle* pReadHandle = taosMemoryMalloc(sizeof(STqReadHandle));
L
Liu Jicong 已提交
62 63 64 65 66 67 68
  if (pReadHandle == NULL) {
    return NULL;
  }
  pReadHandle->pVnodeMeta = pMeta;
  pReadHandle->pMsg = NULL;
  pReadHandle->ver = -1;
  pReadHandle->pColIdList = NULL;
L
Liu Jicong 已提交
69
  pReadHandle->cachedSchemaVer = -1;
L
Liu Jicong 已提交
70
  pReadHandle->cachedSchemaUid = -1;
L
Liu Jicong 已提交
71 72
  pReadHandle->pSchema = NULL;
  pReadHandle->pSchemaWrapper = NULL;
L
Liu Jicong 已提交
73
  pReadHandle->tbIdHash = NULL;
L
Liu Jicong 已提交
74 75 76
  return pReadHandle;
}

L
Liu Jicong 已提交
77
int32_t tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t ver) {
L
Liu Jicong 已提交
78
  pReadHandle->pMsg = pMsg;
L
Liu Jicong 已提交
79

C
Cary Xu 已提交
80
  if (tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter) < 0) return -1;
L
Liu Jicong 已提交
81
  while (true) {
C
Cary Xu 已提交
82
    if (tGetSubmitMsgNext(&pReadHandle->msgIter, &pReadHandle->pBlock) < 0) return -1;
L
Liu Jicong 已提交
83 84 85
    if (pReadHandle->pBlock == NULL) break;
  }

C
Cary Xu 已提交
86
  if (tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter) < 0) return -1;
L
Liu Jicong 已提交
87 88
  pReadHandle->ver = ver;
  memset(&pReadHandle->blkIter, 0, sizeof(SSubmitBlkIter));
L
Liu Jicong 已提交
89
  return 0;
L
Liu Jicong 已提交
90 91 92 93
}

bool tqNextDataBlock(STqReadHandle* pHandle) {
  while (1) {
C
Cary Xu 已提交
94
    if (tGetSubmitMsgNext(&pHandle->msgIter, &pHandle->pBlock) < 0) {
L
Liu Jicong 已提交
95 96 97 98
      return false;
    }
    if (pHandle->pBlock == NULL) return false;

L
Liu Jicong 已提交
99 100 101
    if (pHandle->tbIdHash == NULL) {
      return true;
    }
C
Cary Xu 已提交
102
    void* ret = taosHashGet(pHandle->tbIdHash, &pHandle->msgIter.uid, sizeof(int64_t));
L
Liu Jicong 已提交
103 104
    if (ret != NULL) {
      return true;
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
    }
  }
  return false;
}

bool tqNextDataBlockFilterOut(STqReadHandle* pHandle, SHashObj* filterOutUids) {
  while (1) {
    if (tGetSubmitMsgNext(&pHandle->msgIter, &pHandle->pBlock) < 0) {
      return false;
    }
    if (pHandle->pBlock == NULL) return false;

    ASSERT(pHandle->tbIdHash == NULL);
    void* ret = taosHashGet(filterOutUids, &pHandle->msgIter.uid, sizeof(int64_t));
    if (ret == NULL) {
      return true;
L
Liu Jicong 已提交
121 122 123 124 125
    }
  }
  return false;
}

L
Liu Jicong 已提交
126 127
int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* pGroupId, uint64_t* pUid,
                            int32_t* pNumOfRows, int16_t* pNumOfCols) {
128 129
  *pUid = 0;

130 131 132
  // TODO set to real sversion
  /*int32_t sversion = 1;*/
  int32_t sversion = htonl(pHandle->pBlock->sversion);
L
Liu Jicong 已提交
133
  if (pHandle->cachedSchemaVer != sversion || pHandle->cachedSchemaUid != pHandle->msgIter.suid) {
C
Cary Xu 已提交
134
    pHandle->pSchema = metaGetTbTSchema(pHandle->pVnodeMeta, pHandle->msgIter.uid, sversion);
L
Liu Jicong 已提交
135
    if (pHandle->pSchema == NULL) {
L
Liu Jicong 已提交
136
      tqWarn("cannot found tsschema for table: uid: %ld (suid: %ld), version %d, possibly dropped table",
L
Liu Jicong 已提交
137
             pHandle->msgIter.uid, pHandle->msgIter.suid, pHandle->cachedSchemaVer);
L
Liu Jicong 已提交
138
      /*ASSERT(0);*/
139
      terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
L
Liu Jicong 已提交
140 141
      return -1;
    }
L
Liu Jicong 已提交
142 143

    // this interface use suid instead of uid
C
Cary Xu 已提交
144
    pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, pHandle->msgIter.suid, sversion, true);
L
Liu Jicong 已提交
145 146
    if (pHandle->pSchemaWrapper == NULL) {
      tqWarn("cannot found schema wrapper for table: suid: %ld, version %d, possibly dropped table",
L
Liu Jicong 已提交
147
             pHandle->msgIter.suid, pHandle->cachedSchemaVer);
L
Liu Jicong 已提交
148 149 150 151
      /*ASSERT(0);*/
      terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
      return -1;
    }
L
Liu Jicong 已提交
152
    pHandle->cachedSchemaVer = sversion;
L
Liu Jicong 已提交
153
    pHandle->cachedSchemaUid = pHandle->msgIter.suid;
L
Liu Jicong 已提交
154 155 156 157 158
  }

  STSchema*       pTschema = pHandle->pSchema;
  SSchemaWrapper* pSchemaWrapper = pHandle->pSchemaWrapper;

C
bug fix  
Cary Xu 已提交
159
  *pNumOfRows = pHandle->msgIter.numOfRows;
L
Liu Jicong 已提交
160 161
  int32_t colNumNeed = taosArrayGetSize(pHandle->pColIdList);

L
Liu Jicong 已提交
162 163 164 165 166
  if (colNumNeed == 0) {
    *ppCols = taosArrayInit(pSchemaWrapper->nCols, sizeof(SColumnInfoData));
    if (*ppCols == NULL) {
      return -1;
    }
L
Liu Jicong 已提交
167

L
Liu Jicong 已提交
168 169 170
    int32_t colMeta = 0;
    while (colMeta < pSchemaWrapper->nCols) {
      SSchema*        pColSchema = &pSchemaWrapper->pSchema[colMeta];
L
Liu Jicong 已提交
171 172 173 174 175
      SColumnInfoData colInfo = {0};
      colInfo.info.bytes = pColSchema->bytes;
      colInfo.info.colId = pColSchema->colId;
      colInfo.info.type = pColSchema->type;

L
Liu Jicong 已提交
176
      if (colInfoDataEnsureCapacity(&colInfo, 0, *pNumOfRows) < 0) {
L
Liu Jicong 已提交
177
        goto FAIL;
L
Liu Jicong 已提交
178
      }
L
Liu Jicong 已提交
179
      taosArrayPush(*ppCols, &colInfo);
L
Liu Jicong 已提交
180
      colMeta++;
L
Liu Jicong 已提交
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    }
  } else {
    if (colNumNeed > pSchemaWrapper->nCols) {
      colNumNeed = pSchemaWrapper->nCols;
    }

    *ppCols = taosArrayInit(colNumNeed, sizeof(SColumnInfoData));
    if (*ppCols == NULL) {
      return -1;
    }

    int32_t colMeta = 0;
    int32_t colNeed = 0;
    while (colMeta < pSchemaWrapper->nCols && colNeed < colNumNeed) {
      SSchema* pColSchema = &pSchemaWrapper->pSchema[colMeta];
      col_id_t colIdSchema = pColSchema->colId;
      col_id_t colIdNeed = *(col_id_t*)taosArrayGet(pHandle->pColIdList, colNeed);
      if (colIdSchema < colIdNeed) {
        colMeta++;
      } else if (colIdSchema > colIdNeed) {
        colNeed++;
      } else {
        SColumnInfoData colInfo = {0};
        colInfo.info.bytes = pColSchema->bytes;
        colInfo.info.colId = pColSchema->colId;
        colInfo.info.type = pColSchema->type;

        if (colInfoDataEnsureCapacity(&colInfo, 0, *pNumOfRows) < 0) {
          goto FAIL;
        }
        taosArrayPush(*ppCols, &colInfo);
        colMeta++;
        colNeed++;
      }
L
Liu Jicong 已提交
215 216
    }
  }
L
Liu Jicong 已提交
217

L
Liu Jicong 已提交
218
  int32_t colActual = taosArrayGetSize(*ppCols);
L
Liu Jicong 已提交
219
  *pNumOfCols = colActual;
L
Liu Jicong 已提交
220 221 222 223

  // TODO in stream shuffle case, fetch groupId
  *pGroupId = 0;

L
Liu Jicong 已提交
224 225 226 227
  STSRowIter iter = {0};
  tdSTSRowIterInit(&iter, pTschema);
  STSRow* row;
  int32_t curRow = 0;
228

C
Cary Xu 已提交
229
  tInitSubmitBlkIter(&pHandle->msgIter, pHandle->pBlock, &pHandle->blkIter);
5
54liuyao 已提交
230
  *pUid = pHandle->msgIter.uid;  // set the uid of table for submit block
231

C
Cary Xu 已提交
232
  while ((row = tGetSubmitBlkNext(&pHandle->blkIter)) != NULL) {
L
Liu Jicong 已提交
233 234
    tdSTSRowIterReset(&iter, row);
    // get all wanted col of that block
L
Liu Jicong 已提交
235 236
    for (int32_t i = 0; i < colActual; i++) {
      SColumnInfoData* pColData = taosArrayGet(*ppCols, i);
L
Liu Jicong 已提交
237 238 239 240
      SCellVal         sVal = {0};
      if (!tdSTSRowIterNext(&iter, pColData->info.colId, pColData->info.type, &sVal)) {
        break;
      }
L
Liu Jicong 已提交
241
      if (colDataAppend(pColData, curRow, sVal.val, sVal.valType == TD_VTYPE_NULL) < 0) {
L
Liu Jicong 已提交
242
        goto FAIL;
L
Liu Jicong 已提交
243
      }
L
Liu Jicong 已提交
244 245 246
    }
    curRow++;
  }
L
Liu Jicong 已提交
247 248
  return 0;
FAIL:
L
Liu Jicong 已提交
249
  if (*ppCols) taosArrayDestroy(*ppCols);
L
Liu Jicong 已提交
250
  return -1;
L
Liu Jicong 已提交
251
}
H
Hongze Cheng 已提交
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289

void tqReadHandleSetColIdList(STqReadHandle* pReadHandle, SArray* pColIdList) { pReadHandle->pColIdList = pColIdList; }

int tqReadHandleSetTbUidList(STqReadHandle* pHandle, const SArray* tbUidList) {
  if (pHandle->tbIdHash) {
    taosHashClear(pHandle->tbIdHash);
  }

  pHandle->tbIdHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
  if (pHandle->tbIdHash == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  for (int i = 0; i < taosArrayGetSize(tbUidList); i++) {
    int64_t* pKey = (int64_t*)taosArrayGet(tbUidList, i);
    taosHashPut(pHandle->tbIdHash, pKey, sizeof(int64_t), NULL, 0);
  }

  return 0;
}

int tqReadHandleAddTbUidList(STqReadHandle* pHandle, const SArray* tbUidList) {
  if (pHandle->tbIdHash == NULL) {
    pHandle->tbIdHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
    if (pHandle->tbIdHash == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
  }

  for (int i = 0; i < taosArrayGetSize(tbUidList); i++) {
    int64_t* pKey = (int64_t*)taosArrayGet(tbUidList, i);
    taosHashPut(pHandle->tbIdHash, pKey, sizeof(int64_t), NULL, 0);
  }

  return 0;
}
290 291 292 293

int tqReadHandleRemoveTbUidList(STqReadHandle* pHandle, const SArray* tbUidList) {
  ASSERT(pHandle->tbIdHash != NULL);

L
Liu Jicong 已提交
294 295
  for (int32_t i = 0; i < taosArrayGetSize(tbUidList); i++) {
    int64_t* pKey = (int64_t*)taosArrayGet(tbUidList, i);
296 297 298 299 300
    taosHashRemove(pHandle->tbIdHash, pKey, sizeof(int64_t));
  }

  return 0;
}