Merge branch '3.0' into refact/fillhistory
This commit is contained in:
commit
077e1a1ed4
|
@ -15,7 +15,7 @@
|
|||
[](https://coveralls.io/github/taosdata/TDengine?branch=develop)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/4201)
|
||||
|
||||
简体中文 | [English](README.md) | 很多职位正在热招中,请看[这里](https://www.taosdata.com/cn/careers/)
|
||||
简体中文 | [English](README.md) | [TDengine 云服务](https://cloud.taosdata.com/?utm_medium=cn&utm_source=github) | 很多职位正在热招中,请看[这里](https://www.taosdata.com/cn/careers/)
|
||||
|
||||
# TDengine 简介
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ ENDIF ()
|
|||
option(
|
||||
BUILD_GEOS
|
||||
"If build geos on Windows"
|
||||
OFF
|
||||
ON
|
||||
)
|
||||
|
||||
option(
|
||||
|
|
|
@ -56,17 +56,7 @@ IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin
|
|||
|
||||
SET(TD_DARWIN TRUE)
|
||||
SET(OSTYPE "macOS")
|
||||
execute_process(COMMAND geos-config --cflags OUTPUT_VARIABLE GEOS_CFLAGS)
|
||||
execute_process(COMMAND geos-config --ldflags OUTPUT_VARIABLE GEOS_LDFLAGS)
|
||||
string(SUBSTRING ${GEOS_CFLAGS} 2 -1 GEOS_CFLAGS)
|
||||
string(REGEX REPLACE "\n" "" GEOS_CFLAGS ${GEOS_CFLAGS})
|
||||
string(SUBSTRING ${GEOS_LDFLAGS} 2 -1 GEOS_LDFLAGS)
|
||||
string(REGEX REPLACE "\n" "" GEOS_LDFLAGS ${GEOS_LDFLAGS})
|
||||
MESSAGE("GEOS_CFLAGS "${GEOS_CFLAGS})
|
||||
MESSAGE("GEOS_LDFLAGS "${GEOS_LDFLAGS})
|
||||
ADD_DEFINITIONS("-DDARWIN -Wno-tautological-pointer-compare")
|
||||
INCLUDE_DIRECTORIES(${GEOS_CFLAGS})
|
||||
LINK_DIRECTORIES(${GEOS_LDFLAGS})
|
||||
|
||||
IF (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64")
|
||||
MESSAGE("Current system arch is arm64")
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taos-tools
|
||||
ExternalProject_Add(taos-tools
|
||||
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
|
||||
GIT_TAG 4378702
|
||||
GIT_TAG 3.0
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -65,6 +65,13 @@ taos = "*"
|
|||
taos = { version = "*", default-features = false, features = ["ws"] }
|
||||
```
|
||||
|
||||
当仅启用 `ws` 特性时,可同时指定 `r2d2` 使得在同步(blocking/sync)模式下使用 [r2d2] 作为连接池:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
taos = { version = "*", default-features = false, features = ["r2d2", "ws"] }
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="native" label="仅原生连接">
|
||||
|
@ -257,26 +264,24 @@ let conn: Taos = cfg.build();
|
|||
|
||||
### 连接池
|
||||
|
||||
在复杂应用中,建议启用连接池。[taos] 的连接池使用 [r2d2] 实现。
|
||||
在复杂应用中,建议启用连接池。[taos] 的连接池默认(异步模式)使用 [deadpool] 实现。
|
||||
|
||||
如下,可以生成一个默认参数的连接池。
|
||||
|
||||
```rust
|
||||
let pool = TaosBuilder::from_dsn(dsn)?.pool()?;
|
||||
let pool: Pool<TaosBuilder> = TaosBuilder::from_dsn("taos:///")
|
||||
.unwrap()
|
||||
.pool()
|
||||
.unwrap();
|
||||
```
|
||||
|
||||
同样可以使用连接池的构造器,对连接池参数进行设置:
|
||||
|
||||
```rust
|
||||
let dsn = "taos://localhost:6030";
|
||||
|
||||
let opts = PoolBuilder::new()
|
||||
.max_size(5000) // max connections
|
||||
.max_lifetime(Some(Duration::from_secs(60 * 60))) // lifetime of each connection
|
||||
.min_idle(Some(1000)) // minimal idle connections
|
||||
.connection_timeout(Duration::from_secs(2));
|
||||
|
||||
let pool = TaosBuilder::from_dsn(dsn)?.with_pool_builder(opts)?;
|
||||
let pool: Pool<TaosBuilder> = Pool::builder(Manager::from_dsn(self.dsn.clone()).unwrap().0)
|
||||
.max_size(88) // 最大连接数
|
||||
.build()
|
||||
.unwrap();
|
||||
```
|
||||
|
||||
在应用代码中,使用 `pool.get()?` 来获取一个连接对象 [Taos]。
|
||||
|
@ -516,6 +521,7 @@ consumer.unsubscribe().await;
|
|||
其他相关结构体 API 使用说明请移步 Rust 文档托管网页:<https://docs.rs/taos>。
|
||||
|
||||
[taos]: https://github.com/taosdata/rust-connector-taos
|
||||
[deadpool]: https://crates.io/crates/deadpool
|
||||
[r2d2]: https://crates.io/crates/r2d2
|
||||
[TaosBuilder]: https://docs.rs/taos/latest/taos/struct.TaosBuilder.html
|
||||
[TaosCfg]: https://docs.rs/taos/latest/taos/struct.TaosCfg.html
|
||||
|
|
|
@ -91,11 +91,30 @@ taos --dump-config
|
|||
### maxShellConns
|
||||
|
||||
| 属性 | 说明 |
|
||||
| -------- | ----------------------- |
|
||||
| --------| ----------------------- |
|
||||
| 适用范围 | 仅服务端适用 |
|
||||
| 含义 | 一个 dnode 容许的连接数 |
|
||||
| 含义 | 一个 dnode 容许的连接数 |
|
||||
| 取值范围 | 10-50000000 |
|
||||
| 缺省值 | 5000 |
|
||||
| 缺省值 | 5000 |
|
||||
|
||||
### numOfRpcSessions
|
||||
|
||||
| 属性 | 说明 |
|
||||
| --------| ---------------------- |
|
||||
| 适用范围 | 客户端和服务端都适用 |
|
||||
| 含义 | 一个客户端能创建的最大连接数|
|
||||
| 取值范围 | 100-100000 |
|
||||
| 缺省值 | 10000 |
|
||||
|
||||
### timeToGetAvailableConn
|
||||
|
||||
| 属性 | 说明 |
|
||||
| -------- | --------------------|
|
||||
| 适用范围 | 客户端和服务端都适用 |
|
||||
| 含义 |获得可用连接的最长等待时间|
|
||||
| 取值范围 | 10-50000000(单位为毫秒)|
|
||||
| 缺省值 | 500000 |
|
||||
|
||||
|
||||
### numOfRpcSessions
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMall
|
|||
extern void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull);
|
||||
|
||||
// for stmt bind
|
||||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind);
|
||||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen);
|
||||
void tColDataSortMerge(SArray *colDataArr);
|
||||
|
||||
// for raw block
|
||||
|
|
|
@ -29,7 +29,6 @@ extern "C" {
|
|||
#define SLOW_LOG_TYPE_OTHERS 0x4
|
||||
#define SLOW_LOG_TYPE_ALL 0xFFFFFFFF
|
||||
|
||||
|
||||
// cluster
|
||||
extern char tsFirst[];
|
||||
extern char tsSecond[];
|
||||
|
@ -131,7 +130,7 @@ extern int32_t tsSlowLogScope;
|
|||
// client
|
||||
extern int32_t tsMinSlidingTime;
|
||||
extern int32_t tsMinIntervalTime;
|
||||
extern int32_t tsMaxMemUsedByInsert;
|
||||
extern int32_t tsMaxInsertBatchRows;
|
||||
|
||||
// build info
|
||||
extern char version[];
|
||||
|
@ -181,6 +180,7 @@ extern bool tsDisableStream;
|
|||
extern int64_t tsStreamBufferSize;
|
||||
extern int64_t tsCheckpointInterval;
|
||||
extern bool tsFilterScalarMode;
|
||||
extern int32_t tsMaxStreamBackendCache;
|
||||
|
||||
// #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize)
|
||||
|
||||
|
|
|
@ -2009,10 +2009,8 @@ typedef struct {
|
|||
int8_t withMeta;
|
||||
char* sql;
|
||||
char subDbName[TSDB_DB_FNAME_LEN];
|
||||
union {
|
||||
char* ast;
|
||||
char subStbName[TSDB_TABLE_FNAME_LEN];
|
||||
};
|
||||
char* ast;
|
||||
char subStbName[TSDB_TABLE_FNAME_LEN];
|
||||
} SCMCreateTopicReq;
|
||||
|
||||
int32_t tSerializeSCMCreateTopicReq(void* buf, int32_t bufLen, const SCMCreateTopicReq* pReq);
|
||||
|
@ -2809,37 +2807,49 @@ typedef struct {
|
|||
int64_t suid;
|
||||
} SMqRebVgReq;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqRebVgReq(void** buf, const SMqRebVgReq* pReq) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI64(buf, pReq->leftForVer);
|
||||
tlen += taosEncodeFixedI32(buf, pReq->vgId);
|
||||
tlen += taosEncodeFixedI64(buf, pReq->oldConsumerId);
|
||||
tlen += taosEncodeFixedI64(buf, pReq->newConsumerId);
|
||||
tlen += taosEncodeString(buf, pReq->subKey);
|
||||
tlen += taosEncodeFixedI8(buf, pReq->subType);
|
||||
tlen += taosEncodeFixedI8(buf, pReq->withMeta);
|
||||
static FORCE_INLINE int tEncodeSMqRebVgReq(SEncoder *pCoder, const SMqRebVgReq* pReq) {
|
||||
if (tStartEncode(pCoder) < 0) return -1;
|
||||
if (tEncodeI64(pCoder, pReq->leftForVer) < 0) return -1;
|
||||
if (tEncodeI32(pCoder, pReq->vgId) < 0) return -1;
|
||||
if (tEncodeI64(pCoder, pReq->oldConsumerId) < 0) return -1;
|
||||
if (tEncodeI64(pCoder, pReq->newConsumerId) < 0) return -1;
|
||||
if (tEncodeCStr(pCoder, pReq->subKey) < 0) return -1;
|
||||
if (tEncodeI8(pCoder, pReq->subType) < 0) return -1;
|
||||
if (tEncodeI8(pCoder, pReq->withMeta) < 0) return -1;
|
||||
|
||||
if (pReq->subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
tlen += taosEncodeString(buf, pReq->qmsg);
|
||||
if (tEncodeCStr(pCoder, pReq->qmsg) < 0) return -1;
|
||||
} else if (pReq->subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
tlen += taosEncodeFixedI64(buf, pReq->suid);
|
||||
if (tEncodeI64(pCoder, pReq->suid) < 0) return -1;
|
||||
if (tEncodeCStr(pCoder, pReq->qmsg) < 0) return -1;
|
||||
}
|
||||
return tlen;
|
||||
tEndEncode(pCoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqRebVgReq(const void* buf, SMqRebVgReq* pReq) {
|
||||
buf = taosDecodeFixedI64(buf, &pReq->leftForVer);
|
||||
buf = taosDecodeFixedI32(buf, &pReq->vgId);
|
||||
buf = taosDecodeFixedI64(buf, &pReq->oldConsumerId);
|
||||
buf = taosDecodeFixedI64(buf, &pReq->newConsumerId);
|
||||
buf = taosDecodeStringTo(buf, pReq->subKey);
|
||||
buf = taosDecodeFixedI8(buf, &pReq->subType);
|
||||
buf = taosDecodeFixedI8(buf, &pReq->withMeta);
|
||||
static FORCE_INLINE int tDecodeSMqRebVgReq(SDecoder *pCoder, SMqRebVgReq* pReq) {
|
||||
if (tStartDecode(pCoder) < 0) return -1;
|
||||
|
||||
if (tDecodeI64(pCoder, &pReq->leftForVer) < 0) return -1;
|
||||
|
||||
if (tDecodeI32(pCoder, &pReq->vgId) < 0) return -1;
|
||||
if (tDecodeI64(pCoder, &pReq->oldConsumerId) < 0) return -1;
|
||||
if (tDecodeI64(pCoder, &pReq->newConsumerId) < 0) return -1;
|
||||
if (tDecodeCStrTo(pCoder, pReq->subKey) < 0) return -1;
|
||||
if (tDecodeI8(pCoder, &pReq->subType) < 0) return -1;
|
||||
if (tDecodeI8(pCoder, &pReq->withMeta) < 0) return -1;
|
||||
|
||||
if (pReq->subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
buf = taosDecodeString(buf, &pReq->qmsg);
|
||||
if (tDecodeCStr(pCoder, &pReq->qmsg) < 0) return -1;
|
||||
} else if (pReq->subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
buf = taosDecodeFixedI64(buf, &pReq->suid);
|
||||
if (tDecodeI64(pCoder, &pReq->suid) < 0) return -1;
|
||||
if (!tDecodeIsEnd(pCoder)){
|
||||
if (tDecodeCStr(pCoder, &pReq->qmsg) < 0) return -1;
|
||||
}
|
||||
}
|
||||
return (void*)buf;
|
||||
|
||||
tEndDecode(pCoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TIME_IS_VAR_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
|
||||
#define IS_CALENDAR_TIME_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
|
||||
|
||||
#define TIME_UNIT_NANOSECOND 'b'
|
||||
#define TIME_UNIT_MICROSECOND 'u'
|
||||
|
@ -74,7 +74,7 @@ static FORCE_INLINE int64_t taosGetTimestampToday(int32_t precision) {
|
|||
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
||||
|
||||
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision);
|
||||
int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval);
|
||||
int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision);
|
||||
|
||||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
|
|
|
@ -354,6 +354,7 @@
|
|||
#define TK_WAL 336
|
||||
|
||||
|
||||
|
||||
#define TK_NK_SPACE 600
|
||||
#define TK_NK_COMMENT 601
|
||||
#define TK_NK_ILLEGAL 602
|
||||
|
|
|
@ -82,6 +82,8 @@ qTaskInfo_t qCreateStreamExecTaskInfo(void* msg, SReadHandle* readers, int32_t v
|
|||
qTaskInfo_t qCreateQueueExecTaskInfo(void* msg, SReadHandle* pReaderHandle, int32_t vgId, int32_t* numOfCols,
|
||||
uint64_t id);
|
||||
|
||||
int32_t qGetTableList(int64_t suid, void* pVnode, void* node, SArray **tableList, void* pTaskInfo);
|
||||
|
||||
/**
|
||||
* set the task Id, usually used by message queue process
|
||||
* @param tinfo
|
||||
|
@ -90,6 +92,8 @@ qTaskInfo_t qCreateQueueExecTaskInfo(void* msg, SReadHandle* pReaderHandle, int3
|
|||
*/
|
||||
void qSetTaskId(qTaskInfo_t tinfo, uint64_t taskId, uint64_t queryId);
|
||||
|
||||
//void qSetTaskCode(qTaskInfo_t tinfo, int32_t code);
|
||||
|
||||
int32_t qSetStreamOpOpen(qTaskInfo_t tinfo);
|
||||
|
||||
// todo refactor
|
||||
|
@ -186,7 +190,17 @@ int32_t qSerializeTaskStatus(qTaskInfo_t tinfo, char** pOutput, int32_t* len);
|
|||
|
||||
int32_t qDeserializeTaskStatus(qTaskInfo_t tinfo, const char* pInput, int32_t len);
|
||||
|
||||
STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key);
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order);
|
||||
void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery);
|
||||
STimeWindow getAlignQueryTimeWindow(const SInterval* pInterval, int64_t key);
|
||||
/**
|
||||
* return the scan info, in the form of tuple of two items, including table uid and current timestamp
|
||||
* @param tinfo
|
||||
* @param uid
|
||||
* @param ts
|
||||
* @return
|
||||
*/
|
||||
int32_t qGetStreamScanStatus(qTaskInfo_t tinfo, uint64_t* uid, int64_t* ts);
|
||||
|
||||
SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo);
|
||||
|
||||
|
|
|
@ -364,6 +364,7 @@ typedef struct SCreateTopicStmt {
|
|||
bool ignoreExists;
|
||||
bool withMeta;
|
||||
SNode* pQuery;
|
||||
SNode* pWhere;
|
||||
} SCreateTopicStmt;
|
||||
|
||||
typedef struct SDropTopicStmt {
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct SJoinLogicNode {
|
|||
SNode* pOnConditions;
|
||||
bool isSingleTableJoin;
|
||||
EOrder inputTsOrder;
|
||||
SNode* pColEqualOnConditions;
|
||||
} SJoinLogicNode;
|
||||
|
||||
typedef struct SAggLogicNode {
|
||||
|
@ -406,6 +407,7 @@ typedef struct SSortMergeJoinPhysiNode {
|
|||
SNode* pOnConditions;
|
||||
SNodeList* pTargets;
|
||||
EOrder inputTsOrder;
|
||||
SNode* pColEqualOnConditions;
|
||||
} SSortMergeJoinPhysiNode;
|
||||
|
||||
typedef struct SAggPhysiNode {
|
||||
|
@ -448,7 +450,7 @@ typedef struct SMergePhysiNode {
|
|||
bool ignoreGroupId;
|
||||
} SMergePhysiNode;
|
||||
|
||||
typedef struct SWinodwPhysiNode {
|
||||
typedef struct SWindowPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pExprs; // these are expression list of parameter expression of function
|
||||
SNodeList* pFuncs;
|
||||
|
@ -461,10 +463,10 @@ typedef struct SWinodwPhysiNode {
|
|||
EOrder inputTsOrder;
|
||||
EOrder outputTsOrder;
|
||||
bool mergeDataBlock;
|
||||
} SWinodwPhysiNode;
|
||||
} SWindowPhysiNode;
|
||||
|
||||
typedef struct SIntervalPhysiNode {
|
||||
SWinodwPhysiNode window;
|
||||
SWindowPhysiNode window;
|
||||
int64_t interval;
|
||||
int64_t offset;
|
||||
int64_t sliding;
|
||||
|
@ -497,7 +499,7 @@ typedef struct SMultiTableIntervalPhysiNode {
|
|||
} SMultiTableIntervalPhysiNode;
|
||||
|
||||
typedef struct SSessionWinodwPhysiNode {
|
||||
SWinodwPhysiNode window;
|
||||
SWindowPhysiNode window;
|
||||
int64_t gap;
|
||||
} SSessionWinodwPhysiNode;
|
||||
|
||||
|
@ -506,14 +508,14 @@ typedef SSessionWinodwPhysiNode SStreamSemiSessionWinodwPhysiNode;
|
|||
typedef SSessionWinodwPhysiNode SStreamFinalSessionWinodwPhysiNode;
|
||||
|
||||
typedef struct SStateWinodwPhysiNode {
|
||||
SWinodwPhysiNode window;
|
||||
SWindowPhysiNode window;
|
||||
SNode* pStateKey;
|
||||
} SStateWinodwPhysiNode;
|
||||
|
||||
typedef SStateWinodwPhysiNode SStreamStateWinodwPhysiNode;
|
||||
|
||||
typedef struct SEventWinodwPhysiNode {
|
||||
SWinodwPhysiNode window;
|
||||
SWindowPhysiNode window;
|
||||
SNode* pStartCond;
|
||||
SNode* pEndCond;
|
||||
} SEventWinodwPhysiNode;
|
||||
|
|
|
@ -51,6 +51,12 @@ typedef enum {
|
|||
TARGET_TYPE_OTHER,
|
||||
} ETargetType;
|
||||
|
||||
typedef enum {
|
||||
TCOL_TYPE_COLUMN = 1,
|
||||
TCOL_TYPE_TAG,
|
||||
TCOL_TYPE_NONE,
|
||||
} ETableColumnType;
|
||||
|
||||
#define QUERY_POLICY_VNODE 1
|
||||
#define QUERY_POLICY_HYBRID 2
|
||||
#define QUERY_POLICY_QNODE 3
|
||||
|
@ -253,6 +259,7 @@ void destroyQueryExecRes(SExecResult* pRes);
|
|||
int32_t dataConverToStr(char* str, int type, void* buf, int32_t bufSize, int32_t* len);
|
||||
char* parseTagDatatoJson(void* p);
|
||||
int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst);
|
||||
void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType* pType);
|
||||
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
|
||||
int32_t cloneSVreateTbReq(SVCreateTbReq* pSrc, SVCreateTbReq** pDst);
|
||||
void freeVgInfo(SDBVgInfo* vgInfo);
|
||||
|
|
|
@ -206,7 +206,7 @@ static FORCE_INLINE void streamQueueProcessFail(SStreamQueue* queue) {
|
|||
void* streamQueueNextItem(SStreamQueue* queue);
|
||||
|
||||
SStreamDataSubmit* streamDataSubmitNew(SPackedData* pData, int32_t type);
|
||||
void streamDataSubmitDestroy(SStreamDataSubmit* pDataSubmit);
|
||||
void streamDataSubmitDestroy(SStreamDataSubmit* pDataSubmit);
|
||||
|
||||
SStreamDataSubmit* streamSubmitBlockClone(SStreamDataSubmit* pSubmit);
|
||||
|
||||
|
@ -289,7 +289,7 @@ struct SStreamTask {
|
|||
int16_t dispatchMsgType;
|
||||
SStreamStatus status;
|
||||
int32_t selfChildId;
|
||||
int32_t nodeId; // vgroup id
|
||||
int32_t nodeId; // vgroup id
|
||||
SEpSet epSet;
|
||||
SCheckpointInfo chkInfo;
|
||||
STaskExec exec;
|
||||
|
@ -352,12 +352,14 @@ typedef struct SStreamMeta {
|
|||
void* streamBackend;
|
||||
int32_t streamBackendId;
|
||||
int64_t streamBackendRid;
|
||||
SHashObj* pTaskBackendUnique;
|
||||
} SStreamMeta;
|
||||
|
||||
int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo);
|
||||
int32_t tDecodeStreamEpInfo(SDecoder* pDecoder, SStreamChildEpInfo* pInfo);
|
||||
|
||||
SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, int8_t fillHistory, int64_t triggerParam, SArray* pTaskList);
|
||||
SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, int8_t fillHistory, int64_t triggerParam,
|
||||
SArray* pTaskList);
|
||||
int32_t tEncodeStreamTask(SEncoder* pEncoder, const SStreamTask* pTask);
|
||||
int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask);
|
||||
void tFreeStreamTask(SStreamTask* pTask);
|
||||
|
|
|
@ -212,7 +212,8 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead);
|
|||
int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead);
|
||||
int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead);
|
||||
|
||||
SWalRef *walRefFirstVer(SWal *, SWalRef *);
|
||||
void walRefFirstVer(SWal *, SWalRef *);
|
||||
void walRefLastVer(SWal *, SWalRef *);
|
||||
SWalRef *walRefCommittedVer(SWal *);
|
||||
|
||||
SWalRef *walOpenRef(SWal *);
|
||||
|
|
|
@ -80,4 +80,5 @@ fi
|
|||
|
||||
# there can not libtaos.so*, otherwise ln -s error
|
||||
${csudo}rm -f ${install_main_dir}/driver/libtaos.* || :
|
||||
[ -f ${install_main_dir}/driver/librocksdb.* ] && ${csudo}rm -f ${install_main_dir}/driver/librocksdb.* || :
|
||||
[ -f ${install_main_dir}/driver/libtaosws.so ] && ${csudo}rm -f ${install_main_dir}/driver/libtaosws.so || :
|
||||
|
|
|
@ -40,6 +40,7 @@ else
|
|||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
[ -f ${inc_link_dir}/taosws.h ] && ${csudo}rm -f ${inc_link_dir}/taosws.h || :
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
[ -f ${lib_link_dir}/librocksdb.* ] && ${csudo}rm -f ${lib_link_dir}/librocksdb.* || :
|
||||
[ -f ${lib_link_dir}/libtaosws.so ] && ${csudo}rm -f ${lib_link_dir}/libtaosws.so || :
|
||||
|
||||
${csudo}rm -f ${log_link_dir} || :
|
||||
|
|
|
@ -31,6 +31,7 @@ cd ${pkg_dir}
|
|||
|
||||
libfile="libtaos.so.${tdengine_ver}"
|
||||
wslibfile="libtaosws.so"
|
||||
rocksdblib="librocksdb.so.8"
|
||||
|
||||
# create install dir
|
||||
install_home_path="/usr/local/taos"
|
||||
|
@ -94,6 +95,7 @@ fi
|
|||
|
||||
cp ${compile_dir}/build/bin/taos ${pkg_dir}${install_home_path}/bin
|
||||
cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_path}/driver
|
||||
[ -f ${compile_dir}/build/lib/${rocksdblib} ] && cp ${compile_dir}/build/lib/${rocksdblib} ${pkg_dir}${install_home_path}/driver ||:
|
||||
[ -f ${compile_dir}/build/lib/${wslibfile} ] && cp ${compile_dir}/build/lib/${wslibfile} ${pkg_dir}${install_home_path}/driver ||:
|
||||
cp ${compile_dir}/../include/client/taos.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../include/common/taosdef.h ${pkg_dir}${install_home_path}/include
|
||||
|
|
|
@ -45,6 +45,7 @@ echo buildroot: %{buildroot}
|
|||
|
||||
libfile="libtaos.so.%{_version}"
|
||||
wslibfile="libtaosws.so"
|
||||
rocksdblib="librocksdb.so.8"
|
||||
|
||||
# create install path, and cp file
|
||||
mkdir -p %{buildroot}%{homepath}/bin
|
||||
|
@ -92,6 +93,7 @@ if [ -f %{_compiledir}/build/bin/taosadapter ]; then
|
|||
fi
|
||||
cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driver
|
||||
[ -f %{_compiledir}/build/lib/${wslibfile} ] && cp %{_compiledir}/build/lib/${wslibfile} %{buildroot}%{homepath}/driver ||:
|
||||
[ -f %{_compiledir}/build/lib/${rocksdblib} ] && cp %{_compiledir}/build/lib/${rocksdblib} %{buildroot}%{homepath}/driver ||:
|
||||
cp %{_compiledir}/../include/client/taos.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../include/common/taosdef.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../include/util/taoserror.h %{buildroot}%{homepath}/include
|
||||
|
@ -174,6 +176,7 @@ fi
|
|||
|
||||
# there can not libtaos.so*, otherwise ln -s error
|
||||
${csudo}rm -f %{homepath}/driver/libtaos* || :
|
||||
${csudo}rm -f %{homepath}/driver/librocksdb* || :
|
||||
|
||||
#Scripts executed after installation
|
||||
%post
|
||||
|
@ -219,6 +222,7 @@ if [ $1 -eq 0 ];then
|
|||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo}rm -f ${lib_link_dir}/librocksdb.* || :
|
||||
|
||||
${csudo}rm -f ${log_link_dir} || :
|
||||
${csudo}rm -f ${data_link_dir} || :
|
||||
|
|
|
@ -250,18 +250,30 @@ function install_lib() {
|
|||
# Remove links
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo}rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
${csudo}rm -f ${lib_link_dir}/librocksdb.* || :
|
||||
${csudo}rm -f ${lib64_link_dir}/librocksdb.* || :
|
||||
#${csudo}rm -rf ${v15_java_app_dir} || :
|
||||
${csudo}cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo}chmod 777 ${install_main_dir}/driver/*
|
||||
|
||||
${csudo}ln -sf ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1
|
||||
${csudo}ln -sf ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so
|
||||
|
||||
${csudo}ln -sf ${install_main_dir}/driver/librocksdb.* ${lib_link_dir}/librocksdb.so.8
|
||||
${csudo}ln -sf ${lib_link_dir}/librocksdb.so.8 ${lib_link_dir}/librocksdb.so
|
||||
|
||||
${csudo}ln -sf ${install_main_dir}/driver/librocksdb.* ${lib_link_dir}/librocksdb.so.8
|
||||
${csudo}ln -sf ${lib_link_dir}/librocksdb.so.8 ${lib_link_dir}/librocksdb.so
|
||||
|
||||
|
||||
[ -f ${install_main_dir}/driver/libtaosws.so ] && ${csudo}ln -sf ${install_main_dir}/driver/libtaosws.so ${lib_link_dir}/libtaosws.so || :
|
||||
|
||||
if [[ -d ${lib64_link_dir} && ! -e ${lib64_link_dir}/libtaos.so ]]; then
|
||||
${csudo}ln -sf ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || :
|
||||
${csudo}ln -sf ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || :
|
||||
|
||||
${csudo}ln -sf ${install_main_dir}/driver/librocksdb.* ${lib64_link_dir}/librocksdb.so.8 || :
|
||||
${csudo}ln -sf ${lib64_link_dir}/librocksdb.so.8 ${lib64_link_dir}/librocksdb.so || :
|
||||
|
||||
[ -f ${install_main_dir}/libtaosws.so ] && ${csudo}ln -sf ${install_main_dir}/libtaosws.so ${lib64_link_dir}/libtaosws.so || :
|
||||
fi
|
||||
|
||||
|
|
|
@ -70,8 +70,7 @@ if [ "$pagMode" == "lite" ]; then
|
|||
taostools_bin_files=""
|
||||
else
|
||||
if [ "$verMode" == "cloud" ]; then
|
||||
taostools_bin_files=" ${build_dir}/bin/taosdump \
|
||||
${build_dir}/bin/taosBenchmark"
|
||||
taostools_bin_files=" ${build_dir}/bin/taosBenchmark"
|
||||
else
|
||||
wget https://github.com/taosdata/grafanaplugin/releases/latest/download/TDinsight.sh -O ${build_dir}/bin/TDinsight.sh \
|
||||
&& echo "TDinsight.sh downloaded!" \
|
||||
|
@ -112,9 +111,11 @@ fi
|
|||
if [ "$osType" == "Darwin" ]; then
|
||||
lib_files="${build_dir}/lib/libtaos.${version}.dylib"
|
||||
wslib_files="${build_dir}/lib/libtaosws.dylib"
|
||||
rocksdb_lib_files="${build_dir}/lib/librocksdb.dylib.8.1.1"
|
||||
else
|
||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||
wslib_files="${build_dir}/lib/libtaosws.so"
|
||||
rocksdb_lib_files="${build_dir}/lib/librocksdb.so.8.1.1"
|
||||
fi
|
||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/libs/function/taosudf.h"
|
||||
|
||||
|
@ -337,6 +338,7 @@ fi
|
|||
# Copy driver
|
||||
mkdir -p ${install_dir}/driver && cp ${lib_files} ${install_dir}/driver && echo "${versionComp}" >${install_dir}/driver/vercomp.txt
|
||||
[ -f ${wslib_files} ] && cp ${wslib_files} ${install_dir}/driver || :
|
||||
[ -f ${rocksdb_lib_files} ] && cp ${rocksdb_lib_files} ${install_dir}/driver || :
|
||||
|
||||
# Copy connector
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
|
|
|
@ -202,10 +202,19 @@ function install_lib() {
|
|||
log_print "start install lib from ${lib_dir} to ${lib_link_dir}"
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos* || :
|
||||
${csudo}rm -f ${lib64_link_dir}/libtaos* || :
|
||||
|
||||
#rocksdb
|
||||
[ -f ${lib_link_dir}/librocksdb* ] && ${csudo}rm -f ${lib_link_dir}/librocksdb* || :
|
||||
[ -f ${lib64_link_dir}/librocksdb* ] && ${csudo}rm -f ${lib64_link_dir}/librocksdb* || :
|
||||
|
||||
#rocksdb
|
||||
[ -f ${lib_link_dir}/librocksdb* ] && ${csudo}rm -f ${lib_link_dir}/librocksdb* || :
|
||||
[ -f ${lib64_link_dir}/librocksdb* ] && ${csudo}rm -f ${lib64_link_dir}/librocksdb* || :
|
||||
|
||||
[ -f ${lib_link_dir}/libtaosws.${lib_file_ext} ] && ${csudo}rm -f ${lib_link_dir}/libtaosws.${lib_file_ext} || :
|
||||
[ -f ${lib64_link_dir}/libtaosws.${lib_file_ext} ] && ${csudo}rm -f ${lib64_link_dir}/libtaosws.${lib_file_ext} || :
|
||||
|
||||
${csudo}ln -s ${lib_dir}/librocksdb.* ${lib_link_dir}/librocksdb.${lib_file_ext_1} 2>>${install_log_path} || return 1
|
||||
${csudo}ln -s ${lib_dir}/libtaos.* ${lib_link_dir}/libtaos.${lib_file_ext_1} 2>>${install_log_path} || return 1
|
||||
${csudo}ln -s ${lib_link_dir}/libtaos.${lib_file_ext_1} ${lib_link_dir}/libtaos.${lib_file_ext} 2>>${install_log_path} || return 1
|
||||
|
||||
|
@ -214,6 +223,7 @@ function install_lib() {
|
|||
if [[ -d ${lib64_link_dir} && ! -e ${lib64_link_dir}/libtaos.${lib_file_ext} ]]; then
|
||||
${csudo}ln -s ${lib_dir}/libtaos.* ${lib64_link_dir}/libtaos.${lib_file_ext_1} 2>>${install_log_path} || return 1
|
||||
${csudo}ln -s ${lib64_link_dir}/libtaos.${lib_file_ext_1} ${lib64_link_dir}/libtaos.${lib_file_ext} 2>>${install_log_path} || return 1
|
||||
${csudo}ln -s ${lib_dir}/librocksdb.* ${lib64_link_dir}/librocksdb.${lib_file_ext_1} 2>>${install_log_path} || return 1
|
||||
|
||||
[ -f ${lib_dir}/libtaosws.${lib_file_ext} ] && ${csudo}ln -sf ${lib_dir}/libtaosws.${lib_file_ext} ${lib64_link_dir}/libtaosws.${lib_file_ext} 2>>${install_log_path}
|
||||
fi
|
||||
|
|
|
@ -142,11 +142,14 @@ function clean_local_bin() {
|
|||
function clean_lib() {
|
||||
# Remove link
|
||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo}rm -f ${lib_link_dir}/librocksdb.* || :
|
||||
[ -f ${lib_link_dir}/libtaosws.* ] && ${csudo}rm -f ${lib_link_dir}/libtaosws.* || :
|
||||
|
||||
${csudo}rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
${csudo}rm -f ${lib64_link_dir}/librocksdb.* || :
|
||||
[ -f ${lib64_link_dir}/libtaosws.* ] && ${csudo}rm -f ${lib64_link_dir}/libtaosws.* || :
|
||||
#${csudo}rm -rf ${v15_java_app_dir} || :
|
||||
|
||||
}
|
||||
|
||||
function clean_header() {
|
||||
|
|
|
@ -89,6 +89,7 @@ struct tmq_t {
|
|||
void* commitCbUserParam;
|
||||
|
||||
// status
|
||||
SRWLatch lock;
|
||||
int8_t status;
|
||||
int32_t epoch;
|
||||
#if 0
|
||||
|
@ -148,10 +149,10 @@ typedef struct {
|
|||
SVgOffsetInfo offsetInfo;
|
||||
int32_t vgId;
|
||||
int32_t vgStatus;
|
||||
int32_t vgSkipCnt; // here used to mark the slow vgroups
|
||||
bool receivedInfoFromVnode;// has already received info from vnode
|
||||
int64_t emptyBlockReceiveTs; // once empty block is received, idle for ignoreCnt then start to poll data
|
||||
bool seekUpdated; // offset is updated by seek operator, therefore, not update by vnode rsp.
|
||||
int32_t vgSkipCnt; // here used to mark the slow vgroups
|
||||
bool receivedInfoFromVnode; // has already received info from vnode
|
||||
int64_t emptyBlockReceiveTs; // once empty block is received, idle for ignoreCnt then start to poll data
|
||||
bool seekUpdated; // offset is updated by seek operator, therefore, not update by vnode rsp.
|
||||
SEpSet epSet;
|
||||
} SMqClientVg;
|
||||
|
||||
|
@ -166,6 +167,7 @@ typedef struct {
|
|||
int8_t tmqRspType;
|
||||
int32_t epoch; // epoch can be used to guard the vgHandle
|
||||
int32_t vgId;
|
||||
char topicName[TSDB_TOPIC_FNAME_LEN];
|
||||
SMqClientVg* vgHandle;
|
||||
SMqClientTopic* topicHandle;
|
||||
uint64_t reqId;
|
||||
|
@ -178,8 +180,8 @@ typedef struct {
|
|||
} SMqPollRspWrapper;
|
||||
|
||||
typedef struct {
|
||||
int64_t refId;
|
||||
int32_t epoch;
|
||||
// int64_t refId;
|
||||
// int32_t epoch;
|
||||
tsem_t rspSem;
|
||||
int32_t rspErr;
|
||||
} SMqSubscribeCbParam;
|
||||
|
@ -194,8 +196,9 @@ typedef struct {
|
|||
typedef struct {
|
||||
int64_t refId;
|
||||
int32_t epoch;
|
||||
SMqClientVg* pVg;
|
||||
SMqClientTopic* pTopic;
|
||||
char topicName[TSDB_TOPIC_FNAME_LEN];
|
||||
// SMqClientVg* pVg;
|
||||
// SMqClientTopic* pTopic;
|
||||
int32_t vgId;
|
||||
uint64_t requestId; // request id for debug purpose
|
||||
} SMqPollCbParam;
|
||||
|
@ -743,8 +746,8 @@ static void generateTimedTask(int64_t refId, int32_t type) {
|
|||
*pTaskType = type;
|
||||
taosWriteQitem(tmq->delayedTask, pTaskType);
|
||||
tsem_post(&tmq->rspSem);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
}
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
}
|
||||
|
||||
void tmqAssignAskEpTask(void* param, void* tmrId) {
|
||||
|
@ -1071,6 +1074,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
pTmq->commitCb = conf->commitCb;
|
||||
pTmq->commitCbUserParam = conf->commitCbUserParam;
|
||||
pTmq->resetOffsetCfg = conf->resetOffset;
|
||||
taosInitRWLatch(&pTmq->lock);
|
||||
|
||||
pTmq->hbBgEnable = conf->hbBgEnable;
|
||||
|
||||
|
@ -1119,7 +1123,7 @@ _failed:
|
|||
}
|
||||
|
||||
int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||
const int32_t MAX_RETRY_COUNT = 120 * 4; // let's wait for 4 mins at most
|
||||
const int32_t MAX_RETRY_COUNT = 120 * 60; // let's wait for 2 mins at most
|
||||
const SArray* container = &topic_list->container;
|
||||
int32_t sz = taosArrayGetSize(container);
|
||||
void* buf = NULL;
|
||||
|
@ -1172,7 +1176,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
goto FAIL;
|
||||
}
|
||||
|
||||
SMqSubscribeCbParam param = { .rspErr = 0, .refId = tmq->refId, .epoch = tmq->epoch };
|
||||
SMqSubscribeCbParam param = { .rspErr = 0};
|
||||
if (tsem_init(¶m.rspSem, 0, 0) != 0) {
|
||||
code = TSDB_CODE_TSC_INTERNAL_ERROR;
|
||||
goto FAIL;
|
||||
|
@ -1206,8 +1210,8 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
int32_t retryCnt = 0;
|
||||
while (TSDB_CODE_MND_CONSUMER_NOT_READY == doAskEp(tmq)) {
|
||||
if (retryCnt++ > MAX_RETRY_COUNT) {
|
||||
tscError("consumer:0x%" PRIx64 ", mnd not ready for subscribe, max retry reached:%d", tmq->consumerId, retryCnt);
|
||||
code = TSDB_CODE_TSC_INTERNAL_ERROR;
|
||||
tscError("consumer:0x%" PRIx64 ", mnd not ready for subscribe, retry:%d in 500ms", tmq->consumerId, retryCnt);
|
||||
code = TSDB_CODE_MND_CONSUMER_NOT_READY;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
|
@ -1242,12 +1246,40 @@ void tmq_conf_set_auto_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb, void* para
|
|||
conf->commitCbUserParam = param;
|
||||
}
|
||||
|
||||
static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||
static SMqClientVg* getVgInfo(tmq_t* tmq, char* topicName, int32_t vgId){
|
||||
int32_t topicNumCur = taosArrayGetSize(tmq->clientTopics);
|
||||
for(int i = 0; i < topicNumCur; i++){
|
||||
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
|
||||
if(strcmp(pTopicCur->topicName, topicName) == 0){
|
||||
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
||||
for (int32_t j = 0; j < vgNumCur; j++) {
|
||||
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
|
||||
if(pVgCur->vgId == vgId){
|
||||
return pVgCur;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SMqClientTopic* getTopicInfo(tmq_t* tmq, char* topicName){
|
||||
int32_t topicNumCur = taosArrayGetSize(tmq->clientTopics);
|
||||
for(int i = 0; i < topicNumCur; i++){
|
||||
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
|
||||
if(strcmp(pTopicCur->topicName, topicName) == 0){
|
||||
return pTopicCur;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||
SMqPollCbParam* pParam = (SMqPollCbParam*)param;
|
||||
|
||||
int64_t refId = pParam->refId;
|
||||
SMqClientVg* pVg = pParam->pVg;
|
||||
SMqClientTopic* pTopic = pParam->pTopic;
|
||||
// SMqClientVg* pVg = pParam->pVg;
|
||||
// SMqClientTopic* pTopic = pParam->pTopic;
|
||||
|
||||
tmq_t* tmq = taosAcquireRef(tmqMgmt.rsetId, refId);
|
||||
if (tmq == NULL) {
|
||||
|
@ -1262,15 +1294,13 @@ static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
int32_t vgId = pParam->vgId;
|
||||
uint64_t requestId = pParam->requestId;
|
||||
|
||||
taosMemoryFree(pParam);
|
||||
|
||||
if (code != 0) {
|
||||
if (pMsg->pData) taosMemoryFree(pMsg->pData);
|
||||
if (pMsg->pEpSet) taosMemoryFree(pMsg->pEpSet);
|
||||
|
||||
// in case of consumer mismatch, wait for 500ms and retry
|
||||
if (code == TSDB_CODE_TMQ_CONSUMER_MISMATCH) {
|
||||
taosMsleep(500);
|
||||
// taosMsleep(500);
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__RECOVER);
|
||||
tscDebug("consumer:0x%" PRIx64 " wait for the re-balance, wait for 500ms and set status to be RECOVER",
|
||||
tmq->consumerId);
|
||||
|
@ -1284,8 +1314,8 @@ static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
|
||||
pRspWrapper->tmqRspType = TMQ_MSG_TYPE__END_RSP;
|
||||
taosWriteQitem(tmq->mqueue, pRspWrapper);
|
||||
} else if (code == TSDB_CODE_WAL_LOG_NOT_EXIST) { // poll data while insert
|
||||
taosMsleep(500);
|
||||
// } else if (code == TSDB_CODE_WAL_LOG_NOT_EXIST) { // poll data while insert
|
||||
// taosMsleep(5);
|
||||
} else{
|
||||
tscError("consumer:0x%" PRIx64 " msg from vgId:%d discarded, epoch %d, since %s, reqId:0x%" PRIx64, tmq->consumerId,
|
||||
vgId, epoch, tstrerror(code), requestId);
|
||||
|
@ -1307,6 +1337,8 @@ static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
|
||||
taosMemoryFree(pMsg->pData);
|
||||
taosMemoryFree(pMsg->pEpSet);
|
||||
taosMemoryFree(pParam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1328,11 +1360,12 @@ static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
}
|
||||
|
||||
pRspWrapper->tmqRspType = rspType;
|
||||
pRspWrapper->vgHandle = pVg;
|
||||
pRspWrapper->topicHandle = pTopic;
|
||||
// pRspWrapper->vgHandle = pVg;
|
||||
// pRspWrapper->topicHandle = pTopic;
|
||||
pRspWrapper->reqId = requestId;
|
||||
pRspWrapper->pEpset = pMsg->pEpSet;
|
||||
pRspWrapper->vgId = pVg->vgId;
|
||||
pRspWrapper->vgId = vgId;
|
||||
strcpy(pRspWrapper->topicName, pParam->topicName);
|
||||
|
||||
pMsg->pEpSet = NULL;
|
||||
if (rspType == TMQ_MSG_TYPE__POLL_RSP) {
|
||||
|
@ -1371,16 +1404,23 @@ static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
|
||||
tsem_post(&tmq->rspSem);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
taosMemoryFree(pParam);
|
||||
|
||||
return 0;
|
||||
|
||||
CREATE_MSG_FAIL:
|
||||
if (epoch == tmq->epoch) {
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
taosWLockLatch(&tmq->lock);
|
||||
SMqClientVg* pVg = getVgInfo(tmq, pParam->topicName, vgId);
|
||||
if(pVg){
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
}
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
}
|
||||
|
||||
tsem_post(&tmq->rspSem);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
taosMemoryFree(pParam);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -1503,11 +1543,13 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
|||
|
||||
taosHashCleanup(pVgOffsetHashMap);
|
||||
|
||||
taosWLockLatch(&tmq->lock);
|
||||
// destroy current buffered existed topics info
|
||||
if (tmq->clientTopics) {
|
||||
taosArrayDestroyEx(tmq->clientTopics, freeClientVgInfo);
|
||||
}
|
||||
tmq->clientTopics = newTopics;
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
|
||||
int8_t flag = (topicNumGet == 0) ? TMQ_CONSUMER_STATUS__NO_TOPIC : TMQ_CONSUMER_STATUS__READY;
|
||||
atomic_store_8(&tmq->status, flag);
|
||||
|
@ -1523,7 +1565,7 @@ int32_t askEpCallbackFn(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
|
||||
if (tmq == NULL) {
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_CLOSED;
|
||||
pParam->pUserFn(tmq, terrno, NULL, pParam->pParam);
|
||||
// pParam->pUserFn(tmq, terrno, NULL, pParam->pParam);
|
||||
|
||||
taosMemoryFree(pMsg->pData);
|
||||
taosMemoryFree(pMsg->pEpSet);
|
||||
|
@ -1682,8 +1724,9 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
|||
|
||||
pParam->refId = pTmq->refId;
|
||||
pParam->epoch = pTmq->epoch;
|
||||
pParam->pVg = pVg;
|
||||
pParam->pTopic = pTopic;
|
||||
// pParam->pVg = pVg; // pVg may be released,fix it
|
||||
// pParam->pTopic = pTopic;
|
||||
strcpy(pParam->topicName, pTopic->topicName);
|
||||
pParam->vgId = pVg->vgId;
|
||||
pParam->requestId = req.reqId;
|
||||
|
||||
|
@ -1718,6 +1761,9 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
|||
|
||||
// broadcast the poll request to all related vnodes
|
||||
static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
|
||||
if(atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__RECOVER){
|
||||
return 0;
|
||||
}
|
||||
int32_t numOfTopics = taosArrayGetSize(tmq->clientTopics);
|
||||
tscDebug("consumer:0x%" PRIx64 " start to poll data, numOfTopics:%d", tmq->consumerId, numOfTopics);
|
||||
|
||||
|
@ -1802,8 +1848,14 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
SMqDataRsp* pDataRsp = &pollRspWrapper->dataRsp;
|
||||
|
||||
if (pDataRsp->head.epoch == consumerEpoch) {
|
||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
|
||||
SMqClientVg* pVg = getVgInfo(tmq, pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
pollRspWrapper->vgHandle = pVg;
|
||||
pollRspWrapper->topicHandle = getTopicInfo(tmq, pollRspWrapper->topicName);
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
// update the epset
|
||||
if (pollRspWrapper->pEpset != NULL) {
|
||||
SEp* pEp = GET_ACTIVE_EP(pollRspWrapper->pEpset);
|
||||
|
@ -1816,7 +1868,10 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
// update the local offset value only for the returned values, only when the local offset is NOT updated
|
||||
// by tmq_offset_seek function
|
||||
if (!pVg->seekUpdated) {
|
||||
tscDebug("consumer:0x%" PRIx64" local offset is update, since seekupdate not set", tmq->consumerId);
|
||||
pVg->offsetInfo.currentOffset = pDataRsp->rspOffset;
|
||||
} else {
|
||||
tscDebug("consumer:0x%" PRIx64" local offset is NOT update, since seekupdate is set", tmq->consumerId);
|
||||
}
|
||||
|
||||
// update the status
|
||||
|
@ -1862,8 +1917,16 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
tscDebug("consumer:0x%" PRIx64 " process meta rsp", tmq->consumerId);
|
||||
|
||||
if (pollRspWrapper->metaRsp.head.epoch == consumerEpoch) {
|
||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
if (!pVg->seekUpdated) {
|
||||
SMqClientVg* pVg = getVgInfo(tmq, pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
pollRspWrapper->vgHandle = pVg;
|
||||
pollRspWrapper->topicHandle = getTopicInfo(tmq, pollRspWrapper->topicName);
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pollRspWrapper->metaRsp.rspOffset.type != 0){ // if offset is validate
|
||||
pVg->offsetInfo.currentOffset = pollRspWrapper->metaRsp.rspOffset;
|
||||
}
|
||||
|
||||
|
@ -1883,9 +1946,24 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
int32_t consumerEpoch = atomic_load_32(&tmq->epoch);
|
||||
|
||||
if (pollRspWrapper->taosxRsp.head.epoch == consumerEpoch) {
|
||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
if (!pVg->seekUpdated) { // if offset is validate
|
||||
pVg->offsetInfo.currentOffset = pollRspWrapper->taosxRsp.rspOffset;
|
||||
SMqClientVg* pVg = getVgInfo(tmq, pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
pollRspWrapper->vgHandle = pVg;
|
||||
pollRspWrapper->topicHandle = getTopicInfo(tmq, pollRspWrapper->topicName);
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// update the local offset value only for the returned values, only when the local offset is NOT updated
|
||||
// by tmq_offset_seek function
|
||||
if (!pVg->seekUpdated) {
|
||||
if(pollRspWrapper->taosxRsp.rspOffset.type != 0) { // if offset is validate
|
||||
tscDebug("consumer:0x%" PRIx64" local offset is update, since seekupdate not set", tmq->consumerId);
|
||||
pVg->offsetInfo.currentOffset = pollRspWrapper->taosxRsp.rspOffset;
|
||||
}
|
||||
} else {
|
||||
tscDebug("consumer:0x%" PRIx64" local offset is NOT update, since seekupdate is set", tmq->consumerId);
|
||||
}
|
||||
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
|
|
|
@ -2504,18 +2504,21 @@ _exit:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind) {
|
||||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen) {
|
||||
int32_t code = 0;
|
||||
|
||||
if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
|
||||
ASSERT(pColData->type == pBind->buffer_type);
|
||||
}
|
||||
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type
|
||||
for (int32_t i = 0; i < pBind->num; ++i) {
|
||||
if (pBind->is_null && pBind->is_null[i]) {
|
||||
code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
|
||||
if (code) goto _exit;
|
||||
} else if (pBind->length[i] > buffMaxLen) {
|
||||
uError("var data length too big, len:%d, max:%d", pBind->length[i], buffMaxLen);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
} else {
|
||||
code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
|
||||
pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]);
|
||||
|
@ -3523,6 +3526,43 @@ static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
|
||||
int16_t *numOfNull) {
|
||||
*(uint64_t *)sum = 0;
|
||||
*(uint64_t *)max = 0;
|
||||
*(uint64_t *)min = 0;
|
||||
*numOfNull = 0;
|
||||
|
||||
switch (pColData->flag) {
|
||||
case HAS_NONE:
|
||||
case HAS_NULL:
|
||||
case (HAS_NONE | HAS_NULL):
|
||||
*numOfNull = pColData->nVal;
|
||||
break;
|
||||
case HAS_VALUE:
|
||||
*numOfNull = 0;
|
||||
break;
|
||||
case (HAS_VALUE | HAS_NULL):
|
||||
case (HAS_VALUE | HAS_NONE):
|
||||
for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
|
||||
if (GET_BIT1(pColData->pBitMap, iVal) == 0) {
|
||||
(*numOfNull)++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (HAS_VALUE | HAS_NONE | HAS_NULL):
|
||||
for (int32_t iVal = 0; iVal < pColData->nVal; iVal++) {
|
||||
if (GET_BIT2(pColData->pBitMap, iVal) != 2) {
|
||||
(*numOfNull)++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull) = {
|
||||
NULL,
|
||||
tColDataCalcSMABool, // TSDB_DATA_TYPE_BOOL
|
||||
|
@ -3532,14 +3572,14 @@ void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_
|
|||
tColDataCalcSMABigInt, // TSDB_DATA_TYPE_BIGINT
|
||||
tColDataCalcSMAFloat, // TSDB_DATA_TYPE_FLOAT
|
||||
tColDataCalcSMADouble, // TSDB_DATA_TYPE_DOUBLE
|
||||
NULL, // TSDB_DATA_TYPE_VARCHAR
|
||||
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_VARCHAR
|
||||
tColDataCalcSMABigInt, // TSDB_DATA_TYPE_TIMESTAMP
|
||||
NULL, // TSDB_DATA_TYPE_NCHAR
|
||||
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_NCHAR
|
||||
tColDataCalcSMAUTinyInt, // TSDB_DATA_TYPE_UTINYINT
|
||||
tColDataCalcSMATinyUSmallInt, // TSDB_DATA_TYPE_USMALLINT
|
||||
tColDataCalcSMAUInt, // TSDB_DATA_TYPE_UINT
|
||||
tColDataCalcSMAUBigInt, // TSDB_DATA_TYPE_UBIGINT
|
||||
NULL, // TSDB_DATA_TYPE_JSON
|
||||
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_JSON
|
||||
NULL, // TSDB_DATA_TYPE_VARBINARY
|
||||
NULL, // TSDB_DATA_TYPE_DECIMAL
|
||||
NULL, // TSDB_DATA_TYPE_BLOB
|
||||
|
|
|
@ -60,6 +60,7 @@ int32_t tsNumOfQnodeQueryThreads = 4;
|
|||
int32_t tsNumOfQnodeFetchThreads = 1;
|
||||
int32_t tsNumOfSnodeStreamThreads = 4;
|
||||
int32_t tsNumOfSnodeWriteThreads = 1;
|
||||
int32_t tsMaxStreamBackendCache = 128; // M
|
||||
|
||||
// sync raft
|
||||
int32_t tsElectInterval = 25 * 1000;
|
||||
|
@ -105,7 +106,7 @@ int32_t tsQueryPolicy = 1;
|
|||
int32_t tsQueryRspPolicy = 0;
|
||||
int64_t tsQueryMaxConcurrentTables = 200; // unit is TSDB_TABLE_NUM_UNIT
|
||||
bool tsEnableQueryHb = false;
|
||||
bool tsEnableScience = false; // on taos-cli show float and doulbe with scientific notation if true
|
||||
bool tsEnableScience = false; // on taos-cli show float and doulbe with scientific notation if true
|
||||
int32_t tsQuerySmaOptimize = 0;
|
||||
int32_t tsQueryRsmaTolerance = 1000; // the tolerance time (ms) to judge from which level to query rsma data.
|
||||
bool tsQueryPlannerTrace = false;
|
||||
|
@ -117,8 +118,8 @@ int32_t tsRedirectFactor = 2;
|
|||
int32_t tsRedirectMaxPeriod = 1000;
|
||||
int32_t tsMaxRetryWaitTime = 10000;
|
||||
bool tsUseAdapter = false;
|
||||
int32_t tsMetaCacheMaxSize = -1; // MB
|
||||
int32_t tsSlowLogThreshold = 3; // seconds
|
||||
int32_t tsMetaCacheMaxSize = -1; // MB
|
||||
int32_t tsSlowLogThreshold = 3; // seconds
|
||||
int32_t tsSlowLogScope = SLOW_LOG_TYPE_ALL;
|
||||
|
||||
/*
|
||||
|
@ -141,8 +142,8 @@ int32_t tsCompressColData = -1;
|
|||
// count/hyperloglog function always return values in case of all NULL data or Empty data set.
|
||||
int32_t tsCountAlwaysReturnValue = 1;
|
||||
|
||||
// 10 ms for sliding time, the value will changed in case of time precision changed
|
||||
int32_t tsMinSlidingTime = 10;
|
||||
// 1 ms for sliding time, the value will changed in case of time precision changed
|
||||
int32_t tsMinSlidingTime = 1;
|
||||
|
||||
// the maxinum number of distict query result
|
||||
int32_t tsMaxNumOfDistinctResults = 1000 * 10000;
|
||||
|
@ -150,8 +151,8 @@ int32_t tsMaxNumOfDistinctResults = 1000 * 10000;
|
|||
// 1 database precision unit for interval time range, changed accordingly
|
||||
int32_t tsMinIntervalTime = 1;
|
||||
|
||||
// maximum memory allowed to be allocated for a single csv load (in MB)
|
||||
int32_t tsMaxMemUsedByInsert = 1024;
|
||||
// maximum batch rows numbers imported from a single csv load
|
||||
int32_t tsMaxInsertBatchRows = 1000000;
|
||||
|
||||
float tsSelectivityRatio = 1.0;
|
||||
int32_t tsTagFilterResCacheSize = 1024 * 10;
|
||||
|
@ -345,11 +346,12 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
|
|||
if (cfgAddString(pCfg, "smlTagName", tsSmlTagName, 1) != 0) return -1;
|
||||
// if (cfgAddBool(pCfg, "smlDataFormat", tsSmlDataFormat, 1) != 0) return -1;
|
||||
// if (cfgAddInt32(pCfg, "smlBatchSize", tsSmlBatchSize, 1, INT32_MAX, true) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxMemUsedByInsert", tsMaxMemUsedByInsert, 1, INT32_MAX, true) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxInsertBatchRows", tsMaxInsertBatchRows, 1, INT32_MAX, true) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxRetryWaitTime", tsMaxRetryWaitTime, 0, 86400000, 0) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "useAdapter", tsUseAdapter, true) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "crashReporting", tsEnableCrashReport, true) != 0) return -1;
|
||||
if (cfgAddInt64(pCfg, "queryMaxConcurrentTables", tsQueryMaxConcurrentTables, INT64_MIN, INT64_MAX, 1) != 0) return -1;
|
||||
if (cfgAddInt64(pCfg, "queryMaxConcurrentTables", tsQueryMaxConcurrentTables, INT64_MIN, INT64_MAX, 1) != 0)
|
||||
return -1;
|
||||
if (cfgAddInt32(pCfg, "metaCacheMaxSize", tsMetaCacheMaxSize, -1, INT32_MAX, 1) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "slowLogThreshold", tsSlowLogThreshold, 0, INT32_MAX, true) != 0) return -1;
|
||||
if (cfgAddString(pCfg, "slowLogScope", "", true) != 0) return -1;
|
||||
|
@ -420,7 +422,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
|
||||
if (cfgAddInt32(pCfg, "maxShellConns", tsMaxShellConns, 10, 50000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "statusInterval", tsStatusInterval, 1, 30, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "minSlidingTime", tsMinSlidingTime, 10, 1000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "minSlidingTime", tsMinSlidingTime, 1, 1000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "minIntervalTime", tsMinIntervalTime, 1, 1000000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxNumOfDistinctRes", tsMaxNumOfDistinctResults, 10 * 10000, 10000 * 10000, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "countAlwaysReturnValue", tsCountAlwaysReturnValue, 0, 1, 0) != 0) return -1;
|
||||
|
@ -524,6 +526,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "cacheLazyLoadThreshold", tsCacheLazyLoadThreshold, 0, 100000, 0) != 0) return -1;
|
||||
|
||||
if (cfgAddBool(pCfg, "filterScalarMode", tsFilterScalarMode, 0) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "maxStreamBackendCache", tsMaxStreamBackendCache, 16, 1024, 0) != 0) return -1;
|
||||
|
||||
GRANT_CFG_ADD;
|
||||
return 0;
|
||||
|
@ -773,7 +776,7 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
|
|||
// tsSmlDataFormat = cfgGetItem(pCfg, "smlDataFormat")->bval;
|
||||
|
||||
// tsSmlBatchSize = cfgGetItem(pCfg, "smlBatchSize")->i32;
|
||||
tsMaxMemUsedByInsert = cfgGetItem(pCfg, "maxMemUsedByInsert")->i32;
|
||||
tsMaxInsertBatchRows = cfgGetItem(pCfg, "maxInsertBatchRows")->i32;
|
||||
|
||||
tsShellActivityTimer = cfgGetItem(pCfg, "shellActivityTimer")->i32;
|
||||
tsCompressMsgSize = cfgGetItem(pCfg, "compressMsgSize")->i32;
|
||||
|
@ -781,7 +784,7 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
|
|||
tsNumOfTaskQueueThreads = cfgGetItem(pCfg, "numOfTaskQueueThreads")->i32;
|
||||
tsQueryPolicy = cfgGetItem(pCfg, "queryPolicy")->i32;
|
||||
tsEnableQueryHb = cfgGetItem(pCfg, "enableQueryHb")->bval;
|
||||
tsEnableScience = cfgGetItem(pCfg, "enableScience")->bval;
|
||||
tsEnableScience = cfgGetItem(pCfg, "enableScience")->bval;
|
||||
tsQuerySmaOptimize = cfgGetItem(pCfg, "querySmaOptimize")->i32;
|
||||
tsQueryPlannerTrace = cfgGetItem(pCfg, "queryPlannerTrace")->bval;
|
||||
tsQueryNodeChunkSize = cfgGetItem(pCfg, "queryNodeChunkSize")->i32;
|
||||
|
@ -902,7 +905,8 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
|||
tsCheckpointInterval = cfgGetItem(pCfg, "checkpointInterval")->i64;
|
||||
|
||||
tsFilterScalarMode = cfgGetItem(pCfg, "filterScalarMode")->bval;
|
||||
|
||||
tsMaxStreamBackendCache = cfgGetItem(pCfg, "maxStreamBackendCache")->i32;
|
||||
|
||||
GRANT_CFG_GET;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1044,7 +1048,7 @@ int32_t taosApplyLocalCfg(SConfig *pCfg, char *name) {
|
|||
} else if (strcasecmp("maxNumOfDistinctRes", name) == 0) {
|
||||
tsMaxNumOfDistinctResults = cfgGetItem(pCfg, "maxNumOfDistinctRes")->i32;
|
||||
} else if (strcasecmp("maxMemUsedByInsert", name) == 0) {
|
||||
tsMaxMemUsedByInsert = cfgGetItem(pCfg, "maxMemUsedByInsert")->i32;
|
||||
tsMaxInsertBatchRows = cfgGetItem(pCfg, "maxInsertBatchRows")->i32;
|
||||
} else if (strcasecmp("maxRetryWaitTime", name) == 0) {
|
||||
tsMaxRetryWaitTime = cfgGetItem(pCfg, "maxRetryWaitTime")->i32;
|
||||
}
|
||||
|
|
|
@ -4002,11 +4002,16 @@ int32_t tSerializeSCMCreateTopicReq(void *buf, int32_t bufLen, const SCMCreateTo
|
|||
if (tEncodeI8(&encoder, pReq->withMeta) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->subDbName) < 0) return -1;
|
||||
if (TOPIC_SUB_TYPE__DB == pReq->subType) {
|
||||
} else if (TOPIC_SUB_TYPE__TABLE == pReq->subType) {
|
||||
if (tEncodeCStr(&encoder, pReq->subStbName) < 0) return -1;
|
||||
} else {
|
||||
if (tEncodeI32(&encoder, strlen(pReq->ast)) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->ast) < 0) return -1;
|
||||
if (TOPIC_SUB_TYPE__TABLE == pReq->subType) {
|
||||
if (tEncodeCStr(&encoder, pReq->subStbName) < 0) return -1;
|
||||
}
|
||||
if (pReq->ast && strlen(pReq->ast) > 0) {
|
||||
if (tEncodeI32(&encoder, strlen(pReq->ast)) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->ast) < 0) return -1;
|
||||
} else {
|
||||
if (tEncodeI32(&encoder, 0) < 0) return -1;
|
||||
}
|
||||
}
|
||||
if (tEncodeI32(&encoder, strlen(pReq->sql)) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->sql) < 0) return -1;
|
||||
|
@ -4032,9 +4037,10 @@ int32_t tDeserializeSCMCreateTopicReq(void *buf, int32_t bufLen, SCMCreateTopicR
|
|||
if (tDecodeI8(&decoder, &pReq->withMeta) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->subDbName) < 0) return -1;
|
||||
if (TOPIC_SUB_TYPE__DB == pReq->subType) {
|
||||
} else if (TOPIC_SUB_TYPE__TABLE == pReq->subType) {
|
||||
if (tDecodeCStrTo(&decoder, pReq->subStbName) < 0) return -1;
|
||||
} else {
|
||||
if (TOPIC_SUB_TYPE__TABLE == pReq->subType) {
|
||||
if (tDecodeCStrTo(&decoder, pReq->subStbName) < 0) return -1;
|
||||
}
|
||||
if (tDecodeI32(&decoder, &astLen) < 0) return -1;
|
||||
if (astLen > 0) {
|
||||
pReq->ast = taosMemoryCalloc(1, astLen + 1);
|
||||
|
@ -4057,7 +4063,7 @@ int32_t tDeserializeSCMCreateTopicReq(void *buf, int32_t bufLen, SCMCreateTopicR
|
|||
|
||||
void tFreeSCMCreateTopicReq(SCMCreateTopicReq *pReq) {
|
||||
taosMemoryFreeClear(pReq->sql);
|
||||
if (TOPIC_SUB_TYPE__COLUMN == pReq->subType) {
|
||||
if (TOPIC_SUB_TYPE__DB != pReq->subType) {
|
||||
taosMemoryFreeClear(pReq->ast);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ static int32_t parseLocaltime(char* timestr, int32_t len, int64_t* utime, int32_
|
|||
static int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim);
|
||||
static char* forwardToTimeStringEnd(char* str);
|
||||
static bool checkTzPresent(const char* str, int32_t len);
|
||||
static int32_t parseTimezone(char* str, int64_t* tzOffset);
|
||||
|
||||
static int32_t (*parseLocaltimeFp[])(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim) = {
|
||||
parseLocaltime, parseLocaltimeDst};
|
||||
|
@ -92,13 +93,13 @@ int32_t taosParseTime(const char* timestr, int64_t* utime, int32_t len, int32_t
|
|||
if (checkTzPresent(timestr, len)) {
|
||||
return parseTimeWithTz(timestr, utime, timePrec, 'T');
|
||||
} else {
|
||||
return (*parseLocaltimeFp[day_light])((char*)timestr, len, utime, timePrec, 'T');
|
||||
return parseLocaltimeDst((char*)timestr, len, utime, timePrec, 'T');
|
||||
}
|
||||
} else {
|
||||
if (checkTzPresent(timestr, len)) {
|
||||
return parseTimeWithTz(timestr, utime, timePrec, 0);
|
||||
} else {
|
||||
return (*parseLocaltimeFp[day_light])((char*)timestr, len, utime, timePrec, 0);
|
||||
return parseLocaltimeDst((char*)timestr, len, utime, timePrec, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -713,16 +714,12 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
|||
return t;
|
||||
}
|
||||
|
||||
if (unit != 'n' && unit != 'y') {
|
||||
if (!IS_CALENDAR_TIME_DURATION(unit)) {
|
||||
return t + duration;
|
||||
}
|
||||
|
||||
// The following code handles the y/n time duration
|
||||
int64_t numOfMonth = duration;
|
||||
if (unit == 'y') {
|
||||
numOfMonth *= 12;
|
||||
}
|
||||
|
||||
int64_t numOfMonth = (unit == 'y')? duration*12:duration;
|
||||
int64_t fraction = t % TSDB_TICK_PER_SECOND(precision);
|
||||
|
||||
struct tm tm;
|
||||
|
@ -741,6 +738,7 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char
|
|||
ekey = skey;
|
||||
skey = tmp;
|
||||
}
|
||||
|
||||
if (unit != 'n' && unit != 'y') {
|
||||
return (int32_t)((ekey - skey) / interval);
|
||||
}
|
||||
|
@ -764,13 +762,16 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char
|
|||
return (emon - smon) / (int32_t)interval;
|
||||
}
|
||||
|
||||
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision) {
|
||||
int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
||||
if (pInterval->sliding == 0 && pInterval->interval == 0) {
|
||||
return t;
|
||||
return ts;
|
||||
}
|
||||
|
||||
int64_t start = t;
|
||||
if (pInterval->slidingUnit == 'n' || pInterval->slidingUnit == 'y') {
|
||||
int64_t start = ts;
|
||||
int32_t precision = pInterval->precision;
|
||||
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->slidingUnit)) {
|
||||
|
||||
start /= (int64_t)(TSDB_TICK_PER_SECOND(precision));
|
||||
struct tm tm;
|
||||
time_t tt = (time_t)start;
|
||||
|
@ -792,44 +793,72 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
|
||||
start = (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision));
|
||||
} else {
|
||||
int64_t delta = t - pInterval->interval;
|
||||
int32_t factor = (delta >= 0) ? 1 : -1;
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->intervalUnit)) {
|
||||
int64_t news = (ts / pInterval->sliding) * pInterval->sliding;
|
||||
ASSERT(news <= ts);
|
||||
|
||||
start = (delta / pInterval->sliding + factor) * pInterval->sliding;
|
||||
if (news <= ts) {
|
||||
int64_t prev = news;
|
||||
int64_t newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
|
||||
if (pInterval->intervalUnit == 'd' || pInterval->intervalUnit == 'w') {
|
||||
/*
|
||||
* here we revised the start time of day according to the local time zone,
|
||||
* but in case of DST, the start time of one day need to be dynamically decided.
|
||||
*/
|
||||
// todo refactor to extract function that is available for Linux/Windows/Mac platform
|
||||
#if defined(WINDOWS) && _MSC_VER >= 1900
|
||||
// see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
|
||||
int64_t timezone = _timezone;
|
||||
int32_t daylight = _daylight;
|
||||
char** tzname = _tzname;
|
||||
#endif
|
||||
if (newe < ts) { // move towards the greater endpoint
|
||||
while(newe < ts && news < ts) {
|
||||
news += pInterval->sliding;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
}
|
||||
|
||||
start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision));
|
||||
}
|
||||
|
||||
int64_t end = 0;
|
||||
|
||||
// not enough time range
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
while (end < t) { // move forward to the correct time window
|
||||
start += pInterval->sliding;
|
||||
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
end = start + pInterval->interval - 1;
|
||||
prev = news;
|
||||
} else {
|
||||
end = INT64_MAX;
|
||||
break;
|
||||
while (newe >= ts) {
|
||||
prev = news;
|
||||
news -= pInterval->sliding;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
} else {
|
||||
end = INT64_MAX;
|
||||
int64_t delta = ts - pInterval->interval;
|
||||
int32_t factor = (delta >= 0) ? 1 : -1;
|
||||
|
||||
start = (delta / pInterval->sliding + factor) * pInterval->sliding;
|
||||
|
||||
if (pInterval->intervalUnit == 'd' || pInterval->intervalUnit == 'w') {
|
||||
/*
|
||||
* here we revised the start time of day according to the local time zone,
|
||||
* but in case of DST, the start time of one day need to be dynamically decided.
|
||||
*/
|
||||
// todo refactor to extract function that is available for Linux/Windows/Mac platform
|
||||
#if defined(WINDOWS) && _MSC_VER >= 1900
|
||||
// see
|
||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
|
||||
int64_t timezone = _timezone;
|
||||
int32_t daylight = _daylight;
|
||||
char** tzname = _tzname;
|
||||
#endif
|
||||
|
||||
start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision));
|
||||
}
|
||||
|
||||
int64_t end = 0;
|
||||
|
||||
// not enough time range
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
while (end < ts) { // move forward to the correct time window
|
||||
start += pInterval->sliding;
|
||||
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
end = start + pInterval->interval - 1;
|
||||
} else {
|
||||
end = INT64_MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
end = INT64_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -841,10 +870,10 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
// try to move current window to the left-hande-side, due to the offset effect.
|
||||
int64_t end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
|
||||
int64_t newEnd = end;
|
||||
while (newEnd >= t) {
|
||||
end = newEnd;
|
||||
newEnd = taosTimeAdd(newEnd, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
int64_t newe = end;
|
||||
while (newe >= ts) {
|
||||
end = newe;
|
||||
newe = taosTimeAdd(newe, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
}
|
||||
|
||||
start = taosTimeAdd(end, -pInterval->interval, pInterval->intervalUnit, precision) + 1;
|
||||
|
|
|
@ -78,7 +78,7 @@ static void vmProcessQueryQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
|||
int32_t code = vnodeProcessQueryMsg(pVnode->pImpl, pMsg);
|
||||
if (code != 0) {
|
||||
if (terrno != 0) code = terrno;
|
||||
dGError("vgId:%d, msg:%p failed to query since %s", pVnode->vgId, pMsg, terrstr(code));
|
||||
dGError("vgId:%d, msg:%p failed to query since %s", pVnode->vgId, pMsg, tstrerror(code));
|
||||
vmSendRsp(pMsg, code);
|
||||
}
|
||||
|
||||
|
|
|
@ -929,7 +929,7 @@ static void mndDumpDbCfgInfo(SDbCfgRsp *cfgRsp, SDbObj *pDb) {
|
|||
cfgRsp->walRetentionSize = pDb->cfg.walRetentionSize;
|
||||
cfgRsp->walSegmentSize = pDb->cfg.walSegmentSize;
|
||||
cfgRsp->numOfRetensions = pDb->cfg.numOfRetensions;
|
||||
cfgRsp->pRetensions = pDb->cfg.pRetensions;
|
||||
cfgRsp->pRetensions = taosArrayDup(pDb->cfg.pRetensions, NULL);
|
||||
cfgRsp->schemaless = pDb->cfg.schemaless;
|
||||
cfgRsp->sstTrigger = pDb->cfg.sstTrigger;
|
||||
}
|
||||
|
@ -972,6 +972,8 @@ static int32_t mndProcessGetDbCfgReq(SRpcMsg *pReq) {
|
|||
|
||||
_OVER:
|
||||
|
||||
tFreeSDbCfgRsp(&cfgRsp);
|
||||
|
||||
if (code != 0) {
|
||||
mError("db:%s, failed to get cfg since %s", cfgReq.db, terrstr());
|
||||
}
|
||||
|
|
|
@ -637,7 +637,23 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
|||
terrno = TSDB_CODE_QRY_INVALID_INPUT;
|
||||
return -1;
|
||||
}
|
||||
}else if(pTopic->subType == TOPIC_SUB_TYPE__TABLE && pTopic->ast != NULL){
|
||||
SNode *pAst = NULL;
|
||||
if (nodesStringToNode(pTopic->ast, &pAst) != 0) {
|
||||
mError("topic:%s, failed to create since %s", pTopic->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SPlanContext cxt = {.pAstRoot = pAst, .topicQuery = true};
|
||||
if (qCreateQueryPlan(&cxt, &pPlan, NULL) != 0) {
|
||||
mError("failed to create topic:%s since %s", pTopic->name, terrstr());
|
||||
nodesDestroyNode(pAst);
|
||||
return -1;
|
||||
}
|
||||
nodesDestroyNode(pAst);
|
||||
}
|
||||
|
||||
if(pPlan){
|
||||
int32_t levelNum = LIST_LENGTH(pPlan->pSubplans);
|
||||
if (levelNum != 1) {
|
||||
qDestroyQueryPlan(pPlan);
|
||||
|
@ -678,7 +694,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
|||
|
||||
mDebug("init subscription %s for topic:%s assign vgId:%d", pSub->key, pTopic->name, pVgEp->vgId);
|
||||
|
||||
if (pTopic->subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
if (pSubplan) {
|
||||
int32_t msgLen;
|
||||
|
||||
pSubplan->execNode.epSet = pVgEp->epSet;
|
||||
|
|
|
@ -1230,7 +1230,7 @@ static int32_t mndCheckAlterColForTopic(SMnode *pMnode, const char *stbFullName,
|
|||
|
||||
mInfo("topic:%s, check tag and column modifiable, stb:%s suid:%" PRId64 " colId:%d, subType:%d sql:%s",
|
||||
pTopic->name, stbFullName, suid, colId, pTopic->subType, pTopic->sql);
|
||||
if (pTopic->subType != TOPIC_SUB_TYPE__COLUMN) {
|
||||
if (pTopic->ast == NULL) {
|
||||
sdbRelease(pSdb, pTopic);
|
||||
continue;
|
||||
}
|
||||
|
@ -2272,7 +2272,7 @@ static int32_t mndCheckDropStbForTopic(SMnode *pMnode, const char *stbFullName,
|
|||
}
|
||||
}
|
||||
|
||||
if (pTopic->subType != TOPIC_SUB_TYPE__COLUMN) {
|
||||
if (pTopic->ast == NULL) {
|
||||
sdbRelease(pSdb, pTopic);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,14 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
|
|||
req.suid = pSub->stbUid;
|
||||
tstrncpy(req.subKey, pSub->key, TSDB_SUBSCRIBE_KEY_LEN);
|
||||
|
||||
int32_t tlen = sizeof(SMsgHead) + tEncodeSMqRebVgReq(NULL, &req);
|
||||
int32_t tlen = 0;
|
||||
int32_t ret = 0;
|
||||
tEncodeSize(tEncodeSMqRebVgReq, &req, tlen, ret);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tlen += sizeof(SMsgHead);
|
||||
void *buf = taosMemoryMalloc(tlen);
|
||||
if (buf == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -123,8 +130,14 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
|
|||
pMsgHead->contLen = htonl(tlen);
|
||||
pMsgHead->vgId = htonl(pRebVg->pVgEp->vgId);
|
||||
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
tEncodeSMqRebVgReq(&abuf, &req);
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, POINTER_SHIFT(buf, sizeof(SMsgHead)), tlen);
|
||||
if (tEncodeSMqRebVgReq(&encoder, &req) < 0) {
|
||||
taosMemoryFreeClear(buf);
|
||||
tEncoderClear(&encoder);
|
||||
return -1;
|
||||
}
|
||||
tEncoderClear(&encoder);
|
||||
*pBuf = buf;
|
||||
*pLen = tlen;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "parser.h"
|
||||
#include "tname.h"
|
||||
|
||||
#define MND_TOPIC_VER_NUMBER 2
|
||||
#define MND_TOPIC_VER_NUMBER 3
|
||||
#define MND_TOPIC_RESERVE_SIZE 64
|
||||
|
||||
SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic);
|
||||
|
@ -170,7 +170,7 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) {
|
|||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto TOPIC_DECODE_OVER;
|
||||
|
||||
if (sver != 1 && sver != 2) {
|
||||
if (sver < 1 || sver > MND_TOPIC_VER_NUMBER) {
|
||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||
goto TOPIC_DECODE_OVER;
|
||||
}
|
||||
|
@ -197,7 +197,9 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT8(pRaw, dataPos, &pTopic->withMeta, TOPIC_DECODE_OVER);
|
||||
|
||||
SDB_GET_INT64(pRaw, dataPos, &pTopic->stbUid, TOPIC_DECODE_OVER);
|
||||
SDB_GET_BINARY(pRaw, dataPos, pTopic->stbName, TSDB_TABLE_FNAME_LEN, TOPIC_DECODE_OVER);
|
||||
if (sver >= 3) {
|
||||
SDB_GET_BINARY(pRaw, dataPos, pTopic->stbName, TSDB_TABLE_FNAME_LEN, TOPIC_DECODE_OVER);
|
||||
}
|
||||
SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER);
|
||||
pTopic->sql = taosMemoryCalloc(pTopic->sqlLen, sizeof(char));
|
||||
if (pTopic->sql == NULL) {
|
||||
|
@ -422,6 +424,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
mError("failed to create topic:%s since %s", pCreate->name, terrstr());
|
||||
taosMemoryFree(topicObj.ast);
|
||||
taosMemoryFree(topicObj.sql);
|
||||
nodesDestroyNode(pAst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -429,6 +432,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
if (topicObj.ntbColIds == NULL) {
|
||||
taosMemoryFree(topicObj.ast);
|
||||
taosMemoryFree(topicObj.sql);
|
||||
nodesDestroyNode(pAst);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
@ -444,6 +448,7 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
taosMemoryFree(topicObj.ast);
|
||||
taosMemoryFree(topicObj.sql);
|
||||
nodesDestroyNode(pAst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -465,6 +470,11 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
strcpy(topicObj.stbName, pCreate->subStbName);
|
||||
topicObj.stbUid = pStb->uid;
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
if(pCreate->ast != NULL){
|
||||
qDebugL("topic:%s ast %s", topicObj.name, pCreate->ast);
|
||||
topicObj.ast = taosStrdup(pCreate->ast);
|
||||
topicObj.astLen = strlen(pCreate->ast) + 1;
|
||||
}
|
||||
}
|
||||
/*} else if (pCreate->subType == TOPIC_SUB_TYPE__DB) {*/
|
||||
/*topicObj.ast = NULL;*/
|
||||
|
@ -914,13 +924,12 @@ static int32_t mndRetrieveTopic(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
|
|||
}else if(pTopic->subType == TOPIC_SUB_TYPE__TABLE){
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, pTopic->stbName);
|
||||
if (pStb == NULL) {
|
||||
terrno = TSDB_CODE_MND_STB_NOT_EXIST;
|
||||
taosMemoryFree(schemaJson);
|
||||
return -1;
|
||||
STR_TO_VARSTR(schemaJson, "NULL");
|
||||
mError("mndRetrieveTopic mndAcquireStb null stbName:%s", pTopic->stbName);
|
||||
}else{
|
||||
schemaToJson(pStb->pColumns, pStb->numOfColumns, schemaJson);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
}
|
||||
schemaToJson(pStb->pColumns, pStb->numOfColumns, schemaJson);
|
||||
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
}else{
|
||||
STR_TO_VARSTR(schemaJson, "NULL");
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ int32_t tsdbSetTableList(STsdbReader *pReader, const void *pTableList, int3
|
|||
void tsdbReaderSetId(STsdbReader *pReader, const char *idstr);
|
||||
void tsdbReaderClose(STsdbReader *pReader);
|
||||
int32_t tsdbNextDataBlock(STsdbReader *pReader, bool *hasNext);
|
||||
int32_t tsdbRetrieveDatablockSMA(STsdbReader *pReader, SSDataBlock *pDataBlock, bool *allHave);
|
||||
int32_t tsdbRetrieveDatablockSMA(STsdbReader *pReader, SSDataBlock *pDataBlock, bool *allHave, bool *hasNullSMA);
|
||||
void tsdbReleaseDataBlock(STsdbReader *pReader);
|
||||
SSDataBlock *tsdbRetrieveDataBlock(STsdbReader *pTsdbReadHandle, SArray *pColumnIdList);
|
||||
int32_t tsdbReaderReset(STsdbReader *pReader, SQueryTableDataCond *pCond);
|
||||
|
@ -200,7 +200,7 @@ STqReader *tqReaderOpen(SVnode *pVnode);
|
|||
void tqReaderClose(STqReader *);
|
||||
|
||||
void tqReaderSetColIdList(STqReader *pReader, SArray *pColIdList);
|
||||
int32_t tqReaderSetTbUidList(STqReader *pReader, const SArray *tbUidList);
|
||||
int32_t tqReaderSetTbUidList(STqReader *pReader, const SArray *tbUidList, const char* id);
|
||||
int32_t tqReaderAddTbUidList(STqReader *pReader, const SArray *pTableUidList);
|
||||
int32_t tqReaderRemoveTbUidList(STqReader *pReader, const SArray *tbUidList);
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
char* qmsg; // SubPlanToString
|
||||
SNode* node;
|
||||
} STqExecTb;
|
||||
|
||||
typedef struct {
|
||||
|
@ -96,18 +98,17 @@ typedef enum tq_handle_status {
|
|||
} tq_handle_status;
|
||||
|
||||
typedef struct {
|
||||
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
int64_t consumerId;
|
||||
int32_t epoch;
|
||||
int8_t fetchMeta;
|
||||
int64_t snapshotVer;
|
||||
SWalReader* pWalReader;
|
||||
SWalRef* pRef;
|
||||
// STqPushHandle pushHandle; // push
|
||||
STqExecHandle execHandle; // exec
|
||||
SRpcMsg* msg;
|
||||
int32_t noDataPollCnt;
|
||||
tq_handle_status status;
|
||||
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
int64_t consumerId;
|
||||
int32_t epoch;
|
||||
int8_t fetchMeta;
|
||||
int64_t snapshotVer;
|
||||
SWalReader* pWalReader;
|
||||
SWalRef* pRef;
|
||||
// STqPushHandle pushHandle; // push
|
||||
STqExecHandle execHandle; // exec
|
||||
SRpcMsg* msg;
|
||||
tq_handle_status status;
|
||||
} STqHandle;
|
||||
|
||||
struct STQ {
|
||||
|
|
|
@ -296,6 +296,7 @@ int32_t tsdbUpdateDelFileHdr(SDelFWriter *pWriter);
|
|||
// SDelFReader
|
||||
int32_t tsdbDelFReaderOpen(SDelFReader **ppReader, SDelFile *pFile, STsdb *pTsdb);
|
||||
int32_t tsdbDelFReaderClose(SDelFReader **ppReader);
|
||||
int32_t tsdbReadDelDatav1(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData, int64_t maxVer);
|
||||
int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData);
|
||||
int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx);
|
||||
// tsdbRead.c ==============================================================================================
|
||||
|
|
|
@ -317,42 +317,6 @@ _query:
|
|||
tDecoderClear(&dc);
|
||||
goto _exit;
|
||||
}
|
||||
{ // Traverse to find the previous qualified data
|
||||
TBC *pCur;
|
||||
tdbTbcOpen(pMeta->pTbDb, &pCur, NULL);
|
||||
STbDbKey key = {.version = sver, .uid = INT64_MAX};
|
||||
int c = 0;
|
||||
tdbTbcMoveTo(pCur, &key, sizeof(key), &c);
|
||||
if (c < 0) {
|
||||
tdbTbcMoveToPrev(pCur);
|
||||
}
|
||||
|
||||
void *pKey = NULL;
|
||||
void *pVal = NULL;
|
||||
int vLen = 0, kLen = 0;
|
||||
while (1) {
|
||||
int32_t ret = tdbTbcPrev(pCur, &pKey, &kLen, &pVal, &vLen);
|
||||
if (ret < 0) break;
|
||||
|
||||
STbDbKey *tmp = (STbDbKey *)pKey;
|
||||
if (tmp->uid != uid) {
|
||||
continue;
|
||||
}
|
||||
SDecoder dcNew = {0};
|
||||
SMetaEntry meNew = {0};
|
||||
tDecoderInit(&dcNew, pVal, vLen);
|
||||
metaDecodeEntry(&dcNew, &meNew);
|
||||
pSchema = tCloneSSchemaWrapper(&meNew.stbEntry.schemaRow);
|
||||
tDecoderClear(&dcNew);
|
||||
tdbTbcClose(pCur);
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
goto _exit;
|
||||
}
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
tdbTbcClose(pCur);
|
||||
}
|
||||
} else if (me.type == TSDB_CHILD_TABLE) {
|
||||
uid = me.ctbEntry.suid;
|
||||
tDecoderClear(&dc);
|
||||
|
@ -377,7 +341,6 @@ _query:
|
|||
tDecoderClear(&dc);
|
||||
|
||||
_exit:
|
||||
tDecoderClear(&dc);
|
||||
if (lock) {
|
||||
metaULock(pMeta);
|
||||
}
|
||||
|
@ -385,7 +348,6 @@ _exit:
|
|||
return pSchema;
|
||||
|
||||
_err:
|
||||
tDecoderClear(&dc);
|
||||
if (lock) {
|
||||
metaULock(pMeta);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
static int32_t tqInitialize(STQ* pTq);
|
||||
|
||||
static FORCE_INLINE bool tqIsHandleExec(STqHandle* pHandle) { return TMQ_HANDLE_STATUS_EXEC == pHandle->status; }
|
||||
static FORCE_INLINE void tqSetHandleExec(STqHandle* pHandle) {pHandle->status = TMQ_HANDLE_STATUS_EXEC;}
|
||||
static FORCE_INLINE void tqSetHandleIdle(STqHandle* pHandle) {pHandle->status = TMQ_HANDLE_STATUS_IDLE;}
|
||||
static FORCE_INLINE void tqSetHandleExec(STqHandle* pHandle) { pHandle->status = TMQ_HANDLE_STATUS_EXEC; }
|
||||
static FORCE_INLINE void tqSetHandleIdle(STqHandle* pHandle) { pHandle->status = TMQ_HANDLE_STATUS_IDLE; }
|
||||
|
||||
int32_t tqInit() {
|
||||
int8_t old;
|
||||
|
@ -75,8 +75,10 @@ static void destroyTqHandle(void* data) {
|
|||
} else if (pData->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
walCloseReader(pData->pWalReader);
|
||||
tqReaderClose(pData->execHandle.pTqReader);
|
||||
taosMemoryFreeClear(pData->execHandle.execTb.qmsg);
|
||||
nodesDestroyNode(pData->execHandle.execTb.node);
|
||||
}
|
||||
if(pData->msg != NULL) {
|
||||
if (pData->msg != NULL) {
|
||||
rpcFreeCont(pData->msg->pCont);
|
||||
taosMemoryFree(pData->msg);
|
||||
pData->msg = NULL;
|
||||
|
@ -238,14 +240,15 @@ int32_t tqPushDataRsp(STqHandle* pHandle, int32_t vgId) {
|
|||
|
||||
int64_t sver = 0, ever = 0;
|
||||
walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever);
|
||||
tqDoSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP, sver, ever);
|
||||
tqDoSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP, sver,
|
||||
ever);
|
||||
|
||||
char buf1[80] = {0};
|
||||
char buf2[80] = {0};
|
||||
tFormatOffset(buf1, tListLen(buf1), &dataRsp.reqOffset);
|
||||
tFormatOffset(buf2, tListLen(buf2), &dataRsp.rspOffset);
|
||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s",
|
||||
vgId, dataRsp.head.consumerId, dataRsp.head.epoch, dataRsp.blockNum, buf1, buf2);
|
||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s", vgId,
|
||||
dataRsp.head.consumerId, dataRsp.head.epoch, dataRsp.blockNum, buf1, buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -261,8 +264,8 @@ int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq*
|
|||
tFormatOffset(buf1, 80, &pRsp->reqOffset);
|
||||
tFormatOffset(buf2, 80, &pRsp->rspOffset);
|
||||
|
||||
tqDebug("vgId:%d consumer:0x%" PRIx64 " (epoch %d) send rsp, block num:%d, req:%s, rsp:%s, reqId:0x%" PRIx64,
|
||||
vgId, pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId);
|
||||
tqDebug("vgId:%d consumer:0x%" PRIx64 " (epoch %d) send rsp, block num:%d, req:%s, rsp:%s, reqId:0x%" PRIx64, vgId,
|
||||
pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -334,8 +337,7 @@ int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen)
|
|||
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, pOffset->subKey, strlen(pOffset->subKey));
|
||||
if (pHandle == NULL) {
|
||||
tqError("tmq seek: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", vgOffset.consumerId, vgId,
|
||||
pOffset->subKey);
|
||||
tqError("tmq seek: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", vgOffset.consumerId, vgId, pOffset->subKey);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
@ -351,7 +353,7 @@ int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen)
|
|||
}
|
||||
taosRUnLockLatch(&pTq->lock);
|
||||
|
||||
//3. check the offset info
|
||||
// 3. check the offset info
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey);
|
||||
if (pSavedOffset != NULL) {
|
||||
if (pSavedOffset->val.type != TMQ_OFFSET__LOG) {
|
||||
|
@ -379,7 +381,7 @@ int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen)
|
|||
tqDebug("vgId:%d sub:%s seek to:%" PRId64 " prev offset:%" PRId64, vgId, pOffset->subKey, pOffset->val.version,
|
||||
pSavedOffset->val.version);
|
||||
} else {
|
||||
tqDebug("vgId:%d sub:%s seek to:%"PRId64" not saved yet", vgId, pOffset->subKey, pOffset->val.version);
|
||||
tqDebug("vgId:%d sub:%s seek to:%" PRId64 " not saved yet", vgId, pOffset->subKey, pOffset->val.version);
|
||||
}
|
||||
|
||||
if (tqOffsetWrite(pTq->pOffsetStore, pOffset) < 0) {
|
||||
|
@ -421,6 +423,7 @@ int32_t tqCheckColModifiable(STQ* pTq, int64_t tbUid, int32_t colId) {
|
|||
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SMqPollReq req = {0};
|
||||
int code = 0;
|
||||
if (tDeserializeSMqPollReq(pMsg->pCont, pMsg->contLen, &req) < 0) {
|
||||
tqError("tDeserializeSMqPollReq %d failed", pMsg->contLen);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -431,37 +434,49 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
int32_t reqEpoch = req.epoch;
|
||||
STqOffsetVal reqOffset = req.reqOffset;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
STqHandle* pHandle = NULL;
|
||||
|
||||
taosWLockLatch(&pTq->lock);
|
||||
// 1. find handle
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey));
|
||||
if (pHandle == NULL) {
|
||||
tqError("tmq poll: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", consumerId, vgId, req.subKey);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
while (1) {
|
||||
taosWLockLatch(&pTq->lock);
|
||||
// 1. find handle
|
||||
pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey));
|
||||
if (pHandle == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 2. check re-balance status
|
||||
if (pHandle->consumerId != consumerId) {
|
||||
tqError("ERROR tmq poll: consumer:0x%" PRIx64
|
||||
" vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64,
|
||||
consumerId, TD_VID(pTq->pVnode), req.subKey, pHandle->consumerId);
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool exec = tqIsHandleExec(pHandle);
|
||||
if (!exec) {
|
||||
tqSetHandleExec(pHandle);
|
||||
// qSetTaskCode(pHandle->execHandle.task, TDB_CODE_SUCCESS);
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 "vgId:%d, topic:%s, set handle exec, pHandle:%p", consumerId, vgId,
|
||||
req.subKey, pHandle);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
break;
|
||||
}
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (tqIsHandleExec(pHandle)) {
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 "vgId:%d, topic:%s, subscription is executing, wait for 5ms and retry", consumerId, vgId, req.subKey);
|
||||
taosMsleep(5);
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64
|
||||
"vgId:%d, topic:%s, subscription is executing, wait for 10ms and retry, pHandle:%p",
|
||||
consumerId, vgId, req.subKey, pHandle);
|
||||
taosMsleep(10);
|
||||
}
|
||||
|
||||
// 2. check re-balance status
|
||||
if (pHandle->consumerId != consumerId) {
|
||||
tqDebug("ERROR tmq poll: consumer:0x%" PRIx64 " vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64,
|
||||
consumerId, vgId, req.subKey, pHandle->consumerId);
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
}
|
||||
tqSetHandleExec(pHandle);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
|
||||
// 3. update the epoch value
|
||||
int32_t savedEpoch = pHandle->epoch;
|
||||
if (savedEpoch < reqEpoch) {
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 " epoch update from %d to %d by poll req", consumerId, savedEpoch,
|
||||
if (pHandle->epoch < reqEpoch) {
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 " epoch update from %d to %d by poll req", consumerId, pHandle->epoch,
|
||||
reqEpoch);
|
||||
pHandle->epoch = reqEpoch;
|
||||
}
|
||||
|
@ -471,8 +486,11 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqDebug("tmq poll: consumer:0x%" PRIx64 " (epoch %d), subkey %s, recv poll req vgId:%d, req:%s, reqId:0x%" PRIx64,
|
||||
consumerId, req.epoch, pHandle->subKey, vgId, buf, req.reqId);
|
||||
|
||||
int code = tqExtractDataForMq(pTq, pHandle, &req, pMsg);
|
||||
code = tqExtractDataForMq(pTq, pHandle, &req, pMsg);
|
||||
tqSetHandleIdle(pHandle);
|
||||
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 "vgId:%d, topic:%s, , set handle idle, pHandle:%p", consumerId, vgId,
|
||||
req.subKey, pHandle);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -536,7 +554,7 @@ int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
if (reqOffset.type == TMQ_OFFSET__LOG) {
|
||||
int64_t currentVer = walReaderGetCurrentVer(pHandle->execHandle.pTqReader->pWalReader);
|
||||
if (currentVer == -1) { // not start to read data from wal yet, return req offset directly
|
||||
if (currentVer == -1) { // not start to read data from wal yet, return req offset directly
|
||||
dataRsp.rspOffset.version = reqOffset.version;
|
||||
} else {
|
||||
dataRsp.rspOffset.version = currentVer; // return current consume offset value
|
||||
|
@ -560,7 +578,7 @@ int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
tqDebug("vgId:%d, tq process delete sub req %s", vgId, pReq->subKey);
|
||||
int32_t code = 0;
|
||||
|
@ -569,8 +587,9 @@ int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
STqHandle* pHandle = taosHashGet(pTq->pHandle, pReq->subKey, strlen(pReq->subKey));
|
||||
if (pHandle) {
|
||||
while (tqIsHandleExec(pHandle)) {
|
||||
tqDebug("vgId:%d, topic:%s, subscription is executing, wait for 5ms and retry", vgId, pHandle->subKey);
|
||||
taosMsleep(5);
|
||||
tqDebug("vgId:%d, topic:%s, subscription is executing, wait for 10ms and retry, pHandle:%p", vgId,
|
||||
pHandle->subKey, pHandle);
|
||||
taosMsleep(10);
|
||||
}
|
||||
|
||||
if (pHandle->pRef) {
|
||||
|
@ -629,9 +648,18 @@ int32_t tqProcessDelCheckInfoReq(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
}
|
||||
|
||||
int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
SMqRebVgReq req = {0};
|
||||
tDecodeSMqRebVgReq(msg, &req);
|
||||
SDecoder dc = {0};
|
||||
|
||||
tDecoderInit(&dc, msg, msgLen);
|
||||
|
||||
// decode req
|
||||
if (tDecodeSMqRebVgReq(&dc, &req) < 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
tDecoderClear(&dc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SVnode* pVnode = pTq->pVnode;
|
||||
int32_t vgId = TD_VID(pVnode);
|
||||
|
@ -639,7 +667,6 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
tqDebug("vgId:%d, tq process sub req:%s, Id:0x%" PRIx64 " -> Id:0x%" PRIx64, pVnode->config.vgId, req.subKey,
|
||||
req.oldConsumerId, req.newConsumerId);
|
||||
|
||||
taosWLockLatch(&pTq->lock);
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey));
|
||||
if (pHandle == NULL) {
|
||||
if (req.oldConsumerId != -1) {
|
||||
|
@ -655,7 +682,6 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
STqHandle tqHandle = {0};
|
||||
pHandle = &tqHandle;
|
||||
|
||||
uint64_t oldConsumerId = pHandle->consumerId;
|
||||
memcpy(pHandle->subKey, req.subKey, TSDB_SUBSCRIBE_KEY_LEN);
|
||||
pHandle->consumerId = req.newConsumerId;
|
||||
pHandle->epoch = -1;
|
||||
|
@ -679,8 +705,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
pHandle->snapshotVer = ver;
|
||||
|
||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
pHandle->execHandle.execCol.qmsg = req.qmsg;
|
||||
req.qmsg = NULL;
|
||||
pHandle->execHandle.execCol.qmsg = taosStrdup(req.qmsg);
|
||||
|
||||
pHandle->execHandle.task = qCreateQueueExecTaskInfo(pHandle->execHandle.execCol.qmsg, &handle, vgId,
|
||||
&pHandle->execHandle.numOfCols, req.newConsumerId);
|
||||
|
@ -700,67 +725,75 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
} else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
pHandle->pWalReader = walOpenReader(pVnode->pWal, NULL);
|
||||
pHandle->execHandle.execTb.suid = req.suid;
|
||||
pHandle->execHandle.execTb.qmsg = taosStrdup(req.qmsg);
|
||||
|
||||
SArray* tbUidList = taosArrayInit(0, sizeof(int64_t));
|
||||
vnodeGetCtbIdList(pVnode, req.suid, tbUidList);
|
||||
tqDebug("vgId:%d, tq try to get all ctb, suid:%" PRId64, pVnode->config.vgId, req.suid);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(tbUidList); i++) {
|
||||
int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
|
||||
tqDebug("vgId:%d, idx %d, uid:%" PRId64, vgId, i, tbUid);
|
||||
if (strcmp(pHandle->execHandle.execTb.qmsg, "") != 0) {
|
||||
if (nodesStringToNode(pHandle->execHandle.execTb.qmsg, &pHandle->execHandle.execTb.node) != 0) {
|
||||
tqError("nodesStringToNode error in sub stable, since %s, vgId:%d, subkey:%s consumer:0x%" PRIx64, terrstr(),
|
||||
pVnode->config.vgId, req.subKey, pHandle->consumerId);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
pHandle->execHandle.pTqReader = tqReaderOpen(pVnode);
|
||||
tqReaderSetTbUidList(pHandle->execHandle.pTqReader, tbUidList);
|
||||
taosArrayDestroy(tbUidList);
|
||||
|
||||
buildSnapContext(handle.vnode, handle.version, req.suid, pHandle->execHandle.subType, pHandle->fetchMeta,
|
||||
(SSnapContext**)(&handle.sContext));
|
||||
pHandle->execHandle.task = qCreateQueueExecTaskInfo(NULL, &handle, vgId, NULL, req.newConsumerId);
|
||||
|
||||
SArray* tbUidList = NULL;
|
||||
ret = qGetTableList(req.suid, pVnode, pHandle->execHandle.execTb.node, &tbUidList, pHandle->execHandle.task);
|
||||
if (ret != TDB_CODE_SUCCESS) {
|
||||
tqError("qGetTableList error:%d vgId:%d, subkey:%s consumer:0x%" PRIx64, ret, pVnode->config.vgId, req.subKey,
|
||||
pHandle->consumerId);
|
||||
taosArrayDestroy(tbUidList);
|
||||
goto end;
|
||||
}
|
||||
tqDebug("tq try to get ctb for stb subscribe, vgId:%d, subkey:%s consumer:0x%" PRIx64 " suid:%" PRId64,
|
||||
pVnode->config.vgId, req.subKey, pHandle->consumerId, req.suid);
|
||||
pHandle->execHandle.pTqReader = tqReaderOpen(pVnode);
|
||||
tqReaderSetTbUidList(pHandle->execHandle.pTqReader, tbUidList, NULL);
|
||||
taosArrayDestroy(tbUidList);
|
||||
}
|
||||
|
||||
taosHashPut(pTq->pHandle, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle));
|
||||
tqDebug("try to persist handle %s consumer:0x%" PRIx64 " , old consumer:0x%" PRIx64, req.subKey,
|
||||
pHandle->consumerId, oldConsumerId);
|
||||
tqDebug("try to persist handle %s consumer:0x%" PRIx64, req.subKey, pHandle->consumerId);
|
||||
ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
||||
goto end;
|
||||
} else {
|
||||
while (tqIsHandleExec(pHandle)) {
|
||||
tqDebug("sub req vgId:%d, topic:%s, subscription is executing, wait for 5ms and retry", vgId, pHandle->subKey);
|
||||
taosMsleep(5);
|
||||
}
|
||||
taosWLockLatch(&pTq->lock);
|
||||
|
||||
if (pHandle->consumerId == req.newConsumerId) { // do nothing
|
||||
tqInfo("vgId:%d consumer:0x%" PRIx64 " remains, no switch occurs", req.vgId, req.newConsumerId);
|
||||
atomic_add_fetch_32(&pHandle->epoch, 1);
|
||||
|
||||
tqInfo("vgId:%d consumer:0x%" PRIx64 " remains, no switch occurs, should not reach here", req.vgId,
|
||||
req.newConsumerId);
|
||||
} else {
|
||||
tqInfo("vgId:%d switch consumer from Id:0x%" PRIx64 " to Id:0x%" PRIx64, req.vgId, pHandle->consumerId,
|
||||
req.newConsumerId);
|
||||
atomic_store_64(&pHandle->consumerId, req.newConsumerId);
|
||||
atomic_store_32(&pHandle->epoch, 0);
|
||||
}
|
||||
// atomic_add_fetch_32(&pHandle->epoch, 1);
|
||||
|
||||
// kill executing task
|
||||
qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
|
||||
if (pTaskInfo != NULL) {
|
||||
qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
|
||||
}
|
||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
qStreamCloseTsdbReader(pTaskInfo);
|
||||
}
|
||||
// if(tqIsHandleExec(pHandle)) {
|
||||
// qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
|
||||
// if (pTaskInfo != NULL) {
|
||||
// qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
|
||||
// }
|
||||
|
||||
// if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
// qStreamCloseTsdbReader(pTaskInfo);
|
||||
// }
|
||||
// }
|
||||
// remove if it has been register in the push manager, and return one empty block to consumer
|
||||
tqUnregisterPushHandle(pTq, pHandle);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
taosMemoryFree(req.qmsg);
|
||||
tDecoderClear(&dc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void freePtr(void *ptr) {
|
||||
taosMemoryFree(*(void**)ptr);
|
||||
}
|
||||
void freePtr(void* ptr) { taosMemoryFree(*(void**)ptr); }
|
||||
|
||||
int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
@ -783,7 +816,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
|||
pTask->chkInfo.currentVer = ver;
|
||||
|
||||
// expand executor
|
||||
pTask->status.taskStatus = (pTask->fillHistory)? TASK_STATUS__WAIT_DOWNSTREAM:TASK_STATUS__NORMAL;
|
||||
pTask->status.taskStatus = (pTask->fillHistory) ? TASK_STATUS__WAIT_DOWNSTREAM : TASK_STATUS__NORMAL;
|
||||
|
||||
if (pTask->taskLevel == TASK_LEVEL__SOURCE) {
|
||||
pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pTask, false, -1, -1);
|
||||
|
@ -849,8 +882,8 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
|||
|
||||
streamSetupTrigger(pTask);
|
||||
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId, pTask->id.idStr,
|
||||
pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel);
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId,
|
||||
pTask->id.idStr, pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel);
|
||||
|
||||
// next valid version will add one
|
||||
pTask->chkInfo.version += 1;
|
||||
|
@ -963,7 +996,8 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms
|
|||
SStreamTask* pTask = taosMemoryCalloc(1, sizeof(SStreamTask));
|
||||
if (pTask == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("vgId:%d failed to create stream task due to out of memory, alloc size:%d", vgId, (int32_t) sizeof(SStreamTask));
|
||||
tqError("vgId:%d failed to create stream task due to out of memory, alloc size:%d", vgId,
|
||||
(int32_t)sizeof(SStreamTask));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1115,7 @@ int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
|
||||
// do recovery step 2
|
||||
int64_t st = taosGetTimestampMs();
|
||||
tqDebug("s-task:%s start step2 recover, ts:%"PRId64, pTask->id.idStr, st);
|
||||
tqDebug("s-task:%s start step2 recover, ts:%" PRId64, pTask->id.idStr, st);
|
||||
|
||||
code = streamSourceRecoverScanStep2(pTask, sversion);
|
||||
if (code < 0) {
|
||||
|
@ -1089,7 +1123,8 @@ int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
qDebug("s-task:%s set the start wal offset to be:%"PRId64, pTask->id.idStr, sversion);
|
||||
qDebug("s-task:%s set start wal scan start ver:%"PRId64, pTask->id.idStr, sversion);
|
||||
|
||||
walReaderSeekVer(pTask->exec.pWalReader, sversion);
|
||||
pTask->chkInfo.currentVer = sversion;
|
||||
|
||||
|
@ -1113,7 +1148,7 @@ int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
double el = (taosGetTimestampMs() - st)/ 1000.0;
|
||||
double el = (taosGetTimestampMs() - st) / 1000.0;
|
||||
tqDebug("s-task:%s step2 recover finished, el:%.2fs", pTask->id.idStr, el);
|
||||
|
||||
// dispatch recover finish req to all related downstream task
|
||||
|
@ -1229,8 +1264,8 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
||||
if (pTask != NULL) {
|
||||
if (pTask->status.taskStatus == TASK_STATUS__NORMAL) {
|
||||
tqDebug("vgId:%d s-task:%s start to process block from wal, last chk point:%" PRId64, vgId,
|
||||
pTask->id.idStr, pTask->chkInfo.version);
|
||||
tqDebug("vgId:%d s-task:%s start to process block from wal, last chk point:%" PRId64, vgId, pTask->id.idStr,
|
||||
pTask->chkInfo.version);
|
||||
streamProcessRunReq(pTask);
|
||||
} else {
|
||||
if (streamTaskShouldPause(&pTask->status)) {
|
||||
|
@ -1249,9 +1284,9 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
}
|
||||
|
||||
int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg, bool exec) {
|
||||
char* msgStr = pMsg->pCont;
|
||||
char* msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead));
|
||||
int32_t msgLen = pMsg->contLen - sizeof(SMsgHead);
|
||||
char* msgStr = pMsg->pCont;
|
||||
char* msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead));
|
||||
int32_t msgLen = pMsg->contLen - sizeof(SMsgHead);
|
||||
|
||||
SStreamDispatchReq req = {0};
|
||||
|
||||
|
@ -1275,13 +1310,15 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg) {
|
|||
SStreamDispatchRsp* pRsp = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t taskId = ntohl(pRsp->upstreamTaskId);
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
||||
tqDebug("recv dispatch rsp, code:%x", pMsg->code);
|
||||
|
||||
int32_t vgId = pTq->pStreamMeta->vgId;
|
||||
if (pTask) {
|
||||
streamProcessDispatchRsp(pTask, pRsp, pMsg->code);
|
||||
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
tqDebug("vgId:%d failed to handle the dispatch rsp, since find task:0x%x failed", vgId, taskId);
|
||||
return TSDB_CODE_INVALID_MSG;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1295,7 +1332,7 @@ int32_t tqProcessTaskDropReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgL
|
|||
|
||||
int32_t tqProcessTaskPauseReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)msg;
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId);
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId);
|
||||
if (pTask) {
|
||||
tqDebug("vgId:%d s-task:%s set pause flag", pTq->pStreamMeta->vgId, pTask->id.idStr);
|
||||
atomic_store_8(&pTask->status.keepTaskStatus, pTask->status.taskStatus);
|
||||
|
|
|
@ -37,6 +37,9 @@ int32_t tEncodeSTqHandle(SEncoder* pEncoder, const STqHandle* pHandle) {
|
|||
}
|
||||
} else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
if (tEncodeI64(pEncoder, pHandle->execHandle.execTb.suid) < 0) return -1;
|
||||
if (pHandle->execHandle.execTb.qmsg != NULL){
|
||||
if (tEncodeCStr(pEncoder, pHandle->execHandle.execTb.qmsg) < 0) return -1;
|
||||
}
|
||||
}
|
||||
tEndEncode(pEncoder);
|
||||
return pEncoder->pos;
|
||||
|
@ -64,6 +67,9 @@ int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle) {
|
|||
}
|
||||
} else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
if (tDecodeI64(pDecoder, &pHandle->execHandle.execTb.suid) < 0) return -1;
|
||||
if (!tDecodeIsEnd(pDecoder)){
|
||||
if (tDecodeCStrAlloc(pDecoder, &pHandle->execHandle.execTb.qmsg) < 0) return -1;
|
||||
}
|
||||
}
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
|
@ -337,25 +343,30 @@ int32_t tqMetaRestoreHandle(STQ* pTq) {
|
|||
} else if (handle.execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
handle.pWalReader = walOpenReader(pTq->pVnode->pWal, NULL);
|
||||
|
||||
SArray* tbUidList = taosArrayInit(0, sizeof(int64_t));
|
||||
vnodeGetCtbIdList(pTq->pVnode, handle.execHandle.execTb.suid, tbUidList);
|
||||
tqDebug("vgId:%d, tq try to get all ctb, suid:%" PRId64, pTq->pVnode->config.vgId, handle.execHandle.execTb.suid);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(tbUidList); i++) {
|
||||
int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
|
||||
tqDebug("vgId:%d, idx %d, uid:%" PRId64, vgId, i, tbUid);
|
||||
if(handle.execHandle.execTb.qmsg != NULL && strcmp(handle.execHandle.execTb.qmsg, "") != 0) {
|
||||
if (nodesStringToNode(handle.execHandle.execTb.qmsg, &handle.execHandle.execTb.node) != 0) {
|
||||
tqError("nodesStringToNode error in sub stable, since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
handle.execHandle.pTqReader = tqReaderOpen(pTq->pVnode);
|
||||
tqReaderSetTbUidList(handle.execHandle.pTqReader, tbUidList);
|
||||
taosArrayDestroy(tbUidList);
|
||||
|
||||
buildSnapContext(reader.vnode, reader.version, handle.execHandle.execTb.suid, handle.execHandle.subType,
|
||||
handle.fetchMeta, (SSnapContext**)(&reader.sContext));
|
||||
handle.execHandle.task = qCreateQueueExecTaskInfo(NULL, &reader, vgId, NULL, 0);
|
||||
|
||||
SArray* tbUidList = NULL;
|
||||
int ret = qGetTableList(handle.execHandle.execTb.suid, pTq->pVnode, handle.execHandle.execTb.node, &tbUidList, handle.execHandle.task);
|
||||
if(ret != TDB_CODE_SUCCESS) {
|
||||
tqError("qGetTableList error:%d handle %s consumer:0x%" PRIx64, ret, handle.subKey, handle.consumerId);
|
||||
taosArrayDestroy(tbUidList);
|
||||
goto end;
|
||||
}
|
||||
tqDebug("vgId:%d, tq try to get ctb for stb subscribe, suid:%" PRId64, pTq->pVnode->config.vgId, handle.execHandle.execTb.suid);
|
||||
handle.execHandle.pTqReader = tqReaderOpen(pTq->pVnode);
|
||||
tqReaderSetTbUidList(handle.execHandle.pTqReader, tbUidList, NULL);
|
||||
taosArrayDestroy(tbUidList);
|
||||
}
|
||||
tqDebug("tq restore %s consumer %" PRId64 " vgId:%d", handle.subKey, handle.consumerId, vgId);
|
||||
taosWLockLatch(&pTq->lock);
|
||||
taosHashPut(pTq->pHandle, pKey, kLen, &handle, sizeof(STqHandle));
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
}
|
||||
|
||||
end:
|
||||
|
|
|
@ -78,7 +78,6 @@ int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname) {
|
|||
|
||||
// todo remove this
|
||||
if (offset.val.type == TMQ_OFFSET__LOG) {
|
||||
taosWLockLatch(&pStore->pTq->lock);
|
||||
STqHandle* pHandle = taosHashGet(pStore->pTq->pHandle, offset.subKey, strlen(offset.subKey));
|
||||
if (pHandle) {
|
||||
if (walSetRefVer(pHandle->pRef, offset.val.version) < 0) {
|
||||
|
@ -86,7 +85,6 @@ int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname) {
|
|||
// offset.val.version);
|
||||
}
|
||||
}
|
||||
taosWUnLockLatch(&pStore->pTq->lock);
|
||||
}
|
||||
|
||||
taosMemoryFree(pMemBuf);
|
||||
|
|
|
@ -101,8 +101,11 @@ int32_t tqUnregisterPushHandle(STQ* pTq, void *handle) {
|
|||
STqHandle *pHandle = (STqHandle*)handle;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
if(taosHashGetSize(pTq->pPushMgr) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
int32_t ret = taosHashRemove(pTq->pPushMgr, pHandle->subKey, strlen(pHandle->subKey));
|
||||
tqError("vgId:%d remove pHandle:%p,ret:%d consumer Id:0x%" PRIx64, vgId, pHandle, ret, pHandle->consumerId);
|
||||
tqDebug("vgId:%d remove pHandle:%p,ret:%d consumer Id:0x%" PRIx64, vgId, pHandle, ret, pHandle->consumerId);
|
||||
|
||||
if(pHandle->msg != NULL) {
|
||||
tqPushDataRsp(pHandle, vgId);
|
||||
|
|
|
@ -394,8 +394,8 @@ bool tqNextBlockInWal(STqReader* pReader, const char* id) {
|
|||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
||||
|
||||
if (pReader->tbIdHash == NULL) {
|
||||
SSDataBlock* pRes = NULL;
|
||||
int32_t code = tqRetrieveDataBlock(pReader, &pRes, NULL);
|
||||
SSDataBlock* pRes = NULL;
|
||||
int32_t code = tqRetrieveDataBlock(pReader, &pRes, NULL);
|
||||
if (code == TSDB_CODE_SUCCESS && pRes->info.rows > 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ bool tqNextBlockImpl(STqReader* pReader, const char* idstr) {
|
|||
|
||||
int32_t numOfBlocks = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
||||
while (pReader->nextBlk < numOfBlocks) {
|
||||
tqDebug("tq reader next data block, len:%d ver:%" PRId64 " index:%d/%d, %s", pReader->msg.msgLen, pReader->msg.ver,
|
||||
tqDebug("try next data block, len:%d ver:%" PRId64 " index:%d/%d, %s", pReader->msg.msgLen, pReader->msg.ver,
|
||||
pReader->nextBlk, numOfBlocks, idstr);
|
||||
|
||||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
||||
|
@ -467,10 +467,11 @@ bool tqNextBlockImpl(STqReader* pReader, const char* idstr) {
|
|||
|
||||
void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
|
||||
if (ret != NULL) {
|
||||
tqDebug("tq reader block found, ver:%" PRId64 ", uid:%" PRId64, pReader->msg.ver, pSubmitTbData->uid);
|
||||
tqDebug("block found, ver:%" PRId64 ", uid:%" PRId64", %s", pReader->msg.ver, pSubmitTbData->uid, idstr);
|
||||
return true;
|
||||
} else {
|
||||
tqDebug("tq reader discard submit block, uid:%" PRId64 ", continue", pSubmitTbData->uid);
|
||||
tqDebug("discard submit block, uid:%" PRId64 ", total queried tables:%d continue %s", pSubmitTbData->uid,
|
||||
taosHashGetSize(pReader->tbIdHash), idstr);
|
||||
}
|
||||
|
||||
pReader->nextBlk++;
|
||||
|
@ -604,7 +605,6 @@ static int32_t doSetVal(SColumnInfoData* pColumnInfoData, int32_t rowIndex, SCol
|
|||
|
||||
int32_t tqRetrieveDataBlock(STqReader* pReader, SSDataBlock** pRes, const char* id) {
|
||||
tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg.msgStr, pReader->nextBlk);
|
||||
|
||||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk++);
|
||||
|
||||
SSDataBlock* pBlock = pReader->pResBlock;
|
||||
|
@ -612,6 +612,7 @@ int32_t tqRetrieveDataBlock(STqReader* pReader, SSDataBlock** pRes, const char*
|
|||
|
||||
blockDataCleanup(pBlock);
|
||||
|
||||
int32_t vgId = pReader->pWalReader->pWal->cfg.vgId;
|
||||
int32_t sversion = pSubmitTbData->sver;
|
||||
int64_t suid = pSubmitTbData->suid;
|
||||
int64_t uid = pSubmitTbData->uid;
|
||||
|
@ -628,7 +629,7 @@ int32_t tqRetrieveDataBlock(STqReader* pReader, SSDataBlock** pRes, const char*
|
|||
if (pReader->pSchemaWrapper == NULL) {
|
||||
tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", uid:%" PRId64
|
||||
"version %d, possibly dropped table",
|
||||
pReader->pWalReader->pWal->cfg.vgId, suid, uid, pReader->cachedSchemaVer);
|
||||
vgId, suid, uid, pReader->cachedSchemaVer);
|
||||
pReader->cachedSchemaSuid = 0;
|
||||
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
|
||||
return -1;
|
||||
|
@ -642,6 +643,7 @@ int32_t tqRetrieveDataBlock(STqReader* pReader, SSDataBlock** pRes, const char*
|
|||
if (blockDataGetNumOfCols(pBlock) == 0) {
|
||||
int32_t code = buildResSDataBlock(pReader->pResBlock, pReader->pSchemaWrapper, pReader->pColIdList);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tqError("vgId:%d failed to build data block, code:%s", vgId, tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
@ -998,7 +1000,7 @@ FAIL:
|
|||
|
||||
void tqReaderSetColIdList(STqReader* pReader, SArray* pColIdList) { pReader->pColIdList = pColIdList; }
|
||||
|
||||
int tqReaderSetTbUidList(STqReader* pReader, const SArray* tbUidList) {
|
||||
int tqReaderSetTbUidList(STqReader* pReader, const SArray* tbUidList, const char* id) {
|
||||
if (pReader->tbIdHash) {
|
||||
taosHashClear(pReader->tbIdHash);
|
||||
} else {
|
||||
|
@ -1015,6 +1017,7 @@ int tqReaderSetTbUidList(STqReader* pReader, const SArray* tbUidList) {
|
|||
taosHashPut(pReader->tbIdHash, pKey, sizeof(int64_t), NULL, 0);
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s %d tables are set to be queried target table", id, (int32_t) taosArrayGetSize(tbUidList));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1059,7 +1062,6 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
|
|||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
// update the table list for each consumer handle
|
||||
taosWLockLatch(&pTq->lock);
|
||||
while (1) {
|
||||
pIter = taosHashIterate(pTq->pHandle, pIter);
|
||||
if (pIter == NULL) {
|
||||
|
@ -1083,40 +1085,20 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
|
|||
}
|
||||
} else if (pTqHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
if (isAdd) {
|
||||
SArray* qa = taosArrayInit(4, sizeof(tb_uid_t));
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pTq->pVnode->pMeta, 0);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(tbUidList); ++i) {
|
||||
uint64_t* id = (uint64_t*)taosArrayGet(tbUidList, i);
|
||||
|
||||
int32_t code = metaReaderGetTableEntryByUidCache(&mr, *id);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tqError("failed to get table meta, uid:%" PRIu64 " code:%s", *id, tstrerror(terrno));
|
||||
continue;
|
||||
}
|
||||
|
||||
tDecoderClear(&mr.coder);
|
||||
if (mr.me.type != TSDB_CHILD_TABLE || mr.me.ctbEntry.suid != pTqHandle->execHandle.execTb.suid) {
|
||||
tqDebug("table uid %" PRId64 " does not add to tq handle", *id);
|
||||
continue;
|
||||
}
|
||||
|
||||
tqDebug("table uid %" PRId64 " add to tq handle", *id);
|
||||
taosArrayPush(qa, id);
|
||||
SArray* list = NULL;
|
||||
int ret = qGetTableList(pTqHandle->execHandle.execTb.suid, pTq->pVnode, pTqHandle->execHandle.execTb.node, &list, pTqHandle->execHandle.task);
|
||||
if(ret != TDB_CODE_SUCCESS) {
|
||||
tqError("qGetTableList in tqUpdateTbUidList error:%d handle %s consumer:0x%" PRIx64, ret, pTqHandle->subKey, pTqHandle->consumerId);
|
||||
taosArrayDestroy(list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
metaReaderClear(&mr);
|
||||
if (taosArrayGetSize(qa) > 0) {
|
||||
tqReaderAddTbUidList(pTqHandle->execHandle.pTqReader, qa);
|
||||
}
|
||||
|
||||
taosArrayDestroy(qa);
|
||||
tqReaderSetTbUidList(pTqHandle->execHandle.pTqReader, list, NULL);
|
||||
taosArrayDestroy(list);
|
||||
} else {
|
||||
tqReaderRemoveTbUidList(pTqHandle->execHandle.pTqReader, tbUidList);
|
||||
}
|
||||
}
|
||||
}
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
|
||||
// update the table list handle for each stream scanner/wal reader
|
||||
taosWLockLatch(&pTq->pStreamMeta->lock);
|
||||
|
|
|
@ -84,8 +84,10 @@ int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffs
|
|||
qStreamSetOpen(task);
|
||||
|
||||
tqDebug("consumer:0x%" PRIx64 " vgId:%d, tmq one task start execute", pHandle->consumerId, vgId);
|
||||
if (qExecTask(task, &pDataBlock, &ts) != TSDB_CODE_SUCCESS) {
|
||||
tqError("consumer:0x%" PRIx64 " vgId:%d, task exec error since %s", pHandle->consumerId, vgId, terrstr());
|
||||
code = qExecTask(task, &pDataBlock, &ts);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tqError("consumer:0x%" PRIx64 " vgId:%d, task exec error since %s", pHandle->consumerId, vgId, tstrerror(code));
|
||||
terrno = code;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -128,8 +130,10 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMeta
|
|||
SSDataBlock* pDataBlock = NULL;
|
||||
uint64_t ts = 0;
|
||||
tqDebug("tmqsnap task start to execute");
|
||||
if (qExecTask(task, &pDataBlock, &ts) < 0) {
|
||||
tqError("vgId:%d, task exec error since %s", pTq->pVnode->config.vgId, terrstr());
|
||||
int code = qExecTask(task, &pDataBlock, &ts);
|
||||
if (code != 0) {
|
||||
tqError("vgId:%d, task exec error since %s", pTq->pVnode->config.vgId, tstrerror(code));
|
||||
terrno = code;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d
|
|||
|
||||
int32_t blockSz = taosArrayGetSize(pBlocks);
|
||||
|
||||
tqDebug("vgId:%d, s-task:%s write results blocks:%d into table", TD_VID(pVnode), pTask->id.idStr, blockSz);
|
||||
tqDebug("vgId:%d, s-task:%s write results %d blocks into table", TD_VID(pVnode), pTask->id.idStr, blockSz);
|
||||
|
||||
void* pBuf = NULL;
|
||||
SArray* tagArray = NULL;
|
||||
|
@ -294,6 +294,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d
|
|||
|
||||
char* ctbName = pDataBlock->info.parTbName;
|
||||
if (!ctbName[0]) {
|
||||
memset(ctbName, 0, TSDB_TABLE_NAME_LEN);
|
||||
if (res == TSDB_CODE_SUCCESS) {
|
||||
memcpy(ctbName, pTableSinkInfo->tbName, strlen(pTableSinkInfo->tbName));
|
||||
} else {
|
||||
|
@ -482,17 +483,15 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d
|
|||
tEncoderClear(&encoder);
|
||||
tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
||||
|
||||
SRpcMsg msg = {
|
||||
.msgType = TDMT_VND_SUBMIT,
|
||||
.pCont = pBuf,
|
||||
.contLen = len,
|
||||
};
|
||||
|
||||
SRpcMsg msg = { .msgType = TDMT_VND_SUBMIT, .pCont = pBuf, .contLen = len };
|
||||
if (tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) != 0) {
|
||||
tqDebug("failed to put into write-queue since %s", terrstr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d, s-task:%s write results completed", TD_VID(pVnode), pTask->id.idStr);
|
||||
|
||||
_end:
|
||||
taosArrayDestroy(tagArray);
|
||||
taosArrayDestroy(pVals);
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
#include "tq.h"
|
||||
|
||||
#define IS_OFFSET_RESET_TYPE(_t) ((_t) < 0)
|
||||
#define NO_POLL_CNT 5
|
||||
#define IS_OFFSET_RESET_TYPE(_t) ((_t) < 0)
|
||||
|
||||
static int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq,
|
||||
const SMqMetaRsp* pRsp, int32_t vgId);
|
||||
|
@ -89,15 +88,13 @@ static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, const SMqPollReq* pReq) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest,
|
||||
SRpcMsg* pMsg, bool* pBlockReturned) {
|
||||
static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, bool* pBlockReturned) {
|
||||
uint64_t consumerId = pRequest->consumerId;
|
||||
STqOffsetVal reqOffset = pRequest->reqOffset;
|
||||
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, pRequest->subKey);
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
*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;
|
||||
|
@ -121,21 +118,16 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
tqOffsetResetToData(pOffsetVal, 0, 0);
|
||||
}
|
||||
} else {
|
||||
pHandle->pRef = walRefFirstVer(pTq->pVnode->pWal, pHandle->pRef);
|
||||
if (pHandle->pRef == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// offset set to previous version when init
|
||||
walRefFirstVer(pTq->pVnode->pWal, pHandle->pRef);
|
||||
tqOffsetResetToLog(pOffsetVal, pHandle->pRef->refVer - 1);
|
||||
}
|
||||
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
||||
walRefLastVer(pTq->pVnode->pWal, pHandle->pRef);
|
||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
SMqDataRsp dataRsp = {0};
|
||||
tqInitDataRsp(&dataRsp, pRequest);
|
||||
|
||||
tqOffsetResetToLog(&dataRsp.rspOffset, walGetLastVer(pTq->pVnode->pWal));
|
||||
tqOffsetResetToLog(&dataRsp.rspOffset, pHandle->pRef->refVer);
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, (latest) offset reset to %" PRId64, consumerId,
|
||||
pHandle->subKey, vgId, dataRsp.rspOffset.version);
|
||||
int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId);
|
||||
|
@ -146,7 +138,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
} else {
|
||||
STaosxRsp taosxRsp = {0};
|
||||
tqInitTaosxRsp(&taosxRsp, pRequest);
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, walGetLastVer(pTq->pVnode->pWal));
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, pHandle->pRef->refVer);
|
||||
int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
|
||||
|
@ -176,24 +168,18 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
|
||||
qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId);
|
||||
code = tqScanData(pTq, pHandle, &dataRsp, pOffset);
|
||||
if (code != 0) {
|
||||
if(code != 0 && terrno != TSDB_CODE_WAL_LOG_NOT_EXIST) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
// till now, all data has been transferred to consumer, new data needs to push client once arrived.
|
||||
if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG &&
|
||||
dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) {
|
||||
if (pHandle->noDataPollCnt >= NO_POLL_CNT) { // send poll result to client if no data 5 times to avoid lost data
|
||||
pHandle->noDataPollCnt = 0;
|
||||
// lock
|
||||
taosWLockLatch(&pTq->lock);
|
||||
code = tqRegisterPushHandle(pTq, pHandle, pMsg);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
return code;
|
||||
} else {
|
||||
pHandle->noDataPollCnt++;
|
||||
}
|
||||
if (terrno == TSDB_CODE_WAL_LOG_NOT_EXIST && dataRsp.blockNum == 0) {
|
||||
// lock
|
||||
taosWLockLatch(&pTq->lock);
|
||||
code = tqRegisterPushHandle(pTq, pHandle, pMsg);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
return code;
|
||||
}
|
||||
|
||||
// NOTE: this pHandle->consumerId may have been changed already.
|
||||
|
|
|
@ -1454,7 +1454,7 @@ static int32_t getTableDelDataFromDelIdx(SDelFReader *pDelReader, SDelIdx *pDelI
|
|||
int32_t code = 0;
|
||||
|
||||
if (pDelIdx) {
|
||||
code = tsdbReadDelData(pDelReader, pDelIdx, aDelData);
|
||||
code = tsdbReadDelDatav1(pDelReader, pDelIdx, aDelData, INT64_MAX);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
|
|
@ -201,6 +201,9 @@ int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList,
|
|||
|
||||
void* tsdbCacherowsReaderClose(void* pReader) {
|
||||
SCacheRowsReader* p = pReader;
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p->pSchema != NULL) {
|
||||
for (int32_t i = 0; i < p->pSchema->numOfCols; ++i) {
|
||||
|
|
|
@ -266,7 +266,7 @@ static int32_t tsdbCommitTableDel(SCommitter *pCommitter, STbData *pTbData, SDel
|
|||
suid = pDelIdx->suid;
|
||||
uid = pDelIdx->uid;
|
||||
|
||||
code = tsdbReadDelData(pCommitter->pDelFReader, pDelIdx, pCommitter->aDelData);
|
||||
code = tsdbReadDelDatav1(pCommitter->pDelFReader, pDelIdx, pCommitter->aDelData, INT64_MAX);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
} else {
|
||||
taosArrayClear(pCommitter->aDelData);
|
||||
|
|
|
@ -412,7 +412,7 @@ static int32_t tsdbTombFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo*
|
|||
}
|
||||
}
|
||||
|
||||
code = tsdbReadDelData(pIter->tIter.pReader, pDelIdx, pIter->tIter.aDelData);
|
||||
code = tsdbReadDelDatav1(pIter->tIter.pReader, pDelIdx, pIter->tIter.aDelData, INT64_MAX);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pIter->delInfo.suid = pDelIdx->suid;
|
||||
|
|
|
@ -1896,7 +1896,7 @@ static bool isCleanFileDataBlock(STsdbReader* pReader, SFileDataBlockInfo* pBloc
|
|||
SDataBlockToLoadInfo info = {0};
|
||||
getBlockToLoadInfo(&info, pBlockInfo, pBlock, pScanInfo, keyInBuf, pLastBlockReader, pReader);
|
||||
bool isCleanFileBlock = !(info.overlapWithNeighborBlock || info.hasDupTs || info.overlapWithKeyInBuf ||
|
||||
info.overlapWithDelInfo || info.overlapWithLastBlock || info.partiallyRequired);
|
||||
info.overlapWithDelInfo || info.overlapWithLastBlock);
|
||||
return isCleanFileBlock;
|
||||
}
|
||||
|
||||
|
@ -2857,7 +2857,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader) {
|
|||
// it is a clean block, load it directly
|
||||
if (isCleanFileDataBlock(pReader, pBlockInfo, pBlock, pBlockScanInfo, keyInBuf, pLastBlockReader) &&
|
||||
pBlock->nRow <= pReader->resBlockInfo.capacity) {
|
||||
if (asc || ((!asc) && (!hasDataInLastBlock(pLastBlockReader)))) {
|
||||
if (asc || (!hasDataInLastBlock(pLastBlockReader))) {
|
||||
code = copyBlockDataToSDataBlock(pReader);
|
||||
if (code) {
|
||||
goto _end;
|
||||
|
@ -2876,7 +2876,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader) {
|
|||
}
|
||||
}
|
||||
|
||||
SBlockData* pBlockData = &pReader->status.fileBlockData;
|
||||
SBlockData* pBlockData = &pReader->status.fileBlockData;
|
||||
|
||||
while (1) {
|
||||
bool hasBlockData = false;
|
||||
|
@ -2890,7 +2890,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader) {
|
|||
|
||||
pDumpInfo->rowIndex += step;
|
||||
|
||||
SDataBlk* pBlock = getCurrentBlock(&pReader->status.blockIter);
|
||||
pBlock = getCurrentBlock(&pReader->status.blockIter);
|
||||
if (pDumpInfo->rowIndex >= pBlock->nRow || pDumpInfo->rowIndex < 0) {
|
||||
pBlockInfo = getCurrentBlockInfo(&pReader->status.blockIter); // NOTE: get the new block info
|
||||
|
||||
|
@ -2918,7 +2918,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader) {
|
|||
|
||||
// currently loaded file data block is consumed
|
||||
if ((pBlockData->nRow > 0) && (pDumpInfo->rowIndex >= pBlockData->nRow || pDumpInfo->rowIndex < 0)) {
|
||||
SDataBlk* pBlock = getCurrentBlock(&pReader->status.blockIter);
|
||||
pBlock = getCurrentBlock(&pReader->status.blockIter);
|
||||
setBlockAllDumped(pDumpInfo, pBlock->maxKey.ts, pReader->order);
|
||||
break;
|
||||
}
|
||||
|
@ -2967,7 +2967,7 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
|
|||
SDelIdx* pIdx = taosArraySearch(pReader->pDelIdx, &idx, tCmprDelIdx, TD_EQ);
|
||||
|
||||
if (pIdx != NULL) {
|
||||
code = tsdbReadDelData(pReader->pDelFReader, pIdx, pDelData);
|
||||
code = tsdbReadDelDatav1(pReader->pDelFReader, pIdx, pDelData, pReader->verRange.maxVer);
|
||||
}
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _err;
|
||||
|
@ -2978,7 +2978,10 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
|
|||
if (pMemTbData != NULL) {
|
||||
p = pMemTbData->pHead;
|
||||
while (p) {
|
||||
taosArrayPush(pDelData, p);
|
||||
if (p->version <= pReader->verRange.maxVer) {
|
||||
taosArrayPush(pDelData, p);
|
||||
}
|
||||
|
||||
p = p->pNext;
|
||||
}
|
||||
}
|
||||
|
@ -2986,7 +2989,9 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
|
|||
if (piMemTbData != NULL) {
|
||||
p = piMemTbData->pHead;
|
||||
while (p) {
|
||||
taosArrayPush(pDelData, p);
|
||||
if (p->version <= pReader->verRange.maxVer) {
|
||||
taosArrayPush(pDelData, p);
|
||||
}
|
||||
p = p->pNext;
|
||||
}
|
||||
}
|
||||
|
@ -4558,7 +4563,11 @@ int32_t tsdbReaderOpen(void* pVnode, SQueryTableDataCond* pCond, void* pTableLis
|
|||
|
||||
pReader->pIgnoreTables = pIgnoreTables;
|
||||
|
||||
tsdbDebug("%p total numOfTable:%d in this query %s", pReader, numOfTables, pReader->idStr);
|
||||
tsdbDebug("%p total numOfTable:%d, window:%" PRId64 " - %" PRId64 ", verRange:%" PRId64 " - %" PRId64
|
||||
" in this query %s",
|
||||
pReader, numOfTables, pReader->window.skey, pReader->window.ekey, pReader->verRange.minVer,
|
||||
pReader->verRange.maxVer, pReader->idStr);
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
|
@ -5030,7 +5039,8 @@ int32_t tsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_t numOfCols, SColumnDataAgg* pTsAgg) {
|
||||
static bool doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_t numOfCols, SColumnDataAgg* pTsAgg) {
|
||||
bool hasNullSMA = false;
|
||||
// do fill all null column value SMA info
|
||||
int32_t i = 0, j = 0;
|
||||
int32_t size = (int32_t)taosArrayGetSize(pSup->pColAgg);
|
||||
|
@ -5050,6 +5060,7 @@ static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_
|
|||
taosArrayInsert(pSup->pColAgg, i, &nullColAgg);
|
||||
i += 1;
|
||||
size++;
|
||||
hasNullSMA = true;
|
||||
}
|
||||
j += 1;
|
||||
}
|
||||
|
@ -5060,12 +5071,15 @@ static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_
|
|||
SColumnDataAgg nullColAgg = {.colId = pSup->colId[j], .numOfNull = numOfRows};
|
||||
taosArrayInsert(pSup->pColAgg, i, &nullColAgg);
|
||||
i += 1;
|
||||
hasNullSMA = true;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
return hasNullSMA;
|
||||
}
|
||||
|
||||
int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock, bool* allHave) {
|
||||
int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock, bool* allHave, bool *hasNullSMA) {
|
||||
SColumnDataAgg*** pBlockSMA = &pDataBlock->pBlockAgg;
|
||||
|
||||
int32_t code = 0;
|
||||
|
@ -5129,7 +5143,10 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock,
|
|||
}
|
||||
|
||||
// do fill all null column value SMA info
|
||||
doFillNullColSMA(pSup, pBlock->nRow, numOfCols, pTsAgg);
|
||||
if (doFillNullColSMA(pSup, pBlock->nRow, numOfCols, pTsAgg)) {
|
||||
*hasNullSMA = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
size_t size = taosArrayGetSize(pSup->pColAgg);
|
||||
|
||||
int32_t i = 0, j = 0;
|
||||
|
@ -5296,6 +5313,9 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
|||
}
|
||||
|
||||
static int32_t getBucketIndex(int32_t startRow, int32_t bucketRange, int32_t numOfRows, int32_t numOfBucket) {
|
||||
if (numOfRows < startRow) {
|
||||
return 0;
|
||||
}
|
||||
int32_t bucketIndex = ((numOfRows - startRow) / bucketRange);
|
||||
if (bucketIndex == numOfBucket) {
|
||||
bucketIndex -= 1;
|
||||
|
|
|
@ -523,7 +523,7 @@ static int32_t tsdbWriteBlockSma(SDataFWriter *pWriter, SBlockData *pBlockData,
|
|||
for (int32_t iColData = 0; iColData < pBlockData->nColData; iColData++) {
|
||||
SColData *pColData = tBlockDataGetColDataByIdx(pBlockData, iColData);
|
||||
|
||||
if ((!pColData->smaOn) || IS_VAR_DATA_TYPE(pColData->type) || ((pColData->flag & HAS_VALUE) == 0)) continue;
|
||||
if ((!pColData->smaOn) || ((pColData->flag & HAS_VALUE) == 0)) continue;
|
||||
|
||||
SColumnDataAgg sma = {.colId = pColData->cid};
|
||||
tColDataCalcSMA[pColData->type](pColData, &sma.sum, &sma.max, &sma.min, &sma.numOfNull);
|
||||
|
@ -1489,6 +1489,10 @@ int32_t tsdbDelFReaderClose(SDelFReader **ppReader) {
|
|||
}
|
||||
|
||||
int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData) {
|
||||
return tsdbReadDelDatav1(pReader, pDelIdx, aDelData, INT64_MAX);
|
||||
}
|
||||
|
||||
int32_t tsdbReadDelDatav1(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData, int64_t maxVer) {
|
||||
int32_t code = 0;
|
||||
int64_t offset = pDelIdx->offset;
|
||||
int64_t size = pDelIdx->size;
|
||||
|
@ -1510,11 +1514,15 @@ int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData
|
|||
SDelData delData;
|
||||
n += tGetDelData(pReader->aBuf[0] + n, &delData);
|
||||
|
||||
if (taosArrayPush(aDelData, &delData) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
if (delData.version > maxVer) {
|
||||
continue;
|
||||
}
|
||||
if (taosArrayPush(aDelData, &delData) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(n == size);
|
||||
|
||||
return code;
|
||||
|
|
|
@ -1166,7 +1166,7 @@ static int32_t tsdbSnapWriteDelTableDataStart(STsdbSnapWriter* pWriter, TABLEID*
|
|||
|
||||
int32_t c = tTABLEIDCmprFn(pDelIdx, &pWriter->tbid);
|
||||
if (c < 0) {
|
||||
code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->pTIter->tIter.aDelData);
|
||||
code = tsdbReadDelDatav1(pWriter->pDelFReader, pDelIdx, pWriter->pTIter->tIter.aDelData, INT64_MAX);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
SDelIdx* pDelIdxNew = taosArrayReserve(pWriter->aDelIdx, 1);
|
||||
|
@ -1183,7 +1183,7 @@ static int32_t tsdbSnapWriteDelTableDataStart(STsdbSnapWriter* pWriter, TABLEID*
|
|||
|
||||
pWriter->pTIter->tIter.iDelIdx++;
|
||||
} else if (c == 0) {
|
||||
code = tsdbReadDelData(pWriter->pDelFReader, pDelIdx, pWriter->aDelData);
|
||||
code = tsdbReadDelDatav1(pWriter->pDelFReader, pDelIdx, pWriter->aDelData, INT64_MAX);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
pWriter->pTIter->tIter.iDelIdx++;
|
||||
|
|
|
@ -1562,7 +1562,7 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
|
|||
|
||||
switch (pReq->type) {
|
||||
case AUTH_TYPE_READ: {
|
||||
if (pInfo->readTbs && taosHashGetSize(pInfo->readTbs) > 0) {
|
||||
if (pReq->tbName.type == TSDB_TABLE_NAME_T && pInfo->readTbs && taosHashGetSize(pInfo->readTbs) > 0) {
|
||||
req->singleType = AUTH_TYPE_READ;
|
||||
CTG_ERR_RET(ctgChkSetTbAuthRes(pCtg, req, res));
|
||||
if (pRes->pass || res->metaNotExists) {
|
||||
|
@ -1578,7 +1578,7 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
|
|||
break;
|
||||
}
|
||||
case AUTH_TYPE_WRITE: {
|
||||
if (pInfo->writeTbs && taosHashGetSize(pInfo->writeTbs) > 0) {
|
||||
if (pReq->tbName.type == TSDB_TABLE_NAME_T && pInfo->writeTbs && taosHashGetSize(pInfo->writeTbs) > 0) {
|
||||
req->singleType = AUTH_TYPE_WRITE;
|
||||
CTG_ERR_RET(ctgChkSetTbAuthRes(pCtg, req, res));
|
||||
if (pRes->pass || res->metaNotExists) {
|
||||
|
|
|
@ -135,6 +135,10 @@ struct SResultRowEntryInfo* getResultEntryInfo(const SResultRow* pRow, int32_t i
|
|||
|
||||
static FORCE_INLINE SResultRow* getResultRowByPos(SDiskbasedBuf* pBuf, SResultRowPosition* pos, bool forUpdate) {
|
||||
SFilePage* bufPage = (SFilePage*)getBufPage(pBuf, pos->pageId);
|
||||
if (!bufPage) {
|
||||
uFatal("failed to get the buffer page:%d since %s", pos->pageId, terrstr());
|
||||
return NULL;
|
||||
}
|
||||
if (forUpdate) {
|
||||
setBufPageDirty(bufPage, true);
|
||||
}
|
||||
|
@ -182,4 +186,7 @@ int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle,
|
|||
|
||||
void printDataBlock(SSDataBlock* pBlock, const char* flag);
|
||||
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order);
|
||||
void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery);
|
||||
|
||||
#endif // TDENGINE_EXECUTIL_H
|
||||
|
|
|
@ -456,6 +456,7 @@ typedef struct SStreamIntervalOperatorInfo {
|
|||
SSHashObj* pUpdatedMap;
|
||||
int64_t dataVersion;
|
||||
SStateStore statestore;
|
||||
bool recvGetAll;
|
||||
} SStreamIntervalOperatorInfo;
|
||||
|
||||
typedef struct SDataGroupInfo {
|
||||
|
|
|
@ -120,6 +120,8 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t
|
|||
void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
|
||||
void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp);
|
||||
void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||
void taosFillUpdateStartTimestampInfo(SFillInfo* pFillInfo, int64_t ts);
|
||||
bool taosFillNotStarted(const SFillInfo* pFillInfo);
|
||||
SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprInfo* pNotFillExpr,
|
||||
int32_t numOfNotFillCols, const struct SNodeListNode* val);
|
||||
bool taosFillHasMoreResults(struct SFillInfo* pFillInfo);
|
||||
|
|
|
@ -136,7 +136,7 @@ void initGroupedResultInfo(SGroupResInfo* pGroupResInfo, SSHashObj* pHashmap, in
|
|||
|
||||
size_t keyLen = 0;
|
||||
int32_t iter = 0;
|
||||
int32_t bufLen = 0, offset = 0;
|
||||
int64_t bufLen = 0, offset = 0;
|
||||
|
||||
// todo move away and record this during create window
|
||||
while ((pData = tSimpleHashIterate(pHashmap, pData, &iter)) != NULL) {
|
||||
|
@ -960,6 +960,7 @@ static int32_t doFilterByTagCond(STableListInfo* pListInfo, SArray* pUidList, SN
|
|||
SArray* pBlockList = NULL;
|
||||
SSDataBlock* pResBlock = NULL;
|
||||
SScalarParam output = {0};
|
||||
SArray* pUidTagList = NULL;
|
||||
|
||||
tagFilterAssist ctx = {0};
|
||||
ctx.colHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
|
||||
|
@ -979,7 +980,7 @@ static int32_t doFilterByTagCond(STableListInfo* pListInfo, SArray* pUidList, SN
|
|||
SDataType type = {.type = TSDB_DATA_TYPE_BOOL, .bytes = sizeof(bool)};
|
||||
|
||||
// int64_t stt = taosGetTimestampUs();
|
||||
SArray* pUidTagList = taosArrayInit(10, sizeof(STUidTagInfo));
|
||||
pUidTagList = taosArrayInit(10, sizeof(STUidTagInfo));
|
||||
copyExistedUids(pUidTagList, pUidList);
|
||||
|
||||
FilterCondType condType = checkTagCond(pTagCond);
|
||||
|
@ -1151,6 +1152,21 @@ _end:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t qGetTableList(int64_t suid, void* pVnode, void* node, SArray **tableList, void* pTaskInfo){
|
||||
SSubplan *pSubplan = (SSubplan *)node;
|
||||
SScanPhysiNode pNode = {0};
|
||||
pNode.suid = suid;
|
||||
pNode.uid = suid;
|
||||
pNode.tableType = TSDB_SUPER_TABLE;
|
||||
STableListInfo* pTableListInfo = tableListCreate();
|
||||
uint8_t digest[17] = {0};
|
||||
int code = getTableList(pVnode, &pNode, pSubplan ? pSubplan->pTagCond : NULL, pSubplan ? pSubplan->pTagIndexCond : NULL, pTableListInfo, digest, "qGetTableList", &((SExecTaskInfo*)pTaskInfo)->storageAPI);
|
||||
*tableList = pTableListInfo->pTableList;
|
||||
pTableListInfo->pTableList = NULL;
|
||||
tableListDestroy(pTableListInfo);
|
||||
return code;
|
||||
}
|
||||
|
||||
size_t getTableTagsBufLen(const SNodeList* pGroups) {
|
||||
size_t keyLen = 0;
|
||||
|
||||
|
@ -1745,12 +1761,12 @@ int32_t convertFillType(int32_t mode) {
|
|||
return type;
|
||||
}
|
||||
|
||||
static void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery) {
|
||||
void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery) {
|
||||
if (ascQuery) {
|
||||
*w = getAlignQueryTimeWindow(pInterval, pInterval->precision, ts);
|
||||
*w = getAlignQueryTimeWindow(pInterval, ts);
|
||||
} else {
|
||||
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
|
||||
*w = getAlignQueryTimeWindow(pInterval, pInterval->precision, ts);
|
||||
*w = getAlignQueryTimeWindow(pInterval, ts);
|
||||
|
||||
int64_t key = w->skey;
|
||||
while (key < ts) { // moving towards end
|
||||
|
@ -1767,7 +1783,7 @@ static void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindo
|
|||
static STimeWindow doCalculateTimeWindow(int64_t ts, SInterval* pInterval) {
|
||||
STimeWindow w = {0};
|
||||
|
||||
w.skey = taosTimeTruncate(ts, pInterval, pInterval->precision);
|
||||
w.skey = taosTimeTruncate(ts, pInterval);
|
||||
w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return w;
|
||||
}
|
||||
|
@ -1801,6 +1817,7 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
if (pRow) {
|
||||
w = pRow->win;
|
||||
}
|
||||
|
||||
// in case of typical time window, we can calculate time window directly.
|
||||
if (w.skey > ts || w.ekey < ts) {
|
||||
w = doCalculateTimeWindow(ts, pInterval);
|
||||
|
@ -1815,6 +1832,34 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
return w;
|
||||
}
|
||||
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (!IS_CALENDAR_TIME_DURATION(pInterval->slidingUnit)) {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert key to second
|
||||
int64_t key = convertTimePrecision(tw->skey, pInterval->precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
int64_t duration = pInterval->sliding;
|
||||
if (pInterval->slidingUnit == 'y') {
|
||||
duration *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t) key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + duration * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
}
|
||||
|
||||
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo) {
|
||||
return (pLimitInfo->limit.limit != -1 || pLimitInfo->limit.offset != -1 || pLimitInfo->slimit.limit != -1 ||
|
||||
pLimitInfo->slimit.offset != -1);
|
||||
|
|
|
@ -132,7 +132,8 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
pOperator->status = OP_NOT_OPENED;
|
||||
|
||||
SStreamScanInfo* pInfo = pOperator->info;
|
||||
qDebug("s-task:%s set source blocks:%d", id, (int32_t)numOfBlocks);
|
||||
|
||||
qDebug("s-task:%s in this batch, all %d blocks need to be processed and dump results", id, (int32_t)numOfBlocks);
|
||||
ASSERT(pInfo->validBlockIndex == 0 && taosArrayGetSize(pInfo->pBlockLists) == 0);
|
||||
|
||||
if (type == STREAM_INPUT__MERGED_SUBMIT) {
|
||||
|
@ -140,6 +141,7 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
SPackedData* pReq = POINTER_SHIFT(input, i * sizeof(SPackedData));
|
||||
taosArrayPush(pInfo->pBlockLists, pReq);
|
||||
}
|
||||
|
||||
pInfo->blockType = STREAM_INPUT__DATA_SUBMIT;
|
||||
} else if (type == STREAM_INPUT__DATA_SUBMIT) {
|
||||
taosArrayPush(pInfo->pBlockLists, input);
|
||||
|
@ -150,6 +152,7 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
SPackedData tmp = { .pDataBlock = pDataBlock };
|
||||
taosArrayPush(pInfo->pBlockLists, &tmp);
|
||||
}
|
||||
|
||||
pInfo->blockType = STREAM_INPUT__DATA_BLOCK;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
|
@ -183,6 +186,11 @@ void qSetTaskId(qTaskInfo_t tinfo, uint64_t taskId, uint64_t queryId) {
|
|||
doSetTaskId(pTaskInfo->pRoot, &pTaskInfo->storageAPI);
|
||||
}
|
||||
|
||||
//void qSetTaskCode(qTaskInfo_t tinfo, int32_t code) {
|
||||
// SExecTaskInfo* pTaskInfo = tinfo;
|
||||
// pTaskInfo->code = code;
|
||||
//}
|
||||
|
||||
int32_t qSetStreamOpOpen(qTaskInfo_t tinfo) {
|
||||
if (tinfo == NULL) {
|
||||
return TSDB_CODE_APP_ERROR;
|
||||
|
@ -398,7 +406,7 @@ int32_t qUpdateTableListForStreamScanner(qTaskInfo_t tinfo, const SArray* tableI
|
|||
int32_t code = 0;
|
||||
|
||||
if (isAdd) {
|
||||
qDebug("add %d tables id into query list, %s", (int32_t)taosArrayGetSize(tableIdList), id);
|
||||
qDebug("try to add %d tables id into query list, %s", (int32_t)taosArrayGetSize(tableIdList), id);
|
||||
}
|
||||
|
||||
// traverse to the stream scanner node to add this table id
|
||||
|
|
|
@ -442,15 +442,15 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB
|
|||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key) {
|
||||
STimeWindow getAlignQueryTimeWindow(const SInterval* pInterval, int64_t key) {
|
||||
STimeWindow win = {0};
|
||||
win.skey = taosTimeTruncate(key, pInterval, precision);
|
||||
win.skey = taosTimeTruncate(key, pInterval);
|
||||
|
||||
/*
|
||||
* if the realSkey > INT64_MAX - pInterval->interval, the query duration between
|
||||
* realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
|
||||
*/
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
if (win.ekey < win.skey) {
|
||||
win.ekey = INT64_MAX;
|
||||
}
|
||||
|
@ -726,7 +726,8 @@ void copyResultrowToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SResultR
|
|||
pCtx[j].resultInfo->numOfRes = pRow->numOfRows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
blockDataEnsureCapacity(pBlock, pBlock->info.rows + pCtx[j].resultInfo->numOfRes);
|
||||
int32_t code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
|
||||
if (TAOS_FAILED(code)) {
|
||||
qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
|
@ -827,7 +828,7 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprS
|
|||
}
|
||||
|
||||
if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
|
||||
uint32_t newSize = pBlock->info.rows + pRow->numOfRows + (numOfRows - i) > 1 ? 1 : 0;
|
||||
uint32_t newSize = pBlock->info.rows + pRow->numOfRows + ((numOfRows - i) > 1 ? 1 : 0);
|
||||
blockDataEnsureCapacity(pBlock, newSize);
|
||||
qDebug("datablock capacity not sufficient, expand to required:%d, current capacity:%d, %s",
|
||||
newSize, pBlock->info.capacity, GET_TASKID(pTaskInfo));
|
||||
|
|
|
@ -61,25 +61,28 @@ typedef struct SFillOperatorInfo {
|
|||
SExprSupp noFillExprSupp;
|
||||
} SFillOperatorInfo;
|
||||
|
||||
static void revisedFillStartKey(SFillOperatorInfo* pInfo, SSDataBlock* pBlock, int32_t order);
|
||||
static void destroyFillOperatorInfo(void* param);
|
||||
static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_t order, int32_t scanFlag);
|
||||
|
||||
static void doHandleRemainBlockForNewGroupImpl(SOperatorInfo* pOperator, SFillOperatorInfo* pInfo,
|
||||
SResultInfo* pResultInfo, SExecTaskInfo* pTaskInfo) {
|
||||
SResultInfo* pResultInfo, int32_t order) {
|
||||
pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows;
|
||||
SSDataBlock* pResBlock = pInfo->pFinalRes;
|
||||
|
||||
int32_t order = TSDB_ORDER_ASC;
|
||||
// int32_t order = TSDB_ORDER_ASC;
|
||||
int32_t scanFlag = MAIN_SCAN;
|
||||
getTableScanInfo(pOperator, &order, &scanFlag, false);
|
||||
|
||||
int64_t ekey = pInfo->existNewGroupBlock->info.window.ekey;
|
||||
// getTableScanInfo(pOperator, &order, &scanFlag, false);
|
||||
taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));
|
||||
|
||||
blockDataCleanup(pInfo->pRes);
|
||||
doApplyScalarCalculation(pOperator, pInfo->existNewGroupBlock, order, scanFlag);
|
||||
|
||||
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, ekey);
|
||||
revisedFillStartKey(pInfo, pInfo->existNewGroupBlock, order);
|
||||
|
||||
int64_t ts = (order == TSDB_ORDER_ASC)? pInfo->existNewGroupBlock->info.window.ekey:pInfo->existNewGroupBlock->info.window.skey;
|
||||
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, ts);
|
||||
|
||||
taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->pRes);
|
||||
|
||||
int32_t numOfResultRows = pResultInfo->capacity - pResBlock->info.rows;
|
||||
|
@ -90,7 +93,7 @@ static void doHandleRemainBlockForNewGroupImpl(SOperatorInfo* pOperator, SFillOp
|
|||
}
|
||||
|
||||
static void doHandleRemainBlockFromNewGroup(SOperatorInfo* pOperator, SFillOperatorInfo* pInfo,
|
||||
SResultInfo* pResultInfo, SExecTaskInfo* pTaskInfo) {
|
||||
SResultInfo* pResultInfo, int32_t order) {
|
||||
if (taosFillHasMoreResults(pInfo->pFillInfo)) {
|
||||
int32_t numOfResultRows = pResultInfo->capacity - pInfo->pFinalRes->info.rows;
|
||||
taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pFinalRes, numOfResultRows);
|
||||
|
@ -100,7 +103,7 @@ static void doHandleRemainBlockFromNewGroup(SOperatorInfo* pOperator, SFillOpera
|
|||
|
||||
// handle the cached new group data block
|
||||
if (pInfo->existNewGroupBlock) {
|
||||
doHandleRemainBlockForNewGroupImpl(pOperator, pInfo, pResultInfo, pTaskInfo);
|
||||
doHandleRemainBlockForNewGroupImpl(pOperator, pInfo, pResultInfo, order);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,6 +122,53 @@ void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int
|
|||
pInfo->pRes->info.id.groupId = pBlock->info.id.groupId;
|
||||
}
|
||||
|
||||
// todo refactor: decide the start key according to the query time range.
|
||||
static void revisedFillStartKey(SFillOperatorInfo* pInfo, SSDataBlock* pBlock, int32_t order) {
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
int64_t skey = pBlock->info.window.skey;
|
||||
if (skey < pInfo->pFillInfo->start) { // the start key may be smaller than the
|
||||
ASSERT( taosFillNotStarted(pInfo->pFillInfo));
|
||||
taosFillUpdateStartTimestampInfo(pInfo->pFillInfo, skey);
|
||||
} else if (pInfo->pFillInfo->start < skey) {
|
||||
int64_t t = skey;
|
||||
SInterval* pInterval = &pInfo->pFillInfo->interval;
|
||||
|
||||
while(1) {
|
||||
int64_t prev = taosTimeAdd(t, -pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
if (prev <= pInfo->pFillInfo->start) {
|
||||
t = prev;
|
||||
break;
|
||||
}
|
||||
t = prev;
|
||||
}
|
||||
|
||||
// todo time window chosen problem: t or prev value?
|
||||
taosFillUpdateStartTimestampInfo(pInfo->pFillInfo, t);
|
||||
}
|
||||
} else {
|
||||
int64_t ekey = pBlock->info.window.ekey;
|
||||
if (ekey > pInfo->pFillInfo->start) {
|
||||
ASSERT( taosFillNotStarted(pInfo->pFillInfo));
|
||||
taosFillUpdateStartTimestampInfo(pInfo->pFillInfo, ekey);
|
||||
} else if (ekey < pInfo->pFillInfo->start) {
|
||||
int64_t t = ekey;
|
||||
SInterval* pInterval = &pInfo->pFillInfo->interval;
|
||||
|
||||
while(1) {
|
||||
int64_t prev = taosTimeAdd(t, pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
if (prev >= pInfo->pFillInfo->start) {
|
||||
t = prev;
|
||||
break;
|
||||
}
|
||||
t = prev;
|
||||
}
|
||||
|
||||
// todo time window chosen problem: t or prev value?
|
||||
taosFillUpdateStartTimestampInfo(pInfo->pFillInfo, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
|
||||
SFillOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
@ -132,13 +182,19 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
|
|||
int32_t scanFlag = MAIN_SCAN;
|
||||
getTableScanInfo(pOperator, &order, &scanFlag, false);
|
||||
|
||||
doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, pTaskInfo);
|
||||
SOperatorInfo* pDownstream = pOperator->pDownstream[0];
|
||||
|
||||
// the scan order may be different from the output result order for agg interval operator.
|
||||
if (pDownstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL) {
|
||||
order = ((SIntervalAggOperatorInfo*) pDownstream->info)->resultTsOrder;
|
||||
}
|
||||
|
||||
doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, order);
|
||||
if (pResBlock->info.rows > 0) {
|
||||
pResBlock->info.id.groupId = pInfo->curGroupId;
|
||||
return pResBlock;
|
||||
}
|
||||
|
||||
SOperatorInfo* pDownstream = pOperator->pDownstream[0];
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream);
|
||||
if (pBlock == NULL) {
|
||||
|
@ -158,15 +214,16 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
|
|||
blockDataEnsureCapacity(pInfo->pFinalRes, pBlock->info.rows);
|
||||
doApplyScalarCalculation(pOperator, pBlock, order, scanFlag);
|
||||
|
||||
if (pInfo->curGroupId == 0 || pInfo->curGroupId == pInfo->pRes->info.id.groupId) {
|
||||
if (pInfo->curGroupId == 0 || (pInfo->curGroupId == pInfo->pRes->info.id.groupId)) {
|
||||
if (pInfo->curGroupId == 0 && taosFillNotStarted(pInfo->pFillInfo)) {
|
||||
revisedFillStartKey(pInfo, pBlock, order);
|
||||
}
|
||||
|
||||
pInfo->curGroupId = pInfo->pRes->info.id.groupId; // the first data block
|
||||
pInfo->totalInputRows += pInfo->pRes->info.rows;
|
||||
|
||||
if (order == pInfo->pFillInfo->order) {
|
||||
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, pBlock->info.window.ekey);
|
||||
} else {
|
||||
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, pBlock->info.window.skey);
|
||||
}
|
||||
int64_t ts = (order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey;
|
||||
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, ts);
|
||||
taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->pRes);
|
||||
} else if (pInfo->curGroupId != pBlock->info.id.groupId) { // the new group data block
|
||||
pInfo->existNewGroupBlock = pBlock;
|
||||
|
@ -190,7 +247,7 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
|
|||
return pResBlock;
|
||||
}
|
||||
|
||||
doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, pTaskInfo);
|
||||
doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, order);
|
||||
if (pResBlock->info.rows >= pOperator->resultInfo.threshold || pBlock == NULL) {
|
||||
pResBlock->info.id.groupId = pInfo->curGroupId;
|
||||
return pResBlock;
|
||||
|
@ -198,7 +255,7 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
|
|||
} else if (pInfo->existNewGroupBlock) { // try next group
|
||||
blockDataCleanup(pResBlock);
|
||||
|
||||
doHandleRemainBlockForNewGroupImpl(pOperator, pInfo, pResultInfo, pTaskInfo);
|
||||
doHandleRemainBlockForNewGroupImpl(pOperator, pInfo, pResultInfo, order);
|
||||
if (pResBlock->info.rows > pResultInfo->threshold) {
|
||||
pResBlock->info.id.groupId = pInfo->curGroupId;
|
||||
return pResBlock;
|
||||
|
@ -256,11 +313,11 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
|
|||
const char* id, SInterval* pInterval, int32_t fillType, int32_t order) {
|
||||
SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pNotFillExpr, numOfNotFillCols, pValNode);
|
||||
|
||||
int64_t startKey = (order == TSDB_ORDER_ASC) ? win.skey : win.ekey;
|
||||
STimeWindow w = getAlignQueryTimeWindow(pInterval, pInterval->precision, startKey);
|
||||
w = getFirstQualifiedTimeWindow(startKey, &w, pInterval, order);
|
||||
int64_t startKey = (order == TSDB_ORDER_ASC) ? win.skey : win.ekey;
|
||||
|
||||
pInfo->pFillInfo = taosCreateFillInfo(w.skey, numOfCols, numOfNotFillCols, capacity, pInterval, fillType, pColInfo,
|
||||
// STimeWindow w = {0};
|
||||
// getInitialStartTimeWindow(pInterval, startKey, &w, order == TSDB_ORDER_ASC);
|
||||
pInfo->pFillInfo = taosCreateFillInfo(startKey, numOfCols, numOfNotFillCols, capacity, pInterval, fillType, pColInfo,
|
||||
pInfo->primaryTsCol, order, id);
|
||||
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
|
@ -402,13 +459,13 @@ _error:
|
|||
|
||||
TSKEY getNextWindowTs(TSKEY ts, SInterval* pInterval) {
|
||||
STimeWindow win = {.skey = ts, .ekey = ts};
|
||||
getNextIntervalWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
return win.skey;
|
||||
}
|
||||
|
||||
TSKEY getPrevWindowTs(TSKEY ts, SInterval* pInterval) {
|
||||
STimeWindow win = {.skey = ts, .ekey = ts};
|
||||
getNextIntervalWindow(pInterval, &win, TSDB_ORDER_DESC);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_DESC);
|
||||
return win.skey;
|
||||
}
|
||||
|
||||
|
@ -1002,9 +1059,10 @@ static void doStreamFillImpl(SOperatorInfo* pOperator) {
|
|||
SSDataBlock* pBlock = pInfo->pSrcBlock;
|
||||
uint64_t groupId = pBlock->info.id.groupId;
|
||||
SSDataBlock* pRes = pInfo->pRes;
|
||||
SColumnInfoData* pTsCol = taosArrayGet(pInfo->pSrcBlock->pDataBlock, pInfo->primaryTsCol);
|
||||
TSKEY* tsCol = (TSKEY*)pTsCol->pData;
|
||||
pRes->info.id.groupId = groupId;
|
||||
SColumnInfoData* pTsCol = taosArrayGet(pInfo->pSrcBlock->pDataBlock, pInfo->primaryTsCol);
|
||||
TSKEY* tsCol = (TSKEY*)pTsCol->pData;
|
||||
pInfo->srcRowIndex++;
|
||||
|
||||
if (pInfo->srcRowIndex == 0) {
|
||||
keepBlockRowInDiscBuf(pOperator, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex, groupId, pFillSup->rowSize);
|
||||
|
@ -1242,7 +1300,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) {
|
|||
SSDataBlock* fillResult = NULL;
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
while (1) {
|
||||
if (pInfo->srcRowIndex >= pInfo->pSrcBlock->info.rows) {
|
||||
if (pInfo->srcRowIndex >= pInfo->pSrcBlock->info.rows || pInfo->pSrcBlock->info.rows == 0) {
|
||||
// If there are delete datablocks, we receive them first.
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
|
@ -1281,7 +1339,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) {
|
|||
case STREAM_PULL_DATA: {
|
||||
doApplyStreamScalarCalculation(pOperator, pBlock, pInfo->pSrcBlock);
|
||||
memcpy(pInfo->pSrcBlock->info.parTbName, pBlock->info.parTbName, TSDB_TABLE_NAME_LEN);
|
||||
pInfo->srcRowIndex = 0;
|
||||
pInfo->srcRowIndex = -1;
|
||||
} break;
|
||||
case STREAM_CREATE_CHILD_TABLE: {
|
||||
return pBlock;
|
||||
|
@ -1497,7 +1555,7 @@ SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFi
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->srcRowIndex = 0;
|
||||
pInfo->srcRowIndex = -1;
|
||||
setOperatorInfo(pOperator, "StreamFillOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL, false, OP_NOT_OPENED, pInfo,
|
||||
pTaskInfo);
|
||||
pOperator->fpSet =
|
||||
|
|
|
@ -30,11 +30,13 @@ typedef struct SJoinRowCtx {
|
|||
bool rowRemains;
|
||||
int64_t ts;
|
||||
SArray* leftRowLocations;
|
||||
SArray* rightRowLocations;
|
||||
SArray* leftCreatedBlocks;
|
||||
SArray* rightCreatedBlocks;
|
||||
int32_t leftRowIdx;
|
||||
int32_t rightRowIdx;
|
||||
|
||||
bool rightUseBuildTable;
|
||||
SArray* rightRowLocations;
|
||||
} SJoinRowCtx;
|
||||
|
||||
typedef struct SJoinOperatorInfo {
|
||||
|
@ -50,7 +52,17 @@ typedef struct SJoinOperatorInfo {
|
|||
int32_t rightPos;
|
||||
SColumnInfo rightCol;
|
||||
SNode* pCondAfterMerge;
|
||||
SNode* pColEqualOnConditions;
|
||||
|
||||
SArray* leftEqOnCondCols;
|
||||
char* leftEqOnCondKeyBuf;
|
||||
int32_t leftEqOnCondKeyLen;
|
||||
|
||||
SArray* rightEqOnCondCols;
|
||||
char* rightEqOnCondKeyBuf;
|
||||
int32_t rightEqOnCondKeyLen;
|
||||
|
||||
SSHashObj* rightBuildTable;
|
||||
SJoinRowCtx rowCtx;
|
||||
} SJoinOperatorInfo;
|
||||
|
||||
|
@ -92,6 +104,100 @@ static void extractTimeCondition(SJoinOperatorInfo* pInfo, SOperatorInfo** pDown
|
|||
setJoinColumnInfo(&pInfo->rightCol, rightTsCol);
|
||||
}
|
||||
|
||||
static void extractEqualOnCondColsFromOper(SJoinOperatorInfo* pInfo, SOperatorInfo** pDownstreams, SOperatorNode* pOperNode,
|
||||
SColumn* pLeft, SColumn* pRight) {
|
||||
SColumnNode* pLeftNode = (SColumnNode*)pOperNode->pLeft;
|
||||
SColumnNode* pRightNode = (SColumnNode*)pOperNode->pRight;
|
||||
if (pLeftNode->dataBlockId == pRightNode->dataBlockId || pLeftNode->dataBlockId == pDownstreams[0]->resultDataBlockId) {
|
||||
*pLeft = extractColumnFromColumnNode((SColumnNode*)pOperNode->pLeft);
|
||||
*pRight = extractColumnFromColumnNode((SColumnNode*)pOperNode->pRight);
|
||||
} else {
|
||||
*pLeft = extractColumnFromColumnNode((SColumnNode*)pOperNode->pRight);
|
||||
*pRight = extractColumnFromColumnNode((SColumnNode*)pOperNode->pLeft);
|
||||
}
|
||||
}
|
||||
|
||||
static void extractEqualOnCondCols(SJoinOperatorInfo* pInfo, SOperatorInfo** pDownStream, SNode* pEqualOnCondNode,
|
||||
SArray* leftTagEqCols, SArray* rightTagEqCols) {
|
||||
SColumn left = {0};
|
||||
SColumn right = {0};
|
||||
if (nodeType(pEqualOnCondNode) == QUERY_NODE_LOGIC_CONDITION && ((SLogicConditionNode*)pEqualOnCondNode)->condType == LOGIC_COND_TYPE_AND) {
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, ((SLogicConditionNode*)pEqualOnCondNode)->pParameterList) {
|
||||
SOperatorNode* pOperNode = (SOperatorNode*)pNode;
|
||||
extractEqualOnCondColsFromOper(pInfo, pDownStream, pOperNode, &left, &right);
|
||||
taosArrayPush(leftTagEqCols, &left);
|
||||
taosArrayPush(rightTagEqCols, &right);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (nodeType(pEqualOnCondNode) == QUERY_NODE_OPERATOR) {
|
||||
SOperatorNode* pOperNode = (SOperatorNode*)pEqualOnCondNode;
|
||||
extractEqualOnCondColsFromOper(pInfo, pDownStream, pOperNode, &left, &right);
|
||||
taosArrayPush(leftTagEqCols, &left);
|
||||
taosArrayPush(rightTagEqCols, &right);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t initTagColskeyBuf(int32_t* keyLen, char** keyBuf, const SArray* pGroupColList) {
|
||||
int32_t numOfGroupCols = taosArrayGetSize(pGroupColList);
|
||||
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||
SColumn* pCol = (SColumn*)taosArrayGet(pGroupColList, i);
|
||||
(*keyLen) += pCol->bytes; // actual data + null_flag
|
||||
}
|
||||
|
||||
int32_t nullFlagSize = sizeof(int8_t) * numOfGroupCols;
|
||||
(*keyLen) += nullFlagSize;
|
||||
|
||||
(*keyBuf) = taosMemoryCalloc(1, (*keyLen));
|
||||
if ((*keyBuf) == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t fillKeyBufFromTagCols(SArray* pCols, SSDataBlock* pBlock, int32_t rowIndex, void* pKey) {
|
||||
SColumnDataAgg* pColAgg = NULL;
|
||||
size_t numOfGroupCols = taosArrayGetSize(pCols);
|
||||
char* isNull = (char*)pKey;
|
||||
char* pStart = (char*)pKey + sizeof(int8_t) * numOfGroupCols;
|
||||
|
||||
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||
SColumn* pCol = (SColumn*) taosArrayGet(pCols, i);
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pCol->slotId);
|
||||
|
||||
// valid range check. todo: return error code.
|
||||
if (pCol->slotId > taosArrayGetSize(pBlock->pDataBlock)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pBlock->pBlockAgg != NULL) {
|
||||
pColAgg = pBlock->pBlockAgg[pCol->slotId]; // TODO is agg data matched?
|
||||
}
|
||||
|
||||
if (colDataIsNull(pColInfoData, pBlock->info.rows, rowIndex, pColAgg)) {
|
||||
isNull[i] = 1;
|
||||
} else {
|
||||
isNull[i] = 0;
|
||||
char* val = colDataGetData(pColInfoData, rowIndex);
|
||||
if (pCol->type == TSDB_DATA_TYPE_JSON) {
|
||||
int32_t dataLen = getJsonValueLen(val);
|
||||
memcpy(pStart, val, dataLen);
|
||||
pStart += dataLen;
|
||||
} else if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||
varDataCopy(pStart, val);
|
||||
pStart += varDataTLen(val);
|
||||
} else {
|
||||
memcpy(pStart, val, pCol->bytes);
|
||||
pStart += pCol->bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (int32_t)(pStart - (char*)pKey);
|
||||
}
|
||||
|
||||
SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream,
|
||||
SSortMergeJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo) {
|
||||
SJoinOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SJoinOperatorInfo));
|
||||
|
@ -153,6 +259,16 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
|||
pInfo->inputOrder = TSDB_ORDER_DESC;
|
||||
}
|
||||
|
||||
pInfo->pColEqualOnConditions = pJoinNode->pColEqualOnConditions;
|
||||
if (pInfo->pColEqualOnConditions != NULL) {
|
||||
pInfo->leftEqOnCondCols = taosArrayInit(4, sizeof(SColumn));
|
||||
pInfo->rightEqOnCondCols = taosArrayInit(4, sizeof(SColumn));
|
||||
extractEqualOnCondCols(pInfo, pDownstream, pInfo->pColEqualOnConditions, pInfo->leftEqOnCondCols, pInfo->rightEqOnCondCols);
|
||||
initTagColskeyBuf(&pInfo->leftEqOnCondKeyLen, &pInfo->leftEqOnCondKeyBuf, pInfo->leftEqOnCondCols);
|
||||
initTagColskeyBuf(&pInfo->rightEqOnCondKeyLen, &pInfo->rightEqOnCondKeyBuf, pInfo->rightEqOnCondCols);
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->rightBuildTable = tSimpleHashInit(256, hashFn);
|
||||
}
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doMergeJoin, NULL, destroyMergeJoinOperator, optrDefaultBufFn, NULL);
|
||||
code = appendDownstream(pOperator, pDownstream, numOfDownstream);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -179,8 +295,28 @@ void setJoinColumnInfo(SColumnInfo* pColumn, const SColumnNode* pColumnNode) {
|
|||
pColumn->scale = pColumnNode->node.resType.scale;
|
||||
}
|
||||
|
||||
static void mergeJoinDestoryBuildTable(SSHashObj* pBuildTable) {
|
||||
void* p = NULL;
|
||||
int32_t iter = 0;
|
||||
|
||||
while ((p = tSimpleHashIterate(pBuildTable, p, &iter)) != NULL) {
|
||||
SArray* rows = (*(SArray**)p);
|
||||
taosArrayDestroy(rows);
|
||||
}
|
||||
|
||||
tSimpleHashCleanup(pBuildTable);
|
||||
}
|
||||
|
||||
void destroyMergeJoinOperator(void* param) {
|
||||
SJoinOperatorInfo* pJoinOperator = (SJoinOperatorInfo*)param;
|
||||
if (pJoinOperator->pColEqualOnConditions != NULL) {
|
||||
mergeJoinDestoryBuildTable(pJoinOperator->rightBuildTable);
|
||||
taosMemoryFreeClear(pJoinOperator->rightEqOnCondKeyBuf);
|
||||
taosArrayDestroy(pJoinOperator->rightEqOnCondCols);
|
||||
|
||||
taosMemoryFreeClear(pJoinOperator->leftEqOnCondKeyBuf);
|
||||
taosArrayDestroy(pJoinOperator->leftEqOnCondCols);
|
||||
}
|
||||
nodesDestroyNode(pJoinOperator->pCondAfterMerge);
|
||||
|
||||
pJoinOperator->pRes = blockDataDestroy(pJoinOperator->pRes);
|
||||
|
@ -300,21 +436,122 @@ static int32_t mergeJoinGetDownStreamRowsEqualTimeStamp(SOperatorInfo* pOperator
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mergeJoinFillBuildTable(SJoinOperatorInfo* pInfo, SArray* rightRowLocations) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(rightRowLocations); ++i) {
|
||||
SRowLocation* rightRow = taosArrayGet(rightRowLocations, i);
|
||||
int32_t keyLen = fillKeyBufFromTagCols(pInfo->rightEqOnCondCols, rightRow->pDataBlock, rightRow->pos, pInfo->rightEqOnCondKeyBuf);
|
||||
SArray** ppRows = tSimpleHashGet(pInfo->rightBuildTable, pInfo->rightEqOnCondKeyBuf, keyLen);
|
||||
if (!ppRows) {
|
||||
SArray* rows = taosArrayInit(4, sizeof(SRowLocation));
|
||||
taosArrayPush(rows, rightRow);
|
||||
tSimpleHashPut(pInfo->rightBuildTable, pInfo->rightEqOnCondKeyBuf, keyLen, &rows, POINTER_BYTES);
|
||||
} else {
|
||||
taosArrayPush(*ppRows, rightRow);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mergeJoinLeftRowsRightRows(SOperatorInfo* pOperator, SSDataBlock* pRes, int32_t* nRows,
|
||||
const SArray* leftRowLocations, int32_t leftRowIdx,
|
||||
int32_t rightRowIdx, bool useBuildTableTSRange, SArray* rightRowLocations, bool* pReachThreshold) {
|
||||
*pReachThreshold = false;
|
||||
uint32_t limitRowNum = pOperator->resultInfo.threshold;
|
||||
SJoinOperatorInfo* pJoinInfo = pOperator->info;
|
||||
size_t leftNumJoin = taosArrayGetSize(leftRowLocations);
|
||||
|
||||
int32_t i,j;
|
||||
|
||||
for (i = leftRowIdx; i < leftNumJoin; ++i, rightRowIdx = 0) {
|
||||
SRowLocation* leftRow = taosArrayGet(leftRowLocations, i);
|
||||
SArray* pRightRows = NULL;
|
||||
if (useBuildTableTSRange) {
|
||||
int32_t keyLen = fillKeyBufFromTagCols(pJoinInfo->leftEqOnCondCols, leftRow->pDataBlock, leftRow->pos, pJoinInfo->leftEqOnCondKeyBuf);
|
||||
SArray** ppRightRows = tSimpleHashGet(pJoinInfo->rightBuildTable, pJoinInfo->leftEqOnCondKeyBuf, keyLen);
|
||||
if (!ppRightRows) {
|
||||
continue;
|
||||
}
|
||||
pRightRows = *ppRightRows;
|
||||
} else {
|
||||
pRightRows = rightRowLocations;
|
||||
}
|
||||
size_t rightRowsSize = taosArrayGetSize(pRightRows);
|
||||
for (j = rightRowIdx; j < rightRowsSize; ++j) {
|
||||
if (*nRows >= limitRowNum) {
|
||||
*pReachThreshold = true;
|
||||
break;
|
||||
}
|
||||
|
||||
SRowLocation* rightRow = taosArrayGet(pRightRows, j);
|
||||
mergeJoinJoinLeftRight(pOperator, pRes, *nRows, leftRow->pDataBlock, leftRow->pos, rightRow->pDataBlock,
|
||||
rightRow->pos);
|
||||
++*nRows;
|
||||
}
|
||||
if (*pReachThreshold) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*pReachThreshold) {
|
||||
pJoinInfo->rowCtx.rowRemains = true;
|
||||
pJoinInfo->rowCtx.leftRowIdx = i;
|
||||
pJoinInfo->rowCtx.rightRowIdx = j;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void mergeJoinDestroyTSRangeCtx(SJoinOperatorInfo* pJoinInfo, SArray* leftRowLocations, SArray* leftCreatedBlocks,
|
||||
SArray* rightCreatedBlocks, bool rightUseBuildTable, SArray* rightRowLocations) {
|
||||
for (int i = 0; i < taosArrayGetSize(rightCreatedBlocks); ++i) {
|
||||
SSDataBlock* pBlock = taosArrayGetP(rightCreatedBlocks, i);
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
taosArrayDestroy(rightCreatedBlocks);
|
||||
for (int i = 0; i < taosArrayGetSize(leftCreatedBlocks); ++i) {
|
||||
SSDataBlock* pBlock = taosArrayGetP(leftCreatedBlocks, i);
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
if (rightRowLocations != NULL) {
|
||||
taosArrayDestroy(rightRowLocations);
|
||||
}
|
||||
if (rightUseBuildTable) {
|
||||
void* p = NULL;
|
||||
int32_t iter = 0;
|
||||
while ((p = tSimpleHashIterate(pJoinInfo->rightBuildTable, p, &iter)) != NULL) {
|
||||
SArray* rows = (*(SArray**)p);
|
||||
taosArrayDestroy(rows);
|
||||
}
|
||||
tSimpleHashClear(pJoinInfo->rightBuildTable);
|
||||
}
|
||||
|
||||
taosArrayDestroy(leftCreatedBlocks);
|
||||
taosArrayDestroy(leftRowLocations);
|
||||
|
||||
pJoinInfo->rowCtx.rowRemains = false;
|
||||
pJoinInfo->rowCtx.leftRowLocations = NULL;
|
||||
pJoinInfo->rowCtx.leftCreatedBlocks = NULL;
|
||||
pJoinInfo->rowCtx.rightCreatedBlocks = NULL;
|
||||
pJoinInfo->rowCtx.rightUseBuildTable = false;
|
||||
pJoinInfo->rowCtx.rightRowLocations = NULL;
|
||||
}
|
||||
|
||||
static int32_t mergeJoinJoinDownstreamTsRanges(SOperatorInfo* pOperator, int64_t timestamp, SSDataBlock* pRes,
|
||||
int32_t* nRows) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SJoinOperatorInfo* pJoinInfo = pOperator->info;
|
||||
SArray* leftRowLocations = NULL;
|
||||
SArray* leftCreatedBlocks = NULL;
|
||||
SArray* rightRowLocations = NULL;
|
||||
SArray* leftCreatedBlocks = NULL;
|
||||
SArray* rightCreatedBlocks = NULL;
|
||||
int32_t leftRowIdx = 0;
|
||||
int32_t rightRowIdx = 0;
|
||||
int32_t i, j;
|
||||
|
||||
SSHashObj* rightTableHash = NULL;
|
||||
bool rightUseBuildTable = false;
|
||||
|
||||
if (pJoinInfo->rowCtx.rowRemains) {
|
||||
leftRowLocations = pJoinInfo->rowCtx.leftRowLocations;
|
||||
leftCreatedBlocks = pJoinInfo->rowCtx.leftCreatedBlocks;
|
||||
rightUseBuildTable = pJoinInfo->rowCtx.rightUseBuildTable;
|
||||
rightRowLocations = pJoinInfo->rowCtx.rightRowLocations;
|
||||
rightCreatedBlocks = pJoinInfo->rowCtx.rightCreatedBlocks;
|
||||
leftRowIdx = pJoinInfo->rowCtx.leftRowIdx;
|
||||
|
@ -330,78 +567,40 @@ static int32_t mergeJoinJoinDownstreamTsRanges(SOperatorInfo* pOperator, int64_t
|
|||
pJoinInfo->leftPos, timestamp, leftRowLocations, leftCreatedBlocks);
|
||||
mergeJoinGetDownStreamRowsEqualTimeStamp(pOperator, 1, pJoinInfo->rightCol.slotId, pJoinInfo->pRight,
|
||||
pJoinInfo->rightPos, timestamp, rightRowLocations, rightCreatedBlocks);
|
||||
if (pJoinInfo->pColEqualOnConditions != NULL && taosArrayGetSize(rightRowLocations) > 16) {
|
||||
mergeJoinFillBuildTable(pJoinInfo, rightRowLocations);
|
||||
rightUseBuildTable = true;
|
||||
taosArrayDestroy(rightRowLocations);
|
||||
rightRowLocations = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t leftNumJoin = taosArrayGetSize(leftRowLocations);
|
||||
size_t rightNumJoin = taosArrayGetSize(rightRowLocations);
|
||||
uint32_t maxRowNum = *nRows + (leftNumJoin - leftRowIdx - 1) * rightNumJoin + rightNumJoin - rightRowIdx;
|
||||
uint32_t limitRowNum = maxRowNum;
|
||||
if (maxRowNum > pOperator->resultInfo.threshold) {
|
||||
limitRowNum = pOperator->resultInfo.threshold;
|
||||
if (!pJoinInfo->rowCtx.rowRemains) {
|
||||
code = blockDataEnsureCapacity(pRes, pOperator->resultInfo.threshold);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s can not ensure block capacity for join. left: %zu", GET_TASKID(pOperator->pTaskInfo),
|
||||
leftNumJoin);
|
||||
}
|
||||
|
||||
bool reachThreshold = false;
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
mergeJoinLeftRowsRightRows(pOperator, pRes, nRows, leftRowLocations, leftRowIdx,
|
||||
rightRowIdx, rightUseBuildTable, rightRowLocations, &reachThreshold);
|
||||
}
|
||||
|
||||
if (!reachThreshold) {
|
||||
mergeJoinDestroyTSRangeCtx(pJoinInfo, leftRowLocations, leftCreatedBlocks, rightCreatedBlocks,
|
||||
rightUseBuildTable, rightRowLocations);
|
||||
|
||||
} else {
|
||||
pJoinInfo->rowCtx.rowRemains = true;
|
||||
pJoinInfo->rowCtx.ts = timestamp;
|
||||
pJoinInfo->rowCtx.leftRowLocations = leftRowLocations;
|
||||
pJoinInfo->rowCtx.rightRowLocations = rightRowLocations;
|
||||
pJoinInfo->rowCtx.leftCreatedBlocks = leftCreatedBlocks;
|
||||
pJoinInfo->rowCtx.rightCreatedBlocks = rightCreatedBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
code = blockDataEnsureCapacity(pRes, limitRowNum);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s can not ensure block capacity for join. left: %zu, right: %zu", GET_TASKID(pOperator->pTaskInfo),
|
||||
leftNumJoin, rightNumJoin);
|
||||
}
|
||||
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
bool done = false;
|
||||
for (i = leftRowIdx; i < leftNumJoin; ++i, rightRowIdx = 0) {
|
||||
for (j = rightRowIdx; j < rightNumJoin; ++j) {
|
||||
if (*nRows >= limitRowNum) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
SRowLocation* leftRow = taosArrayGet(leftRowLocations, i);
|
||||
SRowLocation* rightRow = taosArrayGet(rightRowLocations, j);
|
||||
mergeJoinJoinLeftRight(pOperator, pRes, *nRows, leftRow->pDataBlock, leftRow->pos, rightRow->pDataBlock,
|
||||
rightRow->pos);
|
||||
++*nRows;
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxRowNum > pOperator->resultInfo.threshold) {
|
||||
pJoinInfo->rowCtx.leftRowIdx = i;
|
||||
pJoinInfo->rowCtx.rightRowIdx = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxRowNum <= pOperator->resultInfo.threshold) {
|
||||
for (int i = 0; i < taosArrayGetSize(rightCreatedBlocks); ++i) {
|
||||
SSDataBlock* pBlock = taosArrayGetP(rightCreatedBlocks, i);
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
taosArrayDestroy(rightCreatedBlocks);
|
||||
taosArrayDestroy(rightRowLocations);
|
||||
for (int i = 0; i < taosArrayGetSize(leftCreatedBlocks); ++i) {
|
||||
SSDataBlock* pBlock = taosArrayGetP(leftCreatedBlocks, i);
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
taosArrayDestroy(leftCreatedBlocks);
|
||||
taosArrayDestroy(leftRowLocations);
|
||||
|
||||
if (pJoinInfo->rowCtx.rowRemains) {
|
||||
pJoinInfo->rowCtx.rowRemains = false;
|
||||
pJoinInfo->rowCtx.leftRowLocations = NULL;
|
||||
pJoinInfo->rowCtx.rightRowLocations = NULL;
|
||||
pJoinInfo->rowCtx.leftCreatedBlocks = NULL;
|
||||
pJoinInfo->rowCtx.rightCreatedBlocks = NULL;
|
||||
}
|
||||
pJoinInfo->rowCtx.rightUseBuildTable = rightUseBuildTable;
|
||||
pJoinInfo->rowCtx.rightRowLocations = rightRowLocations;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "executorInt.h"
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
|
@ -88,39 +90,6 @@ static void switchCtxOrder(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
|||
}
|
||||
}
|
||||
|
||||
static void getNextTimeWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (pInterval->intervalUnit != 'n' && pInterval->intervalUnit != 'y') {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = tw->skey + pInterval->interval - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t key = tw->skey, interval = pInterval->interval;
|
||||
// convert key to second
|
||||
key = convertTimePrecision(key, pInterval->precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
if (pInterval->intervalUnit == 'y') {
|
||||
interval *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t)key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
mon = (int)(mon + interval);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
tw->ekey -= 1;
|
||||
}
|
||||
|
||||
static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockInfo, int32_t order) {
|
||||
STimeWindow w = {0};
|
||||
|
||||
|
@ -130,7 +99,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
|
|||
}
|
||||
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.skey);
|
||||
w = getAlignQueryTimeWindow(pInterval, pBlockInfo->window.skey);
|
||||
ASSERT(w.ekey >= pBlockInfo->window.skey);
|
||||
|
||||
if (w.ekey < pBlockInfo->window.ekey) {
|
||||
|
@ -149,7 +118,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
|
|||
}
|
||||
}
|
||||
} else {
|
||||
w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.ekey);
|
||||
w = getAlignQueryTimeWindow(pInterval, pBlockInfo->window.ekey);
|
||||
ASSERT(w.skey <= pBlockInfo->window.ekey);
|
||||
|
||||
if (w.skey > pBlockInfo->window.skey) {
|
||||
|
@ -206,7 +175,7 @@ static int32_t insertTableToScanIgnoreList(STableScanInfo* pTableScanInfo, uint6
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
taosHashPut(pTableScanInfo->pIgnoreTables, &uid, sizeof(uid), &pTableScanInfo->scanTimes, sizeof(pTableScanInfo->scanTimes));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -215,7 +184,7 @@ static int32_t insertTableToScanIgnoreList(STableScanInfo* pTableScanInfo, uint6
|
|||
static int32_t doDynamicPruneDataBlock(SOperatorInfo* pOperator, SDataBlockInfo* pBlockInfo, uint32_t* status) {
|
||||
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
||||
if (pTableScanInfo->base.pdInfo.pExprSup == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -267,12 +236,13 @@ static bool doLoadBlockSMA(STableScanBase* pTableScanInfo, SSDataBlock* pBlock,
|
|||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||
|
||||
bool allColumnsHaveAgg = true;
|
||||
int32_t code = pAPI->tsdReader.tsdReaderRetrieveBlockSMAInfo(pTableScanInfo->dataReader, pBlock, &allColumnsHaveAgg);
|
||||
bool hasNullSMA = false;
|
||||
int32_t code = pAPI->tsdReader.tsdReaderRetrieveBlockSMAInfo(pTableScanInfo->dataReader, pBlock, &allColumnsHaveAgg, &hasNullSMA);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
if (!allColumnsHaveAgg) {
|
||||
if (!allColumnsHaveAgg || hasNullSMA) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -751,7 +721,7 @@ static SSDataBlock* doGroupedTableScan(SOperatorInfo* pOperator) {
|
|||
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||
|
||||
|
||||
// The read handle is not initialized yet, since no qualified tables exists
|
||||
if (pTableScanInfo->base.dataReader == NULL || pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
|
@ -1072,6 +1042,7 @@ static void setGroupId(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_t grou
|
|||
|
||||
void resetTableScanInfo(STableScanInfo* pTableScanInfo, STimeWindow* pWin, uint64_t ver) {
|
||||
pTableScanInfo->base.cond.twindows = *pWin;
|
||||
pTableScanInfo->base.cond.startVersion = 0;
|
||||
pTableScanInfo->base.cond.endVersion = ver;
|
||||
pTableScanInfo->scanTimes = 0;
|
||||
pTableScanInfo->currentGroupId = -1;
|
||||
|
@ -1194,6 +1165,7 @@ static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_
|
|||
}
|
||||
|
||||
STableScanInfo* pTScanInfo = pInfo->pTableScanOp->info;
|
||||
qDebug("prepare range scan start:%" PRId64 ",end:%" PRId64 ",maxVer:%" PRIu64, win.skey, win.ekey, pInfo->pUpdateInfo->maxDataVersion);
|
||||
resetTableScanInfo(pInfo->pTableScanOp->info, &win, pInfo->pUpdateInfo->maxDataVersion);
|
||||
pInfo->pTableScanOp->status = OP_OPENED;
|
||||
return true;
|
||||
|
@ -1649,6 +1621,10 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
|
|||
|
||||
qDebug("start to exec queue scan, %s", id);
|
||||
|
||||
if (isTaskKilled(pTaskInfo)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
||||
SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp);
|
||||
if (pResult && pResult->info.rows > 0) {
|
||||
|
@ -1661,7 +1637,7 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
|
|||
|
||||
STableScanInfo* pTSInfo = pInfo->pTableScanOp->info;
|
||||
pAPI->tsdReader.tsdReaderClose(pTSInfo->base.dataReader);
|
||||
|
||||
|
||||
pTSInfo->base.dataReader = NULL;
|
||||
qDebug("queue scan tsdb over, switch to wal ver %" PRId64 "", pTaskInfo->streamInfo.snapshotVer + 1);
|
||||
if (pAPI->tqReaderFn.tqReaderSeek(pInfo->tqReader, pTaskInfo->streamInfo.snapshotVer + 1, pTaskInfo->id.str) < 0) {
|
||||
|
@ -1797,9 +1773,10 @@ void streamScanOperatorDecode(void* pBuff, int32_t len, SStreamScanInfo* pInfo)
|
|||
|
||||
static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
||||
// NOTE: this operator does never check if current status is done or not
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
const char* id = GET_TASKID(pTaskInfo);
|
||||
|
||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||
SStreamScanInfo* pInfo = pOperator->info;
|
||||
|
||||
qDebug("stream scan started, %s", GET_TASKID(pTaskInfo));
|
||||
|
@ -1883,11 +1860,12 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
|||
if (pInfo->pRecoverRes != NULL) {
|
||||
pInfo->blockRecoverContiCnt++;
|
||||
calBlockTbName(pInfo, pInfo->pRecoverRes);
|
||||
if (pInfo->pUpdateInfo) {
|
||||
if (!pInfo->igCheckUpdate && pInfo->pUpdateInfo) {
|
||||
if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__SCAN1) {
|
||||
TSKEY maxTs = pAPI->stateStore.updateInfoFillBlockData(pInfo->pUpdateInfo, pInfo->pRecoverRes, pInfo->primaryTsIndex);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs);
|
||||
} else {
|
||||
pInfo->pUpdateInfo->maxDataVersion = pTaskInfo->streamInfo.fillHistoryVer2;
|
||||
doCheckUpdate(pInfo, pInfo->pRecoverRes->info.window.ekey, pInfo->pRecoverRes);
|
||||
}
|
||||
}
|
||||
|
@ -1896,6 +1874,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
|||
printDataBlock(pInfo->pCreateTbRes, "recover createTbl");
|
||||
return pInfo->pCreateTbRes;
|
||||
}
|
||||
|
||||
qDebug("stream recover scan get block, rows %" PRId64, pInfo->pRecoverRes->info.rows);
|
||||
printDataBlock(pInfo->pRecoverRes, "scan recover");
|
||||
return pInfo->pRecoverRes;
|
||||
|
@ -1922,7 +1901,9 @@ FETCH_NEXT_BLOCK:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t current = pInfo->validBlockIndex++;
|
||||
int32_t current = pInfo->validBlockIndex++;
|
||||
qDebug("process %d/%d input data blocks, %s", current, (int32_t) total, id);
|
||||
|
||||
SPackedData* pPacked = taosArrayGet(pInfo->pBlockLists, current);
|
||||
SSDataBlock* pBlock = pPacked->pDataBlock;
|
||||
if (pBlock->info.parTbName[0]) {
|
||||
|
@ -2002,7 +1983,7 @@ FETCH_NEXT_BLOCK:
|
|||
// printDataBlock(pBlock, "stream scan recv");
|
||||
return pBlock;
|
||||
} else if (pInfo->blockType == STREAM_INPUT__DATA_SUBMIT) {
|
||||
qDebug("scan mode %d", pInfo->scanMode);
|
||||
qDebug("stream scan mode:%d, %s", pInfo->scanMode, id);
|
||||
switch (pInfo->scanMode) {
|
||||
case STREAM_SCAN_FROM_RES: {
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
|
||||
|
@ -2057,7 +2038,6 @@ FETCH_NEXT_BLOCK:
|
|||
return pInfo->pUpdateRes;
|
||||
}
|
||||
|
||||
const char* id = GET_TASKID(pTaskInfo);
|
||||
SSDataBlock* pBlock = pInfo->pRes;
|
||||
SDataBlockInfo* pBlockInfo = &pBlock->info;
|
||||
int32_t totalBlocks = taosArrayGetSize(pInfo->pBlockLists);
|
||||
|
@ -2087,8 +2067,13 @@ FETCH_NEXT_BLOCK:
|
|||
|
||||
while (pAPI->tqReaderFn.tqNextBlockImpl(pInfo->tqReader, id)) {
|
||||
SSDataBlock* pRes = NULL;
|
||||
|
||||
int32_t code = pAPI->tqReaderFn.tqRetrieveBlock(pInfo->tqReader, &pRes, id);
|
||||
qDebug("retrieve data from submit completed code:%s, rows:%" PRId64 " %s", tstrerror(code), pRes->info.rows,
|
||||
id);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS || pRes->info.rows == 0) {
|
||||
qDebug("retrieve data failed, try next block in submit block, %s", id);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2096,6 +2081,7 @@ FETCH_NEXT_BLOCK:
|
|||
|
||||
if (pInfo->pCreateTbRes->info.rows > 0) {
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_RES;
|
||||
qDebug("create table res exists, rows:%"PRId64" return from stream scan, %s", pInfo->pCreateTbRes->info.rows, id);
|
||||
return pInfo->pCreateTbRes;
|
||||
}
|
||||
|
||||
|
@ -2104,6 +2090,8 @@ FETCH_NEXT_BLOCK:
|
|||
pBlock->info.dataLoad = 1;
|
||||
blockDataUpdateTsWindow(pBlock, pInfo->primaryTsIndex);
|
||||
|
||||
qDebug("%" PRId64 " rows in datablock, update res:%" PRId64 " %s", pBlockInfo->rows,
|
||||
pInfo->pUpdateDataRes->info.rows, id);
|
||||
if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -2120,7 +2108,7 @@ FETCH_NEXT_BLOCK:
|
|||
pInfo->numOfExec++;
|
||||
pOperator->resultInfo.totalRows += pBlockInfo->rows;
|
||||
|
||||
qDebug("stream scan get source rows:%" PRId64", %s", pBlockInfo->rows, id);
|
||||
qDebug("stream scan completed, and return source rows:%" PRId64", %s", pBlockInfo->rows, id);
|
||||
if (pBlockInfo->rows > 0) {
|
||||
return pBlock;
|
||||
}
|
||||
|
@ -2306,7 +2294,8 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
|
|||
SArray* pColIds = NULL;
|
||||
SStreamScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||
const char* idstr = pTaskInfo->id.str;
|
||||
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -2417,7 +2406,7 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
|
|||
// set the extract column id to streamHandle
|
||||
pAPI->tqReaderFn.tqReaderSetColIdList(pInfo->tqReader, pColIds);
|
||||
SArray* tableIdList = extractTableIdList(((STableScanInfo*)(pInfo->pTableScanOp->info))->base.pTableListInfo);
|
||||
code = pAPI->tqReaderFn.tqReaderSetQueryTableList(pInfo->tqReader, tableIdList);
|
||||
code = pAPI->tqReaderFn.tqReaderSetQueryTableList(pInfo->tqReader, tableIdList, idstr);
|
||||
if (code != 0) {
|
||||
taosArrayDestroy(tableIdList);
|
||||
goto _error;
|
||||
|
@ -2467,6 +2456,7 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
|
|||
int32_t len = 0;
|
||||
pAPI->stateStore.streamStateGetInfo(pTaskInfo->streamInfo.pState, STREAM_SCAN_OP_NAME, strlen(STREAM_SCAN_OP_NAME), &buff, &len);
|
||||
streamScanOperatorDecode(buff, len, pInfo);
|
||||
taosMemoryFree(buff);
|
||||
}
|
||||
|
||||
setOperatorInfo(pOperator, STREAM_SCAN_OP_NAME, QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN, false, OP_NOT_OPENED, pInfo,
|
||||
|
@ -3481,3 +3471,5 @@ static void destoryTableCountScanOperator(void* param) {
|
|||
taosArrayDestroy(pTableCountScanInfo->stbUidList);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
|
|
@ -517,11 +517,16 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
|||
return;
|
||||
}
|
||||
|
||||
// the endKey is now the aligned time window value. truncate time window isn't correct.
|
||||
pFillInfo->end = endKey;
|
||||
if (!FILL_IS_ASC_FILL(pFillInfo)) {
|
||||
pFillInfo->end = taosTimeTruncate(endKey, &pFillInfo->interval, pFillInfo->interval.precision);
|
||||
pFillInfo->end = taosTimeAdd(pFillInfo->end, pFillInfo->interval.interval, pFillInfo->interval.intervalUnit,pFillInfo->interval.precision);
|
||||
|
||||
#if 0
|
||||
if (pFillInfo->order == TSDB_ORDER_ASC) {
|
||||
ASSERT(pFillInfo->start <= pFillInfo->end);
|
||||
} else {
|
||||
ASSERT(pFillInfo->start >= pFillInfo->end);
|
||||
}
|
||||
#endif
|
||||
|
||||
pFillInfo->index = 0;
|
||||
pFillInfo->numOfRows = numOfRows;
|
||||
|
@ -531,6 +536,13 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput)
|
|||
pFillInfo->pSrcBlock = (SSDataBlock*)pInput;
|
||||
}
|
||||
|
||||
void taosFillUpdateStartTimestampInfo(SFillInfo* pFillInfo, int64_t ts) {
|
||||
pFillInfo->start = ts;
|
||||
pFillInfo->currentKey = ts;
|
||||
}
|
||||
|
||||
bool taosFillNotStarted(const SFillInfo* pFillInfo) {return pFillInfo->start == pFillInfo->currentKey;}
|
||||
|
||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo) {
|
||||
int32_t remain = taosNumOfRemainRows(pFillInfo);
|
||||
if (remain > 0) {
|
||||
|
@ -562,9 +574,10 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma
|
|||
ASSERT(numOfRes >= numOfRows);
|
||||
} else { // reach the end of data
|
||||
if ((ekey1 < pFillInfo->currentKey && FILL_IS_ASC_FILL(pFillInfo)) ||
|
||||
(ekey1 >= pFillInfo->currentKey && !FILL_IS_ASC_FILL(pFillInfo))) {
|
||||
(ekey1 > pFillInfo->currentKey && !FILL_IS_ASC_FILL(pFillInfo))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
numOfRes = taosTimeCountInterval(ekey1, pFillInfo->currentKey, pFillInfo->interval.sliding,
|
||||
pFillInfo->interval.slidingUnit, pFillInfo->interval.precision);
|
||||
numOfRes += 1;
|
||||
|
|
|
@ -271,43 +271,6 @@ int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimary
|
|||
return num;
|
||||
}
|
||||
|
||||
static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t order, STimeWindow* tw) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (pInterval->intervalUnit != 'n' && pInterval->intervalUnit != 'y') {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = tw->skey + pInterval->interval - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t key = tw->skey, interval = pInterval->interval;
|
||||
// convert key to second
|
||||
key = convertTimePrecision(key, precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
if (pInterval->intervalUnit == 'y') {
|
||||
interval *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t)key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, precision);
|
||||
|
||||
mon = (int)(mon + interval);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, precision);
|
||||
|
||||
tw->ekey -= 1;
|
||||
}
|
||||
|
||||
void getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
getNextTimeWindow(pInterval, pInterval->precision, order, tw);
|
||||
}
|
||||
|
||||
void doTimeWindowInterpolation(SArray* pPrevValues, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, TSKEY curTs,
|
||||
int32_t curRowIndex, TSKEY windowKey, int32_t type, SExprSupp* pSup) {
|
||||
SqlFunctionCtx* pCtx = pSup->pCtx;
|
||||
|
@ -449,7 +412,7 @@ static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SEx
|
|||
}
|
||||
|
||||
bool inCalSlidingWindow(SInterval* pInterval, STimeWindow* pWin, TSKEY calStart, TSKEY calEnd, EStreamType blockType) {
|
||||
if (pInterval->interval != pInterval->sliding &&
|
||||
if (pInterval->interval != pInterval->sliding &&
|
||||
((pWin->ekey < calStart || pWin->skey > calEnd) || (blockType == STREAM_PULL_DATA && pWin->skey < calStart) )) {
|
||||
return false;
|
||||
}
|
||||
|
@ -466,7 +429,7 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
bool ascQuery = (order == TSDB_ORDER_ASC);
|
||||
|
||||
int32_t precision = pInterval->precision;
|
||||
getNextTimeWindow(pInterval, precision, order, pNext);
|
||||
getNextTimeWindow(pInterval, pNext, order);
|
||||
|
||||
// next time window is not in current block
|
||||
if ((pNext->skey > pDataBlockInfo->window.ekey && order == TSDB_ORDER_ASC) ||
|
||||
|
@ -511,7 +474,7 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
|
||||
TSKEY next = primaryKeys[startPos];
|
||||
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
|
||||
pNext->skey = taosTimeTruncate(next, pInterval, precision);
|
||||
pNext->skey = taosTimeTruncate(next, pInterval);
|
||||
pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
} else {
|
||||
pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
|
||||
|
@ -520,7 +483,7 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
} else if ((!ascQuery) && primaryKeys[startPos] < pNext->skey) {
|
||||
TSKEY next = primaryKeys[startPos];
|
||||
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
|
||||
pNext->skey = taosTimeTruncate(next, pInterval, precision);
|
||||
pNext->skey = taosTimeTruncate(next, pInterval);
|
||||
pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
} else {
|
||||
pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
|
||||
|
@ -1370,14 +1333,14 @@ static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDa
|
|||
|
||||
do {
|
||||
if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i], pBlock->info.type)) {
|
||||
getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
continue;
|
||||
}
|
||||
uint64_t winGpId = pGpDatas[i];
|
||||
SWinKey winRes = {.ts = win.skey, .groupId = winGpId};
|
||||
void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey));
|
||||
if (chIds) {
|
||||
getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
continue;
|
||||
}
|
||||
bool res = doDeleteWindow(pOperator, win.skey, winGpId);
|
||||
|
@ -1387,7 +1350,7 @@ static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDa
|
|||
if (pUpdatedMap) {
|
||||
tSimpleHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey));
|
||||
}
|
||||
getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
} while (win.ekey <= endTsCols[i]);
|
||||
}
|
||||
}
|
||||
|
@ -1623,7 +1586,7 @@ void initIntervalDownStream(SOperatorInfo* downstream, uint16_t type, SStreamInt
|
|||
SStreamScanInfo* pScanInfo = downstream->info;
|
||||
pScanInfo->windowSup.parentType = type;
|
||||
pScanInfo->windowSup.pIntervalAggSup = &pInfo->aggSup;
|
||||
if (!pScanInfo->igCheckUpdate && !pScanInfo->pUpdateInfo) {
|
||||
if (!pScanInfo->pUpdateInfo) {
|
||||
pScanInfo->pUpdateInfo = pAPI->updateInfoInitP(&pInfo->interval, pInfo->twAggSup.waterMark);
|
||||
}
|
||||
|
||||
|
@ -2150,28 +2113,29 @@ static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pB
|
|||
}
|
||||
|
||||
void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SInterval* pInterval) {
|
||||
SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
|
||||
TSKEY* tsData = (TSKEY*)pStartCol->pData;
|
||||
SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
|
||||
TSKEY* tsEndData = (TSKEY*)pEndCol->pData;
|
||||
SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
|
||||
uint64_t* groupIdData = (uint64_t*)pGroupCol->pData;
|
||||
int32_t chId = getChildIndex(pBlock);
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||
TSKEY winTs = tsData[i];
|
||||
while (winTs < tsEndData[i]) {
|
||||
while (winTs <= tsEndData[i]) {
|
||||
SWinKey winRes = {.ts = winTs, .groupId = groupIdData[i]};
|
||||
void* chIds = taosHashGet(pMap, &winRes, sizeof(SWinKey));
|
||||
if (chIds) {
|
||||
SArray* chArray = *(SArray**)chIds;
|
||||
int32_t index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ);
|
||||
if (index != -1) {
|
||||
qDebug("===stream===window %" PRId64 " delete child id %d", winRes.ts, chId);
|
||||
qDebug("===stream===retrive window %" PRId64 " delete child id %d", winRes.ts, chId);
|
||||
taosArrayRemove(chArray, index);
|
||||
if (taosArrayGetSize(chArray) == 0) {
|
||||
// pull data is over
|
||||
taosArrayDestroy(chArray);
|
||||
taosHashRemove(pMap, &winRes, sizeof(SWinKey));
|
||||
qDebug("===stream===retrive pull data over.window %" PRId64 , winRes.ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2475,6 +2439,15 @@ static inline int winPosCmprImpl(const void* pKey1, const void* pKey2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void resetUnCloseWinInfo(SSHashObj* winMap) {
|
||||
void* pIte = NULL;
|
||||
int32_t iter = 0;
|
||||
while ((pIte = tSimpleHashIterate(winMap, pIte, &iter)) != NULL) {
|
||||
SRowBuffPos* pPos = *(SRowBuffPos**)pIte;
|
||||
pPos->beUsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
||||
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
@ -2508,6 +2481,11 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable);
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
if (!IS_FINAL_OP(pInfo)) {
|
||||
clearFunctionContext(&pOperator->exprSupp);
|
||||
|
@ -2601,6 +2579,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
break;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) {
|
||||
pInfo->recvGetAll = true;
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) {
|
||||
|
@ -2809,6 +2788,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
compareTs, pInfo->pState, pInfo->twAggSup.deleteMark);
|
||||
pInfo->dataVersion = 0;
|
||||
pInfo->statestore = pTaskInfo->storageAPI.stateStore;
|
||||
pInfo->recvGetAll = false;
|
||||
|
||||
pOperator->operatorType = pPhyNode->type;
|
||||
pOperator->blocking = true;
|
||||
|
@ -2903,7 +2883,7 @@ void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uin
|
|||
SStreamScanInfo* pScanInfo = downstream->info;
|
||||
pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = pAggSup->gap, .parentType = type};
|
||||
pScanInfo->pState = pAggSup->pState;
|
||||
if ((!pScanInfo->igCheckUpdate || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE) && !pScanInfo->pUpdateInfo) {
|
||||
if (!pScanInfo->pUpdateInfo) {
|
||||
pScanInfo->pUpdateInfo = pAggSup->stateStore.updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, pTwSup->waterMark);
|
||||
}
|
||||
pScanInfo->twAggSup = *pTwSup;
|
||||
|
@ -4787,6 +4767,12 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
printDataBlock(pInfo->binfo.pRes, "single interval");
|
||||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable);
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
if (pInfo->twAggSup.maxTs > 0 &&
|
||||
pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) {
|
||||
|
@ -4826,6 +4812,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
qDebug("===stream===single interval recv|block type STREAM_GET_ALL");
|
||||
pInfo->recvGetAll = true;
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) {
|
||||
|
@ -4996,6 +4983,8 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL);
|
||||
|
||||
pInfo->statestore = pTaskInfo->storageAPI.stateStore;
|
||||
pInfo->recvGetAll = false;
|
||||
|
||||
initIntervalDownStream(downstream, pPhyNode->type, pInfo);
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "taos.h"
|
||||
#include "thash.h"
|
||||
#include "tsimplehash.h"
|
||||
#include "executor.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
|
||||
namespace {
|
||||
SInterval createInterval(int64_t interval, int64_t sliding, int64_t offset, char intervalUnit, char slidingUnit,
|
||||
char offsetUnit, int8_t precision) {
|
||||
SInterval v = {0};
|
||||
v.interval = interval;
|
||||
v.intervalUnit = intervalUnit;
|
||||
v.sliding = sliding;
|
||||
v.slidingUnit = slidingUnit;
|
||||
v.offset = offset;
|
||||
v.offsetUnit = offsetUnit;
|
||||
v.precision = precision;
|
||||
return v;
|
||||
}
|
||||
|
||||
void printTimeWindow(STimeWindow* pWindow, int8_t precision, int64_t ts) {
|
||||
char buf[64] = {0};
|
||||
char bufs[64] = {0};
|
||||
char bufe[64] = {0};
|
||||
|
||||
taosFormatUtcTime(buf, tListLen(buf), ts, precision);
|
||||
|
||||
taosFormatUtcTime(bufs, tListLen(bufs), pWindow->skey, precision);
|
||||
taosFormatUtcTime(bufe, tListLen(bufe), pWindow->ekey, precision);
|
||||
|
||||
printf("%s [%s - %s]\n", buf, bufs, bufe);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(testCase, timewindow_gen) {
|
||||
// set correct time zone
|
||||
osSetTimezone("UTC");
|
||||
int32_t precision = TSDB_TIME_PRECISION_MILLI;
|
||||
|
||||
SInterval interval =
|
||||
createInterval(10 * 86400 * 1000, 10 * 86400 * 1000, 0, 'd', 'd', 'd', precision);
|
||||
|
||||
int64_t key = 1659312000L * 1000; // 2022-8-1 00:00:00 // UTC+8 (ms)
|
||||
|
||||
STimeWindow w = {0};
|
||||
getInitialStartTimeWindow(&interval, key, &w, true);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&interval, &w, TSDB_ORDER_ASC);
|
||||
printf("next\n");
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("---------------------------------------------------\n");
|
||||
SInterval monthInterval =
|
||||
createInterval(1, 1, 0, 'n', 'n', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
getInitialStartTimeWindow(&monthInterval, key, &w, true);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&monthInterval, &w, TSDB_ORDER_ASC);
|
||||
printf("next\n");
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("----------------------------------------------------------\n");
|
||||
SInterval slidingInterval = createInterval(1, 10*86400*1000, 0, 'n', 'd', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
getInitialStartTimeWindow(&slidingInterval, key, &w, true);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printf("next\n");
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("-----------------calendar_interval_1n_sliding_1d-------\n");
|
||||
SInterval calendar_interval_1n = createInterval(1, 1*86400*1000, 0, 'n', 'd', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
int64_t k1 = 1664409600 * 1000L;
|
||||
getInitialStartTimeWindow(&calendar_interval_1n, k1, &w, true);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
printf("next\n");
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("----------------interval_1d_clendar_sliding_1n---------\n");
|
||||
SInterval interval_1d_calendar_sliding_1n = createInterval(1*86400*1000L, 1, 0, 'd', 'n', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
|
||||
k1 = 1664409600 * 1000L;
|
||||
getInitialStartTimeWindow(&interval_1d_calendar_sliding_1n, k1, &w, true);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
printf("next time window:\n");
|
||||
getNextTimeWindow(&interval_1d_calendar_sliding_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
getNextTimeWindow(&interval_1d_calendar_sliding_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
getNextTimeWindow(&interval_1d_calendar_sliding_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
printf("----------------interval_1d_sliding_1d_calendar_offset_1n---------\n");
|
||||
SInterval offset_1n = createInterval(10*86400*1000L, 10*86400*1000L, 1, 'd', 'd', 'n', TSDB_TIME_PRECISION_MILLI);
|
||||
getInitialStartTimeWindow(&offset_1n, k1, &w, true);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
|
@ -499,7 +499,7 @@ static int64_t getNumOfElems(SqlFunctionCtx* pCtx) {
|
|||
*/
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
if (pInput->colDataSMAIsSet && pInput->totalRows == pInput->numOfRows && !IS_VAR_DATA_TYPE(pInputCol->info.type)) {
|
||||
if (pInput->colDataSMAIsSet && pInput->totalRows == pInput->numOfRows) {
|
||||
numOfElem = pInput->numOfRows - pInput->pColumnDataAgg[0]->numOfNull;
|
||||
} else {
|
||||
if (pInputCol->hasNull) {
|
||||
|
|
|
@ -402,6 +402,7 @@ static int32_t logicJoinCopy(const SJoinLogicNode* pSrc, SJoinLogicNode* pDst) {
|
|||
COPY_SCALAR_FIELD(joinType);
|
||||
CLONE_NODE_FIELD(pMergeCondition);
|
||||
CLONE_NODE_FIELD(pOnConditions);
|
||||
CLONE_NODE_FIELD(pColEqualOnConditions);
|
||||
COPY_SCALAR_FIELD(isSingleTableJoin);
|
||||
COPY_SCALAR_FIELD(inputTsOrder);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -589,7 +590,7 @@ static int32_t physiSysTableScanCopy(const SSystemTableScanPhysiNode* pSrc, SSys
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t physiWindowCopy(const SWinodwPhysiNode* pSrc, SWinodwPhysiNode* pDst) {
|
||||
static int32_t physiWindowCopy(const SWindowPhysiNode* pSrc, SWindowPhysiNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, physiNodeCopy);
|
||||
CLONE_NODE_LIST_FIELD(pExprs);
|
||||
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||
|
|
|
@ -1428,6 +1428,7 @@ static int32_t jsonToLogicPlan(const SJson* pJson, void* pObj) {
|
|||
static const char* jkJoinLogicPlanJoinType = "JoinType";
|
||||
static const char* jkJoinLogicPlanOnConditions = "OnConditions";
|
||||
static const char* jkJoinLogicPlanMergeCondition = "MergeConditions";
|
||||
static const char* jkJoinLogicPlanColEqualOnConditions = "ColumnEqualOnConditions";
|
||||
|
||||
static int32_t logicJoinNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SJoinLogicNode* pNode = (const SJoinLogicNode*)pObj;
|
||||
|
@ -1442,7 +1443,9 @@ static int32_t logicJoinNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkJoinLogicPlanOnConditions, nodeToJson, pNode->pOnConditions);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkJoinLogicPlanColEqualOnConditions, nodeToJson, pNode->pColEqualOnConditions);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1459,7 +1462,9 @@ static int32_t jsonToLogicJoinNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkJoinLogicPlanOnConditions, &pNode->pOnConditions);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkJoinLogicPlanColEqualOnConditions, &pNode->pColEqualOnConditions);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1890,6 +1895,7 @@ static const char* jkJoinPhysiPlanInputTsOrder = "InputTsOrder";
|
|||
static const char* jkJoinPhysiPlanMergeCondition = "MergeCondition";
|
||||
static const char* jkJoinPhysiPlanOnConditions = "OnConditions";
|
||||
static const char* jkJoinPhysiPlanTargets = "Targets";
|
||||
static const char* jkJoinPhysiPlanColEqualOnConditions = "ColumnEqualOnConditions";
|
||||
|
||||
static int32_t physiJoinNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SSortMergeJoinPhysiNode* pNode = (const SSortMergeJoinPhysiNode*)pObj;
|
||||
|
@ -1910,7 +1916,9 @@ static int32_t physiJoinNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkJoinPhysiPlanTargets, pNode->pTargets);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkJoinPhysiPlanColEqualOnConditions, nodeToJson, pNode->pColEqualOnConditions);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1933,7 +1941,9 @@ static int32_t jsonToPhysiJoinNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkJoinPhysiPlanTargets, &pNode->pTargets);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkJoinPhysiPlanColEqualOnConditions, &pNode->pColEqualOnConditions);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -2144,7 +2154,7 @@ static const char* jkWindowPhysiPlanOutputTsOrder = "outputTsOrder";
|
|||
static const char* jkWindowPhysiPlanMergeDataBlock = "MergeDataBlock";
|
||||
|
||||
static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SWinodwPhysiNode* pNode = (const SWinodwPhysiNode*)pObj;
|
||||
const SWindowPhysiNode* pNode = (const SWindowPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -2185,7 +2195,7 @@ static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
|
|||
}
|
||||
|
||||
static int32_t jsonToPhysiWindowNode(const SJson* pJson, void* pObj) {
|
||||
SWinodwPhysiNode* pNode = (SWinodwPhysiNode*)pObj;
|
||||
SWindowPhysiNode* pNode = (SWindowPhysiNode*)pObj;
|
||||
|
||||
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -82,9 +82,7 @@ static bool columnNodeEqual(const SColumnNode* a, const SColumnNode* b) {
|
|||
COMPARE_STRING_FIELD(dbName);
|
||||
COMPARE_STRING_FIELD(tableName);
|
||||
COMPARE_STRING_FIELD(colName);
|
||||
if (0 == a->tableId) {
|
||||
COMPARE_STRING_FIELD(tableAlias);
|
||||
}
|
||||
COMPARE_STRING_FIELD(tableAlias);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2319,7 +2319,8 @@ enum {
|
|||
PHY_SORT_MERGE_JOIN_CODE_MERGE_CONDITION,
|
||||
PHY_SORT_MERGE_JOIN_CODE_ON_CONDITIONS,
|
||||
PHY_SORT_MERGE_JOIN_CODE_TARGETS,
|
||||
PHY_SORT_MERGE_JOIN_CODE_INPUT_TS_ORDER
|
||||
PHY_SORT_MERGE_JOIN_CODE_INPUT_TS_ORDER,
|
||||
PHY_SORT_MERGE_JOIN_CODE_TAG_EQUAL_CONDITIONS
|
||||
};
|
||||
|
||||
static int32_t physiJoinNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
@ -2341,7 +2342,9 @@ static int32_t physiJoinNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeEnum(pEncoder, PHY_SORT_MERGE_JOIN_CODE_INPUT_TS_ORDER, pNode->inputTsOrder);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_TAG_EQUAL_CONDITIONS, nodeToMsg, pNode->pColEqualOnConditions);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -2370,6 +2373,9 @@ static int32_t msgToPhysiJoinNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case PHY_SORT_MERGE_JOIN_CODE_INPUT_TS_ORDER:
|
||||
code = tlvDecodeEnum(pTlv, &pNode->inputTsOrder, sizeof(pNode->inputTsOrder));
|
||||
break;
|
||||
case PHY_SORT_MERGE_JOIN_CODE_TAG_EQUAL_CONDITIONS:
|
||||
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pColEqualOnConditions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2642,7 +2648,7 @@ enum {
|
|||
};
|
||||
|
||||
static int32_t physiWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
const SWinodwPhysiNode* pNode = (const SWinodwPhysiNode*)pObj;
|
||||
const SWindowPhysiNode* pNode = (const SWindowPhysiNode*)pObj;
|
||||
|
||||
int32_t code = tlvEncodeObj(pEncoder, PHY_WINDOW_CODE_BASE_NODE, physiNodeToMsg, &pNode->node);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -2683,7 +2689,7 @@ static int32_t physiWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
}
|
||||
|
||||
static int32_t msgToPhysiWindowNode(STlvDecoder* pDecoder, void* pObj) {
|
||||
SWinodwPhysiNode* pNode = (SWinodwPhysiNode*)pObj;
|
||||
SWindowPhysiNode* pNode = (SWindowPhysiNode*)pObj;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
STlv* pTlv = NULL;
|
||||
|
|
|
@ -120,9 +120,9 @@ int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len) {
|
|||
}
|
||||
|
||||
if (colNode->tableAlias[0]) {
|
||||
*len += snprintf(buf + *len, bufSize - *len, "`%s`", colNode->colName);
|
||||
*len += snprintf(buf + *len, bufSize - *len, "`%s`", colNode->node.userAlias);
|
||||
} else {
|
||||
*len += snprintf(buf + *len, bufSize - *len, "%s", colNode->colName);
|
||||
*len += snprintf(buf + *len, bufSize - *len, "%s", colNode->node.userAlias);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -608,7 +608,7 @@ static void destroyPhysiNode(SPhysiNode* pNode) {
|
|||
nodesDestroyNode(pNode->pSlimit);
|
||||
}
|
||||
|
||||
static void destroyWinodwPhysiNode(SWinodwPhysiNode* pNode) {
|
||||
static void destroyWinodwPhysiNode(SWindowPhysiNode* pNode) {
|
||||
destroyPhysiNode((SPhysiNode*)pNode);
|
||||
nodesDestroyList(pNode->pExprs);
|
||||
nodesDestroyList(pNode->pFuncs);
|
||||
|
@ -921,6 +921,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
break;
|
||||
case QUERY_NODE_CREATE_TOPIC_STMT:
|
||||
nodesDestroyNode(((SCreateTopicStmt*)pNode)->pQuery);
|
||||
nodesDestroyNode(((SCreateTopicStmt*)pNode)->pWhere);
|
||||
break;
|
||||
case QUERY_NODE_DROP_TOPIC_STMT: // no pointer field
|
||||
case QUERY_NODE_DROP_CGROUP_STMT: // no pointer field
|
||||
|
@ -1088,6 +1089,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||
nodesDestroyNode(pLogicNode->pMergeCondition);
|
||||
nodesDestroyNode(pLogicNode->pOnConditions);
|
||||
nodesDestroyNode(pLogicNode->pColEqualOnConditions);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_LOGIC_PLAN_AGG: {
|
||||
|
@ -1220,6 +1222,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyNode(pPhyNode->pMergeCondition);
|
||||
nodesDestroyNode(pPhyNode->pOnConditions);
|
||||
nodesDestroyList(pPhyNode->pTargets);
|
||||
nodesDestroyNode(pPhyNode->pColEqualOnConditions);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
|
||||
|
@ -1257,7 +1260,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL:
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
|
||||
destroyWinodwPhysiNode((SWindowPhysiNode*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: {
|
||||
|
@ -1273,19 +1276,19 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION:
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
|
||||
destroyWinodwPhysiNode((SWindowPhysiNode*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: {
|
||||
SStateWinodwPhysiNode* pPhyNode = (SStateWinodwPhysiNode*)pNode;
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pPhyNode);
|
||||
destroyWinodwPhysiNode((SWindowPhysiNode*)pPhyNode);
|
||||
nodesDestroyNode(pPhyNode->pStateKey);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT: {
|
||||
SEventWinodwPhysiNode* pPhyNode = (SEventWinodwPhysiNode*)pNode;
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pPhyNode);
|
||||
destroyWinodwPhysiNode((SWindowPhysiNode*)pPhyNode);
|
||||
nodesDestroyNode(pPhyNode->pStartCond);
|
||||
nodesDestroyNode(pPhyNode->pEndCond);
|
||||
break;
|
||||
|
@ -2073,7 +2076,7 @@ char* nodesGetNameFromColumnNode(SNode* pNode) {
|
|||
return "NULL";
|
||||
}
|
||||
|
||||
return ((SColumnNode*)pNode)->colName;
|
||||
return ((SColumnNode*)pNode)->node.userAlias;
|
||||
}
|
||||
|
||||
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots) {
|
||||
|
|
|
@ -207,7 +207,7 @@ SNode* createCreateTopicStmtUseQuery(SAstCreateContext* pCxt, bool ignoreExists,
|
|||
SNode* createCreateTopicStmtUseDb(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SToken* pSubDbName,
|
||||
bool withMeta);
|
||||
SNode* createCreateTopicStmtUseTable(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SNode* pRealTable,
|
||||
bool withMeta);
|
||||
bool withMeta, SNode* pWhere);
|
||||
SNode* createDropTopicStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SToken* pTopicName);
|
||||
SNode* createDropCGroupStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pCGroupId, SToken* pTopicName);
|
||||
SNode* createAlterLocalStmt(SAstCreateContext* pCxt, const SToken* pConfig, const SToken* pValue);
|
||||
|
|
|
@ -115,6 +115,7 @@ int32_t getTableIndexFromCache(SParseMetaCache* pMetaCache, const SName* pName,
|
|||
int32_t getTableCfgFromCache(SParseMetaCache* pMetaCache, const SName* pName, STableCfg** pOutput);
|
||||
int32_t getDnodeListFromCache(SParseMetaCache* pMetaCache, SArray** pDnodes);
|
||||
void destoryParseMetaCache(SParseMetaCache* pMetaCache, bool request);
|
||||
SNode* createSelectStmtImpl(bool isDistinct, SNodeList* pProjectionList, SNode* pTable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -543,9 +543,9 @@ cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) AS DATABASE db_name(C).
|
|||
cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B)
|
||||
WITH META AS DATABASE db_name(C). { pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, A, &B, &C, true); }
|
||||
cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B)
|
||||
AS STABLE full_table_name(C). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, false); }
|
||||
AS STABLE full_table_name(C) where_clause_opt(D). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, false, D); }
|
||||
cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B)
|
||||
WITH META AS STABLE full_table_name(C). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, true); }
|
||||
WITH META AS STABLE full_table_name(C) where_clause_opt(D). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, true, D); }
|
||||
cmd ::= DROP TOPIC exists_opt(A) topic_name(B). { pCxt->pRootNode = createDropTopicStmt(pCxt, A, &B); }
|
||||
cmd ::= DROP CONSUMER GROUP exists_opt(A) cgroup_name(B) ON topic_name(C). { pCxt->pRootNode = createDropCGroupStmt(pCxt, A, &B, &C); }
|
||||
|
||||
|
|
|
@ -259,8 +259,19 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
|
|||
strcpy(pExpr->userAlias, ((SColumnNode*)pExpr)->colName);
|
||||
} else {
|
||||
int32_t len = TMIN(sizeof(pExpr->aliasName) - 1, pRawExpr->n);
|
||||
strncpy(pExpr->aliasName, pRawExpr->p, len);
|
||||
pExpr->aliasName[len] = '\0';
|
||||
|
||||
// See TS-3398.
|
||||
// Len of pRawExpr->p could be larger than len of aliasName[TSDB_COL_NAME_LEN].
|
||||
// If aliasName is truncated, hash value of aliasName could be the same.
|
||||
T_MD5_CTX ctx;
|
||||
tMD5Init(&ctx);
|
||||
tMD5Update(&ctx, (uint8_t*)pRawExpr->p, pRawExpr->n);
|
||||
tMD5Final(&ctx);
|
||||
char* p = pExpr->aliasName;
|
||||
for (uint8_t i = 0; i < tListLen(ctx.digest); ++i) {
|
||||
sprintf(p, "%02x", ctx.digest[i]);
|
||||
p += 2;
|
||||
}
|
||||
strncpy(pExpr->userAlias, pRawExpr->p, len);
|
||||
pExpr->userAlias[len] = '\0';
|
||||
}
|
||||
|
@ -822,16 +833,9 @@ SNode* addFillClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pFill) {
|
|||
|
||||
SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
SSelectStmt* select = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
|
||||
SNode* select = createSelectStmtImpl(isDistinct, pProjectionList, pTable);
|
||||
CHECK_OUT_OF_MEM(select);
|
||||
select->isDistinct = isDistinct;
|
||||
select->pProjectionList = pProjectionList;
|
||||
select->pFromTable = pTable;
|
||||
sprintf(select->stmtName, "%p", select);
|
||||
select->isTimeLineResult = true;
|
||||
select->onlyHasKeepOrderFunc = true;
|
||||
select->timeRange = TSWINDOW_INITIALIZER;
|
||||
return (SNode*)select;
|
||||
return select;
|
||||
}
|
||||
|
||||
static void setSubquery(SNode* pStmt) {
|
||||
|
@ -1712,7 +1716,7 @@ SNode* createCreateTopicStmtUseDb(SAstCreateContext* pCxt, bool ignoreExists, ST
|
|||
}
|
||||
|
||||
SNode* createCreateTopicStmtUseTable(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SNode* pRealTable,
|
||||
bool withMeta) {
|
||||
bool withMeta, SNode* pWhere) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
if (!checkTopicName(pCxt, pTopicName)) {
|
||||
return NULL;
|
||||
|
@ -1722,6 +1726,8 @@ SNode* createCreateTopicStmtUseTable(SAstCreateContext* pCxt, bool ignoreExists,
|
|||
COPY_STRING_FORM_ID_TOKEN(pStmt->topicName, pTopicName);
|
||||
pStmt->ignoreExists = ignoreExists;
|
||||
pStmt->withMeta = withMeta;
|
||||
pStmt->pWhere = pWhere;
|
||||
|
||||
strcpy(pStmt->subDbName, ((SRealTableNode*)pRealTable)->table.dbName);
|
||||
strcpy(pStmt->subSTbName, ((SRealTableNode*)pRealTable)->table.tableName);
|
||||
nodesDestroyNode(pRealTable);
|
||||
|
|
|
@ -355,6 +355,11 @@ static int32_t collectMetaKeyFromCreateTopic(SCollectMetaKeyCxt* pCxt, SCreateTo
|
|||
if (NULL != pStmt->pQuery) {
|
||||
return collectMetaKeyFromQuery(pCxt, pStmt->pQuery);
|
||||
}
|
||||
if (NULL != pStmt->pWhere) {
|
||||
int32_t code = collectMetaKeyFromRealTableImpl(pCxt, pStmt->subDbName, pStmt->subSTbName,
|
||||
AUTH_TYPE_READ);
|
||||
return code;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -581,7 +586,7 @@ static int32_t collectMetaKeyFromShowCreateTable(SCollectMetaKeyCxt* pCxt, SShow
|
|||
code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, NULL, AUTH_TYPE_READ,
|
||||
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, pStmt->tableName, AUTH_TYPE_READ,
|
||||
pCxt->pMetaCache);
|
||||
}
|
||||
return code;
|
||||
|
|
|
@ -175,7 +175,7 @@ static int32_t authShowTables(SAuthCxt* pCxt, SShowStmt* pStmt) {
|
|||
static int32_t authShowCreateTable(SAuthCxt* pCxt, SShowCreateTableStmt* pStmt) {
|
||||
SNode* pTagCond = NULL;
|
||||
// todo check tag condition for subtable
|
||||
return checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_READ, &pTagCond);
|
||||
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_READ, &pTagCond);
|
||||
}
|
||||
|
||||
static int32_t authCreateTable(SAuthCxt* pCxt, SCreateTableStmt* pStmt) {
|
||||
|
|
|
@ -1605,7 +1605,7 @@ static int32_t parseCsvFile(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt
|
|||
(*pNumOfRows)++;
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && (*pNumOfRows) > tsMaxMemUsedByInsert * 1024 * 1024) {
|
||||
if (TSDB_CODE_SUCCESS == code && (*pNumOfRows) > tsMaxInsertBatchRows) {
|
||||
pStmt->fileProcessing = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1614,6 +1614,8 @@ static int32_t parseCsvFile(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt
|
|||
}
|
||||
taosMemoryFree(pLine);
|
||||
|
||||
parserDebug("0x%" PRIx64 " %d rows have been parsed", pCxt->pComCxt->requestId, *pNumOfRows);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && 0 == (*pNumOfRows) &&
|
||||
(!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT)) && !pStmt->fileProcessing) {
|
||||
code = buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL);
|
||||
|
|
|
@ -267,7 +267,10 @@ int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, in
|
|||
pBind = bind + c;
|
||||
}
|
||||
|
||||
tColDataAddValueByBind(pCol, pBind);
|
||||
code = tColDataAddValueByBind(pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE: -1);
|
||||
if (code) {
|
||||
goto _return;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("stmt all %d columns bind %d rows data", boundInfo->numOfBound, rowNum);
|
||||
|
@ -310,7 +313,7 @@ int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBu
|
|||
pBind = bind;
|
||||
}
|
||||
|
||||
tColDataAddValueByBind(pCol, pBind);
|
||||
tColDataAddValueByBind(pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE: -1);
|
||||
|
||||
qDebug("stmt col %d bind %d rows data", colIdx, rowNum);
|
||||
|
||||
|
|
|
@ -272,6 +272,41 @@ static int32_t createTableDataCxt(STableMeta* pTableMeta, SVCreateTbReq** pCreat
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t rebuildTableData(SSubmitTbData* pSrc, SSubmitTbData** pDst) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSubmitTbData* pTmp = taosMemoryCalloc(1, sizeof(SSubmitTbData));
|
||||
if (NULL == pTmp) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
} else {
|
||||
pTmp->flags = pSrc->flags;
|
||||
pTmp->suid = pSrc->suid;
|
||||
pTmp->uid = pSrc->uid;
|
||||
pTmp->sver = pSrc->sver;
|
||||
pTmp->pCreateTbReq = NULL;
|
||||
if (pTmp->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
|
||||
pTmp->aCol = taosArrayInit(128, sizeof(SColData));
|
||||
if (NULL == pTmp->aCol) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
taosMemoryFree(pTmp);
|
||||
}
|
||||
} else {
|
||||
pTmp->aRowP = taosArrayInit(128, POINTER_BYTES);
|
||||
if (NULL == pTmp->aRowP) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
taosMemoryFree(pTmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
taosMemoryFree(pSrc);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pDst = pTmp;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static void resetColValues(SArray* pValues) {
|
||||
int32_t num = taosArrayGetSize(pValues);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
|
@ -381,7 +416,7 @@ static int32_t fillVgroupDataCxt(STableDataCxt* pTableCxt, SVgroupDataCxt* pVgCx
|
|||
}
|
||||
}
|
||||
taosArrayPush(pVgCxt->pData->aSubmitTbData, pTableCxt->pData);
|
||||
taosMemoryFreeClear(pTableCxt->pData);
|
||||
rebuildTableData(pTableCxt->pData, &pTableCxt->pData);
|
||||
|
||||
qDebug("add tableDataCxt uid:%" PRId64 " to vgId:%d", pTableCxt->pMeta->uid, pVgCxt->vgId);
|
||||
|
||||
|
|
|
@ -55,6 +55,13 @@ typedef struct STranslateContext {
|
|||
bool showRewrite;
|
||||
} STranslateContext;
|
||||
|
||||
typedef struct SBuildTopicContext {
|
||||
bool colExists;
|
||||
bool colNotFound;
|
||||
STableMeta* pMeta;
|
||||
SNodeList* pTags;
|
||||
} SBuildTopicContext;
|
||||
|
||||
typedef struct SFullDatabaseName {
|
||||
char fullDbName[TSDB_DB_FNAME_LEN];
|
||||
} SFullDatabaseName;
|
||||
|
@ -827,7 +834,7 @@ static void setColumnInfoByExpr(STempTableNode* pTable, SExprNode* pExpr, SColum
|
|||
strcpy(pCol->node.aliasName, pCol->colName);
|
||||
}
|
||||
if ('\0' == pCol->node.userAlias[0]) {
|
||||
strcpy(pCol->node.userAlias, pCol->colName);
|
||||
strcpy(pCol->node.userAlias, pExpr->userAlias);
|
||||
}
|
||||
pCol->node.resType = pExpr->resType;
|
||||
}
|
||||
|
@ -1763,6 +1770,7 @@ static int32_t rewriteFuncToValue(STranslateContext* pCxt, char* pLiteral, SNode
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
strcpy(pVal->node.aliasName, ((SExprNode*)*pNode)->aliasName);
|
||||
strcpy(pVal->node.userAlias, ((SExprNode*)*pNode)->userAlias);
|
||||
pVal->node.resType = ((SExprNode*)*pNode)->resType;
|
||||
if (NULL == pLiteral) {
|
||||
pVal->isNull = true;
|
||||
|
@ -2761,6 +2769,7 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) {
|
|||
} else {
|
||||
len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->aliasName);
|
||||
strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1));
|
||||
len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->userAlias);
|
||||
strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1));
|
||||
}
|
||||
|
||||
|
@ -3207,7 +3216,7 @@ static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode*
|
|||
|
||||
int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
|
||||
int64_t intervalRange = 0;
|
||||
if (TIME_IS_VAR_DURATION(pInterval->unit)) {
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->unit)) {
|
||||
int64_t f = 1;
|
||||
if (pInterval->unit == 'n') {
|
||||
f = 30LL * MILLISECOND_PER_DAY;
|
||||
|
@ -3288,7 +3297,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
uint8_t precision = ((SColumnNode*)pInterval->pCol)->node.resType.precision;
|
||||
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
bool valInter = TIME_IS_VAR_DURATION(pInter->unit);
|
||||
bool valInter = IS_CALENDAR_TIME_DURATION(pInter->unit);
|
||||
if (pInter->datum.i <= 0 || (!valInter && pInter->datum.i < tsMinIntervalTime)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL, tsMinIntervalTime,
|
||||
getPrecisionStr(precision));
|
||||
|
@ -3302,7 +3311,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
if (pInter->unit == 'n' && pOffset->unit == 'y') {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_UNIT);
|
||||
}
|
||||
bool fixed = !TIME_IS_VAR_DURATION(pOffset->unit) && !valInter;
|
||||
bool fixed = !IS_CALENDAR_TIME_DURATION(pOffset->unit) && !valInter;
|
||||
if ((fixed && pOffset->datum.i >= pInter->datum.i) ||
|
||||
(!fixed && getMonthsFromTimeVal(pOffset->datum.i, precision, pOffset->unit) >=
|
||||
getMonthsFromTimeVal(pInter->datum.i, precision, pInter->unit))) {
|
||||
|
@ -3318,7 +3327,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
|
||||
|
||||
SValueNode* pSliding = (SValueNode*)pInterval->pSliding;
|
||||
if (TIME_IS_VAR_DURATION(pSliding->unit)) {
|
||||
if (IS_CALENDAR_TIME_DURATION(pSliding->unit)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_UNIT);
|
||||
}
|
||||
if ((pSliding->datum.i < convertTimePrecision(tsMinSlidingTime, TSDB_TIME_PRECISION_MILLI, precision)) ||
|
||||
|
@ -5823,6 +5832,9 @@ static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pS
|
|||
toName(pCxt->pParseCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name);
|
||||
tNameGetFullDbName(&name, pReq->subDbName);
|
||||
tNameExtractFullName(&name, pReq->subStbName);
|
||||
if(pStmt->pQuery != NULL) {
|
||||
code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
|
||||
}
|
||||
} else if ('\0' != pStmt->subDbName[0]) {
|
||||
pReq->subType = TOPIC_SUB_TYPE__DB;
|
||||
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->subDbName, strlen(pStmt->subDbName));
|
||||
|
@ -5845,12 +5857,108 @@ static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pS
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t addTagList(SNodeList** ppList, SNode* pNode) {
|
||||
if (NULL == *ppList) {
|
||||
*ppList = nodesMakeList();
|
||||
}
|
||||
|
||||
nodesListStrictAppend(*ppList, pNode);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static EDealRes checkColumnTagsInCond(SNode* pNode, void* pContext) {
|
||||
SBuildTopicContext* pCxt = (SBuildTopicContext*)pContext;
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
ETableColumnType type;
|
||||
getColumnTypeFromMeta(pCxt->pMeta, ((SColumnNode*)pNode)->colName, &type);
|
||||
if (type == TCOL_TYPE_COLUMN) {
|
||||
pCxt->colExists = true;
|
||||
return DEAL_RES_ERROR;
|
||||
} else if (type == TCOL_TYPE_TAG) {
|
||||
addTagList(&pCxt->pTags, nodesCloneNode(pNode));
|
||||
} else {
|
||||
pCxt->colNotFound = true;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
} else if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (0 == strcasecmp(pFunc->functionName, "tbname")) {
|
||||
addTagList(&pCxt->pTags, nodesCloneNode(pNode));
|
||||
}
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* pStmt, STableMeta* pMeta, SNodeList** ppProjection) {
|
||||
SBuildTopicContext colCxt = {.colExists = false, .colNotFound = false, .pMeta = pMeta, .pTags = NULL};
|
||||
nodesWalkExprPostOrder(pStmt->pWhere, checkColumnTagsInCond, &colCxt);
|
||||
if (colCxt.colNotFound) {
|
||||
nodesDestroyList(colCxt.pTags);
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Invalid column name");
|
||||
} else if (colCxt.colExists) {
|
||||
nodesDestroyList(colCxt.pTags);
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Columns are forbidden in where clause");
|
||||
}
|
||||
if (NULL == colCxt.pTags) { // put one column to select
|
||||
// for (int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) {
|
||||
SSchema* column = &pMeta->schema[0];
|
||||
SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
strcpy(col->colName, column->name);
|
||||
strcpy(col->node.aliasName, col->colName);
|
||||
strcpy(col->node.userAlias, col->colName);
|
||||
addTagList(&colCxt.pTags, (SNode*)col);
|
||||
// }
|
||||
}
|
||||
|
||||
*ppProjection = colCxt.pTags;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t buildQueryForTableTopic(STranslateContext* pCxt, SCreateTopicStmt* pStmt, SNode** pSelect) {
|
||||
SParseContext* pParCxt = pCxt->pParseCxt;
|
||||
SRequestConnInfo connInfo = {.pTrans = pParCxt->pTransporter,
|
||||
.requestId = pParCxt->requestId,
|
||||
.requestObjRefId = pParCxt->requestRid,
|
||||
.mgmtEps = pParCxt->mgmtEpSet};
|
||||
SName name;
|
||||
STableMeta* pMeta = NULL;
|
||||
int32_t code = getTableMetaImpl(pCxt, toName(pParCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name), &pMeta);
|
||||
if (code) {
|
||||
taosMemoryFree(pMeta);
|
||||
return code;
|
||||
}
|
||||
if (TSDB_SUPER_TABLE != pMeta->tableType) {
|
||||
taosMemoryFree(pMeta);
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Only supertable table can be used");
|
||||
}
|
||||
|
||||
SNodeList* pProjection = NULL;
|
||||
code = checkCollectTopicTags(pCxt, pStmt, pMeta, &pProjection);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
SRealTableNode* realTable = (SRealTableNode*)nodesMakeNode(QUERY_NODE_REAL_TABLE);
|
||||
strcpy(realTable->table.dbName, pStmt->subDbName);
|
||||
strcpy(realTable->table.tableName, pStmt->subSTbName);
|
||||
strcpy(realTable->table.tableAlias, pStmt->subSTbName);
|
||||
*pSelect = createSelectStmtImpl(true, pProjection, (SNode*)realTable);
|
||||
((SSelectStmt*)*pSelect)->pWhere = nodesCloneNode(pStmt->pWhere);
|
||||
pCxt->pParseCxt->topicQuery = true;
|
||||
code = translateQuery(pCxt, *pSelect);
|
||||
}
|
||||
|
||||
taosMemoryFree(pMeta);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t checkCreateTopic(STranslateContext* pCxt, SCreateTopicStmt* pStmt) {
|
||||
if (NULL == pStmt->pQuery) {
|
||||
if (NULL == pStmt->pQuery && NULL == pStmt->pWhere) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt->pQuery)) {
|
||||
if (pStmt->pWhere) {
|
||||
return buildQueryForTableTopic(pCxt, pStmt, &pStmt->pQuery);
|
||||
} else if (QUERY_NODE_SELECT_STMT == nodeType(pStmt->pQuery)) {
|
||||
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
||||
if (!pSelect->isDistinct &&
|
||||
(NULL != pSelect->pFromTable && QUERY_NODE_REAL_TABLE == nodeType(pSelect->pFromTable)) &&
|
||||
|
|
|
@ -499,7 +499,7 @@ int32_t getVnodeSysTableTargetName(int32_t acctId, SNode* pWhere, SName* pName)
|
|||
|
||||
static int32_t userAuthToString(int32_t acctId, const char* pUser, const char* pDb, const char* pTable, AUTH_TYPE type,
|
||||
char* pStr) {
|
||||
return sprintf(pStr, "%s*%d*%s*%s*%d", pUser, acctId, pDb, (NULL != pTable && '\0' == pTable[0]) ? NULL : pTable,
|
||||
return sprintf(pStr, "%s*%d*%s*%s*%d", pUser, acctId, pDb, (NULL == pTable || '\0' == pTable[0]) ? "``" : pTable,
|
||||
type);
|
||||
}
|
||||
|
||||
|
@ -525,6 +525,9 @@ static void getStringFromAuthStr(const char* pStart, char* pStr, char** pNext) {
|
|||
strncpy(pStr, pStart, p - pStart);
|
||||
*pNext = ++p;
|
||||
}
|
||||
if (*pStart == '`' && *(pStart + 1) == '`') {
|
||||
*pStr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void stringToUserAuth(const char* pStr, int32_t len, SUserAuthInfo* pUserAuth) {
|
||||
|
@ -533,7 +536,11 @@ static void stringToUserAuth(const char* pStr, int32_t len, SUserAuthInfo* pUser
|
|||
pUserAuth->tbName.acctId = getIntegerFromAuthStr(p, &p);
|
||||
getStringFromAuthStr(p, pUserAuth->tbName.dbname, &p);
|
||||
getStringFromAuthStr(p, pUserAuth->tbName.tname, &p);
|
||||
pUserAuth->tbName.type = TSDB_TABLE_NAME_T;
|
||||
if (pUserAuth->tbName.tname[0]) {
|
||||
pUserAuth->tbName.type = TSDB_TABLE_NAME_T;
|
||||
} else {
|
||||
pUserAuth->tbName.type = TSDB_DB_NAME_T;
|
||||
}
|
||||
pUserAuth->type = getIntegerFromAuthStr(p, &p);
|
||||
}
|
||||
|
||||
|
@ -667,6 +674,22 @@ int32_t buildCatalogReq(const SParseMetaCache* pMetaCache, SCatalogReq* pCatalog
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
SNode* createSelectStmtImpl(bool isDistinct, SNodeList* pProjectionList, SNode* pTable) {
|
||||
SSelectStmt* select = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
|
||||
if (NULL == select) {
|
||||
return NULL;
|
||||
}
|
||||
select->isDistinct = isDistinct;
|
||||
select->pProjectionList = pProjectionList;
|
||||
select->pFromTable = pTable;
|
||||
sprintf(select->stmtName, "%p", select);
|
||||
select->isTimeLineResult = true;
|
||||
select->onlyHasKeepOrderFunc = true;
|
||||
select->timeRange = TSWINDOW_INITIALIZER;
|
||||
return (SNode*)select;
|
||||
}
|
||||
|
||||
static int32_t putMetaDataToHash(const char* pKey, int32_t len, const SArray* pData, int32_t index, SHashObj** pHash) {
|
||||
if (NULL == *pHash) {
|
||||
*pHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1145,6 +1145,15 @@ TEST_F(ParserInitialCTest, createTopic) {
|
|||
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 with meta as stable st1", nullptr, "test", "st1", 1);
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 WITH META AS STABLE st1");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 as stable st1 where tag1 > 0", nullptr, "test", "st1");
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 AS STABLE st1 WHERE tag1 > 0");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 with meta as stable st1 where tag1 > 0", nullptr, "test", "st1", 1);
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 WITH META AS STABLE st1 WHERE tag1 > 0");
|
||||
clearCreateTopicReq();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -472,6 +472,8 @@ TEST_F(ParserSelectTest, joinSemanticCheck) {
|
|||
|
||||
run("SELECT * FROM (SELECT tag1, SUM(c1) s FROM st1 GROUP BY tag1) t1, st1 t2 where t1.tag1 = t2.tag1",
|
||||
TSDB_CODE_PAR_NOT_SUPPORT_JOIN);
|
||||
|
||||
run("SELECT count(*) FROM t1 a join t1 b on a.ts=b.ts where a.ts=b.ts");
|
||||
}
|
||||
|
||||
} // namespace ParserTest
|
||||
|
|
|
@ -37,19 +37,24 @@ typedef struct SRewriteExprCxt {
|
|||
int32_t errCode;
|
||||
SNodeList* pExprs;
|
||||
bool* pOutputs;
|
||||
bool isPartitionBy;
|
||||
} SRewriteExprCxt;
|
||||
|
||||
static void setColumnInfo(SFunctionNode* pFunc, SColumnNode* pCol) {
|
||||
static void setColumnInfo(SFunctionNode* pFunc, SColumnNode* pCol, bool isPartitionBy) {
|
||||
switch (pFunc->funcType) {
|
||||
case FUNCTION_TYPE_TBNAME:
|
||||
pCol->colType = COLUMN_TYPE_TBNAME;
|
||||
break;
|
||||
case FUNCTION_TYPE_WSTART:
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
if (!isPartitionBy) {
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
}
|
||||
pCol->colType = COLUMN_TYPE_WINDOW_START;
|
||||
break;
|
||||
case FUNCTION_TYPE_WEND:
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
if (!isPartitionBy) {
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
}
|
||||
pCol->colType = COLUMN_TYPE_WINDOW_END;
|
||||
break;
|
||||
case FUNCTION_TYPE_WDURATION:
|
||||
|
@ -100,9 +105,10 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
|
|||
SExprNode* pToBeRewrittenExpr = (SExprNode*)(*pNode);
|
||||
pCol->node.resType = pToBeRewrittenExpr->resType;
|
||||
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
|
||||
strcpy(pCol->node.userAlias, ((SExprNode*)pExpr)->userAlias);
|
||||
strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName);
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
|
||||
setColumnInfo((SFunctionNode*)pExpr, pCol);
|
||||
setColumnInfo((SFunctionNode*)pExpr, pCol, pCxt->isPartitionBy);
|
||||
}
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)pCol;
|
||||
|
@ -141,7 +147,8 @@ static EDealRes doNameExpr(SNode* pNode, void* pContext) {
|
|||
|
||||
static int32_t rewriteExprForSelect(SNode* pExpr, SSelectStmt* pSelect, ESqlClause clause) {
|
||||
nodesWalkExpr(pExpr, doNameExpr, NULL);
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = NULL, .pOutputs = NULL};
|
||||
bool isPartitionBy = (pSelect->pPartitionByList && pSelect->pPartitionByList->length > 0) ? true : false;
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = NULL, .pOutputs = NULL, .isPartitionBy = isPartitionBy};
|
||||
cxt.errCode = nodesListMakeAppend(&cxt.pExprs, pExpr);
|
||||
if (TSDB_CODE_SUCCESS == cxt.errCode) {
|
||||
nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
|
||||
|
@ -169,7 +176,8 @@ static int32_t cloneRewriteExprs(SNodeList* pExprs, bool* pOutputs, SNodeList**
|
|||
static int32_t rewriteExprsForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause,
|
||||
SNodeList** pRewriteExprs) {
|
||||
nodesWalkExprs(pExprs, doNameExpr, NULL);
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs, .pOutputs = NULL};
|
||||
bool isPartitionBy = (pSelect->pPartitionByList && pSelect->pPartitionByList->length > 0) ? true : false;
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs, .pOutputs = NULL, .isPartitionBy = isPartitionBy};
|
||||
if (NULL != pRewriteExprs) {
|
||||
cxt.pOutputs = taosMemoryCalloc(LIST_LENGTH(pExprs), sizeof(bool));
|
||||
if (NULL == cxt.pOutputs) {
|
||||
|
@ -186,14 +194,14 @@ static int32_t rewriteExprsForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ES
|
|||
|
||||
static int32_t rewriteExpr(SNodeList* pExprs, SNode** pTarget) {
|
||||
nodesWalkExprs(pExprs, doNameExpr, NULL);
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs, .pOutputs = NULL};
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs, .pOutputs = NULL, .isPartitionBy = false};
|
||||
nodesRewriteExpr(pTarget, doRewriteExpr, &cxt);
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
||||
static int32_t rewriteExprs(SNodeList* pExprs, SNodeList* pTarget) {
|
||||
nodesWalkExprs(pExprs, doNameExpr, NULL);
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs, .pOutputs = NULL};
|
||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs, .pOutputs = NULL, .isPartitionBy = false};
|
||||
nodesRewriteExprs(pTarget, doRewriteExpr, &cxt);
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
@ -543,11 +551,16 @@ static SNode* createGroupingSetNode(SNode* pExpr) {
|
|||
return (SNode*)pGroupingSet;
|
||||
}
|
||||
|
||||
static EGroupAction getGroupAction(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
static EGroupAction getDistinctGroupAction(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
return (pCxt->pPlanCxt->streamQuery || NULL != pSelect->pLimit || NULL != pSelect->pSlimit) ? GROUP_ACTION_KEEP
|
||||
: GROUP_ACTION_NONE;
|
||||
}
|
||||
|
||||
static EGroupAction getGroupAction(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
return ((pCxt->pPlanCxt->streamQuery || NULL != pSelect->pLimit || NULL != pSelect->pSlimit) && !pSelect->isDistinct) ? GROUP_ACTION_KEEP
|
||||
: GROUP_ACTION_NONE;
|
||||
}
|
||||
|
||||
static EDataOrderLevel getRequireDataOrder(bool needTimeline, SSelectStmt* pSelect) {
|
||||
return needTimeline ? (NULL != pSelect->pPartitionByList ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_GLOBAL)
|
||||
: DATA_ORDER_LEVEL_NONE;
|
||||
|
@ -1166,7 +1179,7 @@ static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pAgg->node.groupAction = GROUP_ACTION_CLEAR;
|
||||
pAgg->node.groupAction = GROUP_ACTION_CLEAR;//getDistinctGroupAction(pCxt, pSelect);
|
||||
pAgg->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||
pAgg->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||
|
||||
|
|
|
@ -740,6 +740,85 @@ static int32_t pushDownCondOptJoinExtractMergeCond(SOptimizeContext* pCxt, SJoin
|
|||
return code;
|
||||
}
|
||||
|
||||
static bool pushDownCondOptIsTableColumn(SNode* pNode, SNodeList* pTableCols) {
|
||||
if (QUERY_NODE_COLUMN != nodeType(pNode)) {
|
||||
return false;
|
||||
}
|
||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||
return pushDownCondOptBelongThisTable(pNode, pTableCols);
|
||||
}
|
||||
|
||||
static bool pushDownCondOptIsColEqualOnCond(SJoinLogicNode* pJoin, SNode* pCond) {
|
||||
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
||||
return false;
|
||||
}
|
||||
SOperatorNode* pOper = (SOperatorNode*)pCond;
|
||||
if (OP_TYPE_EQUAL != pOper->opType) {
|
||||
return false;
|
||||
}
|
||||
if (QUERY_NODE_COLUMN != nodeType(pOper->pLeft) || QUERY_NODE_COLUMN != nodeType(pOper->pRight)) {
|
||||
return false;
|
||||
}
|
||||
SColumnNode* pLeft = (SColumnNode*)(pOper->pLeft);
|
||||
SColumnNode* pRight = (SColumnNode*)(pOper->pRight);
|
||||
//TODO: add cast to operator and remove this restriction of optimization
|
||||
if (pLeft->node.resType.type != pRight->node.resType.type || pLeft->node.resType.bytes != pRight->node.resType.bytes) {
|
||||
return false;
|
||||
}
|
||||
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
||||
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
||||
if (pushDownCondOptIsTableColumn(pOper->pLeft, pLeftCols)) {
|
||||
return pushDownCondOptIsTableColumn(pOper->pRight, pRightCols);
|
||||
} else if (pushDownCondOptIsTableColumn(pOper->pLeft, pRightCols)) {
|
||||
return pushDownCondOptIsTableColumn(pOper->pRight, pLeftCols);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t pushDownCondOptJoinExtractColEqualOnLogicCond(SJoinLogicNode* pJoin) {
|
||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(pJoin->pOnConditions);
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SNodeList* pEqualOnConds = NULL;
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||
if (pushDownCondOptIsColEqualOnCond(pJoin, pCond)) {
|
||||
code = nodesListMakeAppend(&pEqualOnConds, nodesCloneNode(pCond));
|
||||
}
|
||||
}
|
||||
|
||||
SNode* pTempTagEqCond = NULL;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesMergeConds(&pTempTagEqCond, &pEqualOnConds);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pJoin->pColEqualOnConditions = pTempTagEqCond;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
nodesDestroyList(pEqualOnConds);
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t pushDownCondOptJoinExtractColEqualOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||
if (NULL == pJoin->pOnConditions) {
|
||||
pJoin->pColEqualOnConditions = NULL;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pOnConditions) &&
|
||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)(pJoin->pOnConditions))->condType) {
|
||||
return pushDownCondOptJoinExtractColEqualOnLogicCond(pJoin);
|
||||
}
|
||||
|
||||
if (pushDownCondOptIsColEqualOnCond(pJoin, pJoin->pOnConditions)) {
|
||||
pJoin->pColEqualOnConditions = nodesCloneNode(pJoin->pOnConditions);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||
if (OPTIMIZE_FLAG_TEST_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -774,6 +853,10 @@ static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* p
|
|||
code = pushDownCondOptJoinExtractMergeCond(pCxt, pJoin);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = pushDownCondOptJoinExtractColEqualOnCond(pCxt, pJoin);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
OPTIMIZE_FLAG_SET_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
||||
pCxt->optimized = true;
|
||||
|
@ -1259,8 +1342,8 @@ static bool smaIndexOptEqualInterval(SScanLogicNode* pScan, SWindowLogicNode* pW
|
|||
.sliding = pIndex->sliding,
|
||||
.slidingUnit = pIndex->slidingUnit,
|
||||
.precision = pScan->node.precision};
|
||||
return (pScan->scanRange.skey == taosTimeTruncate(pScan->scanRange.skey, &interval, pScan->node.precision)) &&
|
||||
(pScan->scanRange.ekey + 1 == taosTimeTruncate(pScan->scanRange.ekey + 1, &interval, pScan->node.precision));
|
||||
return (pScan->scanRange.skey == taosTimeTruncate(pScan->scanRange.skey, &interval)) &&
|
||||
(pScan->scanRange.ekey + 1 == taosTimeTruncate(pScan->scanRange.ekey + 1, &interval));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2234,7 +2317,7 @@ static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
|||
if (QUERY_NODE_COLUMN == nodeType(pPar)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pPar;
|
||||
if (pCol->colType != COLUMN_TYPE_COLUMN) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (hasSelectFunc || QUERY_NODE_VALUE == nodeType(nodesListGetNode(pAggFunc->pParameterList, 0))) {
|
||||
|
|
|
@ -705,6 +705,9 @@ static int32_t createJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
|
|||
pJoinLogicNode->pOnConditions, &pJoin->pOnConditions);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->pColEqualOnConditions) {
|
||||
code = setNodeSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->pColEqualOnConditions, &pJoin->pColEqualOnConditions);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = setConditionsSlotId(pCxt, (const SLogicNode*)pJoinLogicNode, (SPhysiNode*)pJoin);
|
||||
}
|
||||
|
@ -1147,7 +1150,7 @@ static int32_t createExchangePhysiNode(SPhysiPlanContext* pCxt, SExchangeLogicNo
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWinodwPhysiNode* pWindow,
|
||||
static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWindowPhysiNode* pWindow,
|
||||
SWindowLogicNode* pWindowLogicNode) {
|
||||
pWindow->triggerType = pWindowLogicNode->triggerType;
|
||||
pWindow->watermark = pWindowLogicNode->watermark;
|
||||
|
@ -1644,6 +1647,9 @@ static int32_t createPhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode,
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListStrictAppend(pChildren, (SNode*)pChild);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -454,6 +454,18 @@ int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType* pType) {
|
||||
int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
|
||||
for (int32_t i = 0; i < nums; ++i) {
|
||||
if (0 == strcmp(pName, pMeta->schema[i].name)) {
|
||||
*pType = (i < pMeta->tableInfo.numOfColumns) ? TCOL_TYPE_COLUMN : TCOL_TYPE_TAG;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*pType = TCOL_TYPE_NONE;
|
||||
}
|
||||
|
||||
void freeVgInfo(SDBVgInfo* vgInfo) {
|
||||
if (NULL == vgInfo) {
|
||||
return;
|
||||
|
|
|
@ -126,14 +126,12 @@ int32_t streamTaskEnqueueBlocks(SStreamTask* pTask, const SStreamDispatchReq* pR
|
|||
if (pBlock == NULL) {
|
||||
streamTaskInputFail(pTask);
|
||||
status = TASK_INPUT_STATUS__FAILED;
|
||||
qDebug("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId,
|
||||
qError("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId,
|
||||
pTask->id.idStr);
|
||||
} else {
|
||||
if (tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock) == 0) {
|
||||
status = TASK_INPUT_STATUS__NORMAL;
|
||||
} else { // input queue is full, upstream is blocked now
|
||||
status = TASK_INPUT_STATUS__BLOCKED;
|
||||
}
|
||||
int32_t code = tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock);
|
||||
// input queue is full, upstream is blocked now
|
||||
status = (code == TSDB_CODE_SUCCESS)? TASK_INPUT_STATUS__NORMAL:TASK_INPUT_STATUS__BLOCKED;
|
||||
}
|
||||
|
||||
// rsp by input status
|
||||
|
@ -235,12 +233,11 @@ int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, S
|
|||
}
|
||||
|
||||
int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) {
|
||||
ASSERT(pRsp->inputStatus == TASK_OUTPUT_STATUS__NORMAL || pRsp->inputStatus == TASK_OUTPUT_STATUS__BLOCKED);
|
||||
qDebug("s-task:%s receive dispatch rsp, code: %x", pTask->id.idStr, code);
|
||||
qDebug("s-task:%s receive dispatch rsp, output status:%d code:%d", pTask->id.idStr, pRsp->inputStatus, code);
|
||||
|
||||
if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||
int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1);
|
||||
qDebug("task %d is shuffle, left waiting rsp %d", pTask->id.taskId, leftRsp);
|
||||
qDebug("s-task:%s is shuffle, left waiting rsp %d", pTask->id.idStr, leftRsp);
|
||||
if (leftRsp > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -248,13 +245,20 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i
|
|||
|
||||
int8_t old = atomic_exchange_8(&pTask->outputStatus, pRsp->inputStatus);
|
||||
ASSERT(old == TASK_OUTPUT_STATUS__WAIT);
|
||||
|
||||
// the input queue of the (down stream) task that receive the output data is full, so the TASK_INPUT_STATUS_BLOCKED is rsp
|
||||
// todo we need to send EMPTY PACKAGE to detect if the input queue is available for output of upstream task, every 50 ms.
|
||||
if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) {
|
||||
// TODO: init recover timer
|
||||
ASSERT(0);
|
||||
qError("s-task:%s inputQ of downstream task:0x%x is full, need to block output", pTask->id.idStr, pRsp->downstreamTaskId);
|
||||
|
||||
atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL);
|
||||
qError("s-task:%s ignore error, and reset task output status:%d", pTask->id.idStr, pTask->outputStatus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// continue dispatch one block to down stream in pipeline
|
||||
// otherwise, continue dispatch the first block to down stream task in pipeline
|
||||
streamDispatchStreamBlock(pTask);
|
||||
return 0;
|
||||
}
|
||||
|
@ -292,32 +296,44 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) {
|
|||
|
||||
if (type == STREAM_INPUT__DATA_SUBMIT) {
|
||||
SStreamDataSubmit* px = (SStreamDataSubmit*)pItem;
|
||||
qDebug("s-task:%s submit enqueue msgLen:%d ver:%" PRId64 ", total in queue:%d, size:%.2fMiB", pTask->id.idStr,
|
||||
px->submit.msgLen, px->submit.ver, total, size);
|
||||
|
||||
if ((pTask->taskLevel == TASK_LEVEL__SOURCE) && tInputQueueIsFull(pTask)) {
|
||||
qError("s-task:%s input queue is full, capacity(size:%d num:%dMiB), current(blocks:%d, size:%.2fMiB) abort",
|
||||
qError("s-task:%s input queue is full, capacity(size:%d num:%dMiB), current(blocks:%d, size:%.2fMiB) stop to push data",
|
||||
pTask->id.idStr, STREAM_TASK_INPUT_QUEUEU_CAPACITY, STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE, total,
|
||||
size);
|
||||
streamDataSubmitDestroy(px);
|
||||
taosFreeQitem(pItem);
|
||||
return -1;
|
||||
}
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
|
||||
int32_t code = taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
streamDataSubmitDestroy(px);
|
||||
taosFreeQitem(pItem);
|
||||
return code;
|
||||
}
|
||||
|
||||
qDebug("s-task:%s submit enqueue msgLen:%d ver:%" PRId64 ", total in queue:%d, size:%.2fMiB", pTask->id.idStr,
|
||||
px->submit.msgLen, px->submit.ver, total, size + px->submit.msgLen/1048576.0);
|
||||
} else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE ||
|
||||
type == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
if ((pTask->taskLevel == TASK_LEVEL__SOURCE) && (tInputQueueIsFull(pTask))) {
|
||||
qError("s-task:%s input queue is full, capacity:%d size:%d MiB, current(blocks:%d, size:%.2fMiB) abort",
|
||||
pTask->id.idStr, STREAM_TASK_INPUT_QUEUEU_CAPACITY, STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE, total,
|
||||
size);
|
||||
destroyStreamDataBlock((SStreamDataBlock*) pItem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
qDebug("s-task:%s data block enqueue, current(blocks:%d, size:%.2fMiB)", pTask->id.idStr, total, size);
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
int32_t code = taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
destroyStreamDataBlock((SStreamDataBlock*) pItem);
|
||||
return code;
|
||||
}
|
||||
} else if (type == STREAM_INPUT__CHECKPOINT) {
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
} else if (type == STREAM_INPUT__GET_RES) {
|
||||
// use the default memory limit, refactor later.
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
qDebug("s-task:%s data res enqueue, current(blocks:%d, size:%.2fMiB)", pTask->id.idStr, total, size);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,15 @@ typedef struct {
|
|||
rocksdb_comparator_t** pCompares;
|
||||
} RocksdbCfInst;
|
||||
|
||||
uint32_t nextPow2(uint32_t x) {
|
||||
x = x - 1;
|
||||
x = x | (x >> 1);
|
||||
x = x | (x >> 2);
|
||||
x = x | (x >> 4);
|
||||
x = x | (x >> 8);
|
||||
x = x | (x >> 16);
|
||||
return x + 1;
|
||||
}
|
||||
int32_t streamStateOpenBackendCf(void* backend, char* name, char** cfs, int32_t nCf);
|
||||
|
||||
void destroyRocksdbCfInst(RocksdbCfInst* inst);
|
||||
|
@ -78,8 +87,6 @@ void* streamBackendInit(const char* path) {
|
|||
pHandle->cfInst = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
||||
rocksdb_env_t* env = rocksdb_create_default_env(); // rocksdb_envoptions_create();
|
||||
rocksdb_env_set_low_priority_background_threads(env, 4);
|
||||
rocksdb_env_set_high_priority_background_threads(env, 2);
|
||||
|
||||
rocksdb_cache_t* cache = rocksdb_cache_create_lru(64 << 20);
|
||||
|
||||
|
@ -92,6 +99,8 @@ void* streamBackendInit(const char* path) {
|
|||
rocksdb_options_set_recycle_log_file_num(opts, 6);
|
||||
rocksdb_options_set_max_write_buffer_number(opts, 2);
|
||||
rocksdb_options_set_info_log_level(opts, 0);
|
||||
uint32_t dbLimit = nextPow2(tsMaxStreamBackendCache);
|
||||
rocksdb_options_set_db_write_buffer_size(opts, dbLimit << 20);
|
||||
|
||||
pHandle->env = env;
|
||||
pHandle->dbOpt = opts;
|
||||
|
@ -117,7 +126,9 @@ void* streamBackendInit(const char* path) {
|
|||
*/
|
||||
streamStateOpenBackendCf(pHandle, (char*)path, cfs, nCf);
|
||||
}
|
||||
rocksdb_list_column_families_destroy(cfs, nCf);
|
||||
if (cfs != NULL) {
|
||||
rocksdb_list_column_families_destroy(cfs, nCf);
|
||||
}
|
||||
|
||||
return (void*)pHandle;
|
||||
_EXIT:
|
||||
|
@ -561,9 +572,14 @@ int32_t decodeValueFunc(void* value, int32_t vlen, int64_t* ttl, char** dest) {
|
|||
*dest = NULL;
|
||||
return -1;
|
||||
}
|
||||
int64_t now = taosGetTimestampMs();
|
||||
p = taosDecodeFixedI64(p, &key.unixTimestamp);
|
||||
p = taosDecodeFixedI32(p, &key.len);
|
||||
if (vlen != (sizeof(int64_t) + sizeof(int32_t) + key.len)) {
|
||||
if (dest != NULL) *dest = NULL;
|
||||
qError("vlen: %d, read len: %d", vlen, key.len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (key.len == 0) {
|
||||
key.data = NULL;
|
||||
} else {
|
||||
|
@ -571,6 +587,7 @@ int32_t decodeValueFunc(void* value, int32_t vlen, int64_t* ttl, char** dest) {
|
|||
}
|
||||
|
||||
if (ttl != NULL) {
|
||||
int64_t now = taosGetTimestampMs();
|
||||
*ttl = key.unixTimestamp == 0 ? 0 : key.unixTimestamp - now;
|
||||
}
|
||||
if (dest != NULL) {
|
||||
|
@ -708,7 +725,7 @@ int32_t streamStateOpenBackendCf(void* backend, char* name, char** cfs, int32_t
|
|||
qDebug("succ to open rocksdb cf");
|
||||
}
|
||||
// close default cf
|
||||
rocksdb_column_family_handle_destroy(cfHandle[0]);
|
||||
if (((rocksdb_column_family_handle_t**)cfHandle)[0] != 0) rocksdb_column_family_handle_destroy(cfHandle[0]);
|
||||
rocksdb_options_destroy(cfOpts[0]);
|
||||
handle->db = db;
|
||||
|
||||
|
@ -992,35 +1009,35 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa
|
|||
((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[idx]);
|
||||
}
|
||||
|
||||
#define STREAM_STATE_PUT_ROCKSDB(pState, funcname, key, value, vLen) \
|
||||
do { \
|
||||
code = 0; \
|
||||
char buf[128] = {0}; \
|
||||
char* err = NULL; \
|
||||
int i = streamGetInit(pState, funcname); \
|
||||
if (i < 0) { \
|
||||
qWarn("streamState failed to get cf name: %s", funcname); \
|
||||
code = -1; \
|
||||
break; \
|
||||
} \
|
||||
char toString[128] = {0}; \
|
||||
if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \
|
||||
int32_t klen = ginitDict[i].enFunc((void*)key, buf); \
|
||||
rocksdb_column_family_handle_t* pHandle = \
|
||||
((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[ginitDict[i].idx]; \
|
||||
rocksdb_t* db = pState->pTdbState->rocksdb; \
|
||||
rocksdb_writeoptions_t* opts = pState->pTdbState->writeOpts; \
|
||||
char* ttlV = NULL; \
|
||||
int32_t ttlVLen = ginitDict[i].enValueFunc((char*)value, vLen, 0, &ttlV); \
|
||||
rocksdb_put_cf(db, opts, pHandle, (const char*)buf, klen, (const char*)ttlV, (size_t)ttlVLen, &err); \
|
||||
if (err != NULL) { \
|
||||
taosMemoryFree(err); \
|
||||
qDebug("streamState str: %s failed to write to %s, err: %s", toString, funcname, err); \
|
||||
code = -1; \
|
||||
} else { \
|
||||
qDebug("streamState str:%s succ to write to %s, valLen:%d", toString, funcname, vLen); \
|
||||
} \
|
||||
taosMemoryFree(ttlV); \
|
||||
#define STREAM_STATE_PUT_ROCKSDB(pState, funcname, key, value, vLen) \
|
||||
do { \
|
||||
code = 0; \
|
||||
char buf[128] = {0}; \
|
||||
char* err = NULL; \
|
||||
int i = streamGetInit(pState, funcname); \
|
||||
if (i < 0) { \
|
||||
qWarn("streamState failed to get cf name: %s", funcname); \
|
||||
code = -1; \
|
||||
break; \
|
||||
} \
|
||||
char toString[128] = {0}; \
|
||||
if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \
|
||||
int32_t klen = ginitDict[i].enFunc((void*)key, buf); \
|
||||
rocksdb_column_family_handle_t* pHandle = \
|
||||
((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[ginitDict[i].idx]; \
|
||||
rocksdb_t* db = pState->pTdbState->rocksdb; \
|
||||
rocksdb_writeoptions_t* opts = pState->pTdbState->writeOpts; \
|
||||
char* ttlV = NULL; \
|
||||
int32_t ttlVLen = ginitDict[i].enValueFunc((char*)value, vLen, 0, &ttlV); \
|
||||
rocksdb_put_cf(db, opts, pHandle, (const char*)buf, klen, (const char*)ttlV, (size_t)ttlVLen, &err); \
|
||||
if (err != NULL) { \
|
||||
taosMemoryFree(err); \
|
||||
qError("streamState str: %s failed to write to %s, err: %s", toString, funcname, err); \
|
||||
code = -1; \
|
||||
} else { \
|
||||
qTrace("streamState str:%s succ to write to %s, rowValLen:%d, ttlValLen:%d", toString, funcname, vLen, ttlVLen); \
|
||||
} \
|
||||
taosMemoryFree(ttlV); \
|
||||
} while (0);
|
||||
|
||||
#define STREAM_STATE_GET_ROCKSDB(pState, funcname, key, pVal, vLen) \
|
||||
|
@ -1043,29 +1060,29 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa
|
|||
rocksdb_readoptions_t* opts = pState->pTdbState->readOpts; \
|
||||
size_t len = 0; \
|
||||
char* val = rocksdb_get_cf(db, opts, pHandle, (const char*)buf, klen, (size_t*)&len, &err); \
|
||||
if (val == NULL) { \
|
||||
if (val == NULL || len == 0) { \
|
||||
if (err == NULL) { \
|
||||
qDebug("streamState str: %s failed to read from %s_%s, err: not exist", toString, pState->pTdbState->idstr, \
|
||||
qTrace("streamState str: %s failed to read from %s_%s, err: not exist", toString, pState->pTdbState->idstr, \
|
||||
funcname); \
|
||||
} else { \
|
||||
qDebug("streamState str: %s failed to read from %s_%s, err: %s", toString, pState->pTdbState->idstr, funcname, \
|
||||
qError("streamState str: %s failed to read from %s_%s, err: %s", toString, pState->pTdbState->idstr, funcname, \
|
||||
err); \
|
||||
taosMemoryFreeClear(err); \
|
||||
} \
|
||||
code = -1; \
|
||||
} else { \
|
||||
char* p = NULL; \
|
||||
int32_t len = ginitDict[i].deValueFunc(val, len, NULL, (char**)pVal); \
|
||||
if (len < 0) { \
|
||||
qDebug("streamState str: %s failed to read from %s_%s, err: already ttl ", toString, pState->pTdbState->idstr, \
|
||||
int32_t tlen = ginitDict[i].deValueFunc(val, len, NULL, (char**)pVal); \
|
||||
if (tlen <= 0) { \
|
||||
qError("streamState str: %s failed to read from %s_%s, err: already ttl ", toString, pState->pTdbState->idstr, \
|
||||
funcname); \
|
||||
code = -1; \
|
||||
} else { \
|
||||
qDebug("streamState str: %s succ to read from %s_%s, valLen:%d", toString, pState->pTdbState->idstr, funcname, \
|
||||
len); \
|
||||
qTrace("streamState str: %s succ to read from %s_%s, valLen:%d", toString, pState->pTdbState->idstr, funcname, \
|
||||
tlen); \
|
||||
} \
|
||||
taosMemoryFree(val); \
|
||||
if (vLen != NULL) *vLen = len; \
|
||||
if (vLen != NULL) *vLen = tlen; \
|
||||
} \
|
||||
if (code == 0) \
|
||||
qDebug("streamState str: %s succ to read from %s_%s", toString, pState->pTdbState->idstr, funcname); \
|
||||
|
@ -1096,7 +1113,7 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa
|
|||
taosMemoryFree(err); \
|
||||
code = -1; \
|
||||
} else { \
|
||||
qDebug("streamState str: %s succ to del from %s_%s", toString, pState->pTdbState->idstr, funcname); \
|
||||
qTrace("streamState str: %s succ to del from %s_%s", toString, pState->pTdbState->idstr, funcname); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
|
@ -1123,31 +1140,29 @@ int32_t streamStateDel_rocksdb(SStreamState* pState, const SWinKey* key) {
|
|||
int32_t streamStateClear_rocksdb(SStreamState* pState) {
|
||||
qDebug("streamStateClear_rocksdb");
|
||||
|
||||
SStateKey sKey = {.key = {.ts = 0, .groupId = 0}, .opNum = pState->number};
|
||||
SStateKey eKey = {.key = {.ts = INT64_MAX, .groupId = UINT64_MAX}, .opNum = pState->number};
|
||||
char sKeyStr[128] = {0};
|
||||
char eKeyStr[128] = {0};
|
||||
SStateKey sKey = {.key = {.ts = 0, .groupId = 0}, .opNum = pState->number};
|
||||
SStateKey eKey = {.key = {.ts = INT64_MAX, .groupId = UINT64_MAX}, .opNum = pState->number};
|
||||
|
||||
int sLen = stateKeyEncode(&sKey, sKeyStr);
|
||||
int eLen = stateKeyEncode(&eKey, eKeyStr);
|
||||
|
||||
char toStringStart[128] = {0};
|
||||
char toStringEnd[128] = {0};
|
||||
if (qDebugFlag & DEBUG_TRACE) {
|
||||
stateKeyToString(&sKey, toStringStart);
|
||||
stateKeyToString(&eKey, toStringEnd);
|
||||
}
|
||||
|
||||
char* err = NULL;
|
||||
if (pState->pTdbState->pHandle[1] != NULL) {
|
||||
char* err = NULL;
|
||||
rocksdb_delete_range_cf(pState->pTdbState->rocksdb, pState->pTdbState->writeOpts, pState->pTdbState->pHandle[1],
|
||||
sKeyStr, sLen, eKeyStr, eLen, &err);
|
||||
}
|
||||
// rocksdb_compact_range_cf(pState->pTdbState->rocksdb, pState->pTdbState->pHandle[0], sKeyStr, sLen, eKeyStr,
|
||||
// eLen);
|
||||
if (err != NULL) {
|
||||
qWarn("failed to delete range cf(state) start: %s, end:%s, reason:%s", toStringStart, toStringEnd, err);
|
||||
taosMemoryFree(err);
|
||||
if (err != NULL) {
|
||||
char toStringStart[128] = {0};
|
||||
char toStringEnd[128] = {0};
|
||||
stateKeyToString(&sKey, toStringStart);
|
||||
stateKeyToString(&eKey, toStringEnd);
|
||||
|
||||
qWarn("failed to delete range cf(state) start: %s, end:%s, reason:%s", toStringStart, toStringEnd, err);
|
||||
taosMemoryFree(err);
|
||||
} else {
|
||||
rocksdb_compact_range_cf(pState->pTdbState->rocksdb, pState->pTdbState->pHandle[1], sKeyStr, sLen, eKeyStr, eLen);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1913,17 +1928,17 @@ int32_t streamStateGetParName_rocksdb(SStreamState* pState, int64_t groupId, voi
|
|||
|
||||
int32_t streamDefaultPut_rocksdb(SStreamState* pState, const void* key, void* pVal, int32_t pVLen) {
|
||||
int code = 0;
|
||||
STREAM_STATE_PUT_ROCKSDB(pState, "default", &key, pVal, pVLen);
|
||||
STREAM_STATE_PUT_ROCKSDB(pState, "default", key, pVal, pVLen);
|
||||
return code;
|
||||
}
|
||||
int32_t streamDefaultGet_rocksdb(SStreamState* pState, const void* key, void** pVal, int32_t* pVLen) {
|
||||
int code = 0;
|
||||
STREAM_STATE_GET_ROCKSDB(pState, "default", &key, pVal, pVLen);
|
||||
STREAM_STATE_GET_ROCKSDB(pState, "default", key, pVal, pVLen);
|
||||
return code;
|
||||
}
|
||||
int32_t streamDefaultDel_rocksdb(SStreamState* pState, const void* key) {
|
||||
int code = 0;
|
||||
STREAM_STATE_DEL_ROCKSDB(pState, "default", &key);
|
||||
STREAM_STATE_DEL_ROCKSDB(pState, "default", key);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
|||
tEncodeStreamRetrieveReq(&encoder, &req);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
SRpcMsg rpcMsg = { .code = 0, .msgType = TDMT_STREAM_RETRIEVE, .pCont = buf, .contLen = sizeof(SMsgHead) + len };
|
||||
SRpcMsg rpcMsg = {.code = 0, .msgType = TDMT_STREAM_RETRIEVE, .pCont = buf, .contLen = sizeof(SMsgHead) + len};
|
||||
if (tmsgSendReq(&pEpInfo->epSet, &rpcMsg) < 0) {
|
||||
ASSERT(0);
|
||||
goto CLEAR;
|
||||
|
@ -283,7 +283,7 @@ int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecov
|
|||
msg.info.noResp = 1;
|
||||
|
||||
tmsgSendReq(pEpSet, &msg);
|
||||
qDebug("s-task:%s dispatch recover finish msg to taskId:%d node %d: recover finish msg", pTask->id.idStr,
|
||||
qDebug("s-task:%s dispatch recover finish msg to downstream taskId:0x%x node %d: recover finish msg", pTask->id.idStr,
|
||||
pReq->taskId, vgId);
|
||||
|
||||
return 0;
|
||||
|
@ -318,7 +318,7 @@ int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* pReq, in
|
|||
msg.pCont = buf;
|
||||
msg.msgType = pTask->dispatchMsgType;
|
||||
|
||||
qDebug("dispatch from s-task:%s to taskId:0x%x vgId:%d data msg", pTask->id.idStr, pReq->taskId, vgId);
|
||||
qDebug("s-task:%s dispatch msg to taskId:0x%x vgId:%d data msg", pTask->id.idStr, pReq->taskId, vgId);
|
||||
tmsgSendReq(pEpSet, &msg);
|
||||
|
||||
code = 0;
|
||||
|
@ -414,7 +414,7 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat
|
|||
|
||||
req.taskId = downstreamTaskId;
|
||||
|
||||
qDebug("s-task:%s (child taskId:%d) fix-dispatch blocks:%d to down stream s-task:%d in vgId:%d", pTask->id.idStr,
|
||||
qDebug("s-task:%s (child taskId:%d) fix-dispatch %d block(s) to down stream s-task:0x%x in vgId:%d", pTask->id.idStr,
|
||||
pTask->selfChildId, numOfBlocks, downstreamTaskId, vgId);
|
||||
|
||||
code = doSendDispatchMsg(pTask, &req, vgId, pEpSet);
|
||||
|
@ -510,14 +510,17 @@ int32_t streamDispatchStreamBlock(SStreamTask* pTask) {
|
|||
int8_t old =
|
||||
atomic_val_compare_exchange_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL, TASK_OUTPUT_STATUS__WAIT);
|
||||
if (old != TASK_OUTPUT_STATUS__NORMAL) {
|
||||
qDebug("s-task:%s task wait for dispatch rsp, not dispatch now", pTask->id.idStr);
|
||||
qDebug("s-task:%s task wait for dispatch rsp, not dispatch now, output status:%d", pTask->id.idStr, old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qDebug("s-task:%s start to dispatch msg, set output status:%d", pTask->id.idStr, pTask->outputStatus);
|
||||
|
||||
SStreamDataBlock* pDispatchedBlock = streamQueueNextItem(pTask->outputQueue);
|
||||
if (pDispatchedBlock == NULL) {
|
||||
qDebug("s-task:%s stop dispatching since no output in output queue", pTask->id.idStr);
|
||||
atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL);
|
||||
qDebug("s-task:%s stop dispatching since no output in output queue, output status:%d", pTask->id.idStr,
|
||||
pTask->outputStatus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -527,6 +530,7 @@ int32_t streamDispatchStreamBlock(SStreamTask* pTask) {
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
streamQueueProcessFail(pTask->outputQueue);
|
||||
atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL);
|
||||
qDebug("s-task:%s failed to dispatch msg to downstream, output status:%d", pTask->id.idStr, pTask->outputStatus);
|
||||
}
|
||||
|
||||
// this block can be freed only when it has been pushed to down stream.
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
#include "streamInc.h"
|
||||
|
||||
// maximum allowed processed block batches. One block may include several submit blocks
|
||||
#define MAX_STREAM_EXEC_BATCH_NUM 128
|
||||
#define MIN_STREAM_EXEC_BATCH_NUM 16
|
||||
#define MAX_STREAM_RESULT_DUMP_THRESHOLD 1000
|
||||
#define MAX_STREAM_EXEC_BATCH_NUM 32
|
||||
#define MIN_STREAM_EXEC_BATCH_NUM 4
|
||||
#define MAX_STREAM_RESULT_DUMP_THRESHOLD 100
|
||||
|
||||
static int32_t updateCheckPointInfo (SStreamTask* pTask);
|
||||
static int32_t updateCheckPointInfo(SStreamTask* pTask);
|
||||
|
||||
bool streamTaskShouldStop(const SStreamStatus* pStatus) {
|
||||
int32_t status = atomic_load_8((int8_t*)&pStatus->taskStatus);
|
||||
|
@ -44,14 +44,16 @@ static int32_t doDumpResult(SStreamTask* pTask, SStreamQueueItem* pItem, SArray*
|
|||
if (numOfBlocks > 0) {
|
||||
SStreamDataBlock* pStreamBlocks = createStreamBlockFromResults(pItem, pTask, size, pRes);
|
||||
if (pStreamBlocks == NULL) {
|
||||
qError("s-task:%s failed to create result stream data block, code:%s", pTask->id.idStr, tstrerror(terrno));
|
||||
taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
qDebug("s-task:%s dump stream result data blocks, num:%d, size:%.2fMiB", pTask->id.idStr, numOfBlocks, size/1048576.0);
|
||||
qDebug("s-task:%s dump stream result data blocks, num:%d, size:%.2fMiB", pTask->id.idStr, numOfBlocks,
|
||||
size / 1048576.0);
|
||||
|
||||
code = streamTaskOutputResultBlock(pTask, pStreamBlocks);
|
||||
if (code == TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY) { // back pressure and record position
|
||||
if (code == TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY) { // back pressure and record position
|
||||
destroyStreamDataBlock(pStreamBlocks);
|
||||
return -1;
|
||||
}
|
||||
|
@ -65,7 +67,8 @@ static int32_t doDumpResult(SStreamTask* pTask, SStreamQueueItem* pItem, SArray*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, int64_t* totalSize, int32_t* totalBlocks) {
|
||||
static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, int64_t* totalSize,
|
||||
int32_t* totalBlocks) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
void* pExecutor = pTask->exec.pExecutor;
|
||||
|
||||
|
@ -82,7 +85,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i
|
|||
}
|
||||
|
||||
if (streamTaskShouldStop(&pTask->status)) {
|
||||
taosArrayDestroy(pRes); // memory leak
|
||||
taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -99,9 +102,8 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i
|
|||
|
||||
if (output == NULL) {
|
||||
if (pItem->type == STREAM_INPUT__DATA_RETRIEVE) {
|
||||
SSDataBlock block = {0};
|
||||
|
||||
const SStreamDataBlock* pRetrieveBlock = (const SStreamDataBlock*) pItem;
|
||||
SSDataBlock block = {0};
|
||||
const SStreamDataBlock* pRetrieveBlock = (const SStreamDataBlock*)pItem;
|
||||
ASSERT(taosArrayGetSize(pRetrieveBlock->blocks) == 1);
|
||||
|
||||
assignOneDataBlock(&block, taosArrayGet(pRetrieveBlock->blocks, 0));
|
||||
|
@ -132,7 +134,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i
|
|||
|
||||
taosArrayPush(pRes, &block);
|
||||
|
||||
qDebug("s-task:%s (child %d) executed and get block, total blocks:%d, size:%.2fMiB", pTask->id.idStr,
|
||||
qDebug("s-task:%s (child %d) executed and get %d result blocks, size:%.2fMiB", pTask->id.idStr,
|
||||
pTask->selfChildId, numOfBlocks, size / 1048576.0);
|
||||
|
||||
// current output should be dispatched to down stream nodes
|
||||
|
@ -153,7 +155,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i
|
|||
ASSERT(numOfBlocks == taosArrayGetSize(pRes));
|
||||
code = doDumpResult(pTask, pItem, pRes, size, totalSize, totalBlocks);
|
||||
} else {
|
||||
taosArrayDestroy(pRes);
|
||||
taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -235,11 +237,11 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) {
|
|||
taosFreeQitem(qRes);
|
||||
return code;
|
||||
}
|
||||
|
||||
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||
qDebug("s-task:%s scan exec dispatch blocks:%d", pTask->id.idStr, batchCnt);
|
||||
streamDispatchStreamBlock(pTask);
|
||||
}
|
||||
//
|
||||
// if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||
// qDebug("s-task:%s scan exec dispatch blocks:%d", pTask->id.idStr, batchCnt);
|
||||
// streamDispatchStreamBlock(pTask);
|
||||
// }
|
||||
|
||||
if (finished) {
|
||||
break;
|
||||
|
@ -286,7 +288,7 @@ int32_t streamBatchExec(SStreamTask* pTask, int32_t batchLimit) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int32_t updateCheckPointInfo (SStreamTask* pTask) {
|
||||
int32_t updateCheckPointInfo(SStreamTask* pTask) {
|
||||
int64_t ckId = 0;
|
||||
int64_t dataVer = 0;
|
||||
qGetCheckpointVersion(pTask->exec.pExecutor, &dataVer, &ckId);
|
||||
|
@ -294,7 +296,8 @@ int32_t updateCheckPointInfo (SStreamTask* pTask) {
|
|||
SCheckpointInfo* pCkInfo = &pTask->chkInfo;
|
||||
if (ckId > pCkInfo->id) { // save it since the checkpoint is updated
|
||||
qDebug("s-task:%s exec end, start to update check point, ver from %" PRId64 " to %" PRId64
|
||||
", checkPoint id:%" PRId64 " -> %" PRId64, pTask->id.idStr, pCkInfo->version, dataVer, pCkInfo->id, ckId);
|
||||
", checkPoint id:%" PRId64 " -> %" PRId64,
|
||||
pTask->id.idStr, pCkInfo->version, dataVer, pCkInfo->id, ckId);
|
||||
|
||||
pTask->chkInfo = (SCheckpointInfo){.version = dataVer, .id = ckId, .currentVer = pCkInfo->currentVer};
|
||||
|
||||
|
@ -314,8 +317,13 @@ int32_t updateCheckPointInfo (SStreamTask* pTask) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* todo: the batch of blocks should be tuned dynamic, according to the total elapsed time of each batch of blocks, the
|
||||
* appropriate batch of blocks should be handled in 5 to 10 sec.
|
||||
*/
|
||||
int32_t streamExecForAll(SStreamTask* pTask) {
|
||||
int32_t code = 0;
|
||||
const char* id = pTask->id.idStr;
|
||||
|
||||
while (1) {
|
||||
int32_t batchSize = 1;
|
||||
int16_t times = 0;
|
||||
|
@ -323,7 +331,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
SStreamQueueItem* pInput = NULL;
|
||||
|
||||
// merge multiple input data if possible in the input queue.
|
||||
qDebug("s-task:%s start to extract data block from inputQ", pTask->id.idStr);
|
||||
qDebug("s-task:%s start to extract data block from inputQ", id);
|
||||
|
||||
while (1) {
|
||||
if (streamTaskShouldPause(&pTask->status)) {
|
||||
|
@ -338,7 +346,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
if (qItem == NULL) {
|
||||
if (pTask->taskLevel == TASK_LEVEL__SOURCE && batchSize < MIN_STREAM_EXEC_BATCH_NUM && times < 5) {
|
||||
times++;
|
||||
taosMsleep(1);
|
||||
taosMsleep(10);
|
||||
qDebug("===stream===try again batchSize:%d", batchSize);
|
||||
continue;
|
||||
}
|
||||
|
@ -363,8 +371,10 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
batchSize++;
|
||||
pInput = newRet;
|
||||
streamQueueProcessSuccess(pTask->inputQueue);
|
||||
|
||||
if (batchSize > MAX_STREAM_EXEC_BATCH_NUM) {
|
||||
qDebug("maximum batch limit:%d reached, processing, %s", MAX_STREAM_EXEC_BATCH_NUM, pTask->id.idStr);
|
||||
qDebug("s-task:%s batch size limit:%d reached, start to process blocks", id,
|
||||
MAX_STREAM_EXEC_BATCH_NUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +385,6 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
if (pInput) {
|
||||
streamFreeQitem(pInput);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -385,7 +394,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
|
||||
if (pTask->taskLevel == TASK_LEVEL__SINK) {
|
||||
ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK);
|
||||
qDebug("s-task:%s sink node start to sink result. numOfBlocks:%d", pTask->id.idStr, batchSize);
|
||||
qDebug("s-task:%s sink task start to sink %d blocks", id, batchSize);
|
||||
streamTaskOutputResultBlock(pTask, (SStreamDataBlock*)pInput);
|
||||
continue;
|
||||
}
|
||||
|
@ -394,16 +403,16 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
while (pTask->taskLevel == TASK_LEVEL__SOURCE) {
|
||||
int8_t status = atomic_load_8(&pTask->status.taskStatus);
|
||||
if (status != TASK_STATUS__NORMAL && status != TASK_STATUS__PAUSE) {
|
||||
qError("stream task wait for the end of fill history, s-task:%s, status:%d", pTask->id.idStr,
|
||||
qError("stream task wait for the end of fill history, s-task:%s, status:%d", id,
|
||||
atomic_load_8(&pTask->status.taskStatus));
|
||||
taosMsleep(2);
|
||||
taosMsleep(100);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t st = taosGetTimestampMs();
|
||||
qDebug("s-task:%s start to execute, block batches:%d", pTask->id.idStr, batchSize);
|
||||
qDebug("s-task:%s start to process batch of blocks, num:%d", id, batchSize);
|
||||
|
||||
{
|
||||
// set input
|
||||
|
@ -417,21 +426,21 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
ASSERT(pTask->taskLevel == TASK_LEVEL__SOURCE);
|
||||
const SStreamDataSubmit* pSubmit = (const SStreamDataSubmit*)pInput;
|
||||
qSetMultiStreamInput(pExecutor, &pSubmit->submit, 1, STREAM_INPUT__DATA_SUBMIT);
|
||||
qDebug("s-task:%s set submit blocks as source block completed, %p %p len:%d ver:%" PRId64, pTask->id.idStr, pSubmit,
|
||||
qDebug("s-task:%s set submit blocks as source block completed, %p %p len:%d ver:%" PRId64, id, pSubmit,
|
||||
pSubmit->submit.msgStr, pSubmit->submit.msgLen, pSubmit->submit.ver);
|
||||
} else if (pItem->type == STREAM_INPUT__DATA_BLOCK || pItem->type == STREAM_INPUT__DATA_RETRIEVE) {
|
||||
const SStreamDataBlock* pBlock = (const SStreamDataBlock*)pInput;
|
||||
|
||||
SArray* pBlockList = pBlock->blocks;
|
||||
int32_t numOfBlocks = taosArrayGetSize(pBlockList);
|
||||
qDebug("s-task:%s set sdata blocks as input num:%d, ver:%" PRId64, pTask->id.idStr, numOfBlocks, pBlock->sourceVer);
|
||||
qDebug("s-task:%s set sdata blocks as input num:%d, ver:%" PRId64, id, numOfBlocks, pBlock->sourceVer);
|
||||
qSetMultiStreamInput(pExecutor, pBlockList->pData, numOfBlocks, STREAM_INPUT__DATA_BLOCK);
|
||||
} else if (pItem->type == STREAM_INPUT__MERGED_SUBMIT) {
|
||||
const SStreamMergedSubmit* pMerged = (const SStreamMergedSubmit*)pInput;
|
||||
|
||||
SArray* pBlockList = pMerged->submits;
|
||||
int32_t numOfBlocks = taosArrayGetSize(pBlockList);
|
||||
qDebug("s-task:%s %p set submit input (merged), batch num:%d", pTask->id.idStr, pTask, numOfBlocks);
|
||||
qDebug("s-task:%s %p set (merged) submit blocks as a batch, numOfBlocks:%d", id, pTask, numOfBlocks);
|
||||
qSetMultiStreamInput(pExecutor, pBlockList->pData, numOfBlocks, STREAM_INPUT__MERGED_SUBMIT);
|
||||
} else if (pItem->type == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
const SStreamRefDataBlock* pRefBlock = (const SStreamRefDataBlock*)pInput;
|
||||
|
@ -446,7 +455,8 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
streamTaskExecImpl(pTask, pInput, &resSize, &totalBlocks);
|
||||
|
||||
double el = (taosGetTimestampMs() - st) / 1000.0;
|
||||
qDebug("s-task:%s exec end, elapsed time:%.2fs, result size:%.2fMiB, numOfBlocks:%d", pTask->id.idStr, el, resSize / 1048576.0, totalBlocks);
|
||||
qDebug("s-task:%s batch of input blocks exec end, elapsed time:%.2fs, result size:%.2fMiB, numOfBlocks:%d",
|
||||
id, el, resSize / 1048576.0, totalBlocks);
|
||||
streamFreeQitem(pInput);
|
||||
}
|
||||
|
||||
|
|
|
@ -205,24 +205,25 @@ int32_t streamMetaSaveTask(SStreamMeta* pMeta, SStreamTask* pTask) {
|
|||
|
||||
// add to the ready tasks hash map, not the restored tasks hash map
|
||||
int32_t streamMetaAddDeployedTask(SStreamMeta* pMeta, int64_t ver, SStreamTask* pTask) {
|
||||
if (pMeta->expandFunc(pMeta->ahandle, pTask, ver) < 0) {
|
||||
tFreeStreamTask(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (streamMetaSaveTask(pMeta, pTask) < 0) {
|
||||
tFreeStreamTask(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (streamMetaCommit(pMeta) < 0) {
|
||||
tFreeStreamTask(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* p = taosHashGet(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId));
|
||||
if (p == NULL) {
|
||||
if (pMeta->expandFunc(pMeta->ahandle, pTask, ver) < 0) {
|
||||
tFreeStreamTask(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (streamMetaSaveTask(pMeta, pTask) < 0) {
|
||||
tFreeStreamTask(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (streamMetaCommit(pMeta) < 0) {
|
||||
tFreeStreamTask(pTask);
|
||||
return -1;
|
||||
}
|
||||
taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId), &pTask, POINTER_BYTES);
|
||||
|
@ -359,22 +360,29 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) {
|
|||
tDecodeStreamTask(&decoder, pTask);
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
if (pMeta->expandFunc(pMeta->ahandle, pTask, pTask->chkInfo.version) < 0) {
|
||||
// remove duplicate
|
||||
void* p = taosHashGet(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId));
|
||||
if (p == NULL) {
|
||||
if (pMeta->expandFunc(pMeta->ahandle, pTask, pTask->chkInfo.version) < 0) {
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
tdbTbcClose(pCur);
|
||||
taosMemoryFree(pTask);
|
||||
return -1;
|
||||
}
|
||||
taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
|
||||
} else {
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
tdbTbcClose(pCur);
|
||||
return -1;
|
||||
taosMemoryFree(pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
void* p = taosHashGet(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId));
|
||||
if (p == NULL) {
|
||||
taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
|
||||
}
|
||||
|
||||
if (taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId), &pTask, sizeof(void*)) < 0) {
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
tdbTbcClose(pCur);
|
||||
taosMemoryFree(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1062,7 +1062,7 @@ _end:
|
|||
}
|
||||
|
||||
int32_t streamStatePutParName(SStreamState* pState, int64_t groupId, const char tbname[TSDB_TABLE_NAME_LEN]) {
|
||||
qWarn("try to write to cf parname");
|
||||
qDebug("try to write to cf parname");
|
||||
#ifdef USE_ROCKSDB
|
||||
if (tSimpleHashGetSize(pState->parNameMap) > MAX_TABLE_NAME_NUM) {
|
||||
if (tSimpleHashGet(pState->parNameMap, &groupId, sizeof(int64_t)) == NULL) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue