Merge branch '3.0' into feat/TD-24834
This commit is contained in:
commit
4d660d89c0
|
|
@ -107,6 +107,9 @@ typedef struct SFirstLastRes {
|
|||
bool isNull;
|
||||
int32_t bytes;
|
||||
int64_t ts;
|
||||
char* pkData;
|
||||
int32_t pkBytes;
|
||||
int8_t pkType;
|
||||
STuplePos pos;
|
||||
char buf[];
|
||||
} SFirstLastRes;
|
||||
|
|
@ -200,6 +203,19 @@ typedef struct SBlockID {
|
|||
uint64_t groupId;
|
||||
} SBlockID;
|
||||
|
||||
typedef struct SPkInfo {
|
||||
int8_t type;
|
||||
int32_t bytes;
|
||||
union {
|
||||
int64_t val;
|
||||
uint8_t* pData;
|
||||
} skey;
|
||||
union {
|
||||
int64_t val;
|
||||
uint8_t* pData;
|
||||
} ekey;
|
||||
} SPkInfo;
|
||||
|
||||
typedef struct SDataBlockInfo {
|
||||
STimeWindow window;
|
||||
int32_t rowSize;
|
||||
|
|
@ -210,6 +226,7 @@ typedef struct SDataBlockInfo {
|
|||
int16_t dataLoad; // denote if the data is loaded or not
|
||||
uint8_t scanFlag;
|
||||
bool blankFill;
|
||||
SValue pks[2];
|
||||
|
||||
// TODO: optimize and remove following
|
||||
int64_t version; // used for stream, and need serialization
|
||||
|
|
@ -388,6 +405,7 @@ typedef struct STUidTagInfo {
|
|||
#define CALCULATE_START_TS_COLUMN_INDEX 4
|
||||
#define CALCULATE_END_TS_COLUMN_INDEX 5
|
||||
#define TABLE_NAME_COLUMN_INDEX 6
|
||||
#define PRIMARY_KEY_COLUMN_INDEX 7
|
||||
|
||||
// stream create table block column
|
||||
#define UD_TABLE_NAME_COLUMN_INDEX 0
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int
|
|||
int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* pSource, int32_t numOfRows,
|
||||
const SDataBlockInfo* pBlockInfo);
|
||||
int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock, int32_t tsColumnIndex);
|
||||
int32_t blockDataUpdatePkRange(SSDataBlock* pDataBlock, int32_t pkColumnIndex, bool asc);
|
||||
|
||||
int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRows);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "os.h"
|
||||
#include "talgo.h"
|
||||
#include "tarray.h"
|
||||
#include "tbuffer.h"
|
||||
#include "tencode.h"
|
||||
#include "ttypes.h"
|
||||
#include "tutil.h"
|
||||
|
|
@ -27,7 +28,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SBuffer SBuffer;
|
||||
typedef struct SSchema SSchema;
|
||||
typedef struct SSchema2 SSchema2;
|
||||
typedef struct STColumn STColumn;
|
||||
|
|
@ -40,6 +40,9 @@ typedef struct STagVal STagVal;
|
|||
typedef struct STag STag;
|
||||
typedef struct SColData SColData;
|
||||
|
||||
typedef struct SRowKey SRowKey;
|
||||
typedef struct SValueColumn SValueColumn;
|
||||
|
||||
#define HAS_NONE ((uint8_t)0x1)
|
||||
#define HAS_NULL ((uint8_t)0x2)
|
||||
#define HAS_VALUE ((uint8_t)0x4)
|
||||
|
|
@ -53,9 +56,9 @@ const static uint8_t BIT2_MAP[4] = {0b11111100, 0b11110011, 0b11001111, 0b001111
|
|||
#define ONE ((uint8_t)1)
|
||||
#define THREE ((uint8_t)3)
|
||||
#define DIV_8(i) ((i) >> 3)
|
||||
#define MOD_8(i) ((i)&7)
|
||||
#define MOD_8(i) ((i) & 7)
|
||||
#define DIV_4(i) ((i) >> 2)
|
||||
#define MOD_4(i) ((i)&3)
|
||||
#define MOD_4(i) ((i) & 3)
|
||||
#define MOD_4_TIME_2(i) (MOD_4(i) << 1)
|
||||
#define BIT1_SIZE(n) (DIV_8((n)-1) + 1)
|
||||
#define BIT2_SIZE(n) (DIV_4((n)-1) + 1)
|
||||
|
|
@ -78,32 +81,42 @@ const static uint8_t BIT2_MAP[4] = {0b11111100, 0b11110011, 0b11001111, 0b001111
|
|||
} while (0)
|
||||
#define GET_BIT2(p, i) (((p)[DIV_4(i)] >> MOD_4_TIME_2(i)) & THREE)
|
||||
|
||||
// SBuffer ================================
|
||||
struct SBuffer {
|
||||
int64_t nBuf;
|
||||
uint8_t *pBuf;
|
||||
};
|
||||
|
||||
#define tBufferCreate() \
|
||||
(SBuffer) { .nBuf = 0, .pBuf = NULL }
|
||||
void tBufferDestroy(SBuffer *pBuffer);
|
||||
int32_t tBufferInit(SBuffer *pBuffer, int64_t size);
|
||||
int32_t tBufferPut(SBuffer *pBuffer, const void *pData, int64_t nData);
|
||||
int32_t tBufferReserve(SBuffer *pBuffer, int64_t nData, void **ppData);
|
||||
|
||||
// SColVal ================================
|
||||
#define CV_FLAG_VALUE ((int8_t)0x0)
|
||||
#define CV_FLAG_NONE ((int8_t)0x1)
|
||||
#define CV_FLAG_NULL ((int8_t)0x2)
|
||||
|
||||
#define COL_VAL_NONE(CID, TYPE) ((SColVal){.cid = (CID), .type = (TYPE), .flag = CV_FLAG_NONE})
|
||||
#define COL_VAL_NULL(CID, TYPE) ((SColVal){.cid = (CID), .type = (TYPE), .flag = CV_FLAG_NULL})
|
||||
#define COL_VAL_VALUE(CID, TYPE, V) ((SColVal){.cid = (CID), .type = (TYPE), .value = (V)})
|
||||
#define COL_VAL_NONE(CID, TYPE) ((SColVal){.cid = (CID), .flag = CV_FLAG_NONE, .value = {.type = (TYPE)}})
|
||||
#define COL_VAL_NULL(CID, TYPE) ((SColVal){.cid = (CID), .flag = CV_FLAG_NULL, .value = {.type = (TYPE)}})
|
||||
#define COL_VAL_VALUE(CID, V) ((SColVal){.cid = (CID), .flag = CV_FLAG_VALUE, .value = (V)})
|
||||
|
||||
#define COL_VAL_IS_NONE(CV) ((CV)->flag == CV_FLAG_NONE)
|
||||
#define COL_VAL_IS_NULL(CV) ((CV)->flag == CV_FLAG_NULL)
|
||||
#define COL_VAL_IS_VALUE(CV) ((CV)->flag == CV_FLAG_VALUE)
|
||||
|
||||
// SValueColumn ================================
|
||||
typedef struct {
|
||||
int8_t cmprAlg; // filled by caller
|
||||
int8_t type;
|
||||
int32_t dataOriginalSize;
|
||||
int32_t dataCompressedSize;
|
||||
int32_t offsetOriginalSize;
|
||||
int32_t offsetCompressedSize;
|
||||
} SValueColumnCompressInfo;
|
||||
|
||||
int32_t tValueColumnInit(SValueColumn *valCol);
|
||||
int32_t tValueColumnDestroy(SValueColumn *valCol);
|
||||
int32_t tValueColumnClear(SValueColumn *valCol);
|
||||
int32_t tValueColumnAppend(SValueColumn *valCol, const SValue *value);
|
||||
int32_t tValueColumnUpdate(SValueColumn *valCol, int32_t idx, const SValue *value);
|
||||
int32_t tValueColumnGet(SValueColumn *valCol, int32_t idx, SValue *value);
|
||||
int32_t tValueColumnCompress(SValueColumn *valCol, SValueColumnCompressInfo *info, SBuffer *output, SBuffer *assist);
|
||||
int32_t tValueColumnDecompress(void *input, const SValueColumnCompressInfo *compressInfo, SValueColumn *valCol,
|
||||
SBuffer *buffer);
|
||||
int32_t tValueColumnCompressInfoEncode(const SValueColumnCompressInfo *compressInfo, SBuffer *buffer);
|
||||
int32_t tValueColumnCompressInfoDecode(SBufferReader *reader, SValueColumnCompressInfo *compressInfo);
|
||||
int32_t tValueCompare(const SValue *tv1, const SValue *tv2);
|
||||
|
||||
// SRow ================================
|
||||
int32_t tRowBuild(SArray *aColVal, const STSchema *pTSchema, SRow **ppRow);
|
||||
int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal);
|
||||
|
|
@ -111,6 +124,9 @@ void tRowDestroy(SRow *pRow);
|
|||
int32_t tRowSort(SArray *aRowP);
|
||||
int32_t tRowMerge(SArray *aRowP, STSchema *pTSchema, int8_t flag);
|
||||
int32_t tRowUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aColData, int32_t nColData, int32_t flag);
|
||||
void tRowGetKey(SRow *pRow, SRowKey *key);
|
||||
int32_t tRowKeyCompare(const void *p1, const void *p2);
|
||||
int32_t tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc);
|
||||
|
||||
// SRowIter ================================
|
||||
int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter);
|
||||
|
|
@ -132,9 +148,25 @@ void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remov
|
|||
int32_t parseJsontoTagData(const char *json, SArray *pTagVals, STag **ppTag, void *pMsgBuf);
|
||||
|
||||
// SColData ================================
|
||||
typedef struct {
|
||||
int8_t cmprAlg; // filled by caller
|
||||
int8_t columnFlag;
|
||||
int8_t flag;
|
||||
int8_t dataType;
|
||||
int16_t columnId;
|
||||
int32_t numOfData;
|
||||
int32_t bitmapOriginalSize;
|
||||
int32_t bitmapCompressedSize;
|
||||
int32_t offsetOriginalSize;
|
||||
int32_t offsetCompressedSize;
|
||||
int32_t dataOriginalSize;
|
||||
int32_t dataCompressedSize;
|
||||
} SColDataCompressInfo;
|
||||
|
||||
typedef void *(*xMallocFn)(void *, int32_t);
|
||||
|
||||
void tColDataDestroy(void *ph);
|
||||
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t smaOn);
|
||||
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag);
|
||||
void tColDataClear(SColData *pColData);
|
||||
void tColDataDeepClear(SColData *pColData);
|
||||
int32_t tColDataAppendValue(SColData *pColData, SColVal *pColVal);
|
||||
|
|
@ -142,8 +174,13 @@ int32_t tColDataUpdateValue(SColData *pColData, SColVal *pColVal, bool forward);
|
|||
void tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal);
|
||||
uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal);
|
||||
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg);
|
||||
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key);
|
||||
|
||||
extern void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull);
|
||||
|
||||
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist);
|
||||
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist);
|
||||
|
||||
// for stmt bind
|
||||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen);
|
||||
void tColDataSortMerge(SArray *colDataArr);
|
||||
|
|
@ -152,8 +189,8 @@ void tColDataSortMerge(SArray *colDataArr);
|
|||
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
|
||||
char *data);
|
||||
// for encode/decode
|
||||
int32_t tPutColData(uint8_t *pBuf, SColData *pColData);
|
||||
int32_t tGetColData(uint8_t *pBuf, SColData *pColData);
|
||||
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData);
|
||||
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData);
|
||||
|
||||
// STRUCT ================================
|
||||
struct STColumn {
|
||||
|
|
@ -172,28 +209,47 @@ struct STSchema {
|
|||
STColumn columns[];
|
||||
};
|
||||
|
||||
/*
|
||||
* 1. Tuple format:
|
||||
* SRow + [(type, offset) * numOfPKs +] [bit map +] fix-length data + [var-length data]
|
||||
*
|
||||
* 2. K-V format:
|
||||
* SRow + [(type, offset) * numOfPKs +] offset array + ([-]cid [+ data]) * numColsNotNone
|
||||
*/
|
||||
struct SRow {
|
||||
uint8_t flag;
|
||||
uint8_t rsv;
|
||||
uint8_t numOfPKs;
|
||||
uint16_t sver;
|
||||
uint32_t len;
|
||||
TSKEY ts;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int8_t type;
|
||||
uint32_t offset;
|
||||
} SPrimaryKeyIndex;
|
||||
|
||||
struct SValue {
|
||||
int8_t type;
|
||||
union {
|
||||
int64_t val;
|
||||
struct {
|
||||
uint32_t nData;
|
||||
uint8_t *pData;
|
||||
uint32_t nData;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#define TD_MAX_PK_COLS 2
|
||||
struct SRowKey {
|
||||
TSKEY ts;
|
||||
uint8_t numOfPKs;
|
||||
SValue pks[TD_MAX_PK_COLS];
|
||||
};
|
||||
|
||||
struct SColVal {
|
||||
int16_t cid;
|
||||
int8_t type;
|
||||
int8_t flag;
|
||||
SValue value;
|
||||
};
|
||||
|
|
@ -201,7 +257,7 @@ struct SColVal {
|
|||
struct SColData {
|
||||
int16_t cid;
|
||||
int8_t type;
|
||||
int8_t smaOn;
|
||||
int8_t cflag;
|
||||
int32_t numOfNone; // # of none
|
||||
int32_t numOfNull; // # of null
|
||||
int32_t numOfValue; // # of vale
|
||||
|
|
@ -273,6 +329,36 @@ STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version);
|
|||
pTSchema = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
const STColumn *tTSchemaSearchColumn(const STSchema *pTSchema, int16_t cid);
|
||||
|
||||
struct SValueColumn {
|
||||
int8_t type;
|
||||
uint32_t numOfValues;
|
||||
SBuffer data;
|
||||
SBuffer offsets;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int8_t dataType; // filled by caller
|
||||
int8_t cmprAlg; // filled by caller
|
||||
int32_t originalSize; // filled by caller
|
||||
int32_t compressedSize;
|
||||
} SCompressInfo;
|
||||
|
||||
int32_t tCompressData(void *input, // input
|
||||
SCompressInfo *info, // compress info
|
||||
void *output, // output
|
||||
int32_t outputSize, // output size
|
||||
SBuffer *buffer // assistant buffer provided by caller, can be NULL
|
||||
);
|
||||
int32_t tDecompressData(void *input, // input
|
||||
const SCompressInfo *info, // compress info
|
||||
void *output, // output
|
||||
int32_t outputSize, // output size
|
||||
SBuffer *buffer // assistant buffer provided by caller, can be NULL
|
||||
);
|
||||
int32_t tCompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist);
|
||||
int32_t tDecompressDataToBuffer(void *input, SCompressInfo *info, SBuffer *output, SBuffer *assist);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ extern char tsSmlTsDefaultName[];
|
|||
// extern int32_t tsSmlBatchSize;
|
||||
|
||||
extern int32_t tmqMaxTopicNum;
|
||||
extern int32_t tmqRowSize;
|
||||
|
||||
// wal
|
||||
extern int64_t tsWalFsyncDataSizeLimit;
|
||||
|
|
|
|||
|
|
@ -592,6 +592,7 @@ void tFreeSSubmitRsp(SSubmitRsp* pRsp);
|
|||
|
||||
#define COL_SMA_ON ((int8_t)0x1)
|
||||
#define COL_IDX_ON ((int8_t)0x2)
|
||||
#define COL_IS_KEY ((int8_t)0x4)
|
||||
#define COL_SET_NULL ((int8_t)0x10)
|
||||
#define COL_SET_VAL ((int8_t)0x20)
|
||||
#define COL_IS_SYSINFO ((int8_t)0x40)
|
||||
|
|
@ -1040,6 +1041,7 @@ typedef struct {
|
|||
uint8_t scale;
|
||||
int32_t bytes;
|
||||
int8_t type;
|
||||
uint8_t pk;
|
||||
} SColumnInfo;
|
||||
|
||||
typedef struct STimeWindow {
|
||||
|
|
@ -2571,6 +2573,8 @@ typedef struct {
|
|||
int8_t igUpdate;
|
||||
int64_t lastTs;
|
||||
SArray* pVgroupVerList;
|
||||
// 3.3.0.0
|
||||
SArray* pCols; // array of SField
|
||||
} SCMCreateStreamReq;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -3413,6 +3417,8 @@ enum {
|
|||
ONLY_META = 2,
|
||||
};
|
||||
|
||||
#define TQ_OFFSET_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
int8_t type;
|
||||
union {
|
||||
|
|
@ -3420,6 +3426,7 @@ typedef struct {
|
|||
struct {
|
||||
int64_t uid;
|
||||
int64_t ts;
|
||||
SValue primaryKey;
|
||||
};
|
||||
// log
|
||||
struct {
|
||||
|
|
@ -3428,10 +3435,14 @@ typedef struct {
|
|||
};
|
||||
} STqOffsetVal;
|
||||
|
||||
static FORCE_INLINE void tqOffsetResetToData(STqOffsetVal* pOffsetVal, int64_t uid, int64_t ts) {
|
||||
static FORCE_INLINE void tqOffsetResetToData(STqOffsetVal* pOffsetVal, int64_t uid, int64_t ts, SValue primaryKey) {
|
||||
pOffsetVal->type = TMQ_OFFSET__SNAPSHOT_DATA;
|
||||
pOffsetVal->uid = uid;
|
||||
pOffsetVal->ts = ts;
|
||||
if(IS_VAR_DATA_TYPE(pOffsetVal->primaryKey.type)){
|
||||
taosMemoryFree(pOffsetVal->primaryKey.pData);
|
||||
}
|
||||
pOffsetVal->primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tqOffsetResetToMeta(STqOffsetVal* pOffsetVal, int64_t uid) {
|
||||
|
|
@ -3448,6 +3459,8 @@ int32_t tEncodeSTqOffsetVal(SEncoder* pEncoder, const STqOffsetVal* pOffsetVal);
|
|||
int32_t tDecodeSTqOffsetVal(SDecoder* pDecoder, STqOffsetVal* pOffsetVal);
|
||||
int32_t tFormatOffset(char* buf, int32_t maxLen, const STqOffsetVal* pVal);
|
||||
bool tOffsetEqual(const STqOffsetVal* pLeft, const STqOffsetVal* pRight);
|
||||
void tOffsetCopy(STqOffsetVal* pLeft, const STqOffsetVal* pOffsetVal);
|
||||
void tOffsetDestroy(void* pVal);
|
||||
|
||||
typedef struct {
|
||||
STqOffsetVal val;
|
||||
|
|
@ -3754,6 +3767,7 @@ typedef struct {
|
|||
|
||||
int32_t tSerializeSMqPollReq(void* buf, int32_t bufLen, SMqPollReq* pReq);
|
||||
int32_t tDeserializeSMqPollReq(void* buf, int32_t bufLen, SMqPollReq* pReq);
|
||||
void tDestroySMqPollReq(SMqPollReq *pReq);
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
|
|
@ -3797,7 +3811,9 @@ typedef struct {
|
|||
|
||||
int32_t tEncodeMqMetaRsp(SEncoder* pEncoder, const SMqMetaRsp* pRsp);
|
||||
int32_t tDecodeMqMetaRsp(SDecoder* pDecoder, SMqMetaRsp* pRsp);
|
||||
void tDeleteMqMetaRsp(SMqMetaRsp *pRsp);
|
||||
|
||||
#define MQ_DATA_RSP_VERSION 100
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
STqOffsetVal reqOffset;
|
||||
|
|
@ -3813,7 +3829,7 @@ typedef struct {
|
|||
} SMqDataRsp;
|
||||
|
||||
int32_t tEncodeMqDataRsp(SEncoder* pEncoder, const SMqDataRsp* pRsp);
|
||||
int32_t tDecodeMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp);
|
||||
int32_t tDecodeMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp, int8_t dataVersion);
|
||||
void tDeleteMqDataRsp(SMqDataRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -3834,7 +3850,7 @@ typedef struct {
|
|||
} STaosxRsp;
|
||||
|
||||
int32_t tEncodeSTaosxRsp(SEncoder* pEncoder, const STaosxRsp* pRsp);
|
||||
int32_t tDecodeSTaosxRsp(SDecoder* pDecoder, STaosxRsp* pRsp);
|
||||
int32_t tDecodeSTaosxRsp(SDecoder* pDecoder, STaosxRsp* pRsp, int8_t dateVersion);
|
||||
void tDeleteSTaosxRsp(STaosxRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -4040,6 +4056,7 @@ int32_t tDeserializeSMqSeekReq(void* buf, int32_t bufLen, SMqSeekReq* pReq);
|
|||
#define SUBMIT_REQ_COLUMN_DATA_FORMAT 0x2
|
||||
#define SUBMIT_REQ_FROM_FILE 0x4
|
||||
#define TD_REQ_FROM_TAOX 0x8
|
||||
#define SUBMIT_REQUEST_VERSION (1)
|
||||
|
||||
#define TD_REQ_FROM_TAOX_OLD 0x1 // for compatibility
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#ifndef _TD_COMMON_TOKEN_H_
|
||||
#define _TD_COMMON_TOKEN_H_
|
||||
|
||||
|
||||
#define TK_OR 1
|
||||
#define TK_AND 2
|
||||
#define TK_UNION 3
|
||||
|
|
@ -136,243 +135,244 @@
|
|||
#define TK_NK_EQ 117
|
||||
#define TK_USING 118
|
||||
#define TK_TAGS 119
|
||||
#define TK_BOOL 120
|
||||
#define TK_TINYINT 121
|
||||
#define TK_SMALLINT 122
|
||||
#define TK_INT 123
|
||||
#define TK_INTEGER 124
|
||||
#define TK_BIGINT 125
|
||||
#define TK_FLOAT 126
|
||||
#define TK_DOUBLE 127
|
||||
#define TK_BINARY 128
|
||||
#define TK_NCHAR 129
|
||||
#define TK_UNSIGNED 130
|
||||
#define TK_JSON 131
|
||||
#define TK_VARCHAR 132
|
||||
#define TK_MEDIUMBLOB 133
|
||||
#define TK_BLOB 134
|
||||
#define TK_VARBINARY 135
|
||||
#define TK_GEOMETRY 136
|
||||
#define TK_DECIMAL 137
|
||||
#define TK_COMMENT 138
|
||||
#define TK_MAX_DELAY 139
|
||||
#define TK_WATERMARK 140
|
||||
#define TK_ROLLUP 141
|
||||
#define TK_TTL 142
|
||||
#define TK_SMA 143
|
||||
#define TK_DELETE_MARK 144
|
||||
#define TK_FIRST 145
|
||||
#define TK_LAST 146
|
||||
#define TK_SHOW 147
|
||||
#define TK_PRIVILEGES 148
|
||||
#define TK_DATABASES 149
|
||||
#define TK_TABLES 150
|
||||
#define TK_STABLES 151
|
||||
#define TK_MNODES 152
|
||||
#define TK_QNODES 153
|
||||
#define TK_ARBGROUPS 154
|
||||
#define TK_FUNCTIONS 155
|
||||
#define TK_INDEXES 156
|
||||
#define TK_ACCOUNTS 157
|
||||
#define TK_APPS 158
|
||||
#define TK_CONNECTIONS 159
|
||||
#define TK_LICENCES 160
|
||||
#define TK_GRANTS 161
|
||||
#define TK_FULL 162
|
||||
#define TK_LOGS 163
|
||||
#define TK_MACHINES 164
|
||||
#define TK_ENCRYPTIONS 165
|
||||
#define TK_QUERIES 166
|
||||
#define TK_SCORES 167
|
||||
#define TK_TOPICS 168
|
||||
#define TK_VARIABLES 169
|
||||
#define TK_BNODES 170
|
||||
#define TK_SNODES 171
|
||||
#define TK_TRANSACTIONS 172
|
||||
#define TK_DISTRIBUTED 173
|
||||
#define TK_CONSUMERS 174
|
||||
#define TK_SUBSCRIPTIONS 175
|
||||
#define TK_VNODES 176
|
||||
#define TK_ALIVE 177
|
||||
#define TK_VIEWS 178
|
||||
#define TK_VIEW 179
|
||||
#define TK_COMPACTS 180
|
||||
#define TK_NORMAL 181
|
||||
#define TK_CHILD 182
|
||||
#define TK_LIKE 183
|
||||
#define TK_TBNAME 184
|
||||
#define TK_QTAGS 185
|
||||
#define TK_AS 186
|
||||
#define TK_SYSTEM 187
|
||||
#define TK_INDEX 188
|
||||
#define TK_FUNCTION 189
|
||||
#define TK_INTERVAL 190
|
||||
#define TK_COUNT 191
|
||||
#define TK_LAST_ROW 192
|
||||
#define TK_META 193
|
||||
#define TK_ONLY 194
|
||||
#define TK_TOPIC 195
|
||||
#define TK_CONSUMER 196
|
||||
#define TK_GROUP 197
|
||||
#define TK_DESC 198
|
||||
#define TK_DESCRIBE 199
|
||||
#define TK_RESET 200
|
||||
#define TK_QUERY 201
|
||||
#define TK_CACHE 202
|
||||
#define TK_EXPLAIN 203
|
||||
#define TK_ANALYZE 204
|
||||
#define TK_VERBOSE 205
|
||||
#define TK_NK_BOOL 206
|
||||
#define TK_RATIO 207
|
||||
#define TK_NK_FLOAT 208
|
||||
#define TK_OUTPUTTYPE 209
|
||||
#define TK_AGGREGATE 210
|
||||
#define TK_BUFSIZE 211
|
||||
#define TK_LANGUAGE 212
|
||||
#define TK_REPLACE 213
|
||||
#define TK_STREAM 214
|
||||
#define TK_INTO 215
|
||||
#define TK_PAUSE 216
|
||||
#define TK_RESUME 217
|
||||
#define TK_TRIGGER 218
|
||||
#define TK_AT_ONCE 219
|
||||
#define TK_WINDOW_CLOSE 220
|
||||
#define TK_IGNORE 221
|
||||
#define TK_EXPIRED 222
|
||||
#define TK_FILL_HISTORY 223
|
||||
#define TK_UPDATE 224
|
||||
#define TK_SUBTABLE 225
|
||||
#define TK_UNTREATED 226
|
||||
#define TK_KILL 227
|
||||
#define TK_CONNECTION 228
|
||||
#define TK_TRANSACTION 229
|
||||
#define TK_BALANCE 230
|
||||
#define TK_VGROUP 231
|
||||
#define TK_LEADER 232
|
||||
#define TK_MERGE 233
|
||||
#define TK_REDISTRIBUTE 234
|
||||
#define TK_SPLIT 235
|
||||
#define TK_DELETE 236
|
||||
#define TK_INSERT 237
|
||||
#define TK_NK_BIN 238
|
||||
#define TK_NK_HEX 239
|
||||
#define TK_NULL 240
|
||||
#define TK_NK_QUESTION 241
|
||||
#define TK_NK_ALIAS 242
|
||||
#define TK_NK_ARROW 243
|
||||
#define TK_ROWTS 244
|
||||
#define TK_QSTART 245
|
||||
#define TK_QEND 246
|
||||
#define TK_QDURATION 247
|
||||
#define TK_WSTART 248
|
||||
#define TK_WEND 249
|
||||
#define TK_WDURATION 250
|
||||
#define TK_IROWTS 251
|
||||
#define TK_ISFILLED 252
|
||||
#define TK_CAST 253
|
||||
#define TK_NOW 254
|
||||
#define TK_TODAY 255
|
||||
#define TK_TIMEZONE 256
|
||||
#define TK_CLIENT_VERSION 257
|
||||
#define TK_SERVER_VERSION 258
|
||||
#define TK_SERVER_STATUS 259
|
||||
#define TK_CURRENT_USER 260
|
||||
#define TK_CASE 261
|
||||
#define TK_WHEN 262
|
||||
#define TK_THEN 263
|
||||
#define TK_ELSE 264
|
||||
#define TK_BETWEEN 265
|
||||
#define TK_IS 266
|
||||
#define TK_NK_LT 267
|
||||
#define TK_NK_GT 268
|
||||
#define TK_NK_LE 269
|
||||
#define TK_NK_GE 270
|
||||
#define TK_NK_NE 271
|
||||
#define TK_MATCH 272
|
||||
#define TK_NMATCH 273
|
||||
#define TK_CONTAINS 274
|
||||
#define TK_IN 275
|
||||
#define TK_JOIN 276
|
||||
#define TK_INNER 277
|
||||
#define TK_SELECT 278
|
||||
#define TK_NK_HINT 279
|
||||
#define TK_DISTINCT 280
|
||||
#define TK_WHERE 281
|
||||
#define TK_PARTITION 282
|
||||
#define TK_BY 283
|
||||
#define TK_SESSION 284
|
||||
#define TK_STATE_WINDOW 285
|
||||
#define TK_EVENT_WINDOW 286
|
||||
#define TK_COUNT_WINDOW 287
|
||||
#define TK_SLIDING 288
|
||||
#define TK_FILL 289
|
||||
#define TK_VALUE 290
|
||||
#define TK_VALUE_F 291
|
||||
#define TK_NONE 292
|
||||
#define TK_PREV 293
|
||||
#define TK_NULL_F 294
|
||||
#define TK_LINEAR 295
|
||||
#define TK_NEXT 296
|
||||
#define TK_HAVING 297
|
||||
#define TK_RANGE 298
|
||||
#define TK_EVERY 299
|
||||
#define TK_ORDER 300
|
||||
#define TK_SLIMIT 301
|
||||
#define TK_SOFFSET 302
|
||||
#define TK_LIMIT 303
|
||||
#define TK_OFFSET 304
|
||||
#define TK_ASC 305
|
||||
#define TK_NULLS 306
|
||||
#define TK_ABORT 307
|
||||
#define TK_AFTER 308
|
||||
#define TK_ATTACH 309
|
||||
#define TK_BEFORE 310
|
||||
#define TK_BEGIN 311
|
||||
#define TK_BITAND 312
|
||||
#define TK_BITNOT 313
|
||||
#define TK_BITOR 314
|
||||
#define TK_BLOCKS 315
|
||||
#define TK_CHANGE 316
|
||||
#define TK_COMMA 317
|
||||
#define TK_CONCAT 318
|
||||
#define TK_CONFLICT 319
|
||||
#define TK_COPY 320
|
||||
#define TK_DEFERRED 321
|
||||
#define TK_DELIMITERS 322
|
||||
#define TK_DETACH 323
|
||||
#define TK_DIVIDE 324
|
||||
#define TK_DOT 325
|
||||
#define TK_EACH 326
|
||||
#define TK_FAIL 327
|
||||
#define TK_FILE 328
|
||||
#define TK_FOR 329
|
||||
#define TK_GLOB 330
|
||||
#define TK_ID 331
|
||||
#define TK_IMMEDIATE 332
|
||||
#define TK_IMPORT 333
|
||||
#define TK_INITIALLY 334
|
||||
#define TK_INSTEAD 335
|
||||
#define TK_ISNULL 336
|
||||
#define TK_KEY 337
|
||||
#define TK_MODULES 338
|
||||
#define TK_NK_BITNOT 339
|
||||
#define TK_NK_SEMI 340
|
||||
#define TK_NOTNULL 341
|
||||
#define TK_OF 342
|
||||
#define TK_PLUS 343
|
||||
#define TK_PRIVILEGE 344
|
||||
#define TK_RAISE 345
|
||||
#define TK_RESTRICT 346
|
||||
#define TK_ROW 347
|
||||
#define TK_SEMI 348
|
||||
#define TK_STAR 349
|
||||
#define TK_STATEMENT 350
|
||||
#define TK_STRICT 351
|
||||
#define TK_STRING 352
|
||||
#define TK_TIMES 353
|
||||
#define TK_VALUES 354
|
||||
#define TK_VARIABLE 355
|
||||
#define TK_WAL 356
|
||||
#define TK_PRIMARY 120
|
||||
#define TK_KEY 121
|
||||
#define TK_BOOL 122
|
||||
#define TK_TINYINT 123
|
||||
#define TK_SMALLINT 124
|
||||
#define TK_INT 125
|
||||
#define TK_INTEGER 126
|
||||
#define TK_BIGINT 127
|
||||
#define TK_FLOAT 128
|
||||
#define TK_DOUBLE 129
|
||||
#define TK_BINARY 130
|
||||
#define TK_NCHAR 131
|
||||
#define TK_UNSIGNED 132
|
||||
#define TK_JSON 133
|
||||
#define TK_VARCHAR 134
|
||||
#define TK_MEDIUMBLOB 135
|
||||
#define TK_BLOB 136
|
||||
#define TK_VARBINARY 137
|
||||
#define TK_GEOMETRY 138
|
||||
#define TK_DECIMAL 139
|
||||
#define TK_COMMENT 140
|
||||
#define TK_MAX_DELAY 141
|
||||
#define TK_WATERMARK 142
|
||||
#define TK_ROLLUP 143
|
||||
#define TK_TTL 144
|
||||
#define TK_SMA 145
|
||||
#define TK_DELETE_MARK 146
|
||||
#define TK_FIRST 147
|
||||
#define TK_LAST 148
|
||||
#define TK_SHOW 149
|
||||
#define TK_PRIVILEGES 150
|
||||
#define TK_DATABASES 151
|
||||
#define TK_TABLES 152
|
||||
#define TK_STABLES 153
|
||||
#define TK_MNODES 154
|
||||
#define TK_QNODES 155
|
||||
#define TK_ARBGROUPS 156
|
||||
#define TK_FUNCTIONS 157
|
||||
#define TK_INDEXES 158
|
||||
#define TK_ACCOUNTS 159
|
||||
#define TK_APPS 160
|
||||
#define TK_CONNECTIONS 161
|
||||
#define TK_LICENCES 162
|
||||
#define TK_GRANTS 163
|
||||
#define TK_FULL 164
|
||||
#define TK_LOGS 165
|
||||
#define TK_MACHINES 166
|
||||
#define TK_ENCRYPTIONS 167
|
||||
#define TK_QUERIES 168
|
||||
#define TK_SCORES 169
|
||||
#define TK_TOPICS 170
|
||||
#define TK_VARIABLES 171
|
||||
#define TK_BNODES 172
|
||||
#define TK_SNODES 173
|
||||
#define TK_TRANSACTIONS 174
|
||||
#define TK_DISTRIBUTED 175
|
||||
#define TK_CONSUMERS 176
|
||||
#define TK_SUBSCRIPTIONS 177
|
||||
#define TK_VNODES 178
|
||||
#define TK_ALIVE 179
|
||||
#define TK_VIEWS 180
|
||||
#define TK_VIEW 181
|
||||
#define TK_COMPACTS 182
|
||||
#define TK_NORMAL 183
|
||||
#define TK_CHILD 184
|
||||
#define TK_LIKE 185
|
||||
#define TK_TBNAME 186
|
||||
#define TK_QTAGS 187
|
||||
#define TK_AS 188
|
||||
#define TK_SYSTEM 189
|
||||
#define TK_INDEX 190
|
||||
#define TK_FUNCTION 191
|
||||
#define TK_INTERVAL 192
|
||||
#define TK_COUNT 193
|
||||
#define TK_LAST_ROW 194
|
||||
#define TK_META 195
|
||||
#define TK_ONLY 196
|
||||
#define TK_TOPIC 197
|
||||
#define TK_CONSUMER 198
|
||||
#define TK_GROUP 199
|
||||
#define TK_DESC 200
|
||||
#define TK_DESCRIBE 201
|
||||
#define TK_RESET 202
|
||||
#define TK_QUERY 203
|
||||
#define TK_CACHE 204
|
||||
#define TK_EXPLAIN 205
|
||||
#define TK_ANALYZE 206
|
||||
#define TK_VERBOSE 207
|
||||
#define TK_NK_BOOL 208
|
||||
#define TK_RATIO 209
|
||||
#define TK_NK_FLOAT 210
|
||||
#define TK_OUTPUTTYPE 211
|
||||
#define TK_AGGREGATE 212
|
||||
#define TK_BUFSIZE 213
|
||||
#define TK_LANGUAGE 214
|
||||
#define TK_REPLACE 215
|
||||
#define TK_STREAM 216
|
||||
#define TK_INTO 217
|
||||
#define TK_PAUSE 218
|
||||
#define TK_RESUME 219
|
||||
#define TK_TRIGGER 220
|
||||
#define TK_AT_ONCE 221
|
||||
#define TK_WINDOW_CLOSE 222
|
||||
#define TK_IGNORE 223
|
||||
#define TK_EXPIRED 224
|
||||
#define TK_FILL_HISTORY 225
|
||||
#define TK_UPDATE 226
|
||||
#define TK_SUBTABLE 227
|
||||
#define TK_UNTREATED 228
|
||||
#define TK_KILL 229
|
||||
#define TK_CONNECTION 230
|
||||
#define TK_TRANSACTION 231
|
||||
#define TK_BALANCE 232
|
||||
#define TK_VGROUP 233
|
||||
#define TK_LEADER 234
|
||||
#define TK_MERGE 235
|
||||
#define TK_REDISTRIBUTE 236
|
||||
#define TK_SPLIT 237
|
||||
#define TK_DELETE 238
|
||||
#define TK_INSERT 239
|
||||
#define TK_NK_BIN 240
|
||||
#define TK_NK_HEX 241
|
||||
#define TK_NULL 242
|
||||
#define TK_NK_QUESTION 243
|
||||
#define TK_NK_ALIAS 244
|
||||
#define TK_NK_ARROW 245
|
||||
#define TK_ROWTS 246
|
||||
#define TK_QSTART 247
|
||||
#define TK_QEND 248
|
||||
#define TK_QDURATION 249
|
||||
#define TK_WSTART 250
|
||||
#define TK_WEND 251
|
||||
#define TK_WDURATION 252
|
||||
#define TK_IROWTS 253
|
||||
#define TK_ISFILLED 254
|
||||
#define TK_CAST 255
|
||||
#define TK_NOW 256
|
||||
#define TK_TODAY 257
|
||||
#define TK_TIMEZONE 258
|
||||
#define TK_CLIENT_VERSION 259
|
||||
#define TK_SERVER_VERSION 260
|
||||
#define TK_SERVER_STATUS 261
|
||||
#define TK_CURRENT_USER 262
|
||||
#define TK_CASE 263
|
||||
#define TK_WHEN 264
|
||||
#define TK_THEN 265
|
||||
#define TK_ELSE 266
|
||||
#define TK_BETWEEN 267
|
||||
#define TK_IS 268
|
||||
#define TK_NK_LT 269
|
||||
#define TK_NK_GT 270
|
||||
#define TK_NK_LE 271
|
||||
#define TK_NK_GE 272
|
||||
#define TK_NK_NE 273
|
||||
#define TK_MATCH 274
|
||||
#define TK_NMATCH 275
|
||||
#define TK_CONTAINS 276
|
||||
#define TK_IN 277
|
||||
#define TK_JOIN 278
|
||||
#define TK_INNER 279
|
||||
#define TK_SELECT 280
|
||||
#define TK_NK_HINT 281
|
||||
#define TK_DISTINCT 282
|
||||
#define TK_WHERE 283
|
||||
#define TK_PARTITION 284
|
||||
#define TK_BY 285
|
||||
#define TK_SESSION 286
|
||||
#define TK_STATE_WINDOW 287
|
||||
#define TK_EVENT_WINDOW 288
|
||||
#define TK_COUNT_WINDOW 289
|
||||
#define TK_SLIDING 290
|
||||
#define TK_FILL 291
|
||||
#define TK_VALUE 292
|
||||
#define TK_VALUE_F 293
|
||||
#define TK_NONE 294
|
||||
#define TK_PREV 295
|
||||
#define TK_NULL_F 296
|
||||
#define TK_LINEAR 297
|
||||
#define TK_NEXT 298
|
||||
#define TK_HAVING 299
|
||||
#define TK_RANGE 300
|
||||
#define TK_EVERY 301
|
||||
#define TK_ORDER 302
|
||||
#define TK_SLIMIT 303
|
||||
#define TK_SOFFSET 304
|
||||
#define TK_LIMIT 305
|
||||
#define TK_OFFSET 306
|
||||
#define TK_ASC 307
|
||||
#define TK_NULLS 308
|
||||
#define TK_ABORT 309
|
||||
#define TK_AFTER 310
|
||||
#define TK_ATTACH 311
|
||||
#define TK_BEFORE 312
|
||||
#define TK_BEGIN 313
|
||||
#define TK_BITAND 314
|
||||
#define TK_BITNOT 315
|
||||
#define TK_BITOR 316
|
||||
#define TK_BLOCKS 317
|
||||
#define TK_CHANGE 318
|
||||
#define TK_COMMA 319
|
||||
#define TK_CONCAT 320
|
||||
#define TK_CONFLICT 321
|
||||
#define TK_COPY 322
|
||||
#define TK_DEFERRED 323
|
||||
#define TK_DELIMITERS 324
|
||||
#define TK_DETACH 325
|
||||
#define TK_DIVIDE 326
|
||||
#define TK_DOT 327
|
||||
#define TK_EACH 328
|
||||
#define TK_FAIL 329
|
||||
#define TK_FILE 330
|
||||
#define TK_FOR 331
|
||||
#define TK_GLOB 332
|
||||
#define TK_ID 333
|
||||
#define TK_IMMEDIATE 334
|
||||
#define TK_IMPORT 335
|
||||
#define TK_INITIALLY 336
|
||||
#define TK_INSTEAD 337
|
||||
#define TK_ISNULL 338
|
||||
#define TK_MODULES 339
|
||||
#define TK_NK_BITNOT 340
|
||||
#define TK_NK_SEMI 341
|
||||
#define TK_NOTNULL 342
|
||||
#define TK_OF 343
|
||||
#define TK_PLUS 344
|
||||
#define TK_PRIVILEGE 345
|
||||
#define TK_RAISE 346
|
||||
#define TK_RESTRICT 347
|
||||
#define TK_ROW 348
|
||||
#define TK_SEMI 349
|
||||
#define TK_STAR 350
|
||||
#define TK_STATEMENT 351
|
||||
#define TK_STRICT 352
|
||||
#define TK_STRING 353
|
||||
#define TK_TIMES 354
|
||||
#define TK_VALUES 355
|
||||
#define TK_VARIABLE 356
|
||||
#define TK_WAL 357
|
||||
|
||||
#define TK_NK_SPACE 600
|
||||
#define TK_NK_COMMENT 601
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ typedef struct SMetaTableInfo {
|
|||
} SMetaTableInfo;
|
||||
|
||||
typedef struct SSnapContext {
|
||||
SMeta* pMeta; // todo remove it
|
||||
SMeta* pMeta;
|
||||
int64_t snapVersion;
|
||||
void* pCur;
|
||||
int64_t suid;
|
||||
|
|
@ -143,6 +143,7 @@ typedef struct SSnapContext {
|
|||
int32_t index;
|
||||
int8_t withMeta;
|
||||
int8_t queryMeta; // true-get meta, false-get data
|
||||
bool hasPrimaryKey;
|
||||
} SSnapContext;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -191,7 +192,7 @@ typedef struct TsdReader {
|
|||
typedef struct SStoreCacheReader {
|
||||
int32_t (*openReader)(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr,
|
||||
SArray *pFuncTypeList);
|
||||
SArray *pFuncTypeList, SColumnInfo* pPkCol, int32_t numOfPks);
|
||||
void *(*closeReader)(void *pReader);
|
||||
int32_t (*retrieveRows)(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds,
|
||||
SArray *pTableUidList);
|
||||
|
|
@ -220,6 +221,8 @@ typedef struct SStoreTqReader {
|
|||
int32_t (*tqReaderAddTables)();
|
||||
int32_t (*tqReaderRemoveTables)();
|
||||
|
||||
void (*tqSetTablePrimaryKey)();
|
||||
bool (*tqGetTablePrimaryKey)();
|
||||
bool (*tqReaderIsQueriedTable)();
|
||||
bool (*tqReaderCurrentBlockConsumed)();
|
||||
|
||||
|
|
@ -231,6 +234,8 @@ typedef struct SStoreTqReader {
|
|||
} SStoreTqReader;
|
||||
|
||||
typedef struct SStoreSnapshotFn {
|
||||
bool (*taosXGetTablePrimaryKey)(SSnapContext *ctx);
|
||||
void (*taosXSetTablePrimaryKey)(SSnapContext *ctx, int64_t uid);
|
||||
int32_t (*setForSnapShot)(SSnapContext* ctx, int64_t uid);
|
||||
int32_t (*destroySnapshot)(SSnapContext* ctx);
|
||||
SMetaTableInfo (*getMetaTableInfoFromSnapshot)(SSnapContext* ctx);
|
||||
|
|
@ -328,7 +333,7 @@ typedef struct SStateStore {
|
|||
int32_t (*streamStateGetByPos)(SStreamState* pState, void* pos, void** pVal);
|
||||
int32_t (*streamStateDel)(SStreamState* pState, const SWinKey* key);
|
||||
int32_t (*streamStateClear)(SStreamState* pState);
|
||||
void (*streamStateSetNumber)(SStreamState* pState, int32_t number);
|
||||
void (*streamStateSetNumber)(SStreamState* pState, int32_t number, int32_t tsIdex);
|
||||
int32_t (*streamStateSaveInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void* pVal, int32_t vLen);
|
||||
int32_t (*streamStateGetInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void** pVal, int32_t* pLen);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ struct SResultRowEntryInfo;
|
|||
|
||||
struct SFunctionNode;
|
||||
typedef struct SScalarParam SScalarParam;
|
||||
typedef struct SStreamState SStreamState;
|
||||
|
||||
typedef struct SFuncExecEnv {
|
||||
int32_t calcMemSize;
|
||||
|
|
@ -118,6 +119,7 @@ typedef struct SInputColumnInfoData {
|
|||
int32_t numOfInputCols; // PTS is not included
|
||||
bool colDataSMAIsSet; // if agg is set or not
|
||||
SColumnInfoData *pPTS; // primary timestamp column
|
||||
SColumnInfoData *pPrimaryKey; // primary key column
|
||||
SColumnInfoData **pData;
|
||||
SColumnDataAgg **pColumnDataAgg;
|
||||
uint64_t uid; // table uid, used to set the tag value when building the final query result for selectivity functions.
|
||||
|
|
@ -126,7 +128,7 @@ typedef struct SInputColumnInfoData {
|
|||
typedef struct SSerializeDataHandle {
|
||||
struct SDiskbasedBuf *pBuf;
|
||||
int32_t currentPage;
|
||||
void *pState;
|
||||
SStreamState *pState;
|
||||
} SSerializeDataHandle;
|
||||
|
||||
// incremental state storage
|
||||
|
|
@ -164,7 +166,7 @@ typedef struct STdbState {
|
|||
void *txn;
|
||||
} STdbState;
|
||||
|
||||
typedef struct {
|
||||
struct SStreamState {
|
||||
STdbState *pTdbState;
|
||||
struct SStreamFileState *pFileState;
|
||||
int32_t number;
|
||||
|
|
@ -173,13 +175,51 @@ typedef struct {
|
|||
int64_t streamId;
|
||||
int64_t streamBackendRid;
|
||||
int8_t dump;
|
||||
} SStreamState;
|
||||
int32_t tsIndex;
|
||||
};
|
||||
|
||||
typedef struct SFunctionStateStore {
|
||||
int32_t (*streamStateFuncPut)(SStreamState *pState, const SWinKey *key, const void *value, int32_t vLen);
|
||||
int32_t (*streamStateFuncGet)(SStreamState *pState, const SWinKey *key, void **ppVal, int32_t *pVLen);
|
||||
} SFunctionStateStore;
|
||||
|
||||
typedef struct SFuncInputRow {
|
||||
TSKEY ts;
|
||||
bool isDataNull;
|
||||
char* pData;
|
||||
char* pPk;
|
||||
|
||||
SSDataBlock* block; // prev row block or src block
|
||||
int32_t rowIndex; // prev row block ? 0 : rowIndex in srcBlock
|
||||
|
||||
//TODO:
|
||||
// int32_t startOffset; // for diff, derivative
|
||||
// SPoint1 startPoint; // for twa
|
||||
} SFuncInputRow;
|
||||
|
||||
typedef struct SFuncInputRowIter {
|
||||
bool hasPrev;
|
||||
|
||||
SInputColumnInfoData* pInput;
|
||||
SColumnInfoData* pDataCol;
|
||||
SColumnInfoData* pPkCol;
|
||||
TSKEY* tsList;
|
||||
int32_t rowIndex;
|
||||
int32_t inputEndIndex;
|
||||
SSDataBlock* pSrcBlock;
|
||||
|
||||
TSKEY prevBlockTsEnd;
|
||||
bool prevIsDataNull;
|
||||
char* pPrevData;
|
||||
char* pPrevPk;
|
||||
SSDataBlock* pPrevRowBlock; // pre one row block
|
||||
|
||||
uint64_t groupId;
|
||||
bool hasGroupId;
|
||||
|
||||
bool finalRow;
|
||||
} SFuncInputRowIter;
|
||||
|
||||
// sql function runtime context
|
||||
typedef struct SqlFunctionCtx {
|
||||
SInputColumnInfoData input;
|
||||
|
|
@ -209,6 +249,9 @@ typedef struct SqlFunctionCtx {
|
|||
int32_t exprIdx;
|
||||
char *udfName;
|
||||
SFunctionStateStore *pStore;
|
||||
bool hasPrimaryKey;
|
||||
SFuncInputRowIter rowIter;
|
||||
bool bInputFinished;
|
||||
} SqlFunctionCtx;
|
||||
|
||||
typedef struct tExprNode {
|
||||
|
|
|
|||
|
|
@ -240,8 +240,9 @@ bool fmIsGroupKeyFunc(int32_t funcId);
|
|||
bool fmIsBlockDistFunc(int32_t funcId);
|
||||
bool fmIsConstantResFunc(SFunctionNode* pFunc);
|
||||
bool fmIsSkipScanCheckFunc(int32_t funcId);
|
||||
bool fmIsPrimaryKeyFunc(int32_t funcId);
|
||||
|
||||
void getLastCacheDataType(SDataType* pType);
|
||||
void getLastCacheDataType(SDataType* pType, int32_t pkBytes);
|
||||
SFunctionNode* createFunction(const char* pName, SNodeList* pParameterList);
|
||||
|
||||
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMidFunc, SFunctionNode** pMergeFunc);
|
||||
|
|
@ -255,7 +256,7 @@ typedef enum EFuncDataRequired {
|
|||
} EFuncDataRequired;
|
||||
|
||||
EFuncDataRequired fmFuncDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
|
||||
EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, STimeWindow* pTimeWindow);
|
||||
EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, SDataBlockInfo* pBlockInfo);
|
||||
|
||||
int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet);
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ typedef struct SColumnDefNode {
|
|||
SDataType dataType;
|
||||
char comments[TSDB_TB_COMMENT_LEN];
|
||||
bool sma;
|
||||
bool is_pk;
|
||||
} SColumnDefNode;
|
||||
|
||||
typedef struct SCreateTableStmt {
|
||||
|
|
|
|||
|
|
@ -578,6 +578,7 @@ typedef struct SWindowPhysiNode {
|
|||
int64_t watermark;
|
||||
int64_t deleteMark;
|
||||
int8_t igExpired;
|
||||
int8_t destHasPrimayKey;
|
||||
bool mergeDataBlock;
|
||||
} SWindowPhysiNode;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ typedef struct SColumnNode {
|
|||
char colName[TSDB_COL_NAME_LEN];
|
||||
int16_t dataBlockId;
|
||||
int16_t slotId;
|
||||
int16_t numOfPKs;
|
||||
bool tableHasPk;
|
||||
bool isPk;
|
||||
} SColumnNode;
|
||||
|
||||
typedef struct SColumnRefNode {
|
||||
|
|
@ -163,6 +166,8 @@ typedef struct SFunctionNode {
|
|||
int32_t funcType;
|
||||
SNodeList* pParameterList;
|
||||
int32_t udfBufSize;
|
||||
bool hasPk;
|
||||
int32_t pkBytes;
|
||||
} SFunctionNode;
|
||||
|
||||
typedef struct STableNode {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ typedef struct SPlanContext {
|
|||
const char* pUser;
|
||||
bool sysInfo;
|
||||
int64_t allocatorId;
|
||||
bool destHasPrimaryKey;
|
||||
bool sourceHasPrimaryKey;
|
||||
} SPlanContext;
|
||||
|
||||
// Create the physical plan for the query, according to the AST.
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ typedef struct STableComInfo {
|
|||
uint8_t numOfTags; // the number of tags in schema
|
||||
uint8_t precision; // the number of precision
|
||||
col_id_t numOfColumns; // the number of columns
|
||||
int16_t numOfPKs;
|
||||
int32_t rowSize; // row size of the schema
|
||||
} STableComInfo;
|
||||
|
||||
|
|
@ -197,7 +198,7 @@ typedef struct STableDataCxt {
|
|||
SBoundColInfo boundColsInfo;
|
||||
SArray* pValues;
|
||||
SSubmitTbData* pData;
|
||||
TSKEY lastTs;
|
||||
SRowKey lastKey;
|
||||
bool ordered;
|
||||
bool duplicateTs;
|
||||
} STableDataCxt;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ bool streamStateCheck(SStreamState* pState, const SWinKey* key);
|
|||
int32_t streamStateGetByPos(SStreamState* pState, void* pos, void** pVal);
|
||||
int32_t streamStateDel(SStreamState* pState, const SWinKey* key);
|
||||
int32_t streamStateClear(SStreamState* pState);
|
||||
void streamStateSetNumber(SStreamState* pState, int32_t number);
|
||||
void streamStateSetNumber(SStreamState* pState, int32_t number, int32_t tsIdex);
|
||||
int32_t streamStateSaveInfo(SStreamState* pState, void* pKey, int32_t keyLen, void* pVal, int32_t vLen);
|
||||
int32_t streamStateGetInfo(SStreamState* pState, void* pKey, int32_t keyLen, void** pVal, int32_t* pLen);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ typedef struct SStreamFileState SStreamFileState;
|
|||
typedef SList SStreamSnapshot;
|
||||
|
||||
typedef void* (*_state_buff_get_fn)(void* pRowBuff, const void* pKey, size_t keyLen);
|
||||
typedef int32_t (*_state_buff_put_fn)(void* pRowBuff, const void* pKey, size_t keyLen, const void* data, size_t dataLen);
|
||||
typedef int32_t (*_state_buff_remove_fn)(void* pRowBuff, const void* pKey, size_t keyLen);
|
||||
typedef int32_t (*_state_buff_remove_by_pos_fn)(SStreamFileState* pState, SRowBuffPos* pPos);
|
||||
typedef void (*_state_buff_cleanup_fn)(void* pRowBuff);
|
||||
|
|
@ -41,6 +40,8 @@ typedef int32_t (*_state_file_remove_fn)(SStreamFileState* pFileState, const voi
|
|||
typedef int32_t (*_state_file_get_fn)(SStreamFileState* pFileState, void* pKey, void* data, int32_t* pDataLen);
|
||||
typedef int32_t (*_state_file_clear_fn)(SStreamState* pState);
|
||||
|
||||
typedef int32_t (*_state_fun_get_fn) (SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen);
|
||||
|
||||
typedef int32_t (*range_cmpr_fn)(const SSessionKey* pWin1, const SSessionKey* pWin2);
|
||||
|
||||
SStreamFileState* streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_t rowSize, uint32_t selectRowSize,
|
||||
|
|
@ -64,7 +65,7 @@ int32_t recoverSnapshot(SStreamFileState* pFileState, int64_t ckId);
|
|||
|
||||
int32_t getSnapshotIdList(SStreamFileState* pFileState, SArray* list);
|
||||
int32_t deleteExpiredCheckPoint(SStreamFileState* pFileState, TSKEY mark);
|
||||
int32_t streamFileStateGeSelectRowSize(SStreamFileState* pFileState);
|
||||
int32_t streamFileStateGetSelectRowSize(SStreamFileState* pFileState);
|
||||
void streamFileStateReloadInfo(SStreamFileState* pFileState, TSKEY ts);
|
||||
|
||||
void* getRowStateBuff(SStreamFileState* pFileState);
|
||||
|
|
@ -105,6 +106,10 @@ int32_t getStateWinResultBuff(SStreamFileState* pFileState, SSessionKey* key, ch
|
|||
int32_t getCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, COUNT_TYPE winCount, void** pVal, int32_t* pVLen);
|
||||
int32_t createCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
//function
|
||||
int32_t getSessionRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen);
|
||||
int32_t getFunctionRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -771,6 +771,12 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_VIEW_CONFLICT_WITH_TABLE TAOS_DEF_ERROR_CODE(0, 0x266E)
|
||||
#define TSDB_CODE_PAR_ORDERBY_AMBIGUOUS TAOS_DEF_ERROR_CODE(0, 0x266F)
|
||||
#define TSDB_CODE_PAR_NOT_SUPPORT_MULTI_RESULT TAOS_DEF_ERROR_CODE(0, 0x2670)
|
||||
#define TSDB_CODE_PAR_TAG_IS_PRIMARY_KEY TAOS_DEF_ERROR_CODE(0, 0x2671)
|
||||
#define TSDB_CODE_PAR_SECOND_COL_PK TAOS_DEF_ERROR_CODE(0, 0x2672)
|
||||
#define TSDB_CODE_PAR_COL_PK_TYPE TAOS_DEF_ERROR_CODE(0, 0x2673)
|
||||
#define TSDB_CODE_PAR_INVALID_PK_OP TAOS_DEF_ERROR_CODE(0, 0x2674)
|
||||
#define TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL TAOS_DEF_ERROR_CODE(0, 0x2675)
|
||||
#define TSDB_CODE_PAR_PRIMARY_KEY_IS_NONE TAOS_DEF_ERROR_CODE(0, 0x2676)
|
||||
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
|
||||
|
||||
//planner
|
||||
|
|
@ -810,6 +816,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_SML_INVALID_DB_CONF TAOS_DEF_ERROR_CODE(0, 0x3003)
|
||||
#define TSDB_CODE_SML_NOT_SAME_TYPE TAOS_DEF_ERROR_CODE(0, 0x3004)
|
||||
#define TSDB_CODE_SML_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x3005)
|
||||
#define TSDB_CODE_SML_NOT_SUPPORT_PK TAOS_DEF_ERROR_CODE(0, 0x3006)
|
||||
|
||||
//tsma
|
||||
#define TSDB_CODE_TSMA_INIT_FAILED TAOS_DEF_ERROR_CODE(0, 0x3100)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifndef __TD_BUFFER_H__
|
||||
#define __TD_BUFFER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SBuffer SBuffer;
|
||||
typedef struct SBufferReader SBufferReader;
|
||||
|
||||
// SBuffer
|
||||
#define BUFFER_INITIALIZER ((SBuffer){0, 0, NULL})
|
||||
static int32_t tBufferInit(SBuffer *buffer);
|
||||
static int32_t tBufferDestroy(SBuffer *buffer);
|
||||
static int32_t tBufferClear(SBuffer *buffer);
|
||||
static int32_t tBufferEnsureCapacity(SBuffer *buffer, uint32_t capacity);
|
||||
static int32_t tBufferPut(SBuffer *buffer, const void *data, uint32_t size);
|
||||
static int32_t tBufferPutAt(SBuffer *buffer, uint32_t offset, const void *data, uint32_t size);
|
||||
static int32_t tBufferPutI8(SBuffer *buffer, int8_t value);
|
||||
static int32_t tBufferPutI16(SBuffer *buffer, int16_t value);
|
||||
static int32_t tBufferPutI32(SBuffer *buffer, int32_t value);
|
||||
static int32_t tBufferPutI64(SBuffer *buffer, int64_t value);
|
||||
static int32_t tBufferPutU8(SBuffer *buffer, uint8_t value);
|
||||
static int32_t tBufferPutU16(SBuffer *buffer, uint16_t value);
|
||||
static int32_t tBufferPutU32(SBuffer *buffer, uint32_t value);
|
||||
static int32_t tBufferPutU64(SBuffer *buffer, uint64_t value);
|
||||
static int32_t tBufferPutI16v(SBuffer *buffer, int16_t value);
|
||||
static int32_t tBufferPutI32v(SBuffer *buffer, int32_t value);
|
||||
static int32_t tBufferPutI64v(SBuffer *buffer, int64_t value);
|
||||
static int32_t tBufferPutU16v(SBuffer *buffer, uint16_t value);
|
||||
static int32_t tBufferPutU32v(SBuffer *buffer, uint32_t value);
|
||||
static int32_t tBufferPutU64v(SBuffer *buffer, uint64_t value);
|
||||
static int32_t tBufferPutBinary(SBuffer *buffer, const void *data, uint32_t size);
|
||||
static int32_t tBufferPutCStr(SBuffer *buffer, const char *str);
|
||||
static int32_t tBufferPutF32(SBuffer *buffer, float value);
|
||||
static int32_t tBufferPutF64(SBuffer *buffer, double value);
|
||||
|
||||
#define tBufferGetSize(buffer) ((buffer)->size)
|
||||
#define tBufferGetCapacity(buffer) ((buffer)->capacity)
|
||||
#define tBufferGetData(buffer) ((buffer)->data)
|
||||
#define tBufferGetDataAt(buffer, offset) ((char *)(buffer)->data + (offset))
|
||||
#define tBufferGetDataEnd(buffer) ((char *)(buffer)->data + (buffer)->size)
|
||||
|
||||
// SBufferReader
|
||||
#define BUFFER_READER_INITIALIZER(offset, buffer) ((SBufferReader){offset, buffer})
|
||||
#define BR_PTR(br) tBufferGetDataAt((br)->buffer, (br)->offset)
|
||||
#define tBufferReaderDestroy(reader) ((void)0)
|
||||
#define tBufferReaderGetOffset(reader) ((reader)->offset)
|
||||
static int32_t tBufferGet(SBufferReader *reader, uint32_t size, void *data);
|
||||
static int32_t tBufferReaderInit(SBufferReader *reader, uint32_t offset, SBuffer *buffer);
|
||||
static int32_t tBufferGetI8(SBufferReader *reader, int8_t *value);
|
||||
static int32_t tBufferGetI16(SBufferReader *reader, int16_t *value);
|
||||
static int32_t tBufferGetI32(SBufferReader *reader, int32_t *value);
|
||||
static int32_t tBufferGetI64(SBufferReader *reader, int64_t *value);
|
||||
static int32_t tBufferGetU8(SBufferReader *reader, uint8_t *value);
|
||||
static int32_t tBufferGetU16(SBufferReader *reader, uint16_t *value);
|
||||
static int32_t tBufferGetU32(SBufferReader *reader, uint32_t *value);
|
||||
static int32_t tBufferGetU64(SBufferReader *reader, uint64_t *value);
|
||||
static int32_t tBufferGetI16v(SBufferReader *reader, int16_t *value);
|
||||
static int32_t tBufferGetI32v(SBufferReader *reader, int32_t *value);
|
||||
static int32_t tBufferGetI64v(SBufferReader *reader, int64_t *value);
|
||||
static int32_t tBufferGetU16v(SBufferReader *reader, uint16_t *value);
|
||||
static int32_t tBufferGetU32v(SBufferReader *reader, uint32_t *value);
|
||||
static int32_t tBufferGetU64v(SBufferReader *reader, uint64_t *value);
|
||||
static int32_t tBufferGetBinary(SBufferReader *reader, const void **data, uint32_t *size);
|
||||
static int32_t tBufferGetCStr(SBufferReader *reader, const char **str);
|
||||
static int32_t tBufferGetF32(SBufferReader *reader, float *value);
|
||||
static int32_t tBufferGetF64(SBufferReader *reader, double *value);
|
||||
|
||||
#include "tbuffer.inc"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__TD_BUFFER_H__*/
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "taoserror.h"
|
||||
#include "tcoding.h"
|
||||
|
||||
struct SBuffer {
|
||||
uint32_t size;
|
||||
uint32_t capacity;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct SBufferReader {
|
||||
uint32_t offset;
|
||||
SBuffer *buffer;
|
||||
};
|
||||
|
||||
// SBuffer
|
||||
static FORCE_INLINE int32_t tBufferInit(SBuffer *buffer) {
|
||||
buffer->size = 0;
|
||||
buffer->capacity = 0;
|
||||
buffer->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferDestroy(SBuffer *buffer) {
|
||||
buffer->size = 0;
|
||||
buffer->capacity = 0;
|
||||
if (buffer->data) {
|
||||
taosMemoryFree(buffer->data);
|
||||
buffer->data = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferClear(SBuffer *buffer) {
|
||||
buffer->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferEnsureCapacity(SBuffer *buffer, uint32_t capacity) {
|
||||
if (buffer->capacity < capacity) {
|
||||
uint32_t newCapacity = (buffer->capacity > 0) ? (buffer->capacity << 1) : 1024;
|
||||
while (newCapacity < capacity) {
|
||||
newCapacity <<= 1;
|
||||
}
|
||||
void *newData = taosMemoryRealloc(buffer->data, newCapacity);
|
||||
if (newData == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
buffer->data = newData;
|
||||
buffer->capacity = newCapacity;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPut(SBuffer *buffer, const void *data, uint32_t size) {
|
||||
int32_t code = tBufferEnsureCapacity(buffer, buffer->size + size);
|
||||
if (code) return code;
|
||||
memcpy((char *)buffer->data + buffer->size, data, size);
|
||||
buffer->size += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferPutAt(SBuffer *buffer, uint32_t offset, const void *data, uint32_t size) {
|
||||
if (offset + size > buffer->size) {
|
||||
return TSDB_CODE_OUT_OF_RANGE;
|
||||
}
|
||||
memcpy((char *)buffer->data + offset, data, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI8(SBuffer *buffer, int8_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI16(SBuffer *buffer, int16_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI32(SBuffer *buffer, int32_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI64(SBuffer *buffer, int64_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU8(SBuffer *buffer, uint8_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU16(SBuffer *buffer, uint16_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU32(SBuffer *buffer, uint32_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU64(SBuffer *buffer, uint64_t value) {
|
||||
return tBufferPut(buffer, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU16v(SBuffer *buffer, uint16_t value) { return tBufferPutU64v(buffer, value); }
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU32v(SBuffer *buffer, uint32_t value) { return tBufferPutU64v(buffer, value); }
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutU64v(SBuffer *buffer, uint64_t value) {
|
||||
int32_t code;
|
||||
while (value >= 0x80) {
|
||||
code = tBufferPutU8(buffer, (value & 0x7F) | 0x80);
|
||||
if (code) return code;
|
||||
value >>= 7;
|
||||
}
|
||||
return tBufferPutU8(buffer, value);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI16v(SBuffer *buffer, int16_t value) {
|
||||
return tBufferPutU64v(buffer, ZIGZAGE(int16_t, value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI32v(SBuffer *buffer, int32_t value) {
|
||||
return tBufferPutU64v(buffer, ZIGZAGE(int32_t, value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutI64v(SBuffer *buffer, int64_t value) {
|
||||
return tBufferPutU64v(buffer, ZIGZAGE(int64_t, value));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutBinary(SBuffer *buffer, const void *data, uint32_t size) {
|
||||
int32_t code = tBufferPutU32v(buffer, size);
|
||||
if (code) return code;
|
||||
return tBufferPut(buffer, data, size);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutCStr(SBuffer *buffer, const char *str) {
|
||||
return tBufferPutBinary(buffer, str, str ? strlen(str) + 1 : 0);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutF32(SBuffer *buffer, float value) {
|
||||
union {
|
||||
float f;
|
||||
uint32_t u;
|
||||
} u;
|
||||
u.f = value;
|
||||
return tBufferPutU32(buffer, u.u);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferPutF64(SBuffer *buffer, double value) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} u;
|
||||
u.f = value;
|
||||
return tBufferPutU64(buffer, u.u);
|
||||
}
|
||||
|
||||
// reader
|
||||
// SBufferReader
|
||||
static int32_t tBufferReaderInit(SBufferReader *reader, uint32_t offset, SBuffer *buffer) {
|
||||
reader->offset = offset;
|
||||
reader->buffer = buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tBufferGet(SBufferReader *reader, uint32_t size, void *data) {
|
||||
if (reader->offset < 0 || reader->offset + size > reader->buffer->size) {
|
||||
return TSDB_CODE_OUT_OF_RANGE;
|
||||
}
|
||||
if (data) {
|
||||
memcpy(data, BR_PTR(reader), size);
|
||||
}
|
||||
reader->offset += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetI8(SBufferReader *reader, int8_t *value) { return tBufferGet(reader, sizeof(*value), value); }
|
||||
|
||||
static int32_t tBufferGetI16(SBufferReader *reader, int16_t *value) {
|
||||
return tBufferGet(reader, sizeof(*value), value);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetI32(SBufferReader *reader, int32_t *value) {
|
||||
return tBufferGet(reader, sizeof(*value), value);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetI64(SBufferReader *reader, int64_t *value) {
|
||||
return tBufferGet(reader, sizeof(*value), value);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetU8(SBufferReader *reader, uint8_t *value) { return tBufferGet(reader, sizeof(*value), value); }
|
||||
|
||||
static int32_t tBufferGetU16(SBufferReader *reader, uint16_t *value) {
|
||||
return tBufferGet(reader, sizeof(*value), value);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetU32(SBufferReader *reader, uint32_t *value) {
|
||||
return tBufferGet(reader, sizeof(*value), value);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetU64(SBufferReader *reader, uint64_t *value) {
|
||||
return tBufferGet(reader, sizeof(*value), value);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetU64v(SBufferReader *reader, uint64_t *value) {
|
||||
uint8_t byte;
|
||||
int32_t code;
|
||||
uint64_t u64 = 0;
|
||||
|
||||
for (int32_t i = 0;; i++) {
|
||||
code = tBufferGetU8(reader, &byte);
|
||||
if (code) return code;
|
||||
|
||||
u64 |= (((uint64_t)(byte & 0x7F)) << (i * 7));
|
||||
|
||||
if (byte < 0x80) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (value) {
|
||||
*value = u64;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetU16v(SBufferReader *reader, uint16_t *value) {
|
||||
uint64_t u64;
|
||||
int32_t code = tBufferGetU64v(reader, &u64);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = (uint16_t)u64;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetU32v(SBufferReader *reader, uint32_t *value) {
|
||||
uint64_t u64;
|
||||
int32_t code = tBufferGetU64v(reader, &u64);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = (uint32_t)u64;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetI16v(SBufferReader *reader, int16_t *value) {
|
||||
uint16_t u16;
|
||||
int32_t code = tBufferGetU16v(reader, &u16);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = ZIGZAGD(int16_t, u16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetI32v(SBufferReader *reader, int32_t *value) {
|
||||
uint32_t u32;
|
||||
int32_t code = tBufferGetU32v(reader, &u32);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = ZIGZAGD(int32_t, u32);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetI64v(SBufferReader *reader, int64_t *value) {
|
||||
uint64_t u64;
|
||||
int32_t code = tBufferGetU64v(reader, &u64);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = ZIGZAGD(int64_t, u64);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetBinary(SBufferReader *reader, const void **data, uint32_t *size) {
|
||||
uint32_t tmpSize;
|
||||
int32_t code;
|
||||
|
||||
// size
|
||||
code = tBufferGetU32v(reader, &tmpSize);
|
||||
if (code) return code;
|
||||
if (size) {
|
||||
*size = tmpSize;
|
||||
}
|
||||
|
||||
// data
|
||||
if (tmpSize > 0) {
|
||||
if (reader->offset + tmpSize > reader->buffer->size) {
|
||||
return TSDB_CODE_OUT_OF_RANGE;
|
||||
}
|
||||
if (data) {
|
||||
*data = BR_PTR(reader);
|
||||
}
|
||||
reader->offset += tmpSize;
|
||||
} else if (data) {
|
||||
*data = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetCStr(SBufferReader *reader, const char **str) {
|
||||
return tBufferGetBinary(reader, (const void **)str, NULL);
|
||||
}
|
||||
|
||||
static int32_t tBufferGetF32(SBufferReader *reader, float *value) {
|
||||
union {
|
||||
float f;
|
||||
uint32_t u;
|
||||
} u;
|
||||
int32_t code = tBufferGetU32(reader, &u.u);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = u.f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tBufferGetF64(SBufferReader *reader, double *value) {
|
||||
union {
|
||||
double f;
|
||||
uint64_t u;
|
||||
} u;
|
||||
int32_t code = tBufferGetU64(reader, &u.u);
|
||||
if (code) return code;
|
||||
if (value) {
|
||||
*value = u.f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -432,6 +432,24 @@ static FORCE_INLINE int32_t tDecodeBinaryAlloc(SDecoder* pCoder, void** val, uin
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeBinaryAlloc32(SDecoder* pCoder, void** val, uint32_t* len) {
|
||||
uint32_t length = 0;
|
||||
if (tDecodeU32v(pCoder, &length) < 0) return -1;
|
||||
if (length) {
|
||||
if (len) *len = length;
|
||||
|
||||
if (TD_CODER_CHECK_CAPACITY_FAILED(pCoder, length)) return -1;
|
||||
*val = taosMemoryMalloc(length);
|
||||
if (*val == NULL) return -1;
|
||||
memcpy(*val, TD_CODER_CURRENT(pCoder), length);
|
||||
|
||||
TD_CODER_MOVE_POS(pCoder, length);
|
||||
} else {
|
||||
*val = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeCStrAndLenAlloc(SDecoder* pCoder, char** val, uint64_t* len) {
|
||||
if (tDecodeBinaryAlloc(pCoder, (void**)val, len) < 0) return -1;
|
||||
(*len) -= 1;
|
||||
|
|
|
|||
|
|
@ -342,27 +342,17 @@ void taos_free_result(TAOS_RES *res) {
|
|||
destroyRequest(pRequest);
|
||||
} else if (TD_RES_TMQ_METADATA(res)) {
|
||||
SMqTaosxRspObj *pRsp = (SMqTaosxRspObj *)res;
|
||||
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
|
||||
taosArrayDestroy(pRsp->rsp.blockDataLen);
|
||||
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
|
||||
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||
// taosx
|
||||
taosArrayDestroy(pRsp->rsp.createTableLen);
|
||||
taosArrayDestroyP(pRsp->rsp.createTableReq, taosMemoryFree);
|
||||
|
||||
tDeleteSTaosxRsp(&pRsp->rsp);
|
||||
doFreeReqResultInfo(&pRsp->resInfo);
|
||||
taosMemoryFree(pRsp);
|
||||
} else if (TD_RES_TMQ(res)) {
|
||||
SMqRspObj *pRsp = (SMqRspObj *)res;
|
||||
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
|
||||
taosArrayDestroy(pRsp->rsp.blockDataLen);
|
||||
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
|
||||
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||
tDeleteMqDataRsp(&pRsp->rsp);
|
||||
doFreeReqResultInfo(&pRsp->resInfo);
|
||||
taosMemoryFree(pRsp);
|
||||
} else if (TD_RES_TMQ_META(res)) {
|
||||
SMqMetaRspObj *pRspObj = (SMqMetaRspObj *)res;
|
||||
taosMemoryFree(pRspObj->metaRsp.metaRsp);
|
||||
tDeleteMqMetaRsp(&pRspObj->metaRsp);
|
||||
taosMemoryFree(pRspObj);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ static char* buildCreateTableJson(SSchemaWrapper* schemaRow, SSchemaWrapper* sch
|
|||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
cJSON_AddItemToObject(column, "length", cbytes);
|
||||
}
|
||||
cJSON* isPk = cJSON_CreateBool(s->flags & COL_IS_KEY);
|
||||
cJSON_AddItemToObject(column, "isPrimarykey", isPk);
|
||||
cJSON_AddItemToArray(columns, column);
|
||||
}
|
||||
cJSON_AddItemToObject(json, "columns", columns);
|
||||
|
|
@ -1625,7 +1627,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) {
|
|||
rspObj.resType = RES_TYPE__TMQ;
|
||||
|
||||
tDecoderInit(&decoder, data, dataLen);
|
||||
code = tDecodeMqDataRsp(&decoder, &rspObj.rsp);
|
||||
code = tDecodeMqDataRsp(&decoder, &rspObj.rsp, *(int8_t*)data);
|
||||
if (code != 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto end;
|
||||
|
|
@ -1754,7 +1756,7 @@ static int32_t tmqWriteRawMetaDataImpl(TAOS* taos, void* data, int32_t dataLen)
|
|||
rspObj.resType = RES_TYPE__TMQ_METADATA;
|
||||
|
||||
tDecoderInit(&decoder, data, dataLen);
|
||||
code = tDecodeSTaosxRsp(&decoder, &rspObj.rsp);
|
||||
code = tDecodeSTaosxRsp(&decoder, &rspObj.rsp, *(int8_t*)data);
|
||||
if (code != 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto end;
|
||||
|
|
|
|||
|
|
@ -310,6 +310,16 @@ int32_t smlJoinMeasureTag(SSmlLineInfo *elements){
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool smlIsPKTable(STableMeta *pTableMeta){
|
||||
for(int i = 0; i < pTableMeta->tableInfo.numOfColumns; i++){
|
||||
if(pTableMeta->schema[i].flags & COL_IS_KEY){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t smlProcessSuperTable(SSmlHandle *info, SSmlLineInfo *elements) {
|
||||
bool isSameMeasure = IS_SAME_SUPER_TABLE;
|
||||
if(isSameMeasure) {
|
||||
|
|
@ -328,6 +338,11 @@ int32_t smlProcessSuperTable(SSmlHandle *info, SSmlLineInfo *elements) {
|
|||
info->currSTableMeta = sMeta->tableMeta;
|
||||
info->maxTagKVs = sMeta->tags;
|
||||
info->maxColKVs = sMeta->cols;
|
||||
|
||||
if(smlIsPKTable(sMeta->tableMeta)){
|
||||
terrno = TSDB_CODE_SML_NOT_SUPPORT_PK;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1063,6 +1078,12 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
|
|||
goto end;
|
||||
}
|
||||
} else if (code == TSDB_CODE_SUCCESS) {
|
||||
|
||||
if(smlIsPKTable(pTableMeta)){
|
||||
code = TSDB_CODE_SML_NOT_SUPPORT_PK;
|
||||
goto end;
|
||||
}
|
||||
|
||||
hashTmp = taosHashInit(pTableMeta->tableInfo.numOfTags, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true,
|
||||
HASH_NO_LOCK);
|
||||
for (uint16_t i = pTableMeta->tableInfo.numOfColumns;
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ static int32_t asyncCommitOffset(tmq_t* tmq, char* pTopicName, int32_t vgId, STq
|
|||
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s on vgId:%d send commit msg success, send offset:%s committed:%s",
|
||||
tmq->consumerId, pTopicName, pVg->vgId, offsetBuf, commitBuf);
|
||||
pVg->offsetInfo.committedOffset = *offsetVal;
|
||||
tOffsetCopy(&pVg->offsetInfo.committedOffset, offsetVal);
|
||||
|
||||
end:
|
||||
taosRUnLockLatch(&tmq->lock);
|
||||
|
|
@ -691,7 +691,7 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us
|
|||
tscInfo("consumer:0x%" PRIx64
|
||||
" topic:%s on vgId:%d send commit msg success, send offset:%s committed:%s, ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, offsetBuf, commitBuf, j + 1, numOfVgroups);
|
||||
pVg->offsetInfo.committedOffset = pVg->offsetInfo.endOffset;
|
||||
tOffsetCopy(&pVg->offsetInfo.committedOffset, &pVg->offsetInfo.endOffset);
|
||||
} else {
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s vgId:%d, no commit, current:%" PRId64 ", ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->offsetInfo.endOffset.version, j + 1, numOfVgroups);
|
||||
|
|
@ -925,26 +925,15 @@ static void tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) {
|
|||
SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper;
|
||||
taosMemoryFreeClear(pRsp->pEpset);
|
||||
|
||||
taosArrayDestroyP(pRsp->dataRsp.blockData, taosMemoryFree);
|
||||
taosArrayDestroy(pRsp->dataRsp.blockDataLen);
|
||||
taosArrayDestroyP(pRsp->dataRsp.blockTbName, taosMemoryFree);
|
||||
taosArrayDestroyP(pRsp->dataRsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||
tDeleteMqDataRsp(&pRsp->dataRsp);
|
||||
} else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
||||
SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper;
|
||||
taosMemoryFreeClear(pRsp->pEpset);
|
||||
|
||||
taosMemoryFree(pRsp->metaRsp.metaRsp);
|
||||
tDeleteMqMetaRsp(&pRsp->metaRsp);
|
||||
} else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) {
|
||||
SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper;
|
||||
taosMemoryFreeClear(pRsp->pEpset);
|
||||
|
||||
taosArrayDestroyP(pRsp->taosxRsp.blockData, taosMemoryFree);
|
||||
taosArrayDestroy(pRsp->taosxRsp.blockDataLen);
|
||||
taosArrayDestroyP(pRsp->taosxRsp.blockTbName, taosMemoryFree);
|
||||
taosArrayDestroyP(pRsp->taosxRsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||
// taosx
|
||||
taosArrayDestroy(pRsp->taosxRsp.createTableLen);
|
||||
taosArrayDestroyP(pRsp->taosxRsp.createTableReq, taosMemoryFree);
|
||||
tDeleteSTaosxRsp(&pRsp->taosxRsp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1016,10 +1005,17 @@ int32_t tmq_unsubscribe(tmq_t* tmq) {
|
|||
return rsp;
|
||||
}
|
||||
|
||||
static void freeClientVg(void* param){
|
||||
SMqClientVg* pVg = param;
|
||||
tOffsetDestroy(&pVg->offsetInfo.endOffset);
|
||||
tOffsetDestroy(&pVg->offsetInfo.beginOffset);
|
||||
tOffsetDestroy(&pVg->offsetInfo.committedOffset);
|
||||
|
||||
}
|
||||
static void freeClientVgImpl(void* param) {
|
||||
SMqClientTopic* pTopic = param;
|
||||
taosMemoryFreeClear(pTopic->schema.pSchema);
|
||||
taosArrayDestroy(pTopic->vgs);
|
||||
taosArrayDestroyEx(pTopic->vgs, freeClientVg);
|
||||
}
|
||||
|
||||
void tmqFreeImpl(void* handle) {
|
||||
|
|
@ -1381,7 +1377,12 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
if (rspType == TMQ_MSG_TYPE__POLL_DATA_RSP) {
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeMqDataRsp(&decoder, &pRspWrapper->dataRsp);
|
||||
if(tDecodeMqDataRsp(&decoder, &pRspWrapper->dataRsp, *(int8_t*)POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead))) < 0){
|
||||
tDecoderClear(&decoder);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
memcpy(&pRspWrapper->dataRsp, pMsg->pData, sizeof(SMqRspHead));
|
||||
|
||||
|
|
@ -1392,13 +1393,23 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
} else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeMqMetaRsp(&decoder, &pRspWrapper->metaRsp);
|
||||
if(tDecodeMqMetaRsp(&decoder, &pRspWrapper->metaRsp) < 0){
|
||||
tDecoderClear(&decoder);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
memcpy(&pRspWrapper->metaRsp, pMsg->pData, sizeof(SMqRspHead));
|
||||
} else if (rspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) {
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeSTaosxRsp(&decoder, &pRspWrapper->taosxRsp);
|
||||
if(tDecodeSTaosxRsp(&decoder, &pRspWrapper->taosxRsp, *(int8_t*)POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead))) < 0){
|
||||
tDecoderClear(&decoder);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
memcpy(&pRspWrapper->taosxRsp, pMsg->pData, sizeof(SMqRspHead));
|
||||
} else { // invalid rspType
|
||||
|
|
@ -1472,26 +1483,22 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
|
|||
.numOfRows = pInfo ? pInfo->numOfRows : 0,
|
||||
};
|
||||
|
||||
clientVg.offsetInfo.endOffset = pInfo ? pInfo->currentOffset : offsetNew;
|
||||
clientVg.offsetInfo.committedOffset = pInfo ? pInfo->commitOffset : offsetNew;
|
||||
clientVg.offsetInfo.beginOffset = pInfo ? pInfo->seekOffset : offsetNew;
|
||||
clientVg.offsetInfo.walVerBegin = -1;
|
||||
clientVg.offsetInfo.walVerEnd = -1;
|
||||
clientVg.seekUpdated = false;
|
||||
|
||||
if(pInfo) {
|
||||
tOffsetCopy(&clientVg.offsetInfo.endOffset, &pInfo->currentOffset);
|
||||
tOffsetCopy(&clientVg.offsetInfo.committedOffset, &pInfo->commitOffset);
|
||||
tOffsetCopy(&clientVg.offsetInfo.beginOffset, &pInfo->seekOffset);
|
||||
}else{
|
||||
clientVg.offsetInfo.endOffset = offsetNew;
|
||||
clientVg.offsetInfo.committedOffset = offsetNew;
|
||||
clientVg.offsetInfo.beginOffset = offsetNew;
|
||||
}
|
||||
taosArrayPush(pTopic->vgs, &clientVg);
|
||||
}
|
||||
}
|
||||
|
||||
static void freeClientVgInfo(void* param) {
|
||||
SMqClientTopic* pTopic = param;
|
||||
if (pTopic->schema.nCols) {
|
||||
taosMemoryFreeClear(pTopic->schema.pSchema);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTopic->vgs);
|
||||
}
|
||||
|
||||
static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp) {
|
||||
bool set = false;
|
||||
|
||||
|
|
@ -1558,7 +1565,7 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
|||
|
||||
// destroy current buffered existed topics info
|
||||
if (tmq->clientTopics) {
|
||||
taosArrayDestroyEx(tmq->clientTopics, freeClientVgInfo);
|
||||
taosArrayDestroyEx(tmq->clientTopics, freeClientVgImpl);
|
||||
}
|
||||
tmq->clientTopics = newTopics;
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
|
|
@ -1823,8 +1830,10 @@ static void updateVgInfo(SMqClientVg* pVg, STqOffsetVal* reqOffset, STqOffsetVal
|
|||
int64_t consumerId, bool hasData) {
|
||||
if (!pVg->seekUpdated) {
|
||||
tscDebug("consumer:0x%" PRIx64 " local offset is update, since seekupdate not set", consumerId);
|
||||
if (hasData) pVg->offsetInfo.beginOffset = *reqOffset;
|
||||
pVg->offsetInfo.endOffset = *rspOffset;
|
||||
if (hasData) {
|
||||
tOffsetCopy(&pVg->offsetInfo.beginOffset, reqOffset);
|
||||
}
|
||||
tOffsetCopy(&pVg->offsetInfo.endOffset, rspOffset);
|
||||
} else {
|
||||
tscDebug("consumer:0x%" PRIx64 " local offset is NOT update, since seekupdate is set", consumerId);
|
||||
}
|
||||
|
|
@ -1892,6 +1901,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
if (pollRspWrapper->vgHandle == NULL || pollRspWrapper->topicHandle == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " get vg or topic error, topic:%s vgId:%d", tmq->consumerId,
|
||||
pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
tmqFreeRspWrapper(pRspWrapper);
|
||||
taosFreeQitem(pRspWrapper);
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1960,6 +1971,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
if (pollRspWrapper->vgHandle == NULL || pollRspWrapper->topicHandle == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " get vg or topic error, topic:%s vgId:%d", tmq->consumerId,
|
||||
pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
tmqFreeRspWrapper(pRspWrapper);
|
||||
taosFreeQitem(pRspWrapper);
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1990,6 +2003,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
if (pollRspWrapper->vgHandle == NULL || pollRspWrapper->topicHandle == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " get vg or topic error, topic:%s vgId:%d", tmq->consumerId,
|
||||
pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
tmqFreeRspWrapper(pRspWrapper);
|
||||
taosFreeQitem(pRspWrapper);
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2011,14 +2026,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
}
|
||||
|
||||
// build rsp
|
||||
void* pRsp = NULL;
|
||||
int64_t numOfRows = 0;
|
||||
if (pollRspWrapper->taosxRsp.createTableNum == 0) {
|
||||
tscError("consumer:0x%" PRIx64 " createTableNum should > 0 if rsp type is data_meta", tmq->consumerId);
|
||||
} else {
|
||||
pRsp = tmqBuildTaosxRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
||||
}
|
||||
|
||||
void* pRsp = tmqBuildTaosxRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
||||
tmq->totalRows += numOfRows;
|
||||
|
||||
char buf[TSDB_OFFSET_LEN] = {0};
|
||||
|
|
@ -2676,7 +2685,7 @@ static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
SMqDataRsp rsp;
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeMqDataRsp(&decoder, &rsp);
|
||||
tDecodeMqDataRsp(&decoder, &rsp, *(int8_t*)POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)));
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
SMqRspHead* pHead = pMsg->pData;
|
||||
|
|
@ -2729,6 +2738,7 @@ static int32_t tmCommittedCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)pMsg->pData, pMsg->len);
|
||||
if (tDecodeMqVgOffset(&decoder, &pParam->vgOffset) < 0) {
|
||||
tOffsetDestroy(&pParam->vgOffset.offset);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -2813,6 +2823,7 @@ int64_t getCommittedFromServer(tmq_t* tmq, char* tname, int32_t vgId, SEpSet* ep
|
|||
if (pParam->vgOffset.offset.val.type == TMQ_OFFSET__LOG) {
|
||||
code = pParam->vgOffset.offset.val.version;
|
||||
} else {
|
||||
tOffsetDestroy(&pParam->vgOffset.offset);
|
||||
code = TSDB_CODE_TMQ_SNAPSHOT_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ void createNewTable(TAOS* pConn, int32_t index, int32_t numOfRows, int64_t start
|
|||
printf("failed to insert data, reason:%s\n", taos_errstr(p));
|
||||
}
|
||||
|
||||
// startTs += 20;
|
||||
taos_free_result(p);
|
||||
}
|
||||
}
|
||||
|
|
@ -826,19 +827,19 @@ TEST(clientCase, projection_query_tables) {
|
|||
// }
|
||||
// taos_free_result(pRes);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
TAOS_RES* pRes = taos_query(pConn, "use test");
|
||||
taos_free_result(pRes);
|
||||
|
||||
// TAOS_RES* pRes = taos_query(pConn, "select tbname, last(ts) from abc1.stable_1 group by tbname");
|
||||
pRes = taos_query(pConn, "create table st2 (ts timestamp, k int primary key, j varchar(1000)) tags(a int)");
|
||||
taos_free_result(pRes);
|
||||
|
||||
// pRes = taos_query(pConn, "create stream stream_1 trigger at_once fill_history 1 ignore expired 0 into str_res1 as select _wstart as ts, count(*) from stable_1 interval(10s);");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create stream stream_1 trigger at_once fill_history 1 ignore expired 0 into str_res1 as select _wstart as ts, count(*) from stable_1 interval(10s);");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create table tu using st1 tags(1)");
|
||||
pRes = taos_query(pConn, "create table tu using st2 tags(2)");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
|
|
@ -853,7 +854,7 @@ TEST(clientCase, projection_query_tables) {
|
|||
"ghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz!@#$%^&&*&^^%$#@!qQWERTYUIOPASDFGHJKL:"
|
||||
"QWERTYUIOP{}";
|
||||
|
||||
for(int32_t i = 0; i < 10000; ++i) {
|
||||
for(int32_t i = 0; i < 1; ++i) {
|
||||
char str[1024] = {0};
|
||||
sprintf(str, "create table if not exists tu%d using st2 tags(%d)", i, i);
|
||||
|
||||
|
|
@ -864,10 +865,10 @@ TEST(clientCase, projection_query_tables) {
|
|||
taos_free_result(px);
|
||||
}
|
||||
|
||||
for(int32_t j = 0; j < 5000; ++j) {
|
||||
for(int32_t j = 0; j < 1; ++j) {
|
||||
start += 20;
|
||||
for (int32_t i = 0; i < 10000; ++i) {
|
||||
createNewTable(pConn, i, 20, start, pstr);
|
||||
for (int32_t i = 0; i < 1; ++i) {
|
||||
createNewTable(pConn, i, 100, start, pstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ void colDataSetNItemsNull(SColumnInfoData* pColumnInfoData, uint32_t currentRow,
|
|||
|
||||
memset(&BMCharPos(pColumnInfoData->nullbitmap, currentRow + i), 0xFF, (numOfRows - i) / sizeof(char));
|
||||
i += (numOfRows - i) / sizeof(char) * sizeof(char);
|
||||
|
||||
|
||||
for (; i < numOfRows; ++i) {
|
||||
colDataSetNull_f(pColumnInfoData->nullbitmap, currentRow + i);
|
||||
}
|
||||
|
|
@ -266,23 +266,24 @@ void colDataSetNItemsNull(SColumnInfoData* pColumnInfoData, uint32_t currentRow,
|
|||
}
|
||||
}
|
||||
|
||||
int32_t colDataCopyAndReassign(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows) {
|
||||
int32_t colDataCopyAndReassign(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData,
|
||||
uint32_t numOfRows) {
|
||||
int32_t code = colDataSetVal(pColumnInfoData, currentRow, pData, false);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
if (numOfRows > 1) {
|
||||
int32_t* pOffset = pColumnInfoData->varmeta.offset;
|
||||
memset(&pOffset[currentRow + 1], pOffset[currentRow], sizeof(pOffset[0]) * (numOfRows - 1));
|
||||
pColumnInfoData->reassigned = true;
|
||||
pColumnInfoData->reassigned = true;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t colDataCopyNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData,
|
||||
uint32_t numOfRows, bool isNull) {
|
||||
int32_t colDataCopyNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows,
|
||||
bool isNull) {
|
||||
int32_t len = pColumnInfoData->info.bytes;
|
||||
if (isNull) {
|
||||
colDataSetNItemsNull(pColumnInfoData, currentRow, numOfRows);
|
||||
|
|
@ -293,18 +294,18 @@ int32_t colDataCopyNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow,
|
|||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||
return colDataCopyAndReassign(pColumnInfoData, currentRow, pData, numOfRows);
|
||||
} else {
|
||||
int32_t colBytes = pColumnInfoData->info.bytes;
|
||||
int32_t colOffset = currentRow * colBytes;
|
||||
int32_t colBytes = pColumnInfoData->info.bytes;
|
||||
int32_t colOffset = currentRow * colBytes;
|
||||
uint32_t num = 1;
|
||||
|
||||
void* pStart = pColumnInfoData->pData + colOffset;
|
||||
memcpy(pStart, pData, colBytes);
|
||||
colOffset += num * colBytes;
|
||||
|
||||
|
||||
while (num < numOfRows) {
|
||||
int32_t maxNum = num << 1;
|
||||
int32_t tnum = maxNum > numOfRows ? (numOfRows - num) : num;
|
||||
|
||||
|
||||
memcpy(pColumnInfoData->pData + colOffset, pStart, tnum * colBytes);
|
||||
colOffset += tnum * colBytes;
|
||||
num += tnum;
|
||||
|
|
@ -489,10 +490,6 @@ int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock, int32_t tsColumnIndex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (pDataBlock->info.rows > 0) {
|
||||
// ASSERT(pDataBlock->info.dataLoad == 1);
|
||||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
if (numOfCols <= 0) {
|
||||
return -1;
|
||||
|
|
@ -514,6 +511,52 @@ int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock, int32_t tsColumnIndex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t blockDataUpdatePkRange(SSDataBlock* pDataBlock, int32_t pkColumnIndex, bool asc) {
|
||||
if (pDataBlock == NULL || pDataBlock->info.rows <= 0 || pDataBlock->info.dataLoad == 0 || pkColumnIndex == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
if (numOfCols <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDataBlockInfo* pInfo = &pDataBlock->info;
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, pkColumnIndex);
|
||||
if (!IS_NUMERIC_TYPE(pColInfoData->info.type) && (pColInfoData->info.type != TSDB_DATA_TYPE_VARCHAR)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* skey = colDataGetData(pColInfoData, 0);
|
||||
void* ekey = colDataGetData(pColInfoData, (pInfo->rows - 1));
|
||||
|
||||
if (asc) {
|
||||
if (IS_NUMERIC_TYPE(pColInfoData->info.type)) {
|
||||
GET_TYPED_DATA(pInfo->pks[0].val, int64_t, pColInfoData->info.type, skey);
|
||||
GET_TYPED_DATA(pInfo->pks[1].val, int64_t, pColInfoData->info.type, ekey);
|
||||
} else { // todo refactor
|
||||
memcpy(pInfo->pks[0].pData, varDataVal(skey), varDataLen(skey));
|
||||
pInfo->pks[0].nData = varDataLen(skey);
|
||||
|
||||
memcpy(pInfo->pks[1].pData, varDataVal(ekey), varDataLen(ekey));
|
||||
pInfo->pks[1].nData = varDataLen(ekey);
|
||||
}
|
||||
} else {
|
||||
if (IS_NUMERIC_TYPE(pColInfoData->info.type)) {
|
||||
GET_TYPED_DATA(pInfo->pks[0].val, int64_t, pColInfoData->info.type, ekey);
|
||||
GET_TYPED_DATA(pInfo->pks[1].val, int64_t, pColInfoData->info.type, skey);
|
||||
} else { // todo refactor
|
||||
memcpy(pInfo->pks[0].pData, varDataVal(ekey), varDataLen(ekey));
|
||||
pInfo->pks[0].nData = varDataLen(ekey);
|
||||
|
||||
memcpy(pInfo->pks[1].pData, varDataVal(skey), varDataLen(skey));
|
||||
pInfo->pks[1].nData = varDataLen(skey);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t blockDataMerge(SSDataBlock* pDest, const SSDataBlock* pSrc) {
|
||||
int32_t capacity = pDest->info.capacity;
|
||||
|
||||
|
|
@ -868,8 +911,8 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
|
|||
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
|
||||
// | version | total length | total rows | blankFull | total columns | flag seg| block group id | column schema
|
||||
// | each column length |
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) + sizeof(uint64_t) +
|
||||
numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) +
|
||||
sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
|
||||
}
|
||||
|
||||
double blockDataGetSerialRowSize(const SSDataBlock* pBlock) {
|
||||
|
|
@ -1285,6 +1328,13 @@ void* blockDataDestroy(SSDataBlock* pBlock) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pBlock->info.pks[0].type)) {
|
||||
uInfo("1====free pk:%p, %p pBlock", pBlock->info.pks[0].pData, pBlock);
|
||||
uInfo("2====free pk:%p, %p pBlock", pBlock->info.pks[1].pData, pBlock);
|
||||
taosMemoryFreeClear(pBlock->info.pks[0].pData);
|
||||
taosMemoryFreeClear(pBlock->info.pks[1].pData);
|
||||
}
|
||||
|
||||
blockDataFreeRes(pBlock);
|
||||
taosMemoryFreeClear(pBlock);
|
||||
return NULL;
|
||||
|
|
@ -1432,6 +1482,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
|
||||
SSDataBlock* pBlock = createDataBlock();
|
||||
pBlock->info = pDataBlock->info;
|
||||
|
||||
pBlock->info.rows = 0;
|
||||
pBlock->info.capacity = 0;
|
||||
pBlock->info.rowSize = 0;
|
||||
|
|
@ -1445,6 +1496,26 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
blockDataAppendColInfo(pBlock, &colInfo);
|
||||
}
|
||||
|
||||
// prepare the pk buffer if necessary
|
||||
if (IS_VAR_DATA_TYPE(pDataBlock->info.pks[0].type)) {
|
||||
SValue* pVal = &pBlock->info.pks[0];
|
||||
|
||||
pVal->type = pDataBlock->info.pks[0].type;
|
||||
pVal->pData = taosMemoryCalloc(1, pDataBlock->info.pks[0].nData);
|
||||
pVal->nData = pDataBlock->info.pks[0].nData;
|
||||
memcpy(pVal->pData, pDataBlock->info.pks[0].pData, pVal->nData);
|
||||
|
||||
SValue* p = &pBlock->info.pks[1];
|
||||
p->type = pDataBlock->info.pks[1].type;
|
||||
p->pData = taosMemoryCalloc(1, pDataBlock->info.pks[1].nData);
|
||||
p->nData = pDataBlock->info.pks[1].nData;
|
||||
memcpy(p->pData, pDataBlock->info.pks[1].pData, p->nData);
|
||||
uInfo("===========clone block, with varchar, %p, 0---addr:%p, src:%p, %p", pBlock, pBlock->info.pks[0].pData, pDataBlock, pDataBlock->info.pks[0].pData);
|
||||
uInfo("===========clone block, with varchar, %p, 1---addr:%p, src:%p, %p", pBlock, pBlock->info.pks[1].pData, pDataBlock, pDataBlock->info.pks[1].pData);
|
||||
} else {
|
||||
uInfo("===========clone block without varchar pk, %p, src:%p", pBlock, pDataBlock);
|
||||
}
|
||||
|
||||
if (copyData) {
|
||||
int32_t code = blockDataEnsureCapacity(pBlock, pDataBlock->info.rows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
|
@ -1878,10 +1949,10 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf,
|
|||
int32_t rows = pDataBlock->info.rows;
|
||||
int32_t len = 0;
|
||||
len += snprintf(dumpBuf + len, size - len,
|
||||
"%s===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64
|
||||
"|rows:%" PRId64 "|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n",
|
||||
taskIdStr, flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId,
|
||||
pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version,
|
||||
"%s===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 "|rows:%" PRId64
|
||||
"|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n",
|
||||
taskIdStr, flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId,
|
||||
pDataBlock->info.id.groupId, pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version,
|
||||
pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName);
|
||||
if (len >= size - 1) return dumpBuf;
|
||||
|
||||
|
|
@ -2039,13 +2110,13 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat
|
|||
if (!isStartKey) {
|
||||
isStartKey = true;
|
||||
ASSERT(PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, (SValue){.val = *(TSKEY*)var});
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, ((SValue){.type = pCol->type, .val = *(TSKEY*)var}));
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else if (colDataIsNull_s(pColInfoData, j)) {
|
||||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, (SValue){.val = *(int64_t*)var});
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, ((SValue){.type = pCol->type, .val = *(int64_t*)var}));
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
break;
|
||||
|
|
@ -2057,9 +2128,10 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat
|
|||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
void* data = colDataGetVarData(pColInfoData, j);
|
||||
SValue sv = (SValue){.nData = varDataLen(data), .pData = varDataVal(data)}; // address copy, no value
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
void* data = colDataGetVarData(pColInfoData, j);
|
||||
SValue sv = (SValue){
|
||||
.type = pCol->type, .nData = varDataLen(data), .pData = varDataVal(data)}; // address copy, no value
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
break;
|
||||
|
|
@ -2077,7 +2149,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat
|
|||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); // should use pCol->type
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
SValue sv;
|
||||
SValue sv = {.type = pCol->type};
|
||||
if (pCol->type == pColInfoData->info.type) {
|
||||
memcpy(&sv.val, var, tDataTypes[pCol->type].bytes);
|
||||
} else {
|
||||
|
|
@ -2105,7 +2177,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat
|
|||
}
|
||||
memcpy(&sv.val, tv, tDataTypes[pCol->type].bytes);
|
||||
}
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pColInfoData->info.type, sv);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2204,7 +2276,7 @@ int32_t buildCtbNameByGroupIdImpl(const char* stbFullName, uint64_t groupId, cha
|
|||
int8_t type = TSDB_DATA_TYPE_UBIGINT;
|
||||
const char* name = "group_id";
|
||||
int32_t len = strlen(name);
|
||||
SSmlKv pTag = { .key = name, .keyLen = len, .type = type, .u = groupId, .length = sizeof(uint64_t)};
|
||||
SSmlKv pTag = {.key = name, .keyLen = len, .type = type, .u = groupId, .length = sizeof(uint64_t)};
|
||||
taosArrayPush(tags, &pTag);
|
||||
|
||||
RandTableName rname = {
|
||||
|
|
@ -2586,7 +2658,7 @@ int32_t blockDataGetSortedRows(SSDataBlock* pDataBlock, SArray* pOrderInfo) {
|
|||
pOrder->compFn = getKeyComparFunc(pOrder->pColData->info.type, pOrder->order);
|
||||
}
|
||||
SSDataBlockSortHelper sortHelper = {.orderInfo = pOrderInfo, .pDataBlock = pDataBlock};
|
||||
int32_t rowIdx = 0, nextRowIdx = 1;
|
||||
int32_t rowIdx = 0, nextRowIdx = 1;
|
||||
for (; rowIdx < pDataBlock->info.rows && nextRowIdx < pDataBlock->info.rows; ++rowIdx, ++nextRowIdx) {
|
||||
if (dataBlockCompar(&nextRowIdx, &rowIdx, &sortHelper) < 0) {
|
||||
break;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -159,6 +159,7 @@ char tsCheckpointBackupDir[PATH_MAX] = "/var/lib/taos/backup/checkpoint/";
|
|||
|
||||
// tmq
|
||||
int32_t tmqMaxTopicNum = 20;
|
||||
int32_t tmqRowSize = 4096;
|
||||
// query
|
||||
int32_t tsQueryPolicy = 1;
|
||||
int32_t tsQueryRspPolicy = 0;
|
||||
|
|
@ -733,6 +734,9 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "tmqMaxTopicNum", tmqMaxTopicNum, 1, 10000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
|
||||
if (cfgAddInt32(pCfg, "tmqRowSize", tmqRowSize, 1, 1000000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
|
||||
if (cfgAddInt32(pCfg, "transPullupInterval", tsTransPullupInterval, 1, 10000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) !=
|
||||
0)
|
||||
return -1;
|
||||
|
|
@ -1199,6 +1203,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
|||
tsTelemPort = (uint16_t)cfgGetItem(pCfg, "telemetryPort")->i32;
|
||||
|
||||
tmqMaxTopicNum = cfgGetItem(pCfg, "tmqMaxTopicNum")->i32;
|
||||
tmqRowSize = cfgGetItem(pCfg, "tmqRowSize")->i32;
|
||||
|
||||
tsTransPullupInterval = cfgGetItem(pCfg, "transPullupInterval")->i32;
|
||||
tsCompactPullupInterval = cfgGetItem(pCfg, "compactPullupInterval")->i32;
|
||||
|
|
@ -1529,6 +1534,7 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) {
|
|||
{"queryRspPolicy", &tsQueryRspPolicy},
|
||||
{"timeseriesThreshold", &tsTimeSeriesThreshold},
|
||||
{"tmqMaxTopicNum", &tmqMaxTopicNum},
|
||||
{"tmqRowSize", &tmqRowSize},
|
||||
{"transPullupInterval", &tsTransPullupInterval},
|
||||
{"compactPullupInterval", &tsCompactPullupInterval},
|
||||
{"trimVDbIntervalSec", &tsTrimVDbIntervalSec},
|
||||
|
|
@ -1798,8 +1804,11 @@ static void taosCheckAndSetDebugFlag(int32_t *pFlagPtr, char *name, int32_t flag
|
|||
|
||||
void taosSetGlobalDebugFlag(int32_t flag) { taosSetAllDebugFlag(tsCfg, flag); }
|
||||
|
||||
// NOTE: set all command does not change the tmrDebugFlag
|
||||
static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) {
|
||||
if (flag <= 0) return;
|
||||
if (flag <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SArray *noNeedToSetVars = NULL;
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, "debugFlag");
|
||||
|
|
@ -1809,7 +1818,6 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) {
|
|||
}
|
||||
|
||||
taosCheckAndSetDebugFlag(&simDebugFlag, "simDebugFlag", flag, noNeedToSetVars);
|
||||
taosCheckAndSetDebugFlag(&tmrDebugFlag, "tmrDebugFlag", flag, noNeedToSetVars);
|
||||
taosCheckAndSetDebugFlag(&uDebugFlag, "uDebugFlag", flag, noNeedToSetVars);
|
||||
taosCheckAndSetDebugFlag(&rpcDebugFlag, "rpcDebugFlag", flag, noNeedToSetVars);
|
||||
taosCheckAndSetDebugFlag(&qDebugFlag, "qDebugFlag", flag, noNeedToSetVars);
|
||||
|
|
|
|||
|
|
@ -6961,22 +6961,6 @@ int32_t tDeserializeSResFetchReq(void *buf, int32_t bufLen, SResFetchReq *pReq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tSerializeSTqOffsetVal(SEncoder *pEncoder, STqOffsetVal *pOffset) {
|
||||
if (tEncodeI8(pEncoder, pOffset->type) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pOffset->uid) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pOffset->ts) < 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDerializeSTqOffsetVal(SDecoder *pDecoder, STqOffsetVal *pOffset) {
|
||||
if (tDecodeI8(pDecoder, &pOffset->type) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pOffset->uid) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pOffset->ts) < 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tSerializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
||||
int32_t headLen = sizeof(SMsgHead);
|
||||
if (buf != NULL) {
|
||||
|
|
@ -6995,7 +6979,7 @@ int32_t tSerializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
|||
if (tEncodeU64(&encoder, pReq->reqId) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pReq->consumerId) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pReq->timeout) < 0) return -1;
|
||||
if (tSerializeSTqOffsetVal(&encoder, &pReq->reqOffset) < 0) return -1;
|
||||
if (tEncodeSTqOffsetVal(&encoder, &pReq->reqOffset) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pReq->enableReplay) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pReq->sourceExcluded) < 0) return -1;
|
||||
|
||||
|
|
@ -7016,10 +7000,6 @@ int32_t tSerializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
|||
int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
||||
int32_t headLen = sizeof(SMsgHead);
|
||||
|
||||
// SMsgHead *pHead = buf;
|
||||
// pHead->vgId = pReq->head.vgId;
|
||||
// pHead->contLen = pReq->head.contLen;
|
||||
|
||||
SDecoder decoder = {0};
|
||||
tDecoderInit(&decoder, (char *)buf + headLen, bufLen - headLen);
|
||||
|
||||
|
|
@ -7032,7 +7012,7 @@ int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
|||
if (tDecodeU64(&decoder, &pReq->reqId) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pReq->consumerId) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pReq->timeout) < 0) return -1;
|
||||
if (tDerializeSTqOffsetVal(&decoder, &pReq->reqOffset) < 0) return -1;
|
||||
if (tDecodeSTqOffsetVal(&decoder, &pReq->reqOffset) < 0) return -1;
|
||||
|
||||
if (!tDecodeIsEnd(&decoder)) {
|
||||
if (tDecodeI8(&decoder, &pReq->enableReplay) < 0) return -1;
|
||||
|
|
@ -7048,6 +7028,9 @@ int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tDestroySMqPollReq(SMqPollReq *pReq){
|
||||
tOffsetDestroy(&pReq->reqOffset);
|
||||
}
|
||||
int32_t tSerializeSTaskDropReq(void *buf, int32_t bufLen, STaskDropReq *pReq) {
|
||||
int32_t headLen = sizeof(SMsgHead);
|
||||
if (buf != NULL) {
|
||||
|
|
@ -7679,6 +7662,16 @@ int32_t tSerializeSCMCreateStreamReq(void *buf, int32_t bufLen, const SCMCreateS
|
|||
if (tEncodeI64(&encoder, p->ver) < 0) return -1;
|
||||
}
|
||||
|
||||
int32_t colSize = taosArrayGetSize(pReq->pCols);
|
||||
if (tEncodeI32(&encoder, colSize) < 0) return -1;
|
||||
for (int32_t i = 0; i < colSize; ++i) {
|
||||
SField *pField = taosArrayGet(pReq->pCols, i);
|
||||
if (tEncodeI8(&encoder, pField->type) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pField->flags) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pField->bytes) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
|
||||
}
|
||||
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
|
|
@ -7784,6 +7777,27 @@ int32_t tDeserializeSCMCreateStreamReq(void *buf, int32_t bufLen, SCMCreateStrea
|
|||
}
|
||||
}
|
||||
}
|
||||
int32_t colSize = 0;
|
||||
if (tDecodeI32(&decoder, &colSize) < 0) return -1;
|
||||
if (colSize > 0) {
|
||||
pReq->pCols = taosArrayInit(colSize, sizeof(SField));
|
||||
if (pReq->pCols == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < colSize; ++i) {
|
||||
SField field = {0};
|
||||
if (tDecodeI8(&decoder, &field.type) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &field.flags) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &field.bytes) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, field.name) < 0) return -1;
|
||||
if (taosArrayPush(pReq->pCols, &field) == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tEndDecode(&decoder);
|
||||
tDecoderClear(&decoder);
|
||||
|
|
@ -7864,6 +7878,7 @@ void tFreeSCMCreateStreamReq(SCMCreateStreamReq *pReq) {
|
|||
taosArrayDestroy(pReq->pTags);
|
||||
taosArrayDestroy(pReq->fillNullCols);
|
||||
taosArrayDestroy(pReq->pVgroupVerList);
|
||||
taosArrayDestroy(pReq->pCols);
|
||||
}
|
||||
|
||||
int32_t tEncodeSRSmaParam(SEncoder *pCoder, const SRSmaParam *pRSmaParam) {
|
||||
|
|
@ -8673,10 +8688,18 @@ void tFreeSMCreateStbRsp(SMCreateStbRsp *pRsp) {
|
|||
}
|
||||
|
||||
int32_t tEncodeSTqOffsetVal(SEncoder *pEncoder, const STqOffsetVal *pOffsetVal) {
|
||||
if (tEncodeI8(pEncoder, pOffsetVal->type) < 0) return -1;
|
||||
int8_t type = pOffsetVal->type < 0 ? pOffsetVal->type : (TQ_OFFSET_VERSION << 4) | pOffsetVal->type;
|
||||
if (tEncodeI8(pEncoder, type) < 0) return -1;
|
||||
if (pOffsetVal->type == TMQ_OFFSET__SNAPSHOT_DATA || pOffsetVal->type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||
if (tEncodeI64(pEncoder, pOffsetVal->uid) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pOffsetVal->ts) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pOffsetVal->primaryKey.type) < 0) return -1;
|
||||
if (IS_VAR_DATA_TYPE(pOffsetVal->primaryKey.type)){
|
||||
if (tEncodeBinary(pEncoder, pOffsetVal->primaryKey.pData, pOffsetVal->primaryKey.nData) < 0) return -1;
|
||||
} else {
|
||||
if (tEncodeI64(pEncoder, pOffsetVal->primaryKey.val) < 0) return -1;
|
||||
}
|
||||
|
||||
} else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
|
||||
if (tEncodeI64(pEncoder, pOffsetVal->version) < 0) return -1;
|
||||
} else {
|
||||
|
|
@ -8687,9 +8710,22 @@ int32_t tEncodeSTqOffsetVal(SEncoder *pEncoder, const STqOffsetVal *pOffsetVal)
|
|||
|
||||
int32_t tDecodeSTqOffsetVal(SDecoder *pDecoder, STqOffsetVal *pOffsetVal) {
|
||||
if (tDecodeI8(pDecoder, &pOffsetVal->type) < 0) return -1;
|
||||
int8_t offsetVersion = 0;
|
||||
if (pOffsetVal->type > 0){
|
||||
offsetVersion = (pOffsetVal->type >> 4);
|
||||
pOffsetVal->type = pOffsetVal->type & 0x0F;
|
||||
}
|
||||
if (pOffsetVal->type == TMQ_OFFSET__SNAPSHOT_DATA || pOffsetVal->type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||
if (tDecodeI64(pDecoder, &pOffsetVal->uid) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pOffsetVal->ts) < 0) return -1;
|
||||
if (offsetVersion >= TQ_OFFSET_VERSION) {
|
||||
if (tDecodeI8(pDecoder, &pOffsetVal->primaryKey.type) < 0) return -1;
|
||||
if (IS_VAR_DATA_TYPE(pOffsetVal->primaryKey.type)){
|
||||
if (tDecodeBinaryAlloc32(pDecoder, (void**)&pOffsetVal->primaryKey.pData, &pOffsetVal->primaryKey.nData) < 0) return -1;
|
||||
} else {
|
||||
if (tDecodeI64(pDecoder, &pOffsetVal->primaryKey.val) < 0) return -1;
|
||||
}
|
||||
}
|
||||
} else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
|
||||
if (tDecodeI64(pDecoder, &pOffsetVal->version) < 0) return -1;
|
||||
} else {
|
||||
|
|
@ -8708,7 +8744,15 @@ int32_t tFormatOffset(char *buf, int32_t maxLen, const STqOffsetVal *pVal) {
|
|||
} else if (pVal->type == TMQ_OFFSET__LOG) {
|
||||
snprintf(buf, maxLen, "wal:%" PRId64, pVal->version);
|
||||
} else if (pVal->type == TMQ_OFFSET__SNAPSHOT_DATA || pVal->type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||
snprintf(buf, maxLen, "tsdb:%" PRId64 "|%" PRId64, pVal->uid, pVal->ts);
|
||||
if(IS_VAR_DATA_TYPE(pVal->primaryKey.type)) {
|
||||
char *tmp = taosMemoryCalloc(1, pVal->primaryKey.nData + 1);
|
||||
if (tmp == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
memcpy(tmp, pVal->primaryKey.pData, pVal->primaryKey.nData);
|
||||
snprintf(buf, maxLen, "tsdb:%" PRId64 "|%" PRId64 ",pk type:%d,val:%s", pVal->uid, pVal->ts, pVal->primaryKey.type, tmp);
|
||||
taosMemoryFree(tmp);
|
||||
}else{
|
||||
snprintf(buf, maxLen, "tsdb:%" PRId64 "|%" PRId64 ",pk type:%d,val:%" PRId64, pVal->uid, pVal->ts, pVal->primaryKey.type, pVal->primaryKey.val);
|
||||
}
|
||||
} else {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
|
@ -8721,6 +8765,10 @@ bool tOffsetEqual(const STqOffsetVal *pLeft, const STqOffsetVal *pRight) {
|
|||
if (pLeft->type == TMQ_OFFSET__LOG) {
|
||||
return pLeft->version == pRight->version;
|
||||
} else if (pLeft->type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
||||
if (pLeft->primaryKey.type != 0) {
|
||||
if(pLeft->primaryKey.type != pRight->primaryKey.type) return false;
|
||||
if(tValueCompare(&pLeft->primaryKey, &pRight->primaryKey) != 0) return false;
|
||||
}
|
||||
return pLeft->uid == pRight->uid && pLeft->ts == pRight->ts;
|
||||
} else if (pLeft->type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||
return pLeft->uid == pRight->uid;
|
||||
|
|
@ -8732,6 +8780,21 @@ bool tOffsetEqual(const STqOffsetVal *pLeft, const STqOffsetVal *pRight) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void tOffsetCopy(STqOffsetVal* pLeft, const STqOffsetVal* pRight){
|
||||
tOffsetDestroy(pLeft);
|
||||
*pLeft = *pRight;
|
||||
if(IS_VAR_DATA_TYPE(pRight->primaryKey.type)){
|
||||
pLeft->primaryKey.pData = taosMemoryMalloc(pRight->primaryKey.nData);
|
||||
memcpy(pLeft->primaryKey.pData, pRight->primaryKey.pData, pRight->primaryKey.nData);
|
||||
}
|
||||
}
|
||||
|
||||
void tOffsetDestroy(void* param){
|
||||
STqOffsetVal* pVal = (STqOffsetVal*)param;
|
||||
if(IS_VAR_DATA_TYPE(pVal->primaryKey.type)){
|
||||
taosMemoryFreeClear(pVal->primaryKey.pData);
|
||||
}
|
||||
}
|
||||
int32_t tEncodeSTqOffset(SEncoder *pEncoder, const STqOffset *pOffset) {
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pOffset->val) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pOffset->subKey) < 0) return -1;
|
||||
|
|
@ -8844,6 +8907,10 @@ int32_t tDecodeMqMetaRsp(SDecoder *pDecoder, SMqMetaRsp *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tDeleteMqMetaRsp(SMqMetaRsp *pRsp) {
|
||||
taosMemoryFree(pRsp->metaRsp);
|
||||
}
|
||||
|
||||
int32_t tEncodeMqDataRspCommon(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->reqOffset) < 0) return -1;
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->rspOffset) < 0) return -1;
|
||||
|
|
@ -8870,6 +8937,7 @@ int32_t tEncodeMqDataRspCommon(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
|||
}
|
||||
|
||||
int32_t tEncodeMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
if (tEncodeI8(pEncoder, MQ_DATA_RSP_VERSION) < 0) return -1;
|
||||
if (tEncodeMqDataRspCommon(pEncoder, pRsp) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pRsp->sleepTime) < 0) return -1;
|
||||
return 0;
|
||||
|
|
@ -8921,7 +8989,10 @@ int32_t tDecodeMqDataRspCommon(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
||||
int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp, int8_t dataVersion) {
|
||||
if (dataVersion >= MQ_DATA_RSP_VERSION){
|
||||
if (tDecodeI8(pDecoder, &dataVersion) < 0) return -1;
|
||||
}
|
||||
if (tDecodeMqDataRspCommon(pDecoder, pRsp) < 0) return -1;
|
||||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
if (tDecodeI64(pDecoder, &pRsp->sleepTime) < 0) return -1;
|
||||
|
|
@ -8938,9 +9009,12 @@ void tDeleteMqDataRsp(SMqDataRsp *pRsp) {
|
|||
pRsp->blockSchema = NULL;
|
||||
taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
|
||||
pRsp->blockTbName = NULL;
|
||||
tOffsetDestroy(&pRsp->reqOffset);
|
||||
tOffsetDestroy(&pRsp->rspOffset);
|
||||
}
|
||||
|
||||
int32_t tEncodeSTaosxRsp(SEncoder *pEncoder, const STaosxRsp *pRsp) {
|
||||
if (tEncodeI8(pEncoder, MQ_DATA_RSP_VERSION) < 0) return -1;
|
||||
if (tEncodeMqDataRspCommon(pEncoder, (const SMqDataRsp *)pRsp) < 0) return -1;
|
||||
|
||||
if (tEncodeI32(pEncoder, pRsp->createTableNum) < 0) return -1;
|
||||
|
|
@ -8954,7 +9028,10 @@ int32_t tEncodeSTaosxRsp(SEncoder *pEncoder, const STaosxRsp *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSTaosxRsp(SDecoder *pDecoder, STaosxRsp *pRsp) {
|
||||
int32_t tDecodeSTaosxRsp(SDecoder *pDecoder, STaosxRsp *pRsp, int8_t dataVersion) {
|
||||
if (dataVersion >= MQ_DATA_RSP_VERSION){
|
||||
if (tDecodeI8(pDecoder, &dataVersion) < 0) return -1;
|
||||
}
|
||||
if (tDecodeMqDataRspCommon(pDecoder, (SMqDataRsp*)pRsp) < 0) return -1;
|
||||
|
||||
if (tDecodeI32(pDecoder, &pRsp->createTableNum) < 0) return -1;
|
||||
|
|
@ -8986,6 +9063,8 @@ void tDeleteSTaosxRsp(STaosxRsp *pRsp) {
|
|||
pRsp->createTableLen = taosArrayDestroy(pRsp->createTableLen);
|
||||
taosArrayDestroyP(pRsp->createTableReq, (FDelete)taosMemoryFree);
|
||||
pRsp->createTableReq = NULL;
|
||||
tOffsetDestroy(&pRsp->reqOffset);
|
||||
tOffsetDestroy(&pRsp->rspOffset);
|
||||
}
|
||||
|
||||
int32_t tEncodeSSingleDeleteReq(SEncoder *pEncoder, const SSingleDeleteReq *pReq) {
|
||||
|
|
@ -9056,7 +9135,8 @@ int32_t tDecodeSBatchDeleteReqSetCtime(SDecoder *pDecoder, SBatchDeleteReq *pReq
|
|||
static int32_t tEncodeSSubmitTbData(SEncoder *pCoder, const SSubmitTbData *pSubmitTbData) {
|
||||
if (tStartEncode(pCoder) < 0) return -1;
|
||||
|
||||
if (tEncodeI32v(pCoder, pSubmitTbData->flags) < 0) return -1;
|
||||
int32_t flags = pSubmitTbData->flags | ((SUBMIT_REQUEST_VERSION) << 8);
|
||||
if (tEncodeI32v(pCoder, flags) < 0) return -1;
|
||||
|
||||
// auto create table
|
||||
if (pSubmitTbData->flags & SUBMIT_REQ_AUTO_CREATE_TABLE) {
|
||||
|
|
@ -9076,7 +9156,8 @@ static int32_t tEncodeSSubmitTbData(SEncoder *pCoder, const SSubmitTbData *pSubm
|
|||
if (tEncodeU64v(pCoder, nColData) < 0) return -1;
|
||||
|
||||
for (uint64_t i = 0; i < nColData; i++) {
|
||||
pCoder->pos += tPutColData(pCoder->data ? pCoder->data + pCoder->pos : NULL, &aColData[i]);
|
||||
pCoder->pos +=
|
||||
tPutColData(SUBMIT_REQUEST_VERSION, pCoder->data ? pCoder->data + pCoder->pos : NULL, &aColData[i]);
|
||||
}
|
||||
} else {
|
||||
if (tEncodeU64v(pCoder, TARRAY_SIZE(pSubmitTbData->aRowP)) < 0) return -1;
|
||||
|
|
@ -9095,13 +9176,18 @@ static int32_t tEncodeSSubmitTbData(SEncoder *pCoder, const SSubmitTbData *pSubm
|
|||
|
||||
static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbData) {
|
||||
int32_t code = 0;
|
||||
int32_t flags;
|
||||
uint8_t version;
|
||||
|
||||
if (tStartDecode(pCoder) < 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (tDecodeI32v(pCoder, &pSubmitTbData->flags) < 0) return -1;
|
||||
if (tDecodeI32v(pCoder, &flags) < 0) return -1;
|
||||
|
||||
pSubmitTbData->flags = flags & 0xff;
|
||||
version = (flags >> 8) & 0xff;
|
||||
|
||||
if (pSubmitTbData->flags & SUBMIT_REQ_AUTO_CREATE_TABLE) {
|
||||
pSubmitTbData->pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
|
||||
|
|
@ -9145,7 +9231,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < nColData; ++i) {
|
||||
pCoder->pos += tGetColData(pCoder->data + pCoder->pos, taosArrayReserve(pSubmitTbData->aCol, 1));
|
||||
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, taosArrayReserve(pSubmitTbData->aCol, 1));
|
||||
}
|
||||
} else {
|
||||
uint64_t nRow;
|
||||
|
|
|
|||
|
|
@ -510,9 +510,9 @@ int32_t tdSTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow **ppRow, int8_t r
|
|||
rowTotalLen = sizeof(STSRow) + sizeof(col_id_t) + varDataLen + nonVarDataLen + (nBound - 1) * sizeof(SKvRowIdx) +
|
||||
TD_BITMAP_BYTES(nBound - 1);
|
||||
}
|
||||
if (!(*ppRow)) {
|
||||
*ppRow = (STSRow *)taosMemoryCalloc(1, rowTotalLen);
|
||||
isAlloc = true;
|
||||
if (!(*ppRow)) {
|
||||
*ppRow = (STSRow *)taosMemoryCalloc(1, rowTotalLen);
|
||||
isAlloc = true;
|
||||
}
|
||||
|
||||
if (!(*ppRow)) {
|
||||
|
|
@ -1106,7 +1106,7 @@ void tTSRowGetVal(STSRow *pRow, STSchema *pTSchema, int16_t iCol, SColVal *pColV
|
|||
*pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type);
|
||||
} else {
|
||||
pColVal->cid = pTColumn->colId;
|
||||
pColVal->type = pTColumn->type;
|
||||
pColVal->value.type = pTColumn->type;
|
||||
pColVal->flag = CV_FLAG_VALUE;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pTColumn->type)) {
|
||||
|
|
|
|||
|
|
@ -143,73 +143,73 @@ static int32_t genTestData(const char **data, int16_t nCols, SArray **pArray) {
|
|||
}
|
||||
switch (i) {
|
||||
case 0:
|
||||
colVal.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
colVal.value.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
sscanf(data[i], "%" PRIi64, &colVal.value.val);
|
||||
break;
|
||||
case 1:
|
||||
colVal.type = TSDB_DATA_TYPE_INT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_INT;
|
||||
sscanf(data[i], "%" PRIi32, (int32_t *)&colVal.value.val);
|
||||
break;
|
||||
case 2:
|
||||
colVal.type = TSDB_DATA_TYPE_BIGINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_BIGINT;
|
||||
sscanf(data[i], "%" PRIi64, &colVal.value.val);
|
||||
break;
|
||||
case 3:
|
||||
colVal.type = TSDB_DATA_TYPE_FLOAT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_FLOAT;
|
||||
sscanf(data[i], "%f", (float *)&colVal.value.val);
|
||||
break;
|
||||
case 4:
|
||||
colVal.type = TSDB_DATA_TYPE_DOUBLE;
|
||||
colVal.value.type = TSDB_DATA_TYPE_DOUBLE;
|
||||
sscanf(data[i], "%lf", (double *)&colVal.value.val);
|
||||
break;
|
||||
case 5: {
|
||||
colVal.type = TSDB_DATA_TYPE_BINARY;
|
||||
colVal.value.type = TSDB_DATA_TYPE_BINARY;
|
||||
int16_t dataLen = strlen(data[i]) + 1;
|
||||
colVal.value.nData = dataLen < 10 ? dataLen : 10;
|
||||
colVal.value.pData = (uint8_t *)data[i];
|
||||
} break;
|
||||
case 6: {
|
||||
colVal.type = TSDB_DATA_TYPE_NCHAR;
|
||||
colVal.value.type = TSDB_DATA_TYPE_NCHAR;
|
||||
int16_t dataLen = strlen(data[i]) + 1;
|
||||
colVal.value.nData = dataLen < 40 ? dataLen : 40;
|
||||
colVal.value.pData = (uint8_t *)data[i]; // just for test, not real nchar
|
||||
} break;
|
||||
case 7: {
|
||||
colVal.type = TSDB_DATA_TYPE_TINYINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_TINYINT;
|
||||
int32_t d8;
|
||||
sscanf(data[i], "%" PRId32, &d8);
|
||||
colVal.value.val = (int8_t)d8;
|
||||
}
|
||||
case 8: {
|
||||
colVal.type = TSDB_DATA_TYPE_SMALLINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_SMALLINT;
|
||||
int32_t d16;
|
||||
sscanf(data[i], "%" PRId32, &d16);
|
||||
colVal.value.val = (int16_t)d16;
|
||||
} break;
|
||||
case 9: {
|
||||
colVal.type = TSDB_DATA_TYPE_BOOL;
|
||||
colVal.value.type = TSDB_DATA_TYPE_BOOL;
|
||||
int32_t d8;
|
||||
sscanf(data[i], "%" PRId32, &d8);
|
||||
colVal.value.val = (int8_t)d8;
|
||||
} break;
|
||||
case 10: {
|
||||
colVal.type = TSDB_DATA_TYPE_UTINYINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_UTINYINT;
|
||||
uint32_t u8;
|
||||
sscanf(data[i], "%" PRId32, &u8);
|
||||
colVal.value.val = (uint8_t)u8;
|
||||
} break;
|
||||
case 11: {
|
||||
colVal.type = TSDB_DATA_TYPE_USMALLINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_USMALLINT;
|
||||
uint32_t u16;
|
||||
sscanf(data[i], "%" PRId32, &u16);
|
||||
colVal.value.val = (uint16_t)u16;
|
||||
} break;
|
||||
case 12: {
|
||||
colVal.type = TSDB_DATA_TYPE_UINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_UINT;
|
||||
sscanf(data[i], "%" PRIu32, (uint32_t *)&colVal.value.val);
|
||||
} break;
|
||||
case 13: {
|
||||
colVal.type = TSDB_DATA_TYPE_UBIGINT;
|
||||
colVal.value.type = TSDB_DATA_TYPE_UBIGINT;
|
||||
sscanf(data[i], "%" PRIu64, (uint64_t *)&colVal.value.val);
|
||||
} break;
|
||||
default:
|
||||
|
|
@ -430,7 +430,7 @@ static void checkTSRow(const char **data, STSRow *row, STSchema *pTSchema) {
|
|||
}
|
||||
|
||||
colVal.cid = pCol->colId;
|
||||
colVal.type = pCol->type;
|
||||
colVal.value.type = pCol->type;
|
||||
if (tdValTypeIsNone(cv.valType)) {
|
||||
colVal.flag = CV_FLAG_NONE;
|
||||
} else if (tdValTypeIsNull(cv.valType)) {
|
||||
|
|
|
|||
|
|
@ -287,6 +287,45 @@ static int32_t mndCheckCreateStreamReq(SCMCreateStreamReq *pCreate) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t createSchemaByFields(const SArray* pFields, SSchemaWrapper* pWrapper) {
|
||||
pWrapper->nCols = taosArrayGetSize(pFields);
|
||||
pWrapper->pSchema = taosMemoryCalloc(pWrapper->nCols, sizeof(SSchema));
|
||||
if (NULL == pWrapper->pSchema) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SNode* pNode;
|
||||
int32_t index = 0;
|
||||
for(int32_t i = 0; i < pWrapper->nCols; i++) {
|
||||
SField* pField = (SField*)taosArrayGet(pFields, i);
|
||||
if (TSDB_DATA_TYPE_NULL == pField->type) {
|
||||
pWrapper->pSchema[index].type = TSDB_DATA_TYPE_VARCHAR;
|
||||
pWrapper->pSchema[index].bytes = VARSTR_HEADER_SIZE;
|
||||
} else {
|
||||
pWrapper->pSchema[index].type = pField->type;
|
||||
pWrapper->pSchema[index].bytes = pField->bytes;
|
||||
}
|
||||
pWrapper->pSchema[index].colId = index + 1;
|
||||
strcpy(pWrapper->pSchema[index].name, pField->name);
|
||||
pWrapper->pSchema[index].flags = pField->flags;
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool hasPrimaryKey(SSchemaWrapper* pWrapper) {
|
||||
if (pWrapper->nCols < 2) {
|
||||
return false;
|
||||
}
|
||||
for (int32_t i = 1; i < pWrapper->nCols; i++) {
|
||||
if(pWrapper->pSchema[i].flags & COL_IS_KEY) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, SCMCreateStreamReq *pCreate) {
|
||||
SNode *pAst = NULL;
|
||||
SQueryPlan *pPlan = NULL;
|
||||
|
|
@ -352,8 +391,8 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj,
|
|||
goto FAIL;
|
||||
}
|
||||
|
||||
// extract output schema from ast
|
||||
if (qExtractResultSchema(pAst, (int32_t *)&pObj->outputSchema.nCols, &pObj->outputSchema.pSchema) != 0) {
|
||||
// create output schema
|
||||
if (createSchemaByFields(pCreate->pCols, &pObj->outputSchema) != TSDB_CODE_SUCCESS) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
|
|
@ -389,6 +428,7 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj,
|
|||
pObj->outputSchema.pSchema = pFullSchema;
|
||||
}
|
||||
|
||||
bool hasKey = hasPrimaryKey(&pObj->outputSchema);
|
||||
SPlanContext cxt = {
|
||||
.pAstRoot = pAst,
|
||||
.topicQuery = false,
|
||||
|
|
@ -398,6 +438,7 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj,
|
|||
.igExpired = pObj->conf.igExpired,
|
||||
.deleteMark = pObj->deleteMark,
|
||||
.igCheckUpdate = pObj->igCheckUpdate,
|
||||
.destHasPrimaryKey = hasKey,
|
||||
};
|
||||
|
||||
// using ast and param to build physical plan
|
||||
|
|
|
|||
|
|
@ -1311,6 +1311,7 @@ static int32_t buildResult(SSDataBlock *pBlock, int32_t* numOfRows, int64_t cons
|
|||
for(int i = 0; i < taosArrayGetSize(offsetRows); i++){
|
||||
OffsetRows *tmp = taosArrayGet(offsetRows, i);
|
||||
if(tmp->vgId != pVgEp->vgId){
|
||||
mError("mnd show subscriptions: do not find vgId:%d, %d in offsetRows", tmp->vgId, pVgEp->vgId);
|
||||
continue;
|
||||
}
|
||||
data = tmp;
|
||||
|
|
@ -1374,7 +1375,6 @@ int32_t mndRetrieveSubscribe(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock
|
|||
buildResult(pBlock, &numOfRows, pConsumerEp->consumerId, topic, cgroup, pConsumerEp->vgs, pConsumerEp->offsetRows);
|
||||
}
|
||||
|
||||
// do not show for cleared subscription
|
||||
buildResult(pBlock, &numOfRows, -1, topic, cgroup, pSub->unassignedVgs, pSub->offsetRows);
|
||||
|
||||
pBlock->info.rows = numOfRows;
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ void tsdbReaderSetNotifyCb(STsdbReader* pReader, TsdReaderNotifyCbFn not
|
|||
int32_t tsdbReuseCacherowsReader(void *pReader, void *pTableIdList, int32_t numOfTables);
|
||||
int32_t tsdbCacherowsReaderOpen(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr,
|
||||
SArray* pFuncTypeList);
|
||||
SArray* pFuncTypeList, SColumnInfo* pkCol, int32_t numOfPks);
|
||||
int32_t tsdbRetrieveCacheRows(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds,
|
||||
SArray *pTableUids);
|
||||
void *tsdbCacherowsReaderClose(void *pReader);
|
||||
|
|
@ -212,11 +212,15 @@ typedef struct STqReader {
|
|||
SSchemaWrapper *pSchemaWrapper;
|
||||
SSDataBlock *pResBlock;
|
||||
int64_t lastTs;
|
||||
bool hasPrimaryKey;
|
||||
} STqReader;
|
||||
|
||||
STqReader *tqReaderOpen(SVnode *pVnode);
|
||||
void tqReaderClose(STqReader *);
|
||||
|
||||
bool tqGetTablePrimaryKey(STqReader* pReader);
|
||||
void tqSetTablePrimaryKey(STqReader* pReader, int64_t uid);
|
||||
|
||||
void tqReaderSetColIdList(STqReader *pReader, SArray *pColIdList);
|
||||
int32_t tqReaderSetTbUidList(STqReader *pReader, const SArray *tbUidList, const char *id);
|
||||
int32_t tqReaderAddTbUidList(STqReader *pReader, const SArray *pTableUidList);
|
||||
|
|
@ -251,6 +255,8 @@ int32_t vnodeSnapWriterOpen(SVnode *pVnode, SSnapshotParam *pParam, SVSnapWriter
|
|||
int32_t vnodeSnapWriterClose(SVSnapWriter *pWriter, int8_t rollback, SSnapshot *pSnapshot);
|
||||
int32_t vnodeSnapWrite(SVSnapWriter *pWriter, uint8_t *pData, uint32_t nData);
|
||||
|
||||
bool taosXGetTablePrimaryKey(SSnapContext *ctx);
|
||||
void taosXSetTablePrimaryKey(SSnapContext *ctx, int64_t uid);
|
||||
int32_t buildSnapContext(SVnode *pVnode, int64_t snapVersion, int64_t suid, int8_t subType, int8_t withMeta,
|
||||
SSnapContext **ctxRet);
|
||||
int32_t getTableInfoFromSnapshot(SSnapContext *ctx, void **pBuf, int32_t *contLen, int16_t *type, int64_t *uid);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ typedef struct SBlkInfo SBlkInfo;
|
|||
typedef struct STsdbDataIter2 STsdbDataIter2;
|
||||
typedef struct STsdbFilterInfo STsdbFilterInfo;
|
||||
typedef struct STFileSystem STFileSystem;
|
||||
typedef struct STsdbRowKey STsdbRowKey;
|
||||
|
||||
#define TSDBROW_ROW_FMT ((int8_t)0x0)
|
||||
#define TSDBROW_COL_FMT ((int8_t)0x1)
|
||||
|
|
@ -93,7 +94,7 @@ typedef struct STFileSystem STFileSystem;
|
|||
#define PAGE_CONTENT_SIZE(PAGE) ((PAGE) - sizeof(TSCKSUM))
|
||||
#define LOGIC_TO_FILE_OFFSET(LOFFSET, PAGE) \
|
||||
((LOFFSET) / PAGE_CONTENT_SIZE(PAGE) * (PAGE) + (LOFFSET) % PAGE_CONTENT_SIZE(PAGE))
|
||||
#define FILE_TO_LOGIC_OFFSET(OFFSET, PAGE) ((OFFSET) / (PAGE)*PAGE_CONTENT_SIZE(PAGE) + (OFFSET) % (PAGE))
|
||||
#define FILE_TO_LOGIC_OFFSET(OFFSET, PAGE) ((OFFSET) / (PAGE) * PAGE_CONTENT_SIZE(PAGE) + (OFFSET) % (PAGE))
|
||||
#define PAGE_OFFSET(PGNO, PAGE) (((PGNO)-1) * (PAGE))
|
||||
#define OFFSET_PGNO(OFFSET, PAGE) ((OFFSET) / (PAGE) + 1)
|
||||
|
||||
|
|
@ -120,7 +121,13 @@ static FORCE_INLINE int64_t tsdbLogicToFileSize(int64_t lSize, int32_t szPage) {
|
|||
((TSDBROW){.type = TSDBROW_COL_FMT, .pBlockData = (BLOCKDATA), .iRow = (IROW)})
|
||||
|
||||
void tsdbRowGetColVal(TSDBROW *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal);
|
||||
int32_t tsdbRowCmprFn(const void *p1, const void *p2);
|
||||
int32_t tsdbRowCompare(const void *p1, const void *p2);
|
||||
int32_t tsdbRowCompareWithoutVersion(const void *p1, const void *p2);
|
||||
int32_t tsdbRowKeyCmpr(const STsdbRowKey *key1, const STsdbRowKey *key2);
|
||||
void tsdbRowGetKey(TSDBROW *row, STsdbRowKey *key);
|
||||
void tColRowGetKey(SBlockData *pBlock, int32_t irow, SRowKey *key);
|
||||
int32_t tRowKeyAssign(SRowKey *pDst, SRowKey *pSrc);
|
||||
|
||||
// STSDBRowIter
|
||||
int32_t tsdbRowIterOpen(STSDBRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema);
|
||||
void tsdbRowClose(STSDBRowIter *pIter);
|
||||
|
|
@ -139,8 +146,8 @@ int32_t tTABLEIDCmprFn(const void *p1, const void *p2);
|
|||
#define MIN_TSDBKEY(KEY1, KEY2) ((tsdbKeyCmprFn(&(KEY1), &(KEY2)) < 0) ? (KEY1) : (KEY2))
|
||||
#define MAX_TSDBKEY(KEY1, KEY2) ((tsdbKeyCmprFn(&(KEY1), &(KEY2)) > 0) ? (KEY1) : (KEY2))
|
||||
// SBlockCol
|
||||
int32_t tPutBlockCol(uint8_t *p, void *ph);
|
||||
int32_t tGetBlockCol(uint8_t *p, void *ph);
|
||||
int32_t tPutBlockCol(SBuffer *buffer, const SBlockCol *pBlockCol);
|
||||
int32_t tGetBlockCol(SBufferReader *br, SBlockCol *pBlockCol);
|
||||
int32_t tBlockColCmprFn(const void *p1, const void *p2);
|
||||
// SDataBlk
|
||||
void tDataBlkReset(SDataBlk *pBlock);
|
||||
|
|
@ -172,13 +179,17 @@ int32_t tBlockDataUpdateRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTS
|
|||
int32_t tBlockDataTryUpsertRow(SBlockData *pBlockData, TSDBROW *pRow, int64_t uid);
|
||||
int32_t tBlockDataUpsertRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema, int64_t uid);
|
||||
void tBlockDataClear(SBlockData *pBlockData);
|
||||
void tBlockDataGetColData(SBlockData *pBlockData, int16_t cid, SColData **ppColData);
|
||||
int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut, int32_t *szOut, uint8_t *aBuf[],
|
||||
int32_t aBufN[]);
|
||||
int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uint8_t *aBuf[]);
|
||||
int32_t tBlockDataCompress(SBlockData *bData, int8_t cmprAlg, SBuffer *buffers, SBuffer *assist);
|
||||
int32_t tBlockDataDecompress(SBufferReader *br, SBlockData *blockData, SBuffer *assist);
|
||||
int32_t tBlockDataDecompressKeyPart(const SDiskDataHdr *hdr, SBufferReader *br, SBlockData *blockData, SBuffer *assist);
|
||||
int32_t tBlockDataDecompressColData(const SDiskDataHdr *hdr, const SBlockCol *blockCol, SBufferReader *br,
|
||||
SBlockData *blockData, SBuffer *assist);
|
||||
|
||||
SColData *tBlockDataGetColData(SBlockData *pBlockData, int16_t cid);
|
||||
int32_t tBlockDataAddColData(SBlockData *pBlockData, int16_t cid, int8_t type, int8_t cflag, SColData **ppColData);
|
||||
// SDiskDataHdr
|
||||
int32_t tPutDiskDataHdr(uint8_t *p, const SDiskDataHdr *pHdr);
|
||||
int32_t tGetDiskDataHdr(uint8_t *p, void *ph);
|
||||
int32_t tPutDiskDataHdr(SBuffer *buffer, const SDiskDataHdr *pHdr);
|
||||
int32_t tGetDiskDataHdr(SBufferReader *br, SDiskDataHdr *pHdr);
|
||||
// SDelIdx
|
||||
int32_t tPutDelIdx(uint8_t *p, void *ph);
|
||||
int32_t tGetDelIdx(uint8_t *p, void *ph);
|
||||
|
|
@ -204,16 +215,8 @@ int32_t tsdbKeyFid(TSKEY key, int32_t minutes, int8_t precision);
|
|||
void tsdbFidKeyRange(int32_t fid, int32_t minutes, int8_t precision, TSKEY *minKey, TSKEY *maxKey);
|
||||
int32_t tsdbFidLevel(int32_t fid, STsdbKeepCfg *pKeepCfg, int64_t nowSec);
|
||||
int32_t tsdbBuildDeleteSkyline(SArray *aDelData, int32_t sidx, int32_t eidx, SArray *aSkyline);
|
||||
int32_t tPutColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg);
|
||||
int32_t tGetColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg);
|
||||
int32_t tsdbCmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t nOut,
|
||||
int32_t *szOut, uint8_t **ppBuf);
|
||||
int32_t tsdbDecmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t szOut,
|
||||
uint8_t **ppBuf);
|
||||
int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol, uint8_t **ppOut, int32_t nOut,
|
||||
uint8_t **ppBuf);
|
||||
int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
|
||||
uint8_t **ppBuf);
|
||||
int32_t tPutColumnDataAgg(SBuffer *buffer, SColumnDataAgg *pColAgg);
|
||||
int32_t tGetColumnDataAgg(SBufferReader *br, SColumnDataAgg *pColAgg);
|
||||
int32_t tRowInfoCmprFn(const void *p1, const void *p2);
|
||||
// tsdbMemTable ==============================================================================================
|
||||
// SMemTable
|
||||
|
|
@ -224,9 +227,9 @@ int32_t tsdbRefMemTable(SMemTable *pMemTable, SQueryNode *pQNode);
|
|||
int32_t tsdbUnrefMemTable(SMemTable *pMemTable, SQueryNode *pNode, bool proactive);
|
||||
SArray *tsdbMemTableGetTbDataArray(SMemTable *pMemTable);
|
||||
// STbDataIter
|
||||
int32_t tsdbTbDataIterCreate(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter **ppIter);
|
||||
int32_t tsdbTbDataIterCreate(STbData *pTbData, STsdbRowKey *pFrom, int8_t backward, STbDataIter **ppIter);
|
||||
void *tsdbTbDataIterDestroy(STbDataIter *pIter);
|
||||
void tsdbTbDataIterOpen(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter *pIter);
|
||||
void tsdbTbDataIterOpen(STbData *pTbData, STsdbRowKey *pFrom, int8_t backward, STbDataIter *pIter);
|
||||
bool tsdbTbDataIterNext(STbDataIter *pIter);
|
||||
void tsdbMemTableCountRows(SMemTable *pMemTable, SSHashObj *pTableMap, int64_t *rowsNum);
|
||||
|
||||
|
|
@ -264,11 +267,6 @@ int32_t tsdbDataFReaderClose(SDataFReader **ppReader);
|
|||
int32_t tsdbReadBlockIdx(SDataFReader *pReader, SArray *aBlockIdx);
|
||||
int32_t tsdbReadDataBlk(SDataFReader *pReader, SBlockIdx *pBlockIdx, SMapData *mDataBlk);
|
||||
int32_t tsdbReadSttBlk(SDataFReader *pReader, int32_t iStt, SArray *aSttBlk);
|
||||
int32_t tsdbReadBlockSma(SDataFReader *pReader, SDataBlk *pBlock, SArray *aColumnDataAgg);
|
||||
int32_t tsdbReadDataBlock(SDataFReader *pReader, SDataBlk *pBlock, SBlockData *pBlockData);
|
||||
int32_t tsdbReadDataBlockEx(SDataFReader *pReader, SDataBlk *pDataBlk, SBlockData *pBlockData);
|
||||
int32_t tsdbReadSttBlock(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData);
|
||||
int32_t tsdbReadSttBlockEx(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData);
|
||||
// SDelFReader
|
||||
int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb);
|
||||
int32_t tsdbDelFReaderClose(SDelFReader **ppReader);
|
||||
|
|
@ -279,7 +277,7 @@ int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx);
|
|||
// tsdbRead.c ==============================================================================================
|
||||
int32_t tsdbTakeReadSnap2(STsdbReader *pReader, _query_reseek_func_t reseek, STsdbReadSnap **ppSnap);
|
||||
void tsdbUntakeReadSnap2(STsdbReader *pReader, STsdbReadSnap *pSnap, bool proactive);
|
||||
int32_t tsdbGetTableSchema(SMeta* pMeta, int64_t uid, STSchema** pSchema, int64_t* suid);
|
||||
int32_t tsdbGetTableSchema(SMeta *pMeta, int64_t uid, STSchema **pSchema, int64_t *suid);
|
||||
|
||||
// tsdbMerge.c ==============================================================================================
|
||||
typedef struct {
|
||||
|
|
@ -289,14 +287,6 @@ typedef struct {
|
|||
|
||||
int32_t tsdbMerge(void *arg);
|
||||
|
||||
// tsdbDiskData ==============================================================================================
|
||||
int32_t tDiskDataBuilderCreate(SDiskDataBuilder **ppBuilder);
|
||||
void *tDiskDataBuilderDestroy(SDiskDataBuilder *pBuilder);
|
||||
int32_t tDiskDataBuilderInit(SDiskDataBuilder *pBuilder, STSchema *pTSchema, TABLEID *pId, uint8_t cmprAlg,
|
||||
uint8_t calcSma);
|
||||
int32_t tDiskDataBuilderClear(SDiskDataBuilder *pBuilder);
|
||||
int32_t tDiskDataAddRow(SDiskDataBuilder *pBuilder, TSDBROW *pRow, STSchema *pTSchema, TABLEID *pId);
|
||||
int32_t tGnrtDiskData(SDiskDataBuilder *pBuilder, const SDiskData **ppDiskData, const SBlkInfo **ppBlkInfo);
|
||||
// tsdbDataIter.c ==============================================================================================
|
||||
#define TSDB_MEM_TABLE_DATA_ITER 0
|
||||
#define TSDB_DATA_FILE_DATA_ITER 1
|
||||
|
|
@ -375,15 +365,6 @@ struct TSDBKEY {
|
|||
};
|
||||
|
||||
typedef struct SMemSkipListNode SMemSkipListNode;
|
||||
struct SMemSkipListNode {
|
||||
int8_t level;
|
||||
int8_t flag; // TSDBROW_ROW_FMT for row format, TSDBROW_COL_FMT for col format
|
||||
int32_t iRow;
|
||||
int64_t version;
|
||||
void *pData;
|
||||
SMemSkipListNode *forwards[0];
|
||||
};
|
||||
|
||||
typedef struct SMemSkipList {
|
||||
int64_t size;
|
||||
uint32_t seed;
|
||||
|
|
@ -437,6 +418,17 @@ struct TSDBROW {
|
|||
};
|
||||
};
|
||||
|
||||
struct SMemSkipListNode {
|
||||
int8_t level;
|
||||
TSDBROW row;
|
||||
SMemSkipListNode *forwards[0];
|
||||
};
|
||||
|
||||
struct STsdbRowKey {
|
||||
SRowKey key;
|
||||
int64_t version;
|
||||
};
|
||||
|
||||
struct SBlockIdx {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
|
|
@ -454,7 +446,7 @@ struct SMapData {
|
|||
struct SBlockCol {
|
||||
int16_t cid;
|
||||
int8_t type;
|
||||
int8_t smaOn;
|
||||
int8_t cflag;
|
||||
int8_t flag; // HAS_NONE|HAS_NULL|HAS_VALUE
|
||||
int32_t szOrigin; // original column value size (only save for variant data type)
|
||||
int32_t szBitmap; // bitmap size, 0 only for flag == HAS_VAL
|
||||
|
|
@ -562,6 +554,10 @@ struct SDiskDataHdr {
|
|||
int32_t szBlkCol;
|
||||
int32_t nRow;
|
||||
int8_t cmprAlg;
|
||||
|
||||
// fmtVer == 1
|
||||
int8_t numOfPKs;
|
||||
SBlockCol primaryBlockCols[TD_MAX_PK_COLS];
|
||||
};
|
||||
|
||||
struct SDelFile {
|
||||
|
|
@ -762,9 +758,11 @@ typedef struct SBlockDataInfo {
|
|||
// todo: move away
|
||||
typedef struct {
|
||||
SArray *pUid;
|
||||
SArray *pFirstTs;
|
||||
SArray *pLastTs;
|
||||
SArray *pCount;
|
||||
SArray *pFirstKey;
|
||||
SArray *pLastKey;
|
||||
SArray *pCount;
|
||||
} SSttTableRowsInfo;
|
||||
|
||||
typedef struct SSttBlockLoadInfo {
|
||||
|
|
@ -840,6 +838,7 @@ struct SLDataIter {
|
|||
STimeWindow timeWindow;
|
||||
SVersionRange verRange;
|
||||
SSttBlockLoadInfo *pBlockLoadInfo;
|
||||
SRowKey* pStartRowKey; // current row key
|
||||
bool ignoreEarlierTs;
|
||||
struct SSttFileReader *pReader;
|
||||
};
|
||||
|
|
@ -850,7 +849,7 @@ struct SSttFileReader;
|
|||
typedef int32_t (*_load_tomb_fn)(STsdbReader *pReader, struct SSttFileReader *pSttFileReader,
|
||||
SSttBlockLoadInfo *pLoadInfo);
|
||||
|
||||
typedef struct {
|
||||
typedef struct SMergeTreeConf {
|
||||
int8_t backward;
|
||||
STsdb *pTsdb;
|
||||
uint64_t suid;
|
||||
|
|
@ -863,6 +862,7 @@ typedef struct {
|
|||
STSchema *pSchema;
|
||||
int16_t *pCols;
|
||||
int32_t numOfCols;
|
||||
SRowKey *pCurRowKey;
|
||||
_load_tomb_fn loadTombFn;
|
||||
void *pReader;
|
||||
void *idstr;
|
||||
|
|
@ -870,7 +870,7 @@ typedef struct {
|
|||
} SMergeTreeConf;
|
||||
|
||||
typedef struct SSttDataInfoForTable {
|
||||
SArray *pTimeWindowList;
|
||||
SArray *pKeyRangeList;
|
||||
int64_t numOfRows;
|
||||
} SSttDataInfoForTable;
|
||||
|
||||
|
|
@ -893,11 +893,18 @@ typedef enum {
|
|||
} EExecMode;
|
||||
|
||||
typedef struct {
|
||||
TSKEY ts;
|
||||
int64_t version;
|
||||
SRowKey rowKey;
|
||||
int8_t dirty;
|
||||
SColVal colVal;
|
||||
} SLastCol;
|
||||
|
||||
typedef struct {
|
||||
TSKEY ts;
|
||||
int8_t dirty;
|
||||
SColVal colVal;
|
||||
} SLastColV1;
|
||||
|
||||
int32_t tsdbOpenCache(STsdb *pTsdb);
|
||||
void tsdbCloseCache(STsdb *pTsdb);
|
||||
int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *row);
|
||||
|
|
@ -942,34 +949,7 @@ static FORCE_INLINE int32_t tsdbKeyCmprFn(const void *p1, const void *p2) {
|
|||
// #define SL_NODE_FORWARD(n, l) ((n)->forwards[l])
|
||||
// #define SL_NODE_BACKWARD(n, l) ((n)->forwards[(n)->level + (l)])
|
||||
|
||||
static FORCE_INLINE TSDBROW *tsdbTbDataIterGet(STbDataIter *pIter) {
|
||||
if (pIter == NULL) return NULL;
|
||||
|
||||
if (pIter->pRow) {
|
||||
return pIter->pRow;
|
||||
}
|
||||
|
||||
if (pIter->backward) {
|
||||
if (pIter->pNode == pIter->pTbData->sl.pHead) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (pIter->pNode == pIter->pTbData->sl.pTail) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pIter->pRow = &pIter->row;
|
||||
if (pIter->pNode->flag == TSDBROW_ROW_FMT) {
|
||||
pIter->row = tsdbRowFromTSRow(pIter->pNode->version, pIter->pNode->pData);
|
||||
} else if (pIter->pNode->flag == TSDBROW_COL_FMT) {
|
||||
pIter->row = tsdbRowFromBlockData(pIter->pNode->pData, pIter->pNode->iRow);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
return pIter->pRow;
|
||||
}
|
||||
TSDBROW *tsdbTbDataIterGet(STbDataIter *pIter);
|
||||
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
|
|
|
|||
|
|
@ -234,9 +234,9 @@ int32_t tsdbCacheNewTable(STsdb* pTsdb, int64_t uid, tb_uid_t suid, SSchemaWrapp
|
|||
int32_t tsdbCacheDropTable(STsdb* pTsdb, int64_t uid, tb_uid_t suid, SSchemaWrapper* pSchemaRow);
|
||||
int32_t tsdbCacheDropSubTables(STsdb* pTsdb, SArray* uids, tb_uid_t suid);
|
||||
int32_t tsdbCacheNewSTableColumn(STsdb* pTsdb, SArray* uids, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheDropSTableColumn(STsdb* pTsdb, SArray* uids, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheDropSTableColumn(STsdb* pTsdb, SArray* uids, int16_t cid, bool hasPrimayKey);
|
||||
int32_t tsdbCacheNewNTableColumn(STsdb* pTsdb, int64_t uid, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheDropNTableColumn(STsdb* pTsdb, int64_t uid, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheDropNTableColumn(STsdb* pTsdb, int64_t uid, int16_t cid, bool hasPrimayKey);
|
||||
int32_t tsdbCompact(STsdb* pTsdb, SCompactInfo* pInfo);
|
||||
int32_t tsdbRetention(STsdb* tsdb, int64_t now, int32_t sync);
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb* pTsdb, SSubmitReq2* pMsg);
|
||||
|
|
|
|||
|
|
@ -468,6 +468,20 @@ int32_t setForSnapShot(SSnapContext* ctx, int64_t uid) {
|
|||
return c;
|
||||
}
|
||||
|
||||
void taosXSetTablePrimaryKey(SSnapContext* ctx, int64_t uid){
|
||||
bool ret = false;
|
||||
SSchemaWrapper *schema = metaGetTableSchema(ctx->pMeta, uid, -1, 1);
|
||||
if (schema->nCols >= 2 && schema->pSchema[1].flags & COL_IS_KEY){
|
||||
ret = true;
|
||||
}
|
||||
tDeleteSchemaWrapper(schema);
|
||||
ctx->hasPrimaryKey = ret;
|
||||
}
|
||||
|
||||
bool taosXGetTablePrimaryKey(SSnapContext* ctx){
|
||||
return ctx->hasPrimaryKey;
|
||||
}
|
||||
|
||||
int32_t getTableInfoFromSnapshot(SSnapContext* ctx, void** pBuf, int32_t* contLen, int16_t* type, int64_t* uid) {
|
||||
int32_t ret = 0;
|
||||
void* pKey = NULL;
|
||||
|
|
|
|||
|
|
@ -449,18 +449,20 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
tsdbCacheNewSTableColumn(pTsdb, uids, cid, col_type);
|
||||
} else if (deltaCol == -1) {
|
||||
int16_t cid = -1;
|
||||
int8_t col_type = -1;
|
||||
bool hasPrimaryKey = false;
|
||||
if (onCols >= 2) {
|
||||
hasPrimaryKey = (oStbEntry.stbEntry.schemaRow.pSchema[1].flags & COL_IS_KEY) ? true : false;
|
||||
}
|
||||
for (int i = 0, j = 0; i < nCols && j < onCols; ++i, ++j) {
|
||||
if (pReq->schemaRow.pSchema[i].colId != oStbEntry.stbEntry.schemaRow.pSchema[j].colId) {
|
||||
cid = oStbEntry.stbEntry.schemaRow.pSchema[j].colId;
|
||||
col_type = oStbEntry.stbEntry.schemaRow.pSchema[j].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cid != -1) {
|
||||
metaGetSubtables(pMeta, pReq->suid, uids);
|
||||
tsdbCacheDropSTableColumn(pTsdb, uids, cid, col_type);
|
||||
tsdbCacheDropSTableColumn(pTsdb, uids, cid, hasPrimaryKey);
|
||||
}
|
||||
}
|
||||
if (uids) taosArrayDestroy(uids);
|
||||
|
|
@ -1478,6 +1480,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
|
|||
terrno = TSDB_CODE_VND_COL_SUBSCRIBED;
|
||||
goto _err;
|
||||
}
|
||||
bool hasPrimayKey = false;
|
||||
if (pSchema->nCols >= 2) {
|
||||
hasPrimayKey = pSchema->pSchema[1].flags & COL_IS_KEY ? true : false;
|
||||
}
|
||||
|
||||
pSchema->version++;
|
||||
tlen = (pSchema->nCols - iCol - 1) * sizeof(SSchema);
|
||||
if (tlen) {
|
||||
|
|
@ -1489,9 +1496,8 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
|
|||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
int16_t cid = pColumn->colId;
|
||||
int8_t col_type = pColumn->type;
|
||||
|
||||
(void)tsdbCacheDropNTableColumn(pMeta->pVnode->pTsdb, entry.uid, cid, col_type);
|
||||
(void)tsdbCacheDropNTableColumn(pMeta->pVnode->pTsdb, entry.uid, cid, hasPrimayKey);
|
||||
}
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
|
||||
|
|
|
|||
|
|
@ -187,10 +187,12 @@ int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
SMqVgOffset vgOffset = {0};
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
int32_t code = 0;
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, msgLen);
|
||||
if (tDecodeMqVgOffset(&decoder, &vgOffset) < 0) {
|
||||
return -1;
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
|
@ -205,22 +207,28 @@ int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
pOffset->val.version);
|
||||
} else {
|
||||
tqError("invalid commit offset type:%d", pOffset->val.type);
|
||||
return -1;
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey);
|
||||
if (pSavedOffset != NULL && tqOffsetEqual(pOffset, pSavedOffset)) {
|
||||
tqInfo("not update the offset, vgId:%d sub:%s since committed:%" PRId64 " less than/equal to existed:%" PRId64,
|
||||
vgId, pOffset->subKey, pOffset->val.version, pSavedOffset->val.version);
|
||||
return 0; // no need to update the offset value
|
||||
goto end; // no need to update the offset value
|
||||
}
|
||||
|
||||
// save the new offset value
|
||||
if (tqOffsetWrite(pTq->pOffsetStore, pOffset) < 0) {
|
||||
return -1;
|
||||
code = tqOffsetWrite(pTq->pOffsetStore, pOffset);
|
||||
if(code != 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
return 0;
|
||||
end:
|
||||
tOffsetDestroy(&vgOffset.offset.val);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tqProcessSeekReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
|
|
@ -326,11 +334,11 @@ int32_t tqProcessPollPush(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SMqPollReq req = {0};
|
||||
int code = 0;
|
||||
if (tDeserializeSMqPollReq(pMsg->pCont, pMsg->contLen, &req) < 0) {
|
||||
int code = tDeserializeSMqPollReq(pMsg->pCont, pMsg->contLen, &req);
|
||||
if (code < 0) {
|
||||
tqError("tDeserializeSMqPollReq %d failed", pMsg->contLen);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
int64_t consumerId = req.consumerId;
|
||||
|
|
@ -354,7 +362,8 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqError("tmq poll: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", consumerId, vgId, req.subKey);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
code = -1;
|
||||
goto END;
|
||||
} while (0);
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +374,8 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
consumerId, TD_VID(pTq->pVnode), req.subKey, pHandle->consumerId);
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
code = -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
bool exec = tqIsHandleExec(pHandle);
|
||||
|
|
@ -402,6 +412,9 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 " vgId:%d, topic:%s, set handle idle, pHandle:%p", consumerId, vgId,
|
||||
req.subKey, pHandle);
|
||||
|
||||
END:
|
||||
tDestroySMqPollReq(&req);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -420,8 +433,7 @@ int32_t tqProcessVgCommittedInfoReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
STqOffset* pOffset = &vgOffset.offset;
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey);
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, vgOffset.offset.subKey);
|
||||
if (pSavedOffset == NULL) {
|
||||
terrno = TSDB_CODE_TMQ_NO_COMMITTED;
|
||||
return terrno;
|
||||
|
|
@ -1181,7 +1193,6 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// ASSERT(status == TASK_STATUS__HALT);
|
||||
if (status != TASK_STATUS__HALT) {
|
||||
tqError("s-task:%s should in halt status, let's halt it directly", pTask->id.idStr);
|
||||
// streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_HALT);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
STqOffset offset;
|
||||
STqOffset offset = {0};
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, pMemBuf, size);
|
||||
if (tDecodeSTqOffset(&decoder, &offset) < 0) {
|
||||
|
|
@ -108,6 +108,7 @@ STqOffsetStore* tqOffsetOpen(STQ* pTq) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
taosHashSetFreeFp(pStore->pHash, tOffsetDestroy);
|
||||
char* fname = tqOffsetBuildFName(pStore->pTq->path, 0);
|
||||
if (tqOffsetRestoreFromFile(pStore, fname) < 0) {
|
||||
taosMemoryFree(fname);
|
||||
|
|
|
|||
|
|
@ -247,6 +247,20 @@ END:
|
|||
return code;
|
||||
}
|
||||
|
||||
bool tqGetTablePrimaryKey(STqReader* pReader){
|
||||
return pReader->hasPrimaryKey;
|
||||
}
|
||||
|
||||
void tqSetTablePrimaryKey(STqReader* pReader, int64_t uid){
|
||||
bool ret = false;
|
||||
SSchemaWrapper *schema = metaGetTableSchema(pReader->pVnodeMeta, uid, -1, 1);
|
||||
if (schema->nCols >= 2 && schema->pSchema[1].flags & COL_IS_KEY){
|
||||
ret = true;
|
||||
}
|
||||
tDeleteSchemaWrapper(schema);
|
||||
pReader->hasPrimaryKey = ret;
|
||||
}
|
||||
|
||||
STqReader* tqReaderOpen(SVnode* pVnode) {
|
||||
STqReader* pReader = taosMemoryCalloc(1, sizeof(STqReader));
|
||||
if (pReader == NULL) {
|
||||
|
|
@ -578,7 +592,7 @@ static int32_t buildResSDataBlock(SSDataBlock* pBlock, SSchemaWrapper* pSchema,
|
|||
static int32_t doSetVal(SColumnInfoData* pColumnInfoData, int32_t rowIndex, SColVal* pColVal) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (IS_STR_DATA_TYPE(pColVal->type)) {
|
||||
if (IS_STR_DATA_TYPE(pColVal->value.type)) {
|
||||
char val[65535 + 2] = {0};
|
||||
if (COL_VAL_IS_VALUE(pColVal)) {
|
||||
if (pColVal->value.pData != NULL) {
|
||||
|
|
|
|||
|
|
@ -80,8 +80,6 @@ int32_t getDataBlock(qTaskInfo_t task, const STqHandle* pHandle, int32_t vgId, S
|
|||
}
|
||||
|
||||
int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset, const SMqPollReq* pRequest) {
|
||||
const int32_t MAX_ROWS_TO_RETURN = 4096;
|
||||
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
int32_t code = 0;
|
||||
int32_t totalRows = 0;
|
||||
|
|
@ -113,9 +111,8 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
|
|||
STqOffsetVal offset = {0};
|
||||
qStreamExtractOffset(task, &offset);
|
||||
pHandle->block = createOneDataBlock(pDataBlock, true);
|
||||
// pHandle->block = createDataBlock();
|
||||
// copyDataBlock(pHandle->block, pDataBlock);
|
||||
pHandle->blockTime = offset.ts;
|
||||
tOffsetDestroy(&offset);
|
||||
code = getDataBlock(task, pHandle, vgId, &pDataBlock);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
|
|
@ -139,6 +136,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
|
|||
qStreamExtractOffset(task, &offset);
|
||||
pRsp->sleepTime = offset.ts - pHandle->blockTime;
|
||||
pHandle->blockTime = offset.ts;
|
||||
tOffsetDestroy(&offset);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -153,7 +151,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
|
|||
|
||||
pRsp->blockNum++;
|
||||
totalRows += pDataBlock->info.rows;
|
||||
if (totalRows >= MAX_ROWS_TO_RETURN) {
|
||||
if (totalRows >= tmqRowSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -215,7 +213,7 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMeta
|
|||
continue;
|
||||
} else {
|
||||
rowCnt += pDataBlock->info.rows;
|
||||
if (rowCnt <= 4096) continue;
|
||||
if (rowCnt <= tmqRowSize) continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ int32_t doBuildAndSendSubmitMsg(SVnode* pVnode, SStreamTask* pTask, SSubmitReq2*
|
|||
int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, const char* id) {
|
||||
int32_t oldLen = taosArrayGetSize(pExisted->aRowP);
|
||||
int32_t newLen = taosArrayGetSize(pNew->aRowP);
|
||||
int32_t numOfPk = 0;
|
||||
|
||||
int32_t j = 0, k = 0;
|
||||
SArray* pFinal = taosArrayInit(oldLen + newLen, POINTER_BYTES);
|
||||
|
|
@ -335,17 +336,40 @@ int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, c
|
|||
while (j < newLen && k < oldLen) {
|
||||
SRow* pNewRow = taosArrayGetP(pNew->aRowP, j);
|
||||
SRow* pOldRow = taosArrayGetP(pExisted->aRowP, k);
|
||||
if (pNewRow->ts <= pOldRow->ts) {
|
||||
if (pNewRow->ts < pOldRow->ts) {
|
||||
taosArrayPush(pFinal, &pNewRow);
|
||||
j += 1;
|
||||
|
||||
if (pNewRow->ts == pOldRow->ts) {
|
||||
k += 1;
|
||||
tRowDestroy(pOldRow);
|
||||
}
|
||||
} else {
|
||||
} else if (pNewRow->ts > pOldRow->ts) {
|
||||
taosArrayPush(pFinal, &pOldRow);
|
||||
k += 1;
|
||||
} else {
|
||||
// check for the existance of primary key
|
||||
if (pNewRow->numOfPKs == 0) {
|
||||
taosArrayPush(pFinal, &pNewRow);
|
||||
k += 1;
|
||||
j += 1;
|
||||
tRowDestroy(pOldRow);
|
||||
} else {
|
||||
numOfPk = pNewRow->numOfPKs;
|
||||
|
||||
SRowKey kNew, kOld;
|
||||
tRowGetKey(pNewRow, &kNew);
|
||||
tRowGetKey(pOldRow, &kOld);
|
||||
|
||||
int32_t ret = tRowKeyCompare(&kNew, &kOld);
|
||||
if (ret <= 0) {
|
||||
taosArrayPush(pFinal, &pNewRow);
|
||||
j += 1;
|
||||
|
||||
if (ret == 0) {
|
||||
k += 1;
|
||||
tRowDestroy(pOldRow);
|
||||
}
|
||||
} else {
|
||||
taosArrayPush(pFinal, &pOldRow);
|
||||
k += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,8 +387,8 @@ int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, c
|
|||
taosArrayDestroy(pExisted->aRowP);
|
||||
pExisted->aRowP = pFinal;
|
||||
|
||||
tqTrace("s-task:%s rows merged, final rows:%d, uid:%" PRId64 ", existed auto-create table:%d, new-block:%d", id,
|
||||
(int32_t)taosArrayGetSize(pFinal), pExisted->uid, (pExisted->pCreateTbReq != NULL),
|
||||
tqTrace("s-task:%s rows merged, final rows:%d, pk:%d uid:%" PRId64 ", existed auto-create table:%d, new-block:%d",
|
||||
id, (int32_t)taosArrayGetSize(pFinal), numOfPk, pExisted->uid, (pExisted->pCreateTbReq != NULL),
|
||||
(pNew->pCreateTbReq != NULL));
|
||||
|
||||
tdDestroySVCreateTbReq(pNew->pCreateTbReq);
|
||||
|
|
@ -546,20 +570,35 @@ int32_t doConvertRows(SSubmitTbData* pTableData, const STSchema* pTSchema, SSDat
|
|||
taosArrayClear(pVals);
|
||||
|
||||
int32_t dataIndex = 0;
|
||||
int64_t ts = 0;
|
||||
|
||||
for (int32_t k = 0; k < pTSchema->numOfCols; k++) {
|
||||
const STColumn* pCol = &pTSchema->columns[k];
|
||||
|
||||
// primary timestamp column, for debug purpose
|
||||
if (k == 0) {
|
||||
SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex);
|
||||
void* colData = colDataGetData(pColData, j);
|
||||
tqTrace("s-task:%s sink row %d, col %d ts %" PRId64, id, j, k, *(int64_t*)colData);
|
||||
ts = *(int64_t*)colDataGetData(pColData, j);
|
||||
tqTrace("s-task:%s sink row %d, col %d ts %" PRId64, id, j, k, ts);
|
||||
}
|
||||
|
||||
if (IS_SET_NULL(pCol)) {
|
||||
if (pCol->flags & COL_IS_KEY) {
|
||||
qError("ts:%" PRId64 " Primary key column should not be null, colId:%" PRIi16 ", colType:%" PRIi8, ts,
|
||||
pCol->colId, pCol->type);
|
||||
break;
|
||||
}
|
||||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex);
|
||||
if (colDataIsNull_s(pColData, j)) {
|
||||
if (pCol->flags & COL_IS_KEY) {
|
||||
qError("ts:%" PRId64 "Primary key column should not be null, colId:%" PRIi16 ", colType:%" PRIi8,
|
||||
ts, pCol->colId, pCol->type);
|
||||
break;
|
||||
}
|
||||
|
||||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
dataIndex++;
|
||||
|
|
@ -567,13 +606,14 @@ int32_t doConvertRows(SSubmitTbData* pTableData, const STSchema* pTSchema, SSDat
|
|||
void* colData = colDataGetData(pColData, j);
|
||||
if (IS_STR_DATA_TYPE(pCol->type)) {
|
||||
// address copy, no value
|
||||
SValue sv = (SValue){.nData = varDataLen(colData), .pData = (uint8_t*)varDataVal(colData)};
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
SValue sv =
|
||||
(SValue){.type = pCol->type, .nData = varDataLen(colData), .pData = (uint8_t*)varDataVal(colData)};
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
SValue sv;
|
||||
SValue sv = {.type = pCol->type};
|
||||
memcpy(&sv.val, colData, tDataTypes[pCol->type].bytes);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
dataIndex++;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ static int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const
|
|||
const SMqMetaRsp* pRsp, int32_t vgId);
|
||||
|
||||
int32_t tqInitDataRsp(SMqDataRsp* pRsp, STqOffsetVal pOffset) {
|
||||
pRsp->reqOffset = pOffset;
|
||||
pRsp->rspOffset = pOffset;
|
||||
tOffsetCopy(&pRsp->reqOffset, &pOffset);
|
||||
tOffsetCopy(&pRsp->rspOffset, &pOffset);
|
||||
|
||||
pRsp->blockData = taosArrayInit(0, sizeof(void*));
|
||||
pRsp->blockDataLen = taosArrayInit(0, sizeof(int32_t));
|
||||
|
|
@ -40,8 +40,8 @@ void tqUpdateNodeStage(STQ* pTq, bool isLeader) {
|
|||
}
|
||||
|
||||
static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, STqOffsetVal pOffset) {
|
||||
pRsp->reqOffset = pOffset;
|
||||
pRsp->rspOffset = pOffset;
|
||||
tOffsetCopy(&pRsp->reqOffset, &pOffset);
|
||||
tOffsetCopy(&pRsp->rspOffset, &pOffset);
|
||||
|
||||
pRsp->withTbName = 1;
|
||||
pRsp->withSchema = 1;
|
||||
|
|
@ -81,7 +81,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
*pBlockReturned = false;
|
||||
// In this vnode, data has been polled by consumer for this topic, so let's continue from the last offset value.
|
||||
if (pOffset != NULL) {
|
||||
*pOffsetVal = pOffset->val;
|
||||
tOffsetCopy(pOffsetVal, &pOffset->val);
|
||||
|
||||
char formatBuf[TSDB_OFFSET_LEN] = {0};
|
||||
tFormatOffset(formatBuf, TSDB_OFFSET_LEN, pOffsetVal);
|
||||
|
|
@ -98,7 +98,8 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
if (pHandle->fetchMeta) {
|
||||
tqOffsetResetToMeta(pOffsetVal, 0);
|
||||
} else {
|
||||
tqOffsetResetToData(pOffsetVal, 0, 0);
|
||||
SValue val = {0};
|
||||
tqOffsetResetToData(pOffsetVal, 0, 0, val);
|
||||
}
|
||||
} else {
|
||||
walRefFirstVer(pTq->pVnode->pWal, pHandle->pRef);
|
||||
|
|
@ -157,7 +158,7 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
taosWUnLockLatch(&pTq->lock);
|
||||
}
|
||||
|
||||
dataRsp.reqOffset = *pOffset; // reqOffset represents the current date offset, may be changed if wal not exists
|
||||
tOffsetCopy(&dataRsp.reqOffset, pOffset); // reqOffset represents the current date offset, may be changed if wal not exists
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
|
||||
end : {
|
||||
|
|
@ -207,7 +208,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
",ts:%" PRId64,
|
||||
pRequest->consumerId, pHandle->subKey, vgId, metaRsp.rspOffset.type, metaRsp.rspOffset.uid,
|
||||
metaRsp.rspOffset.ts);
|
||||
taosMemoryFree(metaRsp.metaRsp);
|
||||
tDeleteMqMetaRsp(&metaRsp);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +220,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
goto end;
|
||||
} else {
|
||||
*offset = taosxRsp.rspOffset;
|
||||
tOffsetCopy(offset, &taosxRsp.rspOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +291,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (totalRows >= 4096 || (taosGetTimestampMs() - st > 1000)) {
|
||||
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > 1000)) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1);
|
||||
code = tqSendDataRsp(
|
||||
pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp,
|
||||
|
|
@ -309,33 +310,37 @@ end:
|
|||
}
|
||||
|
||||
int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg) {
|
||||
STqOffsetVal reqOffset = pRequest->reqOffset;
|
||||
int32_t code = 0;
|
||||
STqOffsetVal reqOffset = {0};
|
||||
tOffsetCopy(&reqOffset, &pRequest->reqOffset);
|
||||
|
||||
// 1. reset the offset if needed
|
||||
// reset the offset if needed
|
||||
if (IS_OFFSET_RESET_TYPE(pRequest->reqOffset.type)) {
|
||||
// handle the reset offset cases, according to the consumer's choice.
|
||||
bool blockReturned = false;
|
||||
int32_t code = extractResetOffsetVal(&reqOffset, pTq, pHandle, pRequest, pMsg, &blockReturned);
|
||||
code = extractResetOffsetVal(&reqOffset, pTq, pHandle, pRequest, pMsg, &blockReturned);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
goto END;
|
||||
}
|
||||
|
||||
// empty block returned, quit
|
||||
if (blockReturned) {
|
||||
return 0;
|
||||
goto END;
|
||||
}
|
||||
} else if (reqOffset.type == 0) { // use the consumer specified offset
|
||||
uError("req offset type is 0");
|
||||
return TSDB_CODE_TMQ_INVALID_MSG;
|
||||
code = TSDB_CODE_TMQ_INVALID_MSG;
|
||||
goto END;
|
||||
}
|
||||
|
||||
// this is a normal subscribe requirement
|
||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
return extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &reqOffset);
|
||||
code = extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &reqOffset);
|
||||
} else {
|
||||
// for taosx
|
||||
return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &reqOffset);
|
||||
code = extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &reqOffset);
|
||||
}
|
||||
|
||||
END:
|
||||
tOffsetDestroy(&reqOffset);
|
||||
return code;
|
||||
}
|
||||
|
||||
static void initMqRspHead(SMqRspHead* pMsgHead, int32_t type, int32_t epoch, int64_t consumerId, int64_t sver,
|
||||
|
|
|
|||
|
|
@ -127,12 +127,25 @@ static void tsdbClosePgCache(STsdb *pTsdb) {
|
|||
|
||||
#define ROCKS_KEY_LEN (sizeof(tb_uid_t) + sizeof(int16_t) + sizeof(int8_t))
|
||||
|
||||
enum {
|
||||
LFLAG_LAST_ROW = 0,
|
||||
LFLAG_LAST = 1,
|
||||
LFLAG_PRIMARY_KEY = (1 << 4),
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
tb_uid_t uid;
|
||||
int16_t cid;
|
||||
int8_t ltype;
|
||||
int8_t lflag;
|
||||
} SLastKey;
|
||||
|
||||
#define LAST_COL_VERSION_BASE (((int64_t)(0x1)) << 63)
|
||||
#define LAST_COL_VERSION (LAST_COL_VERSION_BASE + 2)
|
||||
|
||||
#define HAS_PRIMARY_KEY(k) (((k).lflag & LFLAG_PRIMARY_KEY) == LFLAG_PRIMARY_KEY)
|
||||
#define IS_LAST_ROW_KEY(k) (((k).lflag & LFLAG_LAST) == LFLAG_LAST_ROW)
|
||||
#define IS_LAST_KEY(k) (((k).lflag & LFLAG_LAST) == LFLAG_LAST)
|
||||
|
||||
static void tsdbGetRocksPath(STsdb *pTsdb, char *path) {
|
||||
SVnode *pVnode = pTsdb->pVnode;
|
||||
vnodeGetPrimaryDir(pTsdb->path, pVnode->diskPrimary, pVnode->pTfs, path, TSDB_FILENAME_LEN);
|
||||
|
|
@ -167,9 +180,9 @@ static int myCmp(void *state, const char *a, size_t alen, const char *b, size_t
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (lhs->ltype < rhs->ltype) {
|
||||
if (lhs->lflag < rhs->lflag) {
|
||||
return -1;
|
||||
} else if (lhs->ltype > rhs->ltype) {
|
||||
} else if (lhs->lflag > rhs->lflag) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -322,16 +335,63 @@ static void rocksMayWrite(STsdb *pTsdb, bool force, bool read, bool lock) {
|
|||
}
|
||||
}
|
||||
|
||||
static SLastCol *tsdbCacheDeserialize(char const *value) {
|
||||
// note: new object do not own colVal's resource, just copy the pointer
|
||||
static SLastCol *tsdbCacheConvertLastColV1(SLastColV1 *pLastColV1) {
|
||||
SLastCol *pLastCol = taosMemoryCalloc(1, sizeof(SLastCol));
|
||||
if (pLastCol == NULL) return NULL;
|
||||
pLastCol->version = LAST_COL_VERSION;
|
||||
pLastCol->rowKey.ts = pLastColV1->ts;
|
||||
pLastCol->rowKey.numOfPKs = 0;
|
||||
pLastCol->dirty = pLastColV1->dirty;
|
||||
pLastCol->colVal = pLastColV1->colVal;
|
||||
|
||||
return pLastCol;
|
||||
}
|
||||
|
||||
static SLastCol *tsdbCacheDeserializeV1(char const *value) {
|
||||
if (!value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLastCol *pLastCol = (SLastCol *)value;
|
||||
SColVal *pColVal = &pLastCol->colVal;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
SLastColV1 *pLastColV1 = (SLastColV1 *)value;
|
||||
SColVal *pColVal = &pLastColV1->colVal;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
if (pColVal->value.nData > 0) {
|
||||
pColVal->value.pData = (char *)value + sizeof(*pLastCol);
|
||||
pColVal->value.pData = (char *)value + sizeof(*pLastColV1);
|
||||
} else {
|
||||
pColVal->value.pData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return tsdbCacheConvertLastColV1(pLastColV1);
|
||||
}
|
||||
|
||||
static SLastCol *tsdbCacheDeserializeV2(char const *value) {
|
||||
if (!value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLastCol *pLastCol = taosMemoryMalloc(sizeof(SLastCol));
|
||||
*pLastCol = *(SLastCol *)(value);
|
||||
|
||||
char* currentPos = (char *)value + sizeof(*pLastCol);
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue* pValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
if (pValue->nData > 0) {
|
||||
pValue->pData = currentPos;
|
||||
currentPos += pValue->nData;
|
||||
} else {
|
||||
pValue->pData = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SColVal *pColVal = &pLastCol->colVal;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
if (pColVal->value.nData > 0) {
|
||||
pColVal->value.pData = currentPos;
|
||||
currentPos += pColVal->value.nData;
|
||||
} else {
|
||||
pColVal->value.pData = NULL;
|
||||
}
|
||||
|
|
@ -340,25 +400,65 @@ static SLastCol *tsdbCacheDeserialize(char const *value) {
|
|||
return pLastCol;
|
||||
}
|
||||
|
||||
static SLastCol *tsdbCacheDeserialize(char const *value) {
|
||||
if (!value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool hasVersion = ((*(int64_t *)value) & LAST_COL_VERSION_BASE) == LAST_COL_VERSION_BASE;
|
||||
if (!hasVersion) {
|
||||
return tsdbCacheDeserializeV1(value);
|
||||
}
|
||||
return tsdbCacheDeserializeV2(value);
|
||||
}
|
||||
|
||||
static uint32_t tsdbCacheCopyVarData(SValue *from, SValue *to) {
|
||||
ASSERT(from->nData >= 0);
|
||||
if (from->nData > 0) {
|
||||
memcpy(to->pData, from->pData, from->nData);
|
||||
}
|
||||
to->type = from->type;
|
||||
to->nData = from->nData;
|
||||
return from->nData;
|
||||
}
|
||||
|
||||
static void tsdbCacheSerialize(SLastCol *pLastCol, char **value, size_t *size) {
|
||||
SColVal *pColVal = &pLastCol->colVal;
|
||||
size_t length = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->rowKey.pks[i].type)) {
|
||||
length += pLastCol->rowKey.pks[i].nData;
|
||||
}
|
||||
}
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
length += pColVal->value.nData;
|
||||
}
|
||||
|
||||
// set version
|
||||
*value = taosMemoryMalloc(length);
|
||||
|
||||
*(SLastCol *)(*value) = *pLastCol;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
uint8_t *pVal = pColVal->value.pData;
|
||||
SColVal *pDColVal = &((SLastCol *)(*value))->colVal;
|
||||
pDColVal->value.pData = *value + sizeof(*pLastCol);
|
||||
if (pColVal->value.nData > 0) {
|
||||
memcpy(pDColVal->value.pData, pVal, pColVal->value.nData);
|
||||
} else {
|
||||
pDColVal->value.pData = NULL;
|
||||
// copy last col
|
||||
SLastCol* pToLastCol = (SLastCol *)(*value);
|
||||
*pToLastCol = *pLastCol;
|
||||
char *currentPos = *value + sizeof(*pLastCol);
|
||||
|
||||
// copy var data pks
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue *pFromValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pFromValue->type)) {
|
||||
SValue *pToValue = &pToLastCol->rowKey.pks[i];
|
||||
pToValue->pData = (pFromValue->nData == 0) ? NULL : currentPos;
|
||||
currentPos += tsdbCacheCopyVarData(pFromValue, pToValue);
|
||||
}
|
||||
}
|
||||
|
||||
// copy var data value
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
SValue *pFromValue = &pColVal->value;
|
||||
SValue *pToValue = &pToLastCol->colVal.value;
|
||||
pToValue->pData = (pFromValue->nData == 0) ? NULL : currentPos;
|
||||
currentPos += tsdbCacheCopyVarData(pFromValue, pToValue);
|
||||
}
|
||||
*size = length;
|
||||
}
|
||||
|
||||
|
|
@ -433,18 +533,22 @@ int32_t tsdbCacheCommit(STsdb *pTsdb) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static void reallocVarData(SColVal *pColVal) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
uint8_t *pVal = pColVal->value.pData;
|
||||
if (pColVal->value.nData > 0) {
|
||||
pColVal->value.pData = taosMemoryMalloc(pColVal->value.nData);
|
||||
memcpy(pColVal->value.pData, pVal, pColVal->value.nData);
|
||||
static void reallocVarDataVal(SValue *pValue) {
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
uint8_t *pVal = pValue->pData;
|
||||
if (pValue->nData > 0) {
|
||||
pValue->pData = taosMemoryMalloc(pValue->nData);
|
||||
memcpy(pValue->pData, pVal, pValue->nData);
|
||||
} else {
|
||||
pColVal->value.pData = NULL;
|
||||
pValue->pData = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reallocVarData(SColVal *pColVal) {
|
||||
reallocVarDataVal(&pColVal->value);
|
||||
}
|
||||
|
||||
static void tsdbCacheDeleter(const void *key, size_t klen, void *value, void *ud) {
|
||||
SLastCol *pLastCol = (SLastCol *)value;
|
||||
|
||||
|
|
@ -452,32 +556,45 @@ static void tsdbCacheDeleter(const void *key, size_t klen, void *value, void *ud
|
|||
tsdbCachePutBatch(pLastCol, key, klen, (SCacheFlushState *)ud);
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type) /* && pLastCol->colVal.value.nData > 0*/) {
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.value.type) /* && pLastCol->colVal.value.nData > 0*/) {
|
||||
taosMemoryFree(pLastCol->colVal.value.pData);
|
||||
}
|
||||
|
||||
taosMemoryFree(value);
|
||||
}
|
||||
|
||||
static int32_t tsdbCacheNewTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type, int8_t ltype) {
|
||||
static int32_t tsdbCacheNewTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type, int8_t lflag) {
|
||||
int32_t code = 0;
|
||||
|
||||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
rocksdb_writebatch_t *wb = pTsdb->rCache.writebatch;
|
||||
SLastCol noneCol = {.ts = TSKEY_MIN, .colVal = COL_VAL_NONE(cid, col_type), .dirty = 1};
|
||||
SLastCol *pLastCol = &noneCol;
|
||||
SRowKey noneRowKey = {0};
|
||||
noneRowKey.ts = TSKEY_MIN;
|
||||
noneRowKey.numOfPKs = 0;
|
||||
SLastCol noneCol = {
|
||||
.version = LAST_COL_VERSION, .rowKey = noneRowKey, .colVal = COL_VAL_NONE(cid, col_type), .dirty = 1};
|
||||
SLastCol *pLastCol = &noneCol;
|
||||
|
||||
SLastCol *pTmpLastCol = taosMemoryCalloc(1, sizeof(SLastCol));
|
||||
*pTmpLastCol = *pLastCol;
|
||||
pLastCol = pTmpLastCol;
|
||||
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
size_t charge = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type)) {
|
||||
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue *pValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
reallocVarDataVal(pValue);
|
||||
charge += pValue->nData;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.value.type)) {
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
charge += pLastCol->colVal.value.nData;
|
||||
}
|
||||
|
||||
SLastKey *pLastKey = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
SLastKey *pLastKey = &(SLastKey){.lflag = lflag, .uid = uid, .cid = cid};
|
||||
LRUStatus status = taosLRUCacheInsert(pCache, pLastKey, ROCKS_KEY_LEN, pLastCol, charge, tsdbCacheDeleter, NULL,
|
||||
TAOS_LRU_PRIORITY_LOW, &pTsdb->flushState);
|
||||
if (status != TAOS_LRU_STATUS_OK) {
|
||||
|
|
@ -519,7 +636,7 @@ int32_t tsdbCacheCommitNoLock(STsdb *pTsdb) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type, int8_t ltype) {
|
||||
static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, bool hasPrimaryKey) {
|
||||
int32_t code = 0;
|
||||
|
||||
// build keys & multi get from rocks
|
||||
|
|
@ -527,9 +644,11 @@ static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid,
|
|||
size_t *keys_list_sizes = taosMemoryCalloc(2, sizeof(size_t));
|
||||
const size_t klen = ROCKS_KEY_LEN;
|
||||
|
||||
int8_t lflag = hasPrimaryKey ? LFLAG_PRIMARY_KEY : 0;
|
||||
|
||||
char *keys = taosMemoryCalloc(2, sizeof(SLastKey));
|
||||
((SLastKey *)keys)[0] = (SLastKey){.ltype = 1, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[1] = (SLastKey){.ltype = 0, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[0] = (SLastKey){.lflag = lflag | LFLAG_LAST, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[1] = (SLastKey){.lflag = lflag | LFLAG_LAST_ROW, .uid = uid, .cid = cid};
|
||||
|
||||
keys_list[0] = keys;
|
||||
keys_list[1] = keys + sizeof(SLastKey);
|
||||
|
|
@ -557,10 +676,13 @@ static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid,
|
|||
if (NULL != pLastCol) {
|
||||
rocksdb_writebatch_delete(wb, keys_list[0], klen);
|
||||
}
|
||||
taosMemoryFreeClear(pLastCol);
|
||||
|
||||
pLastCol = tsdbCacheDeserialize(values_list[1]);
|
||||
if (NULL != pLastCol) {
|
||||
rocksdb_writebatch_delete(wb, keys_list[1], klen);
|
||||
}
|
||||
taosMemoryFreeClear(pLastCol);
|
||||
|
||||
rocksdb_free(values_list[0]);
|
||||
rocksdb_free(values_list[1]);
|
||||
|
|
@ -568,9 +690,7 @@ static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid,
|
|||
bool erase = false;
|
||||
LRUHandle *h = taosLRUCacheLookup(pTsdb->lruCache, keys_list[0], klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pTsdb->lruCache, h);
|
||||
erase = true;
|
||||
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
}
|
||||
if (erase) {
|
||||
|
|
@ -580,9 +700,7 @@ static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid,
|
|||
erase = false;
|
||||
h = taosLRUCacheLookup(pTsdb->lruCache, keys_list[1], klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pTsdb->lruCache, h);
|
||||
erase = true;
|
||||
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
}
|
||||
if (erase) {
|
||||
|
|
@ -606,13 +724,18 @@ int32_t tsdbCacheNewTable(STsdb *pTsdb, tb_uid_t uid, tb_uid_t suid, SSchemaWrap
|
|||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
if (suid < 0) {
|
||||
int nCols = pSchemaRow->nCols;
|
||||
int8_t lflag = 0;
|
||||
int nCols = pSchemaRow->nCols;
|
||||
if (nCols >= 2) {
|
||||
lflag = (pSchemaRow->pSchema[1].flags & COL_IS_KEY) ? LFLAG_PRIMARY_KEY : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pSchemaRow->pSchema[i].colId;
|
||||
int8_t col_type = pSchemaRow->pSchema[i].type;
|
||||
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, lflag | LFLAG_LAST_ROW);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, lflag | LFLAG_LAST);
|
||||
}
|
||||
} else {
|
||||
STSchema *pTSchema = NULL;
|
||||
|
|
@ -622,13 +745,18 @@ int32_t tsdbCacheNewTable(STsdb *pTsdb, tb_uid_t uid, tb_uid_t suid, SSchemaWrap
|
|||
return -1;
|
||||
}
|
||||
|
||||
int nCols = pTSchema->numOfCols;
|
||||
int8_t lflag = 0;
|
||||
int nCols = pTSchema->numOfCols;
|
||||
if (nCols >= 2) {
|
||||
lflag = (pTSchema->columns[1].flags & COL_IS_KEY) ? LFLAG_PRIMARY_KEY : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
int8_t col_type = pTSchema->columns[i].type;
|
||||
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, lflag | LFLAG_LAST_ROW);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, lflag | LFLAG_LAST);
|
||||
}
|
||||
|
||||
taosMemoryFree(pTSchema);
|
||||
|
|
@ -646,14 +774,17 @@ int32_t tsdbCacheDropTable(STsdb *pTsdb, tb_uid_t uid, tb_uid_t suid, SSchemaWra
|
|||
|
||||
(void)tsdbCacheCommitNoLock(pTsdb);
|
||||
|
||||
if (suid < 0) {
|
||||
int nCols = pSchemaRow->nCols;
|
||||
if (pSchemaRow != NULL) {
|
||||
bool hasPrimayKey = false;
|
||||
int nCols = pSchemaRow->nCols;
|
||||
if (nCols >= 2) {
|
||||
hasPrimayKey = (pSchemaRow->pSchema[1].flags & COL_IS_KEY) ? true : false;
|
||||
}
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pSchemaRow->pSchema[i].colId;
|
||||
int8_t col_type = pSchemaRow->pSchema[i].type;
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, hasPrimayKey);
|
||||
}
|
||||
} else {
|
||||
STSchema *pTSchema = NULL;
|
||||
|
|
@ -663,13 +794,16 @@ int32_t tsdbCacheDropTable(STsdb *pTsdb, tb_uid_t uid, tb_uid_t suid, SSchemaWra
|
|||
return -1;
|
||||
}
|
||||
|
||||
int nCols = pTSchema->numOfCols;
|
||||
bool hasPrimayKey = false;
|
||||
int nCols = pTSchema->numOfCols;
|
||||
if (nCols >= 2) {
|
||||
hasPrimayKey = (pTSchema->columns[1].flags & COL_IS_KEY) ? true : false;
|
||||
}
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
int8_t col_type = pTSchema->columns[i].type;
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, hasPrimayKey);
|
||||
}
|
||||
|
||||
taosMemoryFree(pTSchema);
|
||||
|
|
@ -698,13 +832,17 @@ int32_t tsdbCacheDropSubTables(STsdb *pTsdb, SArray *uids, tb_uid_t suid) {
|
|||
for (int i = 0; i < TARRAY_SIZE(uids); ++i) {
|
||||
int64_t uid = ((tb_uid_t *)TARRAY_DATA(uids))[i];
|
||||
|
||||
int nCols = pTSchema->numOfCols;
|
||||
bool hasPrimayKey = false;
|
||||
int nCols = pTSchema->numOfCols;
|
||||
if (nCols >= 2) {
|
||||
hasPrimayKey = (pTSchema->columns[1].flags & COL_IS_KEY) ? true : false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
int8_t col_type = pTSchema->columns[i].type;
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, hasPrimayKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -732,15 +870,14 @@ int32_t tsdbCacheNewNTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheDropNTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type) {
|
||||
int32_t tsdbCacheDropNTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, bool hasPrimayKey) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
(void)tsdbCacheCommitNoLock(pTsdb);
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, hasPrimayKey);
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, true);
|
||||
|
||||
|
|
@ -768,7 +905,7 @@ int32_t tsdbCacheNewSTableColumn(STsdb *pTsdb, SArray *uids, int16_t cid, int8_t
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheDropSTableColumn(STsdb *pTsdb, SArray *uids, int16_t cid, int8_t col_type) {
|
||||
int32_t tsdbCacheDropSTableColumn(STsdb *pTsdb, SArray *uids, int16_t cid, bool hasPrimayKey) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
|
@ -778,8 +915,7 @@ int32_t tsdbCacheDropSTableColumn(STsdb *pTsdb, SArray *uids, int16_t cid, int8_
|
|||
for (int i = 0; i < TARRAY_SIZE(uids); ++i) {
|
||||
int64_t uid = ((tb_uid_t *)TARRAY_DATA(uids))[i];
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, hasPrimayKey);
|
||||
}
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, true);
|
||||
|
|
@ -794,6 +930,59 @@ typedef struct {
|
|||
SLastKey key;
|
||||
} SIdxKey;
|
||||
|
||||
static void tsdbCacheUpdateLastCol(SLastCol *pLastCol, SRowKey *pRowKey, SColVal *pColVal) {
|
||||
uint8_t *pVal = NULL;
|
||||
int nData = 0;
|
||||
|
||||
// update rowkey
|
||||
pLastCol->version = LAST_COL_VERSION;
|
||||
pLastCol->rowKey.ts = pRowKey->ts;
|
||||
pLastCol->rowKey.numOfPKs = pRowKey->numOfPKs;
|
||||
for (int8_t i = 0; i < pRowKey->numOfPKs; i++) {
|
||||
SValue *pPKValue = &pLastCol->rowKey.pks[i];
|
||||
SValue *pNewPKValue = &pRowKey->pks[i];
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pPKValue->type)) {
|
||||
pVal = pPKValue->pData;
|
||||
nData = pPKValue->nData;
|
||||
}
|
||||
*pPKValue = *pNewPKValue;
|
||||
if (IS_VAR_DATA_TYPE(pPKValue->type)) {
|
||||
if (nData < pPKValue->nData) {
|
||||
taosMemoryFree(pVal);
|
||||
pPKValue->pData = taosMemoryCalloc(1, pNewPKValue->nData);
|
||||
} else {
|
||||
pPKValue->pData = pVal;
|
||||
}
|
||||
if (pNewPKValue->nData) {
|
||||
memcpy(pPKValue->pData, pNewPKValue->pData, pNewPKValue->nData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update colval
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
nData = pLastCol->colVal.value.nData;
|
||||
pVal = pLastCol->colVal.value.pData;
|
||||
}
|
||||
pLastCol->colVal = *pColVal;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
if (nData < pColVal->value.nData) {
|
||||
taosMemoryFree(pVal);
|
||||
pLastCol->colVal.value.pData = taosMemoryCalloc(1, pColVal->value.nData);
|
||||
} else {
|
||||
pLastCol->colVal.value.pData = pVal;
|
||||
}
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(pLastCol->colVal.value.pData, pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pLastCol->dirty) {
|
||||
pLastCol->dirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
|
@ -821,46 +1010,27 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
|
||||
// 3, build keys & multi get from rocks
|
||||
int num_keys = TARRAY_SIZE(aColVal);
|
||||
TSKEY keyTs = TSDBROW_TS(pRow);
|
||||
SArray *remainCols = NULL;
|
||||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
|
||||
STsdbRowKey tsdbRowKey = {0};
|
||||
tsdbRowGetKey(pRow, &tsdbRowKey);
|
||||
SRowKey *pRowKey = &tsdbRowKey.key;
|
||||
int8_t lflag = (pRowKey->numOfPKs != 0) ? LFLAG_PRIMARY_KEY : 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
for (int i = 0; i < num_keys; ++i) {
|
||||
SColVal *pColVal = (SColVal *)taosArrayGet(aColVal, i);
|
||||
int16_t cid = pColVal->cid;
|
||||
|
||||
SLastKey *key = &(SLastKey){.ltype = 0, .uid = uid, .cid = cid};
|
||||
SLastKey *key = &(SLastKey){.lflag = lflag | LFLAG_LAST_ROW, .uid = uid, .cid = cid};
|
||||
size_t klen = ROCKS_KEY_LEN;
|
||||
LRUHandle *h = taosLRUCacheLookup(pCache, key, klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pCache, h);
|
||||
|
||||
if (pLastCol->ts <= keyTs) {
|
||||
uint8_t *pVal = NULL;
|
||||
int nData = pLastCol->colVal.value.nData;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
pVal = pLastCol->colVal.value.pData;
|
||||
}
|
||||
pLastCol->ts = keyTs;
|
||||
pLastCol->colVal = *pColVal;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
if (nData < pColVal->value.nData) {
|
||||
taosMemoryFree(pVal);
|
||||
pLastCol->colVal.value.pData = taosMemoryCalloc(1, pColVal->value.nData);
|
||||
} else {
|
||||
pLastCol->colVal.value.pData = pVal;
|
||||
}
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(pLastCol->colVal.value.pData, pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pLastCol->dirty) {
|
||||
pLastCol->dirty = 1;
|
||||
}
|
||||
if (tRowKeyCompare(&pLastCol->rowKey, pRowKey) != 1) {
|
||||
tsdbCacheUpdateLastCol(pLastCol, pRowKey, pColVal);
|
||||
}
|
||||
|
||||
taosLRUCacheRelease(pCache, h, false);
|
||||
} else {
|
||||
if (!remainCols) {
|
||||
|
|
@ -870,36 +1040,13 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
}
|
||||
|
||||
if (COL_VAL_IS_VALUE(pColVal)) {
|
||||
key->ltype = 1;
|
||||
key->lflag = lflag | LFLAG_LAST;
|
||||
LRUHandle *h = taosLRUCacheLookup(pCache, key, klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pCache, h);
|
||||
|
||||
if (pLastCol->ts <= keyTs) {
|
||||
uint8_t *pVal = NULL;
|
||||
int nData = pLastCol->colVal.value.nData;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
pVal = pLastCol->colVal.value.pData;
|
||||
}
|
||||
pLastCol->ts = keyTs;
|
||||
pLastCol->colVal = *pColVal;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
if (nData < pColVal->value.nData) {
|
||||
taosMemoryFree(pVal);
|
||||
pLastCol->colVal.value.pData = taosMemoryCalloc(1, pColVal->value.nData);
|
||||
} else {
|
||||
pLastCol->colVal.value.pData = pVal;
|
||||
}
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(pLastCol->colVal.value.pData, pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pLastCol->dirty) {
|
||||
pLastCol->dirty = 1;
|
||||
}
|
||||
if (tRowKeyCompare(&pLastCol->rowKey, pRowKey) != 1) {
|
||||
tsdbCacheUpdateLastCol(pLastCol, pRowKey, pColVal);
|
||||
}
|
||||
|
||||
taosLRUCacheRelease(pCache, h, false);
|
||||
} else {
|
||||
if (!remainCols) {
|
||||
|
|
@ -942,12 +1089,13 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
// SColVal *pColVal = (SColVal *)taosArrayGet(aColVal, idxKey->idx);
|
||||
|
||||
SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i]);
|
||||
SLastCol *PToFree = pLastCol;
|
||||
|
||||
if (idxKey->key.ltype == 0) {
|
||||
if (NULL == pLastCol || pLastCol->ts <= keyTs) {
|
||||
if (IS_LAST_ROW_KEY(idxKey->key)) {
|
||||
if (NULL == pLastCol || (tRowKeyCompare(&pLastCol->rowKey, pRowKey) != 1)) {
|
||||
char *value = NULL;
|
||||
size_t vlen = 0;
|
||||
tsdbCacheSerialize(&(SLastCol){.ts = keyTs, .colVal = *pColVal}, &value, &vlen);
|
||||
tsdbCacheSerialize(&(SLastCol){.rowKey = *pRowKey, .colVal = *pColVal}, &value, &vlen);
|
||||
// SLastKey key = (SLastKey){.ltype = 0, .uid = uid, .cid = pColVal->cid};
|
||||
taosThreadMutexLock(&pTsdb->rCache.rMutex);
|
||||
|
||||
|
|
@ -960,9 +1108,17 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
*pTmpLastCol = *pLastCol;
|
||||
pLastCol = pTmpLastCol;
|
||||
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
size_t charge = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type)) {
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue *pValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
reallocVarDataVal(pValue);
|
||||
charge += pValue->nData;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.value.type)) {
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
charge += pLastCol->colVal.value.nData;
|
||||
}
|
||||
|
||||
|
|
@ -976,10 +1132,10 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
}
|
||||
} else {
|
||||
if (COL_VAL_IS_VALUE(pColVal)) {
|
||||
if (NULL == pLastCol || pLastCol->ts <= keyTs) {
|
||||
if (NULL == pLastCol || (tRowKeyCompare(&pLastCol->rowKey, pRowKey) != 1)) {
|
||||
char *value = NULL;
|
||||
size_t vlen = 0;
|
||||
tsdbCacheSerialize(&(SLastCol){.ts = keyTs, .colVal = *pColVal}, &value, &vlen);
|
||||
tsdbCacheSerialize(&(SLastCol){.rowKey = *pRowKey, .colVal = *pColVal}, &value, &vlen);
|
||||
// SLastKey key = (SLastKey){.ltype = 1, .uid = uid, .cid = pColVal->cid};
|
||||
taosThreadMutexLock(&pTsdb->rCache.rMutex);
|
||||
|
||||
|
|
@ -992,9 +1148,17 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
*pTmpLastCol = *pLastCol;
|
||||
pLastCol = pTmpLastCol;
|
||||
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
size_t charge = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type)) {
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue *pValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
reallocVarDataVal(pValue);
|
||||
charge += pValue->nData;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.value.type)) {
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
charge += pLastCol->colVal.value.nData;
|
||||
}
|
||||
|
||||
|
|
@ -1009,6 +1173,7 @@ int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow
|
|||
}
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(PToFree);
|
||||
rocksdb_free(values_list[i]);
|
||||
}
|
||||
|
||||
|
|
@ -1221,7 +1386,7 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
|
||||
SIdxKey *idxKey = taosArrayGet(remainCols, 0);
|
||||
if (idxKey->key.cid != PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
SLastKey *key = &(SLastKey){.ltype = ltype, .uid = uid, .cid = PRIMARYKEY_TIMESTAMP_COL_ID};
|
||||
SLastKey *key = &(SLastKey){.lflag = ltype, .uid = uid, .cid = PRIMARYKEY_TIMESTAMP_COL_ID};
|
||||
|
||||
taosArrayInsert(remainCols, 0, &(SIdxKey){0, *key});
|
||||
}
|
||||
|
|
@ -1244,7 +1409,7 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
for (int i = 0; i < num_keys; ++i) {
|
||||
SIdxKey *idxKey = taosArrayGet(remainCols, i);
|
||||
slotIds[i] = pr->pSlotIds[idxKey->idx];
|
||||
if (idxKey->key.ltype == CACHESCAN_RETRIEVE_LAST >> 3) {
|
||||
if (idxKey->key.lflag == CACHESCAN_RETRIEVE_LAST >> 3) {
|
||||
if (NULL == lastTmpIndexArray) {
|
||||
lastTmpIndexArray = taosArrayInit(num_keys, sizeof(int32_t));
|
||||
}
|
||||
|
|
@ -1290,7 +1455,8 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
}
|
||||
|
||||
// still null, then make up a none col value
|
||||
SLastCol noneCol = {.ts = TSKEY_MIN,
|
||||
SLastCol noneCol = {.version = LAST_COL_VERSION,
|
||||
.rowKey.ts = TSKEY_MIN,
|
||||
.colVal = COL_VAL_NONE(idxKey->key.cid, pr->pSchema->columns[slotIds[i]].type)};
|
||||
if (!pLastCol) {
|
||||
pLastCol = &noneCol;
|
||||
|
|
@ -1308,9 +1474,16 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
*pTmpLastCol = *pLastCol;
|
||||
pLastCol = pTmpLastCol;
|
||||
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
size_t charge = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type)) {
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue *pValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
reallocVarDataVal(pValue);
|
||||
charge += pValue->nData;
|
||||
}
|
||||
}
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.value.type)) {
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
charge += pLastCol->colVal.value.nData;
|
||||
}
|
||||
|
||||
|
|
@ -1386,15 +1559,23 @@ static int32_t tsdbCacheLoadFromRocks(STsdb *pTsdb, tb_uid_t uid, SArray *pLastA
|
|||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
for (int i = 0, j = 0; i < num_keys && j < TARRAY_SIZE(remainCols); ++i) {
|
||||
SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i]);
|
||||
SLastCol* PToFree = pLastCol;
|
||||
SIdxKey *idxKey = &((SIdxKey *)TARRAY_DATA(remainCols))[j];
|
||||
if (pLastCol) {
|
||||
SLastCol *pTmpLastCol = taosMemoryCalloc(1, sizeof(SLastCol));
|
||||
*pTmpLastCol = *pLastCol;
|
||||
pLastCol = pTmpLastCol;
|
||||
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
size_t charge = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type)) {
|
||||
for (int8_t i = 0; i < pLastCol->rowKey.numOfPKs; i++) {
|
||||
SValue *pValue = &pLastCol->rowKey.pks[i];
|
||||
if (IS_VAR_DATA_TYPE(pValue->type)) {
|
||||
reallocVarDataVal(pValue);
|
||||
charge += pValue->nData;
|
||||
}
|
||||
}
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.value.type)) {
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
charge += pLastCol->colVal.value.nData;
|
||||
}
|
||||
|
||||
|
|
@ -1405,10 +1586,14 @@ static int32_t tsdbCacheLoadFromRocks(STsdb *pTsdb, tb_uid_t uid, SArray *pLastA
|
|||
}
|
||||
|
||||
SLastCol lastCol = *pLastCol;
|
||||
for (int8_t i = 0; i < lastCol.rowKey.numOfPKs; i++) {
|
||||
reallocVarDataVal(&lastCol.rowKey.pks[i]);
|
||||
}
|
||||
reallocVarData(&lastCol.colVal);
|
||||
taosArraySet(pLastArray, idxKey->idx, &lastCol);
|
||||
taosArrayRemove(remainCols, j);
|
||||
|
||||
taosMemoryFreeClear(PToFree);
|
||||
taosMemoryFree(values_list[i]);
|
||||
} else {
|
||||
++j;
|
||||
|
|
@ -1436,7 +1621,7 @@ int32_t tsdbCacheGetBatch(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCache
|
|||
for (int i = 0; i < num_keys; ++i) {
|
||||
int16_t cid = ((int16_t *)TARRAY_DATA(pCidList))[i];
|
||||
|
||||
SLastKey *key = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
SLastKey *key = &(SLastKey){.lflag = ltype, .uid = uid, .cid = cid};
|
||||
// for select last_row, last case
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
if (pr->pFuncTypeList != NULL && taosArrayGetSize(pr->pFuncTypeList) > i) {
|
||||
|
|
@ -1444,7 +1629,7 @@ int32_t tsdbCacheGetBatch(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCache
|
|||
}
|
||||
if (((pr->type & CACHESCAN_RETRIEVE_LAST) == CACHESCAN_RETRIEVE_LAST) && FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
int8_t tempType = CACHESCAN_RETRIEVE_LAST_ROW | (pr->type ^ CACHESCAN_RETRIEVE_LAST);
|
||||
key->ltype = (tempType & CACHESCAN_RETRIEVE_LAST) >> 3;
|
||||
key->lflag = (tempType & CACHESCAN_RETRIEVE_LAST) >> 3;
|
||||
}
|
||||
|
||||
LRUHandle *h = taosLRUCacheLookup(pCache, key, ROCKS_KEY_LEN);
|
||||
|
|
@ -1452,12 +1637,17 @@ int32_t tsdbCacheGetBatch(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCache
|
|||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pCache, h);
|
||||
|
||||
SLastCol lastCol = *pLastCol;
|
||||
for (int8_t i = 0; i < lastCol.rowKey.numOfPKs; i++) {
|
||||
reallocVarDataVal(&lastCol.rowKey.pks[i]);
|
||||
}
|
||||
reallocVarData(&lastCol.colVal);
|
||||
taosArrayPush(pLastArray, &lastCol);
|
||||
|
||||
taosLRUCacheRelease(pCache, h, false);
|
||||
} else {
|
||||
SLastCol noneCol = {.ts = TSKEY_MIN, .colVal = COL_VAL_NONE(cid, pr->pSchema->columns[pr->pSlotIds[i]].type)};
|
||||
SLastCol noneCol = {.version = LAST_COL_VERSION,
|
||||
.rowKey.ts = TSKEY_MIN,
|
||||
.colVal = COL_VAL_NONE(cid, pr->pSchema->columns[pr->pSlotIds[i]].type)};
|
||||
|
||||
taosArrayPush(pLastArray, &noneCol);
|
||||
|
||||
|
|
@ -1477,6 +1667,9 @@ int32_t tsdbCacheGetBatch(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCache
|
|||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pCache, h);
|
||||
|
||||
SLastCol lastCol = *pLastCol;
|
||||
for (int8_t i = 0; i < lastCol.rowKey.numOfPKs; i++) {
|
||||
reallocVarDataVal(&lastCol.rowKey.pks[i]);
|
||||
}
|
||||
reallocVarData(&lastCol.colVal);
|
||||
taosArraySet(pLastArray, idxKey->idx, &lastCol);
|
||||
|
||||
|
|
@ -1517,12 +1710,18 @@ int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKE
|
|||
char **keys_list = taosMemoryCalloc(num_keys * 2, sizeof(char *));
|
||||
size_t *keys_list_sizes = taosMemoryCalloc(num_keys * 2, sizeof(size_t));
|
||||
const size_t klen = ROCKS_KEY_LEN;
|
||||
|
||||
int8_t lflag = 0;
|
||||
if (num_keys >= 2) {
|
||||
lflag = (pTSchema->columns[1].flags & COL_IS_KEY) ? LFLAG_PRIMARY_KEY : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_keys; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
|
||||
char *keys = taosMemoryCalloc(2, sizeof(SLastKey));
|
||||
((SLastKey *)keys)[0] = (SLastKey){.ltype = 1, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[1] = (SLastKey){.ltype = 0, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[0] = (SLastKey){.lflag = lflag | LFLAG_LAST, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[1] = (SLastKey){.lflag = lflag | LFLAG_LAST_ROW, .uid = uid, .cid = cid};
|
||||
|
||||
keys_list[i] = keys;
|
||||
keys_list[num_keys + i] = keys + sizeof(SLastKey);
|
||||
|
|
@ -1554,14 +1753,17 @@ int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKE
|
|||
for (int i = 0; i < num_keys; ++i) {
|
||||
SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i]);
|
||||
taosThreadMutexLock(&pTsdb->rCache.rMutex);
|
||||
if (NULL != pLastCol && (pLastCol->ts <= eKey && pLastCol->ts >= sKey)) {
|
||||
if (NULL != pLastCol && (pLastCol->rowKey.ts <= eKey && pLastCol->rowKey.ts >= sKey)) {
|
||||
rocksdb_writebatch_delete(wb, keys_list[i], klen);
|
||||
}
|
||||
taosMemoryFreeClear(pLastCol);
|
||||
|
||||
pLastCol = tsdbCacheDeserialize(values_list[i + num_keys]);
|
||||
if (NULL != pLastCol && (pLastCol->ts <= eKey && pLastCol->ts >= sKey)) {
|
||||
if (NULL != pLastCol && (pLastCol->rowKey.ts <= eKey && pLastCol->rowKey.ts >= sKey)) {
|
||||
rocksdb_writebatch_delete(wb, keys_list[num_keys + i], klen);
|
||||
}
|
||||
taosThreadMutexUnlock(&pTsdb->rCache.rMutex);
|
||||
taosMemoryFreeClear(pLastCol);
|
||||
|
||||
rocksdb_free(values_list[i]);
|
||||
rocksdb_free(values_list[i + num_keys]);
|
||||
|
|
@ -1575,7 +1777,7 @@ int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKE
|
|||
if (pLastCol->dirty) {
|
||||
pLastCol->dirty = 0;
|
||||
}
|
||||
if (pLastCol->ts <= eKey && pLastCol->ts >= sKey) {
|
||||
if (pLastCol->rowKey.ts <= eKey && pLastCol->rowKey.ts >= sKey) {
|
||||
erase = true;
|
||||
}
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
|
|
@ -1591,7 +1793,7 @@ int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKE
|
|||
if (pLastCol->dirty) {
|
||||
pLastCol->dirty = 0;
|
||||
}
|
||||
if (pLastCol->ts <= eKey && pLastCol->ts >= sKey) {
|
||||
if (pLastCol->rowKey.ts <= eKey && pLastCol->rowKey.ts >= sKey) {
|
||||
erase = true;
|
||||
}
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
|
|
@ -2175,7 +2377,7 @@ static int32_t loadTombFromBlk(const TTombBlkArray *pTombBlkArray, SCacheRowsRea
|
|||
|
||||
STombRecord record = {0};
|
||||
bool finished = false;
|
||||
for (int32_t k = 0; k < TARRAY2_SIZE(block.suid); ++k) {
|
||||
for (int32_t k = 0; k < TOMB_BLOCK_SIZE(&block); ++k) {
|
||||
code = tTombBlockGet(&block, k, &record);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
finished = true;
|
||||
|
|
@ -2288,6 +2490,7 @@ static int32_t lastIterOpen(SFSLastIter *iter, STFileSet *pFileSet, STsdb *pTsdb
|
|||
.loadTombFn = loadSttTomb,
|
||||
.pReader = pr,
|
||||
.idstr = pr->idstr,
|
||||
.pCurRowKey = &pr->rowKey,
|
||||
};
|
||||
|
||||
code = tMergeTreeOpen2(&iter->mergeTree, &conf, NULL);
|
||||
|
|
@ -2551,7 +2754,7 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow, bool *pIgnoreEarlie
|
|||
goto _err;
|
||||
}
|
||||
|
||||
state->iBrinRecord = BRIN_BLOCK_SIZE(&state->brinBlock) - 1;
|
||||
state->iBrinRecord = state->brinBlock.numOfRecords - 1;
|
||||
state->state = SFSNEXTROW_BRINBLOCK;
|
||||
}
|
||||
|
||||
|
|
@ -3081,7 +3284,9 @@ static int32_t initLastColArrayPartial(STSchema *pTSchema, SArray **ppColArray,
|
|||
|
||||
for (int32_t i = 0; i < nCols; ++i) {
|
||||
int16_t slotId = slotIds[i];
|
||||
SLastCol col = {.ts = 0, .colVal = COL_VAL_NULL(pTSchema->columns[slotId].colId, pTSchema->columns[slotId].type)};
|
||||
SLastCol col = {.version = LAST_COL_VERSION,
|
||||
.rowKey.ts = 0,
|
||||
.colVal = COL_VAL_NULL(pTSchema->columns[slotId].colId, pTSchema->columns[slotId].type)};
|
||||
taosArrayPush(pColArray, &col);
|
||||
}
|
||||
*ppColArray = pColArray;
|
||||
|
|
@ -3185,14 +3390,14 @@ static int32_t mergeLastCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SC
|
|||
if (slotIds[iCol] == 0) {
|
||||
STColumn *pTColumn = &pTSchema->columns[0];
|
||||
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = rowTs});
|
||||
taosArraySet(pColArray, 0, &(SLastCol){.ts = rowTs, .colVal = *pColVal});
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, ((SValue){.type = pTColumn->type, .val = rowTs}));
|
||||
taosArraySet(pColArray, 0, &(SLastCol){.version = LAST_COL_VERSION, .rowKey.ts = rowTs, .colVal = *pColVal});
|
||||
continue;
|
||||
}
|
||||
tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal);
|
||||
|
||||
*pCol = (SLastCol){.ts = rowTs, .colVal = *pColVal};
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type) /*&& pColVal->value.nData > 0*/) {
|
||||
*pCol = (SLastCol){.version = LAST_COL_VERSION, .rowKey.ts = rowTs, .colVal = *pColVal};
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type) /*&& pColVal->value.nData > 0*/) {
|
||||
if (pColVal->value.nData > 0) {
|
||||
pCol->colVal.value.pData = taosMemoryMalloc(pCol->colVal.value.nData);
|
||||
if (pCol->colVal.value.pData == NULL) {
|
||||
|
|
@ -3241,8 +3446,8 @@ static int32_t mergeLastCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SC
|
|||
|
||||
tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal);
|
||||
if (!COL_VAL_IS_VALUE(tColVal) && COL_VAL_IS_VALUE(pColVal)) {
|
||||
SLastCol lastCol = {.ts = rowTs, .colVal = *pColVal};
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type) /* && pColVal->value.nData > 0 */) {
|
||||
SLastCol lastCol = {.version = LAST_COL_VERSION, .rowKey.ts = rowTs, .colVal = *pColVal};
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type) /* && pColVal->value.nData > 0 */) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosArrayGet(pColArray, iCol);
|
||||
taosMemoryFree(pLastCol->colVal.value.pData);
|
||||
|
||||
|
|
@ -3364,14 +3569,14 @@ static int32_t mergeLastRowCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray,
|
|||
if (slotIds[iCol] == 0) {
|
||||
STColumn *pTColumn = &pTSchema->columns[0];
|
||||
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = rowTs});
|
||||
taosArraySet(pColArray, 0, &(SLastCol){.ts = rowTs, .colVal = *pColVal});
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, ((SValue){.type = pTColumn->type, .val = rowTs}));
|
||||
taosArraySet(pColArray, 0, &(SLastCol){.version = LAST_COL_VERSION, .rowKey.ts = rowTs, .colVal = *pColVal});
|
||||
continue;
|
||||
}
|
||||
tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal);
|
||||
|
||||
*pCol = (SLastCol){.ts = rowTs, .colVal = *pColVal};
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type) /*&& pColVal->value.nData > 0*/) {
|
||||
*pCol = (SLastCol){.version = LAST_COL_VERSION, .rowKey.ts = rowTs, .colVal = *pColVal};
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type) /*&& pColVal->value.nData > 0*/) {
|
||||
if (pColVal->value.nData > 0) {
|
||||
pCol->colVal.value.pData = taosMemoryMalloc(pCol->colVal.value.nData);
|
||||
if (pCol->colVal.value.pData == NULL) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#define HASTYPE(_type, _t) (((_type) & (_t)) == (_t))
|
||||
|
||||
static void setFirstLastResColToNull(SColumnInfoData* pCol, int32_t row) {
|
||||
char *buf = taosMemoryCalloc(1, pCol->info.bytes);
|
||||
char* buf = taosMemoryCalloc(1, pCol->info.bytes);
|
||||
SFirstLastRes* pRes = (SFirstLastRes*)((char*)buf + VARSTR_HEADER_SIZE);
|
||||
pRes->bytes = 0;
|
||||
pRes->hasResult = true;
|
||||
|
|
@ -36,10 +36,10 @@ static void setFirstLastResColToNull(SColumnInfoData* pCol, int32_t row) {
|
|||
|
||||
static void saveOneRowForLastRaw(SLastCol* pColVal, SCacheRowsReader* pReader, const int32_t slotId,
|
||||
SColumnInfoData* pColInfoData, int32_t numOfRows) {
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
|
||||
// allNullRow = false;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.value.type)) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
} else {
|
||||
|
|
@ -57,18 +57,16 @@ static void saveOneRowForLastRaw(SLastCol* pColVal, SCacheRowsReader* pReader, c
|
|||
static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pReader, const int32_t* slotIds,
|
||||
const int32_t* dstSlotIds, void** pRes, const char* idStr) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
// bool allNullRow = true;
|
||||
|
||||
if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
|
||||
uint64_t ts = TSKEY_MIN;
|
||||
uint64_t ts = TSKEY_MIN;
|
||||
SFirstLastRes* p = NULL;
|
||||
col_id_t colId = -1;
|
||||
col_id_t colId = -1;
|
||||
|
||||
SArray* funcTypeBlockArray = taosArrayInit(pReader->numOfCols, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
if (pReader->pFuncTypeList != NULL && taosArrayGetSize(pReader->pFuncTypeList) > i) {
|
||||
funcType = *(int32_t*)taosArrayGet(pReader->pFuncTypeList, i);
|
||||
}
|
||||
|
|
@ -93,31 +91,32 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
|
||||
p = (SFirstLastRes*)varDataVal(pRes[i]);
|
||||
|
||||
p->ts = pColVal->ts;
|
||||
p->ts = pColVal->rowKey.ts;
|
||||
ts = p->ts;
|
||||
p->isNull = !COL_VAL_IS_VALUE(&pColVal->colVal);
|
||||
// allNullRow = p->isNull & allNullRow;
|
||||
if (!p->isNull) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.value.type)) {
|
||||
varDataSetLen(p->buf, pColVal->colVal.value.nData);
|
||||
|
||||
memcpy(varDataVal(p->buf), pColVal->colVal.value.pData, pColVal->colVal.value.nData);
|
||||
p->bytes = pColVal->colVal.value.nData + VARSTR_HEADER_SIZE; // binary needs to plus the header size
|
||||
} else {
|
||||
memcpy(p->buf, &pColVal->colVal.value, pReader->pSchema->columns[slotId].bytes);
|
||||
memcpy(p->buf, &pColVal->colVal.value.val, pReader->pSchema->columns[slotId].bytes);
|
||||
p->bytes = pReader->pSchema->columns[slotId].bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// pColInfoData->info.bytes includes the VARSTR_HEADER_SIZE, need to substruct it
|
||||
// pColInfoData->info.bytes includes the VARSTR_HEADER_SIZE, need to subtract it
|
||||
p->hasResult = true;
|
||||
varDataSetLen(pRes[i], pColInfoData->info.bytes - VARSTR_HEADER_SIZE);
|
||||
colDataSetVal(pColInfoData, numOfRows, (const char*)pRes[i], false);
|
||||
}
|
||||
|
||||
for (int32_t idx = 0; idx < taosArrayGetSize(pBlock->pDataBlock); ++idx) {
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, idx);
|
||||
if (idx < funcTypeBlockArray->size) {
|
||||
int32_t funcType = *(int32_t*)taosArrayGet(funcTypeBlockArray, idx);
|
||||
int32_t funcType = *(int32_t*)taosArrayGet(funcTypeBlockArray, idx);
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -146,7 +145,7 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
|
||||
int32_t slotId = slotIds[i];
|
||||
int32_t slotId = slotIds[i];
|
||||
if (slotId == -1) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
continue;
|
||||
|
|
@ -210,7 +209,7 @@ int32_t tsdbReuseCacherowsReader(void* reader, void* pTableIdList, int32_t numOf
|
|||
|
||||
int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray* pCidList, int32_t* pSlotIds, uint64_t suid, void** pReader, const char* idstr,
|
||||
SArray* pFuncTypeList) {
|
||||
SArray* pFuncTypeList, SColumnInfo* pPkCol, int32_t numOfPks) {
|
||||
*pReader = NULL;
|
||||
SCacheRowsReader* p = taosMemoryCalloc(1, sizeof(SCacheRowsReader));
|
||||
if (p == NULL) {
|
||||
|
|
@ -227,6 +226,16 @@ int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList,
|
|||
p->pSlotIds = pSlotIds;
|
||||
p->pFuncTypeList = pFuncTypeList;
|
||||
|
||||
p->rowKey.numOfPKs = numOfPks;
|
||||
if (numOfPks > 0) {
|
||||
p->rowKey.pks[0].type = pPkCol->type;
|
||||
if (IS_VAR_DATA_TYPE(pPkCol->type)) {
|
||||
p->rowKey.pks[0].pData = taosMemoryCalloc(1, pPkCol->bytes);
|
||||
}
|
||||
|
||||
p->pkColumn = *pPkCol;
|
||||
}
|
||||
|
||||
if (numOfTables == 0) {
|
||||
*pReader = p;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
@ -315,7 +324,7 @@ void* tsdbCacherowsReaderClose(void* pReader) {
|
|||
|
||||
static void freeItem(void* pItem) {
|
||||
SLastCol* pCol = (SLastCol*)pItem;
|
||||
if (IS_VAR_DATA_TYPE(pCol->colVal.type) && pCol->colVal.value.pData) {
|
||||
if (IS_VAR_DATA_TYPE(pCol->colVal.value.type) && pCol->colVal.value.pData) {
|
||||
taosMemoryFree(pCol->colVal.value.pData);
|
||||
}
|
||||
}
|
||||
|
|
@ -358,14 +367,15 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
goto _end;
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < pr->numOfCols; ++j) {
|
||||
int32_t bytes;
|
||||
if (slotIds[j] == -1)
|
||||
bytes = 1;
|
||||
else
|
||||
bytes = pr->pSchema->columns[slotIds[j]].bytes;
|
||||
int32_t pkBufLen = 0;
|
||||
if (pr->rowKey.numOfPKs > 0) {
|
||||
pkBufLen = pr->pkColumn.bytes;
|
||||
}
|
||||
|
||||
pRes[j] = taosMemoryCalloc(1, sizeof(SFirstLastRes) + bytes + VARSTR_HEADER_SIZE);
|
||||
for (int32_t j = 0; j < pr->numOfCols; ++j) {
|
||||
int32_t bytes = (slotIds[j] == -1) ? 1 : pr->pSchema->columns[slotIds[j]].bytes;
|
||||
|
||||
pRes[j] = taosMemoryCalloc(1, sizeof(SFirstLastRes) + bytes + pkBufLen + VARSTR_HEADER_SIZE);
|
||||
SFirstLastRes* p = (SFirstLastRes*)varDataVal(pRes[j]);
|
||||
p->ts = INT64_MIN;
|
||||
}
|
||||
|
|
@ -388,14 +398,14 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pr->numOfCols; ++i) {
|
||||
int32_t slotId = slotIds[i];
|
||||
int32_t slotId = slotIds[i];
|
||||
if (slotId == -1) {
|
||||
SLastCol p = {.ts = INT64_MIN, .colVal.type = TSDB_DATA_TYPE_BOOL, .colVal.flag = CV_FLAG_NULL};
|
||||
SLastCol p = {.rowKey.ts = INT64_MIN, .colVal.value.type = TSDB_DATA_TYPE_BOOL, .colVal.flag = CV_FLAG_NULL};
|
||||
taosArrayPush(pLastCols, &p);
|
||||
continue;
|
||||
}
|
||||
struct STColumn* pCol = &pr->pSchema->columns[slotId];
|
||||
SLastCol p = {.ts = INT64_MIN, .colVal.type = pCol->type, .colVal.flag = CV_FLAG_NULL};
|
||||
SLastCol p = {.rowKey.ts = INT64_MIN, .colVal.value.type = pCol->type, .colVal.flag = CV_FLAG_NULL};
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||
p.colVal.value.pData = taosMemoryCalloc(pCol->bytes, sizeof(char));
|
||||
|
|
@ -422,19 +432,19 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
SLastCol* p = taosArrayGet(pLastCols, k);
|
||||
SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, k);
|
||||
|
||||
if (pColVal->ts > p->ts) {
|
||||
if (pColVal->rowKey.ts > p->rowKey.ts) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal) && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
if (!COL_VAL_IS_VALUE(&p->colVal)) {
|
||||
hasNotNullRow = false;
|
||||
}
|
||||
// For all of cols is null, the last null col of last table will be save
|
||||
// For all of cols is null, the last null col of last table will be save
|
||||
if (i != pr->numOfTables - 1 || k != pr->numOfCols - 1 || hasRes) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
hasRes = true;
|
||||
p->ts = pColVal->ts;
|
||||
p->rowKey.ts = pColVal->rowKey.ts;
|
||||
if (k == 0) {
|
||||
if (TARRAY_SIZE(pTableUidList) == 0) {
|
||||
taosArrayPush(pTableUidList, &uid);
|
||||
|
|
@ -443,11 +453,11 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
}
|
||||
}
|
||||
|
||||
if (pColVal->ts < singleTableLastTs && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
singleTableLastTs = pColVal->ts;
|
||||
if (pColVal->rowKey.ts < singleTableLastTs && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
singleTableLastTs = pColVal->rowKey.ts;
|
||||
}
|
||||
|
||||
if (!IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (!IS_VAR_DATA_TYPE(pColVal->colVal.value.type)) {
|
||||
p->colVal = pColVal->colVal;
|
||||
} else {
|
||||
if (COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
|
|
@ -455,7 +465,7 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
}
|
||||
|
||||
p->colVal.value.nData = pColVal->colVal.value.nData;
|
||||
p->colVal.type = pColVal->colVal.type;
|
||||
p->colVal.value.type = pColVal->colVal.value.type;
|
||||
p->colVal.flag = pColVal->colVal.flag;
|
||||
p->colVal.cid = pColVal->colVal.cid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int32_t tRowInfoCmprFn(const void *p1, const void *p2) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
return tsdbRowCmprFn(&pInfo1->row, &pInfo2->row);
|
||||
return tsdbRowCompare(&pInfo1->row, &pInfo2->row);
|
||||
}
|
||||
|
||||
int32_t tsdbBegin(STsdb *pTsdb) {
|
||||
|
|
|
|||
|
|
@ -298,8 +298,11 @@ static int32_t tsdbCommitOpenIter(SCommitter2 *committer) {
|
|||
// mem data iter
|
||||
config.type = TSDB_ITER_TYPE_MEMT;
|
||||
config.memt = committer->tsdb->imem;
|
||||
config.from->ts = committer->ctx->minKey;
|
||||
config.from->version = VERSION_MIN;
|
||||
config.from->key = (SRowKey){
|
||||
.ts = committer->ctx->minKey,
|
||||
.numOfPKs = 0, // TODO: support multiple primary keys
|
||||
};
|
||||
|
||||
code = tsdbIterOpen(&config, &iter);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -25,18 +25,16 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef TARRAY2(SBlockIdx) TBlockIdxArray;
|
||||
typedef TARRAY2(SDataBlk) TDataBlkArray;
|
||||
typedef TARRAY2(SColumnDataAgg) TColumnDataAggArray;
|
||||
|
||||
typedef struct {
|
||||
SFDataPtr brinBlkPtr[1];
|
||||
SFDataPtr rsrvd[2];
|
||||
char rsrvd[32];
|
||||
} SHeadFooter;
|
||||
|
||||
typedef struct {
|
||||
SFDataPtr tombBlkPtr[1];
|
||||
SFDataPtr rsrvd[2];
|
||||
char rsrvd[32];
|
||||
} STombFooter;
|
||||
|
||||
// SDataFileReader =============================================
|
||||
|
|
@ -48,7 +46,7 @@ typedef struct SDataFileReaderConfig {
|
|||
bool exist;
|
||||
STFile file;
|
||||
} files[TSDB_FTYPE_MAX];
|
||||
uint8_t **bufArr;
|
||||
SBuffer *buffers;
|
||||
} SDataFileReaderConfig;
|
||||
|
||||
int32_t tsdbDataFileReaderOpen(const char *fname[/* TSDB_FTYPE_MAX */], const SDataFileReaderConfig *config,
|
||||
|
|
@ -85,7 +83,7 @@ typedef struct SDataFileWriterConfig {
|
|||
} files[TSDB_FTYPE_MAX];
|
||||
SSkmInfo *skmTb;
|
||||
SSkmInfo *skmRow;
|
||||
uint8_t **bufArr;
|
||||
SBuffer *buffers;
|
||||
} SDataFileWriterConfig;
|
||||
|
||||
int32_t tsdbDataFileWriterOpen(const SDataFileWriterConfig *config, SDataFileWriter **writer);
|
||||
|
|
@ -97,22 +95,22 @@ int32_t tsdbDataFileFlush(SDataFileWriter *writer);
|
|||
|
||||
// head
|
||||
int32_t tsdbFileWriteBrinBlock(STsdbFD *fd, SBrinBlock *brinBlock, int8_t cmprAlg, int64_t *fileSize,
|
||||
TBrinBlkArray *brinBlkArray, uint8_t **bufArr, SVersionRange *range,
|
||||
TBrinBlkArray *brinBlkArray, SBuffer *buffers, SVersionRange *range,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
int32_t tsdbFileWriteBrinBlk(STsdbFD *fd, TBrinBlkArray *brinBlkArray, SFDataPtr *ptr, int64_t *fileSize,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
int32_t tsdbFileWriteHeadFooter(STsdbFD *fd, int64_t *fileSize, const SHeadFooter *footer, int32_t encryptAlgorithm,
|
||||
char* encryptKey);
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
int32_t tsdbFileWriteHeadFooter(STsdbFD *fd, int64_t *fileSize, const SHeadFooter *footer,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
|
||||
// tomb
|
||||
int32_t tsdbDataFileWriteTombRecord(SDataFileWriter *writer, const STombRecord *record);
|
||||
int32_t tsdbFileWriteTombBlock(STsdbFD *fd, STombBlock *tombBlock, int8_t cmprAlg, int64_t *fileSize,
|
||||
TTombBlkArray *tombBlkArray, uint8_t **bufArr, SVersionRange *range,
|
||||
TTombBlkArray *tombBlkArray, SBuffer *buffers, SVersionRange *range,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
int32_t tsdbFileWriteTombBlk(STsdbFD *fd, const TTombBlkArray *tombBlkArray, SFDataPtr *ptr, int64_t *fileSize,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
int32_t tsdbFileWriteTombFooter(STsdbFD *fd, const STombFooter *footer, int64_t *fileSize, int32_t encryptAlgorithm,
|
||||
char* encryptKey);
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
int32_t tsdbFileWriteTombFooter(STsdbFD *fd, const STombFooter *footer, int64_t *fileSize,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
|
||||
// utils
|
||||
int32_t tsdbWriterUpdVerRange(SVersionRange *range, int64_t minVer, int64_t maxVer);
|
||||
|
|
|
|||
|
|
@ -1,477 +0,0 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
#include "vnodeInt.h"
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
// STsdbDataIter2
|
||||
/* open */
|
||||
int32_t tsdbOpenDataFileDataIter(SDataFReader* pReader, STsdbDataIter2** ppIter) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
// create handle
|
||||
STsdbDataIter2* pIter = (STsdbDataIter2*)taosMemoryCalloc(1, sizeof(*pIter));
|
||||
if (pIter == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
pIter->type = TSDB_DATA_FILE_DATA_ITER;
|
||||
pIter->dIter.pReader = pReader;
|
||||
if ((pIter->dIter.aBlockIdx = taosArrayInit(0, sizeof(SBlockIdx))) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
code = tBlockDataCreate(&pIter->dIter.bData);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->dIter.iBlockIdx = 0;
|
||||
pIter->dIter.iDataBlk = 0;
|
||||
pIter->dIter.iRow = 0;
|
||||
|
||||
// read data
|
||||
code = tsdbReadBlockIdx(pReader, pIter->dIter.aBlockIdx);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
if (taosArrayGetSize(pIter->dIter.aBlockIdx) == 0) goto _clear;
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
if (pIter) {
|
||||
_clear:
|
||||
tBlockDataDestroy(&pIter->dIter.bData);
|
||||
taosArrayDestroy(pIter->dIter.aBlockIdx);
|
||||
taosMemoryFree(pIter);
|
||||
pIter = NULL;
|
||||
}
|
||||
}
|
||||
*ppIter = pIter;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbOpenSttFileDataIter(SDataFReader* pReader, int32_t iStt, STsdbDataIter2** ppIter) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
// create handle
|
||||
STsdbDataIter2* pIter = (STsdbDataIter2*)taosMemoryCalloc(1, sizeof(*pIter));
|
||||
if (pIter == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
pIter->type = TSDB_STT_FILE_DATA_ITER;
|
||||
pIter->sIter.pReader = pReader;
|
||||
pIter->sIter.iStt = iStt;
|
||||
pIter->sIter.aSttBlk = taosArrayInit(0, sizeof(SSttBlk));
|
||||
if (pIter->sIter.aSttBlk == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
code = tBlockDataCreate(&pIter->sIter.bData);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->sIter.iSttBlk = 0;
|
||||
pIter->sIter.iRow = 0;
|
||||
|
||||
// read data
|
||||
code = tsdbReadSttBlk(pReader, iStt, pIter->sIter.aSttBlk);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
if (taosArrayGetSize(pIter->sIter.aSttBlk) == 0) goto _clear;
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
if (pIter) {
|
||||
_clear:
|
||||
taosArrayDestroy(pIter->sIter.aSttBlk);
|
||||
tBlockDataDestroy(&pIter->sIter.bData);
|
||||
taosMemoryFree(pIter);
|
||||
pIter = NULL;
|
||||
}
|
||||
}
|
||||
*ppIter = pIter;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbOpenTombFileDataIter(SDelFReader* pReader, STsdbDataIter2** ppIter) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
STsdbDataIter2* pIter = (STsdbDataIter2*)taosMemoryCalloc(1, sizeof(*pIter));
|
||||
if (pIter == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
pIter->type = TSDB_TOMB_FILE_DATA_ITER;
|
||||
|
||||
pIter->tIter.pReader = pReader;
|
||||
if ((pIter->tIter.aDelIdx = taosArrayInit(0, sizeof(SDelIdx))) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
if ((pIter->tIter.aDelData = taosArrayInit(0, sizeof(SDelData))) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
code = tsdbReadDelIdx(pReader, pIter->tIter.aDelIdx);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
if (taosArrayGetSize(pIter->tIter.aDelIdx) == 0) goto _clear;
|
||||
|
||||
pIter->tIter.iDelIdx = 0;
|
||||
pIter->tIter.iDelData = 0;
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
if (pIter) {
|
||||
_clear:
|
||||
taosArrayDestroy(pIter->tIter.aDelIdx);
|
||||
taosArrayDestroy(pIter->tIter.aDelData);
|
||||
taosMemoryFree(pIter);
|
||||
pIter = NULL;
|
||||
}
|
||||
}
|
||||
*ppIter = pIter;
|
||||
return code;
|
||||
}
|
||||
|
||||
/* close */
|
||||
static void tsdbCloseDataFileDataIter(STsdbDataIter2* pIter) {
|
||||
tBlockDataDestroy(&pIter->dIter.bData);
|
||||
tMapDataClear(&pIter->dIter.mDataBlk);
|
||||
taosArrayDestroy(pIter->dIter.aBlockIdx);
|
||||
taosMemoryFree(pIter);
|
||||
}
|
||||
|
||||
static void tsdbCloseSttFileDataIter(STsdbDataIter2* pIter) {
|
||||
tBlockDataDestroy(&pIter->sIter.bData);
|
||||
taosArrayDestroy(pIter->sIter.aSttBlk);
|
||||
taosMemoryFree(pIter);
|
||||
}
|
||||
|
||||
static void tsdbCloseTombFileDataIter(STsdbDataIter2* pIter) {
|
||||
taosArrayDestroy(pIter->tIter.aDelData);
|
||||
taosArrayDestroy(pIter->tIter.aDelIdx);
|
||||
taosMemoryFree(pIter);
|
||||
}
|
||||
|
||||
void tsdbCloseDataIter2(STsdbDataIter2* pIter) {
|
||||
if (pIter->type == TSDB_MEM_TABLE_DATA_ITER) {
|
||||
ASSERT(0);
|
||||
} else if (pIter->type == TSDB_DATA_FILE_DATA_ITER) {
|
||||
tsdbCloseDataFileDataIter(pIter);
|
||||
} else if (pIter->type == TSDB_STT_FILE_DATA_ITER) {
|
||||
tsdbCloseSttFileDataIter(pIter);
|
||||
} else if (pIter->type == TSDB_TOMB_FILE_DATA_ITER) {
|
||||
tsdbCloseTombFileDataIter(pIter);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* cmpr */
|
||||
int32_t tsdbDataIterCmprFn(const SRBTreeNode* pNode1, const SRBTreeNode* pNode2) {
|
||||
STsdbDataIter2* pIter1 = TSDB_RBTN_TO_DATA_ITER(pNode1);
|
||||
STsdbDataIter2* pIter2 = TSDB_RBTN_TO_DATA_ITER(pNode2);
|
||||
return tRowInfoCmprFn(&pIter1->rowInfo, &pIter2->rowInfo);
|
||||
}
|
||||
|
||||
/* seek */
|
||||
|
||||
/* iter next */
|
||||
static int32_t tsdbDataFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo* pFilterInfo) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
for (;;) {
|
||||
while (pIter->dIter.iRow < pIter->dIter.bData.nRow) {
|
||||
if (pFilterInfo) {
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
|
||||
if (pIter->dIter.bData.aVersion[pIter->dIter.iRow] < pFilterInfo->sver ||
|
||||
pIter->dIter.bData.aVersion[pIter->dIter.iRow] > pFilterInfo->ever) {
|
||||
pIter->dIter.iRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(pIter->rowInfo.suid == pIter->dIter.bData.suid);
|
||||
ASSERT(pIter->rowInfo.uid == pIter->dIter.bData.uid);
|
||||
pIter->rowInfo.row = tsdbRowFromBlockData(&pIter->dIter.bData, pIter->dIter.iRow);
|
||||
pIter->dIter.iRow++;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
while (pIter->dIter.iDataBlk < pIter->dIter.mDataBlk.nItem) {
|
||||
SDataBlk dataBlk;
|
||||
tMapDataGetItemByIdx(&pIter->dIter.mDataBlk, pIter->dIter.iDataBlk, &dataBlk, tGetDataBlk);
|
||||
|
||||
// filter
|
||||
if (pFilterInfo) {
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
|
||||
if (pFilterInfo->sver > dataBlk.maxVer || pFilterInfo->ever < dataBlk.minVer) {
|
||||
pIter->dIter.iDataBlk++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code = tsdbReadDataBlockEx(pIter->dIter.pReader, &dataBlk, &pIter->dIter.bData);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->dIter.iDataBlk++;
|
||||
pIter->dIter.iRow = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (pIter->dIter.iRow < pIter->dIter.bData.nRow) break;
|
||||
|
||||
for (;;) {
|
||||
if (pIter->dIter.iBlockIdx < taosArrayGetSize(pIter->dIter.aBlockIdx)) {
|
||||
SBlockIdx* pBlockIdx = taosArrayGet(pIter->dIter.aBlockIdx, pIter->dIter.iBlockIdx);
|
||||
|
||||
if (pFilterInfo) {
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
|
||||
int32_t c = tTABLEIDCmprFn(pBlockIdx, &pFilterInfo->tbid);
|
||||
if (c == 0) {
|
||||
pIter->dIter.iBlockIdx++;
|
||||
continue;
|
||||
} else if (c < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE) {
|
||||
SMetaInfo info;
|
||||
if (metaGetInfo(pIter->dIter.pReader->pTsdb->pVnode->pMeta, pBlockIdx->uid, &info, NULL)) {
|
||||
pIter->dIter.iBlockIdx++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code = tsdbReadDataBlk(pIter->dIter.pReader, pBlockIdx, &pIter->dIter.mDataBlk);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->rowInfo.suid = pBlockIdx->suid;
|
||||
pIter->rowInfo.uid = pBlockIdx->uid;
|
||||
|
||||
pIter->dIter.iBlockIdx++;
|
||||
pIter->dIter.iDataBlk = 0;
|
||||
|
||||
break;
|
||||
} else {
|
||||
pIter->rowInfo = (SRowInfo){0};
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbSttFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo* pFilterInfo) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
for (;;) {
|
||||
while (pIter->sIter.iRow < pIter->sIter.bData.nRow) {
|
||||
if (pFilterInfo) {
|
||||
int64_t uid = pIter->sIter.bData.uid ? pIter->sIter.bData.uid : pIter->sIter.bData.aUid[pIter->sIter.iRow];
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
|
||||
if (pFilterInfo->tbid.uid == uid) {
|
||||
pIter->sIter.iRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE) {
|
||||
if (pIter->rowInfo.uid != uid) {
|
||||
SMetaInfo info;
|
||||
if (metaGetInfo(pIter->sIter.pReader->pTsdb->pVnode->pMeta, uid, &info, NULL)) {
|
||||
pIter->sIter.iRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
|
||||
if (pFilterInfo->sver > pIter->sIter.bData.aVersion[pIter->sIter.iRow] ||
|
||||
pFilterInfo->ever < pIter->sIter.bData.aVersion[pIter->sIter.iRow]) {
|
||||
pIter->sIter.iRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pIter->rowInfo.suid = pIter->sIter.bData.suid;
|
||||
pIter->rowInfo.uid = pIter->sIter.bData.uid ? pIter->sIter.bData.uid : pIter->sIter.bData.aUid[pIter->sIter.iRow];
|
||||
pIter->rowInfo.row = tsdbRowFromBlockData(&pIter->sIter.bData, pIter->sIter.iRow);
|
||||
pIter->sIter.iRow++;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (pIter->sIter.iSttBlk < taosArrayGetSize(pIter->sIter.aSttBlk)) {
|
||||
SSttBlk* pSttBlk = taosArrayGet(pIter->sIter.aSttBlk, pIter->sIter.iSttBlk);
|
||||
|
||||
if (pFilterInfo) {
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
|
||||
if (pSttBlk->suid == pFilterInfo->tbid.suid && pSttBlk->minUid == pFilterInfo->tbid.uid &&
|
||||
pSttBlk->maxUid == pFilterInfo->tbid.uid) {
|
||||
pIter->sIter.iSttBlk++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
|
||||
if (pFilterInfo->sver > pSttBlk->maxVer || pFilterInfo->ever < pSttBlk->minVer) {
|
||||
pIter->sIter.iSttBlk++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code = tsdbReadSttBlockEx(pIter->sIter.pReader, pIter->sIter.iStt, pSttBlk, &pIter->sIter.bData);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->sIter.iRow = 0;
|
||||
pIter->sIter.iSttBlk++;
|
||||
break;
|
||||
} else {
|
||||
pIter->rowInfo = (SRowInfo){0};
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbTombFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo* pFilterInfo) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
for (;;) {
|
||||
while (pIter->tIter.iDelData < taosArrayGetSize(pIter->tIter.aDelData)) {
|
||||
SDelData* pDelData = taosArrayGet(pIter->tIter.aDelData, pIter->tIter.iDelData);
|
||||
|
||||
if (pFilterInfo) {
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
|
||||
if (pFilterInfo->sver > pDelData->version || pFilterInfo->ever < pDelData->version) {
|
||||
pIter->tIter.iDelData++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pIter->delInfo.delData = *pDelData;
|
||||
pIter->tIter.iDelData++;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (pIter->tIter.iDelIdx < taosArrayGetSize(pIter->tIter.aDelIdx)) {
|
||||
SDelIdx* pDelIdx = taosArrayGet(pIter->tIter.aDelIdx, pIter->tIter.iDelIdx);
|
||||
|
||||
if (pFilterInfo) {
|
||||
if (pFilterInfo->flag & TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE) {
|
||||
SMetaInfo info;
|
||||
if (metaGetInfo(pIter->dIter.pReader->pTsdb->pVnode->pMeta, pDelIdx->uid, &info, NULL)) {
|
||||
pIter->tIter.iDelIdx++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code = tsdbReadDelDatav1(pIter->tIter.pReader, pDelIdx, pIter->tIter.aDelData, INT64_MAX);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->delInfo.suid = pDelIdx->suid;
|
||||
pIter->delInfo.uid = pDelIdx->uid;
|
||||
pIter->tIter.iDelData = 0;
|
||||
pIter->tIter.iDelIdx++;
|
||||
break;
|
||||
} else {
|
||||
pIter->delInfo = (SDelInfo){0};
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbDataIterNext2(STsdbDataIter2* pIter, STsdbFilterInfo* pFilterInfo) {
|
||||
int32_t code = 0;
|
||||
|
||||
if (pIter->type == TSDB_MEM_TABLE_DATA_ITER) {
|
||||
ASSERT(0);
|
||||
return code;
|
||||
} else if (pIter->type == TSDB_DATA_FILE_DATA_ITER) {
|
||||
return tsdbDataFileDataIterNext(pIter, pFilterInfo);
|
||||
} else if (pIter->type == TSDB_STT_FILE_DATA_ITER) {
|
||||
return tsdbSttFileDataIterNext(pIter, pFilterInfo);
|
||||
} else if (pIter->type == TSDB_TOMB_FILE_DATA_ITER) {
|
||||
return tsdbTombFileDataIterNext(pIter, pFilterInfo);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* get */
|
||||
|
||||
// STsdbFSetIter
|
||||
typedef struct STsdbFSetDataIter {
|
||||
STsdb* pTsdb;
|
||||
int32_t flags;
|
||||
|
||||
/* tombstone */
|
||||
SDelFReader* pDelFReader;
|
||||
SArray* aDelIdx; // SArray<SDelIdx>
|
||||
SArray* aDelData; // SArray<SDelData>
|
||||
SArray* aSkeyLine; // SArray<TABLEID>
|
||||
int32_t iDelIdx;
|
||||
int32_t iSkyLine;
|
||||
|
||||
/* time-series data */
|
||||
SDataFReader* pReader;
|
||||
STsdbDataIter2* iterList;
|
||||
STsdbDataIter2* pIter;
|
||||
SRBTree rbt;
|
||||
} STsdbFSetDataIter;
|
||||
|
|
@ -33,6 +33,7 @@ typedef struct SFDataPtr {
|
|||
|
||||
extern int32_t tsdbOpenFile(const char *path, STsdb *pTsdb, int32_t flag, STsdbFD **ppFD);
|
||||
extern void tsdbCloseFile(STsdbFD **ppFD);
|
||||
|
||||
extern int32_t tsdbWriteFile(STsdbFD *pFD, int64_t offset, const uint8_t *pBuf, int64_t size,
|
||||
int32_t encryptAlgorithm, char* encryptKey);
|
||||
extern int32_t tsdbReadFile(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size, int64_t szHint,
|
||||
|
|
|
|||
|
|
@ -1,697 +0,0 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
typedef struct SDiskColBuilder SDiskColBuilder;
|
||||
|
||||
struct SDiskColBuilder {
|
||||
int16_t cid;
|
||||
int8_t type;
|
||||
uint8_t cmprAlg;
|
||||
uint8_t calcSma;
|
||||
int8_t flag;
|
||||
int32_t nVal;
|
||||
uint8_t *pBitMap;
|
||||
int32_t offset;
|
||||
SCompressor *pOffC;
|
||||
SCompressor *pValC;
|
||||
SColumnDataAgg sma;
|
||||
uint8_t minSet;
|
||||
uint8_t maxSet;
|
||||
uint8_t *aBuf[2];
|
||||
};
|
||||
|
||||
// SDiskData ================================================
|
||||
static int32_t tDiskDataDestroy(SDiskData *pDiskData) {
|
||||
int32_t code = 0;
|
||||
pDiskData->aDiskCol = taosArrayDestroy(pDiskData->aDiskCol);
|
||||
return code;
|
||||
}
|
||||
|
||||
// SDiskColBuilder ================================================
|
||||
#define tDiskColBuilderCreate() \
|
||||
(SDiskColBuilder) { 0 }
|
||||
|
||||
static int32_t tDiskColBuilderDestroy(SDiskColBuilder *pBuilder) {
|
||||
int32_t code = 0;
|
||||
|
||||
tFree(pBuilder->pBitMap);
|
||||
if (pBuilder->pOffC) tCompressorDestroy(pBuilder->pOffC);
|
||||
if (pBuilder->pValC) tCompressorDestroy(pBuilder->pValC);
|
||||
for (int32_t iBuf = 0; iBuf < sizeof(pBuilder->aBuf) / sizeof(pBuilder->aBuf[0]); iBuf++) {
|
||||
tFree(pBuilder->aBuf[iBuf]);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tDiskColBuilderInit(SDiskColBuilder *pBuilder, int16_t cid, int8_t type, uint8_t cmprAlg,
|
||||
uint8_t calcSma) {
|
||||
int32_t code = 0;
|
||||
|
||||
pBuilder->cid = cid;
|
||||
pBuilder->type = type;
|
||||
pBuilder->cmprAlg = cmprAlg;
|
||||
pBuilder->calcSma = IS_VAR_DATA_TYPE(type) ? 0 : calcSma;
|
||||
pBuilder->flag = 0;
|
||||
pBuilder->nVal = 0;
|
||||
pBuilder->offset = 0;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
if (pBuilder->pOffC == NULL && (code = tCompressorCreate(&pBuilder->pOffC))) return code;
|
||||
code = tCompressStart(pBuilder->pOffC, TSDB_DATA_TYPE_INT, cmprAlg);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
if (pBuilder->pValC == NULL && (code = tCompressorCreate(&pBuilder->pValC))) return code;
|
||||
code = tCompressStart(pBuilder->pValC, type, cmprAlg);
|
||||
if (code) return code;
|
||||
|
||||
if (pBuilder->calcSma) {
|
||||
pBuilder->sma = (SColumnDataAgg){.colId = cid};
|
||||
pBuilder->minSet = 0;
|
||||
pBuilder->maxSet = 0;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tGnrtDiskCol(SDiskColBuilder *pBuilder, SDiskCol *pDiskCol) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pBuilder->flag && pBuilder->flag != HAS_NONE);
|
||||
|
||||
*pDiskCol = (SDiskCol){(SBlockCol){.cid = pBuilder->cid,
|
||||
.type = pBuilder->type,
|
||||
.smaOn = pBuilder->calcSma,
|
||||
.flag = pBuilder->flag,
|
||||
.szOrigin = 0,
|
||||
.szBitmap = 0,
|
||||
.szOffset = 0,
|
||||
.szValue = 0,
|
||||
.offset = 0},
|
||||
.pBit = NULL, .pOff = NULL, .pVal = NULL, .agg = pBuilder->sma};
|
||||
|
||||
if (pBuilder->flag == HAS_NULL) return code;
|
||||
|
||||
// BITMAP
|
||||
if (pBuilder->flag != HAS_VALUE) {
|
||||
int32_t nBit;
|
||||
if (pBuilder->flag == (HAS_VALUE | HAS_NULL | HAS_NONE)) {
|
||||
nBit = BIT2_SIZE(pBuilder->nVal);
|
||||
} else {
|
||||
nBit = BIT1_SIZE(pBuilder->nVal);
|
||||
}
|
||||
|
||||
code = tRealloc(&pBuilder->aBuf[0], nBit + COMP_OVERFLOW_BYTES);
|
||||
if (code) return code;
|
||||
|
||||
code = tRealloc(&pBuilder->aBuf[1], nBit + COMP_OVERFLOW_BYTES);
|
||||
if (code) return code;
|
||||
|
||||
pDiskCol->bCol.szBitmap =
|
||||
tsCompressTinyint(pBuilder->pBitMap, nBit, nBit, pBuilder->aBuf[0], nBit + COMP_OVERFLOW_BYTES,
|
||||
pBuilder->cmprAlg, pBuilder->aBuf[1], nBit + COMP_OVERFLOW_BYTES);
|
||||
pDiskCol->pBit = pBuilder->aBuf[0];
|
||||
}
|
||||
|
||||
// OFFSET
|
||||
if (IS_VAR_DATA_TYPE(pBuilder->type)) {
|
||||
code = tCompressEnd(pBuilder->pOffC, &pDiskCol->pOff, &pDiskCol->bCol.szOffset, NULL);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
// VALUE
|
||||
if (pBuilder->flag != (HAS_NULL | HAS_NONE)) {
|
||||
code = tCompressEnd(pBuilder->pValC, &pDiskCol->pVal, &pDiskCol->bCol.szValue, &pDiskCol->bCol.szOrigin);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDiskColPutValue(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
code = tCompress(pBuilder->pOffC, &pBuilder->offset, sizeof(int32_t));
|
||||
if (code) return code;
|
||||
pBuilder->offset += pColVal->value.nData;
|
||||
|
||||
code = tCompress(pBuilder->pValC, pColVal->value.pData, pColVal->value.nData);
|
||||
if (code) return code;
|
||||
} else {
|
||||
code = tCompress(pBuilder->pValC, &pColVal->value.val, tDataTypes[pColVal->type].bytes);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal00(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
pBuilder->flag = HAS_VALUE;
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal01(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
pBuilder->flag = HAS_NONE;
|
||||
return 0;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal02(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
pBuilder->flag = HAS_NULL;
|
||||
return 0;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal10(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
// bit map
|
||||
int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
|
||||
code = tRealloc(&pBuilder->pBitMap, nBit);
|
||||
if (code) return code;
|
||||
|
||||
memset(pBuilder->pBitMap, 0, nBit);
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
// value
|
||||
pBuilder->flag |= HAS_VALUE;
|
||||
|
||||
SColVal cv = COL_VAL_VALUE(pColVal->cid, pColVal->type, (SValue){0});
|
||||
for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
|
||||
code = tDiskColPutValue(pBuilder, &cv);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal12(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
|
||||
code = tRealloc(&pBuilder->pBitMap, nBit);
|
||||
if (code) return code;
|
||||
|
||||
memset(pBuilder->pBitMap, 0, nBit);
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
pBuilder->flag |= HAS_NULL;
|
||||
|
||||
return code;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal20(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
|
||||
code = tRealloc(&pBuilder->pBitMap, nBit);
|
||||
if (code) return code;
|
||||
|
||||
pBuilder->flag |= HAS_VALUE;
|
||||
|
||||
memset(pBuilder->pBitMap, 0, nBit);
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
SColVal cv = COL_VAL_VALUE(pColVal->cid, pColVal->type, (SValue){0});
|
||||
for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
|
||||
code = tDiskColPutValue(pBuilder, &cv);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal21(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
|
||||
code = tRealloc(&pBuilder->pBitMap, nBit);
|
||||
if (code) return code;
|
||||
|
||||
pBuilder->flag |= HAS_NONE;
|
||||
|
||||
memset(pBuilder->pBitMap, 255, nBit);
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return code;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal30(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
pBuilder->flag |= HAS_VALUE;
|
||||
|
||||
uint8_t *pBitMap = NULL;
|
||||
code = tRealloc(&pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
|
||||
for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
|
||||
SET_BIT2(pBitMap, iVal, GET_BIT1(pBuilder->pBitMap, iVal));
|
||||
}
|
||||
SET_BIT2(pBitMap, pBuilder->nVal, 2);
|
||||
|
||||
tFree(pBuilder->pBitMap);
|
||||
pBuilder->pBitMap = pBitMap;
|
||||
|
||||
SColVal cv = COL_VAL_VALUE(pColVal->cid, pColVal->type, (SValue){0});
|
||||
for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
|
||||
code = tDiskColPutValue(pBuilder, &cv);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal31(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return code;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal32(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
return code;
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal40(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal41(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
pBuilder->flag |= HAS_NONE;
|
||||
|
||||
int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
|
||||
code = tRealloc(&pBuilder->pBitMap, nBit);
|
||||
if (code) return code;
|
||||
|
||||
memset(pBuilder->pBitMap, 255, nBit);
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal42(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
pBuilder->flag |= HAS_NULL;
|
||||
|
||||
int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
|
||||
code = tRealloc(&pBuilder->pBitMap, nBit);
|
||||
if (code) return code;
|
||||
|
||||
memset(pBuilder->pBitMap, 255, nBit);
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal50(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal51(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal52(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
pBuilder->flag |= HAS_NULL;
|
||||
|
||||
uint8_t *pBitMap = NULL;
|
||||
code = tRealloc(&pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
|
||||
for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
|
||||
SET_BIT2(pBitMap, iVal, GET_BIT1(pBuilder->pBitMap, iVal) ? 2 : 0);
|
||||
}
|
||||
SET_BIT2(pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
tFree(pBuilder->pBitMap);
|
||||
pBuilder->pBitMap = pBitMap;
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal60(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal61(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
pBuilder->flag |= HAS_NONE;
|
||||
|
||||
uint8_t *pBitMap = NULL;
|
||||
code = tRealloc(&pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
|
||||
for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
|
||||
SET_BIT2(pBitMap, iVal, GET_BIT1(pBuilder->pBitMap, iVal) ? 2 : 1);
|
||||
}
|
||||
SET_BIT2(pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
tFree(pBuilder->pBitMap);
|
||||
pBuilder->pBitMap = pBitMap;
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal62(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal70(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT2(pBuilder->pBitMap, pBuilder->nVal, 2);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal71(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT2(pBuilder->pBitMap, pBuilder->nVal, 0);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static FORCE_INLINE int32_t tDiskColAddVal72(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tRealloc(&pBuilder->pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
|
||||
if (code) return code;
|
||||
SET_BIT2(pBuilder->pBitMap, pBuilder->nVal, 1);
|
||||
|
||||
return tDiskColPutValue(pBuilder, pColVal);
|
||||
}
|
||||
static int32_t (*tDiskColAddValImpl[8][3])(SDiskColBuilder *pBuilder, SColVal *pColVal) = {
|
||||
{tDiskColAddVal00, tDiskColAddVal01, tDiskColAddVal02}, // 0
|
||||
{tDiskColAddVal10, NULL, tDiskColAddVal12}, // HAS_NONE
|
||||
{tDiskColAddVal20, tDiskColAddVal21, NULL}, // HAS_NULL
|
||||
{tDiskColAddVal30, tDiskColAddVal31, tDiskColAddVal32}, // HAS_NULL|HAS_NONE
|
||||
{tDiskColAddVal40, tDiskColAddVal41, tDiskColAddVal42}, // HAS_VALUE
|
||||
{tDiskColAddVal50, tDiskColAddVal51, tDiskColAddVal52}, // HAS_VALUE|HAS_NONE
|
||||
{tDiskColAddVal60, tDiskColAddVal61, tDiskColAddVal62}, // HAS_VALUE|HAS_NULL
|
||||
{tDiskColAddVal70, tDiskColAddVal71, tDiskColAddVal72} // HAS_VALUE|HAS_NULL|HAS_NONE
|
||||
};
|
||||
// extern void (*tSmaUpdateImpl[])(SColumnDataAgg *pColAgg, SColVal *pColVal, uint8_t *minSet, uint8_t *maxSet);
|
||||
static int32_t tDiskColAddVal(SDiskColBuilder *pBuilder, SColVal *pColVal) {
|
||||
int32_t code = 0;
|
||||
|
||||
if (pBuilder->calcSma) {
|
||||
if (COL_VAL_IS_VALUE(pColVal)) {
|
||||
// tSmaUpdateImpl[pBuilder->type](&pBuilder->sma, pColVal, &pBuilder->minSet, &pBuilder->maxSet);
|
||||
} else {
|
||||
pBuilder->sma.numOfNull++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tDiskColAddValImpl[pBuilder->flag][pColVal->flag]) {
|
||||
code = tDiskColAddValImpl[pBuilder->flag][pColVal->flag](pBuilder, pColVal);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
pBuilder->nVal++;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
// SDiskDataBuilder ================================================
|
||||
int32_t tDiskDataBuilderCreate(SDiskDataBuilder **ppBuilder) {
|
||||
int32_t code = 0;
|
||||
|
||||
*ppBuilder = (SDiskDataBuilder *)taosMemoryCalloc(1, sizeof(SDiskDataBuilder));
|
||||
if (*ppBuilder == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void *tDiskDataBuilderDestroy(SDiskDataBuilder *pBuilder) {
|
||||
if (pBuilder == NULL) return NULL;
|
||||
|
||||
if (pBuilder->pUidC) tCompressorDestroy(pBuilder->pUidC);
|
||||
if (pBuilder->pVerC) tCompressorDestroy(pBuilder->pVerC);
|
||||
if (pBuilder->pKeyC) tCompressorDestroy(pBuilder->pKeyC);
|
||||
|
||||
if (pBuilder->aBuilder) {
|
||||
for (int32_t iBuilder = 0; iBuilder < taosArrayGetSize(pBuilder->aBuilder); iBuilder++) {
|
||||
SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder);
|
||||
tDiskColBuilderDestroy(pDCBuilder);
|
||||
}
|
||||
taosArrayDestroy(pBuilder->aBuilder);
|
||||
}
|
||||
for (int32_t iBuf = 0; iBuf < sizeof(pBuilder->aBuf) / sizeof(pBuilder->aBuf[0]); iBuf++) {
|
||||
tFree(pBuilder->aBuf[iBuf]);
|
||||
}
|
||||
tDiskDataDestroy(&pBuilder->dd);
|
||||
taosMemoryFree(pBuilder);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t tDiskDataBuilderInit(SDiskDataBuilder *pBuilder, STSchema *pTSchema, TABLEID *pId, uint8_t cmprAlg,
|
||||
uint8_t calcSma) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pId->suid || pId->uid);
|
||||
|
||||
pBuilder->suid = pId->suid;
|
||||
pBuilder->uid = pId->uid;
|
||||
pBuilder->nRow = 0;
|
||||
pBuilder->cmprAlg = cmprAlg;
|
||||
pBuilder->calcSma = calcSma;
|
||||
pBuilder->bi = (SBlkInfo){.minUid = INT64_MAX,
|
||||
.maxUid = INT64_MIN,
|
||||
.minKey = TSKEY_MAX,
|
||||
.maxKey = TSKEY_MIN,
|
||||
.minVer = VERSION_MAX,
|
||||
.maxVer = VERSION_MIN,
|
||||
.minTKey = TSDBKEY_MAX,
|
||||
.maxTKey = TSDBKEY_MIN};
|
||||
|
||||
if (pBuilder->pUidC == NULL && (code = tCompressorCreate(&pBuilder->pUidC))) return code;
|
||||
code = tCompressStart(pBuilder->pUidC, TSDB_DATA_TYPE_BIGINT, cmprAlg);
|
||||
if (code) return code;
|
||||
|
||||
if (pBuilder->pVerC == NULL && (code = tCompressorCreate(&pBuilder->pVerC))) return code;
|
||||
code = tCompressStart(pBuilder->pVerC, TSDB_DATA_TYPE_BIGINT, cmprAlg);
|
||||
if (code) return code;
|
||||
|
||||
if (pBuilder->pKeyC == NULL && (code = tCompressorCreate(&pBuilder->pKeyC))) return code;
|
||||
code = tCompressStart(pBuilder->pKeyC, TSDB_DATA_TYPE_TIMESTAMP, cmprAlg);
|
||||
if (code) return code;
|
||||
|
||||
if (pBuilder->aBuilder == NULL) {
|
||||
pBuilder->aBuilder = taosArrayInit(pTSchema->numOfCols - 1, sizeof(SDiskColBuilder));
|
||||
if (pBuilder->aBuilder == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
pBuilder->nBuilder = 0;
|
||||
for (int32_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) {
|
||||
STColumn *pTColumn = &pTSchema->columns[iCol];
|
||||
|
||||
if (pBuilder->nBuilder >= taosArrayGetSize(pBuilder->aBuilder)) {
|
||||
SDiskColBuilder dc = tDiskColBuilderCreate();
|
||||
if (taosArrayPush(pBuilder->aBuilder, &dc) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, pBuilder->nBuilder);
|
||||
|
||||
code = tDiskColBuilderInit(pDCBuilder, pTColumn->colId, pTColumn->type, cmprAlg,
|
||||
(calcSma && (pTColumn->flags & COL_SMA_ON)));
|
||||
if (code) return code;
|
||||
|
||||
pBuilder->nBuilder++;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tDiskDataBuilderClear(SDiskDataBuilder *pBuilder) {
|
||||
int32_t code = 0;
|
||||
pBuilder->suid = 0;
|
||||
pBuilder->uid = 0;
|
||||
pBuilder->nRow = 0;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tDiskDataAddRow(SDiskDataBuilder *pBuilder, TSDBROW *pRow, STSchema *pTSchema, TABLEID *pId) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pBuilder->suid || pBuilder->uid);
|
||||
ASSERT(pId->suid == pBuilder->suid);
|
||||
|
||||
TSDBKEY kRow = TSDBROW_KEY(pRow);
|
||||
if (tsdbKeyCmprFn(&pBuilder->bi.minTKey, &kRow) > 0) pBuilder->bi.minTKey = kRow;
|
||||
if (tsdbKeyCmprFn(&pBuilder->bi.maxTKey, &kRow) < 0) pBuilder->bi.maxTKey = kRow;
|
||||
|
||||
// uid
|
||||
if (pBuilder->uid && pBuilder->uid != pId->uid) {
|
||||
ASSERT(pBuilder->suid);
|
||||
for (int32_t iRow = 0; iRow < pBuilder->nRow; iRow++) {
|
||||
code = tCompress(pBuilder->pUidC, &pBuilder->uid, sizeof(int64_t));
|
||||
if (code) return code;
|
||||
}
|
||||
pBuilder->uid = 0;
|
||||
}
|
||||
if (pBuilder->uid == 0) {
|
||||
code = tCompress(pBuilder->pUidC, &pId->uid, sizeof(int64_t));
|
||||
if (code) return code;
|
||||
}
|
||||
if (pBuilder->bi.minUid > pId->uid) pBuilder->bi.minUid = pId->uid;
|
||||
if (pBuilder->bi.maxUid < pId->uid) pBuilder->bi.maxUid = pId->uid;
|
||||
|
||||
// version
|
||||
code = tCompress(pBuilder->pVerC, &kRow.version, sizeof(int64_t));
|
||||
if (code) return code;
|
||||
if (pBuilder->bi.minVer > kRow.version) pBuilder->bi.minVer = kRow.version;
|
||||
if (pBuilder->bi.maxVer < kRow.version) pBuilder->bi.maxVer = kRow.version;
|
||||
|
||||
// TSKEY
|
||||
code = tCompress(pBuilder->pKeyC, &kRow.ts, sizeof(int64_t));
|
||||
if (code) return code;
|
||||
if (pBuilder->bi.minKey > kRow.ts) pBuilder->bi.minKey = kRow.ts;
|
||||
if (pBuilder->bi.maxKey < kRow.ts) pBuilder->bi.maxKey = kRow.ts;
|
||||
|
||||
STSDBRowIter iter = {0};
|
||||
tsdbRowIterOpen(&iter, pRow, pTSchema);
|
||||
|
||||
SColVal *pColVal = tsdbRowIterNext(&iter);
|
||||
for (int32_t iBuilder = 0; iBuilder < pBuilder->nBuilder; iBuilder++) {
|
||||
SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder);
|
||||
|
||||
while (pColVal && pColVal->cid < pDCBuilder->cid) {
|
||||
pColVal = tsdbRowIterNext(&iter);
|
||||
}
|
||||
|
||||
if (pColVal && pColVal->cid == pDCBuilder->cid) {
|
||||
code = tDiskColAddVal(pDCBuilder, pColVal);
|
||||
if (code) return code;
|
||||
pColVal = tsdbRowIterNext(&iter);
|
||||
} else {
|
||||
code = tDiskColAddVal(pDCBuilder, &COL_VAL_NONE(pDCBuilder->cid, pDCBuilder->type));
|
||||
if (code) return code;
|
||||
}
|
||||
}
|
||||
pBuilder->nRow++;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tGnrtDiskData(SDiskDataBuilder *pBuilder, const SDiskData **ppDiskData, const SBlkInfo **ppBlkInfo) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pBuilder->nRow);
|
||||
|
||||
*ppDiskData = NULL;
|
||||
*ppBlkInfo = NULL;
|
||||
|
||||
SDiskData *pDiskData = &pBuilder->dd;
|
||||
// reset SDiskData
|
||||
pDiskData->hdr = (SDiskDataHdr){.delimiter = TSDB_FILE_DLMT,
|
||||
.fmtVer = 0,
|
||||
.suid = pBuilder->suid,
|
||||
.uid = pBuilder->uid,
|
||||
.szUid = 0,
|
||||
.szVer = 0,
|
||||
.szKey = 0,
|
||||
.szBlkCol = 0,
|
||||
.nRow = pBuilder->nRow,
|
||||
.cmprAlg = pBuilder->cmprAlg};
|
||||
pDiskData->pUid = NULL;
|
||||
pDiskData->pVer = NULL;
|
||||
pDiskData->pKey = NULL;
|
||||
|
||||
// UID
|
||||
if (pBuilder->uid == 0) {
|
||||
code = tCompressEnd(pBuilder->pUidC, &pDiskData->pUid, &pDiskData->hdr.szUid, NULL);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
// VERSION
|
||||
code = tCompressEnd(pBuilder->pVerC, &pDiskData->pVer, &pDiskData->hdr.szVer, NULL);
|
||||
if (code) return code;
|
||||
|
||||
// TSKEY
|
||||
code = tCompressEnd(pBuilder->pKeyC, &pDiskData->pKey, &pDiskData->hdr.szKey, NULL);
|
||||
if (code) return code;
|
||||
|
||||
// aDiskCol
|
||||
if (pDiskData->aDiskCol) {
|
||||
taosArrayClear(pDiskData->aDiskCol);
|
||||
} else {
|
||||
pDiskData->aDiskCol = taosArrayInit(pBuilder->nBuilder, sizeof(SDiskCol));
|
||||
if (pDiskData->aDiskCol == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t offset = 0;
|
||||
for (int32_t iBuilder = 0; iBuilder < pBuilder->nBuilder; iBuilder++) {
|
||||
SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder);
|
||||
|
||||
if (pDCBuilder->flag == HAS_NONE) continue;
|
||||
|
||||
SDiskCol dCol;
|
||||
|
||||
code = tGnrtDiskCol(pDCBuilder, &dCol);
|
||||
if (code) return code;
|
||||
|
||||
dCol.bCol.offset = offset;
|
||||
offset = offset + dCol.bCol.szBitmap + dCol.bCol.szOffset + dCol.bCol.szValue;
|
||||
|
||||
if (taosArrayPush(pDiskData->aDiskCol, &dCol) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
}
|
||||
|
||||
pDiskData->hdr.szBlkCol += tPutBlockCol(NULL, &dCol.bCol);
|
||||
}
|
||||
|
||||
*ppDiskData = pDiskData;
|
||||
*ppBlkInfo = &pBuilder->bi;
|
||||
return code;
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ struct SFSetWriter {
|
|||
|
||||
SSkmInfo skmTb[1];
|
||||
SSkmInfo skmRow[1];
|
||||
uint8_t *bufArr[10];
|
||||
SBuffer buffers[10];
|
||||
|
||||
struct {
|
||||
TABLEID tbid[1];
|
||||
|
|
@ -148,7 +148,7 @@ int32_t tsdbFSetWriterOpen(SFSetWriterConfig *config, SFSetWriter **writer) {
|
|||
.compactVersion = config->compactVersion,
|
||||
.skmTb = writer[0]->skmTb,
|
||||
.skmRow = writer[0]->skmRow,
|
||||
.bufArr = writer[0]->bufArr,
|
||||
.buffers = writer[0]->buffers,
|
||||
};
|
||||
for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX; ++ftype) {
|
||||
dataWriterConfig.files[ftype].exist = config->files[ftype].exist;
|
||||
|
|
@ -172,7 +172,8 @@ int32_t tsdbFSetWriterOpen(SFSetWriterConfig *config, SFSetWriter **writer) {
|
|||
.level = config->level,
|
||||
.skmTb = writer[0]->skmTb,
|
||||
.skmRow = writer[0]->skmRow,
|
||||
.bufArr = writer[0]->bufArr,
|
||||
.buffers = writer[0]->buffers,
|
||||
|
||||
};
|
||||
code = tsdbSttFileWriterOpen(&sttWriterConfig, &writer[0]->sttWriter);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
@ -208,8 +209,8 @@ int32_t tsdbFSetWriterClose(SFSetWriter **writer, bool abort, TFileOpArray *fopA
|
|||
for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->blockData); i++) {
|
||||
tBlockDataDestroy(&writer[0]->blockData[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->bufArr); i++) {
|
||||
tFree(writer[0]->bufArr[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->buffers); i++) {
|
||||
tBufferDestroy(&writer[0]->buffers[i]);
|
||||
}
|
||||
tDestroyTSchema(writer[0]->skmRow->pTSchema);
|
||||
tDestroyTSchema(writer[0]->skmTb->pTSchema);
|
||||
|
|
@ -244,10 +245,11 @@ int32_t tsdbFSetWriteRow(SFSetWriter *writer, SRowInfo *row) {
|
|||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
TSDBKEY key = TSDBROW_KEY(&row->row);
|
||||
if (key.version <= writer->config->compactVersion //
|
||||
&& writer->blockData[writer->blockDataIdx].nRow > 0 //
|
||||
&& key.ts == writer->blockData[writer->blockDataIdx].aTSKEY[writer->blockData[writer->blockDataIdx].nRow - 1]) {
|
||||
if (TSDBROW_VERSION(&row->row) <= writer->config->compactVersion //
|
||||
&& writer->blockData[writer->blockDataIdx].nRow > 0 //
|
||||
&& tsdbRowCompareWithoutVersion(&row->row,
|
||||
&tsdbRowFromBlockData(&writer->blockData[writer->blockDataIdx],
|
||||
writer->blockData[writer->blockDataIdx].nRow - 1)) == 0) {
|
||||
code = tBlockDataUpdateRow(&writer->blockData[writer->blockDataIdx], &row->row, writer->skmRow->pTSchema);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct STsdbIter {
|
|||
} dataData[1];
|
||||
struct {
|
||||
SMemTable *memt;
|
||||
TSDBKEY from[1];
|
||||
STsdbRowKey from[1];
|
||||
SRBTreeIter iter[1];
|
||||
STbData *tbData;
|
||||
STbDataIter tbIter[1];
|
||||
|
|
@ -147,12 +147,11 @@ static int32_t tsdbDataIterNext(STsdbIter *iter, const TABLEID *tbid) {
|
|||
}
|
||||
|
||||
// SBrinBlock
|
||||
if (iter->dataData->brinBlockIdx >= BRIN_BLOCK_SIZE(iter->dataData->brinBlock)) {
|
||||
if (iter->dataData->brinBlockIdx >= iter->dataData->brinBlock->numOfRecords) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (; iter->dataData->brinBlockIdx < BRIN_BLOCK_SIZE(iter->dataData->brinBlock);
|
||||
iter->dataData->brinBlockIdx++) {
|
||||
for (; iter->dataData->brinBlockIdx < iter->dataData->brinBlock->numOfRecords; iter->dataData->brinBlockIdx++) {
|
||||
SBrinRecord record[1];
|
||||
tBrinBlockGet(iter->dataData->brinBlock, iter->dataData->brinBlockIdx, record);
|
||||
|
||||
|
|
@ -255,9 +254,7 @@ _exit:
|
|||
static int32_t tsdbDataTombIterNext(STsdbIter *iter, const TABLEID *tbid) {
|
||||
while (!iter->noMoreData) {
|
||||
for (; iter->dataTomb->tombBlockIdx < TOMB_BLOCK_SIZE(iter->dataTomb->tombBlock); iter->dataTomb->tombBlockIdx++) {
|
||||
iter->record->suid = TARRAY2_GET(iter->dataTomb->tombBlock->suid, iter->dataTomb->tombBlockIdx);
|
||||
iter->record->uid = TARRAY2_GET(iter->dataTomb->tombBlock->uid, iter->dataTomb->tombBlockIdx);
|
||||
iter->record->version = TARRAY2_GET(iter->dataTomb->tombBlock->version, iter->dataTomb->tombBlockIdx);
|
||||
tTombBlockGet(iter->dataTomb->tombBlock, iter->dataTomb->tombBlockIdx, iter->record);
|
||||
|
||||
if (iter->filterByVersion && (iter->record->version < iter->range[0] || iter->record->version > iter->range[1])) {
|
||||
continue;
|
||||
|
|
@ -266,9 +263,6 @@ static int32_t tsdbDataTombIterNext(STsdbIter *iter, const TABLEID *tbid) {
|
|||
if (tbid && iter->record->suid == tbid->suid && iter->record->uid == tbid->uid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iter->record->skey = TARRAY2_GET(iter->dataTomb->tombBlock->skey, iter->dataTomb->tombBlockIdx);
|
||||
iter->record->ekey = TARRAY2_GET(iter->dataTomb->tombBlock->ekey, iter->dataTomb->tombBlockIdx);
|
||||
iter->dataTomb->tombBlockIdx++;
|
||||
goto _exit;
|
||||
}
|
||||
|
|
@ -445,9 +439,7 @@ static int32_t tsdbMemTableIterClose(STsdbIter *iter) { return 0; }
|
|||
static int32_t tsdbSttTombIterNext(STsdbIter *iter, const TABLEID *tbid) {
|
||||
while (!iter->noMoreData) {
|
||||
for (; iter->sttTomb->tombBlockIdx < TOMB_BLOCK_SIZE(iter->sttTomb->tombBlock); iter->sttTomb->tombBlockIdx++) {
|
||||
iter->record->suid = TARRAY2_GET(iter->sttTomb->tombBlock->suid, iter->sttTomb->tombBlockIdx);
|
||||
iter->record->uid = TARRAY2_GET(iter->sttTomb->tombBlock->uid, iter->sttTomb->tombBlockIdx);
|
||||
iter->record->version = TARRAY2_GET(iter->sttTomb->tombBlock->version, iter->sttTomb->tombBlockIdx);
|
||||
tTombBlockGet(iter->sttTomb->tombBlock, iter->sttTomb->tombBlockIdx, iter->record);
|
||||
|
||||
if (iter->filterByVersion && (iter->record->version < iter->range[0] || iter->record->version > iter->range[1])) {
|
||||
continue;
|
||||
|
|
@ -457,8 +449,6 @@ static int32_t tsdbSttTombIterNext(STsdbIter *iter, const TABLEID *tbid) {
|
|||
continue;
|
||||
}
|
||||
|
||||
iter->record->skey = TARRAY2_GET(iter->sttTomb->tombBlock->skey, iter->sttTomb->tombBlockIdx);
|
||||
iter->record->ekey = TARRAY2_GET(iter->sttTomb->tombBlock->ekey, iter->sttTomb->tombBlockIdx);
|
||||
iter->sttTomb->tombBlockIdx++;
|
||||
goto _exit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ typedef struct {
|
|||
SSttFileReader *sttReader; // TSDB_ITER_TYPE_STT || TSDB_ITER_TYPE_STT_TOMB
|
||||
SDataFileReader *dataReader; // TSDB_ITER_TYPE_DATA || TSDB_ITER_TYPE_DATA_TOMB
|
||||
struct {
|
||||
SMemTable *memt; // TSDB_ITER_TYPE_MEMT_TOMB
|
||||
TSDBKEY from[1];
|
||||
SMemTable *memt; // TSDB_ITER_TYPE_MEMT_TOMB
|
||||
STsdbRowKey from[1];
|
||||
}; // TSDB_ITER_TYPE_MEMT
|
||||
};
|
||||
bool filterByVersion;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#define SL_MOVE_BACKWARD 0x1
|
||||
#define SL_MOVE_FROM_POS 0x2
|
||||
|
||||
static void tbDataMovePosTo(STbData *pTbData, SMemSkipListNode **pos, TSDBKEY *pKey, int32_t flags);
|
||||
static void tbDataMovePosTo(STbData *pTbData, SMemSkipListNode **pos, STsdbRowKey *pKey, int32_t flags);
|
||||
static int32_t tsdbGetOrCreateTbData(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, STbData **ppTbData);
|
||||
static int32_t tsdbInsertRowDataToTable(SMemTable *pMemTable, STbData *pTbData, int64_t version,
|
||||
SSubmitTbData *pSubmitTbData, int32_t *affectedRows);
|
||||
|
|
@ -194,18 +194,8 @@ int32_t tsdbDeleteTableData(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid
|
|||
pMemTable->nDel++;
|
||||
pMemTable->minVer = TMIN(pMemTable->minVer, version);
|
||||
pMemTable->maxVer = TMAX(pMemTable->maxVer, version);
|
||||
/*
|
||||
if (TSDB_CACHE_LAST_ROW(pMemTable->pTsdb->pVnode->config) && tsdbKeyCmprFn(&lastKey, &pTbData->maxKey) >= 0) {
|
||||
tsdbCacheDeleteLastrow(pTsdb->lruCache, pTbData->uid, eKey);
|
||||
}
|
||||
|
||||
if (TSDB_CACHE_LAST(pMemTable->pTsdb->pVnode->config)) {
|
||||
tsdbCacheDeleteLast(pTsdb->lruCache, pTbData->uid, eKey);
|
||||
}
|
||||
*/
|
||||
// if (eKey >= pTbData->maxKey && sKey <= pTbData->maxKey) {
|
||||
tsdbCacheDel(pTsdb, suid, uid, sKey, eKey);
|
||||
//}
|
||||
|
||||
tsdbTrace("vgId:%d, delete data from table suid:%" PRId64 " uid:%" PRId64 " skey:%" PRId64 " eKey:%" PRId64
|
||||
" at version %" PRId64,
|
||||
|
|
@ -219,7 +209,7 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbTbDataIterCreate(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter **ppIter) {
|
||||
int32_t tsdbTbDataIterCreate(STbData *pTbData, STsdbRowKey *pFrom, int8_t backward, STbDataIter **ppIter) {
|
||||
int32_t code = 0;
|
||||
|
||||
(*ppIter) = (STbDataIter *)taosMemoryCalloc(1, sizeof(STbDataIter));
|
||||
|
|
@ -241,7 +231,7 @@ void *tsdbTbDataIterDestroy(STbDataIter *pIter) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void tsdbTbDataIterOpen(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter *pIter) {
|
||||
void tsdbTbDataIterOpen(STbData *pTbData, STsdbRowKey *pFrom, int8_t backward, STbDataIter *pIter) {
|
||||
SMemSkipListNode *pos[SL_MAX_LEVEL];
|
||||
SMemSkipListNode *pHead;
|
||||
SMemSkipListNode *pTail;
|
||||
|
|
@ -433,10 +423,10 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
static void tbDataMovePosTo(STbData *pTbData, SMemSkipListNode **pos, TSDBKEY *pKey, int32_t flags) {
|
||||
static void tbDataMovePosTo(STbData *pTbData, SMemSkipListNode **pos, STsdbRowKey *pKey, int32_t flags) {
|
||||
SMemSkipListNode *px;
|
||||
SMemSkipListNode *pn;
|
||||
TSDBKEY tKey = {0};
|
||||
STsdbRowKey tKey;
|
||||
int32_t backward = flags & SL_MOVE_BACKWARD;
|
||||
int32_t fromPos = flags & SL_MOVE_FROM_POS;
|
||||
|
||||
|
|
@ -455,15 +445,9 @@ static void tbDataMovePosTo(STbData *pTbData, SMemSkipListNode **pos, TSDBKEY *p
|
|||
for (int8_t iLevel = pTbData->sl.level - 1; iLevel >= 0; iLevel--) {
|
||||
pn = SL_GET_NODE_BACKWARD(px, iLevel);
|
||||
while (pn != pTbData->sl.pHead) {
|
||||
if (pn->flag == TSDBROW_ROW_FMT) {
|
||||
tKey.version = pn->version;
|
||||
tKey.ts = ((SRow *)pn->pData)->ts;
|
||||
} else if (pn->flag == TSDBROW_COL_FMT) {
|
||||
tKey.version = ((SBlockData *)pn->pData)->aVersion[pn->iRow];
|
||||
tKey.ts = ((SBlockData *)pn->pData)->aTSKEY[pn->iRow];
|
||||
}
|
||||
tsdbRowGetKey(&pn->row, &tKey);
|
||||
|
||||
int32_t c = tsdbKeyCmprFn(&tKey, pKey);
|
||||
int32_t c = tsdbRowKeyCmpr(&tKey, pKey);
|
||||
if (c <= 0) {
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -490,15 +474,9 @@ static void tbDataMovePosTo(STbData *pTbData, SMemSkipListNode **pos, TSDBKEY *p
|
|||
for (int8_t iLevel = pTbData->sl.level - 1; iLevel >= 0; iLevel--) {
|
||||
pn = SL_GET_NODE_FORWARD(px, iLevel);
|
||||
while (pn != pTbData->sl.pTail) {
|
||||
if (pn->flag == TSDBROW_ROW_FMT) {
|
||||
tKey.version = pn->version;
|
||||
tKey.ts = ((SRow *)pn->pData)->ts;
|
||||
} else if (pn->flag == TSDBROW_COL_FMT) {
|
||||
tKey.version = ((SBlockData *)pn->pData)->aVersion[pn->iRow];
|
||||
tKey.ts = ((SBlockData *)pn->pData)->aTSKEY[pn->iRow];
|
||||
}
|
||||
tsdbRowGetKey(&pn->row, &tKey);
|
||||
|
||||
int32_t c = tsdbKeyCmprFn(&tKey, pKey);
|
||||
int32_t c = tsdbRowKeyCmpr(&tKey, pKey);
|
||||
if (c >= 0) {
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -547,16 +525,10 @@ static int32_t tbDataDoPut(SMemTable *pMemTable, STbData *pTbData, SMemSkipListN
|
|||
}
|
||||
|
||||
pNode->level = level;
|
||||
pNode->flag = pRow->type;
|
||||
pNode->row = *pRow;
|
||||
if (pRow->type == TSDBROW_ROW_FMT) {
|
||||
pNode->version = pRow->version;
|
||||
pNode->pData = (char *)pNode + nSize;
|
||||
memcpy(pNode->pData, pRow->pTSRow, pRow->pTSRow->len);
|
||||
} else if (pRow->type == TSDBROW_COL_FMT) {
|
||||
pNode->iRow = pRow->iRow;
|
||||
pNode->pData = pRow->pBlockData;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
pNode->row.pTSRow = (SRow *)((char *)pNode + nSize);
|
||||
memcpy(pNode->row.pTSRow, pRow->pTSRow, pRow->pTSRow->len);
|
||||
}
|
||||
|
||||
// set node
|
||||
|
|
@ -656,13 +628,14 @@ static int32_t tsdbInsertColDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
// loop to add each row to the skiplist
|
||||
SMemSkipListNode *pos[SL_MAX_LEVEL];
|
||||
TSDBROW tRow = tsdbRowFromBlockData(pBlockData, 0);
|
||||
TSDBKEY key = {.version = version, .ts = pBlockData->aTSKEY[0]};
|
||||
STsdbRowKey key;
|
||||
TSDBROW lRow; // last row
|
||||
|
||||
// first row
|
||||
tsdbRowGetKey(&tRow, &key);
|
||||
tbDataMovePosTo(pTbData, pos, &key, SL_MOVE_BACKWARD);
|
||||
if ((code = tbDataDoPut(pMemTable, pTbData, pos, &tRow, 0))) goto _exit;
|
||||
pTbData->minKey = TMIN(pTbData->minKey, key.ts);
|
||||
pTbData->minKey = TMIN(pTbData->minKey, key.key.ts);
|
||||
lRow = tRow;
|
||||
|
||||
// remain row
|
||||
|
|
@ -673,7 +646,7 @@ static int32_t tsdbInsertColDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
}
|
||||
|
||||
while (tRow.iRow < pBlockData->nRow) {
|
||||
key.ts = pBlockData->aTSKEY[tRow.iRow];
|
||||
tsdbRowGetKey(&tRow, &key);
|
||||
|
||||
if (SL_NODE_FORWARD(pos[0], 0) != pTbData->sl.pTail) {
|
||||
tbDataMovePosTo(pTbData, pos, &key, SL_MOVE_FROM_POS);
|
||||
|
|
@ -686,8 +659,8 @@ static int32_t tsdbInsertColDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
}
|
||||
}
|
||||
|
||||
if (key.ts >= pTbData->maxKey) {
|
||||
pTbData->maxKey = key.ts;
|
||||
if (key.key.ts >= pTbData->maxKey) {
|
||||
pTbData->maxKey = key.key.ts;
|
||||
}
|
||||
|
||||
if (!TSDB_CACHE_NO(pMemTable->pTsdb->pVnode->config)) {
|
||||
|
|
@ -711,7 +684,7 @@ static int32_t tsdbInsertRowDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
|
||||
int32_t nRow = TARRAY_SIZE(pSubmitTbData->aRowP);
|
||||
SRow **aRow = (SRow **)TARRAY_DATA(pSubmitTbData->aRowP);
|
||||
TSDBKEY key = {.version = version};
|
||||
STsdbRowKey key;
|
||||
SMemSkipListNode *pos[SL_MAX_LEVEL];
|
||||
TSDBROW tRow = {.type = TSDBROW_ROW_FMT, .version = version};
|
||||
int32_t iRow = 0;
|
||||
|
|
@ -719,13 +692,13 @@ static int32_t tsdbInsertRowDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
|
||||
// backward put first data
|
||||
tRow.pTSRow = aRow[iRow++];
|
||||
key.ts = tRow.pTSRow->ts;
|
||||
tsdbRowGetKey(&tRow, &key);
|
||||
tbDataMovePosTo(pTbData, pos, &key, SL_MOVE_BACKWARD);
|
||||
code = tbDataDoPut(pMemTable, pTbData, pos, &tRow, 0);
|
||||
if (code) goto _exit;
|
||||
lRow = tRow;
|
||||
|
||||
pTbData->minKey = TMIN(pTbData->minKey, key.ts);
|
||||
pTbData->minKey = TMIN(pTbData->minKey, key.key.ts);
|
||||
|
||||
// forward put rest data
|
||||
if (iRow < nRow) {
|
||||
|
|
@ -735,7 +708,7 @@ static int32_t tsdbInsertRowDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
|
||||
while (iRow < nRow) {
|
||||
tRow.pTSRow = aRow[iRow];
|
||||
key.ts = tRow.pTSRow->ts;
|
||||
tsdbRowGetKey(&tRow, &key);
|
||||
|
||||
if (SL_NODE_FORWARD(pos[0], 0) != pTbData->sl.pTail) {
|
||||
tbDataMovePosTo(pTbData, pos, &key, SL_MOVE_FROM_POS);
|
||||
|
|
@ -750,8 +723,8 @@ static int32_t tsdbInsertRowDataToTable(SMemTable *pMemTable, STbData *pTbData,
|
|||
}
|
||||
}
|
||||
|
||||
if (key.ts >= pTbData->maxKey) {
|
||||
pTbData->maxKey = key.ts;
|
||||
if (key.key.ts >= pTbData->maxKey) {
|
||||
pTbData->maxKey = key.key.ts;
|
||||
}
|
||||
if (!TSDB_CACHE_NO(pMemTable->pTsdb->pVnode->config)) {
|
||||
tsdbCacheUpdate(pMemTable->pTsdb, pTbData->suid, pTbData->uid, &lRow);
|
||||
|
|
@ -833,3 +806,26 @@ SArray *tsdbMemTableGetTbDataArray(SMemTable *pMemTable) {
|
|||
_exit:
|
||||
return aTbDataP;
|
||||
}
|
||||
|
||||
TSDBROW *tsdbTbDataIterGet(STbDataIter *pIter) {
|
||||
if (pIter == NULL) return NULL;
|
||||
|
||||
if (pIter->pRow) {
|
||||
return pIter->pRow;
|
||||
}
|
||||
|
||||
if (pIter->backward) {
|
||||
if (pIter->pNode == pIter->pTbData->sl.pHead) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (pIter->pNode == pIter->pTbData->sl.pTail) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pIter->pRow = &pIter->row;
|
||||
pIter->row = pIter->pNode->row;
|
||||
|
||||
return pIter->pRow;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
|
||||
#include "tsdb.h"
|
||||
#include "tsdbFSet2.h"
|
||||
#include "tsdbUtil2.h"
|
||||
#include "tsdbMerge.h"
|
||||
#include "tsdbReadUtil.h"
|
||||
#include "tsdbSttFileRW.h"
|
||||
#include "tsdbUtil2.h"
|
||||
|
||||
static void tLDataIterClose2(SLDataIter *pIter);
|
||||
|
||||
|
|
@ -53,6 +53,13 @@ SSttBlockLoadInfo *tCreateSttBlockLoadInfo(STSchema *pSchema, int16_t *colList,
|
|||
return pLoadInfo;
|
||||
}
|
||||
|
||||
static void freeItem(void* pValue) {
|
||||
SValue* p = (SValue*) pValue;
|
||||
if (IS_VAR_DATA_TYPE(p->type)) {
|
||||
taosMemoryFree(p->pData);
|
||||
}
|
||||
}
|
||||
|
||||
void *destroySttBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo) {
|
||||
if (pLoadInfo == NULL) {
|
||||
return NULL;
|
||||
|
|
@ -60,7 +67,7 @@ void *destroySttBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo) {
|
|||
|
||||
pLoadInfo->currentLoadBlockIndex = 1;
|
||||
|
||||
SBlockDataInfo* pInfo = &pLoadInfo->blockData[0];
|
||||
SBlockDataInfo *pInfo = &pLoadInfo->blockData[0];
|
||||
tBlockDataDestroy(&pInfo->data);
|
||||
pInfo->sttBlockIndex = -1;
|
||||
pInfo->pin = false;
|
||||
|
|
@ -72,9 +79,11 @@ void *destroySttBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo) {
|
|||
|
||||
if (pLoadInfo->info.pCount != NULL) {
|
||||
taosArrayDestroy(pLoadInfo->info.pUid);
|
||||
taosArrayDestroy(pLoadInfo->info.pFirstKey);
|
||||
taosArrayDestroy(pLoadInfo->info.pLastKey);
|
||||
taosArrayDestroyEx(pLoadInfo->info.pFirstKey, freeItem);
|
||||
taosArrayDestroyEx(pLoadInfo->info.pLastKey, freeItem);
|
||||
taosArrayDestroy(pLoadInfo->info.pCount);
|
||||
taosArrayDestroy(pLoadInfo->info.pFirstTs);
|
||||
taosArrayDestroy(pLoadInfo->info.pLastTs);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pLoadInfo->aSttBlk);
|
||||
|
|
@ -88,7 +97,7 @@ void destroyLDataIter(SLDataIter *pIter) {
|
|||
taosMemoryFree(pIter);
|
||||
}
|
||||
|
||||
void *destroySttBlockReader(SArray *pLDataIterArray, SSttBlockLoadCostInfo* pLoadCost) {
|
||||
void *destroySttBlockReader(SArray *pLDataIterArray, SSttBlockLoadCostInfo *pLoadCost) {
|
||||
if (pLDataIterArray == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -115,7 +124,7 @@ void *destroySttBlockReader(SArray *pLDataIterArray, SSttBlockLoadCostInfo* pLoa
|
|||
}
|
||||
|
||||
// choose the unpinned slot to load next data block
|
||||
static void updateBlockLoadSlot(SSttBlockLoadInfo* pLoadInfo) {
|
||||
static void updateBlockLoadSlot(SSttBlockLoadInfo *pLoadInfo) {
|
||||
int32_t nextSlotIndex = pLoadInfo->currentLoadBlockIndex ^ 1;
|
||||
if (pLoadInfo->blockData[nextSlotIndex].pin) {
|
||||
nextSlotIndex = nextSlotIndex ^ 1;
|
||||
|
|
@ -180,7 +189,7 @@ static SBlockData *loadLastBlock(SLDataIter *pIter, const char *idStr) {
|
|||
pInfo->blockData[1].sttBlockIndex, pIter->iRow, idStr);
|
||||
return &pInfo->blockData[pInfo->currentLoadBlockIndex].data;
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
}
|
||||
|
|
@ -317,6 +326,21 @@ static int32_t extractSttBlockInfo(SLDataIter *pIter, const TSttBlkArray *pArray
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tValueDupPayload(SValue *pVal) {
|
||||
if (IS_VAR_DATA_TYPE(pVal->type)) {
|
||||
char *p = (char *)pVal->pData;
|
||||
char *pBuf = taosMemoryMalloc(pVal->nData);
|
||||
if (pBuf == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(pBuf, p, pVal->nData);
|
||||
pVal->pData = (uint8_t *)pBuf;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t loadSttStatisticsBlockData(SSttFileReader *pSttFileReader, SSttBlockLoadInfo *pBlockLoadInfo,
|
||||
TStatisBlkArray *pStatisBlkArray, uint64_t suid, const char *id) {
|
||||
int32_t numOfBlocks = TARRAY2_SIZE(pStatisBlkArray);
|
||||
|
|
@ -325,7 +349,7 @@ static int32_t loadSttStatisticsBlockData(SSttFileReader *pSttFileReader, SSttBl
|
|||
}
|
||||
|
||||
int32_t startIndex = 0;
|
||||
while((startIndex < numOfBlocks) && (pStatisBlkArray->data[startIndex].maxTbid.suid < suid)) {
|
||||
while ((startIndex < numOfBlocks) && (pStatisBlkArray->data[startIndex].maxTbid.suid < suid)) {
|
||||
++startIndex;
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +358,7 @@ static int32_t loadSttStatisticsBlockData(SSttFileReader *pSttFileReader, SSttBl
|
|||
}
|
||||
|
||||
int32_t endIndex = startIndex;
|
||||
while(endIndex < numOfBlocks && pStatisBlkArray->data[endIndex].minTbid.suid <= suid) {
|
||||
while (endIndex < numOfBlocks && pStatisBlkArray->data[endIndex].minTbid.suid <= suid) {
|
||||
++endIndex;
|
||||
}
|
||||
|
||||
|
|
@ -346,12 +370,12 @@ static int32_t loadSttStatisticsBlockData(SSttFileReader *pSttFileReader, SSttBl
|
|||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
for(int32_t k = startIndex; k < endIndex; ++k) {
|
||||
for (int32_t k = startIndex; k < endIndex; ++k) {
|
||||
tsdbSttFileReadStatisBlock(pSttFileReader, &pStatisBlkArray->data[k], &block);
|
||||
|
||||
int32_t i = 0;
|
||||
int32_t rows = TARRAY2_SIZE(block.suid);
|
||||
while (i < rows && block.suid->data[i] != suid) {
|
||||
int32_t rows = block.numOfRecords;
|
||||
while (i < rows && ((int64_t *)block.suids.data)[i] != suid) {
|
||||
++i;
|
||||
}
|
||||
|
||||
|
|
@ -359,22 +383,79 @@ static int32_t loadSttStatisticsBlockData(SSttFileReader *pSttFileReader, SSttBl
|
|||
if (i < rows) {
|
||||
if (pBlockLoadInfo->info.pUid == NULL) {
|
||||
pBlockLoadInfo->info.pUid = taosArrayInit(rows, sizeof(int64_t));
|
||||
pBlockLoadInfo->info.pFirstKey = taosArrayInit(rows, sizeof(int64_t));
|
||||
pBlockLoadInfo->info.pLastKey = taosArrayInit(rows, sizeof(int64_t));
|
||||
pBlockLoadInfo->info.pFirstTs = taosArrayInit(rows, sizeof(int64_t));
|
||||
pBlockLoadInfo->info.pLastTs = taosArrayInit(rows, sizeof(int64_t));
|
||||
pBlockLoadInfo->info.pCount = taosArrayInit(rows, sizeof(int64_t));
|
||||
|
||||
pBlockLoadInfo->info.pFirstKey = taosArrayInit(rows, sizeof(SValue));
|
||||
pBlockLoadInfo->info.pLastKey = taosArrayInit(rows, sizeof(SValue));
|
||||
}
|
||||
|
||||
if (pStatisBlkArray->data[k].maxTbid.suid == suid) {
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pUid, &block.uid->data[i], rows - i);
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pFirstKey, &block.firstKey->data[i], rows - i);
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pLastKey, &block.lastKey->data[i], rows - i);
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pCount, &block.count->data[i], rows - i);
|
||||
int32_t size = rows - i;
|
||||
int32_t offset = i * sizeof(int64_t);
|
||||
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pUid, tBufferGetDataAt(&block.uids, offset), size);
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pFirstTs, tBufferGetDataAt(&block.firstKeyTimestamps, offset), size);
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pLastTs, tBufferGetDataAt(&block.lastKeyTimestamps, offset), size);
|
||||
taosArrayAddBatch(pBlockLoadInfo->info.pCount, tBufferGetDataAt(&block.counts, offset), size);
|
||||
|
||||
if (block.numOfPKs > 0) {
|
||||
SValue vFirst = {0}, vLast = {0};
|
||||
for (int32_t f = i; f < rows; ++f) {
|
||||
int32_t code = tValueColumnGet(&block.firstKeyPKs[0], f, &vFirst);
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
|
||||
tValueDupPayload(&vFirst);
|
||||
taosArrayPush(pBlockLoadInfo->info.pFirstKey, &vFirst);
|
||||
|
||||
// todo add api to clone the original data
|
||||
code = tValueColumnGet(&block.lastKeyPKs[0], f, &vLast);
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
|
||||
tValueDupPayload(&vLast);
|
||||
taosArrayPush(pBlockLoadInfo->info.pLastKey, &vLast);
|
||||
}
|
||||
} else {
|
||||
SValue vFirst = {0};
|
||||
for(int32_t j = 0; j < size; ++j) {
|
||||
taosArrayPush(pBlockLoadInfo->info.pFirstKey, &vFirst);
|
||||
taosArrayPush(pBlockLoadInfo->info.pLastKey, &vFirst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (i < rows && block.suid->data[i] == suid) {
|
||||
taosArrayPush(pBlockLoadInfo->info.pUid, &block.uid->data[i]);
|
||||
taosArrayPush(pBlockLoadInfo->info.pFirstKey, &block.firstKey->data[i]);
|
||||
taosArrayPush(pBlockLoadInfo->info.pLastKey, &block.lastKey->data[i]);
|
||||
taosArrayPush(pBlockLoadInfo->info.pCount, &block.count->data[i]);
|
||||
STbStatisRecord record = {0};
|
||||
|
||||
while (i < rows) {
|
||||
tStatisBlockGet(&block, i, &record);
|
||||
if (record.suid != suid) {
|
||||
break;
|
||||
}
|
||||
|
||||
taosArrayPush(pBlockLoadInfo->info.pUid, &record.uid);
|
||||
taosArrayPush(pBlockLoadInfo->info.pCount, &record.count);
|
||||
|
||||
taosArrayPush(pBlockLoadInfo->info.pFirstTs, &record.firstKey.ts);
|
||||
taosArrayPush(pBlockLoadInfo->info.pLastTs, &record.lastKey.ts);
|
||||
|
||||
if (record.firstKey.numOfPKs > 0) {
|
||||
SValue s = record.firstKey.pks[0];
|
||||
tValueDupPayload(&s);
|
||||
taosArrayPush(pBlockLoadInfo->info.pFirstKey, &s);
|
||||
|
||||
s = record.lastKey.pks[0];
|
||||
tValueDupPayload(&s);
|
||||
taosArrayPush(pBlockLoadInfo->info.pLastKey, &s);
|
||||
} else {
|
||||
SValue v = {0};
|
||||
taosArrayPush(pBlockLoadInfo->info.pFirstKey, &v);
|
||||
taosArrayPush(pBlockLoadInfo->info.pLastKey, &v);
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -433,34 +514,39 @@ static int32_t doLoadSttFilesBlk(SSttBlockLoadInfo *pBlockLoadInfo, SLDataIter *
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t uidComparFn(const void* p1, const void* p2) {
|
||||
static int32_t uidComparFn(const void *p1, const void *p2) {
|
||||
const uint64_t *pFirst = p1;
|
||||
const uint64_t *pVal = p2;
|
||||
|
||||
if (*pFirst == *pVal) {
|
||||
return 0;
|
||||
} else {
|
||||
return *pFirst < *pVal? -1:1;
|
||||
return *pFirst < *pVal ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void setSttInfoForCurrentTable(SSttBlockLoadInfo *pLoadInfo, uint64_t uid, STimeWindow *pTimeWindow,
|
||||
static void setSttInfoForCurrentTable(SSttBlockLoadInfo *pLoadInfo, uint64_t uid, SSttKeyRange *pRange,
|
||||
int64_t *numOfRows) {
|
||||
if (pTimeWindow == NULL || taosArrayGetSize(pLoadInfo->info.pUid) == 0) {
|
||||
if (pRange == NULL || taosArrayGetSize(pLoadInfo->info.pUid) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t index = taosArraySearchIdx(pLoadInfo->info.pUid, &uid, uidComparFn, TD_EQ);
|
||||
if (index >= 0) {
|
||||
pTimeWindow->skey = *(int64_t *)taosArrayGet(pLoadInfo->info.pFirstKey, index);
|
||||
pTimeWindow->ekey = *(int64_t *)taosArrayGet(pLoadInfo->info.pLastKey, index);
|
||||
pRange->skey.ts = *(int64_t *)taosArrayGet(pLoadInfo->info.pFirstTs, index);
|
||||
pRange->ekey.ts = *(int64_t *)taosArrayGet(pLoadInfo->info.pLastTs, index);
|
||||
|
||||
*numOfRows += *(int64_t*) taosArrayGet(pLoadInfo->info.pCount, index);
|
||||
*numOfRows += *(int64_t *)taosArrayGet(pLoadInfo->info.pCount, index);
|
||||
|
||||
if (pRange->skey.numOfPKs > 0) {
|
||||
memcpy(&pRange->skey.pks[0], taosArrayGet(pLoadInfo->info.pFirstKey, index), sizeof(SValue));
|
||||
memcpy(&pRange->ekey.pks[0], taosArrayGet(pLoadInfo->info.pLastKey, index), sizeof(SValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tLDataIterOpen2(SLDataIter *pIter, SSttFileReader *pSttFileReader, int32_t cid, int8_t backward,
|
||||
SMergeTreeConf *pConf, SSttBlockLoadInfo *pBlockLoadInfo, STimeWindow *pTimeWindow,
|
||||
SMergeTreeConf *pConf, SSttBlockLoadInfo *pBlockLoadInfo, SSttKeyRange *pKeyRange,
|
||||
int64_t *numOfRows, const char *idStr) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
|
@ -471,6 +557,8 @@ int32_t tLDataIterOpen2(SLDataIter *pIter, SSttFileReader *pSttFileReader, int32
|
|||
pIter->verRange.maxVer = pConf->verRange.maxVer;
|
||||
pIter->timeWindow.skey = pConf->timewindow.skey;
|
||||
pIter->timeWindow.ekey = pConf->timewindow.ekey;
|
||||
|
||||
pIter->pStartRowKey = pConf->pCurRowKey;
|
||||
pIter->pReader = pSttFileReader;
|
||||
pIter->pBlockLoadInfo = pBlockLoadInfo;
|
||||
|
||||
|
|
@ -489,7 +577,7 @@ int32_t tLDataIterOpen2(SLDataIter *pIter, SSttFileReader *pSttFileReader, int32
|
|||
}
|
||||
}
|
||||
|
||||
setSttInfoForCurrentTable(pBlockLoadInfo, pConf->uid, pTimeWindow, numOfRows);
|
||||
setSttInfoForCurrentTable(pBlockLoadInfo, pConf->uid, pKeyRange, numOfRows);
|
||||
|
||||
// find the start block, actually we could load the position to avoid repeatly searching for the start position when
|
||||
// the skey is updated.
|
||||
|
|
@ -610,17 +698,39 @@ static void findNextValidRow(SLDataIter *pIter, const char *idStr) {
|
|||
}
|
||||
|
||||
int64_t ts = pData->aTSKEY[i];
|
||||
if (!pIter->backward) { // asc
|
||||
if (!pIter->backward) { // asc
|
||||
if (ts > pIter->timeWindow.ekey) { // no more data
|
||||
break;
|
||||
} else if (ts < pIter->timeWindow.skey) {
|
||||
continue;
|
||||
} else {
|
||||
if (ts < pIter->timeWindow.skey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ts == pIter->timeWindow.skey && pIter->pStartRowKey->numOfPKs > 0) {
|
||||
SRowKey key;
|
||||
tColRowGetKey(pData, i, &key);
|
||||
int32_t ret = pkCompEx(&key, pIter->pStartRowKey);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ts < pIter->timeWindow.skey) {
|
||||
break;
|
||||
} else if (ts > pIter->timeWindow.ekey) {
|
||||
continue;
|
||||
} else {
|
||||
if (ts > pIter->timeWindow.ekey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ts == pIter->timeWindow.ekey && pIter->pStartRowKey->numOfPKs > 0) {
|
||||
SRowKey key;
|
||||
tColRowGetKey(pData, i, &key);
|
||||
int32_t ret = pkCompEx(&key, pIter->pStartRowKey);
|
||||
if (ret > 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,7 +819,7 @@ bool tLDataIterNextRow(SLDataIter *pIter, const char *idStr) {
|
|||
pIter->rInfo.uid = pBlockData->uid;
|
||||
pIter->rInfo.row = tsdbRowFromBlockData(pBlockData, pIter->iRow);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
return (terrno == TSDB_CODE_SUCCESS) && (pIter->pSttBlk != NULL) && (pBlockData != NULL);
|
||||
}
|
||||
|
||||
|
|
@ -740,7 +850,7 @@ static FORCE_INLINE int32_t tLDataIterDescCmprFn(const SRBTreeNode *p1, const SR
|
|||
return -1 * tLDataIterCmprFn(p1, p2);
|
||||
}
|
||||
|
||||
int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoForTable* pSttDataInfo) {
|
||||
int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoForTable *pSttDataInfo) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
pMTree->pIter = NULL;
|
||||
|
|
@ -765,12 +875,12 @@ int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoF
|
|||
|
||||
for (int32_t j = 0; j < numOfLevels; ++j) {
|
||||
SSttLvl *pSttLevel = ((STFileSet *)pConf->pCurrentFileset)->lvlArr->data[j];
|
||||
SArray * pList = taosArrayGetP(pConf->pSttFileBlockIterArray, j);
|
||||
SArray *pList = taosArrayGetP(pConf->pSttFileBlockIterArray, j);
|
||||
|
||||
for (int32_t i = 0; i < TARRAY2_SIZE(pSttLevel->fobjArr); ++i) { // open all last file
|
||||
SLDataIter *pIter = taosArrayGetP(pList, i);
|
||||
|
||||
SSttFileReader * pSttFileReader = pIter->pReader;
|
||||
SSttFileReader *pSttFileReader = pIter->pReader;
|
||||
SSttBlockLoadInfo *pLoadInfo = pIter->pBlockLoadInfo;
|
||||
|
||||
// open stt file reader if not opened yet
|
||||
|
|
@ -792,11 +902,12 @@ int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoF
|
|||
|
||||
memset(pIter, 0, sizeof(SLDataIter));
|
||||
|
||||
STimeWindow w = {0};
|
||||
int64_t numOfRows = 0;
|
||||
SSttKeyRange range = {.skey.numOfPKs = pConf->pCurRowKey->numOfPKs, .ekey.numOfPKs = pConf->pCurRowKey->numOfPKs};
|
||||
int64_t numOfRows = 0;
|
||||
int64_t cid = pSttLevel->fobjArr->data[i]->f->cid;
|
||||
|
||||
int64_t cid = pSttLevel->fobjArr->data[i]->f->cid;
|
||||
code = tLDataIterOpen2(pIter, pSttFileReader, cid, pMTree->backward, pConf, pLoadInfo, &w, &numOfRows, pMTree->idStr);
|
||||
code = tLDataIterOpen2(pIter, pSttFileReader, cid, pMTree->backward, pConf, pLoadInfo, &range, &numOfRows,
|
||||
pMTree->idStr);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
}
|
||||
|
|
@ -807,7 +918,7 @@ int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoF
|
|||
|
||||
// let's record the time window for current table of uid in the stt files
|
||||
if (pSttDataInfo != NULL && numOfRows > 0) {
|
||||
taosArrayPush(pSttDataInfo->pTimeWindowList, &w);
|
||||
taosArrayPush(pSttDataInfo->pKeyRangeList, &range);
|
||||
pSttDataInfo->numOfRows += numOfRows;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -820,7 +931,7 @@ int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoF
|
|||
|
||||
return code;
|
||||
|
||||
_end:
|
||||
_end:
|
||||
tMergeTreeClose(pMTree);
|
||||
return code;
|
||||
}
|
||||
|
|
@ -829,8 +940,8 @@ void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter) { tRBTreePut(&pMTr
|
|||
|
||||
bool tMergeTreeIgnoreEarlierTs(SMergeTree *pMTree) { return pMTree->ignoreEarlierTs; }
|
||||
|
||||
static void tLDataIterPinSttBlock(SLDataIter* pIter, const char* id) {
|
||||
SSttBlockLoadInfo* pInfo = pIter->pBlockLoadInfo;
|
||||
static void tLDataIterPinSttBlock(SLDataIter *pIter, const char *id) {
|
||||
SSttBlockLoadInfo *pInfo = pIter->pBlockLoadInfo;
|
||||
|
||||
if (pInfo->blockData[0].sttBlockIndex == pIter->iSttBlk) {
|
||||
pInfo->blockData[0].pin = true;
|
||||
|
|
@ -842,15 +953,15 @@ static void tLDataIterPinSttBlock(SLDataIter* pIter, const char* id) {
|
|||
if (pInfo->blockData[1].sttBlockIndex == pIter->iSttBlk) {
|
||||
pInfo->blockData[1].pin = true;
|
||||
ASSERT(!pInfo->blockData[0].pin);
|
||||
tsdbTrace("pin stt-block, blockIndex:%d, stt-fileVer:%"PRId64" %s", pIter->iSttBlk, pIter->cid, id);
|
||||
tsdbTrace("pin stt-block, blockIndex:%d, stt-fileVer:%" PRId64 " %s", pIter->iSttBlk, pIter->cid, id);
|
||||
return;
|
||||
}
|
||||
|
||||
tsdbError("failed to pin any stt block, sttBlock:%d stt-fileVer:%"PRId64" %s", pIter->iSttBlk, pIter->cid, id);
|
||||
tsdbError("failed to pin any stt block, sttBlock:%d stt-fileVer:%" PRId64 " %s", pIter->iSttBlk, pIter->cid, id);
|
||||
}
|
||||
|
||||
static void tLDataIterUnpinSttBlock(SLDataIter* pIter, const char* id) {
|
||||
SSttBlockLoadInfo* pInfo = pIter->pBlockLoadInfo;
|
||||
static void tLDataIterUnpinSttBlock(SLDataIter *pIter, const char *id) {
|
||||
SSttBlockLoadInfo *pInfo = pIter->pBlockLoadInfo;
|
||||
if (pInfo->blockData[0].pin) {
|
||||
ASSERT(!pInfo->blockData[1].pin);
|
||||
pInfo->blockData[0].pin = false;
|
||||
|
|
@ -883,7 +994,7 @@ void tMergeTreeUnpinSttBlock(SMergeTree *pMTree) {
|
|||
return;
|
||||
}
|
||||
|
||||
SLDataIter* pIter = pMTree->pPinnedBlockIter;
|
||||
SLDataIter *pIter = pMTree->pPinnedBlockIter;
|
||||
pMTree->pPinnedBlockIter = NULL;
|
||||
tLDataIterUnpinSttBlock(pIter, pMTree->idStr);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "tsdbReadUtil.h"
|
||||
#include "osDef.h"
|
||||
#include "tsdb.h"
|
||||
#include "tsdbDataFileRW.h"
|
||||
#include "tsdbFS2.h"
|
||||
|
|
@ -131,6 +130,92 @@ STableBlockScanInfo* getTableBlockScanInfo(SSHashObj* pTableMap, uint64_t uid, c
|
|||
return *p;
|
||||
}
|
||||
|
||||
int32_t initRowKey(SRowKey* pKey, int64_t ts, int32_t numOfPks, int32_t type, int32_t len, bool asc) {
|
||||
pKey->numOfPKs = numOfPks;
|
||||
pKey->ts = ts;
|
||||
|
||||
if (numOfPks > 0) {
|
||||
pKey->pks[0].type = type;
|
||||
if (IS_NUMERIC_TYPE(pKey->pks[0].type)) {
|
||||
if (asc) {
|
||||
switch(pKey->pks[0].type) {
|
||||
case TSDB_DATA_TYPE_BIGINT:pKey->pks[0].val = INT64_MIN;break;
|
||||
case TSDB_DATA_TYPE_INT:pKey->pks[0].val = INT32_MIN;break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:pKey->pks[0].val = INT16_MIN;break;
|
||||
case TSDB_DATA_TYPE_TINYINT:pKey->pks[0].val = INT8_MIN;break;
|
||||
}
|
||||
} else {
|
||||
switch(pKey->pks[0].type) {
|
||||
case TSDB_DATA_TYPE_BIGINT:pKey->pks[0].val = INT64_MAX;break;
|
||||
case TSDB_DATA_TYPE_INT:pKey->pks[0].val = INT32_MAX;break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:pKey->pks[0].val = INT16_MAX;break;
|
||||
case TSDB_DATA_TYPE_TINYINT:pKey->pks[0].val = INT8_MAX;break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pKey->pks[0].pData = taosMemoryCalloc(1, len);
|
||||
pKey->pks[0].nData = 0;
|
||||
|
||||
if (pKey->pks[0].pData == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return terrno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void clearRowKey(SRowKey* pKey) {
|
||||
if (pKey == NULL || pKey->numOfPKs == 0 || (!IS_VAR_DATA_TYPE(pKey->pks[0].type))) {
|
||||
return;
|
||||
}
|
||||
taosMemoryFreeClear(pKey->pks[0].pData);
|
||||
}
|
||||
|
||||
static void initLastProcKey(STableBlockScanInfo *pScanInfo, STsdbReader* pReader) {
|
||||
int32_t numOfPks = pReader->suppInfo.numOfPks;
|
||||
bool asc = ASCENDING_TRAVERSE(pReader->info.order);
|
||||
int8_t type = pReader->suppInfo.pk.type;
|
||||
int8_t bytes = pReader->suppInfo.pk.bytes;
|
||||
|
||||
SRowKey* pRowKey = &pScanInfo->lastProcKey;
|
||||
if (asc) {
|
||||
int64_t skey = pReader->info.window.skey;
|
||||
int64_t ts = (skey > INT64_MIN) ? (skey - 1) : skey;
|
||||
|
||||
initRowKey(pRowKey, ts, numOfPks, type, bytes, asc);
|
||||
initRowKey(&pScanInfo->sttKeyInfo.nextProcKey, skey, numOfPks, type, bytes, asc);
|
||||
} else {
|
||||
int64_t ekey = pReader->info.window.ekey;
|
||||
int64_t ts = (ekey < INT64_MAX) ? (ekey + 1) : ekey;
|
||||
|
||||
initRowKey(pRowKey, ts, numOfPks, type, bytes, asc);
|
||||
initRowKey(&pScanInfo->sttKeyInfo.nextProcKey, ekey, numOfPks, type, bytes, asc);
|
||||
}
|
||||
|
||||
initRowKey(&pScanInfo->sttRange.skey, INT64_MAX, numOfPks, type, bytes, asc);
|
||||
initRowKey(&pScanInfo->sttRange.ekey, INT64_MIN, numOfPks, type, bytes, asc);
|
||||
}
|
||||
|
||||
int32_t initTableBlockScanInfo(STableBlockScanInfo* pScanInfo, uint64_t uid, SSHashObj* pTableMap,
|
||||
STsdbReader* pReader) {
|
||||
pScanInfo->uid = uid;
|
||||
INIT_KEYRANGE(&pScanInfo->sttRange);
|
||||
INIT_TIMEWINDOW(&pScanInfo->filesetWindow);
|
||||
|
||||
pScanInfo->cleanSttBlocks = false;
|
||||
pScanInfo->sttBlockReturned = false;
|
||||
|
||||
initLastProcKey(pScanInfo, pReader);
|
||||
|
||||
pScanInfo->sttKeyInfo.status = STT_FILE_READER_UNINIT;
|
||||
tSimpleHashPut(pTableMap, &pScanInfo->uid, sizeof(uint64_t), &pScanInfo, POINTER_BYTES);
|
||||
tsdbTrace("%p check table uid:%" PRId64 " from lastKey:%" PRId64 " %s", pReader, pScanInfo->uid,
|
||||
pScanInfo->lastProcKey.ts, pReader->idStr);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// NOTE: speedup the whole processing by preparing the buffer for STableBlockScanInfo in batch model
|
||||
SSHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList,
|
||||
STableUidList* pUidList, int32_t numOfTables) {
|
||||
|
|
@ -153,31 +238,10 @@ SSHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf
|
|||
pUidList->currentIndex = 0;
|
||||
|
||||
for (int32_t j = 0; j < numOfTables; ++j) {
|
||||
STableBlockScanInfo* pScanInfo = getPosInBlockInfoBuf(pBuf, j);
|
||||
|
||||
pScanInfo->uid = idList[j].uid;
|
||||
INIT_TIMEWINDOW(&pScanInfo->sttWindow);
|
||||
INIT_TIMEWINDOW(&pScanInfo->filesetWindow);
|
||||
|
||||
pScanInfo->cleanSttBlocks = false;
|
||||
pScanInfo->sttBlockReturned = false;
|
||||
|
||||
pUidList->tableUidList[j] = idList[j].uid;
|
||||
|
||||
if (ASCENDING_TRAVERSE(pTsdbReader->info.order)) {
|
||||
int64_t skey = pTsdbReader->info.window.skey;
|
||||
pScanInfo->lastProcKey = (skey > INT64_MIN) ? (skey - 1) : skey;
|
||||
pScanInfo->sttKeyInfo.nextProcKey = skey;
|
||||
} else {
|
||||
int64_t ekey = pTsdbReader->info.window.ekey;
|
||||
pScanInfo->lastProcKey = (ekey < INT64_MAX) ? (ekey + 1) : ekey;
|
||||
pScanInfo->sttKeyInfo.nextProcKey = ekey;
|
||||
}
|
||||
|
||||
pScanInfo->sttKeyInfo.status = STT_FILE_READER_UNINIT;
|
||||
tSimpleHashPut(pTableMap, &pScanInfo->uid, sizeof(uint64_t), &pScanInfo, POINTER_BYTES);
|
||||
tsdbTrace("%p check table uid:%" PRId64 " from lastKey:%" PRId64 " %s", pTsdbReader, pScanInfo->uid,
|
||||
pScanInfo->lastProcKey, pTsdbReader->idStr);
|
||||
STableBlockScanInfo* pScanInfo = getPosInBlockInfoBuf(pBuf, j);
|
||||
initTableBlockScanInfo(pScanInfo, idList[j].uid, pTableMap, pTsdbReader);
|
||||
}
|
||||
|
||||
taosSort(pUidList->tableUidList, numOfTables, sizeof(uint64_t), uidComparFunc);
|
||||
|
|
@ -210,8 +274,9 @@ void resetAllDataBlockScanInfo(SSHashObj* pTableMap, int64_t ts, int32_t step) {
|
|||
}
|
||||
|
||||
pInfo->delSkyline = taosArrayDestroy(pInfo->delSkyline);
|
||||
pInfo->lastProcKey = ts;
|
||||
pInfo->sttKeyInfo.nextProcKey = ts + step;
|
||||
pInfo->lastProcKey.ts = ts;
|
||||
// todo check the nextProcKey info
|
||||
pInfo->sttKeyInfo.nextProcKey.ts = ts + step;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,6 +299,11 @@ void clearBlockScanInfo(STableBlockScanInfo* p) {
|
|||
p->pBlockIdxList = taosArrayDestroy(p->pBlockIdxList);
|
||||
p->pMemDelData = taosArrayDestroy(p->pMemDelData);
|
||||
p->pFileDelData = taosArrayDestroy(p->pFileDelData);
|
||||
|
||||
clearRowKey(&p->lastProcKey);
|
||||
clearRowKey(&p->sttRange.skey);
|
||||
clearRowKey(&p->sttRange.ekey);
|
||||
clearRowKey(&p->sttKeyInfo.nextProcKey);
|
||||
}
|
||||
|
||||
void destroyAllBlockScanInfo(SSHashObj* pTableMap) {
|
||||
|
|
@ -255,7 +325,7 @@ static void doCleanupInfoForNextFileset(STableBlockScanInfo* pScanInfo) {
|
|||
pScanInfo->cleanSttBlocks = false;
|
||||
pScanInfo->numOfRowsInStt = 0;
|
||||
pScanInfo->sttBlockReturned = false;
|
||||
INIT_TIMEWINDOW(&pScanInfo->sttWindow);
|
||||
INIT_KEYRANGE(&pScanInfo->sttRange);
|
||||
INIT_TIMEWINDOW(&pScanInfo->filesetWindow);
|
||||
pScanInfo->sttKeyInfo.status = STT_FILE_READER_UNINIT;
|
||||
}
|
||||
|
|
@ -281,7 +351,7 @@ void initBrinRecordIter(SBrinRecordIter* pIter, SDataFileReader* pReader, SArray
|
|||
}
|
||||
|
||||
SBrinRecord* getNextBrinRecord(SBrinRecordIter* pIter) {
|
||||
if (pIter->blockIndex == -1 || (pIter->recordIndex + 1) >= TARRAY2_SIZE(pIter->block.numRow)) {
|
||||
if (pIter->blockIndex == -1 || (pIter->recordIndex + 1) >= pIter->block.numOfRecords) {
|
||||
pIter->blockIndex += 1;
|
||||
if (pIter->blockIndex >= taosArrayGetSize(pIter->pBrinBlockList)) {
|
||||
return NULL;
|
||||
|
|
@ -356,10 +426,10 @@ static int32_t fileDataBlockOrderCompar(const void* pLeft, const void* pRight, v
|
|||
return pLeftBlock->offset > pRightBlock->offset ? 1 : -1;
|
||||
}
|
||||
|
||||
static void recordToBlockInfo(SFileDataBlockInfo* pBlockInfo, SBrinRecord* record){
|
||||
void recordToBlockInfo(SFileDataBlockInfo* pBlockInfo, SBrinRecord* record) {
|
||||
pBlockInfo->uid = record->uid;
|
||||
pBlockInfo->firstKey = record->firstKey;
|
||||
pBlockInfo->lastKey = record->lastKey;
|
||||
pBlockInfo->firstKey = record->firstKey.key.ts;
|
||||
pBlockInfo->lastKey = record->lastKey.key.ts;
|
||||
pBlockInfo->minVer = record->minVer;
|
||||
pBlockInfo->maxVer = record->maxVer;
|
||||
pBlockInfo->blockOffset = record->blockOffset;
|
||||
|
|
@ -369,16 +439,61 @@ static void recordToBlockInfo(SFileDataBlockInfo* pBlockInfo, SBrinRecord* recor
|
|||
pBlockInfo->smaSize = record->smaSize;
|
||||
pBlockInfo->numRow = record->numRow;
|
||||
pBlockInfo->count = record->count;
|
||||
|
||||
SRowKey* pFirstKey = &record->firstKey.key;
|
||||
if (pFirstKey->numOfPKs > 0) {
|
||||
if (IS_NUMERIC_TYPE(pFirstKey->pks[0].type)) {
|
||||
pBlockInfo->firstPk.val = pFirstKey->pks[0].val;
|
||||
pBlockInfo->lastPk.val = record->lastKey.key.pks[0].val;
|
||||
} else {
|
||||
char* p = taosMemoryCalloc(1, pFirstKey->pks[0].nData + VARSTR_HEADER_SIZE);
|
||||
memcpy(varDataVal(p), pFirstKey->pks[0].pData, pFirstKey->pks[0].nData);
|
||||
varDataSetLen(p, pFirstKey->pks[0].nData);
|
||||
pBlockInfo->firstPk.pData = (uint8_t*)p;
|
||||
|
||||
int32_t keyLen = record->lastKey.key.pks[0].nData;
|
||||
p = taosMemoryCalloc(1, keyLen + VARSTR_HEADER_SIZE);
|
||||
memcpy(varDataVal(p), record->lastKey.key.pks[0].pData, keyLen);
|
||||
varDataSetLen(p, keyLen);
|
||||
pBlockInfo->lastPk.pData = (uint8_t*)p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void freePkItem(void* pItem) {
|
||||
SFileDataBlockInfo* p = pItem;
|
||||
taosMemoryFreeClear(p->firstPk.pData);
|
||||
taosMemoryFreeClear(p->lastPk.pData);
|
||||
}
|
||||
|
||||
void clearDataBlockIterator(SDataBlockIter* pIter, bool needFree) {
|
||||
pIter->index = -1;
|
||||
pIter->numOfBlocks = 0;
|
||||
|
||||
if (needFree) {
|
||||
taosArrayClearEx(pIter->blockList, freePkItem);
|
||||
} else {
|
||||
taosArrayClear(pIter->blockList);
|
||||
}
|
||||
}
|
||||
|
||||
void cleanupDataBlockIterator(SDataBlockIter* pIter, bool needFree) {
|
||||
pIter->index = -1;
|
||||
pIter->numOfBlocks = 0;
|
||||
if (needFree) {
|
||||
taosArrayDestroyEx(pIter->blockList, freePkItem);
|
||||
} else {
|
||||
taosArrayDestroy(pIter->blockList);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int32_t numOfBlocks, SArray* pTableList) {
|
||||
bool asc = ASCENDING_TRAVERSE(pReader->info.order);
|
||||
|
||||
SBlockOrderSupporter sup = {0};
|
||||
pBlockIter->numOfBlocks = numOfBlocks;
|
||||
taosArrayClear(pBlockIter->blockList);
|
||||
clearDataBlockIterator(pBlockIter, shouldFreePkBuf(&pReader->suppInfo));
|
||||
|
||||
pBlockIter->pTableMap = pReader->status.pTableMap;
|
||||
pBlockIter->numOfBlocks = numOfBlocks;
|
||||
|
||||
// access data blocks according to the offset of each block in asc/desc order.
|
||||
int32_t numOfTables = taosArrayGetSize(pTableList);
|
||||
|
|
@ -393,7 +508,6 @@ int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int3
|
|||
|
||||
for (int32_t i = 0; i < numOfTables; ++i) {
|
||||
STableBlockScanInfo* pTableScanInfo = taosArrayGetP(pTableList, i);
|
||||
// ASSERT(pTableScanInfo->pBlockList != NULL && taosArrayGetSize(pTableScanInfo->pBlockList) > 0);
|
||||
|
||||
size_t num = taosArrayGetSize(pTableScanInfo->pBlockList);
|
||||
sup.numOfBlocksPerTable[sup.numOfTables] = num;
|
||||
|
|
@ -407,9 +521,9 @@ int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int3
|
|||
sup.pDataBlockInfo[sup.numOfTables] = (SBlockOrderWrapper*)buf;
|
||||
|
||||
for (int32_t k = 0; k < num; ++k) {
|
||||
SBrinRecord* pRecord = taosArrayGet(pTableScanInfo->pBlockList, k);
|
||||
SFileDataBlockInfo* pBlockInfo = taosArrayGet(pTableScanInfo->pBlockList, k);
|
||||
sup.pDataBlockInfo[sup.numOfTables][k] =
|
||||
(SBlockOrderWrapper){.uid = pTableScanInfo->uid, .offset = pRecord->blockOffset, .pInfo = pTableScanInfo};
|
||||
(SBlockOrderWrapper){.uid = pTableScanInfo->uid, .offset = pBlockInfo->blockOffset, .pInfo = pTableScanInfo};
|
||||
cnt++;
|
||||
}
|
||||
|
||||
|
|
@ -424,18 +538,12 @@ int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int3
|
|||
// since there is only one table qualified, blocks are not sorted
|
||||
if (sup.numOfTables == 1) {
|
||||
STableBlockScanInfo* pTableScanInfo = taosArrayGetP(pTableList, 0);
|
||||
if (pTableScanInfo->pBlockIdxList == NULL) {
|
||||
pTableScanInfo->pBlockIdxList = taosArrayInit(numOfBlocks, sizeof(STableDataBlockIdx));
|
||||
}
|
||||
for (int32_t i = 0; i < numOfBlocks; ++i) {
|
||||
SFileDataBlockInfo blockInfo = {.tbBlockIdx = i};
|
||||
SBrinRecord* record = (SBrinRecord*)taosArrayGet(sup.pDataBlockInfo[0][i].pInfo->pBlockList, i);
|
||||
recordToBlockInfo(&blockInfo, record);
|
||||
|
||||
taosArrayPush(pBlockIter->blockList, &blockInfo);
|
||||
STableDataBlockIdx tableDataBlockIdx = {.globalIndex = i};
|
||||
taosArrayPush(pTableScanInfo->pBlockIdxList, &tableDataBlockIdx);
|
||||
}
|
||||
|
||||
taosArrayAddAll(pBlockIter->blockList, pTableScanInfo->pBlockList);
|
||||
pTableScanInfo->pBlockList = taosArrayDestroy(pTableScanInfo->pBlockList);
|
||||
|
||||
int64_t et = taosGetTimestampUs();
|
||||
|
|
@ -463,18 +571,13 @@ int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int3
|
|||
int32_t pos = tMergeTreeGetChosenIndex(pTree);
|
||||
int32_t index = sup.indexPerTable[pos]++;
|
||||
|
||||
SFileDataBlockInfo blockInfo = {.tbBlockIdx = index};
|
||||
SBrinRecord* record = (SBrinRecord*)taosArrayGet(sup.pDataBlockInfo[pos][index].pInfo->pBlockList, index);
|
||||
recordToBlockInfo(&blockInfo, record);
|
||||
SFileDataBlockInfo* pBlockInfo = taosArrayGet(sup.pDataBlockInfo[pos][index].pInfo->pBlockList, index);
|
||||
taosArrayPush(pBlockIter->blockList, pBlockInfo);
|
||||
|
||||
taosArrayPush(pBlockIter->blockList, &blockInfo);
|
||||
STableBlockScanInfo* pTableScanInfo = sup.pDataBlockInfo[pos][index].pInfo;
|
||||
if (pTableScanInfo->pBlockIdxList == NULL) {
|
||||
size_t szTableDataBlocks = taosArrayGetSize(pTableScanInfo->pBlockList);
|
||||
pTableScanInfo->pBlockIdxList = taosArrayInit(szTableDataBlocks, sizeof(STableDataBlockIdx));
|
||||
}
|
||||
STableDataBlockIdx tableDataBlockIdx = {.globalIndex = numOfTotal};
|
||||
STableDataBlockIdx tableDataBlockIdx = {.globalIndex = numOfTotal};
|
||||
taosArrayPush(pTableScanInfo->pBlockIdxList, &tableDataBlockIdx);
|
||||
|
||||
// set data block index overflow, in order to disable the offset comparator
|
||||
if (sup.indexPerTable[pos] >= sup.numOfBlocksPerTable[pos]) {
|
||||
sup.indexPerTable[pos] = sup.numOfBlocksPerTable[pos] + 1;
|
||||
|
|
@ -529,7 +632,7 @@ static int32_t doCheckTombBlock(STombBlock* pBlock, STsdbReader* pReader, int32_
|
|||
pScanInfo->pFileDelData = taosArrayInit(4, sizeof(SDelData));
|
||||
}
|
||||
|
||||
for (int32_t k = 0; k < TARRAY2_SIZE(pBlock->suid); ++k) {
|
||||
for (int32_t k = 0; k < pBlock->numOfRecords; ++k) {
|
||||
code = tTombBlockGet(pBlock, k, &record);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
*pRet = BLK_CHECK_QUIT;
|
||||
|
|
@ -722,11 +825,11 @@ int32_t getNumOfRowsInSttBlock(SSttFileReader* pSttFileReader, SSttBlockLoadInfo
|
|||
pBlockLoadInfo->cost.statisElapsedTime += el;
|
||||
|
||||
int32_t index = 0;
|
||||
while (index < TARRAY2_SIZE(pStatisBlock->suid) && pStatisBlock->suid->data[index] < suid) {
|
||||
while (index < pStatisBlock->numOfRecords && ((int64_t*)pStatisBlock->suids.data)[index] < suid) {
|
||||
++index;
|
||||
}
|
||||
|
||||
if (index >= TARRAY2_SIZE(pStatisBlock->suid)) {
|
||||
if (index >= pStatisBlock->numOfRecords) {
|
||||
tStatisBlockDestroy(pStatisBlock);
|
||||
taosMemoryFreeClear(pStatisBlock);
|
||||
return num;
|
||||
|
|
@ -744,14 +847,14 @@ int32_t getNumOfRowsInSttBlock(SSttFileReader* pSttFileReader, SSttBlockLoadInfo
|
|||
|
||||
uint64_t uid = pUidList[uidIndex];
|
||||
|
||||
if (pStatisBlock->uid->data[j] == uid) {
|
||||
num += pStatisBlock->count->data[j];
|
||||
if (((int64_t*)pStatisBlock->uids.data)[j] == uid) {
|
||||
num += ((int64_t*)pStatisBlock->counts.data)[j];
|
||||
uidIndex += 1;
|
||||
j += 1;
|
||||
loadNextStatisticsBlock(pSttFileReader, pStatisBlock, pStatisBlkArray, pStatisBlock->suid->size, &i, &j);
|
||||
} else if (pStatisBlock->uid->data[j] < uid) {
|
||||
loadNextStatisticsBlock(pSttFileReader, pStatisBlock, pStatisBlkArray, pStatisBlock->numOfRecords, &i, &j);
|
||||
} else if (((int64_t*)pStatisBlock->uids.data)[j] < uid) {
|
||||
j += 1;
|
||||
loadNextStatisticsBlock(pSttFileReader, pStatisBlock, pStatisBlkArray, pStatisBlock->suid->size, &i, &j);
|
||||
loadNextStatisticsBlock(pSttFileReader, pStatisBlock, pStatisBlkArray, pStatisBlock->numOfRecords, &i, &j);
|
||||
} else {
|
||||
uidIndex += 1;
|
||||
}
|
||||
|
|
@ -915,39 +1018,39 @@ static bool overlapWithTimeWindow(STimeWindow* p1, STimeWindow* pQueryWindow, ST
|
|||
}
|
||||
|
||||
static int32_t sortUidComparFn(const void* p1, const void* p2) {
|
||||
const STimeWindow* px1 = p1;
|
||||
const STimeWindow* px2 = p2;
|
||||
if (px1->skey == px2->skey) {
|
||||
return 0;
|
||||
} else {
|
||||
return px1->skey < px2->skey ? -1 : 1;
|
||||
}
|
||||
const SSttKeyRange* px1 = p1;
|
||||
const SSttKeyRange* px2 = p2;
|
||||
|
||||
int32_t ret = tRowKeyCompare(&px1, px2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool isCleanSttBlock(SArray* pTimewindowList, STimeWindow* pQueryWindow, STableBlockScanInfo* pScanInfo,
|
||||
bool isCleanSttBlock(SArray* pKeyRangeList, STimeWindow* pQueryWindow, STableBlockScanInfo* pScanInfo,
|
||||
int32_t order) {
|
||||
// check if it overlap with del skyline
|
||||
taosArraySort(pTimewindowList, sortUidComparFn);
|
||||
taosArraySort(pKeyRangeList, sortUidComparFn);
|
||||
|
||||
int32_t num = taosArrayGetSize(pTimewindowList);
|
||||
int32_t num = taosArrayGetSize(pKeyRangeList);
|
||||
if (num == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STimeWindow* p = taosArrayGet(pTimewindowList, 0);
|
||||
if (overlapWithTimeWindow(p, pQueryWindow, pScanInfo, order)) {
|
||||
SSttKeyRange* pRange = taosArrayGet(pKeyRangeList, 0);
|
||||
STimeWindow w = {.skey = pRange->skey.ts, .ekey = pRange->ekey.ts};
|
||||
if (overlapWithTimeWindow(&w, pQueryWindow, pScanInfo, order)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < num - 1; ++i) {
|
||||
STimeWindow* p1 = taosArrayGet(pTimewindowList, i);
|
||||
STimeWindow* p2 = taosArrayGet(pTimewindowList, i + 1);
|
||||
SSttKeyRange* p1 = taosArrayGet(pKeyRangeList, i);
|
||||
SSttKeyRange* p2 = taosArrayGet(pKeyRangeList, i + 1);
|
||||
|
||||
if (p1->ekey >= p2->skey) {
|
||||
if (p1->ekey.ts >= p2->skey.ts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool overlap = overlapWithTimeWindow(p2, pQueryWindow, pScanInfo, order);
|
||||
STimeWindow w2 = {.skey = p2->skey.ts, .ekey = p2->ekey.ts};
|
||||
bool overlap = overlapWithTimeWindow(&w2, pQueryWindow, pScanInfo, order);
|
||||
if (overlap) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -962,15 +1065,15 @@ static bool doCheckDatablockOverlap(STableBlockScanInfo* pBlockScanInfo, const S
|
|||
|
||||
for (int32_t i = startIndex; i < num; i += 1) {
|
||||
TSDBKEY* p = taosArrayGet(pBlockScanInfo->delSkyline, i);
|
||||
if (p->ts >= pRecord->firstKey && p->ts <= pRecord->lastKey) {
|
||||
if (p->ts >= pRecord->firstKey.key.ts && p->ts <= pRecord->lastKey.key.ts) {
|
||||
if (p->version >= pRecord->minVer) {
|
||||
return true;
|
||||
}
|
||||
} else if (p->ts < pRecord->firstKey) { // p->ts < pBlock->minKey.ts
|
||||
} else if (p->ts < pRecord->firstKey.key.ts) { // p->ts < pBlock->minKey.ts
|
||||
if (p->version >= pRecord->minVer) {
|
||||
if (i < num - 1) {
|
||||
TSDBKEY* pnext = taosArrayGet(pBlockScanInfo->delSkyline, i + 1);
|
||||
if (pnext->ts >= pRecord->firstKey) {
|
||||
if (pnext->ts >= pRecord->firstKey.key.ts) {
|
||||
return true;
|
||||
}
|
||||
} else { // it must be the last point
|
||||
|
|
@ -991,12 +1094,12 @@ static bool doCheckDatablockOverlapWithoutVersion(STableBlockScanInfo* pBlockSca
|
|||
|
||||
for (int32_t i = startIndex; i < num; i += 1) {
|
||||
TSDBKEY* p = taosArrayGet(pBlockScanInfo->delSkyline, i);
|
||||
if (p->ts >= pRecord->firstKey && p->ts <= pRecord->lastKey) {
|
||||
if (p->ts >= pRecord->firstKey.key.ts && p->ts <= pRecord->lastKey.key.ts) {
|
||||
return true;
|
||||
} else if (p->ts < pRecord->firstKey) { // p->ts < pBlock->minKey.ts
|
||||
} else if (p->ts < pRecord->firstKey.key.ts) { // p->ts < pBlock->minKey.ts
|
||||
if (i < num - 1) {
|
||||
TSDBKEY* pnext = taosArrayGet(pBlockScanInfo->delSkyline, i + 1);
|
||||
if (pnext->ts >= pRecord->firstKey) {
|
||||
if (pnext->ts >= pRecord->firstKey.key.ts) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1016,7 +1119,7 @@ bool overlapWithDelSkyline(STableBlockScanInfo* pBlockScanInfo, const SBrinRecor
|
|||
// ts is not overlap
|
||||
TSDBKEY* pFirst = taosArrayGet(pBlockScanInfo->delSkyline, 0);
|
||||
TSDBKEY* pLast = taosArrayGetLast(pBlockScanInfo->delSkyline);
|
||||
if (pRecord->firstKey > pLast->ts || pRecord->lastKey < pFirst->ts) {
|
||||
if (pRecord->firstKey.key.ts > pLast->ts || pRecord->lastKey.key.ts < pFirst->ts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1027,10 +1130,10 @@ bool overlapWithDelSkyline(STableBlockScanInfo* pBlockScanInfo, const SBrinRecor
|
|||
int32_t index = pBlockScanInfo->fileDelIndex;
|
||||
while (1) {
|
||||
TSDBKEY* p = taosArrayGet(pBlockScanInfo->delSkyline, index);
|
||||
if (p->ts > pRecord->firstKey && index > 0) {
|
||||
if (p->ts > pRecord->firstKey.key.ts && index > 0) {
|
||||
index -= 1;
|
||||
} else { // find the first point that is smaller than the minKey.ts of dataBlock.
|
||||
if (p->ts == pRecord->firstKey && p->version < pRecord->maxVer && index > 0) {
|
||||
if (p->ts == pRecord->firstKey.key.ts && p->version < pRecord->maxVer && index > 0) {
|
||||
index -= 1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1049,7 +1152,7 @@ bool overlapWithDelSkylineWithoutVer(STableBlockScanInfo* pBlockScanInfo, const
|
|||
// ts is not overlap
|
||||
TSDBKEY* pFirst = taosArrayGet(pBlockScanInfo->delSkyline, 0);
|
||||
TSDBKEY* pLast = taosArrayGetLast(pBlockScanInfo->delSkyline);
|
||||
if (pRecord->firstKey > pLast->ts || pRecord->lastKey < pFirst->ts) {
|
||||
if (pRecord->firstKey.key.ts > pLast->ts || pRecord->lastKey.key.ts < pFirst->ts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1060,10 +1163,10 @@ bool overlapWithDelSkylineWithoutVer(STableBlockScanInfo* pBlockScanInfo, const
|
|||
int32_t index = pBlockScanInfo->fileDelIndex;
|
||||
while (1) {
|
||||
TSDBKEY* p = taosArrayGet(pBlockScanInfo->delSkyline, index);
|
||||
if (p->ts > pRecord->firstKey && index > 0) {
|
||||
if (p->ts > pRecord->firstKey.key.ts && index > 0) {
|
||||
index -= 1;
|
||||
} else { // find the first point that is smaller than the minKey.ts of dataBlock.
|
||||
if (p->ts == pRecord->firstKey && index > 0) {
|
||||
if (p->ts == pRecord->firstKey.key.ts && index > 0) {
|
||||
index -= 1;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ extern "C" {
|
|||
(_w)->ekey = INT64_MIN; \
|
||||
} while (0);
|
||||
|
||||
#define INIT_KEYRANGE(_k) \
|
||||
do { \
|
||||
(_k)->skey.ts = INT64_MAX; \
|
||||
(_k)->ekey.ts = INT64_MIN; \
|
||||
} while (0);
|
||||
|
||||
typedef enum {
|
||||
READER_STATUS_SUSPEND = 0x1,
|
||||
READER_STATUS_NORMAL = 0x2,
|
||||
|
|
@ -77,33 +83,39 @@ typedef enum ESttKeyStatus {
|
|||
|
||||
typedef struct SSttKeyInfo {
|
||||
ESttKeyStatus status; // this value should be updated when switch to the next fileset
|
||||
int64_t nextProcKey;
|
||||
SRowKey nextProcKey;
|
||||
} SSttKeyInfo;
|
||||
|
||||
typedef struct SSttKeyRange {
|
||||
SRowKey skey;
|
||||
SRowKey ekey;
|
||||
} SSttKeyRange;
|
||||
|
||||
// clean stt file blocks:
|
||||
// 1. not overlap with stt blocks in other stt files of the same fileset
|
||||
// 2. not overlap with delete skyline
|
||||
// 3. not overlap with in-memory data (mem/imem)
|
||||
// 4. not overlap with data file blocks
|
||||
typedef struct STableBlockScanInfo {
|
||||
uint64_t uid;
|
||||
TSKEY lastProcKey;
|
||||
SSttKeyInfo sttKeyInfo;
|
||||
SArray* pBlockList; // block data index list, SArray<SBrinRecord>
|
||||
SArray* pBlockIdxList; // SArray<STableDataBlockIndx>
|
||||
SArray* pMemDelData; // SArray<SDelData>
|
||||
SArray* pFileDelData; // SArray<SDelData> from each file set
|
||||
SIterInfo iter; // mem buffer skip list iterator
|
||||
SIterInfo iiter; // imem buffer skip list iterator
|
||||
SArray* delSkyline; // delete info for this table
|
||||
int32_t fileDelIndex; // file block delete index
|
||||
int32_t sttBlockDelIndex; // delete index for last block
|
||||
bool iterInit; // whether to initialize the in-memory skip list iterator or not
|
||||
bool cleanSttBlocks; // stt block is clean in current fileset
|
||||
bool sttBlockReturned; // result block returned alreay
|
||||
int64_t numOfRowsInStt;
|
||||
STimeWindow sttWindow; // timestamp window for current stt files
|
||||
STimeWindow filesetWindow; // timestamp window for current file set
|
||||
uint64_t uid;
|
||||
SRowKey lastProcKey;
|
||||
SSttKeyInfo sttKeyInfo;
|
||||
SArray* pBlockList; // block data index list, SArray<SBrinRecord>
|
||||
SArray* pBlockIdxList; // SArray<STableDataBlockIndx>
|
||||
SArray* pMemDelData; // SArray<SDelData>
|
||||
SArray* pFileDelData; // SArray<SDelData> from each file set
|
||||
SIterInfo iter; // mem buffer skip list iterator
|
||||
SIterInfo iiter; // imem buffer skip list iterator
|
||||
SArray* delSkyline; // delete info for this table
|
||||
int32_t fileDelIndex; // file block delete index
|
||||
int32_t sttBlockDelIndex; // delete index for last block
|
||||
bool iterInit; // whether to initialize the in-memory skip list iterator or not
|
||||
bool cleanSttBlocks; // stt block is clean in current fileset
|
||||
bool sttBlockReturned; // result block returned alreay
|
||||
int64_t numOfRowsInStt;
|
||||
SSttKeyRange sttRange;
|
||||
// STimeWindow sttWindow; // timestamp window for current stt files
|
||||
STimeWindow filesetWindow; // timestamp window for current file set
|
||||
} STableBlockScanInfo;
|
||||
|
||||
typedef struct SResultBlockInfo {
|
||||
|
|
@ -156,8 +168,12 @@ typedef struct SBlockLoadSuppInfo {
|
|||
SColumnDataAgg tsColAgg;
|
||||
int16_t* colId;
|
||||
int16_t* slotId;
|
||||
int32_t numOfCols;
|
||||
char** buildBuf; // build string tmp buffer, todo remove it later after all string format being updated.
|
||||
int32_t numOfCols;
|
||||
int32_t numOfPks;
|
||||
SColumnInfo pk;
|
||||
int32_t pkSrcSlot;
|
||||
int32_t pkDstSlot;
|
||||
bool smaValid; // the sma on all queried columns are activated
|
||||
} SBlockLoadSuppInfo;
|
||||
|
||||
|
|
@ -168,7 +184,8 @@ typedef struct SSttBlockReader {
|
|||
int32_t order;
|
||||
uint64_t uid;
|
||||
SMergeTree mergeTree;
|
||||
int64_t currentKey;
|
||||
SRowKey currentKey;
|
||||
int32_t numOfPks;
|
||||
} SSttBlockReader;
|
||||
|
||||
typedef struct SFilesetIter {
|
||||
|
|
@ -181,12 +198,19 @@ typedef struct SFilesetIter {
|
|||
|
||||
typedef struct SFileDataBlockInfo {
|
||||
// index position in STableBlockScanInfo in order to check whether neighbor block overlaps with it
|
||||
// int64_t suid;
|
||||
int64_t uid;
|
||||
int64_t firstKey;
|
||||
// int64_t firstKeyVer;
|
||||
union {
|
||||
int64_t val;
|
||||
uint8_t* pData;
|
||||
} firstPk;
|
||||
|
||||
int64_t lastKey;
|
||||
// int64_t lastKeyVer;
|
||||
union {
|
||||
int64_t val;
|
||||
uint8_t* pData;
|
||||
} lastPk;
|
||||
|
||||
int64_t minVer;
|
||||
int64_t maxVer;
|
||||
int64_t blockOffset;
|
||||
|
|
@ -205,13 +229,12 @@ typedef struct SDataBlockIter {
|
|||
SArray* blockList; // SArray<SFileDataBlockInfo>
|
||||
int32_t order;
|
||||
SDataBlk block; // current SDataBlk data
|
||||
SSHashObj* pTableMap;
|
||||
} SDataBlockIter;
|
||||
|
||||
typedef struct SFileBlockDumpInfo {
|
||||
int32_t totalRows;
|
||||
int32_t rowIndex;
|
||||
int64_t lastKey;
|
||||
// STsdbRowKey lastKey; // this key should be removed
|
||||
bool allDumped;
|
||||
} SFileBlockDumpInfo;
|
||||
|
||||
|
|
@ -249,7 +272,6 @@ struct STsdbReader {
|
|||
TdThreadMutex readerMutex;
|
||||
EReaderStatus flag;
|
||||
int32_t code;
|
||||
uint64_t rowsNum;
|
||||
SResultBlockInfo resBlockInfo;
|
||||
SReaderStatus status;
|
||||
char* idStr; // query info handle, for debug purpose
|
||||
|
|
@ -266,7 +288,7 @@ struct STsdbReader {
|
|||
STsdbReader* innerReader[2];
|
||||
bool bFilesetDelimited; // duration by duration output
|
||||
TsdReaderNotifyCbFn notifyFn;
|
||||
void* notifyParam;
|
||||
void* notifyParam;
|
||||
};
|
||||
|
||||
typedef struct SBrinRecordIter {
|
||||
|
|
@ -283,8 +305,10 @@ int32_t uidComparFunc(const void* p1, const void* p2);
|
|||
|
||||
STableBlockScanInfo* getTableBlockScanInfo(SSHashObj* pTableMap, uint64_t uid, const char* id);
|
||||
|
||||
SSHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList,
|
||||
SSHashObj* createDataBlockScanInfo(STsdbReader* pReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList,
|
||||
STableUidList* pUidList, int32_t numOfTables);
|
||||
int32_t initTableBlockScanInfo(STableBlockScanInfo* pScanInfo, uint64_t uid, SSHashObj* pTableMap,
|
||||
STsdbReader* pReader);
|
||||
void clearBlockScanInfo(STableBlockScanInfo* p);
|
||||
void destroyAllBlockScanInfo(SSHashObj* pTableMap);
|
||||
void resetAllDataBlockScanInfo(SSHashObj* pTableMap, int64_t ts, int32_t step);
|
||||
|
|
@ -309,6 +333,7 @@ int32_t loadSttTombDataForAll(STsdbReader* pReader, SSttFileReader* pSttFileRead
|
|||
int32_t getNumOfRowsInSttBlock(SSttFileReader* pSttFileReader, SSttBlockLoadInfo* pBlockLoadInfo,
|
||||
TStatisBlkArray* pStatisBlkArray, uint64_t suid, const uint64_t* pUidList,
|
||||
int32_t numOfTables);
|
||||
void recordToBlockInfo(SFileDataBlockInfo* pBlockInfo, SBrinRecord* record);
|
||||
|
||||
void destroyLDataIter(SLDataIter* pIter);
|
||||
int32_t adjustSttDataIters(SArray* pSttFileBlockIterArray, STFileSet* pFileSet);
|
||||
|
|
@ -316,6 +341,14 @@ int32_t tsdbGetRowsInSttFiles(STFileSet* pFileSet, SArray* pSttFileBlockIterArra
|
|||
const char* pstr);
|
||||
bool isCleanSttBlock(SArray* pTimewindowList, STimeWindow* pQueryWindow, STableBlockScanInfo* pScanInfo, int32_t order);
|
||||
bool overlapWithDelSkyline(STableBlockScanInfo* pBlockScanInfo, const SBrinRecord* pRecord, int32_t order);
|
||||
int32_t pkCompEx(SRowKey* p1, SRowKey* p2);
|
||||
int32_t initRowKey(SRowKey* pKey, int64_t ts, int32_t numOfPks, int32_t type, int32_t len, bool asc);
|
||||
void clearRowKey(SRowKey* pKey);
|
||||
|
||||
bool shouldFreePkBuf(SBlockLoadSuppInfo *pSupp);
|
||||
void resetDataBlockIterator(SDataBlockIter* pIter, int32_t order, bool hasPk);
|
||||
void clearDataBlockIterator(SDataBlockIter* pIter, bool needFree);
|
||||
void cleanupDataBlockIterator(SDataBlockIter* pIter, bool hasPk);
|
||||
|
||||
typedef struct {
|
||||
SArray* pTombData;
|
||||
|
|
@ -349,6 +382,8 @@ typedef struct SCacheRowsReader {
|
|||
char* idstr;
|
||||
int64_t lastTs;
|
||||
SArray* pFuncTypeList;
|
||||
SRowKey rowKey;
|
||||
SColumnInfo pkColumn;
|
||||
} SCacheRowsReader;
|
||||
|
||||
int32_t tsdbCacheGetBatch(STsdb* pTsdb, tb_uid_t uid, SArray* pLastArray, SCacheRowsReader* pr, int8_t ltype);
|
||||
|
|
|
|||
|
|
@ -464,6 +464,20 @@ _exit:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadFileToBuffer(STsdbFD *pFD, int64_t offset, int64_t size, SBuffer *buffer, int64_t szHint,
|
||||
int32_t encryptAlgorithm, char* encryptKey) {
|
||||
int32_t code;
|
||||
|
||||
code = tBufferEnsureCapacity(buffer, buffer->size + size);
|
||||
if (code) return code;
|
||||
code = tsdbReadFile(pFD, offset, (uint8_t *)tBufferGetDataEnd(buffer), size, szHint,
|
||||
encryptAlgorithm, encryptKey);
|
||||
if (code) return code;
|
||||
buffer->size += size;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFsyncFile(STsdbFD *pFD, int32_t encryptAlgorithm, char* encryptKey) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
|
@ -676,246 +690,6 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadBlockSma(SDataFReader *pReader, SDataBlk *pDataBlk, SArray *aColumnDataAgg) {
|
||||
int32_t code = 0;
|
||||
SSmaInfo *pSmaInfo = &pDataBlk->smaInfo;
|
||||
|
||||
ASSERT(pSmaInfo->size > 0);
|
||||
|
||||
taosArrayClear(aColumnDataAgg);
|
||||
|
||||
// alloc
|
||||
code = tRealloc(&pReader->aBuf[0], pSmaInfo->size);
|
||||
if (code) goto _err;
|
||||
|
||||
// read
|
||||
int32_t encryptAlgorithm = pReader->pTsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = pReader->pTsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(pReader->pSmaFD, pSmaInfo->offset, pReader->aBuf[0], pSmaInfo->size, 0, encryptAlgorithm,
|
||||
encryptKey);
|
||||
if (code) goto _err;
|
||||
|
||||
// decode
|
||||
int32_t n = 0;
|
||||
while (n < pSmaInfo->size) {
|
||||
SColumnDataAgg sma;
|
||||
n += tGetColumnDataAgg(pReader->aBuf[0] + n, &sma);
|
||||
|
||||
if (taosArrayPush(aColumnDataAgg, &sma) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
ASSERT(n == pSmaInfo->size);
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d, tsdb read block sma failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbReadBlockDataImpl(SDataFReader *pReader, SBlockInfo *pBlkInfo, SBlockData *pBlockData,
|
||||
int32_t iStt) {
|
||||
int32_t code = 0;
|
||||
|
||||
tBlockDataClear(pBlockData);
|
||||
|
||||
STsdbFD *pFD = (iStt < 0) ? pReader->pDataFD : pReader->aSttFD[iStt];
|
||||
|
||||
// uid + version + tskey
|
||||
code = tRealloc(&pReader->aBuf[0], pBlkInfo->szKey);
|
||||
if (code) goto _err;
|
||||
|
||||
int32_t encryptAlgorithm = pReader->pTsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = pReader->pTsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(pFD, pBlkInfo->offset, pReader->aBuf[0], pBlkInfo->szKey, 0, encryptAlgorithm, encryptKey);
|
||||
if (code) goto _err;
|
||||
|
||||
SDiskDataHdr hdr;
|
||||
uint8_t *p = pReader->aBuf[0] + tGetDiskDataHdr(pReader->aBuf[0], &hdr);
|
||||
|
||||
ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
|
||||
ASSERT(pBlockData->suid == hdr.suid);
|
||||
|
||||
pBlockData->uid = hdr.uid;
|
||||
pBlockData->nRow = hdr.nRow;
|
||||
|
||||
// uid
|
||||
if (hdr.uid == 0) {
|
||||
ASSERT(hdr.szUid);
|
||||
code = tsdbDecmprData(p, hdr.szUid, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aUid,
|
||||
sizeof(int64_t) * hdr.nRow, &pReader->aBuf[1]);
|
||||
if (code) goto _err;
|
||||
} else {
|
||||
ASSERT(!hdr.szUid);
|
||||
}
|
||||
p += hdr.szUid;
|
||||
|
||||
// version
|
||||
code = tsdbDecmprData(p, hdr.szVer, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aVersion,
|
||||
sizeof(int64_t) * hdr.nRow, &pReader->aBuf[1]);
|
||||
if (code) goto _err;
|
||||
p += hdr.szVer;
|
||||
|
||||
// TSKEY
|
||||
code = tsdbDecmprData(p, hdr.szKey, TSDB_DATA_TYPE_TIMESTAMP, hdr.cmprAlg, (uint8_t **)&pBlockData->aTSKEY,
|
||||
sizeof(TSKEY) * hdr.nRow, &pReader->aBuf[1]);
|
||||
if (code) goto _err;
|
||||
p += hdr.szKey;
|
||||
|
||||
ASSERT(p - pReader->aBuf[0] == pBlkInfo->szKey);
|
||||
|
||||
// read and decode columns
|
||||
if (pBlockData->nColData == 0) goto _exit;
|
||||
|
||||
if (hdr.szBlkCol > 0) {
|
||||
int64_t offset = pBlkInfo->offset + pBlkInfo->szKey;
|
||||
|
||||
code = tRealloc(&pReader->aBuf[0], hdr.szBlkCol);
|
||||
if (code) goto _err;
|
||||
|
||||
code = tsdbReadFile(pFD, offset, pReader->aBuf[0], hdr.szBlkCol, 0, encryptAlgorithm, encryptKey);
|
||||
if (code) goto _err;
|
||||
}
|
||||
|
||||
SBlockCol blockCol = {.cid = 0};
|
||||
SBlockCol *pBlockCol = &blockCol;
|
||||
int32_t n = 0;
|
||||
|
||||
for (int32_t iColData = 0; iColData < pBlockData->nColData; iColData++) {
|
||||
SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
|
||||
|
||||
while (pBlockCol && pBlockCol->cid < pColData->cid) {
|
||||
if (n < hdr.szBlkCol) {
|
||||
n += tGetBlockCol(pReader->aBuf[0] + n, pBlockCol);
|
||||
} else {
|
||||
ASSERT(n == hdr.szBlkCol);
|
||||
pBlockCol = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBlockCol == NULL || pBlockCol->cid > pColData->cid) {
|
||||
// add a lot of NONE
|
||||
for (int32_t iRow = 0; iRow < hdr.nRow; iRow++) {
|
||||
code = tColDataAppendValue(pColData, &COL_VAL_NONE(pColData->cid, pColData->type));
|
||||
if (code) goto _err;
|
||||
}
|
||||
} else {
|
||||
ASSERT(pBlockCol->type == pColData->type);
|
||||
ASSERT(pBlockCol->flag && pBlockCol->flag != HAS_NONE);
|
||||
|
||||
if (pBlockCol->flag == HAS_NULL) {
|
||||
// add a lot of NULL
|
||||
for (int32_t iRow = 0; iRow < hdr.nRow; iRow++) {
|
||||
code = tColDataAppendValue(pColData, &COL_VAL_NULL(pBlockCol->cid, pBlockCol->type));
|
||||
if (code) goto _err;
|
||||
}
|
||||
} else {
|
||||
// decode from binary
|
||||
int64_t offset = pBlkInfo->offset + pBlkInfo->szKey + hdr.szBlkCol + pBlockCol->offset;
|
||||
int32_t size = pBlockCol->szBitmap + pBlockCol->szOffset + pBlockCol->szValue;
|
||||
|
||||
code = tRealloc(&pReader->aBuf[1], size);
|
||||
if (code) goto _err;
|
||||
|
||||
code = tsdbReadFile(pFD, offset, pReader->aBuf[1], size, 0, encryptAlgorithm, encryptKey);
|
||||
if (code) goto _err;
|
||||
|
||||
code = tsdbDecmprColData(pReader->aBuf[1], pBlockCol, hdr.cmprAlg, hdr.nRow, pColData, &pReader->aBuf[2]);
|
||||
if (code) goto _err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d, tsdb read block data impl failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadDataBlockEx(SDataFReader *pReader, SDataBlk *pDataBlk, SBlockData *pBlockData) {
|
||||
int32_t code = 0;
|
||||
SBlockInfo *pBlockInfo = &pDataBlk->aSubBlock[0];
|
||||
|
||||
// alloc
|
||||
code = tRealloc(&pReader->aBuf[0], pBlockInfo->szBlock);
|
||||
if (code) goto _err;
|
||||
|
||||
// read
|
||||
int32_t encryptAlgorithm = pReader->pTsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = pReader->pTsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(pReader->pDataFD, pBlockInfo->offset, pReader->aBuf[0], pBlockInfo->szBlock, 0, encryptAlgorithm,
|
||||
encryptKey);
|
||||
if (code) goto _err;
|
||||
|
||||
// decmpr
|
||||
code = tDecmprBlockData(pReader->aBuf[0], pBlockInfo->szBlock, pBlockData, &pReader->aBuf[1]);
|
||||
if (code) goto _err;
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d, tsdb read data block ex failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadDataBlock(SDataFReader *pReader, SDataBlk *pDataBlk, SBlockData *pBlockData) {
|
||||
int32_t code = 0;
|
||||
|
||||
code = tsdbReadBlockDataImpl(pReader, &pDataBlk->aSubBlock[0], pBlockData, -1);
|
||||
if (code) goto _err;
|
||||
|
||||
ASSERT(pDataBlk->nSubBlock == 1);
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d, tsdb read data block failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadSttBlock(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
code = tsdbReadBlockDataImpl(pReader, &pSttBlk->bInfo, pBlockData, iStt);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("vgId:%d, %s failed at %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbReadSttBlockEx(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
// alloc
|
||||
code = tRealloc(&pReader->aBuf[0], pSttBlk->bInfo.szBlock);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
// read
|
||||
int32_t encryptAlgorithm = pReader->pTsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = pReader->pTsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(pReader->aSttFD[iStt], pSttBlk->bInfo.offset, pReader->aBuf[0], pSttBlk->bInfo.szBlock, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
// decmpr
|
||||
code = tDecmprBlockData(pReader->aBuf[0], pSttBlk->bInfo.szBlock, pBlockData, &pReader->aBuf[1]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("vgId:%d, %s failed at %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
// SDelFReader ====================================================
|
||||
struct SDelFReader {
|
||||
STsdb *pTsdb;
|
||||
|
|
|
|||
|
|
@ -29,17 +29,17 @@ struct STsdbSnapReader {
|
|||
int64_t ever;
|
||||
int8_t type;
|
||||
|
||||
uint8_t* aBuf[5];
|
||||
SBuffer buffers[10];
|
||||
SSkmInfo skmTb[1];
|
||||
|
||||
TFileSetRangeArray* fsrArr;
|
||||
|
||||
// context
|
||||
struct {
|
||||
int32_t fsrArrIdx;
|
||||
int32_t fsrArrIdx;
|
||||
STFileSetRange* fsr;
|
||||
bool isDataDone;
|
||||
bool isTombDone;
|
||||
bool isDataDone;
|
||||
bool isTombDone;
|
||||
} ctx[1];
|
||||
|
||||
// reader
|
||||
|
|
@ -68,7 +68,7 @@ static int32_t tsdbSnapReadFileSetOpenReader(STsdbSnapReader* reader) {
|
|||
SDataFileReaderConfig config = {
|
||||
.tsdb = reader->tsdb,
|
||||
.szPage = reader->tsdb->pVnode->config.tsdbPageSize,
|
||||
.bufArr = reader->aBuf,
|
||||
.buffers = reader->buffers,
|
||||
};
|
||||
bool hasDataFile = false;
|
||||
for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX; ftype++) {
|
||||
|
|
@ -94,7 +94,7 @@ static int32_t tsdbSnapReadFileSetOpenReader(STsdbSnapReader* reader) {
|
|||
.tsdb = reader->tsdb,
|
||||
.szPage = reader->tsdb->pVnode->config.tsdbPageSize,
|
||||
.file = fobj->f[0],
|
||||
.bufArr = reader->aBuf,
|
||||
.buffers = reader->buffers,
|
||||
};
|
||||
|
||||
code = tsdbSttFileReaderOpen(fobj->fname, &config, &sttReader);
|
||||
|
|
@ -247,11 +247,14 @@ static int32_t tsdbSnapCmprData(STsdbSnapReader* reader, uint8_t** data) {
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
int32_t aBufN[5] = {0};
|
||||
code = tCmprBlockData(reader->blockData, NO_COMPRESSION, NULL, NULL, reader->aBuf, aBufN);
|
||||
code = tBlockDataCompress(reader->blockData, NO_COMPRESSION, reader->buffers, reader->buffers + 4);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
// TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
int32_t size = aBufN[0] + aBufN[1] + aBufN[2] + aBufN[3];
|
||||
int32_t size = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
size += reader->buffers[i].size;
|
||||
}
|
||||
*data = taosMemoryMalloc(sizeof(SSnapDataHdr) + size);
|
||||
if (*data == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
|
@ -259,16 +262,13 @@ static int32_t tsdbSnapCmprData(STsdbSnapReader* reader, uint8_t** data) {
|
|||
}
|
||||
|
||||
SSnapDataHdr* pHdr = (SSnapDataHdr*)*data;
|
||||
uint8_t* pBuf = pHdr->data;
|
||||
|
||||
pHdr->type = reader->type;
|
||||
pHdr->size = size;
|
||||
|
||||
memcpy(pHdr->data, reader->aBuf[3], aBufN[3]);
|
||||
memcpy(pHdr->data + aBufN[3], reader->aBuf[2], aBufN[2]);
|
||||
if (aBufN[1]) {
|
||||
memcpy(pHdr->data + aBufN[3] + aBufN[2], reader->aBuf[1], aBufN[1]);
|
||||
}
|
||||
if (aBufN[0]) {
|
||||
memcpy(pHdr->data + aBufN[3] + aBufN[2] + aBufN[1], reader->aBuf[0], aBufN[0]);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
memcpy(pBuf, reader->buffers[i].data, reader->buffers[i].size);
|
||||
pBuf += reader->buffers[i].size;
|
||||
}
|
||||
|
||||
_exit:
|
||||
|
|
@ -355,8 +355,8 @@ static int32_t tsdbSnapCmprTombData(STsdbSnapReader* reader, uint8_t** data) {
|
|||
int32_t lino = 0;
|
||||
|
||||
int64_t size = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader->tombBlock->dataArr); i++) {
|
||||
size += TARRAY2_DATA_LEN(reader->tombBlock->dataArr + i);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader->tombBlock->buffers); i++) {
|
||||
size += reader->tombBlock->buffers[i].size;
|
||||
}
|
||||
|
||||
data[0] = taosMemoryMalloc(size + sizeof(SSnapDataHdr));
|
||||
|
|
@ -370,9 +370,9 @@ static int32_t tsdbSnapCmprTombData(STsdbSnapReader* reader, uint8_t** data) {
|
|||
hdr->size = size;
|
||||
|
||||
uint8_t* tdata = hdr->data;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader->tombBlock->dataArr); i++) {
|
||||
memcpy(tdata, TARRAY2_DATA(reader->tombBlock->dataArr + i), TARRAY2_DATA_LEN(reader->tombBlock->dataArr + i));
|
||||
tdata += TARRAY2_DATA_LEN(reader->tombBlock->dataArr + i);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader->tombBlock->buffers); i++) {
|
||||
memcpy(tdata, reader->tombBlock->buffers[i].data, reader->tombBlock->buffers[i].size);
|
||||
tdata += reader->tombBlock->buffers[i].size;
|
||||
}
|
||||
|
||||
_exit:
|
||||
|
|
@ -475,8 +475,8 @@ int32_t tsdbSnapReaderClose(STsdbSnapReader** reader) {
|
|||
tsdbFSDestroyRefRangedSnapshot(&reader[0]->fsrArr);
|
||||
tDestroyTSchema(reader[0]->skmTb->pTSchema);
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->aBuf); ++i) {
|
||||
tFree(reader[0]->aBuf[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->buffers); ++i) {
|
||||
tBufferDestroy(reader[0]->buffers + i);
|
||||
}
|
||||
|
||||
taosMemoryFree(reader[0]);
|
||||
|
|
@ -542,19 +542,19 @@ _exit:
|
|||
|
||||
// STsdbSnapWriter ========================================
|
||||
struct STsdbSnapWriter {
|
||||
STsdb* tsdb;
|
||||
int64_t sver;
|
||||
int64_t ever;
|
||||
int32_t minutes;
|
||||
int8_t precision;
|
||||
int32_t minRow;
|
||||
int32_t maxRow;
|
||||
int8_t cmprAlg;
|
||||
int64_t commitID;
|
||||
int32_t szPage;
|
||||
int64_t compactVersion;
|
||||
int64_t now;
|
||||
uint8_t* aBuf[5];
|
||||
STsdb* tsdb;
|
||||
int64_t sver;
|
||||
int64_t ever;
|
||||
int32_t minutes;
|
||||
int8_t precision;
|
||||
int32_t minRow;
|
||||
int32_t maxRow;
|
||||
int8_t cmprAlg;
|
||||
int64_t commitID;
|
||||
int32_t szPage;
|
||||
int64_t compactVersion;
|
||||
int64_t now;
|
||||
SBuffer buffers[10];
|
||||
|
||||
TFileSetArray* fsetArr;
|
||||
TFileOpArray fopArr[1];
|
||||
|
|
@ -649,7 +649,7 @@ static int32_t tsdbSnapWriteFileSetOpenReader(STsdbSnapWriter* writer) {
|
|||
// open data reader
|
||||
SDataFileReaderConfig dataFileReaderConfig = {
|
||||
.tsdb = writer->tsdb,
|
||||
.bufArr = writer->aBuf,
|
||||
.buffers = writer->buffers,
|
||||
.szPage = writer->szPage,
|
||||
};
|
||||
|
||||
|
|
@ -683,7 +683,7 @@ static int32_t tsdbSnapWriteFileSetOpenReader(STsdbSnapWriter* writer) {
|
|||
SSttFileReaderConfig sttFileReaderConfig = {
|
||||
.tsdb = writer->tsdb,
|
||||
.szPage = writer->szPage,
|
||||
.bufArr = writer->aBuf,
|
||||
.buffers = writer->buffers,
|
||||
.file = fobj->f[0],
|
||||
};
|
||||
|
||||
|
|
@ -956,7 +956,14 @@ static int32_t tsdbSnapWriteTimeSeriesData(STsdbSnapWriter* writer, SSnapDataHdr
|
|||
|
||||
SBlockData blockData[1] = {0};
|
||||
|
||||
code = tDecmprBlockData(hdr->data, hdr->size - sizeof(*hdr), blockData, writer->aBuf);
|
||||
SBuffer buffer = {
|
||||
.capacity = hdr->size,
|
||||
.data = hdr->data,
|
||||
.size = hdr->size,
|
||||
};
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(0, &buffer);
|
||||
|
||||
code = tBlockDataDecompress(&br, blockData, &writer->buffers[0]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
int32_t fid = tsdbKeyFid(blockData->aTSKEY[0], writer->minutes, writer->precision);
|
||||
|
|
@ -994,15 +1001,19 @@ static int32_t tsdbSnapWriteDecmprTombBlock(SSnapDataHdr* hdr, STombBlock* tombB
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
tTombBlockClear(tombBlock);
|
||||
|
||||
int64_t size = hdr->size;
|
||||
ASSERT(size % TOMB_RECORD_ELEM_NUM == 0);
|
||||
size = size / TOMB_RECORD_ELEM_NUM;
|
||||
ASSERT(size % sizeof(int64_t) == 0);
|
||||
tombBlock->numOfRecords = size / sizeof(int64_t);
|
||||
|
||||
int64_t* data = (int64_t*)hdr->data;
|
||||
// int64_t* data = (int64_t*)hdr->data;
|
||||
uint8_t* data = hdr->data;
|
||||
for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) {
|
||||
code = TARRAY2_APPEND_BATCH(&tombBlock->dataArr[i], hdr->data + i * size, size / sizeof(int64_t));
|
||||
code = tBufferPut(tombBlock->buffers + i, data, size);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
data += size;
|
||||
}
|
||||
|
||||
_exit:
|
||||
|
|
@ -1078,7 +1089,8 @@ int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, void* pRang
|
|||
writer[0]->compactVersion = INT64_MAX;
|
||||
writer[0]->now = taosGetTimestampMs();
|
||||
|
||||
code = tsdbFSCreateCopyRangedSnapshot(pTsdb->pFS, (TFileSetRangeArray*)pRanges, &writer[0]->fsetArr, writer[0]->fopArr);
|
||||
code =
|
||||
tsdbFSCreateCopyRangedSnapshot(pTsdb->pFS, (TFileSetRangeArray*)pRanges, &writer[0]->fsetArr, writer[0]->fopArr);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
|
|
@ -1144,8 +1156,8 @@ int32_t tsdbSnapWriterClose(STsdbSnapWriter** writer, int8_t rollback) {
|
|||
TARRAY2_DESTROY(writer[0]->fopArr, NULL);
|
||||
tsdbFSDestroyCopyRangedSnapshot(&writer[0]->fsetArr);
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->aBuf); ++i) {
|
||||
tFree(writer[0]->aBuf[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->buffers); ++i) {
|
||||
tBufferDestroy(writer[0]->buffers + i);
|
||||
}
|
||||
|
||||
taosMemoryFree(writer[0]);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ struct SSttFileReader {
|
|||
TSttBlkArray sttBlkArray[1];
|
||||
TStatisBlkArray statisBlkArray[1];
|
||||
TTombBlkArray tombBlkArray[1];
|
||||
uint8_t *bufArr[5];
|
||||
SBuffer local[10];
|
||||
SBuffer *buffers;
|
||||
};
|
||||
|
||||
// SSttFileReader
|
||||
|
|
@ -41,8 +42,9 @@ int32_t tsdbSttFileReaderOpen(const char *fname, const SSttFileReaderConfig *con
|
|||
if (reader[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
reader[0]->config[0] = config[0];
|
||||
if (reader[0]->config->bufArr == NULL) {
|
||||
reader[0]->config->bufArr = reader[0]->bufArr;
|
||||
reader[0]->buffers = config->buffers;
|
||||
if (reader[0]->buffers == NULL) {
|
||||
reader[0]->buffers = reader[0]->local;
|
||||
}
|
||||
|
||||
// open file
|
||||
|
|
@ -76,8 +78,8 @@ _exit:
|
|||
|
||||
int32_t tsdbSttFileReaderClose(SSttFileReader **reader) {
|
||||
if (reader[0]) {
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->bufArr); ++i) {
|
||||
tFree(reader[0]->bufArr[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->local); ++i) {
|
||||
tBufferDestroy(reader[0]->local + i);
|
||||
}
|
||||
tsdbCloseFile(&reader[0]->fd);
|
||||
TARRAY2_DESTROY(reader[0]->tombBlkArray, NULL);
|
||||
|
|
@ -187,16 +189,19 @@ int32_t tsdbSttFileReadBlockData(SSttFileReader *reader, const SSttBlk *sttBlk,
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
code = tRealloc(&reader->config->bufArr[0], sttBlk->bInfo.szBlock);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
SBuffer *buffer0 = reader->buffers + 0;
|
||||
SBuffer *assist = reader->buffers + 1;
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(reader->fd, sttBlk->bInfo.offset, reader->config->bufArr[0], sttBlk->bInfo.szBlock, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
// load data
|
||||
tBufferClear(buffer0);
|
||||
code = tsdbReadFileToBuffer(reader->fd, sttBlk->bInfo.offset, sttBlk->bInfo.szBlock, buffer0, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
code = tDecmprBlockData(reader->config->bufArr[0], sttBlk->bInfo.szBlock, bData, &reader->config->bufArr[1]);
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer0);
|
||||
code = tBlockDataDecompress(&br, bData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
|
|
@ -211,122 +216,108 @@ int32_t tsdbSttFileReadBlockDataByColumn(SSttFileReader *reader, const SSttBlk *
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
TABLEID tbid = {.suid = sttBlk->suid};
|
||||
if (tbid.suid == 0) {
|
||||
tbid.uid = sttBlk->minUid;
|
||||
} else {
|
||||
tbid.uid = 0;
|
||||
}
|
||||
|
||||
code = tBlockDataInit(bData, &tbid, pTSchema, cids, ncid);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
// uid + version + tskey
|
||||
code = tRealloc(&reader->config->bufArr[0], sttBlk->bInfo.szKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
SDiskDataHdr hdr;
|
||||
SBuffer *buffer0 = reader->buffers + 0;
|
||||
SBuffer *buffer1 = reader->buffers + 1;
|
||||
SBuffer *assist = reader->buffers + 2;
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(reader->fd, sttBlk->bInfo.offset, reader->config->bufArr[0], sttBlk->bInfo.szKey, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
// load key part
|
||||
tBufferClear(buffer0);
|
||||
code = tsdbReadFileToBuffer(reader->fd, sttBlk->bInfo.offset, sttBlk->bInfo.szKey, buffer0, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
// hdr
|
||||
SDiskDataHdr hdr[1];
|
||||
int32_t size = 0;
|
||||
// decode header
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer0);
|
||||
code = tGetDiskDataHdr(&br, &hdr);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
size += tGetDiskDataHdr(reader->config->bufArr[0] + size, hdr);
|
||||
ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
|
||||
|
||||
ASSERT(hdr->delimiter == TSDB_FILE_DLMT);
|
||||
// set data container
|
||||
tBlockDataReset(bData);
|
||||
bData->suid = hdr.suid;
|
||||
bData->uid = (sttBlk->suid == 0) ? sttBlk->minUid : 0;
|
||||
bData->nRow = hdr.nRow;
|
||||
|
||||
bData->nRow = hdr->nRow;
|
||||
bData->uid = hdr->uid;
|
||||
// key part
|
||||
code = tBlockDataDecompressKeyPart(&hdr, &br, bData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
ASSERT(br.offset == buffer0->size);
|
||||
|
||||
// uid
|
||||
if (hdr->uid == 0) {
|
||||
ASSERT(hdr->szUid);
|
||||
code = tsdbDecmprData(reader->config->bufArr[0] + size, hdr->szUid, TSDB_DATA_TYPE_BIGINT, hdr->cmprAlg,
|
||||
(uint8_t **)&bData->aUid, sizeof(int64_t) * hdr->nRow, &reader->config->bufArr[1]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
} else {
|
||||
ASSERT(hdr->szUid == 0);
|
||||
bool loadExtra = false;
|
||||
for (int i = 0; i < ncid; i++) {
|
||||
if (tBlockDataGetColData(bData, cids[i]) == NULL) {
|
||||
loadExtra = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
size += hdr->szUid;
|
||||
|
||||
// version
|
||||
code = tsdbDecmprData(reader->config->bufArr[0] + size, hdr->szVer, TSDB_DATA_TYPE_BIGINT, hdr->cmprAlg,
|
||||
(uint8_t **)&bData->aVersion, sizeof(int64_t) * hdr->nRow, &reader->config->bufArr[1]);
|
||||
if (!loadExtra) {
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
// load SBlockCol part
|
||||
tBufferClear(buffer0);
|
||||
code = tsdbReadFileToBuffer(reader->fd, sttBlk->bInfo.offset + sttBlk->bInfo.szKey, hdr.szBlkCol, buffer0, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
size += hdr->szVer;
|
||||
|
||||
// ts
|
||||
code = tsdbDecmprData(reader->config->bufArr[0] + size, hdr->szKey, TSDB_DATA_TYPE_TIMESTAMP, hdr->cmprAlg,
|
||||
(uint8_t **)&bData->aTSKEY, sizeof(TSKEY) * hdr->nRow, &reader->config->bufArr[1]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
size += hdr->szKey;
|
||||
// load each column
|
||||
SBlockCol blockCol = {
|
||||
.cid = 0,
|
||||
};
|
||||
br = BUFFER_READER_INITIALIZER(0, buffer0);
|
||||
for (int32_t i = 0; i < ncid; i++) {
|
||||
int16_t cid = cids[i];
|
||||
|
||||
ASSERT(size == sttBlk->bInfo.szKey);
|
||||
if (tBlockDataGetColData(bData, cid)) { // already loaded
|
||||
continue;
|
||||
}
|
||||
|
||||
// other columns
|
||||
if (bData->nColData > 0) {
|
||||
if (hdr->szBlkCol > 0) {
|
||||
code = tRealloc(&reader->config->bufArr[0], hdr->szBlkCol);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
while (cid > blockCol.cid) {
|
||||
if (br.offset >= buffer0->size) {
|
||||
blockCol.cid = INT16_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(reader->fd, sttBlk->bInfo.offset + sttBlk->bInfo.szKey, reader->config->bufArr[0],
|
||||
hdr->szBlkCol, 0, encryptAlgorithm, encryptKey);
|
||||
code = tGetBlockCol(&br, &blockCol);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
SBlockCol bc[1] = {{.cid = 0}};
|
||||
SBlockCol *blockCol = bc;
|
||||
if (cid < blockCol.cid) {
|
||||
const STColumn *tcol = tTSchemaSearchColumn(pTSchema, cid);
|
||||
ASSERT(tcol);
|
||||
SBlockCol none = {
|
||||
.cid = cid,
|
||||
.type = tcol->type,
|
||||
.cflag = tcol->flags,
|
||||
.flag = HAS_NONE,
|
||||
.szOrigin = 0,
|
||||
.szBitmap = 0,
|
||||
.szOffset = 0,
|
||||
.szValue = 0,
|
||||
.offset = 0,
|
||||
};
|
||||
code = tBlockDataDecompressColData(&hdr, &none, &br, bData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
} else if (cid == blockCol.cid) {
|
||||
// load from file
|
||||
tBufferClear(buffer1);
|
||||
code =
|
||||
tsdbReadFileToBuffer(reader->fd, sttBlk->bInfo.offset + sttBlk->bInfo.szKey + hdr.szBlkCol + blockCol.offset,
|
||||
blockCol.szBitmap + blockCol.szOffset + blockCol.szValue, buffer1, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
size = 0;
|
||||
for (int32_t i = 0; i < bData->nColData; i++) {
|
||||
SColData *colData = tBlockDataGetColDataByIdx(bData, i);
|
||||
|
||||
while (blockCol && blockCol->cid < colData->cid) {
|
||||
if (size < hdr->szBlkCol) {
|
||||
size += tGetBlockCol(reader->config->bufArr[0] + size, blockCol);
|
||||
} else {
|
||||
ASSERT(size == hdr->szBlkCol);
|
||||
blockCol = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (blockCol == NULL || blockCol->cid > colData->cid) {
|
||||
for (int32_t iRow = 0; iRow < hdr->nRow; iRow++) {
|
||||
code = tColDataAppendValue(colData, &COL_VAL_NONE(colData->cid, colData->type));
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
} else {
|
||||
ASSERT(blockCol->type == colData->type);
|
||||
ASSERT(blockCol->flag && blockCol->flag != HAS_NONE);
|
||||
|
||||
if (blockCol->flag == HAS_NULL) {
|
||||
for (int32_t iRow = 0; iRow < hdr->nRow; iRow++) {
|
||||
code = tColDataAppendValue(colData, &COL_VAL_NULL(blockCol->cid, blockCol->type));
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
} else {
|
||||
int32_t size1 = blockCol->szBitmap + blockCol->szOffset + blockCol->szValue;
|
||||
|
||||
code = tRealloc(&reader->config->bufArr[1], size1);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(reader->fd, sttBlk->bInfo.offset + sttBlk->bInfo.szKey + hdr->szBlkCol + blockCol->offset,
|
||||
reader->config->bufArr[1], size1, 0, encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
code = tsdbDecmprColData(reader->config->bufArr[1], blockCol, hdr->cmprAlg, hdr->nRow, colData,
|
||||
&reader->config->bufArr[2]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
// decode the buffer
|
||||
SBufferReader br1 = BUFFER_READER_INITIALIZER(0, buffer1);
|
||||
code = tBlockDataDecompressColData(&hdr, &blockCol, &br1, bData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -341,29 +332,35 @@ int32_t tsdbSttFileReadTombBlock(SSttFileReader *reader, const STombBlk *tombBlk
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
code = tRealloc(&reader->config->bufArr[0], tombBlk->dp->size);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
SBuffer *buffer0 = reader->buffers + 0;
|
||||
SBuffer *assist = reader->buffers + 1;
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(reader->fd, tombBlk->dp->offset, reader->config->bufArr[0], tombBlk->dp->size, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
if (code) TSDB_CHECK_CODE(code, lino, _exit);
|
||||
// load
|
||||
tBufferClear(buffer0);
|
||||
code = tsdbReadFileToBuffer(reader->fd, tombBlk->dp->offset, tombBlk->dp->size, buffer0, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
int64_t size = 0;
|
||||
// decode
|
||||
int32_t size = 0;
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer0);
|
||||
tTombBlockClear(tombBlock);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(tombBlock->dataArr); ++i) {
|
||||
code = tsdbDecmprData(reader->config->bufArr[0] + size, tombBlk->size[i], TSDB_DATA_TYPE_BIGINT, tombBlk->cmprAlg,
|
||||
&reader->config->bufArr[1], sizeof(int64_t) * tombBlk->numRec, &reader->config->bufArr[2]);
|
||||
tombBlock->numOfRecords = tombBlk->numRec;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(tombBlock->buffers); ++i) {
|
||||
SCompressInfo cinfo = {
|
||||
.cmprAlg = tombBlk->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.originalSize = tombBlk->numRec * sizeof(int64_t),
|
||||
.compressedSize = tombBlk->size[i],
|
||||
};
|
||||
code = tDecompressDataToBuffer(BR_PTR(&br), &cinfo, tombBlock->buffers + i, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
code = TARRAY2_APPEND_BATCH(&tombBlock->dataArr[i], reader->config->bufArr[1], tombBlk->numRec);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
size += tombBlk->size[i];
|
||||
br.offset += tombBlk->size[i];
|
||||
}
|
||||
|
||||
ASSERT(size == tombBlk->dp->size);
|
||||
ASSERT(br.offset == tombBlk->dp->size);
|
||||
_exit:
|
||||
if (code) {
|
||||
TSDB_ERROR_LOG(TD_VID(reader->config->tsdb->pVnode), lino, code);
|
||||
|
|
@ -375,30 +372,65 @@ int32_t tsdbSttFileReadStatisBlock(SSttFileReader *reader, const SStatisBlk *sta
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
code = tRealloc(&reader->config->bufArr[0], statisBlk->dp->size);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
SBuffer *buffer0 = reader->buffers + 0;
|
||||
SBuffer *assist = reader->buffers + 1;
|
||||
|
||||
int32_t encryptAlgorithm = reader->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = reader->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
code = tsdbReadFile(reader->fd, statisBlk->dp->offset, reader->config->bufArr[0], statisBlk->dp->size, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
// load data
|
||||
tBufferClear(buffer0);
|
||||
code = tsdbReadFileToBuffer(reader->fd, statisBlk->dp->offset, statisBlk->dp->size, buffer0, 0,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
int64_t size = 0;
|
||||
// decode data
|
||||
tStatisBlockClear(statisBlock);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(statisBlock->dataArr); ++i) {
|
||||
code =
|
||||
tsdbDecmprData(reader->config->bufArr[0] + size, statisBlk->size[i], TSDB_DATA_TYPE_BIGINT, statisBlk->cmprAlg,
|
||||
&reader->config->bufArr[1], sizeof(int64_t) * statisBlk->numRec, &reader->config->bufArr[2]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
statisBlock->numOfPKs = statisBlk->numOfPKs;
|
||||
statisBlock->numOfRecords = statisBlk->numRec;
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer0);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(statisBlock->buffers); ++i) {
|
||||
SCompressInfo info = {
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.cmprAlg = statisBlk->cmprAlg,
|
||||
.compressedSize = statisBlk->size[i],
|
||||
.originalSize = statisBlk->numRec * sizeof(int64_t),
|
||||
};
|
||||
|
||||
code = TARRAY2_APPEND_BATCH(statisBlock->dataArr + i, reader->config->bufArr[1], statisBlk->numRec);
|
||||
code = tDecompressDataToBuffer(BR_PTR(&br), &info, &statisBlock->buffers[i], assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
size += statisBlk->size[i];
|
||||
br.offset += statisBlk->size[i];
|
||||
}
|
||||
|
||||
ASSERT(size == statisBlk->dp->size);
|
||||
if (statisBlk->numOfPKs > 0) {
|
||||
SValueColumnCompressInfo firstKeyInfos[TD_MAX_PK_COLS];
|
||||
SValueColumnCompressInfo lastKeyInfos[TD_MAX_PK_COLS];
|
||||
|
||||
// decode compress info
|
||||
for (int32_t i = 0; i < statisBlk->numOfPKs; i++) {
|
||||
code = tValueColumnCompressInfoDecode(&br, &firstKeyInfos[i]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < statisBlk->numOfPKs; i++) {
|
||||
code = tValueColumnCompressInfoDecode(&br, &lastKeyInfos[i]);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
// decode value columns
|
||||
for (int32_t i = 0; i < statisBlk->numOfPKs; i++) {
|
||||
code = tValueColumnDecompress(BR_PTR(&br), firstKeyInfos + i, &statisBlock->firstKeyPKs[i], assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
br.offset += (firstKeyInfos[i].dataCompressedSize + firstKeyInfos[i].offsetCompressedSize);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < statisBlk->numOfPKs; i++) {
|
||||
code = tValueColumnDecompress(BR_PTR(&br), &lastKeyInfos[i], &statisBlock->lastKeyPKs[i], assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
br.offset += (lastKeyInfos[i].dataCompressedSize + lastKeyInfos[i].offsetCompressedSize);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(br.offset == buffer0->size);
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
|
|
@ -430,11 +462,12 @@ struct SSttFileWriter {
|
|||
// helper data
|
||||
SSkmInfo skmTb[1];
|
||||
SSkmInfo skmRow[1];
|
||||
uint8_t *bufArr[5];
|
||||
SBuffer local[10];
|
||||
SBuffer *buffers;
|
||||
};
|
||||
|
||||
static int32_t tsdbFileDoWriteSttBlockData(STsdbFD *fd, SBlockData *blockData, int8_t cmprAlg, int64_t *fileSize,
|
||||
TSttBlkArray *sttBlkArray, uint8_t **bufArr, SVersionRange *range,
|
||||
TSttBlkArray *sttBlkArray, SBuffer *buffers, SVersionRange *range,
|
||||
int32_t encryptAlgorithm, char* encryptKey) {
|
||||
if (blockData->nRow == 0) return 0;
|
||||
|
||||
|
|
@ -460,19 +493,17 @@ static int32_t tsdbFileDoWriteSttBlockData(STsdbFD *fd, SBlockData *blockData, i
|
|||
|
||||
tsdbWriterUpdVerRange(range, sttBlk->minVer, sttBlk->maxVer);
|
||||
|
||||
int32_t sizeArr[5] = {0};
|
||||
code = tCmprBlockData(blockData, cmprAlg, NULL, NULL, bufArr, sizeArr);
|
||||
code = tBlockDataCompress(blockData, cmprAlg, buffers, buffers + 4);
|
||||
if (code) return code;
|
||||
|
||||
sttBlk->bInfo.offset = *fileSize;
|
||||
sttBlk->bInfo.szKey = sizeArr[2] + sizeArr[3];
|
||||
sttBlk->bInfo.szBlock = sizeArr[0] + sizeArr[1] + sttBlk->bInfo.szKey;
|
||||
sttBlk->bInfo.szKey = buffers[0].size + buffers[1].size;
|
||||
sttBlk->bInfo.szBlock = buffers[2].size + buffers[3].size + sttBlk->bInfo.szKey;
|
||||
|
||||
for (int32_t i = 3; i >= 0; i--) {
|
||||
if (sizeArr[i]) {
|
||||
code = tsdbWriteFile(fd, *fileSize, bufArr[i], sizeArr[i], encryptAlgorithm, encryptKey);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (buffers[i].size) {
|
||||
code = tsdbWriteFile(fd, *fileSize, buffers[i].data, buffers[i].size, encryptAlgorithm, encryptKey);
|
||||
if (code) return code;
|
||||
*fileSize += sizeArr[i];
|
||||
*fileSize += buffers[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -494,8 +525,8 @@ static int32_t tsdbSttFileDoWriteBlockData(SSttFileWriter *writer) {
|
|||
char* encryptKey = writer->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
|
||||
code = tsdbFileDoWriteSttBlockData(writer->fd, writer->blockData, writer->config->cmprAlg, &writer->file->size,
|
||||
writer->sttBlkArray, writer->config->bufArr, &writer->ctx->range, encryptAlgorithm,
|
||||
encryptKey);
|
||||
writer->sttBlkArray, writer->buffers, &writer->ctx->range,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
|
|
@ -506,49 +537,91 @@ _exit:
|
|||
}
|
||||
|
||||
static int32_t tsdbSttFileDoWriteStatisBlock(SSttFileWriter *writer) {
|
||||
if (STATIS_BLOCK_SIZE(writer->staticBlock) == 0) return 0;
|
||||
if (writer->staticBlock->numOfRecords == 0) return 0;
|
||||
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
SStatisBlk statisBlk[1] = {{
|
||||
.dp[0] =
|
||||
{
|
||||
.offset = writer->file->size,
|
||||
.size = 0,
|
||||
},
|
||||
.minTbid =
|
||||
{
|
||||
.suid = TARRAY2_FIRST(writer->staticBlock->suid),
|
||||
.uid = TARRAY2_FIRST(writer->staticBlock->uid),
|
||||
},
|
||||
.maxTbid =
|
||||
{
|
||||
.suid = TARRAY2_LAST(writer->staticBlock->suid),
|
||||
.uid = TARRAY2_LAST(writer->staticBlock->uid),
|
||||
},
|
||||
.numRec = STATIS_BLOCK_SIZE(writer->staticBlock),
|
||||
.cmprAlg = writer->config->cmprAlg,
|
||||
}};
|
||||
SBuffer *buffer0 = writer->buffers + 0;
|
||||
SBuffer *buffer1 = writer->buffers + 1;
|
||||
SBuffer *assist = writer->buffers + 2;
|
||||
|
||||
STbStatisRecord record;
|
||||
STbStatisBlock *statisBlock = writer->staticBlock;
|
||||
SStatisBlk statisBlk = {0};
|
||||
|
||||
statisBlk.dp->offset = writer->file->size;
|
||||
statisBlk.dp->size = 0;
|
||||
statisBlk.numRec = statisBlock->numOfRecords;
|
||||
statisBlk.cmprAlg = writer->config->cmprAlg;
|
||||
statisBlk.numOfPKs = statisBlock->numOfPKs;
|
||||
|
||||
tStatisBlockGet(statisBlock, 0, &record);
|
||||
statisBlk.minTbid.suid = record.suid;
|
||||
statisBlk.minTbid.uid = record.uid;
|
||||
|
||||
tStatisBlockGet(statisBlock, statisBlock->numOfRecords - 1, &record);
|
||||
statisBlk.maxTbid.suid = record.suid;
|
||||
statisBlk.maxTbid.uid = record.uid;
|
||||
|
||||
// compress each column
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(statisBlk.size); i++) {
|
||||
SCompressInfo info = {
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.cmprAlg = statisBlk.cmprAlg,
|
||||
.originalSize = statisBlock->buffers[i].size,
|
||||
};
|
||||
|
||||
int32_t encryptAlgorithm = writer->config->tsdb->pVnode->config.tsdbCfg.encryptAlgorithm;
|
||||
char* encryptKey = writer->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
|
||||
for (int32_t i = 0; i < STATIS_RECORD_NUM_ELEM; i++) {
|
||||
code = tsdbCmprData((uint8_t *)TARRAY2_DATA(writer->staticBlock->dataArr + i),
|
||||
TARRAY2_DATA_LEN(&writer->staticBlock->dataArr[i]), TSDB_DATA_TYPE_BIGINT, statisBlk->cmprAlg,
|
||||
&writer->config->bufArr[0], 0, &statisBlk->size[i], &writer->config->bufArr[1]);
|
||||
tBufferClear(buffer0);
|
||||
code = tCompressDataToBuffer(statisBlock->buffers[i].data, &info, buffer0, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
code = tsdbWriteFile(writer->fd, writer->file->size, writer->config->bufArr[0], statisBlk->size[i],
|
||||
encryptAlgorithm, encryptKey);
|
||||
code = tsdbWriteFile(writer->fd, writer->file->size, buffer0->data, info.compressedSize,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
statisBlk->dp->size += statisBlk->size[i];
|
||||
writer->file->size += statisBlk->size[i];
|
||||
statisBlk.size[i] = info.compressedSize;
|
||||
statisBlk.dp->size += info.compressedSize;
|
||||
writer->file->size += info.compressedSize;
|
||||
}
|
||||
|
||||
code = TARRAY2_APPEND_PTR(writer->statisBlkArray, statisBlk);
|
||||
// compress primary keys
|
||||
if (statisBlk.numOfPKs > 0) {
|
||||
SValueColumnCompressInfo compressInfo = {.cmprAlg = statisBlk.cmprAlg};
|
||||
|
||||
tBufferClear(buffer0);
|
||||
tBufferClear(buffer1);
|
||||
|
||||
for (int32_t i = 0; i < statisBlk.numOfPKs; i++) {
|
||||
code = tValueColumnCompress(&statisBlock->firstKeyPKs[i], &compressInfo, buffer1, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tValueColumnCompressInfoEncode(&compressInfo, buffer0);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < statisBlk.numOfPKs; i++) {
|
||||
code = tValueColumnCompress(&statisBlock->lastKeyPKs[i], &compressInfo, buffer1, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tValueColumnCompressInfoEncode(&compressInfo, buffer0);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
code = tsdbWriteFile(writer->fd, writer->file->size, buffer0->data, buffer0->size);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
writer->file->size += buffer0->size;
|
||||
statisBlk.dp->size += buffer0->size;
|
||||
|
||||
code = tsdbWriteFile(writer->fd, writer->file->size, buffer1->data, buffer1->size);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
writer->file->size += buffer1->size;
|
||||
statisBlk.dp->size += buffer1->size;
|
||||
}
|
||||
|
||||
code = TARRAY2_APPEND_PTR(writer->statisBlkArray, &statisBlk);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
tStatisBlockClear(writer->staticBlock);
|
||||
|
|
@ -570,8 +643,8 @@ static int32_t tsdbSttFileDoWriteTombBlock(SSttFileWriter *writer) {
|
|||
char* encryptKey = writer->config->tsdb->pVnode->config.tsdbCfg.encryptKey;
|
||||
|
||||
code = tsdbFileWriteTombBlock(writer->fd, writer->tombBlock, writer->config->cmprAlg, &writer->file->size,
|
||||
writer->tombBlkArray, writer->config->bufArr, &writer->ctx->range, encryptAlgorithm,
|
||||
encryptKey);
|
||||
writer->tombBlkArray, writer->buffers, &writer->ctx->range,
|
||||
encryptAlgorithm, encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
|
|
@ -678,7 +751,10 @@ static int32_t tsdbSttFWriterDoOpen(SSttFileWriter *writer) {
|
|||
// set
|
||||
if (!writer->config->skmTb) writer->config->skmTb = writer->skmTb;
|
||||
if (!writer->config->skmRow) writer->config->skmRow = writer->skmRow;
|
||||
if (!writer->config->bufArr) writer->config->bufArr = writer->bufArr;
|
||||
writer->buffers = writer->config->buffers;
|
||||
if (writer->buffers == NULL) {
|
||||
writer->buffers = writer->local;
|
||||
}
|
||||
|
||||
writer->file[0] = (STFile){
|
||||
.type = TSDB_FTYPE_STT,
|
||||
|
|
@ -725,8 +801,8 @@ _exit:
|
|||
static void tsdbSttFWriterDoClose(SSttFileWriter *writer) {
|
||||
ASSERT(writer->fd == NULL);
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(writer->bufArr); ++i) {
|
||||
tFree(writer->bufArr[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(writer->local); ++i) {
|
||||
tBufferDestroy(writer->local + i);
|
||||
}
|
||||
tDestroyTSchema(writer->skmRow->pTSchema);
|
||||
tDestroyTSchema(writer->skmTb->pTSchema);
|
||||
|
|
@ -858,40 +934,24 @@ int32_t tsdbSttFileWriteRow(SSttFileWriter *writer, SRowInfo *row) {
|
|||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
TSDBKEY key[1];
|
||||
if (row->row.type == TSDBROW_ROW_FMT) {
|
||||
key->ts = row->row.pTSRow->ts;
|
||||
key->version = row->row.version;
|
||||
} else {
|
||||
key->ts = row->row.pBlockData->aTSKEY[row->row.iRow];
|
||||
key->version = row->row.pBlockData->aVersion[row->row.iRow];
|
||||
}
|
||||
|
||||
if (writer->ctx->tbid->uid != row->uid) {
|
||||
writer->ctx->tbid->suid = row->suid;
|
||||
writer->ctx->tbid->uid = row->uid;
|
||||
}
|
||||
|
||||
if (STATIS_BLOCK_SIZE(writer->staticBlock) >= writer->config->maxRow) {
|
||||
STsdbRowKey key;
|
||||
tsdbRowGetKey(&row->row, &key);
|
||||
|
||||
for (;;) {
|
||||
code = tStatisBlockPut(writer->staticBlock, row, writer->config->maxRow);
|
||||
if (code == TSDB_CODE_INVALID_PARA) {
|
||||
code = tsdbSttFileDoWriteStatisBlock(writer);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
continue;
|
||||
} else {
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
STbStatisRecord record = {
|
||||
.suid = row->suid,
|
||||
.uid = row->uid,
|
||||
.firstKey = key->ts,
|
||||
.lastKey = key->ts,
|
||||
.count = 1,
|
||||
};
|
||||
code = tStatisBlockPut(writer->staticBlock, &record);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
} else {
|
||||
ASSERT(key->ts >= TARRAY2_LAST(writer->staticBlock->lastKey));
|
||||
|
||||
if (key->ts > TARRAY2_LAST(writer->staticBlock->lastKey)) {
|
||||
TARRAY2_LAST(writer->staticBlock->count)++;
|
||||
TARRAY2_LAST(writer->staticBlock->lastKey) = key->ts;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (row->row.type == TSDBROW_ROW_FMT) {
|
||||
|
|
@ -901,12 +961,13 @@ int32_t tsdbSttFileWriteRow(SSttFileWriter *writer, SRowInfo *row) {
|
|||
}
|
||||
|
||||
// row to col conversion
|
||||
if (key->version <= writer->config->compactVersion //
|
||||
if (key.version <= writer->config->compactVersion //
|
||||
&& writer->blockData->nRow > 0 //
|
||||
&& writer->blockData->aTSKEY[writer->blockData->nRow - 1] == key->ts //
|
||||
&& (writer->blockData->uid //
|
||||
? writer->blockData->uid //
|
||||
: writer->blockData->aUid[writer->blockData->nRow - 1]) == row->uid //
|
||||
&& tsdbRowCompareWithoutVersion(&row->row,
|
||||
&tsdbRowFromBlockData(writer->blockData, writer->blockData->nRow - 1)) == 0 //
|
||||
) {
|
||||
code = tBlockDataUpdateRow(writer->blockData, &row->row, writer->config->skmRow->pTSchema);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
|
|||
|
|
@ -54,10 +54,10 @@ int32_t tsdbSttFileReadStatisBlock(SSttFileReader *reader, const SStatisBlk *sta
|
|||
int32_t tsdbSttFileReadTombBlock(SSttFileReader *reader, const STombBlk *delBlk, STombBlock *dData);
|
||||
|
||||
struct SSttFileReaderConfig {
|
||||
STsdb *tsdb;
|
||||
int32_t szPage;
|
||||
STFile file[1];
|
||||
uint8_t **bufArr;
|
||||
STsdb *tsdb;
|
||||
int32_t szPage;
|
||||
STFile file[1];
|
||||
SBuffer *buffers;
|
||||
};
|
||||
|
||||
// SSttFileWriter ==========================================
|
||||
|
|
@ -88,7 +88,7 @@ struct SSttFileWriterConfig {
|
|||
int32_t level;
|
||||
SSkmInfo *skmTb;
|
||||
SSkmInfo *skmRow;
|
||||
uint8_t **bufArr;
|
||||
SBuffer *buffers;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -33,13 +33,12 @@ static int32_t tsdbUpgradeHead(STsdb *tsdb, SDFileSet *pDFileSet, SDataFReader *
|
|||
// init
|
||||
struct {
|
||||
// config
|
||||
int32_t maxRow;
|
||||
int8_t cmprAlg;
|
||||
int32_t szPage;
|
||||
uint8_t *bufArr[8];
|
||||
int32_t maxRow;
|
||||
int8_t cmprAlg;
|
||||
int32_t szPage;
|
||||
SBuffer buffers[10];
|
||||
int32_t encryptAlgorithm;
|
||||
char* encryptKey;
|
||||
|
||||
// reader
|
||||
SArray *aBlockIdx;
|
||||
SMapData mDataBlk[1];
|
||||
|
|
@ -102,10 +101,24 @@ static int32_t tsdbUpgradeHead(STsdb *tsdb, SDFileSet *pDFileSet, SDataFReader *
|
|||
SBrinRecord record = {
|
||||
.suid = pBlockIdx->suid,
|
||||
.uid = pBlockIdx->uid,
|
||||
.firstKey = dataBlk->minKey.ts,
|
||||
.firstKeyVer = dataBlk->minKey.version,
|
||||
.lastKey = dataBlk->maxKey.ts,
|
||||
.lastKeyVer = dataBlk->maxKey.version,
|
||||
.firstKey =
|
||||
(STsdbRowKey){
|
||||
.key =
|
||||
(SRowKey){
|
||||
.ts = dataBlk->minKey.ts,
|
||||
.numOfPKs = 0,
|
||||
},
|
||||
.version = dataBlk->minKey.version,
|
||||
},
|
||||
.lastKey =
|
||||
(STsdbRowKey){
|
||||
.key =
|
||||
(SRowKey){
|
||||
.ts = dataBlk->maxKey.ts,
|
||||
.numOfPKs = 0,
|
||||
},
|
||||
.version = dataBlk->maxKey.version,
|
||||
},
|
||||
.minVer = dataBlk->minVer,
|
||||
.maxVer = dataBlk->maxVer,
|
||||
.blockOffset = dataBlk->aSubBlock->offset,
|
||||
|
|
@ -124,19 +137,19 @@ static int32_t tsdbUpgradeHead(STsdb *tsdb, SDFileSet *pDFileSet, SDataFReader *
|
|||
code = tBrinBlockPut(ctx->brinBlock, &record);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
if (BRIN_BLOCK_SIZE(ctx->brinBlock) >= ctx->maxRow) {
|
||||
if (ctx->brinBlock->numOfRecords >= ctx->maxRow) {
|
||||
SVersionRange range = {.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
|
||||
code = tsdbFileWriteBrinBlock(ctx->fd, ctx->brinBlock, ctx->cmprAlg, &fset->farr[TSDB_FTYPE_HEAD]->f->size,
|
||||
ctx->brinBlkArray, ctx->bufArr, &range, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
ctx->brinBlkArray, ctx->buffers, &range, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BRIN_BLOCK_SIZE(ctx->brinBlock) > 0) {
|
||||
if (ctx->brinBlock->numOfRecords > 0) {
|
||||
SVersionRange range = {.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
|
||||
code = tsdbFileWriteBrinBlock(ctx->fd, ctx->brinBlock, ctx->cmprAlg, &fset->farr[TSDB_FTYPE_HEAD]->f->size,
|
||||
ctx->brinBlkArray, ctx->bufArr, &range, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
ctx->brinBlkArray, ctx->buffers, &range, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
|
|
@ -163,8 +176,8 @@ _exit:
|
|||
tBlockDataDestroy(ctx->blockData);
|
||||
tMapDataClear(ctx->mDataBlk);
|
||||
taosArrayDestroy(ctx->aBlockIdx);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(ctx->bufArr); ++i) {
|
||||
tFree(ctx->bufArr[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(ctx->buffers); ++i) {
|
||||
tBufferDestroy(ctx->buffers + i);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
@ -448,15 +461,14 @@ static int32_t tsdbDumpTombDataToFSet(STsdb *tsdb, SDelFReader *reader, SArray *
|
|||
|
||||
struct {
|
||||
// context
|
||||
bool toStt;
|
||||
int8_t cmprAlg;
|
||||
int32_t maxRow;
|
||||
int64_t minKey;
|
||||
int64_t maxKey;
|
||||
uint8_t *bufArr[8];
|
||||
bool toStt;
|
||||
int8_t cmprAlg;
|
||||
int32_t maxRow;
|
||||
int64_t minKey;
|
||||
int64_t maxKey;
|
||||
SBuffer buffers[10];
|
||||
int32_t encryptAlgorithm;
|
||||
char* encryptKey;
|
||||
|
||||
// reader
|
||||
SArray *aDelData;
|
||||
// writer
|
||||
|
|
@ -507,7 +519,7 @@ static int32_t tsdbDumpTombDataToFSet(STsdb *tsdb, SDelFReader *reader, SArray *
|
|||
}
|
||||
SVersionRange tombRange = {.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
|
||||
code = tsdbFileWriteTombBlock(ctx->fd, ctx->tombBlock, ctx->cmprAlg, &ctx->fobj->f->size, ctx->tombBlkArray,
|
||||
ctx->bufArr, &tombRange, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
ctx->buffers, &tombRange, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
|
|
@ -520,7 +532,7 @@ static int32_t tsdbDumpTombDataToFSet(STsdb *tsdb, SDelFReader *reader, SArray *
|
|||
}
|
||||
SVersionRange tombRange = {.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
|
||||
code = tsdbFileWriteTombBlock(ctx->fd, ctx->tombBlock, ctx->cmprAlg, &ctx->fobj->f->size, ctx->tombBlkArray,
|
||||
ctx->bufArr, &tombRange, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
ctx->buffers, &tombRange, ctx->encryptAlgorithm, ctx->encryptKey);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
|
|
@ -553,8 +565,8 @@ _exit:
|
|||
if (code) {
|
||||
TSDB_ERROR_LOG(TD_VID(tsdb->pVnode), lino, code);
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(ctx->bufArr); i++) {
|
||||
tFree(ctx->bufArr[i]);
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(ctx->buffers); i++) {
|
||||
tBufferDestroy(ctx->buffers + i);
|
||||
}
|
||||
TARRAY2_DESTROY(ctx->tombBlkArray, NULL);
|
||||
tTombBlockDestroy(ctx->tombBlock);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include "tdataformat.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
static int32_t tBlockDataCompressKeyPart(SBlockData *bData, SDiskDataHdr *hdr, SBuffer *buffer, SBuffer *assist);
|
||||
|
||||
// SMapData =======================================================================
|
||||
void tMapDataReset(SMapData *pMapData) {
|
||||
pMapData->nItem = 0;
|
||||
|
|
@ -380,47 +382,44 @@ int32_t tGetSttBlk(uint8_t *p, void *ph) {
|
|||
}
|
||||
|
||||
// SBlockCol ======================================================
|
||||
int32_t tPutBlockCol(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SBlockCol *pBlockCol = (SBlockCol *)ph;
|
||||
int32_t tPutBlockCol(SBuffer *buffer, const SBlockCol *pBlockCol) {
|
||||
int32_t code;
|
||||
|
||||
ASSERT(pBlockCol->flag && (pBlockCol->flag != HAS_NONE));
|
||||
|
||||
n += tPutI16v(p ? p + n : p, pBlockCol->cid);
|
||||
n += tPutI8(p ? p + n : p, pBlockCol->type);
|
||||
n += tPutI8(p ? p + n : p, pBlockCol->smaOn);
|
||||
n += tPutI8(p ? p + n : p, pBlockCol->flag);
|
||||
n += tPutI32v(p ? p + n : p, pBlockCol->szOrigin);
|
||||
if ((code = tBufferPutI16v(buffer, pBlockCol->cid))) return code;
|
||||
if ((code = tBufferPutI8(buffer, pBlockCol->type))) return code;
|
||||
if ((code = tBufferPutI8(buffer, pBlockCol->cflag))) return code;
|
||||
if ((code = tBufferPutI8(buffer, pBlockCol->flag))) return code;
|
||||
if ((code = tBufferPutI32v(buffer, pBlockCol->szOrigin))) return code;
|
||||
|
||||
if (pBlockCol->flag != HAS_NULL) {
|
||||
if (pBlockCol->flag != HAS_VALUE) {
|
||||
n += tPutI32v(p ? p + n : p, pBlockCol->szBitmap);
|
||||
if ((code = tBufferPutI32v(buffer, pBlockCol->szBitmap))) return code;
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pBlockCol->type)) {
|
||||
n += tPutI32v(p ? p + n : p, pBlockCol->szOffset);
|
||||
if ((code = tBufferPutI32v(buffer, pBlockCol->szOffset))) return code;
|
||||
}
|
||||
|
||||
if (pBlockCol->flag != (HAS_NULL | HAS_NONE)) {
|
||||
n += tPutI32v(p ? p + n : p, pBlockCol->szValue);
|
||||
if ((code = tBufferPutI32v(buffer, pBlockCol->szValue))) return code;
|
||||
}
|
||||
|
||||
n += tPutI32v(p ? p + n : p, pBlockCol->offset);
|
||||
if ((code = tBufferPutI32v(buffer, pBlockCol->offset))) return code;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tGetBlockCol(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SBlockCol *pBlockCol = (SBlockCol *)ph;
|
||||
int32_t tGetBlockCol(SBufferReader *br, SBlockCol *pBlockCol) {
|
||||
int32_t code;
|
||||
|
||||
n += tGetI16v(p + n, &pBlockCol->cid);
|
||||
n += tGetI8(p + n, &pBlockCol->type);
|
||||
n += tGetI8(p + n, &pBlockCol->smaOn);
|
||||
n += tGetI8(p + n, &pBlockCol->flag);
|
||||
n += tGetI32v(p + n, &pBlockCol->szOrigin);
|
||||
if ((code = tBufferGetI16v(br, &pBlockCol->cid))) return code;
|
||||
if ((code = tBufferGetI8(br, &pBlockCol->type))) return code;
|
||||
if ((code = tBufferGetI8(br, &pBlockCol->cflag))) return code;
|
||||
if ((code = tBufferGetI8(br, &pBlockCol->flag))) return code;
|
||||
if ((code = tBufferGetI32v(br, &pBlockCol->szOrigin))) return code;
|
||||
|
||||
ASSERT(pBlockCol->flag && (pBlockCol->flag != HAS_NONE));
|
||||
|
||||
|
|
@ -431,21 +430,21 @@ int32_t tGetBlockCol(uint8_t *p, void *ph) {
|
|||
|
||||
if (pBlockCol->flag != HAS_NULL) {
|
||||
if (pBlockCol->flag != HAS_VALUE) {
|
||||
n += tGetI32v(p + n, &pBlockCol->szBitmap);
|
||||
if ((code = tBufferGetI32v(br, &pBlockCol->szBitmap))) return code;
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pBlockCol->type)) {
|
||||
n += tGetI32v(p + n, &pBlockCol->szOffset);
|
||||
if ((code = tBufferGetI32v(br, &pBlockCol->szOffset))) return code;
|
||||
}
|
||||
|
||||
if (pBlockCol->flag != (HAS_NULL | HAS_NONE)) {
|
||||
n += tGetI32v(p + n, &pBlockCol->szValue);
|
||||
if ((code = tBufferGetI32v(br, &pBlockCol->szValue))) return code;
|
||||
}
|
||||
|
||||
n += tGetI32v(p + n, &pBlockCol->offset);
|
||||
if ((code = tBufferGetI32v(br, &pBlockCol->offset))) return code;
|
||||
}
|
||||
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
|
|
@ -589,9 +588,7 @@ void tsdbRowGetColVal(TSDBROW *pRow, STSchema *pTSchema, int32_t iCol, SColVal *
|
|||
if (pRow->type == TSDBROW_ROW_FMT) {
|
||||
tRowGet(pRow->pTSRow, pTSchema, iCol, pColVal);
|
||||
} else if (pRow->type == TSDBROW_COL_FMT) {
|
||||
SColData *pColData;
|
||||
|
||||
tBlockDataGetColData(pRow->pBlockData, pTColumn->colId, &pColData);
|
||||
SColData *pColData = tBlockDataGetColData(pRow->pBlockData, pTColumn->colId);
|
||||
|
||||
if (pColData) {
|
||||
tColDataGetValue(pColData, pRow->iRow, pColVal);
|
||||
|
|
@ -603,8 +600,63 @@ void tsdbRowGetColVal(TSDBROW *pRow, STSchema *pTSchema, int32_t iCol, SColVal *
|
|||
}
|
||||
}
|
||||
|
||||
int32_t tsdbRowCmprFn(const void *p1, const void *p2) {
|
||||
return tsdbKeyCmprFn(&TSDBROW_KEY((TSDBROW *)p1), &TSDBROW_KEY((TSDBROW *)p2));
|
||||
void tsdbRowGetKey(TSDBROW *row, STsdbRowKey *key) {
|
||||
if (row->type == TSDBROW_ROW_FMT) {
|
||||
key->version = row->version;
|
||||
tRowGetKey(row->pTSRow, &key->key);
|
||||
} else {
|
||||
key->version = row->pBlockData->aVersion[row->iRow];
|
||||
tColRowGetKey(row->pBlockData, row->iRow, &key->key);
|
||||
}
|
||||
}
|
||||
|
||||
void tColRowGetKey(SBlockData* pBlock, int32_t irow, SRowKey* key) {
|
||||
key->ts = pBlock->aTSKEY[irow];
|
||||
key->numOfPKs = 0;
|
||||
|
||||
for (int32_t i = 0; i < pBlock->nColData; i++) {
|
||||
SColData *pColData = &pBlock->aColData[i];
|
||||
if (pColData->cflag & COL_IS_KEY) {
|
||||
SColVal cv;
|
||||
tColDataGetValue(pColData, irow, &cv);
|
||||
ASSERT(COL_VAL_IS_VALUE(&cv));
|
||||
key->pks[key->numOfPKs] = cv.value;
|
||||
key->numOfPKs++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tsdbRowKeyCmpr(const STsdbRowKey *key1, const STsdbRowKey *key2) {
|
||||
int32_t c = tRowKeyCompare(&key1->key, &key2->key);
|
||||
|
||||
if (c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
if (key1->version < key2->version) {
|
||||
return -1;
|
||||
} else if (key1->version > key2->version) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tsdbRowCompare(const void *p1, const void *p2) {
|
||||
STsdbRowKey key1, key2;
|
||||
|
||||
tsdbRowGetKey((TSDBROW *)p1, &key1);
|
||||
tsdbRowGetKey((TSDBROW *)p2, &key2);
|
||||
return tsdbRowKeyCmpr(&key1, &key2);
|
||||
}
|
||||
|
||||
int32_t tsdbRowCompareWithoutVersion(const void *p1, const void *p2) {
|
||||
STsdbRowKey key1, key2;
|
||||
|
||||
tsdbRowGetKey((TSDBROW *)p1, &key1);
|
||||
tsdbRowGetKey((TSDBROW *)p2, &key2);
|
||||
return tRowKeyCompare(&key1.key, &key2.key);
|
||||
}
|
||||
|
||||
// STSDBRowIter ======================================================
|
||||
|
|
@ -636,8 +688,9 @@ SColVal *tsdbRowIterNext(STSDBRowIter *pIter) {
|
|||
return tRowIterNext(pIter->pIter);
|
||||
} else if (pIter->pRow->type == TSDBROW_COL_FMT) {
|
||||
if (pIter->iColData == 0) {
|
||||
pIter->cv = COL_VAL_VALUE(PRIMARYKEY_TIMESTAMP_COL_ID, TSDB_DATA_TYPE_TIMESTAMP,
|
||||
(SValue){.val = pIter->pRow->pBlockData->aTSKEY[pIter->pRow->iRow]});
|
||||
pIter->cv = COL_VAL_VALUE(
|
||||
PRIMARYKEY_TIMESTAMP_COL_ID,
|
||||
((SValue){.type = TSDB_DATA_TYPE_TIMESTAMP, .val = pIter->pRow->pBlockData->aTSKEY[pIter->pRow->iRow]}));
|
||||
++pIter->iColData;
|
||||
return &pIter->cv;
|
||||
}
|
||||
|
|
@ -674,11 +727,10 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
|
||||
ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = key.ts});
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, ((SValue){.type = pTColumn->type, .val = key.ts}));
|
||||
if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return code;
|
||||
// goto _exit;
|
||||
}
|
||||
|
||||
// other
|
||||
|
|
@ -694,7 +746,7 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
}
|
||||
|
||||
tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
|
||||
if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
uint8_t *pVal = pColVal->value.pData;
|
||||
|
||||
pColVal->value.pData = NULL;
|
||||
|
|
@ -738,7 +790,7 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
|
||||
if (key.version > pMerger->version) {
|
||||
if (!COL_VAL_IS_NONE(pColVal)) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
if (!COL_VAL_IS_NULL(pColVal)) {
|
||||
code = tRealloc(&pTColVal->value.pData, pColVal->value.nData);
|
||||
|
|
@ -760,7 +812,7 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
} else if (key.version < pMerger->version) {
|
||||
SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
|
||||
if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
|
||||
if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->value.type)) {
|
||||
code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
|
||||
if (code) return code;
|
||||
|
||||
|
|
@ -796,7 +848,7 @@ int32_t tsdbRowMergerInit(SRowMerger *pMerger, STSchema *pSchema) {
|
|||
void tsdbRowMergerClear(SRowMerger *pMerger) {
|
||||
for (int32_t iCol = 1; iCol < pMerger->pTSchema->numOfCols; iCol++) {
|
||||
SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
if (IS_VAR_DATA_TYPE(pTColVal->type)) {
|
||||
if (IS_VAR_DATA_TYPE(pTColVal->value.type)) {
|
||||
tFree(pTColVal->value.pData);
|
||||
}
|
||||
}
|
||||
|
|
@ -808,7 +860,7 @@ void tsdbRowMergerCleanup(SRowMerger *pMerger) {
|
|||
int32_t numOfCols = taosArrayGetSize(pMerger->pArray);
|
||||
for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
|
||||
SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
if (IS_VAR_DATA_TYPE(pTColVal->type)) {
|
||||
if (IS_VAR_DATA_TYPE(pTColVal->value.type)) {
|
||||
tFree(pTColVal->value.pData);
|
||||
}
|
||||
}
|
||||
|
|
@ -1140,8 +1192,7 @@ int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema,
|
|||
continue;
|
||||
}
|
||||
|
||||
tColDataInit(&pBlockData->aColData[iCid], pTColumn->colId, pTColumn->type,
|
||||
(pTColumn->flags & COL_SMA_ON) ? 1 : 0);
|
||||
tColDataInit(&pBlockData->aColData[iCid], pTColumn->colId, pTColumn->type, pTColumn->flags);
|
||||
|
||||
iColumn++;
|
||||
pTColumn = (iColumn < pTSchema->numOfCols) ? &pTSchema->columns[iColumn] : NULL;
|
||||
|
|
@ -1152,8 +1203,7 @@ int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema,
|
|||
|
||||
for (int32_t iColData = 0; iColData < pBlockData->nColData; iColData++) {
|
||||
STColumn *pTColumn = &pTSchema->columns[iColData + 1];
|
||||
tColDataInit(&pBlockData->aColData[iColData], pTColumn->colId, pTColumn->type,
|
||||
(pTColumn->flags & COL_SMA_ON) ? 1 : 0);
|
||||
tColDataInit(&pBlockData->aColData[iColData], pTColumn->colId, pTColumn->type, pTColumn->flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1181,6 +1231,24 @@ void tBlockDataClear(SBlockData *pBlockData) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t tBlockDataAddColData(SBlockData *pBlockData, int16_t cid, int8_t type, int8_t cflag, SColData **ppColData) {
|
||||
ASSERT(pBlockData->nColData == 0 || pBlockData->aColData[pBlockData->nColData - 1].cid < cid);
|
||||
|
||||
SColData *newColData = taosMemoryRealloc(pBlockData->aColData, sizeof(SColData) * (pBlockData->nColData + 1));
|
||||
if (newColData == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pBlockData->aColData = newColData;
|
||||
pBlockData->nColData++;
|
||||
|
||||
*ppColData = &pBlockData->aColData[pBlockData->nColData - 1];
|
||||
memset(*ppColData, 0, sizeof(SColData));
|
||||
tColDataInit(*ppColData, cid, type, cflag);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flag > 0: forward update
|
||||
* flag == 0: insert
|
||||
* flag < 0: backward update
|
||||
|
|
@ -1303,7 +1371,7 @@ int32_t tBlockDataUpsertRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTS
|
|||
}
|
||||
#endif
|
||||
|
||||
void tBlockDataGetColData(SBlockData *pBlockData, int16_t cid, SColData **ppColData) {
|
||||
SColData *tBlockDataGetColData(SBlockData *pBlockData, int16_t cid) {
|
||||
ASSERT(cid != PRIMARYKEY_TIMESTAMP_COL_ID);
|
||||
int32_t lidx = 0;
|
||||
int32_t ridx = pBlockData->nColData - 1;
|
||||
|
|
@ -1314,8 +1382,7 @@ void tBlockDataGetColData(SBlockData *pBlockData, int16_t cid, SColData **ppColD
|
|||
int32_t c = (pColData->cid == cid) ? 0 : ((pColData->cid > cid) ? 1 : -1);
|
||||
|
||||
if (c == 0) {
|
||||
*ppColData = pColData;
|
||||
return;
|
||||
return pColData;
|
||||
} else if (c < 0) {
|
||||
lidx = midx + 1;
|
||||
} else {
|
||||
|
|
@ -1323,170 +1390,112 @@ void tBlockDataGetColData(SBlockData *pBlockData, int16_t cid, SColData **ppColD
|
|||
}
|
||||
}
|
||||
|
||||
*ppColData = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t tCmprBlockData(SBlockData *pBlockData, int8_t cmprAlg, uint8_t **ppOut, int32_t *szOut, uint8_t *aBuf[],
|
||||
int32_t aBufN[]) {
|
||||
/* buffers[0]: SDiskDataHdr
|
||||
* buffers[1]: key part: uid + version + ts + primary keys
|
||||
* buffers[2]: SBlockCol part
|
||||
* buffers[3]: regular column part
|
||||
*/
|
||||
int32_t tBlockDataCompress(SBlockData *bData, int8_t cmprAlg, SBuffer *buffers, SBuffer *assist) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
SDiskDataHdr hdr = {.delimiter = TSDB_FILE_DLMT,
|
||||
.fmtVer = 0,
|
||||
.suid = pBlockData->suid,
|
||||
.uid = pBlockData->uid,
|
||||
.nRow = pBlockData->nRow,
|
||||
.cmprAlg = cmprAlg};
|
||||
SDiskDataHdr hdr = {
|
||||
.delimiter = TSDB_FILE_DLMT,
|
||||
.fmtVer = 1,
|
||||
.suid = bData->suid,
|
||||
.uid = bData->uid,
|
||||
.szUid = 0, // filled by compress key
|
||||
.szVer = 0, // filled by compress key
|
||||
.szKey = 0, // filled by compress key
|
||||
.szBlkCol = 0, // filled by this func
|
||||
.nRow = bData->nRow,
|
||||
.cmprAlg = cmprAlg,
|
||||
.numOfPKs = 0, // filled by compress key
|
||||
};
|
||||
|
||||
// encode =================
|
||||
// columns AND SBlockCol
|
||||
aBufN[0] = 0;
|
||||
for (int32_t iColData = 0; iColData < pBlockData->nColData; iColData++) {
|
||||
SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
|
||||
// Key part
|
||||
tBufferClear(&buffers[1]);
|
||||
code = tBlockDataCompressKeyPart(bData, &hdr, &buffers[1], assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
ASSERT(pColData->flag);
|
||||
// Regulart column part
|
||||
tBufferClear(&buffers[2]);
|
||||
tBufferClear(&buffers[3]);
|
||||
for (int i = 0; i < bData->nColData; i++) {
|
||||
SColData *colData = tBlockDataGetColDataByIdx(bData, i);
|
||||
|
||||
if (pColData->flag == HAS_NONE) continue;
|
||||
|
||||
SBlockCol blockCol = {.cid = pColData->cid,
|
||||
.type = pColData->type,
|
||||
.smaOn = pColData->smaOn,
|
||||
.flag = pColData->flag,
|
||||
.szOrigin = pColData->nData};
|
||||
|
||||
if (pColData->flag != HAS_NULL) {
|
||||
code = tsdbCmprColData(pColData, cmprAlg, &blockCol, &aBuf[0], aBufN[0], &aBuf[2]);
|
||||
if (code) goto _exit;
|
||||
|
||||
blockCol.offset = aBufN[0];
|
||||
aBufN[0] = aBufN[0] + blockCol.szBitmap + blockCol.szOffset + blockCol.szValue;
|
||||
if (colData->cflag & COL_IS_KEY) {
|
||||
continue;
|
||||
}
|
||||
if (colData->flag == HAS_NONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
code = tRealloc(&aBuf[1], hdr.szBlkCol + tPutBlockCol(NULL, &blockCol));
|
||||
if (code) goto _exit;
|
||||
hdr.szBlkCol += tPutBlockCol(aBuf[1] + hdr.szBlkCol, &blockCol);
|
||||
SColDataCompressInfo cinfo = {
|
||||
.cmprAlg = cmprAlg,
|
||||
};
|
||||
int32_t offset = buffers[3].size;
|
||||
code = tColDataCompress(colData, &cinfo, &buffers[3], assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
SBlockCol blockCol = (SBlockCol){
|
||||
.cid = cinfo.columnId,
|
||||
.type = cinfo.dataType,
|
||||
.cflag = cinfo.columnFlag,
|
||||
.flag = cinfo.flag,
|
||||
.szOrigin = cinfo.dataOriginalSize,
|
||||
.szBitmap = cinfo.bitmapCompressedSize,
|
||||
.szOffset = cinfo.offsetCompressedSize,
|
||||
.szValue = cinfo.dataCompressedSize,
|
||||
.offset = offset,
|
||||
};
|
||||
|
||||
code = tPutBlockCol(&buffers[2], &blockCol);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
hdr.szBlkCol = buffers[2].size;
|
||||
|
||||
// SBlockCol
|
||||
aBufN[1] = hdr.szBlkCol;
|
||||
|
||||
// uid + version + tskey
|
||||
aBufN[2] = 0;
|
||||
if (pBlockData->uid == 0) {
|
||||
code = tsdbCmprData((uint8_t *)pBlockData->aUid, sizeof(int64_t) * pBlockData->nRow, TSDB_DATA_TYPE_BIGINT, cmprAlg,
|
||||
&aBuf[2], aBufN[2], &hdr.szUid, &aBuf[3]);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
aBufN[2] += hdr.szUid;
|
||||
|
||||
code = tsdbCmprData((uint8_t *)pBlockData->aVersion, sizeof(int64_t) * pBlockData->nRow, TSDB_DATA_TYPE_BIGINT,
|
||||
cmprAlg, &aBuf[2], aBufN[2], &hdr.szVer, &aBuf[3]);
|
||||
if (code) goto _exit;
|
||||
aBufN[2] += hdr.szVer;
|
||||
|
||||
code = tsdbCmprData((uint8_t *)pBlockData->aTSKEY, sizeof(TSKEY) * pBlockData->nRow, TSDB_DATA_TYPE_TIMESTAMP,
|
||||
cmprAlg, &aBuf[2], aBufN[2], &hdr.szKey, &aBuf[3]);
|
||||
if (code) goto _exit;
|
||||
aBufN[2] += hdr.szKey;
|
||||
|
||||
// hdr
|
||||
aBufN[3] = tPutDiskDataHdr(NULL, &hdr);
|
||||
code = tRealloc(&aBuf[3], aBufN[3]);
|
||||
if (code) goto _exit;
|
||||
tPutDiskDataHdr(aBuf[3], &hdr);
|
||||
|
||||
// aggragate
|
||||
if (ppOut) {
|
||||
*szOut = aBufN[0] + aBufN[1] + aBufN[2] + aBufN[3];
|
||||
code = tRealloc(ppOut, *szOut);
|
||||
if (code) goto _exit;
|
||||
|
||||
memcpy(*ppOut, aBuf[3], aBufN[3]);
|
||||
memcpy(*ppOut + aBufN[3], aBuf[2], aBufN[2]);
|
||||
if (aBufN[1]) {
|
||||
memcpy(*ppOut + aBufN[3] + aBufN[2], aBuf[1], aBufN[1]);
|
||||
}
|
||||
if (aBufN[0]) {
|
||||
memcpy(*ppOut + aBufN[3] + aBufN[2] + aBufN[1], aBuf[0], aBufN[0]);
|
||||
}
|
||||
}
|
||||
// SDiskDataHdr part
|
||||
tBufferClear(&buffers[0]);
|
||||
code = tPutDiskDataHdr(&buffers[0], &hdr);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tDecmprBlockData(uint8_t *pIn, int32_t szIn, SBlockData *pBlockData, uint8_t *aBuf[]) {
|
||||
int32_t code = 0;
|
||||
|
||||
tBlockDataReset(pBlockData);
|
||||
|
||||
int32_t n = 0;
|
||||
SDiskDataHdr hdr = {0};
|
||||
int32_t tBlockDataDecompress(SBufferReader *br, SBlockData *blockData, SBuffer *assist) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
SDiskDataHdr hdr = {0};
|
||||
SCompressInfo cinfo;
|
||||
|
||||
// SDiskDataHdr
|
||||
n += tGetDiskDataHdr(pIn + n, &hdr);
|
||||
ASSERT(hdr.delimiter == TSDB_FILE_DLMT);
|
||||
code = tGetDiskDataHdr(br, &hdr);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pBlockData->suid = hdr.suid;
|
||||
pBlockData->uid = hdr.uid;
|
||||
pBlockData->nRow = hdr.nRow;
|
||||
tBlockDataReset(blockData);
|
||||
blockData->suid = hdr.suid;
|
||||
blockData->uid = hdr.uid;
|
||||
blockData->nRow = hdr.nRow;
|
||||
|
||||
// uid
|
||||
if (hdr.uid == 0) {
|
||||
ASSERT(hdr.szUid);
|
||||
code = tsdbDecmprData(pIn + n, hdr.szUid, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aUid,
|
||||
sizeof(int64_t) * hdr.nRow, &aBuf[0]);
|
||||
if (code) goto _exit;
|
||||
} else {
|
||||
ASSERT(!hdr.szUid);
|
||||
}
|
||||
n += hdr.szUid;
|
||||
// Key part
|
||||
code = tBlockDataDecompressKeyPart(&hdr, br, blockData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
// version
|
||||
code = tsdbDecmprData(pIn + n, hdr.szVer, TSDB_DATA_TYPE_BIGINT, hdr.cmprAlg, (uint8_t **)&pBlockData->aVersion,
|
||||
sizeof(int64_t) * hdr.nRow, &aBuf[0]);
|
||||
if (code) goto _exit;
|
||||
n += hdr.szVer;
|
||||
// Column part
|
||||
SBufferReader br2 = *br;
|
||||
br->offset += hdr.szBlkCol;
|
||||
for (uint32_t startOffset = br2.offset; br2.offset - startOffset < hdr.szBlkCol;) {
|
||||
SBlockCol blockCol;
|
||||
|
||||
// TSKEY
|
||||
code = tsdbDecmprData(pIn + n, hdr.szKey, TSDB_DATA_TYPE_TIMESTAMP, hdr.cmprAlg, (uint8_t **)&pBlockData->aTSKEY,
|
||||
sizeof(TSKEY) * hdr.nRow, &aBuf[0]);
|
||||
if (code) goto _exit;
|
||||
n += hdr.szKey;
|
||||
|
||||
// loop to decode each column data
|
||||
if (hdr.szBlkCol == 0) goto _exit;
|
||||
|
||||
int32_t nColData = 0;
|
||||
int32_t nt = 0;
|
||||
while (nt < hdr.szBlkCol) {
|
||||
SBlockCol blockCol = {0};
|
||||
nt += tGetBlockCol(pIn + n + nt, &blockCol);
|
||||
++nColData;
|
||||
}
|
||||
ASSERT(nt == hdr.szBlkCol);
|
||||
|
||||
code = tBlockDataAdjustColData(pBlockData, nColData);
|
||||
if (code) goto _exit;
|
||||
|
||||
nt = 0;
|
||||
int32_t iColData = 0;
|
||||
while (nt < hdr.szBlkCol) {
|
||||
SBlockCol blockCol = {0};
|
||||
nt += tGetBlockCol(pIn + n + nt, &blockCol);
|
||||
|
||||
SColData *pColData = &pBlockData->aColData[iColData++];
|
||||
|
||||
tColDataInit(pColData, blockCol.cid, blockCol.type, blockCol.smaOn);
|
||||
if (blockCol.flag == HAS_NULL) {
|
||||
for (int32_t iRow = 0; iRow < hdr.nRow; iRow++) {
|
||||
code = tColDataAppendValue(pColData, &COL_VAL_NULL(blockCol.cid, blockCol.type));
|
||||
if (code) goto _exit;
|
||||
}
|
||||
} else {
|
||||
code = tsdbDecmprColData(pIn + n + hdr.szBlkCol + blockCol.offset, &blockCol, hdr.cmprAlg, hdr.nRow, pColData,
|
||||
&aBuf[0]);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
code = tGetBlockCol(&br2, &blockCol);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tBlockDataDecompressColData(&hdr, &blockCol, br, blockData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
_exit:
|
||||
|
|
@ -1494,219 +1503,255 @@ _exit:
|
|||
}
|
||||
|
||||
// SDiskDataHdr ==============================
|
||||
int32_t tPutDiskDataHdr(uint8_t *p, const SDiskDataHdr *pHdr) {
|
||||
int32_t n = 0;
|
||||
int32_t tPutDiskDataHdr(SBuffer *buffer, const SDiskDataHdr *pHdr) {
|
||||
int32_t code;
|
||||
|
||||
n += tPutU32(p ? p + n : p, pHdr->delimiter);
|
||||
n += tPutU32v(p ? p + n : p, pHdr->fmtVer);
|
||||
n += tPutI64(p ? p + n : p, pHdr->suid);
|
||||
n += tPutI64(p ? p + n : p, pHdr->uid);
|
||||
n += tPutI32v(p ? p + n : p, pHdr->szUid);
|
||||
n += tPutI32v(p ? p + n : p, pHdr->szVer);
|
||||
n += tPutI32v(p ? p + n : p, pHdr->szKey);
|
||||
n += tPutI32v(p ? p + n : p, pHdr->szBlkCol);
|
||||
n += tPutI32v(p ? p + n : p, pHdr->nRow);
|
||||
n += tPutI8(p ? p + n : p, pHdr->cmprAlg);
|
||||
if ((code = tBufferPutU32(buffer, pHdr->delimiter))) return code;
|
||||
if ((code = tBufferPutU32v(buffer, pHdr->fmtVer))) return code;
|
||||
if ((code = tBufferPutI64(buffer, pHdr->suid))) return code;
|
||||
if ((code = tBufferPutI64(buffer, pHdr->uid))) return code;
|
||||
if ((code = tBufferPutI32v(buffer, pHdr->szUid))) return code;
|
||||
if ((code = tBufferPutI32v(buffer, pHdr->szVer))) return code;
|
||||
if ((code = tBufferPutI32v(buffer, pHdr->szKey))) return code;
|
||||
if ((code = tBufferPutI32v(buffer, pHdr->szBlkCol))) return code;
|
||||
if ((code = tBufferPutI32v(buffer, pHdr->nRow))) return code;
|
||||
if ((code = tBufferPutI8(buffer, pHdr->cmprAlg))) return code;
|
||||
if (pHdr->fmtVer == 1) {
|
||||
if ((code = tBufferPutI8(buffer, pHdr->numOfPKs))) return code;
|
||||
for (int i = 0; i < pHdr->numOfPKs; i++) {
|
||||
if ((code = tPutBlockCol(buffer, &pHdr->primaryBlockCols[i]))) return code;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tGetDiskDataHdr(uint8_t *p, void *ph) {
|
||||
int32_t n = 0;
|
||||
SDiskDataHdr *pHdr = (SDiskDataHdr *)ph;
|
||||
int32_t tGetDiskDataHdr(SBufferReader *br, SDiskDataHdr *pHdr) {
|
||||
int32_t code;
|
||||
|
||||
n += tGetU32(p + n, &pHdr->delimiter);
|
||||
n += tGetU32v(p + n, &pHdr->fmtVer);
|
||||
n += tGetI64(p + n, &pHdr->suid);
|
||||
n += tGetI64(p + n, &pHdr->uid);
|
||||
n += tGetI32v(p + n, &pHdr->szUid);
|
||||
n += tGetI32v(p + n, &pHdr->szVer);
|
||||
n += tGetI32v(p + n, &pHdr->szKey);
|
||||
n += tGetI32v(p + n, &pHdr->szBlkCol);
|
||||
n += tGetI32v(p + n, &pHdr->nRow);
|
||||
n += tGetI8(p + n, &pHdr->cmprAlg);
|
||||
if ((code = tBufferGetU32(br, &pHdr->delimiter))) return code;
|
||||
if ((code = tBufferGetU32v(br, &pHdr->fmtVer))) return code;
|
||||
if ((code = tBufferGetI64(br, &pHdr->suid))) return code;
|
||||
if ((code = tBufferGetI64(br, &pHdr->uid))) return code;
|
||||
if ((code = tBufferGetI32v(br, &pHdr->szUid))) return code;
|
||||
if ((code = tBufferGetI32v(br, &pHdr->szVer))) return code;
|
||||
if ((code = tBufferGetI32v(br, &pHdr->szKey))) return code;
|
||||
if ((code = tBufferGetI32v(br, &pHdr->szBlkCol))) return code;
|
||||
if ((code = tBufferGetI32v(br, &pHdr->nRow))) return code;
|
||||
if ((code = tBufferGetI8(br, &pHdr->cmprAlg))) return code;
|
||||
if (pHdr->fmtVer == 1) {
|
||||
if ((code = tBufferGetI8(br, &pHdr->numOfPKs))) return code;
|
||||
for (int i = 0; i < pHdr->numOfPKs; i++) {
|
||||
if ((code = tGetBlockCol(br, &pHdr->primaryBlockCols[i]))) return code;
|
||||
}
|
||||
} else {
|
||||
pHdr->numOfPKs = 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ALGORITHM ==============================
|
||||
int32_t tPutColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg) {
|
||||
int32_t n = 0;
|
||||
int32_t tPutColumnDataAgg(SBuffer *buffer, SColumnDataAgg *pColAgg) {
|
||||
int32_t code;
|
||||
|
||||
n += tPutI16v(p ? p + n : p, pColAgg->colId);
|
||||
n += tPutI16v(p ? p + n : p, pColAgg->numOfNull);
|
||||
n += tPutI64(p ? p + n : p, pColAgg->sum);
|
||||
n += tPutI64(p ? p + n : p, pColAgg->max);
|
||||
n += tPutI64(p ? p + n : p, pColAgg->min);
|
||||
if ((code = tBufferPutI16v(buffer, pColAgg->colId))) return code;
|
||||
if ((code = tBufferPutI16v(buffer, pColAgg->numOfNull))) return code;
|
||||
if ((code = tBufferPutI64(buffer, pColAgg->sum))) return code;
|
||||
if ((code = tBufferPutI64(buffer, pColAgg->max))) return code;
|
||||
if ((code = tBufferPutI64(buffer, pColAgg->min))) return code;
|
||||
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tGetColumnDataAgg(uint8_t *p, SColumnDataAgg *pColAgg) {
|
||||
int32_t n = 0;
|
||||
int32_t tGetColumnDataAgg(SBufferReader *br, SColumnDataAgg *pColAgg) {
|
||||
int32_t code;
|
||||
|
||||
n += tGetI16v(p + n, &pColAgg->colId);
|
||||
n += tGetI16v(p + n, &pColAgg->numOfNull);
|
||||
n += tGetI64(p + n, &pColAgg->sum);
|
||||
n += tGetI64(p + n, &pColAgg->max);
|
||||
n += tGetI64(p + n, &pColAgg->min);
|
||||
if ((code = tBufferGetI16v(br, &pColAgg->colId))) return code;
|
||||
if ((code = tBufferGetI16v(br, &pColAgg->numOfNull))) return code;
|
||||
if ((code = tBufferGetI64(br, &pColAgg->sum))) return code;
|
||||
if ((code = tBufferGetI64(br, &pColAgg->max))) return code;
|
||||
if ((code = tBufferGetI64(br, &pColAgg->min))) return code;
|
||||
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tsdbCmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t nOut,
|
||||
int32_t *szOut, uint8_t **ppBuf) {
|
||||
int32_t code = 0;
|
||||
static int32_t tBlockDataCompressKeyPart(SBlockData *bData, SDiskDataHdr *hdr, SBuffer *buffer, SBuffer *assist) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
SCompressInfo cinfo;
|
||||
|
||||
ASSERT(szIn > 0 && ppOut);
|
||||
// uid
|
||||
if (bData->uid == 0) {
|
||||
cinfo = (SCompressInfo){
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.originalSize = sizeof(int64_t) * bData->nRow,
|
||||
};
|
||||
code = tCompressDataToBuffer(bData->aUid, &cinfo, buffer, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
hdr->szUid = cinfo.compressedSize;
|
||||
}
|
||||
|
||||
if (cmprAlg == NO_COMPRESSION) {
|
||||
code = tRealloc(ppOut, nOut + szIn);
|
||||
if (code) goto _exit;
|
||||
// version
|
||||
cinfo = (SCompressInfo){
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.originalSize = sizeof(int64_t) * bData->nRow,
|
||||
};
|
||||
code = tCompressDataToBuffer((uint8_t *)bData->aVersion, &cinfo, buffer, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
hdr->szVer = cinfo.compressedSize;
|
||||
|
||||
memcpy(*ppOut + nOut, pIn, szIn);
|
||||
*szOut = szIn;
|
||||
} else {
|
||||
int32_t size = szIn + COMP_OVERFLOW_BYTES;
|
||||
// ts
|
||||
cinfo = (SCompressInfo){
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_TIMESTAMP,
|
||||
.originalSize = sizeof(TSKEY) * bData->nRow,
|
||||
};
|
||||
code = tCompressDataToBuffer((uint8_t *)bData->aTSKEY, &cinfo, buffer, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
hdr->szKey = cinfo.compressedSize;
|
||||
|
||||
code = tRealloc(ppOut, nOut + size);
|
||||
if (code) goto _exit;
|
||||
// primary keys
|
||||
for (hdr->numOfPKs = 0; hdr->numOfPKs < bData->nColData; hdr->numOfPKs++) {
|
||||
ASSERT(hdr->numOfPKs <= TD_MAX_PK_COLS);
|
||||
|
||||
if (cmprAlg == TWO_STAGE_COMP) {
|
||||
ASSERT(ppBuf);
|
||||
code = tRealloc(ppBuf, size);
|
||||
if (code) goto _exit;
|
||||
SBlockCol *blockCol = &hdr->primaryBlockCols[hdr->numOfPKs];
|
||||
SColData *colData = tBlockDataGetColDataByIdx(bData, hdr->numOfPKs);
|
||||
|
||||
if ((colData->cflag & COL_IS_KEY) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*szOut =
|
||||
tDataTypes[type].compFunc(pIn, szIn, szIn / tDataTypes[type].bytes, *ppOut + nOut, size, cmprAlg, *ppBuf, size);
|
||||
if (*szOut <= 0) {
|
||||
code = TSDB_CODE_COMPRESS_ERROR;
|
||||
goto _exit;
|
||||
}
|
||||
SColDataCompressInfo info = {
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
};
|
||||
code = tColDataCompress(colData, &info, buffer, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
*blockCol = (SBlockCol){
|
||||
.cid = info.columnId,
|
||||
.type = info.dataType,
|
||||
.cflag = info.columnFlag,
|
||||
.flag = info.flag,
|
||||
.szOrigin = info.dataOriginalSize,
|
||||
.szBitmap = info.bitmapCompressedSize,
|
||||
.szOffset = info.offsetCompressedSize,
|
||||
.szValue = info.dataCompressedSize,
|
||||
.offset = 0,
|
||||
};
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbDecmprData(uint8_t *pIn, int32_t szIn, int8_t type, int8_t cmprAlg, uint8_t **ppOut, int32_t szOut,
|
||||
uint8_t **ppBuf) {
|
||||
int32_t tBlockDataDecompressColData(const SDiskDataHdr *hdr, const SBlockCol *blockCol, SBufferReader *br,
|
||||
SBlockData *blockData, SBuffer *assist) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
code = tRealloc(ppOut, szOut);
|
||||
if (code) goto _exit;
|
||||
SColData *colData;
|
||||
|
||||
if (cmprAlg == NO_COMPRESSION) {
|
||||
ASSERT(szIn == szOut);
|
||||
memcpy(*ppOut, pIn, szOut);
|
||||
} else {
|
||||
if (cmprAlg == TWO_STAGE_COMP) {
|
||||
code = tRealloc(ppBuf, szOut + COMP_OVERFLOW_BYTES);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
code = tBlockDataAddColData(blockData, blockCol->cid, blockCol->type, blockCol->cflag, &colData);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
int32_t size = tDataTypes[type].decompFunc(pIn, szIn, szOut / tDataTypes[type].bytes, *ppOut, szOut, cmprAlg,
|
||||
*ppBuf, szOut + COMP_OVERFLOW_BYTES);
|
||||
if (size <= 0) {
|
||||
code = TSDB_CODE_COMPRESS_ERROR;
|
||||
goto _exit;
|
||||
}
|
||||
// ASSERT(blockCol->flag != HAS_NONE);
|
||||
|
||||
ASSERT(size == szOut);
|
||||
SColDataCompressInfo info = {
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.columnFlag = blockCol->cflag,
|
||||
.flag = blockCol->flag,
|
||||
.dataType = blockCol->type,
|
||||
.columnId = blockCol->cid,
|
||||
.numOfData = hdr->nRow,
|
||||
.bitmapOriginalSize = 0,
|
||||
.bitmapCompressedSize = blockCol->szBitmap,
|
||||
.offsetOriginalSize = blockCol->szOffset ? sizeof(int32_t) * hdr->nRow : 0,
|
||||
.offsetCompressedSize = blockCol->szOffset,
|
||||
.dataOriginalSize = blockCol->szOrigin,
|
||||
.dataCompressedSize = blockCol->szValue,
|
||||
};
|
||||
|
||||
switch (blockCol->flag) {
|
||||
case (HAS_NONE | HAS_NULL | HAS_VALUE):
|
||||
info.bitmapOriginalSize = BIT2_SIZE(hdr->nRow);
|
||||
break;
|
||||
case (HAS_NONE | HAS_NULL):
|
||||
case (HAS_NONE | HAS_VALUE):
|
||||
case (HAS_NULL | HAS_VALUE):
|
||||
info.bitmapOriginalSize = BIT1_SIZE(hdr->nRow);
|
||||
break;
|
||||
}
|
||||
|
||||
code = tColDataDecompress(BR_PTR(br), &info, colData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
br->offset += blockCol->szBitmap + blockCol->szOffset + blockCol->szValue;
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol, uint8_t **ppOut, int32_t nOut,
|
||||
uint8_t **ppBuf) {
|
||||
int32_t code = 0;
|
||||
int32_t tBlockDataDecompressKeyPart(const SDiskDataHdr *hdr, SBufferReader *br, SBlockData *blockData,
|
||||
SBuffer *assist) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
SCompressInfo cinfo;
|
||||
|
||||
ASSERT(pColData->flag && (pColData->flag != HAS_NONE) && (pColData->flag != HAS_NULL));
|
||||
// uid
|
||||
if (hdr->szUid > 0) {
|
||||
cinfo = (SCompressInfo){
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.compressedSize = hdr->szUid,
|
||||
.originalSize = sizeof(int64_t) * hdr->nRow,
|
||||
};
|
||||
|
||||
pBlockCol->szBitmap = 0;
|
||||
pBlockCol->szOffset = 0;
|
||||
pBlockCol->szValue = 0;
|
||||
|
||||
int32_t size = 0;
|
||||
// bitmap
|
||||
if (pColData->flag != HAS_VALUE) {
|
||||
int32_t szBitMap;
|
||||
if (pColData->flag == (HAS_VALUE | HAS_NULL | HAS_NONE)) {
|
||||
szBitMap = BIT2_SIZE(pColData->nVal);
|
||||
} else {
|
||||
szBitMap = BIT1_SIZE(pColData->nVal);
|
||||
}
|
||||
|
||||
code = tsdbCmprData(pColData->pBitMap, szBitMap, TSDB_DATA_TYPE_TINYINT, cmprAlg, ppOut, nOut + size,
|
||||
&pBlockCol->szBitmap, ppBuf);
|
||||
if (code) goto _exit;
|
||||
code = tRealloc((uint8_t **)&blockData->aUid, cinfo.originalSize);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tDecompressData(BR_PTR(br), &cinfo, blockData->aUid, cinfo.originalSize, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
br->offset += cinfo.compressedSize;
|
||||
}
|
||||
size += pBlockCol->szBitmap;
|
||||
|
||||
// offset
|
||||
if (IS_VAR_DATA_TYPE(pColData->type) && pColData->flag != (HAS_NULL | HAS_NONE)) {
|
||||
code = tsdbCmprData((uint8_t *)pColData->aOffset, sizeof(int32_t) * pColData->nVal, TSDB_DATA_TYPE_INT, cmprAlg,
|
||||
ppOut, nOut + size, &pBlockCol->szOffset, ppBuf);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
size += pBlockCol->szOffset;
|
||||
// version
|
||||
cinfo = (SCompressInfo){
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_BIGINT,
|
||||
.compressedSize = hdr->szVer,
|
||||
.originalSize = sizeof(int64_t) * hdr->nRow,
|
||||
};
|
||||
code = tRealloc((uint8_t **)&blockData->aVersion, cinfo.originalSize);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tDecompressData(BR_PTR(br), &cinfo, blockData->aVersion, cinfo.originalSize, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
br->offset += cinfo.compressedSize;
|
||||
|
||||
// value
|
||||
if ((pColData->flag != (HAS_NULL | HAS_NONE)) && pColData->nData) {
|
||||
code = tsdbCmprData((uint8_t *)pColData->pData, pColData->nData, pColData->type, cmprAlg, ppOut, nOut + size,
|
||||
&pBlockCol->szValue, ppBuf);
|
||||
if (code) goto _exit;
|
||||
// ts
|
||||
cinfo = (SCompressInfo){
|
||||
.cmprAlg = hdr->cmprAlg,
|
||||
.dataType = TSDB_DATA_TYPE_TIMESTAMP,
|
||||
.compressedSize = hdr->szKey,
|
||||
.originalSize = sizeof(TSKEY) * hdr->nRow,
|
||||
};
|
||||
code = tRealloc((uint8_t **)&blockData->aTSKEY, cinfo.originalSize);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tDecompressData(BR_PTR(br), &cinfo, blockData->aTSKEY, cinfo.originalSize, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
br->offset += cinfo.compressedSize;
|
||||
|
||||
// primary keys
|
||||
for (int i = 0; i < hdr->numOfPKs; i++) {
|
||||
const SBlockCol *blockCol = &hdr->primaryBlockCols[i];
|
||||
|
||||
ASSERT(blockCol->flag == HAS_VALUE);
|
||||
ASSERT(blockCol->cflag & COL_IS_KEY);
|
||||
|
||||
code = tBlockDataDecompressColData(hdr, blockCol, br, blockData, assist);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
size += pBlockCol->szValue;
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
|
||||
uint8_t **ppBuf) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pColData->cid == pBlockCol->cid);
|
||||
ASSERT(pColData->type == pBlockCol->type);
|
||||
pColData->smaOn = pBlockCol->smaOn;
|
||||
pColData->flag = pBlockCol->flag;
|
||||
pColData->nVal = nVal;
|
||||
pColData->nData = pBlockCol->szOrigin;
|
||||
|
||||
uint8_t *p = pIn;
|
||||
// bitmap
|
||||
if (pBlockCol->szBitmap) {
|
||||
int32_t szBitMap;
|
||||
if (pColData->flag == (HAS_VALUE | HAS_NULL | HAS_NONE)) {
|
||||
szBitMap = BIT2_SIZE(pColData->nVal);
|
||||
} else {
|
||||
szBitMap = BIT1_SIZE(pColData->nVal);
|
||||
}
|
||||
|
||||
code = tsdbDecmprData(p, pBlockCol->szBitmap, TSDB_DATA_TYPE_TINYINT, cmprAlg, &pColData->pBitMap, szBitMap, ppBuf);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
p += pBlockCol->szBitmap;
|
||||
|
||||
// offset
|
||||
if (pBlockCol->szOffset) {
|
||||
code = tsdbDecmprData(p, pBlockCol->szOffset, TSDB_DATA_TYPE_INT, cmprAlg, (uint8_t **)&pColData->aOffset,
|
||||
sizeof(int32_t) * pColData->nVal, ppBuf);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
p += pBlockCol->szOffset;
|
||||
|
||||
// value
|
||||
if (pBlockCol->szValue) {
|
||||
code = tsdbDecmprData(p, pBlockCol->szValue, pColData->type, cmprAlg, &pColData->pData, pColData->nData, ppBuf);
|
||||
if (code) goto _exit;
|
||||
}
|
||||
p += pBlockCol->szValue;
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,39 +17,46 @@
|
|||
|
||||
// SDelBlock ----------
|
||||
int32_t tTombBlockInit(STombBlock *tombBlock) {
|
||||
tombBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) {
|
||||
TARRAY2_INIT(&tombBlock->dataArr[i]);
|
||||
tBufferInit(&tombBlock->buffers[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tTombBlockDestroy(STombBlock *tombBlock) {
|
||||
tombBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) {
|
||||
TARRAY2_DESTROY(&tombBlock->dataArr[i], NULL);
|
||||
tBufferDestroy(&tombBlock->buffers[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tTombBlockClear(STombBlock *tombBlock) {
|
||||
tombBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) {
|
||||
TARRAY2_CLEAR(&tombBlock->dataArr[i], NULL);
|
||||
tBufferClear(&tombBlock->buffers[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tTombBlockPut(STombBlock *tombBlock, const STombRecord *record) {
|
||||
int32_t code;
|
||||
for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) {
|
||||
code = TARRAY2_APPEND(&tombBlock->dataArr[i], record->dataArr[i]);
|
||||
int32_t code = tBufferPutI64(&tombBlock->buffers[i], record->data[i]);
|
||||
if (code) return code;
|
||||
}
|
||||
tombBlock->numOfRecords++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tTombBlockGet(STombBlock *tombBlock, int32_t idx, STombRecord *record) {
|
||||
if (idx >= TOMB_BLOCK_SIZE(tombBlock)) return TSDB_CODE_OUT_OF_RANGE;
|
||||
if (idx < 0 || idx >= tombBlock->numOfRecords) {
|
||||
return TSDB_CODE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) {
|
||||
record->dataArr[i] = TARRAY2_GET(&tombBlock->dataArr[i], idx);
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(sizeof(int64_t) * idx, &tombBlock->buffers[i]);
|
||||
tBufferGetI64(&br, &record->data[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -66,95 +73,374 @@ int32_t tTombRecordCompare(const STombRecord *r1, const STombRecord *r2) {
|
|||
|
||||
// STbStatisBlock ----------
|
||||
int32_t tStatisBlockInit(STbStatisBlock *statisBlock) {
|
||||
for (int32_t i = 0; i < STATIS_RECORD_NUM_ELEM; ++i) {
|
||||
TARRAY2_INIT(&statisBlock->dataArr[i]);
|
||||
statisBlock->numOfPKs = 0;
|
||||
statisBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(statisBlock->buffers); ++i) {
|
||||
tBufferInit(&statisBlock->buffers[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < TD_MAX_PK_COLS; ++i) {
|
||||
tValueColumnInit(&statisBlock->firstKeyPKs[i]);
|
||||
tValueColumnInit(&statisBlock->lastKeyPKs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tStatisBlockDestroy(STbStatisBlock *statisBlock) {
|
||||
for (int32_t i = 0; i < STATIS_RECORD_NUM_ELEM; ++i) {
|
||||
TARRAY2_DESTROY(&statisBlock->dataArr[i], NULL);
|
||||
statisBlock->numOfPKs = 0;
|
||||
statisBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(statisBlock->buffers); ++i) {
|
||||
tBufferDestroy(&statisBlock->buffers[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < TD_MAX_PK_COLS; ++i) {
|
||||
tValueColumnDestroy(&statisBlock->firstKeyPKs[i]);
|
||||
tValueColumnDestroy(&statisBlock->lastKeyPKs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tStatisBlockClear(STbStatisBlock *statisBlock) {
|
||||
for (int32_t i = 0; i < STATIS_RECORD_NUM_ELEM; ++i) {
|
||||
TARRAY2_CLEAR(&statisBlock->dataArr[i], NULL);
|
||||
statisBlock->numOfPKs = 0;
|
||||
statisBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(statisBlock->buffers); ++i) {
|
||||
tBufferClear(&statisBlock->buffers[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < TD_MAX_PK_COLS; ++i) {
|
||||
tValueColumnClear(&statisBlock->firstKeyPKs[i]);
|
||||
tValueColumnClear(&statisBlock->lastKeyPKs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tStatisBlockPut(STbStatisBlock *statisBlock, const STbStatisRecord *record) {
|
||||
int32_t code;
|
||||
for (int32_t i = 0; i < STATIS_RECORD_NUM_ELEM; ++i) {
|
||||
code = TARRAY2_APPEND(&statisBlock->dataArr[i], record->dataArr[i]);
|
||||
if (code) return code;
|
||||
static int32_t tStatisBlockAppend(STbStatisBlock *block, SRowInfo *row) {
|
||||
int32_t code;
|
||||
STsdbRowKey key;
|
||||
|
||||
tsdbRowGetKey(&row->row, &key);
|
||||
if (block->numOfRecords == 0) {
|
||||
block->numOfPKs = key.key.numOfPKs;
|
||||
} else if (block->numOfPKs != key.key.numOfPKs) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
} else {
|
||||
for (int i = 0; i < block->numOfPKs; i++) {
|
||||
if (key.key.pks[i].type != block->firstKeyPKs[i].type) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((code = tBufferPutI64(&block->suids, row->suid))) return code;
|
||||
if ((code = tBufferPutI64(&block->uids, row->uid))) return code;
|
||||
if ((code = tBufferPutI64(&block->firstKeyTimestamps, key.key.ts))) return code;
|
||||
if ((code = tBufferPutI64(&block->lastKeyTimestamps, key.key.ts))) return code;
|
||||
if ((code = tBufferPutI64(&block->counts, 1))) return code;
|
||||
for (int32_t i = 0; i < block->numOfPKs; ++i) {
|
||||
if ((code = tValueColumnAppend(block->firstKeyPKs + i, key.key.pks + i))) return code;
|
||||
if ((code = tValueColumnAppend(block->lastKeyPKs + i, key.key.pks + i))) return code;
|
||||
}
|
||||
|
||||
block->numOfRecords++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tStatisBlockUpdate(STbStatisBlock *block, SRowInfo *row) {
|
||||
STbStatisRecord record;
|
||||
STsdbRowKey key;
|
||||
int32_t c;
|
||||
int32_t code;
|
||||
|
||||
tStatisBlockGet(block, block->numOfRecords - 1, &record);
|
||||
tsdbRowGetKey(&row->row, &key);
|
||||
|
||||
c = tRowKeyCompare(&record.lastKey, &key.key);
|
||||
if (c == 0) {
|
||||
return 0;
|
||||
} else if (c < 0) {
|
||||
// last ts
|
||||
code = tBufferPutAt(&block->lastKeyTimestamps, (block->numOfRecords - 1) * sizeof(record.lastKey.ts), &key.key.ts,
|
||||
sizeof(key.key.ts));
|
||||
if (code) return code;
|
||||
|
||||
// last primary keys
|
||||
for (int i = 0; i < block->numOfPKs; i++) {
|
||||
code = tValueColumnUpdate(&block->lastKeyPKs[i], block->numOfRecords - 1, &key.key.pks[i]);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
// count
|
||||
record.count++;
|
||||
code = tBufferPutAt(&block->counts, (block->numOfRecords - 1) * sizeof(record.count), &record.count,
|
||||
sizeof(record.count));
|
||||
if (code) return code;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tStatisBlockPut(STbStatisBlock *block, SRowInfo *row, int32_t maxRecords) {
|
||||
if (block->numOfRecords > 0) {
|
||||
int64_t lastUid;
|
||||
SBufferReader br = BUFFER_READER_INITIALIZER(sizeof(int64_t) * (block->numOfRecords - 1), &block->uids);
|
||||
tBufferGetI64(&br, &lastUid);
|
||||
|
||||
if (lastUid == row->uid) {
|
||||
return tStatisBlockUpdate(block, row);
|
||||
} else if (block->numOfRecords >= maxRecords) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
}
|
||||
return tStatisBlockAppend(block, row);
|
||||
}
|
||||
|
||||
int32_t tStatisBlockGet(STbStatisBlock *statisBlock, int32_t idx, STbStatisRecord *record) {
|
||||
if (idx >= STATIS_BLOCK_SIZE(statisBlock)) return TSDB_CODE_OUT_OF_RANGE;
|
||||
for (int32_t i = 0; i < STATIS_RECORD_NUM_ELEM; ++i) {
|
||||
record->dataArr[i] = TARRAY2_GET(&statisBlock->dataArr[i], idx);
|
||||
int32_t code;
|
||||
SBufferReader reader;
|
||||
|
||||
if (idx < 0 || idx >= statisBlock->numOfRecords) {
|
||||
return TSDB_CODE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(record->suid), &statisBlock->suids);
|
||||
code = tBufferGetI64(&reader, &record->suid);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(record->uid), &statisBlock->uids);
|
||||
code = tBufferGetI64(&reader, &record->uid);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(record->firstKey.ts), &statisBlock->firstKeyTimestamps);
|
||||
code = tBufferGetI64(&reader, &record->firstKey.ts);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(record->lastKey.ts), &statisBlock->lastKeyTimestamps);
|
||||
code = tBufferGetI64(&reader, &record->lastKey.ts);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(record->count), &statisBlock->counts);
|
||||
code = tBufferGetI64(&reader, &record->count);
|
||||
if (code) return code;
|
||||
|
||||
// primary keys
|
||||
for (record->firstKey.numOfPKs = 0; record->firstKey.numOfPKs < statisBlock->numOfPKs; record->firstKey.numOfPKs++) {
|
||||
code = tValueColumnGet(&statisBlock->firstKeyPKs[record->firstKey.numOfPKs], idx,
|
||||
&record->firstKey.pks[record->firstKey.numOfPKs]);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
for (record->lastKey.numOfPKs = 0; record->lastKey.numOfPKs < statisBlock->numOfPKs; record->lastKey.numOfPKs++) {
|
||||
code = tValueColumnGet(&statisBlock->lastKeyPKs[record->lastKey.numOfPKs], idx,
|
||||
&record->lastKey.pks[record->lastKey.numOfPKs]);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SBrinRecord ----------
|
||||
int32_t tBrinBlockInit(SBrinBlock *brinBlock) {
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr1); ++i) {
|
||||
TARRAY2_INIT(&brinBlock->dataArr1[i]);
|
||||
brinBlock->numOfPKs = 0;
|
||||
brinBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->buffers); ++i) {
|
||||
tBufferInit(&brinBlock->buffers[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr2); ++i) {
|
||||
TARRAY2_INIT(&brinBlock->dataArr2[i]);
|
||||
for (int32_t i = 0; i < TD_MAX_PK_COLS; ++i) {
|
||||
tValueColumnInit(&brinBlock->firstKeyPKs[i]);
|
||||
tValueColumnInit(&brinBlock->lastKeyPKs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tBrinBlockDestroy(SBrinBlock *brinBlock) {
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr1); ++i) {
|
||||
TARRAY2_DESTROY(&brinBlock->dataArr1[i], NULL);
|
||||
brinBlock->numOfPKs = 0;
|
||||
brinBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->buffers); ++i) {
|
||||
tBufferDestroy(&brinBlock->buffers[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr2); ++i) {
|
||||
TARRAY2_DESTROY(&brinBlock->dataArr2[i], NULL);
|
||||
for (int32_t i = 0; i < TD_MAX_PK_COLS; ++i) {
|
||||
tValueColumnDestroy(&brinBlock->firstKeyPKs[i]);
|
||||
tValueColumnDestroy(&brinBlock->lastKeyPKs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tBrinBlockClear(SBrinBlock *brinBlock) {
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr1); ++i) {
|
||||
TARRAY2_CLEAR(&brinBlock->dataArr1[i], NULL);
|
||||
brinBlock->numOfPKs = 0;
|
||||
brinBlock->numOfRecords = 0;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->buffers); ++i) {
|
||||
tBufferClear(&brinBlock->buffers[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr2); ++i) {
|
||||
TARRAY2_CLEAR(&brinBlock->dataArr2[i], NULL);
|
||||
for (int32_t i = 0; i < TD_MAX_PK_COLS; ++i) {
|
||||
tValueColumnClear(&brinBlock->firstKeyPKs[i]);
|
||||
tValueColumnClear(&brinBlock->lastKeyPKs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tBrinBlockPut(SBrinBlock *brinBlock, const SBrinRecord *record) {
|
||||
int32_t code;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr1); ++i) {
|
||||
code = TARRAY2_APPEND(&brinBlock->dataArr1[i], record->dataArr1[i]);
|
||||
if (code) return code;
|
||||
|
||||
ASSERT(record->firstKey.key.numOfPKs == record->lastKey.key.numOfPKs);
|
||||
|
||||
if (brinBlock->numOfRecords == 0) { // the first row
|
||||
brinBlock->numOfPKs = record->firstKey.key.numOfPKs;
|
||||
} else if (brinBlock->numOfPKs != record->firstKey.key.numOfPKs) {
|
||||
// if the number of primary keys are not the same,
|
||||
// return an error code and the caller should handle it
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
} else {
|
||||
for (int i = 0; i < brinBlock->numOfPKs; i++) {
|
||||
if (record->firstKey.key.pks[i].type != brinBlock->firstKeyPKs[i].type) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr2); ++i) {
|
||||
code = TARRAY2_APPEND(&brinBlock->dataArr2[i], record->dataArr2[i]);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->suids, record->suid);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->uids, record->uid);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->firstKeyTimestamps, record->firstKey.key.ts);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->firstKeyVersions, record->firstKey.version);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->lastKeyTimestamps, record->lastKey.key.ts);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->lastKeyVersions, record->lastKey.version);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->minVers, record->minVer);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->maxVers, record->maxVer);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->blockOffsets, record->blockOffset);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI64(&brinBlock->smaOffsets, record->smaOffset);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI32(&brinBlock->blockSizes, record->blockSize);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI32(&brinBlock->blockKeySizes, record->blockKeySize);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI32(&brinBlock->smaSizes, record->smaSize);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI32(&brinBlock->numRows, record->numRow);
|
||||
if (code) return code;
|
||||
|
||||
code = tBufferPutI32(&brinBlock->counts, record->count);
|
||||
if (code) return code;
|
||||
|
||||
if (brinBlock->numOfPKs > 0) {
|
||||
for (int32_t i = 0; i < brinBlock->numOfPKs; ++i) {
|
||||
code = tValueColumnAppend(&brinBlock->firstKeyPKs[i], &record->firstKey.key.pks[i]);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < brinBlock->numOfPKs; ++i) {
|
||||
code = tValueColumnAppend(&brinBlock->lastKeyPKs[i], &record->lastKey.key.pks[i]);
|
||||
if (code) return code;
|
||||
}
|
||||
}
|
||||
|
||||
brinBlock->numOfRecords++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tBrinBlockGet(SBrinBlock *brinBlock, int32_t idx, SBrinRecord *record) {
|
||||
if (idx >= BRIN_BLOCK_SIZE(brinBlock)) return TSDB_CODE_OUT_OF_RANGE;
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr1); ++i) {
|
||||
record->dataArr1[i] = TARRAY2_GET(&brinBlock->dataArr1[i], idx);
|
||||
int32_t code;
|
||||
SBufferReader reader;
|
||||
|
||||
if (idx < 0 || idx >= brinBlock->numOfRecords) {
|
||||
return TSDB_CODE_OUT_OF_RANGE;
|
||||
}
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(brinBlock->dataArr2); ++i) {
|
||||
record->dataArr2[i] = TARRAY2_GET(&brinBlock->dataArr2[i], idx);
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->suids);
|
||||
code = tBufferGetI64(&reader, &record->suid);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->uids);
|
||||
code = tBufferGetI64(&reader, &record->uid);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->firstKeyTimestamps);
|
||||
code = tBufferGetI64(&reader, &record->firstKey.key.ts);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->firstKeyVersions);
|
||||
code = tBufferGetI64(&reader, &record->firstKey.version);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->lastKeyTimestamps);
|
||||
code = tBufferGetI64(&reader, &record->lastKey.key.ts);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->lastKeyVersions);
|
||||
code = tBufferGetI64(&reader, &record->lastKey.version);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->minVers);
|
||||
code = tBufferGetI64(&reader, &record->minVer);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->maxVers);
|
||||
code = tBufferGetI64(&reader, &record->maxVer);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->blockOffsets);
|
||||
code = tBufferGetI64(&reader, &record->blockOffset);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int64_t), &brinBlock->smaOffsets);
|
||||
code = tBufferGetI64(&reader, &record->smaOffset);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int32_t), &brinBlock->blockSizes);
|
||||
code = tBufferGetI32(&reader, &record->blockSize);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int32_t), &brinBlock->blockKeySizes);
|
||||
code = tBufferGetI32(&reader, &record->blockKeySize);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int32_t), &brinBlock->smaSizes);
|
||||
code = tBufferGetI32(&reader, &record->smaSize);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int32_t), &brinBlock->numRows);
|
||||
code = tBufferGetI32(&reader, &record->numRow);
|
||||
if (code) return code;
|
||||
|
||||
reader = BUFFER_READER_INITIALIZER(idx * sizeof(int32_t), &brinBlock->counts);
|
||||
code = tBufferGetI32(&reader, &record->count);
|
||||
if (code) return code;
|
||||
|
||||
// primary keys
|
||||
for (record->firstKey.key.numOfPKs = 0; record->firstKey.key.numOfPKs < brinBlock->numOfPKs;
|
||||
record->firstKey.key.numOfPKs++) {
|
||||
code = tValueColumnGet(&brinBlock->firstKeyPKs[record->firstKey.key.numOfPKs], idx,
|
||||
&record->firstKey.key.pks[record->firstKey.key.numOfPKs]);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
for (record->lastKey.key.numOfPKs = 0; record->lastKey.key.numOfPKs < brinBlock->numOfPKs;
|
||||
record->lastKey.key.numOfPKs++) {
|
||||
code = tValueColumnGet(&brinBlock->lastKeyPKs[record->lastKey.key.numOfPKs], idx,
|
||||
&record->lastKey.key.pks[record->lastKey.key.numOfPKs]);
|
||||
if (code) return code;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
// STombRecord ----------
|
||||
#define TOMB_RECORD_ELEM_NUM 5
|
||||
typedef union {
|
||||
int64_t dataArr[TOMB_RECORD_ELEM_NUM];
|
||||
int64_t data[TOMB_RECORD_ELEM_NUM];
|
||||
struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
|
|
@ -35,14 +35,17 @@ typedef union {
|
|||
};
|
||||
} STombRecord;
|
||||
|
||||
typedef union {
|
||||
TARRAY2(int64_t) dataArr[TOMB_RECORD_ELEM_NUM];
|
||||
struct {
|
||||
TARRAY2(int64_t) suid[1];
|
||||
TARRAY2(int64_t) uid[1];
|
||||
TARRAY2(int64_t) version[1];
|
||||
TARRAY2(int64_t) skey[1];
|
||||
TARRAY2(int64_t) ekey[1];
|
||||
typedef struct {
|
||||
int32_t numOfRecords;
|
||||
union {
|
||||
SBuffer buffers[TOMB_RECORD_ELEM_NUM];
|
||||
struct {
|
||||
SBuffer suids;
|
||||
SBuffer uids;
|
||||
SBuffer versions;
|
||||
SBuffer skeys;
|
||||
SBuffer ekeys;
|
||||
};
|
||||
};
|
||||
} STombBlock;
|
||||
|
||||
|
|
@ -60,7 +63,7 @@ typedef struct {
|
|||
|
||||
typedef TARRAY2(STombBlk) TTombBlkArray;
|
||||
|
||||
#define TOMB_BLOCK_SIZE(db) TARRAY2_SIZE((db)->suid)
|
||||
#define TOMB_BLOCK_SIZE(db) ((db)->numOfRecords)
|
||||
|
||||
int32_t tTombBlockInit(STombBlock *tombBlock);
|
||||
int32_t tTombBlockDestroy(STombBlock *tombBlock);
|
||||
|
|
@ -70,27 +73,29 @@ int32_t tTombBlockGet(STombBlock *tombBlock, int32_t idx, STombRecord *record);
|
|||
int32_t tTombRecordCompare(const STombRecord *record1, const STombRecord *record2);
|
||||
|
||||
// STbStatisRecord ----------
|
||||
#define STATIS_RECORD_NUM_ELEM 5
|
||||
typedef union {
|
||||
int64_t dataArr[STATIS_RECORD_NUM_ELEM];
|
||||
struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
int64_t firstKey;
|
||||
int64_t lastKey;
|
||||
int64_t count;
|
||||
};
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
SRowKey firstKey;
|
||||
SRowKey lastKey;
|
||||
int64_t count;
|
||||
} STbStatisRecord;
|
||||
|
||||
typedef union {
|
||||
TARRAY2(int64_t) dataArr[STATIS_RECORD_NUM_ELEM];
|
||||
struct {
|
||||
TARRAY2(int64_t) suid[1];
|
||||
TARRAY2(int64_t) uid[1];
|
||||
TARRAY2(int64_t) firstKey[1];
|
||||
TARRAY2(int64_t) lastKey[1];
|
||||
TARRAY2(int64_t) count[1];
|
||||
typedef struct {
|
||||
int8_t numOfPKs;
|
||||
int32_t numOfRecords;
|
||||
union {
|
||||
SBuffer buffers[5];
|
||||
struct {
|
||||
SBuffer suids; // int64_t
|
||||
SBuffer uids; // int64_t
|
||||
SBuffer firstKeyTimestamps; // int64_t
|
||||
SBuffer lastKeyTimestamps; // int64_t
|
||||
SBuffer counts; // int64_t
|
||||
};
|
||||
};
|
||||
SValueColumn firstKeyPKs[TD_MAX_PK_COLS];
|
||||
SValueColumn lastKeyPKs[TD_MAX_PK_COLS];
|
||||
} STbStatisBlock;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -98,66 +103,62 @@ typedef struct {
|
|||
TABLEID minTbid;
|
||||
TABLEID maxTbid;
|
||||
int32_t numRec;
|
||||
int32_t size[STATIS_RECORD_NUM_ELEM];
|
||||
int32_t size[5];
|
||||
int8_t cmprAlg;
|
||||
int8_t rsvd[7];
|
||||
int8_t numOfPKs; // number of primary keys
|
||||
int8_t rsvd[6];
|
||||
} SStatisBlk;
|
||||
|
||||
#define STATIS_BLOCK_SIZE(db) TARRAY2_SIZE((db)->suid)
|
||||
#define STATIS_BLOCK_SIZE(db) ((db)->numOfRecords)
|
||||
|
||||
int32_t tStatisBlockInit(STbStatisBlock *statisBlock);
|
||||
int32_t tStatisBlockDestroy(STbStatisBlock *statisBlock);
|
||||
int32_t tStatisBlockClear(STbStatisBlock *statisBlock);
|
||||
int32_t tStatisBlockPut(STbStatisBlock *statisBlock, const STbStatisRecord *record);
|
||||
int32_t tStatisBlockPut(STbStatisBlock *statisBlock, SRowInfo *row, int32_t maxRecords);
|
||||
int32_t tStatisBlockGet(STbStatisBlock *statisBlock, int32_t idx, STbStatisRecord *record);
|
||||
|
||||
// SBrinRecord ----------
|
||||
typedef union {
|
||||
struct {
|
||||
int64_t dataArr1[10];
|
||||
int32_t dataArr2[5];
|
||||
};
|
||||
struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
int64_t firstKey;
|
||||
int64_t firstKeyVer;
|
||||
int64_t lastKey;
|
||||
int64_t lastKeyVer;
|
||||
int64_t minVer;
|
||||
int64_t maxVer;
|
||||
int64_t blockOffset;
|
||||
int64_t smaOffset;
|
||||
int32_t blockSize;
|
||||
int32_t blockKeySize;
|
||||
int32_t smaSize;
|
||||
int32_t numRow;
|
||||
int32_t count;
|
||||
};
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
STsdbRowKey firstKey;
|
||||
STsdbRowKey lastKey;
|
||||
int64_t minVer;
|
||||
int64_t maxVer;
|
||||
int64_t blockOffset;
|
||||
int64_t smaOffset;
|
||||
int32_t blockSize;
|
||||
int32_t blockKeySize;
|
||||
int32_t smaSize;
|
||||
int32_t numRow;
|
||||
int32_t count;
|
||||
} SBrinRecord;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
TARRAY2(int64_t) dataArr1[10];
|
||||
TARRAY2(int32_t) dataArr2[5];
|
||||
};
|
||||
struct {
|
||||
TARRAY2(int64_t) suid[1];
|
||||
TARRAY2(int64_t) uid[1];
|
||||
TARRAY2(int64_t) firstKey[1];
|
||||
TARRAY2(int64_t) firstKeyVer[1];
|
||||
TARRAY2(int64_t) lastKey[1];
|
||||
TARRAY2(int64_t) lastKeyVer[1];
|
||||
TARRAY2(int64_t) minVer[1];
|
||||
TARRAY2(int64_t) maxVer[1];
|
||||
TARRAY2(int64_t) blockOffset[1];
|
||||
TARRAY2(int64_t) smaOffset[1];
|
||||
TARRAY2(int32_t) blockSize[1];
|
||||
TARRAY2(int32_t) blockKeySize[1];
|
||||
TARRAY2(int32_t) smaSize[1];
|
||||
TARRAY2(int32_t) numRow[1];
|
||||
TARRAY2(int32_t) count[1];
|
||||
typedef struct {
|
||||
int8_t numOfPKs;
|
||||
int32_t numOfRecords;
|
||||
union {
|
||||
SBuffer buffers[15];
|
||||
struct {
|
||||
SBuffer suids; // int64_t
|
||||
SBuffer uids; // int64_t
|
||||
SBuffer firstKeyTimestamps; // int64_t
|
||||
SBuffer firstKeyVersions; // int64_t
|
||||
SBuffer lastKeyTimestamps; // int64_t
|
||||
SBuffer lastKeyVersions; // int64_t
|
||||
SBuffer minVers; // int64_t
|
||||
SBuffer maxVers; // int64_t
|
||||
SBuffer blockOffsets; // int64_t
|
||||
SBuffer smaOffsets; // int64_t
|
||||
SBuffer blockSizes; // int32_t
|
||||
SBuffer blockKeySizes; // int32_t
|
||||
SBuffer smaSizes; // int32_t
|
||||
SBuffer numRows; // int32_t
|
||||
SBuffer counts; // int32_t
|
||||
};
|
||||
};
|
||||
SValueColumn firstKeyPKs[TD_MAX_PK_COLS];
|
||||
SValueColumn lastKeyPKs[TD_MAX_PK_COLS];
|
||||
} SBrinBlock;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -169,12 +170,13 @@ typedef struct {
|
|||
int32_t numRec;
|
||||
int32_t size[15];
|
||||
int8_t cmprAlg;
|
||||
int8_t rsvd[7];
|
||||
int8_t numOfPKs; // number of primary keys
|
||||
int8_t rsvd[6];
|
||||
} SBrinBlk;
|
||||
|
||||
typedef TARRAY2(SBrinBlk) TBrinBlkArray;
|
||||
|
||||
#define BRIN_BLOCK_SIZE(db) TARRAY2_SIZE((db)->suid)
|
||||
#define BRIN_BLOCK_SIZE(db) ((db)->numOfRecords)
|
||||
|
||||
int32_t tBrinBlockInit(SBrinBlock *brinBlock);
|
||||
int32_t tBrinBlockDestroy(SBrinBlock *brinBlock);
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ void initTqAPI(SStoreTqReader* pTq) {
|
|||
pTq->tqReaderSeek = tqReaderSeek;
|
||||
pTq->tqRetrieveBlock = tqRetrieveDataBlock;
|
||||
|
||||
pTq->tqGetTablePrimaryKey = tqGetTablePrimaryKey;
|
||||
pTq->tqSetTablePrimaryKey = tqSetTablePrimaryKey;
|
||||
pTq->tqReaderNextBlockInWal = tqNextBlockInWal;
|
||||
|
||||
pTq->tqNextBlockImpl = tqNextBlockImpl; // todo remove it
|
||||
|
|
@ -258,6 +260,8 @@ void initCacheFn(SStoreCacheReader* pCache) {
|
|||
}
|
||||
|
||||
void initSnapshotFn(SStoreSnapshotFn* pSnapshot) {
|
||||
pSnapshot->taosXGetTablePrimaryKey = taosXGetTablePrimaryKey;
|
||||
pSnapshot->taosXSetTablePrimaryKey = taosXSetTablePrimaryKey;
|
||||
pSnapshot->setForSnapShot = setForSnapShot;
|
||||
pSnapshot->destroySnapshot = destroySnapContext;
|
||||
pSnapshot->getMetaTableInfoFromSnapshot = getMetaTableInfoFromSnapshot;
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ static int32_t vnodeProcessAlterTbReq(SVnode *pVnode, int64_t ver, void *pReq, i
|
|||
static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginRpc);
|
||||
static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginalMsg);
|
||||
SRpcMsg *pOriginalMsg);
|
||||
static int32_t vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessAlterConfirmReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessAlterConfigReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDropTtlTbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessTrimReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDeleteReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginalMsg);
|
||||
SRpcMsg *pOriginalMsg);
|
||||
static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessCreateIndexReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDropIndexReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
|
|
@ -240,10 +240,13 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int
|
|||
}
|
||||
|
||||
SSubmitTbData submitTbData;
|
||||
uint8_t version;
|
||||
if (tDecodeI32v(pCoder, &submitTbData.flags) < 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
version = (submitTbData.flags >> 8) & 0xff;
|
||||
submitTbData.flags = submitTbData.flags & 0xff;
|
||||
|
||||
if (submitTbData.flags & SUBMIT_REQ_FROM_FILE) {
|
||||
code = grantCheck(TSDB_GRANT_CSV);
|
||||
|
|
@ -307,7 +310,7 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int
|
|||
}
|
||||
|
||||
SColData colData = {0};
|
||||
pCoder->pos += tGetColData(pCoder->data + pCoder->pos, &colData);
|
||||
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, &colData);
|
||||
if (colData.flag != HAS_VALUE) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto _exit;
|
||||
|
|
@ -321,7 +324,7 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int
|
|||
}
|
||||
|
||||
for (uint64_t i = 1; i < nColData; i++) {
|
||||
pCoder->pos += tGetColData(pCoder->data + pCoder->pos, &colData);
|
||||
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, &colData);
|
||||
}
|
||||
} else {
|
||||
uint64_t nRow;
|
||||
|
|
@ -1516,7 +1519,7 @@ static int32_t vnodeRebuildSubmitReqMsg(SSubmitReq2 *pSubmitReq, void **ppMsg) {
|
|||
}
|
||||
|
||||
static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginalMsg) {
|
||||
SRpcMsg *pOriginalMsg) {
|
||||
int32_t code = 0;
|
||||
terrno = 0;
|
||||
|
||||
|
|
@ -1572,26 +1575,41 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, in
|
|||
goto _exit;
|
||||
}
|
||||
|
||||
SColData *pColData = (SColData *)taosArrayGet(pSubmitTbData->aCol, 0);
|
||||
TSKEY *aKey = (TSKEY *)(pColData->pData);
|
||||
|
||||
for (int32_t iRow = 0; iRow < pColData->nVal; iRow++) {
|
||||
if (aKey[iRow] < minKey || aKey[iRow] > maxKey || (iRow > 0 && aKey[iRow] <= aKey[iRow - 1])) {
|
||||
SColData *colDataArr = TARRAY_DATA(pSubmitTbData->aCol);
|
||||
SRowKey lastKey;
|
||||
tColDataArrGetRowKey(colDataArr, TARRAY_SIZE(pSubmitTbData->aCol), 0, &lastKey);
|
||||
for (int32_t iRow = 1; iRow < colDataArr[0].nVal; iRow++) {
|
||||
SRowKey key;
|
||||
tColDataArrGetRowKey(TARRAY_DATA(pSubmitTbData->aCol), TARRAY_SIZE(pSubmitTbData->aCol), iRow, &key);
|
||||
if (tRowKeyCompare(&lastKey, &key) >= 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
vError("vgId:%d %s failed since %s, version:%" PRId64, TD_VID(pVnode), __func__, tstrerror(terrno), ver);
|
||||
vError("vgId:%d %s failed 1 since %s, version:%" PRId64, TD_VID(pVnode), __func__, tstrerror(terrno), ver);
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
int32_t nRow = TARRAY_SIZE(pSubmitTbData->aRowP);
|
||||
SRow **aRow = (SRow **)TARRAY_DATA(pSubmitTbData->aRowP);
|
||||
SRowKey lastRowKey;
|
||||
for (int32_t iRow = 0; iRow < nRow; ++iRow) {
|
||||
if (aRow[iRow]->ts < minKey || aRow[iRow]->ts > maxKey || (iRow > 0 && aRow[iRow]->ts <= aRow[iRow - 1]->ts)) {
|
||||
if (aRow[iRow]->ts < minKey || aRow[iRow]->ts > maxKey) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
vError("vgId:%d %s failed since %s, version:%" PRId64, TD_VID(pVnode), __func__, tstrerror(code), ver);
|
||||
vError("vgId:%d %s failed 2 since %s, version:%" PRId64, TD_VID(pVnode), __func__, tstrerror(code), ver);
|
||||
goto _exit;
|
||||
}
|
||||
if (iRow == 0) {
|
||||
tRowGetKey(aRow[iRow], &lastRowKey);
|
||||
} else {
|
||||
SRowKey rowKey;
|
||||
tRowGetKey(aRow[iRow], &rowKey);
|
||||
|
||||
if (tRowKeyCompare(&lastRowKey, &rowKey) >= 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
vError("vgId:%d %s failed 3 since %s, version:%" PRId64, TD_VID(pVnode), __func__, tstrerror(code), ver);
|
||||
goto _exit;
|
||||
}
|
||||
lastRowKey = rowKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1735,10 +1753,14 @@ _exit:
|
|||
atomic_add_fetch_64(&pVnode->statis.nInsertSuccess, pSubmitRsp->affectedRows);
|
||||
atomic_add_fetch_64(&pVnode->statis.nBatchInsert, 1);
|
||||
|
||||
if(tsEnableMonitor && pSubmitRsp->affectedRows > 0 && strlen(pOriginalMsg->info.conn.user) > 0){
|
||||
const char *sample_labels[] = {VNODE_METRIC_TAG_VALUE_INSERT_AFFECTED_ROWS, pVnode->monitor.strClusterId,
|
||||
pVnode->monitor.strDnodeId, tsLocalEp, pVnode->monitor.strVgId,
|
||||
pOriginalMsg->info.conn.user, "Success"};
|
||||
if (tsEnableMonitor && pSubmitRsp->affectedRows > 0 && strlen(pOriginalMsg->info.conn.user) > 0) {
|
||||
const char *sample_labels[] = {VNODE_METRIC_TAG_VALUE_INSERT_AFFECTED_ROWS,
|
||||
pVnode->monitor.strClusterId,
|
||||
pVnode->monitor.strDnodeId,
|
||||
tsLocalEp,
|
||||
pVnode->monitor.strVgId,
|
||||
pOriginalMsg->info.conn.user,
|
||||
"Success"};
|
||||
taos_counter_add(pVnode->monitor.insertCounter, pSubmitRsp->affectedRows, sample_labels);
|
||||
}
|
||||
|
||||
|
|
@ -2019,7 +2041,7 @@ static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t ver, void *pRe
|
|||
}
|
||||
|
||||
static int32_t vnodeProcessDeleteReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp,
|
||||
SRpcMsg *pOriginalMsg) {
|
||||
SRpcMsg *pOriginalMsg) {
|
||||
int32_t code = 0;
|
||||
SDecoder *pCoder = &(SDecoder){0};
|
||||
SDeleteRes *pRes = &(SDeleteRes){0};
|
||||
|
|
|
|||
|
|
@ -113,7 +113,13 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock,
|
|||
int32_t bytes = getSchemaBytes(pMeta->schema + i);
|
||||
colDataSetVal(pCol3, pBlock->info.rows, (const char*)&bytes, false);
|
||||
if (TSDB_VIEW_TABLE != pMeta->tableType) {
|
||||
STR_TO_VARSTR(buf, i >= pMeta->tableInfo.numOfColumns ? "TAG" : "");
|
||||
if (i >= pMeta->tableInfo.numOfColumns) {
|
||||
STR_TO_VARSTR(buf, "TAG");
|
||||
} else if (i == 1 && pMeta->schema[i].flags & COL_IS_KEY) {
|
||||
STR_TO_VARSTR(buf, "PRIMARY KEY")
|
||||
} else {
|
||||
STR_TO_VARSTR(buf, "");
|
||||
}
|
||||
} else {
|
||||
STR_TO_VARSTR(buf, "VIEW COL");
|
||||
}
|
||||
|
|
@ -507,8 +513,12 @@ void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
|
|||
} else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) {
|
||||
sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
}
|
||||
|
||||
*len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type);
|
||||
if (!(pSchema->flags & COL_IS_KEY)) {
|
||||
*len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type);
|
||||
} else {
|
||||
char* pk = "PRIMARY KEY";
|
||||
*len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s %s", ((i > 0) ? ", " : ""), pSchema->name, type, pk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ typedef struct SColMatchItem {
|
|||
bool needOutput;
|
||||
SDataType dataType;
|
||||
int32_t funcType;
|
||||
bool isPk;
|
||||
} SColMatchItem;
|
||||
|
||||
typedef struct SColMatchInfo {
|
||||
|
|
@ -161,6 +162,7 @@ bool hasRemainResults(SGroupResInfo* pGroupResInfo);
|
|||
int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo);
|
||||
|
||||
SSDataBlock* createDataBlockFromDescNode(SDataBlockDescNode* pNode);
|
||||
int32_t prepareDataBlockBuf(SSDataBlock* pDataBlock, SColMatchInfo* pMatchInfo);
|
||||
|
||||
EDealRes doTranslateTagExpr(SNode** pNode, void* pContext);
|
||||
int32_t getGroupIdFromTagsVal(void* pVnode, uint64_t uid, SNodeList* pGroupNode, char* keyBuf, uint64_t* pGroupId, SStorageAPI* pAPI);
|
||||
|
|
|
|||
|
|
@ -302,11 +302,13 @@ typedef struct STmsSubTableInput {
|
|||
|
||||
int32_t rowIdx;
|
||||
int64_t* aTs;
|
||||
SSDataBlock* pInputBlock;
|
||||
} STmsSubTableInput;
|
||||
|
||||
typedef struct SBlockOrderInfo SBlockOrderInfo;
|
||||
typedef struct STmsSubTablesMergeInfo {
|
||||
SBlockOrderInfo* pOrderInfo;
|
||||
SBlockOrderInfo* pTsOrderInfo;
|
||||
SBlockOrderInfo* pPkOrderInfo;
|
||||
|
||||
int32_t numSubTables;
|
||||
STmsSubTableInput* aInputs;
|
||||
|
|
@ -338,22 +340,21 @@ typedef struct STableMergeScanInfo {
|
|||
int32_t scanTimes;
|
||||
int32_t readIdx;
|
||||
SSDataBlock* pResBlock;
|
||||
SSampleExecInfo sample; // sample execution info
|
||||
SSHashObj* mTableNumRows; // uid->num of table rows
|
||||
SHashObj* mSkipTables;
|
||||
int64_t mergeLimit;
|
||||
SSampleExecInfo sample; // sample execution info
|
||||
SSHashObj* mTableNumRows; // uid->num of table rows
|
||||
SHashObj* mSkipTables;
|
||||
int64_t mergeLimit;
|
||||
SSortExecInfo sortExecInfo;
|
||||
bool needCountEmptyTable;
|
||||
bool bGroupProcessed; // the group return data means processed
|
||||
bool filesetDelimited;
|
||||
bool bNewFilesetEvent;
|
||||
bool bNextDurationBlockEvent;
|
||||
int32_t numNextDurationBlocks;
|
||||
SSDataBlock* nextDurationBlocks[2];
|
||||
bool rtnNextDurationBlocks;
|
||||
int32_t nextDurationBlocksIdx;
|
||||
|
||||
bool bSortRowId;
|
||||
bool needCountEmptyTable;
|
||||
bool bGroupProcessed; // the group return data means processed
|
||||
bool filesetDelimited;
|
||||
bool bNewFilesetEvent;
|
||||
bool bNextDurationBlockEvent;
|
||||
int32_t numNextDurationBlocks;
|
||||
SSDataBlock* nextDurationBlocks[2];
|
||||
bool rtnNextDurationBlocks;
|
||||
int32_t nextDurationBlocksIdx;
|
||||
bool bSortRowId;
|
||||
|
||||
STmsSubTablesMergeInfo* pSubTablesMergeInfo;
|
||||
} STableMergeScanInfo;
|
||||
|
|
@ -449,8 +450,10 @@ typedef struct SStreamScanInfo {
|
|||
SExprInfo* pPseudoExpr;
|
||||
int32_t numOfPseudoExpr;
|
||||
SExprSupp tbnameCalSup;
|
||||
SExprSupp* pPartTbnameSup;
|
||||
SExprSupp tagCalSup;
|
||||
int32_t primaryTsIndex; // primary time stamp slot id
|
||||
int32_t primaryKeyIndex;
|
||||
SReadHandle readHandle;
|
||||
SInterval interval; // if the upstream is an interval operator, the interval info is also kept here.
|
||||
SColMatchInfo matchInfo;
|
||||
|
|
@ -604,6 +607,8 @@ typedef struct SStreamIntervalOperatorInfo {
|
|||
bool clearState;
|
||||
SArray* pMidPullDatas;
|
||||
int32_t midDelIndex;
|
||||
SSHashObj* pDeletedMap;
|
||||
bool destHasPrimaryKey;
|
||||
} SStreamIntervalOperatorInfo;
|
||||
|
||||
typedef struct SDataGroupInfo {
|
||||
|
|
@ -654,6 +659,8 @@ typedef struct SStreamSessionAggOperatorInfo {
|
|||
SSDataBlock* pCheckpointRes;
|
||||
bool clearState;
|
||||
bool recvGetAll;
|
||||
bool destHasPrimaryKey;
|
||||
SSHashObj* pPkDeleted;
|
||||
} SStreamSessionAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamStateAggOperatorInfo {
|
||||
|
|
@ -678,6 +685,8 @@ typedef struct SStreamStateAggOperatorInfo {
|
|||
bool reCkBlock;
|
||||
SSDataBlock* pCheckpointRes;
|
||||
bool recvGetAll;
|
||||
SSHashObj* pPkDeleted;
|
||||
bool destHasPrimaryKey;
|
||||
} SStreamStateAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamEventAggOperatorInfo {
|
||||
|
|
@ -704,6 +713,8 @@ typedef struct SStreamEventAggOperatorInfo {
|
|||
SSDataBlock* pCheckpointRes;
|
||||
SFilterInfo* pStartCondInfo;
|
||||
SFilterInfo* pEndCondInfo;
|
||||
SSHashObj* pPkDeleted;
|
||||
bool destHasPrimaryKey;
|
||||
} SStreamEventAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamCountAggOperatorInfo {
|
||||
|
|
@ -725,6 +736,8 @@ typedef struct SStreamCountAggOperatorInfo {
|
|||
bool reCkBlock;
|
||||
bool recvGetAll;
|
||||
SSDataBlock* pCheckpointRes;
|
||||
SSHashObj* pPkDeleted;
|
||||
bool destHasPrimaryKey;
|
||||
} SStreamCountAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamPartitionOperatorInfo {
|
||||
|
|
@ -861,10 +874,8 @@ bool isOverdue(TSKEY ts, STimeWindowAggSupp* pSup);
|
|||
bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup);
|
||||
bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup,
|
||||
SStateStore* pStore);
|
||||
void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
|
||||
void appendDataToSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
|
||||
uint64_t* pGp, void* pTbName);
|
||||
void appendAllColumnToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, TSKEY* pCalStartTs,
|
||||
TSKEY* pCalEndTs, uint64_t* pUid, uint64_t* pGp, void* pTbName);
|
||||
|
||||
uint64_t calGroupIdByData(SPartitionBySupporter* pParSup, SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t rowId);
|
||||
|
||||
|
|
@ -897,13 +908,13 @@ int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo*
|
|||
int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SExprSupp* pExpSup, int32_t numOfOutput, int64_t gap,
|
||||
SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore,
|
||||
SReadHandle* pHandle, STimeWindowAggSupp* pTwAggSup, const char* taskIdStr,
|
||||
SStorageAPI* pApi);
|
||||
SStorageAPI* pApi, int32_t tsIndex);
|
||||
void initDownStream(struct SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uint16_t type, int32_t tsColIndex,
|
||||
STimeWindowAggSupp* pTwSup);
|
||||
void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins);
|
||||
void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList);
|
||||
void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey);
|
||||
void deleteSessionWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate, SSHashObj* pMapDelete);
|
||||
void deleteSessionWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate, SSHashObj* pMapDelete, SSHashObj* pPkDelete, bool needAdd);
|
||||
int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated);
|
||||
int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed);
|
||||
int32_t copyUpdateResult(SSHashObj** ppWinUpdated, SArray* pUpdated, __compar_fn_t compar);
|
||||
|
|
@ -953,6 +964,7 @@ bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pK
|
|||
void saveDeleteInfo(SArray* pWins, SSessionKey key);
|
||||
void removeSessionResults(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SArray* pWins);
|
||||
void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted);
|
||||
void copyDeleteSessionKey(SSHashObj* source, SSHashObj* dest);
|
||||
|
||||
bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pBlockInfo);
|
||||
bool inCalSlidingWindow(SInterval* pInterval, STimeWindow* pWin, TSKEY calStart, TSKEY calEnd, EStreamType blockType);
|
||||
|
|
|
|||
|
|
@ -56,10 +56,11 @@ typedef struct SMsortComparParam {
|
|||
bool cmpGroupId;
|
||||
|
||||
int32_t sortType;
|
||||
// the following field to speed up when sortType == SORT_BLOCK_TS_MERGE
|
||||
// the following fields to speed up sorting when sortType == SORT_BLOCK_TS_MERGE
|
||||
int32_t tsSlotId;
|
||||
int32_t order;
|
||||
__compar_fn_t cmpFn;
|
||||
int32_t tsOrder;
|
||||
__compar_fn_t cmpTsFn;
|
||||
void* pPkOrder; // SBlockOrderInfo*
|
||||
} SMsortComparParam;
|
||||
|
||||
typedef struct SSortHandle SSortHandle;
|
||||
|
|
@ -211,6 +212,9 @@ int32_t tsortCompAndBuildKeys(const SArray* pSortCols, char* keyBuf, int32_t* ke
|
|||
* @brief set the merge limit reached callback. it calls mergeLimitReached param with tableUid and param
|
||||
*/
|
||||
void tsortSetMergeLimitReachedFp(SSortHandle* pHandle, void (*mergeLimitReached)(uint64_t tableUid, void* param), void* param);
|
||||
|
||||
int tsortComparBlockCell(SSDataBlock* pLeftBlock, SSDataBlock* pRightBlock,
|
||||
int32_t leftRowIndex, int32_t rightRowIndex, void* pOrder);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,12 +40,14 @@ typedef struct SCacheRowsScanInfo {
|
|||
SExprSupp pseudoExprSup;
|
||||
int32_t retrieveType;
|
||||
int32_t currentGroupIndex;
|
||||
SSDataBlock* pBufferredRes;
|
||||
SSDataBlock* pBufferedRes;
|
||||
SArray* pUidList;
|
||||
SArray* pCidList;
|
||||
int32_t indexOfBufferedRes;
|
||||
STableListInfo* pTableList;
|
||||
SArray* pFuncTypeList;
|
||||
int32_t numOfPks;
|
||||
SColumnInfo pkCol;
|
||||
} SCacheRowsScanInfo;
|
||||
|
||||
static SSDataBlock* doScanCache(SOperatorInfo* pOperator);
|
||||
|
|
@ -106,6 +108,16 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe
|
|||
goto _error;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < taosArrayGetSize(pInfo->matchInfo.pList); ++i) {
|
||||
SColMatchItem* pItem = taosArrayGet(pInfo->matchInfo.pList, i);
|
||||
if (pItem->isPk) {
|
||||
pInfo->numOfPks += 1;
|
||||
pInfo->pkCol.type = pItem->dataType.type; // only record one primary key
|
||||
pInfo->pkCol.bytes = pItem->dataType.bytes; // only record one primary key
|
||||
pInfo->pkCol.pk = 1;
|
||||
}
|
||||
}
|
||||
|
||||
SArray* pCidList = taosArrayInit(numOfCols, sizeof(int16_t));
|
||||
pInfo->pFuncTypeList = taosArrayInit(taosArrayGetSize(pScanNode->pFuncTypes), sizeof(int32_t));
|
||||
taosArrayAddAll(pInfo->pFuncTypeList, pScanNode->pFuncTypes);
|
||||
|
|
@ -140,16 +152,17 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe
|
|||
uint64_t suid = tableListGetSuid(pTableListInfo);
|
||||
code = pInfo->readHandle.api.cacheFn.openReader(pInfo->readHandle.vnode, pInfo->retrieveType, pList, totalTables,
|
||||
taosArrayGetSize(pInfo->matchInfo.pList), pCidList, pInfo->pSlotIds,
|
||||
suid, &pInfo->pLastrowReader, pTaskInfo->id.str, pScanNode->pFuncTypes);
|
||||
suid, &pInfo->pLastrowReader, pTaskInfo->id.str, pScanNode->pFuncTypes,
|
||||
&pInfo->pkCol, pInfo->numOfPks);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
capacity = TMIN(totalTables, 4096);
|
||||
|
||||
pInfo->pBufferredRes = createOneDataBlock(pInfo->pRes, false);
|
||||
setColIdForCacheReadBlock(pInfo->pBufferredRes, pScanNode);
|
||||
blockDataEnsureCapacity(pInfo->pBufferredRes, capacity);
|
||||
pInfo->pBufferedRes = createOneDataBlock(pInfo->pRes, false);
|
||||
setColIdForCacheReadBlock(pInfo->pBufferedRes, pScanNode);
|
||||
blockDataEnsureCapacity(pInfo->pBufferedRes, capacity);
|
||||
} else { // by tags
|
||||
pInfo->retrieveType = CACHESCAN_RETRIEVE_TYPE_SINGLE | SCAN_ROW_TYPE(pScanNode->ignoreNull);
|
||||
capacity = 1; // only one row output
|
||||
|
|
@ -206,18 +219,18 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) {
|
|||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||
}
|
||||
|
||||
if (pInfo->indexOfBufferedRes >= pInfo->pBufferredRes->info.rows) {
|
||||
blockDataCleanup(pInfo->pBufferredRes);
|
||||
if (pInfo->indexOfBufferedRes >= pInfo->pBufferedRes->info.rows) {
|
||||
blockDataCleanup(pInfo->pBufferedRes);
|
||||
taosArrayClear(pInfo->pUidList);
|
||||
|
||||
int32_t code = pInfo->readHandle.api.cacheFn.retrieveRows(pInfo->pLastrowReader, pInfo->pBufferredRes, pInfo->pSlotIds,
|
||||
int32_t code = pInfo->readHandle.api.cacheFn.retrieveRows(pInfo->pLastrowReader, pInfo->pBufferedRes, pInfo->pSlotIds,
|
||||
pInfo->pDstSlotIds, pInfo->pUidList);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
// check for tag values
|
||||
int32_t resultRows = pInfo->pBufferredRes->info.rows;
|
||||
int32_t resultRows = pInfo->pBufferedRes->info.rows;
|
||||
|
||||
// the results may be null, if last values are all null
|
||||
ASSERT(resultRows == 0 || resultRows == taosArrayGetSize(pInfo->pUidList));
|
||||
|
|
@ -226,12 +239,12 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) {
|
|||
|
||||
SSDataBlock* pRes = pInfo->pRes;
|
||||
|
||||
if (pInfo->indexOfBufferedRes < pInfo->pBufferredRes->info.rows) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pInfo->pBufferredRes->pDataBlock); ++i) {
|
||||
if (pInfo->indexOfBufferedRes < pInfo->pBufferedRes->info.rows) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pInfo->pBufferedRes->pDataBlock); ++i) {
|
||||
SColumnInfoData* pCol = taosArrayGet(pRes->pDataBlock, i);
|
||||
int32_t slotId = pCol->info.slotId;
|
||||
|
||||
SColumnInfoData* pSrc = taosArrayGet(pInfo->pBufferredRes->pDataBlock, slotId);
|
||||
SColumnInfoData* pSrc = taosArrayGet(pInfo->pBufferedRes->pDataBlock, slotId);
|
||||
SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, slotId);
|
||||
|
||||
if (colDataIsNull_s(pSrc, pInfo->indexOfBufferedRes)) {
|
||||
|
|
@ -282,7 +295,7 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) {
|
|||
if (NULL == pInfo->pLastrowReader) {
|
||||
code = pInfo->readHandle.api.cacheFn.openReader(pInfo->readHandle.vnode, pInfo->retrieveType, pList, num,
|
||||
taosArrayGetSize(pInfo->matchInfo.pList), pInfo->pCidList, pInfo->pSlotIds, suid, &pInfo->pLastrowReader,
|
||||
pTaskInfo->id.str, pInfo->pFuncTypeList);
|
||||
pTaskInfo->id.str, pInfo->pFuncTypeList, &pInfo->pkCol, pInfo->numOfPks);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pInfo->currentGroupIndex += 1;
|
||||
taosArrayClear(pInfo->pUidList);
|
||||
|
|
@ -337,7 +350,7 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) {
|
|||
void destroyCacheScanOperator(void* param) {
|
||||
SCacheRowsScanInfo* pInfo = (SCacheRowsScanInfo*)param;
|
||||
blockDataDestroy(pInfo->pRes);
|
||||
blockDataDestroy(pInfo->pBufferredRes);
|
||||
blockDataDestroy(pInfo->pBufferedRes);
|
||||
taosMemoryFree(pInfo->pSlotIds);
|
||||
taosMemoryFree(pInfo->pDstSlotIds);
|
||||
taosArrayDestroy(pInfo->pCidList);
|
||||
|
|
|
|||
|
|
@ -189,8 +189,7 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp
|
|||
}
|
||||
|
||||
int64_t lastTs = TSKEY_MIN;
|
||||
bool updateLastRow = false;
|
||||
bool disorderTs = false;
|
||||
bool needSortMerge = false;
|
||||
|
||||
for (int32_t j = 0; j < rows; ++j) { // iterate by row
|
||||
taosArrayClear(pVals);
|
||||
|
|
@ -220,9 +219,10 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp
|
|||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
void* data = colDataGetVarData(pColInfoData, j);
|
||||
SValue sv = (SValue){.nData = varDataLen(data), .pData = varDataVal(data)}; // address copy, no value
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
void* data = colDataGetVarData(pColInfoData, j);
|
||||
SValue sv = (SValue){
|
||||
.type = pCol->type, .nData = varDataLen(data), .pData = varDataVal(data)}; // address copy, no value
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
break;
|
||||
|
|
@ -239,27 +239,25 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp
|
|||
if (pColInfoData->info.type < TSDB_DATA_TYPE_MAX && pColInfoData->info.type > TSDB_DATA_TYPE_NULL) {
|
||||
if (colDataIsNull_s(pColInfoData, j)) {
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) {
|
||||
qError("NULL value for primary key");
|
||||
qError("Primary timestamp column should not be null");
|
||||
terrno = TSDB_CODE_PAR_INCORRECT_TIMESTAMP_VAL;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
|
||||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); // should use pCol->type
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) {
|
||||
if (*(int64_t*)var == lastTs) {
|
||||
updateLastRow = true;
|
||||
} else if (*(int64_t*)var < lastTs) {
|
||||
disorderTs = true;
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && !needSortMerge) {
|
||||
if (*(int64_t*)var <= lastTs) {
|
||||
needSortMerge = true;
|
||||
} else {
|
||||
lastTs = *(int64_t*)var;
|
||||
}
|
||||
}
|
||||
|
||||
SValue sv;
|
||||
SValue sv = {.type = pCol->type};
|
||||
memcpy(&sv.val, var, tDataTypes[pCol->type].bytes);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -276,19 +274,12 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp
|
|||
tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
||||
goto _end;
|
||||
}
|
||||
if (updateLastRow) {
|
||||
updateLastRow = false;
|
||||
SRow** lastRow = taosArrayPop(tbData.aRowP);
|
||||
tRowDestroy(*lastRow);
|
||||
taosArrayPush(tbData.aRowP, &pRow);
|
||||
} else {
|
||||
taosArrayPush(tbData.aRowP, &pRow);
|
||||
}
|
||||
taosArrayPush(tbData.aRowP, &pRow);
|
||||
}
|
||||
|
||||
if (disorderTs) {
|
||||
if (needSortMerge) {
|
||||
if ((tRowSort(tbData.aRowP) != TSDB_CODE_SUCCESS) ||
|
||||
(terrno = tRowMerge(tbData.aRowP, (STSchema*)pTSchema, 0)) != 0) {
|
||||
(terrno = tRowMerge(tbData.aRowP, (STSchema*)pTSchema, 0)) != 0) {
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
|
@ -393,7 +384,7 @@ static int32_t destroyDataSinker(SDataSinkHandle* pHandle) {
|
|||
taosMemoryFree(pInserter->pParam);
|
||||
taosHashCleanup(pInserter->pCols);
|
||||
taosThreadMutexDestroy(&pInserter->mutex);
|
||||
|
||||
|
||||
taosMemoryFree(pInserter->pManager);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
@ -475,6 +466,6 @@ _return:
|
|||
} else {
|
||||
taosMemoryFree(pManager);
|
||||
}
|
||||
|
||||
return terrno;
|
||||
|
||||
return terrno;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,6 +250,41 @@ SSDataBlock* createDataBlockFromDescNode(SDataBlockDescNode* pNode) {
|
|||
return pBlock;
|
||||
}
|
||||
|
||||
int32_t prepareDataBlockBuf(SSDataBlock* pDataBlock, SColMatchInfo* pMatchInfo) {
|
||||
SDataBlockInfo* pBlockInfo = &pDataBlock->info;
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pMatchInfo->pList); ++i) {
|
||||
SColMatchItem* pItem = taosArrayGet(pMatchInfo->pList, i);
|
||||
|
||||
if (pItem->isPk) {
|
||||
SColumnInfoData* pInfoData = taosArrayGet(pDataBlock->pDataBlock, pItem->dstSlotId);
|
||||
pBlockInfo->pks[0].type = pInfoData->info.type;
|
||||
pBlockInfo->pks[1].type = pInfoData->info.type;
|
||||
|
||||
// allocate enough buffer size, which is pInfoData->info.bytes
|
||||
if (IS_VAR_DATA_TYPE(pItem->dataType.type)) {
|
||||
pBlockInfo->pks[0].pData = taosMemoryCalloc(1, pInfoData->info.bytes);
|
||||
if (pBlockInfo->pks[0].pData == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pBlockInfo->pks[1].pData = taosMemoryCalloc(1, pInfoData->info.bytes);
|
||||
if (pBlockInfo->pks[1].pData == NULL) {
|
||||
taosMemoryFreeClear(pBlockInfo->pks[0].pData);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pBlockInfo->pks[0].nData = pInfoData->info.bytes;
|
||||
pBlockInfo->pks[1].nData = pInfoData->info.bytes;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
EDealRes doTranslateTagExpr(SNode** pNode, void* pContext) {
|
||||
SMetaReader* mr = (SMetaReader*)pContext;
|
||||
if (nodeType(*pNode) == QUERY_NODE_COLUMN) {
|
||||
|
|
@ -370,7 +405,8 @@ static EDealRes getColumn(SNode** pNode, void* pContext) {
|
|||
pSColumnNode->slotId = pData->index++;
|
||||
SColumnInfo cInfo = {.colId = pSColumnNode->colId,
|
||||
.type = pSColumnNode->node.resType.type,
|
||||
.bytes = pSColumnNode->node.resType.bytes};
|
||||
.bytes = pSColumnNode->node.resType.bytes,
|
||||
.pk = pSColumnNode->isPk};
|
||||
#if TAG_FILTER_DEBUG
|
||||
qDebug("tagfilter build column info, slotId:%d, colId:%d, type:%d", pSColumnNode->slotId, cInfo.colId, cInfo.type);
|
||||
#endif
|
||||
|
|
@ -1342,6 +1378,8 @@ int32_t extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
c.colId = pColNode->colId;
|
||||
c.srcSlotId = pColNode->slotId;
|
||||
c.dstSlotId = pNode->slotId;
|
||||
c.isPk = pColNode->isPk;
|
||||
c.dataType = pColNode->node.resType;
|
||||
taosArrayPush(pList, &c);
|
||||
}
|
||||
}
|
||||
|
|
@ -1765,6 +1803,7 @@ int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysi
|
|||
pCond->colList[j].type = pColNode->node.resType.type;
|
||||
pCond->colList[j].bytes = pColNode->node.resType.bytes;
|
||||
pCond->colList[j].colId = pColNode->colId;
|
||||
pCond->colList[j].pk = pColNode->isPk;
|
||||
|
||||
pCond->pSlotList[j] = pNode->slotId;
|
||||
j += 1;
|
||||
|
|
|
|||
|
|
@ -1082,7 +1082,7 @@ SMqMetaRsp* qStreamExtractMetaMsg(qTaskInfo_t tinfo) {
|
|||
|
||||
void qStreamExtractOffset(qTaskInfo_t tinfo, STqOffsetVal* pOffset) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
memcpy(pOffset, &pTaskInfo->streamInfo.currentOffset, sizeof(STqOffsetVal));
|
||||
tOffsetCopy(pOffset, &pTaskInfo->streamInfo.currentOffset);
|
||||
}
|
||||
|
||||
int32_t initQueryTableDataCondForTmq(SQueryTableDataCond* pCond, SSnapContext* sContext, SMetaTableInfo* pMtInfo) {
|
||||
|
|
@ -1109,6 +1109,7 @@ int32_t initQueryTableDataCondForTmq(SQueryTableDataCond* pCond, SSnapContext* s
|
|||
pColInfo->type = pMtInfo->schema->pSchema[i].type;
|
||||
pColInfo->bytes = pMtInfo->schema->pSchema[i].bytes;
|
||||
pColInfo->colId = pMtInfo->schema->pSchema[i].colId;
|
||||
pColInfo->pk = pMtInfo->schema->pSchema[i].flags & COL_IS_KEY;
|
||||
|
||||
pCond->pSlotList[i] = i;
|
||||
}
|
||||
|
|
@ -1161,7 +1162,6 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
|||
STableListInfo* pTableListInfo = pScanBaseInfo->pTableListInfo;
|
||||
|
||||
if (pOffset->type == TMQ_OFFSET__LOG) {
|
||||
// todo refactor: move away
|
||||
pTaskInfo->storageAPI.tsdReader.tsdReaderClose(pScanBaseInfo->dataReader);
|
||||
pScanBaseInfo->dataReader = NULL;
|
||||
|
||||
|
|
@ -1196,6 +1196,7 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
pTaskInfo->storageAPI.tqReaderFn.tqSetTablePrimaryKey(pInfo->tqReader, uid);
|
||||
|
||||
qDebug("switch to table uid:%" PRId64 " ts:%" PRId64 "% " PRId64 " rows returned", uid, ts,
|
||||
pInfo->pTableScanOp->resultInfo.totalRows);
|
||||
|
|
@ -1220,7 +1221,11 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
|||
int64_t oldSkey = pScanBaseInfo->cond.twindows.skey;
|
||||
|
||||
// let's start from the next ts that returned to consumer.
|
||||
pScanBaseInfo->cond.twindows.skey = ts + 1;
|
||||
if(pTaskInfo->storageAPI.tqReaderFn.tqGetTablePrimaryKey(pInfo->tqReader)){
|
||||
pScanBaseInfo->cond.twindows.skey = ts;
|
||||
}else{
|
||||
pScanBaseInfo->cond.twindows.skey = ts + 1;
|
||||
}
|
||||
pScanInfo->scanTimes = 0;
|
||||
|
||||
if (pScanBaseInfo->dataReader == NULL) {
|
||||
|
|
@ -1251,7 +1256,6 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
|||
}
|
||||
|
||||
} else { // subType == TOPIC_SUB_TYPE__TABLE/TOPIC_SUB_TYPE__DB
|
||||
|
||||
if (pOffset->type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
||||
SStreamRawScanInfo* pInfo = pOperator->info;
|
||||
SSnapContext* sContext = pInfo->sContext;
|
||||
|
|
@ -1276,8 +1280,13 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
|||
goto end; // no data
|
||||
}
|
||||
|
||||
pAPI->snapshotFn.taosXSetTablePrimaryKey(sContext, mtInfo.uid);
|
||||
initQueryTableDataCondForTmq(&pTaskInfo->streamInfo.tableCond, sContext, &mtInfo);
|
||||
pTaskInfo->streamInfo.tableCond.twindows.skey = pOffset->ts;
|
||||
if(pAPI->snapshotFn.taosXGetTablePrimaryKey(sContext)){
|
||||
pTaskInfo->streamInfo.tableCond.twindows.skey = pOffset->ts;
|
||||
}else{
|
||||
pTaskInfo->streamInfo.tableCond.twindows.skey = pOffset->ts + 1;
|
||||
}
|
||||
|
||||
tableListAddTableInfo(pTableListInfo, mtInfo.uid, 0);
|
||||
|
||||
|
|
@ -1312,7 +1321,7 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
|||
}
|
||||
|
||||
end:
|
||||
pTaskInfo->streamInfo.currentOffset = *pOffset;
|
||||
tOffsetCopy(&pTaskInfo->streamInfo.currentOffset, pOffset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -303,6 +303,12 @@ static int32_t doSetInputDataBlock(SExprSupp* pExprSup, SSDataBlock* pBlock, int
|
|||
pInput->colDataSMAIsSet = false;
|
||||
|
||||
SExprInfo* pOneExpr = &pExprSup->pExprInfo[i];
|
||||
bool hasPk = pOneExpr->pExpr->nodeType == QUERY_NODE_FUNCTION && pOneExpr->pExpr->_function.pFunctNode->hasPk;
|
||||
pCtx[i].hasPrimaryKey = hasPk;
|
||||
|
||||
int16_t tsParamIdx = (!hasPk) ? pOneExpr->base.numOfParams - 1 : pOneExpr->base.numOfParams - 2;
|
||||
int16_t pkParamIdx = pOneExpr->base.numOfParams - 1;
|
||||
|
||||
for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
|
||||
SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
|
||||
if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
|
||||
|
|
@ -315,9 +321,13 @@ static int32_t doSetInputDataBlock(SExprSupp* pExprSup, SSDataBlock* pBlock, int
|
|||
|
||||
// NOTE: the last parameter is the primary timestamp column
|
||||
// todo: refactor this
|
||||
if (fmIsImplicitTsFunc(pCtx[i].functionId) && (j == pOneExpr->base.numOfParams - 1)) {
|
||||
|
||||
if (fmIsImplicitTsFunc(pCtx[i].functionId) && (j == tsParamIdx)) {
|
||||
pInput->pPTS = pInput->pData[j]; // in case of merge function, this is not always the ts column data.
|
||||
}
|
||||
if (hasPk && (j == pkParamIdx)) {
|
||||
pInput->pPrimaryKey = pInput->pData[j];
|
||||
}
|
||||
ASSERT(pInput->pData[j] != NULL);
|
||||
} else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
|
||||
// todo avoid case: top(k, 12), 12 is the value parameter.
|
||||
|
|
|
|||
|
|
@ -1255,7 +1255,7 @@ static void destroyStreamPartitionOperatorInfo(void* param) {
|
|||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
void initParDownStream(SOperatorInfo* downstream, SPartitionBySupporter* pParSup, SExprSupp* pExpr) {
|
||||
void initParDownStream(SOperatorInfo* downstream, SPartitionBySupporter* pParSup, SExprSupp* pExpr, SExprSupp* pTbnameExpr) {
|
||||
SStorageAPI* pAPI = &downstream->pTaskInfo->storageAPI;
|
||||
|
||||
if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
|
|
@ -1265,6 +1265,7 @@ void initParDownStream(SOperatorInfo* downstream, SPartitionBySupporter* pParSup
|
|||
SStreamScanInfo* pScanInfo = downstream->info;
|
||||
pScanInfo->partitionSup = *pParSup;
|
||||
pScanInfo->pPartScalarSup = pExpr;
|
||||
pScanInfo->pPartTbnameSup = pTbnameExpr;
|
||||
if (!pScanInfo->pUpdateInfo) {
|
||||
pScanInfo->pUpdateInfo = pAPI->stateStore.updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, 0, pScanInfo->igCheckUpdate);
|
||||
}
|
||||
|
|
@ -1408,7 +1409,7 @@ SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStr
|
|||
destroyStreamPartitionOperatorInfo, optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
|
||||
setOperatorStreamStateFn(pOperator, streamOpReleaseState, streamOpReloadState);
|
||||
|
||||
initParDownStream(downstream, &pInfo->partitionSup, &pInfo->scalarSup);
|
||||
initParDownStream(downstream, &pInfo->partitionSup, &pInfo->scalarSup, &pInfo->tbnameCalSup);
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
||||
|
|
|
|||
|
|
@ -387,14 +387,14 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
|||
pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0;
|
||||
}
|
||||
|
||||
if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
||||
printDataBlock(p, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
}
|
||||
|
||||
if (pProjectInfo->outputIgnoreGroup) {
|
||||
p->info.id.groupId = 0;
|
||||
}
|
||||
|
||||
if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
||||
printDataBlock(p, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
}
|
||||
|
||||
return (p->info.rows > 0) ? p : NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -209,7 +209,10 @@ SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode) {
|
|||
return pqSw;
|
||||
}
|
||||
|
||||
static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) { tDeleteSchemaWrapper(pStreamInfo->schema); }
|
||||
static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) {
|
||||
tDeleteSchemaWrapper(pStreamInfo->schema);
|
||||
tOffsetDestroy(&pStreamInfo->currentOffset);
|
||||
}
|
||||
|
||||
static void freeBlock(void* pParam) {
|
||||
SSDataBlock* pBlock = *(SSDataBlock**)pParam;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -24,7 +24,7 @@
|
|||
#include "tlog.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#define IS_FINAL_COUNT_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_COUNT)
|
||||
#define IS_NORMAL_COUNT_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT)
|
||||
#define STREAM_COUNT_OP_STATE_NAME "StreamCountHistoryState"
|
||||
#define STREAM_COUNT_OP_CHECKPOINT_NAME "StreamCountOperator_Checkpoint"
|
||||
|
||||
|
|
@ -61,6 +61,8 @@ void destroyStreamCountAggOperatorInfo(void* param) {
|
|||
taosArrayDestroy(pInfo->historyWins);
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
|
||||
tSimpleHashCleanup(pInfo->pPkDeleted);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
|
|
@ -267,23 +269,27 @@ static void doStreamCountAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
range.win.skey = TMIN(startTsCols[i], range.win.skey);
|
||||
range.win.ekey = TMAX(startTsCols[rows-1], range.win.ekey);
|
||||
uint64_t uid = 0;
|
||||
appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &range.win.skey, &range.win.ekey, &uid, &range.groupId, NULL);
|
||||
appendDataToSpecialBlock(pAggSup->pScanBlock, &range.win.skey, &range.win.ekey, &uid, &range.groupId, NULL);
|
||||
break;
|
||||
}
|
||||
code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput,
|
||||
pOperator, 0);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s do stream count aggregate impl error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
saveSessionOutputBuf(pAggSup, &curWin.winInfo);
|
||||
|
||||
if (pInfo->destHasPrimaryKey && curWin.winInfo.isOutput && IS_NORMAL_COUNT_OP(pOperator)) {
|
||||
saveDeleteRes(pInfo->pPkDeleted, curWin.winInfo.sessionWin);
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) {
|
||||
code = saveResult(curWin.winInfo, pStUpdated);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s do stream count aggregate impl, set result error, code %s", GET_TASKID(pTaskInfo),
|
||||
tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
|
|
@ -484,7 +490,7 @@ void doDeleteCountWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SAr
|
|||
}
|
||||
|
||||
void deleteCountWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate,
|
||||
SSHashObj* pMapDelete) {
|
||||
SSHashObj* pMapDelete, SSHashObj* pPkDelete, bool needAdd) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
doDeleteCountWindows(pAggSup, pBlock, pWins);
|
||||
|
|
@ -493,6 +499,9 @@ void deleteCountWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHa
|
|||
}
|
||||
removeSessionResults(pAggSup, pMapUpdate, pWins);
|
||||
copyDeleteWindowInfo(pWins, pMapDelete);
|
||||
if (needAdd) {
|
||||
copyDeleteWindowInfo(pWins, pPkDelete);
|
||||
}
|
||||
taosArrayDestroy(pWins);
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +551,8 @@ static SSDataBlock* doStreamCountAgg(SOperatorInfo* pOperator) {
|
|||
printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo));
|
||||
|
||||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
|
||||
deleteCountWinState(&pInfo->streamAggSup, pBlock, pInfo->pStUpdated, pInfo->pStDeleted);
|
||||
bool add = pInfo->destHasPrimaryKey && IS_NORMAL_COUNT_OP(pOperator);
|
||||
deleteCountWinState(&pInfo->streamAggSup, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, pInfo->pPkDeleted, add);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_CLEAR) {
|
||||
doResetCountWindows(&pInfo->streamAggSup, pBlock);
|
||||
|
|
@ -582,6 +592,10 @@ static SSDataBlock* doStreamCountAgg(SOperatorInfo* pOperator) {
|
|||
pInfo->pUpdated = NULL;
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
if (pInfo->destHasPrimaryKey && IS_NORMAL_COUNT_OP(pOperator)) {
|
||||
copyDeleteSessionKey(pInfo->pPkDeleted, pInfo->pStDeleted);
|
||||
}
|
||||
|
||||
SSDataBlock* opRes = buildCountResult(pOperator);
|
||||
if (opRes) {
|
||||
return opRes;
|
||||
|
|
@ -657,9 +671,10 @@ SOperatorInfo* createStreamCountAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pCountNode->window.pTspk)->slotId;
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, 0,
|
||||
pTaskInfo->streamInfo.pState, sizeof(COUNT_TYPE), 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI, pInfo->primaryTsIndex);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
|
@ -675,8 +690,6 @@ SOperatorInfo* createStreamCountAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pCountNode->window.pTspk)->slotId;
|
||||
|
||||
pInfo->binfo.pRes = pResBlock;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pStDeleted = tSimpleHashInit(64, hashFn);
|
||||
|
|
@ -694,6 +707,8 @@ SOperatorInfo* createStreamCountAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
|
||||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
pInfo->recvGetAll = false;
|
||||
pInfo->pPkDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->destHasPrimaryKey = pCountNode->window.destHasPrimayKey;
|
||||
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT;
|
||||
setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT, true,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "tlog.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#define IS_FINAL_EVENT_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_EVENT)
|
||||
#define IS_NORMAL_EVENT_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT)
|
||||
#define STREAM_EVENT_OP_STATE_NAME "StreamEventHistoryState"
|
||||
#define STREAM_EVENT_OP_CHECKPOINT_NAME "StreamEventOperator_Checkpoint"
|
||||
|
||||
|
|
@ -66,6 +66,8 @@ void destroyStreamEventOperatorInfo(void* param) {
|
|||
taosArrayDestroy(pInfo->historyWins);
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
|
||||
tSimpleHashCleanup(pInfo->pPkDeleted);
|
||||
|
||||
if (pInfo->pStartCondInfo != NULL) {
|
||||
filterFreeInfo(pInfo->pStartCondInfo);
|
||||
pInfo->pStartCondInfo = NULL;
|
||||
|
|
@ -99,17 +101,21 @@ int32_t getEndCondIndex(bool* pEnd, int32_t start, int32_t rows) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static bool isWindowIncomplete(SEventWindowInfo* pWinInfo) {
|
||||
return !(pWinInfo->pWinFlag->startFlag && pWinInfo->pWinFlag->endFlag);
|
||||
}
|
||||
int32_t reuseOutputBuf(void* pState, SRowBuffPos* pPos, SStateStore* pAPI) {
|
||||
pAPI->streamStateReleaseBuf(pState, pPos, true);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void setEventOutputBuf(SStreamAggSupporter* pAggSup, TSKEY* pTs, uint64_t groupId, bool* pStart, bool* pEnd, int32_t index, int32_t rows, SEventWindowInfo* pCurWin, SSessionKey* pNextWinKey) {
|
||||
void setEventOutputBuf(SStreamAggSupporter* pAggSup, TSKEY* pTs, uint64_t groupId, bool* pStart, bool* pEnd,
|
||||
int32_t index, int32_t rows, SEventWindowInfo* pCurWin, SSessionKey* pNextWinKey) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t size = pAggSup->resultRowSize;
|
||||
TSKEY ts = pTs [index];
|
||||
bool start = pStart[index];
|
||||
bool end = pEnd[index];
|
||||
TSKEY ts = pTs[index];
|
||||
bool start = pStart[index];
|
||||
bool end = pEnd[index];
|
||||
pCurWin->winInfo.sessionWin.groupId = groupId;
|
||||
pCurWin->winInfo.sessionWin.win.skey = ts;
|
||||
pCurWin->winInfo.sessionWin.win.ekey = ts;
|
||||
|
|
@ -122,7 +128,7 @@ void setEventOutputBuf(SStreamAggSupporter* pAggSup, TSKEY* pTs, uint64_t groupI
|
|||
bool inWin = isInTimeWindow(&leftWinKey.win, ts, 0);
|
||||
setEventWindowInfo(pAggSup, &leftWinKey, pVal, pCurWin);
|
||||
if(inWin || (pCurWin->pWinFlag->startFlag && !pCurWin->pWinFlag->endFlag) ) {
|
||||
pCurWin->winInfo.isOutput = true;
|
||||
pCurWin->winInfo.isOutput = !isWindowIncomplete(pCurWin);
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
|
@ -135,7 +141,7 @@ void setEventOutputBuf(SStreamAggSupporter* pAggSup, TSKEY* pTs, uint64_t groupI
|
|||
int32_t endi = getEndCondIndex(pEnd, index, rows);
|
||||
if (endi < 0 || pTs[endi] >= rightWinKey.win.skey) {
|
||||
setEventWindowInfo(pAggSup, &rightWinKey, pVal, pCurWin);
|
||||
pCurWin->winInfo.isOutput = true;
|
||||
pCurWin->winInfo.isOutput = !isWindowIncomplete(pCurWin);
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
|
@ -247,10 +253,6 @@ static int32_t compactEventWindow(SOperatorInfo* pOperator, SEventWindowInfo* pC
|
|||
return winNum;
|
||||
}
|
||||
|
||||
static bool isWindowIncomplete(SEventWindowInfo* pWinInfo) {
|
||||
return !(pWinInfo->pWinFlag->startFlag && pWinInfo->pWinFlag->endFlag);
|
||||
}
|
||||
|
||||
bool doDeleteEventWindow(SStreamAggSupporter* pAggSup, SSHashObj* pSeUpdated, SSessionKey* pKey) {
|
||||
pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey);
|
||||
removeSessionResult(pAggSup, pSeUpdated, pAggSup->pResultRows, pKey);
|
||||
|
|
@ -324,10 +326,13 @@ static void doStreamEventAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
ASSERT(winRows >= 1);
|
||||
if (rebuild) {
|
||||
uint64_t uid = 0;
|
||||
appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey,
|
||||
appendDataToSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey,
|
||||
&curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL);
|
||||
tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey));
|
||||
doDeleteEventWindow(pAggSup, pSeUpdated, &curWin.winInfo.sessionWin);
|
||||
if (pInfo->destHasPrimaryKey && curWin.winInfo.isOutput && IS_NORMAL_EVENT_OP(pOperator) && !isWindowIncomplete(&curWin)) {
|
||||
saveDeleteRes(pInfo->pPkDeleted, curWin.winInfo.sessionWin);
|
||||
}
|
||||
releaseOutputBuf(pAggSup->pState, curWin.winInfo.pStatePos, &pAPI->stateStore);
|
||||
SSessionKey tmpSeInfo = {0};
|
||||
getSessionHashKey(&curWin.winInfo.sessionWin, &tmpSeInfo);
|
||||
|
|
@ -337,7 +342,7 @@ static void doStreamEventAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput,
|
||||
pOperator, 0);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
compactEventWindow(pOperator, &curWin, pInfo->pSeUpdated, pInfo->pSeDeleted, false);
|
||||
saveSessionOutputBuf(pAggSup, &curWin.winInfo);
|
||||
|
|
@ -351,6 +356,10 @@ static void doStreamEventAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
continue;
|
||||
}
|
||||
|
||||
if (pInfo->destHasPrimaryKey && curWin.winInfo.isOutput && IS_NORMAL_EVENT_OP(pOperator)) {
|
||||
saveDeleteRes(pInfo->pPkDeleted, curWin.winInfo.sessionWin);
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
code = saveResult(curWin.winInfo, pSeUpdated);
|
||||
}
|
||||
|
|
@ -523,7 +532,8 @@ static SSDataBlock* doStreamEventAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
|
||||
pBlock->info.type == STREAM_CLEAR) {
|
||||
deleteSessionWinState(&pInfo->streamAggSup, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted);
|
||||
bool add = pInfo->destHasPrimaryKey && IS_NORMAL_EVENT_OP(pOperator);
|
||||
deleteSessionWinState(&pInfo->streamAggSup, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted, pInfo->pPkDeleted, add);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
pInfo->recvGetAll = true;
|
||||
|
|
@ -563,6 +573,9 @@ static SSDataBlock* doStreamEventAgg(SOperatorInfo* pOperator) {
|
|||
getMaxTsWins(pHisWins, pInfo->historyWins);
|
||||
taosArrayDestroy(pHisWins);
|
||||
}
|
||||
if (pInfo->destHasPrimaryKey && IS_NORMAL_EVENT_OP(pOperator)) {
|
||||
copyDeleteSessionKey(pInfo->pPkDeleted, pInfo->pSeDeleted);
|
||||
}
|
||||
|
||||
initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated);
|
||||
pInfo->pUpdated = NULL;
|
||||
|
|
@ -709,14 +722,14 @@ SOperatorInfo* createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->primaryTsIndex = tsSlotId;
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, 0, pTaskInfo->streamInfo.pState,
|
||||
sizeof(bool) + sizeof(bool), 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI, pInfo->primaryTsIndex);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->primaryTsIndex = tsSlotId;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pSeDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->pDelIterator = NULL;
|
||||
|
|
@ -744,6 +757,8 @@ SOperatorInfo* createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
pInfo->reCkBlock = false;
|
||||
pInfo->recvGetAll = false;
|
||||
pInfo->pPkDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->destHasPrimaryKey = pEventNode->window.destHasPrimayKey;
|
||||
|
||||
setOperatorInfo(pOperator, "StreamEventAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT, true, OP_NOT_OPENED,
|
||||
pInfo, pTaskInfo);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,13 @@
|
|||
|
||||
#define IS_FINAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL)
|
||||
#define IS_MID_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL)
|
||||
#define IS_NORMAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL || (op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL)
|
||||
|
||||
#define IS_FINAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION)
|
||||
#define IS_NORMAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION || (op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION)
|
||||
|
||||
#define IS_NORMAL_STATE_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE)
|
||||
|
||||
#define DEAULT_DELETE_MARK INT64_MAX
|
||||
#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState"
|
||||
#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState"
|
||||
|
|
@ -371,11 +377,11 @@ static void doBuildDeleteResult(SStreamIntervalOperatorInfo* pInfo, SArray* pWin
|
|||
void* tbname = NULL;
|
||||
pInfo->stateStore.streamStateGetParName(pInfo->pState, pWin->groupId, &tbname);
|
||||
if (tbname == NULL) {
|
||||
appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, NULL);
|
||||
appendDataToSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, NULL);
|
||||
} else {
|
||||
char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN];
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName));
|
||||
appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, parTbName);
|
||||
appendDataToSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, parTbName);
|
||||
}
|
||||
pInfo->stateStore.streamStateFreeVal(tbname);
|
||||
(*index)++;
|
||||
|
|
@ -432,6 +438,7 @@ void destroyStreamFinalIntervalOperatorInfo(void* param) {
|
|||
tSimpleHashCleanup(pInfo->pUpdatedMap);
|
||||
pInfo->pUpdatedMap = NULL;
|
||||
pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated);
|
||||
tSimpleHashCleanup(pInfo->pDeletedMap);
|
||||
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
|
||||
|
|
@ -526,9 +533,7 @@ int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResu
|
|||
char* value = NULL;
|
||||
int32_t size = pAggSup->resultRowSize;
|
||||
|
||||
if (pStore->streamStateAddIfNotExist(pState, &key, (void**)&value, &size) < 0) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
int32_t code = pStore->streamStateAddIfNotExist(pState, &key, (void**)&value, &size);
|
||||
|
||||
*pResult = (SRowBuffPos*)value;
|
||||
SResultRow* res = (SResultRow*)((*pResult)->pRowBuff);
|
||||
|
|
@ -536,7 +541,7 @@ int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResu
|
|||
// set time window for current result
|
||||
res->win = (*win);
|
||||
setResultRowInitCtx(res, pCtx, numOfOutput, rowEntryInfoOffset);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup,
|
||||
|
|
@ -612,6 +617,7 @@ static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pB
|
|||
|
||||
static bool processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins,
|
||||
int32_t numOfCh, SOperatorInfo* pOperator) {
|
||||
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
|
||||
TSKEY* tsData = (TSKEY*)pStartCol->pData;
|
||||
SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
|
||||
|
|
@ -654,6 +660,10 @@ static bool processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFina
|
|||
taosArrayPush(pInfo->pMidPullDatas, &winRes);
|
||||
} else if (savePullWindow(&pull, pPullWins) == TSDB_CODE_SUCCESS) {
|
||||
addPullWindow(pMap, &winRes, numOfCh);
|
||||
if (pInfo->destHasPrimaryKey) {
|
||||
tSimpleHashPut(pInfo->pDeletedMap,&winRes, sizeof(SWinKey), NULL, 0);
|
||||
}
|
||||
qDebug("===stream===prepare final retrive for delete %" PRId64 ", size:%d", winRes.ts, numOfCh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -677,6 +687,9 @@ static void addRetriveWindow(SArray* wins, SStreamIntervalOperatorInfo* pInfo, i
|
|||
// add pull data request
|
||||
if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) {
|
||||
addPullWindow(pInfo->pPullDataMap, winKey, pInfo->numOfChild);
|
||||
if (pInfo->destHasPrimaryKey) {
|
||||
tSimpleHashPut(pInfo->pDeletedMap,winKey, sizeof(SWinKey), NULL, 0);
|
||||
}
|
||||
qDebug("===stream===prepare retrive for delete %" PRId64 ", size:%d", winKey->ts, pInfo->numOfChild);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -807,7 +820,7 @@ static int32_t getNextQualifiedFinalWindow(SInterval* pInterval, STimeWindow* pN
|
|||
}
|
||||
|
||||
static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, uint64_t groupId,
|
||||
SSHashObj* pUpdatedMap) {
|
||||
SSHashObj* pUpdatedMap, SSHashObj* pDeletedMap) {
|
||||
SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperator->info;
|
||||
pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version);
|
||||
|
||||
|
|
@ -875,6 +888,9 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
// add pull data request
|
||||
if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) {
|
||||
addPullWindow(pInfo->pPullDataMap, &winRes, pInfo->numOfChild);
|
||||
if (pInfo->destHasPrimaryKey) {
|
||||
tSimpleHashPut(pInfo->pDeletedMap,&winRes, sizeof(SWinKey), NULL, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int32_t index = -1;
|
||||
|
|
@ -902,9 +918,9 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
int32_t code = setIntervalOutputBuf(pInfo->pState, &nextWin, &pResPos, groupId, pSup->pCtx, numOfOutput,
|
||||
pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->stateStore);
|
||||
pResult = (SResultRow*)pResPos->pRowBuff;
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
if (pResult == NULL) {
|
||||
qError("%s set interval output buff error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
if (IS_FINAL_INTERVAL_OP(pOperator)) {
|
||||
forwardRows = 1;
|
||||
|
|
@ -917,6 +933,11 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
.ts = pResult->win.skey,
|
||||
.groupId = groupId,
|
||||
};
|
||||
|
||||
if (pInfo->destHasPrimaryKey && code == TSDB_CODE_SUCCESS && IS_NORMAL_INTERVAL_OP(pOperator)) {
|
||||
tSimpleHashPut(pDeletedMap,&key, sizeof(SWinKey), NULL, 0);
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) {
|
||||
saveWinResult(&key, pResPos, pUpdatedMap);
|
||||
}
|
||||
|
|
@ -1174,6 +1195,16 @@ void doStreamIntervalSaveCheckpoint(SOperatorInfo* pOperator) {
|
|||
taosMemoryFree(buf);
|
||||
}
|
||||
|
||||
static void copyIntervalDeleteKey(SSHashObj* pMap, SArray* pWins) {
|
||||
void* pIte = NULL;
|
||||
int32_t iter = 0;
|
||||
while ((pIte = tSimpleHashIterate(pMap, pIte, &iter)) != NULL) {
|
||||
void* pKey = tSimpleHashGetKey(pIte, NULL);
|
||||
taosArrayPush(pWins, pKey);
|
||||
}
|
||||
tSimpleHashClear(pMap);
|
||||
}
|
||||
|
||||
static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator) {
|
||||
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
|
@ -1359,7 +1390,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
|
||||
}
|
||||
setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
|
||||
doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap);
|
||||
doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap, pInfo->pDeletedMap);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark);
|
||||
pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey);
|
||||
|
|
@ -1369,6 +1400,9 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
if (IS_FINAL_INTERVAL_OP(pOperator)) {
|
||||
closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval,
|
||||
pInfo->pPullDataMap, pInfo->pUpdatedMap, pInfo->pDelWins, pOperator);
|
||||
if (pInfo->destHasPrimaryKey) {
|
||||
copyIntervalDeleteKey(pInfo->pDeletedMap, pInfo->pDelWins);
|
||||
}
|
||||
}
|
||||
pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs;
|
||||
|
||||
|
|
@ -1522,7 +1556,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
|
||||
qInfo("copy state %p to %p", pTaskInfo->streamInfo.pState, pInfo->pState);
|
||||
|
||||
pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1);
|
||||
pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1, pInfo->primaryTsIndex);
|
||||
code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str,
|
||||
pInfo->pState, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
|
@ -1565,6 +1599,8 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
pInfo->pMidPulloverRes = createSpecialDataBlock(STREAM_MID_RETRIEVE);
|
||||
pInfo->clearState = false;
|
||||
pInfo->pMidPullDatas = taosArrayInit(4, sizeof(SWinKey));
|
||||
pInfo->pDeletedMap = tSimpleHashInit(4096, hashFn);
|
||||
pInfo->destHasPrimaryKey = pIntervalPhyNode->window.destHasPrimayKey;
|
||||
|
||||
pOperator->operatorType = pPhyNode->type;
|
||||
if (!IS_FINAL_INTERVAL_OP(pOperator) || numOfChild == 0) {
|
||||
|
|
@ -1646,6 +1682,7 @@ void destroyStreamSessionAggOperatorInfo(void* param) {
|
|||
|
||||
taosArrayDestroy(pInfo->historyWins);
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
tSimpleHashCleanup(pInfo->pPkDeleted);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
|
@ -1705,7 +1742,7 @@ static TSKEY sesionTs(void* pKey) {
|
|||
int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SExprSupp* pExpSup, int32_t numOfOutput, int64_t gap,
|
||||
SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore,
|
||||
SReadHandle* pHandle, STimeWindowAggSupp* pTwAggSup, const char* taskIdStr,
|
||||
SStorageAPI* pApi) {
|
||||
SStorageAPI* pApi, int32_t tsIndex) {
|
||||
pSup->resultRowSize = keySize + getResultRowSize(pExpSup->pCtx, numOfOutput);
|
||||
pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR);
|
||||
pSup->gap = gap;
|
||||
|
|
@ -1721,7 +1758,7 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SExprSupp* pExpSup, in
|
|||
initDummyFunction(pSup->pDummyCtx, pExpSup->pCtx, numOfOutput);
|
||||
pSup->pState = taosMemoryCalloc(1, sizeof(SStreamState));
|
||||
*(pSup->pState) = *pState;
|
||||
pSup->stateStore.streamStateSetNumber(pSup->pState, -1);
|
||||
pSup->stateStore.streamStateSetNumber(pSup->pState, -1, tsIndex);
|
||||
int32_t funResSize = getMaxFunResSize(pExpSup, numOfOutput);
|
||||
pSup->pState->pFileState = pSup->stateStore.streamFileStateInit(
|
||||
tsStreamBufferSize, sizeof(SSessionKey), pSup->resultRowSize, funResSize, sesionTs, pSup->pState,
|
||||
|
|
@ -1730,25 +1767,8 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SExprSupp* pExpSup, in
|
|||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pSup->pResultRows = tSimpleHashInit(32, hashFn);
|
||||
|
||||
int32_t pageSize = 4096;
|
||||
while (pageSize < pSup->resultRowSize * 4) {
|
||||
pageSize <<= 1u;
|
||||
}
|
||||
// at least four pages need to be in buffer
|
||||
int32_t bufSize = 4096 * 256;
|
||||
if (bufSize <= pageSize) {
|
||||
bufSize = pageSize * 4;
|
||||
}
|
||||
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir);
|
||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
pExpSup->pCtx[i].saveHandle.pBuf = pSup->pResultBuf;
|
||||
pExpSup->pCtx[i].saveHandle.pState = pSup->pState;
|
||||
}
|
||||
|
||||
pSup->pSessionAPI = pApi;
|
||||
|
|
@ -1865,10 +1885,10 @@ void removeSessionDeleteResults(SSHashObj* pHashMap, SArray* pWins) {
|
|||
}
|
||||
int32_t size = taosArrayGetSize(pWins);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
SSessionKey* pWin = taosArrayGet(pWins, i);
|
||||
SResultWindowInfo* pWin = taosArrayGet(pWins, i);
|
||||
if (!pWin) continue;
|
||||
SSessionKey key = {0};
|
||||
getSessionHashKey(pWin, &key);
|
||||
getSessionHashKey(&pWin->sessionWin, &key);
|
||||
tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey));
|
||||
}
|
||||
}
|
||||
|
|
@ -2109,17 +2129,20 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData
|
|||
pOperator, winDelta);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s do stream session aggregate impl error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted, addGap);
|
||||
saveSessionOutputBuf(pAggSup, &winInfo);
|
||||
|
||||
if (pInfo->destHasPrimaryKey && winInfo.isOutput && IS_NORMAL_SESSION_OP(pOperator)) {
|
||||
saveDeleteRes(pInfo->pPkDeleted, winInfo.sessionWin);
|
||||
}
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) {
|
||||
code = saveResult(winInfo, pStUpdated);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s do stream session aggregate impl, set result error, code %s", GET_TASKID(pTaskInfo),
|
||||
tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
|
|
@ -2645,6 +2668,20 @@ void resetUnCloseSessionWinInfo(SSHashObj* winMap) {
|
|||
}
|
||||
}
|
||||
|
||||
void copyDeleteSessionKey(SSHashObj* source, SSHashObj* dest) {
|
||||
if (tSimpleHashGetSize(source) == 0) {
|
||||
return;
|
||||
}
|
||||
void* pIte = NULL;
|
||||
int32_t iter = 0;
|
||||
size_t keyLen = 0;
|
||||
while ((pIte = tSimpleHashIterate(source, pIte, &iter)) != NULL) {
|
||||
SSessionKey* pKey = tSimpleHashGetKey(pIte, &keyLen);
|
||||
saveDeleteRes(dest, *pKey);
|
||||
}
|
||||
tSimpleHashClear(source);
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
|
||||
|
|
@ -2705,6 +2742,9 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
rebuildSessionWindow(pOperator, pWins, pInfo->pStUpdated);
|
||||
}
|
||||
copyDeleteWindowInfo(pWins, pInfo->pStDeleted);
|
||||
if (pInfo->destHasPrimaryKey && IS_NORMAL_SESSION_OP(pOperator)) {
|
||||
copyDeleteWindowInfo(pWins, pInfo->pPkDeleted);
|
||||
}
|
||||
taosArrayDestroy(pWins);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
|
|
@ -2760,6 +2800,9 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
if (pInfo->isHistoryOp) {
|
||||
getMaxTsWins(pInfo->pUpdated, pInfo->historyWins);
|
||||
}
|
||||
if (pInfo->destHasPrimaryKey && IS_NORMAL_SESSION_OP(pOperator)) {
|
||||
copyDeleteSessionKey(pInfo->pPkDeleted, pInfo->pStDeleted);
|
||||
}
|
||||
initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated);
|
||||
pInfo->pUpdated = NULL;
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
|
@ -2948,16 +2991,16 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh
|
|||
.deleteMark = getDeleteMark(&pSessionNode->window, 0),
|
||||
};
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, pSessionNode->gap,
|
||||
pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI, pInfo->primaryTsIndex);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
|
||||
if (pSessionNode->window.pTsEnd) {
|
||||
pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId;
|
||||
}
|
||||
|
|
@ -2985,6 +3028,8 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh
|
|||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
pInfo->clearState = false;
|
||||
pInfo->recvGetAll = false;
|
||||
pInfo->destHasPrimaryKey = pSessionNode->window.destHasPrimayKey;
|
||||
pInfo->pPkDeleted = tSimpleHashInit(64, hashFn);
|
||||
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION;
|
||||
setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true,
|
||||
|
|
@ -3025,11 +3070,14 @@ static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) {
|
|||
}
|
||||
|
||||
void deleteSessionWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate,
|
||||
SSHashObj* pMapDelete) {
|
||||
SSHashObj* pMapDelete, SSHashObj* pPkDelete, bool needAdd) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
|
||||
doDeleteTimeWindows(pAggSup, pBlock, pWins);
|
||||
removeSessionResults(pAggSup, pMapUpdate, pWins);
|
||||
copyDeleteWindowInfo(pWins, pMapDelete);
|
||||
if (needAdd) {
|
||||
copyDeleteWindowInfo(pWins, pPkDelete);
|
||||
}
|
||||
taosArrayDestroy(pWins);
|
||||
}
|
||||
|
||||
|
|
@ -3092,7 +3140,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
|||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
|
||||
pBlock->info.type == STREAM_CLEAR) {
|
||||
// gap must be 0
|
||||
deleteSessionWinState(pAggSup, pBlock, pInfo->pStUpdated, pInfo->pStDeleted);
|
||||
deleteSessionWinState(pAggSup, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, NULL, false);
|
||||
pInfo->clearState = true;
|
||||
break;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
|
|
@ -3175,7 +3223,7 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream
|
|||
}
|
||||
SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info;
|
||||
pChInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE;
|
||||
pAPI->stateStore.streamStateSetNumber(pChInfo->streamAggSup.pState, i);
|
||||
pAPI->stateStore.streamStateSetNumber(pChInfo->streamAggSup.pState, i, pInfo->primaryTsIndex);
|
||||
taosArrayPush(pInfo->pChildren, &pChildOp);
|
||||
}
|
||||
}
|
||||
|
|
@ -3218,6 +3266,7 @@ void destroyStreamStateOperatorInfo(void* param) {
|
|||
|
||||
taosArrayDestroy(pInfo->historyWins);
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
tSimpleHashCleanup(pInfo->pPkDeleted);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
|
@ -3448,7 +3497,7 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
pAggSup->pResultRows, pSeUpdated, pStDeleted);
|
||||
if (!allEqual) {
|
||||
uint64_t uid = 0;
|
||||
appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey,
|
||||
appendDataToSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey,
|
||||
&curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL);
|
||||
tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey));
|
||||
doDeleteSessionWindow(pAggSup, &curWin.winInfo.sessionWin);
|
||||
|
|
@ -3459,15 +3508,19 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
|
|||
pOperator, 0);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s do one window aggregate impl error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
saveSessionOutputBuf(pAggSup, &curWin.winInfo);
|
||||
|
||||
if (pInfo->destHasPrimaryKey && curWin.winInfo.isOutput && IS_NORMAL_STATE_OP(pOperator)) {
|
||||
saveDeleteRes(pInfo->pPkDeleted, curWin.winInfo.sessionWin);
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
code = saveResult(curWin.winInfo, pSeUpdated);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s do stream state aggregate impl, set result error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3654,7 +3707,8 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
|
||||
pBlock->info.type == STREAM_CLEAR) {
|
||||
deleteSessionWinState(&pInfo->streamAggSup, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted);
|
||||
bool add = pInfo->destHasPrimaryKey && IS_NORMAL_STATE_OP(pOperator);
|
||||
deleteSessionWinState(&pInfo->streamAggSup, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted, pInfo->pPkDeleted, add);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
pInfo->recvGetAll = true;
|
||||
|
|
@ -3690,6 +3744,9 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
if (pInfo->isHistoryOp) {
|
||||
getMaxTsWins(pInfo->pUpdated, pInfo->historyWins);
|
||||
}
|
||||
if (pInfo->destHasPrimaryKey && IS_NORMAL_STATE_OP(pOperator)) {
|
||||
copyDeleteSessionKey(pInfo->pPkDeleted, pInfo->pSeDeleted);
|
||||
}
|
||||
|
||||
initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated);
|
||||
pInfo->pUpdated = NULL;
|
||||
|
|
@ -3843,14 +3900,13 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
}
|
||||
int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes;
|
||||
int16_t type = pColNode->node.resType.type;
|
||||
pInfo->primaryTsIndex = tsSlotId;
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize,
|
||||
type, &pTaskInfo->storageAPI.stateStore, pHandle, &pInfo->twAggSup,
|
||||
GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI, pInfo->primaryTsIndex);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->primaryTsIndex = tsSlotId;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pSeDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->pDelIterator = NULL;
|
||||
|
|
@ -3871,6 +3927,8 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
|
||||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
pInfo->recvGetAll = false;
|
||||
pInfo->pPkDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->destHasPrimaryKey = pStateNode->window.destHasPrimayKey;
|
||||
|
||||
setOperatorInfo(pOperator, "StreamStateAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE, true, OP_NOT_OPENED,
|
||||
pInfo, pTaskInfo);
|
||||
|
|
@ -4011,7 +4069,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
#endif
|
||||
|
||||
doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap);
|
||||
doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap, pInfo->pDeletedMap);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey);
|
||||
}
|
||||
|
|
@ -4019,6 +4077,9 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins);
|
||||
closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL,
|
||||
pInfo->pUpdatedMap, pInfo->pDelWins, pOperator);
|
||||
if (pInfo->destHasPrimaryKey && IS_NORMAL_INTERVAL_OP(pOperator)) {
|
||||
copyIntervalDeleteKey(pInfo->pDeletedMap, pInfo->pDelWins);
|
||||
}
|
||||
|
||||
void* pIte = NULL;
|
||||
int32_t iter = 0;
|
||||
|
|
@ -4082,7 +4143,7 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
|
||||
pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState));
|
||||
*(pInfo->pState) = *(pTaskInfo->streamInfo.pState);
|
||||
pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1);
|
||||
pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1, pInfo->primaryTsIndex);
|
||||
|
||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||
code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, pInfo->pState,
|
||||
|
|
@ -4135,6 +4196,10 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
pInfo->recvGetAll = false;
|
||||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pDeletedMap = tSimpleHashInit(4096, hashFn);
|
||||
pInfo->destHasPrimaryKey = pIntervalPhyNode->window.destHasPrimayKey;
|
||||
|
||||
// for stream
|
||||
void* buff = NULL;
|
||||
int32_t len = 0;
|
||||
|
|
@ -4213,8 +4278,9 @@ static void doStreamMidIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pS
|
|||
int32_t code = setIntervalOutputBuf(pInfo->pState, &nextWin, &pResPos, groupId, pSup->pCtx, numOfOutput,
|
||||
pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->stateStore);
|
||||
pResult = (SResultRow*)pResPos->pRowBuff;
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
if (pResult == NULL) {
|
||||
qError("%s set interval output buff error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
break;
|
||||
}
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
|
|
|
|||
|
|
@ -2330,6 +2330,7 @@ static int32_t initTableblockDistQueryCond(uint64_t uid, SQueryTableDataCond* pC
|
|||
pCond->colList->colId = 1;
|
||||
pCond->colList->type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
pCond->colList->bytes = sizeof(TSKEY);
|
||||
pCond->colList->pk = 0;
|
||||
|
||||
pCond->pSlotList[0] = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,13 +39,15 @@ typedef struct STimeSliceOperatorInfo {
|
|||
SColumn tsCol; // primary timestamp column
|
||||
SExprSupp scalarSup; // scalar calculation
|
||||
struct SFillColInfo* pFillColInfo; // fill column info
|
||||
int64_t prevTs;
|
||||
SRowKey prevKey;
|
||||
bool prevTsSet;
|
||||
uint64_t groupId;
|
||||
SGroupKeys* pPrevGroupKey;
|
||||
SSDataBlock* pNextGroupRes;
|
||||
SSDataBlock* pRemainRes; // save block unfinished processing
|
||||
int32_t remainIndex; // the remaining index in the block to be processed
|
||||
bool hasPk;
|
||||
SColumn pkCol;
|
||||
} STimeSliceOperatorInfo;
|
||||
|
||||
static void destroyTimeSliceOperatorInfo(void* param);
|
||||
|
|
@ -176,28 +178,41 @@ static bool isIsfilledPseudoColumn(SExprInfo* pExprInfo) {
|
|||
return (IS_BOOLEAN_TYPE(pExprInfo->base.resSchema.type) && strcasecmp(name, "_isfilled") == 0);
|
||||
}
|
||||
|
||||
static void tRowGetKeyFromColData(int64_t ts, SColumnInfoData* pPkCol, int32_t rowIndex, SRowKey* pKey) {
|
||||
pKey->ts = ts;
|
||||
pKey->numOfPKs = 1;
|
||||
|
||||
int8_t t = pPkCol->info.type;
|
||||
|
||||
pKey->pks[0].type = t;
|
||||
if (IS_NUMERIC_TYPE(t)) {
|
||||
GET_TYPED_DATA(pKey->pks[0].val, int64_t, t, colDataGetNumData(pPkCol, rowIndex));
|
||||
} else {
|
||||
char* p = colDataGetVarData(pPkCol, rowIndex);
|
||||
pKey->pks[0].pData = (uint8_t*)varDataVal(p);
|
||||
pKey->pks[0].nData = varDataLen(p);
|
||||
}
|
||||
}
|
||||
|
||||
static bool checkDuplicateTimestamps(STimeSliceOperatorInfo* pSliceInfo, SColumnInfoData* pTsCol,
|
||||
int32_t curIndex, int32_t rows) {
|
||||
|
||||
|
||||
SColumnInfoData* pPkCol, int32_t curIndex, int32_t rows) {
|
||||
int64_t currentTs = *(int64_t*)colDataGetData(pTsCol, curIndex);
|
||||
if (currentTs > pSliceInfo->win.ekey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pSliceInfo->prevTsSet == true) && (currentTs == pSliceInfo->prevTs)) {
|
||||
SRowKey cur = {.ts = currentTs, .numOfPKs = (pPkCol != NULL)? 1:0};
|
||||
if (pPkCol != NULL) {
|
||||
cur.pks[0].type = pPkCol->info.type;
|
||||
}
|
||||
|
||||
// let's discard the duplicated ts
|
||||
if ((pSliceInfo->prevTsSet == true) && (currentTs == pSliceInfo->prevKey.ts)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pSliceInfo->prevTsSet = true;
|
||||
pSliceInfo->prevTs = currentTs;
|
||||
|
||||
if (currentTs == pSliceInfo->win.ekey && curIndex < rows - 1) {
|
||||
int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, curIndex + 1);
|
||||
if (currentTs == nextTs) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tRowKeyAssign(&pSliceInfo->prevKey, &cur);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -693,14 +708,19 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
SInterval* pInterval = &pSliceInfo->interval;
|
||||
|
||||
SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId);
|
||||
SColumnInfoData* pPkCol = NULL;
|
||||
|
||||
if (pSliceInfo->hasPk) {
|
||||
pPkCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->pkCol.slotId);
|
||||
}
|
||||
|
||||
int32_t i = (pSliceInfo->pRemainRes == NULL) ? 0 : pSliceInfo->remainIndex;
|
||||
for (; i < pBlock->info.rows; ++i) {
|
||||
int64_t ts = *(int64_t*)colDataGetData(pTsCol, i);
|
||||
|
||||
// check for duplicate timestamps
|
||||
if (checkDuplicateTimestamps(pSliceInfo, pTsCol, i, pBlock->info.rows)) {
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_FUNC_DUP_TIMESTAMP);
|
||||
if (checkDuplicateTimestamps(pSliceInfo, pTsCol, pPkCol, i, pBlock->info.rows)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkNullRow(&pOperator->exprSupp, pBlock, i, ignoreNull)) {
|
||||
|
|
@ -719,6 +739,7 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
if (checkWindowBoundReached(pSliceInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) {
|
||||
saveBlockStatus(pSliceInfo, pBlock, i);
|
||||
return;
|
||||
|
|
@ -793,7 +814,6 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
// if reached here, meaning block processing finished naturally,
|
||||
// or interpolation reach window upper bound
|
||||
pSliceInfo->pRemainRes = NULL;
|
||||
|
||||
}
|
||||
|
||||
static void genInterpAfterDataBlock(STimeSliceOperatorInfo* pSliceInfo, SOperatorInfo* pOperator, int32_t index) {
|
||||
|
|
@ -873,11 +893,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
STimeSliceOperatorInfo* pSliceInfo = pOperator->info;
|
||||
SSDataBlock* pResBlock = pSliceInfo->pRes;
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
blockDataCleanup(pResBlock);
|
||||
|
||||
while (1) {
|
||||
|
|
@ -953,6 +971,25 @@ _finished:
|
|||
return pResBlock->info.rows == 0 ? NULL : pResBlock;
|
||||
}
|
||||
|
||||
static int32_t extractPkColumnFromFuncs(SNodeList* pFuncs, bool* pHasPk, SColumn* pPkColumn) {
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pFuncs) {
|
||||
if ((nodeType(pNode) == QUERY_NODE_TARGET) &&
|
||||
(nodeType(((STargetNode*)pNode)->pExpr) == QUERY_NODE_FUNCTION)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)((STargetNode*)pNode)->pExpr;
|
||||
if (fmIsInterpFunc(pFunc->funcId) && pFunc->hasPk) {
|
||||
SNode* pNode2 = (pFunc->pParameterList->pTail->pNode);
|
||||
if ((nodeType(pNode2) == QUERY_NODE_COLUMN) && ((SColumnNode*)pNode2)->isPk) {
|
||||
*pHasPk = true;
|
||||
*pPkColumn = extractColumnFromColumnNode((SColumnNode*)pNode2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo) {
|
||||
STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
|
|
@ -985,6 +1022,7 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode
|
|||
}
|
||||
|
||||
pInfo->tsCol = extractColumnFromColumnNode((SColumnNode*)pInterpPhyNode->pTimeSeries);
|
||||
extractPkColumnFromFuncs(pInterpPhyNode->pFuncs, &pInfo->hasPk, &pInfo->pkCol);
|
||||
pInfo->fillType = convertFillType(pInterpPhyNode->fillMode);
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
|
||||
|
|
@ -995,13 +1033,23 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode
|
|||
pInfo->interval.interval = pInterpPhyNode->interval;
|
||||
pInfo->current = pInfo->win.skey;
|
||||
pInfo->prevTsSet = false;
|
||||
pInfo->prevTs = 0;
|
||||
pInfo->prevKey.ts = INT64_MIN;
|
||||
pInfo->groupId = 0;
|
||||
pInfo->pPrevGroupKey = NULL;
|
||||
pInfo->pNextGroupRes = NULL;
|
||||
pInfo->pRemainRes = NULL;
|
||||
pInfo->remainIndex = 0;
|
||||
|
||||
if (pInfo->hasPk) {
|
||||
pInfo->prevKey.numOfPKs = 1;
|
||||
pInfo->prevKey.ts = INT64_MIN;
|
||||
pInfo->prevKey.pks[0].type = pInfo->pkCol.type;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pInfo->pkCol.type)) {
|
||||
pInfo->prevKey.pks[0].pData = taosMemoryCalloc(1, pInfo->pkCol.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
|
||||
STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info;
|
||||
pScanInfo->base.cond.twindows = pInfo->win;
|
||||
|
|
|
|||
|
|
@ -359,8 +359,8 @@ static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo* pInfo, i
|
|||
}
|
||||
|
||||
static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SExprSupp* pSup, int32_t endRowIndex,
|
||||
SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
|
||||
STimeWindow* win) {
|
||||
int32_t nextRowIndex, SArray* pDataBlock, const TSKEY* tsCols,
|
||||
TSKEY blockEkey, STimeWindow* win) {
|
||||
int32_t order = pInfo->binfo.inputTsOrder;
|
||||
|
||||
TSKEY actualEndKey = tsCols[endRowIndex];
|
||||
|
|
@ -378,7 +378,6 @@ static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SEx
|
|||
return true;
|
||||
}
|
||||
|
||||
int32_t nextRowIndex = endRowIndex + 1;
|
||||
ASSERT(nextRowIndex >= 0);
|
||||
|
||||
TSKEY nextKey = tsCols[nextRowIndex];
|
||||
|
|
@ -496,7 +495,6 @@ static void doWindowBorderInterpolation(SIntervalAggOperatorInfo* pInfo, SSDataB
|
|||
|
||||
ASSERT(pBlock != NULL);
|
||||
if (pBlock->pDataBlock == NULL) {
|
||||
// tscError("pBlock->pDataBlock == NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -514,17 +512,25 @@ static void doWindowBorderInterpolation(SIntervalAggOperatorInfo* pInfo, SSDataB
|
|||
}
|
||||
|
||||
// point interpolation does not require the end key time window interpolation.
|
||||
// if (pointInterpQuery) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// interpolation query does not generate the time window end interpolation
|
||||
done = isResultRowInterpolated(pResult, RESULT_ROW_END_INTERP);
|
||||
if (!done) {
|
||||
int32_t endRowIndex = startPos + forwardRows - 1;
|
||||
int32_t nextRowIndex = endRowIndex + 1;
|
||||
|
||||
// duplicated ts row does not involve in the interpolation of end value for current time window
|
||||
int32_t x = endRowIndex;
|
||||
while(x > 0) {
|
||||
if (tsCols[x] == tsCols[x-1]) {
|
||||
x -= 1;
|
||||
} else {
|
||||
endRowIndex = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TSKEY endKey = (pInfo->binfo.inputTsOrder == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey;
|
||||
bool interp = setTimeWindowInterpolationEndTs(pInfo, pSup, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
|
||||
bool interp = setTimeWindowInterpolationEndTs(pInfo, pSup, endRowIndex, nextRowIndex, pBlock->pDataBlock, tsCols, endKey, win);
|
||||
if (interp) {
|
||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||
}
|
||||
|
|
@ -658,11 +664,12 @@ static bool isCalculatedWin(SIntervalAggOperatorInfo* pInfo, const STimeWindow*
|
|||
*/
|
||||
static bool filterWindowWithLimit(SIntervalAggOperatorInfo* pOperatorInfo, STimeWindow* win, uint64_t groupId) {
|
||||
if (!pOperatorInfo->limited // if no limit info, no filter will be applied
|
||||
|| pOperatorInfo->binfo.inputTsOrder !=
|
||||
pOperatorInfo->binfo.outputTsOrder // if input/output ts order mismatch, no filter
|
||||
|| pOperatorInfo->binfo.inputTsOrder != pOperatorInfo->binfo.outputTsOrder
|
||||
// if input/output ts order mismatch, no filter
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pOperatorInfo->limit == 0) return true;
|
||||
|
||||
if (pOperatorInfo->pBQ == NULL) {
|
||||
|
|
@ -1332,23 +1339,26 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator
|
|||
// The gap is less than the threshold, so it belongs to current session window that has been opened already.
|
||||
doKeepTuple(pRowSup, tsList[j], gid);
|
||||
} else { // start a new session window
|
||||
SResultRow* pResult = NULL;
|
||||
// start a new session window
|
||||
if (pRowSup->numOfRows > 0) { // handled data that belongs to the previous session window
|
||||
SResultRow* pResult = NULL;
|
||||
|
||||
// keep the time window for the closed time window.
|
||||
STimeWindow window = pRowSup->win;
|
||||
// keep the time window for the closed time window.
|
||||
STimeWindow window = pRowSup->win;
|
||||
|
||||
pRowSup->win.ekey = pRowSup->win.skey;
|
||||
int32_t ret = setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &window, masterScan, &pResult, gid, pSup->pCtx,
|
||||
numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_APP_ERROR);
|
||||
int32_t ret =
|
||||
setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &window, masterScan, &pResult, gid, pSup->pCtx,
|
||||
numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_APP_ERROR);
|
||||
}
|
||||
|
||||
// pInfo->numOfRows data belong to the current session window
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, 0);
|
||||
applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
pRowSup->numOfRows, pBlock->info.rows, numOfOutput);
|
||||
}
|
||||
|
||||
// pInfo->numOfRows data belong to the current session window
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, 0);
|
||||
applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
pRowSup->numOfRows, pBlock->info.rows, numOfOutput);
|
||||
|
||||
// here we start a new session window
|
||||
doKeepNewWindowStartInfo(pRowSup, tsList, j, gid);
|
||||
doKeepTuple(pRowSup, tsList[j], gid);
|
||||
|
|
|
|||
|
|
@ -108,8 +108,8 @@ struct SSortHandle {
|
|||
int32_t extRowsPageSize;
|
||||
int32_t extRowsMemSize;
|
||||
int32_t srcTsSlotId;
|
||||
SBlockOrderInfo extRowsOrderInfo;
|
||||
|
||||
SArray* aExtRowsOrders;
|
||||
bool bSortPk;
|
||||
void (*mergeLimitReachedFn)(uint64_t tableUid, void* param);
|
||||
void* mergeLimitReachedParam;
|
||||
};
|
||||
|
|
@ -261,10 +261,17 @@ SSortHandle* tsortCreateSortHandle(SArray* pSortInfo, int32_t type, int32_t page
|
|||
pSortHandle->cmpParam.cmpGroupId = false;
|
||||
pSortHandle->cmpParam.sortType = type;
|
||||
if (type == SORT_BLOCK_TS_MERGE) {
|
||||
SBlockOrderInfo* pOrder = TARRAY_GET_ELEM(pSortInfo, 0);
|
||||
pSortHandle->cmpParam.tsSlotId = pOrder->slotId;
|
||||
pSortHandle->cmpParam.order = pOrder->order;
|
||||
pSortHandle->cmpParam.cmpFn = (pOrder->order == TSDB_ORDER_ASC) ? compareInt64Val : compareInt64ValDesc;
|
||||
SBlockOrderInfo* pTsOrder = TARRAY_GET_ELEM(pSortInfo, 0);
|
||||
pSortHandle->cmpParam.tsSlotId = pTsOrder->slotId;
|
||||
pSortHandle->cmpParam.tsOrder = pTsOrder->order;
|
||||
pSortHandle->cmpParam.cmpTsFn = pTsOrder->compFn;
|
||||
if (taosArrayGetSize(pSortHandle->pSortInfo) == 2) {
|
||||
pSortHandle->cmpParam.pPkOrder = taosArrayGet(pSortHandle->pSortInfo, 1);
|
||||
pSortHandle->bSortPk = true;
|
||||
} else {
|
||||
pSortHandle->cmpParam.pPkOrder = NULL;
|
||||
pSortHandle->bSortPk = false;
|
||||
}
|
||||
}
|
||||
tsortSetComparFp(pSortHandle, msortComparFn);
|
||||
|
||||
|
|
@ -347,6 +354,8 @@ void tsortDestroySortHandle(SSortHandle* pSortHandle) {
|
|||
destroySortMemFile(pSortHandle);
|
||||
}
|
||||
taosArrayDestroy(pSortHandle->pSortInfo);
|
||||
taosArrayDestroy(pSortHandle->aExtRowsOrders);
|
||||
pSortHandle->aExtRowsOrders = NULL;
|
||||
taosMemoryFreeClear(pSortHandle);
|
||||
}
|
||||
|
||||
|
|
@ -624,6 +633,57 @@ static SSDataBlock* getSortedBlockDataInner(SSortHandle* pHandle, SMsortComparPa
|
|||
return (pHandle->pDataBlock->info.rows > 0) ? pHandle->pDataBlock : NULL;
|
||||
}
|
||||
|
||||
// TODO: improve this function performance
|
||||
|
||||
int tsortComparBlockCell(SSDataBlock* pLeftBlock, SSDataBlock* pRightBlock,
|
||||
int32_t leftRowIndex, int32_t rightRowIndex, void* pCompareOrder) {
|
||||
SBlockOrderInfo* pOrder = pCompareOrder;
|
||||
SColumnInfoData* pLeftColInfoData = TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pOrder->slotId);
|
||||
SColumnInfoData* pRightColInfoData = TARRAY_GET_ELEM(pRightBlock->pDataBlock, pOrder->slotId);
|
||||
|
||||
bool isVarType = IS_VAR_DATA_TYPE(pLeftColInfoData->info.type);
|
||||
if (pLeftColInfoData->hasNull || pRightColInfoData->hasNull) {
|
||||
bool leftNull = false;
|
||||
if (pLeftColInfoData->hasNull) {
|
||||
if (pLeftBlock->pBlockAgg == NULL) {
|
||||
leftNull = colDataIsNull_t(pLeftColInfoData, leftRowIndex, isVarType);
|
||||
} else {
|
||||
leftNull =
|
||||
colDataIsNull(pLeftColInfoData, pLeftBlock->info.rows, leftRowIndex, pLeftBlock->pBlockAgg[pOrder->slotId]);
|
||||
}
|
||||
}
|
||||
|
||||
bool rightNull = false;
|
||||
if (pRightColInfoData->hasNull) {
|
||||
if (pRightBlock->pBlockAgg == NULL) {
|
||||
rightNull = colDataIsNull_t(pRightColInfoData, rightRowIndex, isVarType);
|
||||
} else {
|
||||
rightNull = colDataIsNull(pRightColInfoData, pRightBlock->info.rows, rightRowIndex,
|
||||
pRightBlock->pBlockAgg[pOrder->slotId]);
|
||||
}
|
||||
}
|
||||
|
||||
if (leftNull && rightNull) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rightNull) {
|
||||
return pOrder->nullFirst ? 1 : -1;
|
||||
}
|
||||
|
||||
if (leftNull) {
|
||||
return pOrder->nullFirst ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
void *left1, *right1;
|
||||
left1 = colDataGetData(pLeftColInfoData, leftRowIndex);
|
||||
right1 = colDataGetData(pRightColInfoData, rightRowIndex);
|
||||
__compar_fn_t fn = pOrder->compFn;
|
||||
int ret = fn(left1, right1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t msortComparFn(const void* pLeft, const void* pRight, void* param) {
|
||||
int32_t pLeftIdx = *(int32_t*)pLeft;
|
||||
int32_t pRightIdx = *(int32_t*)pRight;
|
||||
|
|
@ -654,12 +714,16 @@ int32_t msortComparFn(const void* pLeft, const void* pRight, void* param) {
|
|||
}
|
||||
|
||||
if (pParam->sortType == SORT_BLOCK_TS_MERGE) {
|
||||
SColumnInfoData* pLeftColInfoData = TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pParam->tsSlotId);
|
||||
SColumnInfoData* pRightColInfoData = TARRAY_GET_ELEM(pRightBlock->pDataBlock, pParam->tsSlotId);
|
||||
int64_t* left1 = (int64_t*)(pLeftColInfoData->pData) + pLeftSource->src.rowIndex;
|
||||
int64_t* right1 = (int64_t*)(pRightColInfoData->pData) + pRightSource->src.rowIndex;
|
||||
SColumnInfoData* pLeftTsCol = TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pParam->tsSlotId);
|
||||
SColumnInfoData* pRightTsCol = TARRAY_GET_ELEM(pRightBlock->pDataBlock, pParam->tsSlotId);
|
||||
int64_t* leftTs = (int64_t*)(pLeftTsCol->pData) + pLeftSource->src.rowIndex;
|
||||
int64_t* rightTs = (int64_t*)(pRightTsCol->pData) + pRightSource->src.rowIndex;
|
||||
|
||||
int ret = pParam->cmpFn(left1, right1);
|
||||
int ret = pParam->cmpTsFn(leftTs, rightTs);
|
||||
if (ret == 0 && pParam->pPkOrder) {
|
||||
ret = tsortComparBlockCell(pLeftBlock, pRightBlock,
|
||||
pLeftSource->src.rowIndex, pRightSource->src.rowIndex, (SBlockOrderInfo*)pParam->pPkOrder);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
bool isVarType;
|
||||
|
|
@ -1208,7 +1272,8 @@ static void appendToRowIndexDataBlock(SSortHandle* pHandle, SSDataBlock* pSource
|
|||
saveBlockRowToExtRowsMemFile(pHandle, pSource, *rowIndex, &pageId, &offset, &length);
|
||||
|
||||
SSDataBlock* pBlock = pHandle->pDataBlock;
|
||||
SColumnInfoData* pSrcTsCol = taosArrayGet(pSource->pDataBlock, pHandle->extRowsOrderInfo.slotId);
|
||||
SBlockOrderInfo* extRowsTsOrder = taosArrayGet(pHandle->aExtRowsOrders, 0);
|
||||
SColumnInfoData* pSrcTsCol = taosArrayGet(pSource->pDataBlock, extRowsTsOrder->slotId);
|
||||
SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
char* pData = colDataGetData(pSrcTsCol, *rowIndex);
|
||||
colDataSetVal(pTsCol, pBlock->info.rows, pData, false);
|
||||
|
|
@ -1222,11 +1287,26 @@ static void appendToRowIndexDataBlock(SSortHandle* pHandle, SSDataBlock* pSource
|
|||
SColumnInfoData* pLengthCol = taosArrayGet(pBlock->pDataBlock, 3);
|
||||
colDataSetInt32(pLengthCol, pBlock->info.rows, &length);
|
||||
|
||||
if (pHandle->bSortPk) {
|
||||
SBlockOrderInfo* extRowsPkOrder = taosArrayGet(pHandle->aExtRowsOrders, 1);
|
||||
SColumnInfoData* pSrcPkCol = taosArrayGet(pSource->pDataBlock, extRowsPkOrder->slotId);
|
||||
SColumnInfoData* pPkCol = taosArrayGet(pBlock->pDataBlock, 4);
|
||||
if (colDataIsNull_s(pSrcPkCol, *rowIndex)) {
|
||||
colDataSetNULL(pPkCol, pBlock->info.rows);
|
||||
} else {
|
||||
char* pPkData = colDataGetData(pSrcPkCol, *rowIndex);
|
||||
colDataSetVal(pPkCol, pBlock->info.rows, pPkData, false);
|
||||
}
|
||||
}
|
||||
|
||||
pBlock->info.rows += 1;
|
||||
*rowIndex += 1;
|
||||
}
|
||||
|
||||
static void initRowIdSort(SSortHandle* pHandle) {
|
||||
SBlockOrderInfo* pkOrder = (pHandle->bSortPk) ? taosArrayGet(pHandle->aExtRowsOrders, 1) : NULL;
|
||||
SColumnInfoData* extPkCol = (pHandle->bSortPk) ? taosArrayGet(pHandle->pDataBlock->pDataBlock, pkOrder->slotId) : NULL;
|
||||
SColumnInfoData pkCol = {0};
|
||||
|
||||
SSDataBlock* pSortInput = createDataBlock();
|
||||
SColumnInfoData tsCol = createColumnInfoData(TSDB_DATA_TYPE_TIMESTAMP, 8, 1);
|
||||
|
|
@ -1237,7 +1317,10 @@ static void initRowIdSort(SSortHandle* pHandle) {
|
|||
blockDataAppendColInfo(pSortInput, &offsetCol);
|
||||
SColumnInfoData lengthCol = createColumnInfoData(TSDB_DATA_TYPE_INT, 4, 4);
|
||||
blockDataAppendColInfo(pSortInput, &lengthCol);
|
||||
|
||||
if (pHandle->bSortPk) {
|
||||
pkCol = createColumnInfoData(extPkCol->info.type, extPkCol->info.bytes, 5);
|
||||
blockDataAppendColInfo(pSortInput, &pkCol);
|
||||
}
|
||||
blockDataDestroy(pHandle->pDataBlock);
|
||||
pHandle->pDataBlock = pSortInput;
|
||||
|
||||
|
|
@ -1246,15 +1329,24 @@ static void initRowIdSort(SSortHandle* pHandle) {
|
|||
pHandle->pageSize = 256 * 1024; // 256k
|
||||
pHandle->numOfPages = 256;
|
||||
|
||||
SBlockOrderInfo* pOrder = taosArrayGet(pHandle->pSortInfo, 0);
|
||||
SBlockOrderInfo bi = {0};
|
||||
bi.order = pOrder->order;
|
||||
bi.slotId = 0;
|
||||
bi.nullFirst = NULL_ORDER_FIRST;
|
||||
|
||||
SArray* aOrder = taosArrayInit(1, sizeof(SBlockOrderInfo));
|
||||
taosArrayPush(aOrder, &bi);
|
||||
|
||||
SBlockOrderInfo* pTsOrder = taosArrayGet(pHandle->pSortInfo, 0);
|
||||
SBlockOrderInfo biTs = {0};
|
||||
biTs.order = pTsOrder->order;
|
||||
biTs.slotId = 0;
|
||||
biTs.nullFirst = (biTs.order == TSDB_ORDER_ASC);
|
||||
biTs.compFn = getKeyComparFunc(TSDB_DATA_TYPE_TIMESTAMP, biTs.order);
|
||||
taosArrayPush(aOrder, &biTs);
|
||||
|
||||
if (pHandle->bSortPk) {
|
||||
SBlockOrderInfo biPk = {0};
|
||||
biPk.order = pkOrder->order;
|
||||
biPk.slotId = 4;
|
||||
biPk.nullFirst = (biPk.order == TSDB_ORDER_ASC);
|
||||
biPk.compFn = getKeyComparFunc(pkCol.info.type, biPk.order);
|
||||
taosArrayPush(aOrder, &biPk);
|
||||
}
|
||||
taosArrayDestroy(pHandle->pSortInfo);
|
||||
pHandle->pSortInfo = aOrder;
|
||||
return;
|
||||
|
|
@ -1263,8 +1355,7 @@ static void initRowIdSort(SSortHandle* pHandle) {
|
|||
int32_t tsortSetSortByRowId(SSortHandle* pHandle, int32_t extRowsMemSize) {
|
||||
pHandle->extRowBytes = blockDataGetRowSize(pHandle->pDataBlock) + taosArrayGetSize(pHandle->pDataBlock->pDataBlock) + sizeof(int32_t);
|
||||
pHandle->extRowsMemSize = extRowsMemSize;
|
||||
SBlockOrderInfo* pOrder = taosArrayGet(pHandle->pSortInfo, 0);
|
||||
pHandle->extRowsOrderInfo = *pOrder;
|
||||
pHandle->aExtRowsOrders = taosArrayDup(pHandle->pSortInfo, NULL);
|
||||
initRowIdSort(pHandle);
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
|
|
@ -1279,7 +1370,10 @@ int32_t tsortSetSortByRowId(SSortHandle* pHandle, int32_t extRowsMemSize) {
|
|||
typedef struct SBlkMergeSupport {
|
||||
int64_t** aTs;
|
||||
int32_t* aRowIdx;
|
||||
int32_t order;
|
||||
int32_t tsOrder;
|
||||
|
||||
SBlockOrderInfo* pPkOrder;
|
||||
SSDataBlock** aBlks;
|
||||
} SBlkMergeSupport;
|
||||
|
||||
static int32_t blockCompareTsFn(const void* pLeft, const void* pRight, void* param) {
|
||||
|
|
@ -1297,12 +1391,36 @@ static int32_t blockCompareTsFn(const void* pLeft, const void* pRight, void* par
|
|||
int64_t rightTs = pSup->aTs[right][pSup->aRowIdx[right]];
|
||||
|
||||
int32_t ret = leftTs>rightTs ? 1 : ((leftTs < rightTs) ? -1 : 0);
|
||||
if (pSup->order == TSDB_ORDER_DESC) {
|
||||
if (pSup->tsOrder == TSDB_ORDER_DESC) {
|
||||
ret = -1 * ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t blockCompareTsPkFn(const void* pLeft, const void* pRight, void* param) {
|
||||
int32_t left = *(int32_t*)pLeft;
|
||||
int32_t right = *(int32_t*)pRight;
|
||||
|
||||
SBlkMergeSupport* pSup = (SBlkMergeSupport*)param;
|
||||
if (pSup->aRowIdx[left] == -1) {
|
||||
return 1;
|
||||
} else if (pSup->aRowIdx[right] == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t leftTs = pSup->aTs[left][pSup->aRowIdx[left]];
|
||||
int64_t rightTs = pSup->aTs[right][pSup->aRowIdx[right]];
|
||||
|
||||
int32_t ret = leftTs>rightTs ? 1 : ((leftTs < rightTs) ? -1 : 0);
|
||||
if (pSup->tsOrder == TSDB_ORDER_DESC) {
|
||||
ret = -1 * ret;
|
||||
}
|
||||
if (ret == 0 && pSup->pPkOrder) {
|
||||
ret = tsortComparBlockCell(pSup->aBlks[left], pSup->aBlks[right], pSup->aRowIdx[left], pSup->aRowIdx[right], pSup->pPkOrder);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t appendDataBlockToPageBuf(SSortHandle* pHandle, SSDataBlock* blk, SArray* aPgId) {
|
||||
int32_t pageId = -1;
|
||||
void* pPage = getNewBufPage(pHandle->pBuf, &pageId);
|
||||
|
|
@ -1358,18 +1476,27 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
blockDataCleanup(pHandle->pDataBlock);
|
||||
int32_t numBlks = taosArrayGetSize(aBlk);
|
||||
|
||||
SBlockOrderInfo* pOrigBlockOrder = (!pHandle->bSortByRowId) ? taosArrayGet(pHandle->pSortInfo, 0) : &pHandle->extRowsOrderInfo;
|
||||
SBlockOrderInfo* pHandleBlockOrder = taosArrayGet(pHandle->pSortInfo, 0);
|
||||
SBlkMergeSupport sup;
|
||||
SBlockOrderInfo* pOrigBlockTsOrder = (!pHandle->bSortByRowId) ?
|
||||
taosArrayGet(pHandle->pSortInfo, 0) : taosArrayGet(pHandle->aExtRowsOrders, 0);
|
||||
SBlockOrderInfo* pHandleBlockTsOrder = taosArrayGet(pHandle->pSortInfo, 0);
|
||||
SBlkMergeSupport sup = {0};
|
||||
sup.aRowIdx = taosMemoryCalloc(numBlks, sizeof(int32_t));
|
||||
sup.aTs = taosMemoryCalloc(numBlks, sizeof(int64_t*));
|
||||
sup.order = pOrigBlockOrder->order;
|
||||
sup.tsOrder = pOrigBlockTsOrder->order;
|
||||
sup.aBlks = taosMemoryCalloc(numBlks, sizeof(SSDataBlock*));
|
||||
for (int i = 0; i < numBlks; ++i) {
|
||||
SSDataBlock* blk = taosArrayGetP(aBlk, i);
|
||||
SColumnInfoData* col = taosArrayGet(blk->pDataBlock, pOrigBlockOrder->slotId);
|
||||
SColumnInfoData* col = taosArrayGet(blk->pDataBlock, pOrigBlockTsOrder->slotId);
|
||||
sup.aTs[i] = (int64_t*)col->pData;
|
||||
sup.aRowIdx[i] = 0;
|
||||
sup.aBlks[i] = blk;
|
||||
}
|
||||
SBlockOrderInfo* pOrigBlockPkOrder = NULL;
|
||||
if (pHandle->bSortPk) {
|
||||
pOrigBlockPkOrder = (!pHandle->bSortByRowId) ?
|
||||
taosArrayGet(pHandle->pSortInfo, 1) : taosArrayGet(pHandle->aExtRowsOrders, 1);
|
||||
}
|
||||
sup.pPkOrder = pOrigBlockPkOrder;
|
||||
|
||||
int32_t totalRows = 0;
|
||||
for (int i = 0; i < numBlks; ++i) {
|
||||
|
|
@ -1377,11 +1504,13 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
totalRows += blk->info.rows;
|
||||
}
|
||||
|
||||
SMultiwayMergeTreeInfo* pTree = NULL;
|
||||
code = tMergeTreeCreate(&pTree, taosArrayGetSize(aBlk), &sup, blockCompareTsFn);
|
||||
SMultiwayMergeTreeInfo* pTree = NULL;
|
||||
__merge_compare_fn_t mergeCompareFn = (!pHandle->bSortPk) ? blockCompareTsFn : blockCompareTsPkFn;
|
||||
code = tMergeTreeCreate(&pTree, taosArrayGetSize(aBlk), &sup, mergeCompareFn);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
taosMemoryFree(sup.aRowIdx);
|
||||
taosMemoryFree(sup.aTs);
|
||||
taosMemoryFree(sup.aBlks);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -1390,8 +1519,8 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
int32_t nMergedRows = 0;
|
||||
bool mergeLimitReached = false;
|
||||
size_t blkPgSz = pgHeaderSz;
|
||||
int64_t lastPageBufTs = (pHandleBlockOrder->order == TSDB_ORDER_ASC) ? INT64_MAX : INT64_MIN;
|
||||
int64_t currTs = (pHandleBlockOrder->order == TSDB_ORDER_ASC) ? INT64_MAX : INT64_MIN;
|
||||
int64_t lastPageBufTs = (pHandleBlockTsOrder->order == TSDB_ORDER_ASC) ? INT64_MAX : INT64_MIN;
|
||||
int64_t currTs = (pHandleBlockTsOrder->order == TSDB_ORDER_ASC) ? INT64_MAX : INT64_MIN;
|
||||
while (nRows < totalRows) {
|
||||
int32_t minIdx = tMergeTreeGetChosenIndex(pTree);
|
||||
SSDataBlock* minBlk = taosArrayGetP(aBlk, minIdx);
|
||||
|
|
@ -1400,7 +1529,7 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
int32_t bufInc = getPageBufIncForRow(incBlock, minRow, pHandle->pDataBlock->info.rows);
|
||||
|
||||
if (blkPgSz <= pHandle->pageSize && blkPgSz + bufInc > pHandle->pageSize) {
|
||||
SColumnInfoData* tsCol = taosArrayGet(pHandle->pDataBlock->pDataBlock, pHandleBlockOrder->slotId);
|
||||
SColumnInfoData* tsCol = taosArrayGet(pHandle->pDataBlock->pDataBlock, pHandleBlockTsOrder->slotId);
|
||||
lastPageBufTs = ((int64_t*)tsCol->pData)[pHandle->pDataBlock->info.rows - 1];
|
||||
code = appendDataBlockToPageBuf(pHandle, pHandle->pDataBlock, aPgId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
|
@ -1408,6 +1537,7 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
taosArrayDestroy(aPgId);
|
||||
taosMemoryFree(sup.aRowIdx);
|
||||
taosMemoryFree(sup.aTs);
|
||||
taosMemoryFree(sup.aBlks);
|
||||
return code;
|
||||
}
|
||||
nMergedRows += pHandle->pDataBlock->info.rows;
|
||||
|
|
@ -1418,8 +1548,8 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
|
||||
if ((pHandle->mergeLimit != -1) && (nMergedRows >= pHandle->mergeLimit)) {
|
||||
mergeLimitReached = true;
|
||||
if ((lastPageBufTs < pHandle->currMergeLimitTs && pHandleBlockOrder->order == TSDB_ORDER_ASC) ||
|
||||
(lastPageBufTs > pHandle->currMergeLimitTs && pHandleBlockOrder->order == TSDB_ORDER_DESC)) {
|
||||
if ((lastPageBufTs < pHandle->currMergeLimitTs && pHandleBlockTsOrder->order == TSDB_ORDER_ASC) ||
|
||||
(lastPageBufTs > pHandle->currMergeLimitTs && pHandleBlockTsOrder->order == TSDB_ORDER_DESC)) {
|
||||
pHandle->currMergeLimitTs = lastPageBufTs;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1444,7 +1574,7 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
}
|
||||
if (pHandle->pDataBlock->info.rows > 0) {
|
||||
if (!mergeLimitReached) {
|
||||
SColumnInfoData* tsCol = taosArrayGet(pHandle->pDataBlock->pDataBlock, pHandleBlockOrder->slotId);
|
||||
SColumnInfoData* tsCol = taosArrayGet(pHandle->pDataBlock->pDataBlock, pHandleBlockTsOrder->slotId);
|
||||
lastPageBufTs = ((int64_t*)tsCol->pData)[pHandle->pDataBlock->info.rows - 1];
|
||||
code = appendDataBlockToPageBuf(pHandle, pHandle->pDataBlock, aPgId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
|
@ -1452,13 +1582,14 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
taosMemoryFree(pTree);
|
||||
taosMemoryFree(sup.aRowIdx);
|
||||
taosMemoryFree(sup.aTs);
|
||||
taosMemoryFree(sup.aBlks);
|
||||
return code;
|
||||
}
|
||||
nMergedRows += pHandle->pDataBlock->info.rows;
|
||||
if ((pHandle->mergeLimit != -1) && (nMergedRows >= pHandle->mergeLimit)) {
|
||||
mergeLimitReached = true;
|
||||
if ((lastPageBufTs < pHandle->currMergeLimitTs && pHandleBlockOrder->order == TSDB_ORDER_ASC) ||
|
||||
(lastPageBufTs > pHandle->currMergeLimitTs && pHandleBlockOrder->order == TSDB_ORDER_DESC)) {
|
||||
if ((lastPageBufTs < pHandle->currMergeLimitTs && pHandleBlockTsOrder->order == TSDB_ORDER_ASC) ||
|
||||
(lastPageBufTs > pHandle->currMergeLimitTs && pHandleBlockTsOrder->order == TSDB_ORDER_DESC)) {
|
||||
pHandle->currMergeLimitTs = lastPageBufTs;
|
||||
}
|
||||
}
|
||||
|
|
@ -1471,6 +1602,7 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SArray*
|
|||
|
||||
taosMemoryFree(sup.aRowIdx);
|
||||
taosMemoryFree(sup.aTs);
|
||||
taosMemoryFree(sup.aBlks);
|
||||
|
||||
tMergeTreeDestroy(&pTree);
|
||||
|
||||
|
|
@ -1517,8 +1649,8 @@ static SSDataBlock* getRowsBlockWithinMergeLimit(const SSortHandle* pHandle, SSH
|
|||
}
|
||||
|
||||
static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
|
||||
size_t nSrc = taosArrayGetSize(pHandle->pOrderedSource);
|
||||
SArray* aExtSrc = taosArrayInit(nSrc, POINTER_BYTES);
|
||||
size_t nSrc = taosArrayGetSize(pHandle->pOrderedSource);
|
||||
SArray* aExtSrc = taosArrayInit(nSrc, POINTER_BYTES);
|
||||
|
||||
size_t maxBufSize = (pHandle->bSortByRowId) ? pHandle->extRowsMemSize : (pHandle->numOfPages * pHandle->pageSize);
|
||||
|
||||
|
|
@ -1531,8 +1663,9 @@ static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
|
|||
SSortSource* pSrc = taosArrayGetP(pHandle->pOrderedSource, 0);
|
||||
int32_t szSort = 0;
|
||||
|
||||
SBlockOrderInfo* pOrigOrder = (!pHandle->bSortByRowId) ? taosArrayGet(pHandle->pSortInfo, 0) : &pHandle->extRowsOrderInfo;
|
||||
if (pOrigOrder->order == TSDB_ORDER_ASC) {
|
||||
SBlockOrderInfo* pOrigTsOrder = (!pHandle->bSortByRowId) ?
|
||||
taosArrayGet(pHandle->pSortInfo, 0) : taosArrayGet(pHandle->aExtRowsOrders, 0);
|
||||
if (pOrigTsOrder->order == TSDB_ORDER_ASC) {
|
||||
pHandle->currMergeLimitTs = INT64_MAX;
|
||||
} else {
|
||||
pHandle->currMergeLimitTs = INT64_MIN;
|
||||
|
|
@ -1554,13 +1687,13 @@ static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
|
|||
}
|
||||
|
||||
if (pBlk != NULL) {
|
||||
SColumnInfoData* tsCol = taosArrayGet(pBlk->pDataBlock, pOrigOrder->slotId);
|
||||
int64_t firstRowTs = *(int64_t*)tsCol->pData;
|
||||
if ((pOrigOrder->order == TSDB_ORDER_ASC && firstRowTs > pHandle->currMergeLimitTs) ||
|
||||
(pOrigOrder->order == TSDB_ORDER_DESC && firstRowTs < pHandle->currMergeLimitTs)) {
|
||||
SColumnInfoData* tsCol = taosArrayGet(pBlk->pDataBlock, pOrigTsOrder->slotId);
|
||||
int64_t firstRowTs = *(int64_t*)tsCol->pData;
|
||||
if ((pOrigTsOrder->order == TSDB_ORDER_ASC && firstRowTs > pHandle->currMergeLimitTs) ||
|
||||
(pOrigTsOrder->order == TSDB_ORDER_DESC && firstRowTs < pHandle->currMergeLimitTs)) {
|
||||
if (bExtractedBlock) {
|
||||
blockDataDestroy(pBlk);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
typedef int32_t (*FTranslateFunc)(SFunctionNode* pFunc, char* pErrBuf, int32_t len);
|
||||
typedef EFuncDataRequired (*FFuncDataRequired)(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
|
||||
typedef int32_t (*FCreateMergeFuncParameters)(SNodeList* pRawParameters, SNode* pPartialRes, SNodeList** pParameters);
|
||||
typedef EFuncDataRequired (*FFuncDynDataRequired)(void* pRes, STimeWindow* pTimeWindow);
|
||||
typedef EFuncDataRequired (*FFuncDynDataRequired)(void* pRes, SDataBlockInfo* pBlocInfo);
|
||||
typedef EFuncReturnRows (*FEstimateReturnRows)(SFunctionNode* pFunc);
|
||||
|
||||
typedef struct SBuiltinFuncDefinition {
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ int32_t irateFunction(SqlFunctionCtx* pCtx);
|
|||
int32_t irateFunctionMerge(SqlFunctionCtx* pCtx);
|
||||
int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t iratePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t getIrateInfoSize();
|
||||
int32_t getIrateInfoSize(int32_t pkBytes);
|
||||
|
||||
int32_t cachedLastRowFunction(SqlFunctionCtx* pCtx);
|
||||
|
||||
|
|
@ -157,9 +157,9 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
|||
int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
int32_t getFirstLastInfoSize(int32_t resBytes);
|
||||
EFuncDataRequired firstDynDataReq(void* pRes, STimeWindow* pTimeWindow);
|
||||
EFuncDataRequired lastDynDataReq(void* pRes, STimeWindow* pTimeWindow);
|
||||
int32_t getFirstLastInfoSize(int32_t resBytes, int32_t pkBytes);
|
||||
EFuncDataRequired firstDynDataReq(void* pRes, SDataBlockInfo* pBlockInfo);
|
||||
EFuncDataRequired lastDynDataReq(void* pRes, SDataBlockInfo* pBlockInfo);
|
||||
|
||||
int32_t lastRowFunction(SqlFunctionCtx* pCtx);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ extern "C" {
|
|||
#define FUNC_MGT_GEOMETRY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(24)
|
||||
#define FUNC_MGT_FORBID_SYSTABLE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(25)
|
||||
#define FUNC_MGT_SKIP_SCAN_CHECK_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(26)
|
||||
#define FUNC_MGT_PRIMARY_KEY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(27)
|
||||
|
||||
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||
|
||||
|
|
|
|||
|
|
@ -1632,13 +1632,14 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (isPartial) {
|
||||
if (3 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
if (3 != LIST_LENGTH(pFunc->pParameterList) && 4 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
pFunc->node.resType = (SDataType){.bytes = getIrateInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
int32_t pkBytes = (pFunc->hasPk) ? pFunc->pkBytes : 0;
|
||||
pFunc->node.resType = (SDataType){.bytes = getIrateInfoSize(pkBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
} else {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
|
@ -1782,9 +1783,9 @@ static int32_t translateFirstLastImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t pkBytes = (pFunc->hasPk) ? pFunc->pkBytes : 0;
|
||||
pFunc->node.resType =
|
||||
(SDataType){.bytes = getFirstLastInfoSize(paraBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
(SDataType){.bytes = getFirstLastInfoSize(paraBytes, pkBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
} else {
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
|
@ -2761,7 +2762,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "interp",
|
||||
.type = FUNCTION_TYPE_INTERP,
|
||||
.classification = FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateInterp,
|
||||
.getEnvFunc = getSelectivityFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
|
@ -2773,7 +2774,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "derivative",
|
||||
.type = FUNCTION_TYPE_DERIVATIVE,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateDerivative,
|
||||
.getEnvFunc = getDerivativeFuncEnv,
|
||||
.initFunc = derivativeFuncSetup,
|
||||
|
|
@ -2786,7 +2787,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "irate",
|
||||
.type = FUNCTION_TYPE_IRATE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateIrate,
|
||||
.getEnvFunc = getIrateFuncEnv,
|
||||
.initFunc = irateFuncSetup,
|
||||
|
|
@ -2800,7 +2801,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_irate_partial",
|
||||
.type = FUNCTION_TYPE_IRATE_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateIratePartial,
|
||||
.getEnvFunc = getIrateFuncEnv,
|
||||
.initFunc = irateFuncSetup,
|
||||
|
|
@ -2823,7 +2824,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "last_row",
|
||||
.type = FUNCTION_TYPE_LAST_ROW,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLast,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
|
|
@ -2860,7 +2861,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_last_row_partial",
|
||||
.type = FUNCTION_TYPE_LAST_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLastPartial,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
|
|
@ -2872,7 +2873,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_last_row_merge",
|
||||
.type = FUNCTION_TYPE_LAST_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLastMerge,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
|
@ -2883,7 +2884,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "first",
|
||||
.type = FUNCTION_TYPE_FIRST,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLast,
|
||||
.dynDataRequiredFunc = firstDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
|
|
@ -2899,7 +2900,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_first_partial",
|
||||
.type = FUNCTION_TYPE_FIRST_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLastPartial,
|
||||
.dynDataRequiredFunc = firstDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
|
|
@ -2912,7 +2913,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_first_merge",
|
||||
.type = FUNCTION_TYPE_FIRST_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLastMerge,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
|
@ -2924,7 +2925,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "last",
|
||||
.type = FUNCTION_TYPE_LAST,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLast,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
|
|
@ -2940,7 +2941,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_last_partial",
|
||||
.type = FUNCTION_TYPE_LAST_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLastPartial,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
|
|
@ -2953,7 +2954,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "_last_merge",
|
||||
.type = FUNCTION_TYPE_LAST_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateFirstLastMerge,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
|
@ -2965,7 +2966,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "twa",
|
||||
.type = FUNCTION_TYPE_TWA,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC | FUNC_MGT_FORBID_STREAM_FUNC |
|
||||
FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateInNumOutDou,
|
||||
.dataRequiredFunc = statisDataRequired,
|
||||
.getEnvFunc = getTwaFuncEnv,
|
||||
|
|
@ -3068,7 +3069,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "diff",
|
||||
.type = FUNCTION_TYPE_DIFF,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC,
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateDiff,
|
||||
.getEnvFunc = getDiffFuncEnv,
|
||||
.initFunc = diffFunctionSetup,
|
||||
|
|
@ -3152,7 +3153,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "unique",
|
||||
.type = FUNCTION_TYPE_UNIQUE,
|
||||
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||
.translateFunc = translateUnique,
|
||||
.getEnvFunc = getUniqueFuncEnv,
|
||||
.initFunc = uniqueFunctionSetup,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -115,7 +115,7 @@ EFuncDataRequired fmFuncDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWin
|
|||
return funcMgtBuiltins[pFunc->funcId].dataRequiredFunc(pFunc, pTimeWindow);
|
||||
}
|
||||
|
||||
EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, STimeWindow* pTimeWindow) {
|
||||
EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, SDataBlockInfo* pBlockInfo) {
|
||||
if (fmIsUserDefinedFunc(funcId) || funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, STimeWindow*
|
|||
if (funcMgtBuiltins[funcId].dynDataRequiredFunc == NULL) {
|
||||
return FUNC_DATA_REQUIRED_DATA_LOAD;
|
||||
} else {
|
||||
return funcMgtBuiltins[funcId].dynDataRequiredFunc(pRes, pTimeWindow);
|
||||
return funcMgtBuiltins[funcId].dynDataRequiredFunc(pRes, pBlockInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,8 +352,12 @@ bool fmIsSkipScanCheckFunc(int32_t funcId) {
|
|||
return isSpecificClassifyFunc(funcId, FUNC_MGT_SKIP_SCAN_CHECK_FUNC);
|
||||
}
|
||||
|
||||
void getLastCacheDataType(SDataType* pType) {
|
||||
pType->bytes = getFirstLastInfoSize(pType->bytes) + VARSTR_HEADER_SIZE;
|
||||
bool fmIsPrimaryKeyFunc(int32_t funcId) {
|
||||
return isSpecificClassifyFunc(funcId, FUNC_MGT_PRIMARY_KEY_FUNC);
|
||||
}
|
||||
void getLastCacheDataType(SDataType* pType, int32_t pkBytes) {
|
||||
//TODO: do it later.
|
||||
pType->bytes = getFirstLastInfoSize(pType->bytes, pkBytes) + VARSTR_HEADER_SIZE;
|
||||
pType->type = TSDB_DATA_TYPE_BINARY;
|
||||
}
|
||||
|
||||
|
|
@ -411,6 +415,8 @@ static int32_t createPartialFunction(const SFunctionNode* pSrcFunc, SFunctionNod
|
|||
int32_t len = snprintf(name, sizeof(name) - 1, "%s.%p", (*pPartialFunc)->functionName, pSrcFunc);
|
||||
taosCreateMD5Hash(name, len);
|
||||
strncpy((*pPartialFunc)->node.aliasName, name, TSDB_COL_NAME_LEN - 1);
|
||||
(*pPartialFunc)->hasPk = pSrcFunc->hasPk;
|
||||
(*pPartialFunc)->pkBytes = pSrcFunc->pkBytes;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -449,7 +455,8 @@ static int32_t createMidFunction(const SFunctionNode* pSrcFunc, const SFunctionN
|
|||
} else {
|
||||
nodesDestroyList(pParameterList);
|
||||
}
|
||||
|
||||
(*pMidFunc)->hasPk = pPartialFunc->hasPk;
|
||||
(*pMidFunc)->pkBytes = pPartialFunc->pkBytes;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +485,8 @@ static int32_t createMergeFunction(const SFunctionNode* pSrcFunc, const SFunctio
|
|||
} else {
|
||||
nodesDestroyList(pParameterList);
|
||||
}
|
||||
|
||||
(*pMergeFunc)->hasPk = pPartialFunc->hasPk;
|
||||
(*pMergeFunc)->pkBytes = pPartialFunc->pkBytes;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cmdnodes.h"
|
||||
#include "nodesUtil.h"
|
||||
#include "plannodes.h"
|
||||
#include "querynodes.h"
|
||||
|
|
@ -119,6 +120,18 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|||
COPY_CHAR_ARRAY_FIELD(colName);
|
||||
COPY_SCALAR_FIELD(dataBlockId);
|
||||
COPY_SCALAR_FIELD(slotId);
|
||||
COPY_SCALAR_FIELD(tableHasPk);
|
||||
COPY_SCALAR_FIELD(isPk);
|
||||
COPY_SCALAR_FIELD(numOfPKs);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t columnDefNodeCopy(const SColumnDefNode* pSrc, SColumnDefNode* pDst) {
|
||||
COPY_CHAR_ARRAY_FIELD(colName);
|
||||
COPY_OBJECT_FIELD(dataType, sizeof(SDataType));
|
||||
COPY_CHAR_ARRAY_FIELD(comments);
|
||||
COPY_SCALAR_FIELD(sma);
|
||||
COPY_SCALAR_FIELD(is_pk);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -208,6 +221,8 @@ static int32_t functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst)
|
|||
COPY_SCALAR_FIELD(funcType);
|
||||
CLONE_NODE_LIST_FIELD(pParameterList);
|
||||
COPY_SCALAR_FIELD(udfBufSize);
|
||||
COPY_SCALAR_FIELD(hasPk);
|
||||
COPY_SCALAR_FIELD(pkBytes);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -713,6 +728,7 @@ static int32_t physiWindowCopy(const SWindowPhysiNode* pSrc, SWindowPhysiNode* p
|
|||
COPY_SCALAR_FIELD(triggerType);
|
||||
COPY_SCALAR_FIELD(watermark);
|
||||
COPY_SCALAR_FIELD(igExpired);
|
||||
COPY_SCALAR_FIELD(destHasPrimayKey);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -830,6 +846,9 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
|||
case QUERY_NODE_COLUMN:
|
||||
code = columnNodeCopy((const SColumnNode*)pNode, (SColumnNode*)pDst);
|
||||
break;
|
||||
case QUERY_NODE_COLUMN_DEF:
|
||||
code = columnDefNodeCopy((const SColumnDefNode*)pNode, (SColumnDefNode*)pDst);
|
||||
break;
|
||||
case QUERY_NODE_VALUE:
|
||||
code = valueNodeCopy((const SValueNode*)pNode, (SValueNode*)pDst);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -516,6 +516,7 @@ static const char* jkSchemaType = "Type";
|
|||
static const char* jkSchemaColId = "ColId";
|
||||
static const char* jkSchemaBytes = "bytes";
|
||||
static const char* jkSchemaName = "Name";
|
||||
static const char* jkSchemaFlags = "Flags";
|
||||
|
||||
static int32_t schemaToJson(const void* pObj, SJson* pJson) {
|
||||
const SSchema* pNode = (const SSchema*)pObj;
|
||||
|
|
@ -530,6 +531,9 @@ static int32_t schemaToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkSchemaName, pNode->name);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkSchemaFlags, pNode->flags);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -548,6 +552,9 @@ static int32_t jsonToSchema(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetStringValue(pJson, jkSchemaName, pNode->name);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
tjsonGetNumberValue(pJson, jkSchemaFlags, pNode->flags, code);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -2515,6 +2522,7 @@ static const char* jkWindowPhysiPlanDeleteMark = "DeleteMark";
|
|||
static const char* jkWindowPhysiPlanIgnoreExpired = "IgnoreExpired";
|
||||
static const char* jkWindowPhysiPlanInputTsOrder = "InputTsOrder";
|
||||
static const char* jkWindowPhysiPlanMergeDataBlock = "MergeDataBlock";
|
||||
static const char* jkWindowPhysiPlanDestHasPrimaryKey = "DestHasPrimaryKey";
|
||||
|
||||
static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SWindowPhysiNode* pNode = (const SWindowPhysiNode*)pObj;
|
||||
|
|
@ -2547,6 +2555,9 @@ static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkWindowPhysiPlanMergeDataBlock, pNode->mergeDataBlock);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkWindowPhysiPlanDestHasPrimaryKey, pNode->destHasPrimayKey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -2582,6 +2593,9 @@ static int32_t jsonToPhysiWindowNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkWindowPhysiPlanMergeDataBlock, &pNode->mergeDataBlock);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetTinyIntValue(pJson, jkWindowPhysiPlanDestHasPrimaryKey, &pNode->destHasPrimayKey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -3618,6 +3632,9 @@ static const char* jkColumnTableAlias = "TableAlias";
|
|||
static const char* jkColumnColName = "ColName";
|
||||
static const char* jkColumnDataBlockId = "DataBlockId";
|
||||
static const char* jkColumnSlotId = "SlotId";
|
||||
static const char* jkColumnTableHasPk = "TableHasPk";
|
||||
static const char* jkColumnIsPk = "IsPk";
|
||||
static const char* jkColumnNumOfPKs = "NumOfPKs";
|
||||
|
||||
static int32_t columnNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SColumnNode* pNode = (const SColumnNode*)pObj;
|
||||
|
|
@ -3656,7 +3673,15 @@ static int32_t columnNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnSlotId, pNode->slotId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkColumnTableHasPk, pNode->tableHasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkColumnIsPk, pNode->isPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnNumOfPKs, pNode->numOfPKs);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -3697,7 +3722,15 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetSmallIntValue(pJson, jkColumnSlotId, &pNode->slotId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkColumnTableHasPk, &pNode->tableHasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkColumnIsPk, &pNode->isPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetSmallIntValue(pJson, jkColumnNumOfPKs, &pNode->numOfPKs);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -4036,6 +4069,8 @@ static const char* jkFunctionId = "Id";
|
|||
static const char* jkFunctionType = "Type";
|
||||
static const char* jkFunctionParameter = "Parameters";
|
||||
static const char* jkFunctionUdfBufSize = "UdfBufSize";
|
||||
static const char* jkFunctionHasPk = "HasPk";
|
||||
static const char* jkFunctionPkBytes = "PkBytes";
|
||||
|
||||
static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFunctionNode* pNode = (const SFunctionNode*)pObj;
|
||||
|
|
@ -4056,7 +4091,12 @@ static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFunctionUdfBufSize, pNode->udfBufSize);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkFunctionHasPk, pNode->hasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFunctionPkBytes, pNode->pkBytes);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -4079,7 +4119,12 @@ static int32_t jsonToFunctionNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetIntValue(pJson, jkFunctionUdfBufSize, &pNode->udfBufSize);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkFunctionHasPk, &pNode->hasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetIntValue(pJson, jkFunctionPkBytes, &pNode->pkBytes);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -4706,6 +4751,7 @@ static const char* jkColumnDefColName = "ColName";
|
|||
static const char* jkColumnDefDataType = "DataType";
|
||||
static const char* jkColumnDefComments = "Comments";
|
||||
static const char* jkColumnDefSma = "Sma";
|
||||
static const char* jkColumnDefIsPK = "IsPK";
|
||||
|
||||
static int32_t columnDefNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SColumnDefNode* pNode = (const SColumnDefNode*)pObj;
|
||||
|
|
@ -4720,6 +4766,9 @@ static int32_t columnDefNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkColumnDefSma, pNode->sma);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkColumnDefIsPK, pNode->is_pk);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -4737,7 +4786,9 @@ static int32_t jsonToColumnDefNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkColumnDefSma, &pNode->sma);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkColumnDefIsPK, &pNode->is_pk);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -725,7 +725,15 @@ static int32_t columnNodeInlineToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeValueI16(pEncoder, pNode->slotId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeValueBool(pEncoder, pNode->tableHasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeValueBool(pEncoder, pNode->isPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeValueI16(pEncoder, pNode->numOfPKs);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -767,7 +775,15 @@ static int32_t msgToColumnNodeInline(STlvDecoder* pDecoder, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvDecodeValueI16(pDecoder, &pNode->slotId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvDecodeValueBool(pDecoder, &pNode->tableHasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvDecodeValueBool(pDecoder, &pNode->isPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvDecodeValueI16(pDecoder, &pNode->numOfPKs);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -1091,7 +1107,9 @@ enum {
|
|||
FUNCTION_CODE_FUNCTION_ID,
|
||||
FUNCTION_CODE_FUNCTION_TYPE,
|
||||
FUNCTION_CODE_PARAMETERS,
|
||||
FUNCTION_CODE_UDF_BUF_SIZE
|
||||
FUNCTION_CODE_UDF_BUF_SIZE,
|
||||
FUNCTION_NODE_HAS_PK,
|
||||
FUNCTION_NODE_PK_BYTES
|
||||
};
|
||||
|
||||
static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
|
@ -1113,7 +1131,12 @@ static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, FUNCTION_CODE_UDF_BUF_SIZE, pNode->udfBufSize);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, FUNCTION_NODE_HAS_PK, pNode->hasPk);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, FUNCTION_NODE_PK_BYTES, pNode->pkBytes);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
@ -1142,6 +1165,12 @@ static int32_t msgToFunctionNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case FUNCTION_CODE_UDF_BUF_SIZE:
|
||||
code = tlvDecodeI32(pTlv, &pNode->udfBufSize);
|
||||
break;
|
||||
case FUNCTION_NODE_HAS_PK:
|
||||
code = tlvDecodeBool(pTlv, &pNode->hasPk);
|
||||
break;
|
||||
case FUNCTION_NODE_PK_BYTES:
|
||||
code = tlvDecodeI32(pTlv, &pNode->pkBytes);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2884,7 +2913,8 @@ enum {
|
|||
PHY_WINDOW_CODE_IG_EXPIRED,
|
||||
PHY_WINDOW_CODE_INPUT_TS_ORDER,
|
||||
PHY_WINDOW_CODE_OUTPUT_TS_ORDER,
|
||||
PHY_WINDOW_CODE_MERGE_DATA_BLOCK
|
||||
PHY_WINDOW_CODE_MERGE_DATA_BLOCK,
|
||||
PHY_WINDOW_CODE_DEST_HAS_PRIMARY_KEY,
|
||||
};
|
||||
|
||||
static int32_t physiWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
|
@ -2918,6 +2948,9 @@ static int32_t physiWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, PHY_WINDOW_CODE_MERGE_DATA_BLOCK, pNode->mergeDataBlock);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI8(pEncoder, PHY_WINDOW_CODE_DEST_HAS_PRIMARY_KEY, pNode->destHasPrimayKey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -2959,6 +2992,9 @@ static int32_t msgToPhysiWindowNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case PHY_WINDOW_CODE_MERGE_DATA_BLOCK:
|
||||
code = tlvDecodeBool(pTlv, &pNode->mergeDataBlock);
|
||||
break;
|
||||
case PHY_WINDOW_CODE_DEST_HAS_PRIMARY_KEY:
|
||||
code = tlvDecodeI8(pTlv, &pNode->destHasPrimayKey);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue