diff --git a/cmake/taostools_CMakeLists.txt.in b/cmake/taostools_CMakeLists.txt.in
index ea4d48a2b1..49e94896cd 100644
--- a/cmake/taostools_CMakeLists.txt.in
+++ b/cmake/taostools_CMakeLists.txt.in
@@ -2,7 +2,7 @@
# taos-tools
ExternalProject_Add(taos-tools
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
- GIT_TAG c64858f
+ GIT_TAG 9284147
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE
diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md
index 2b39c4b9e5..48bc5e743e 100644
--- a/docs/en/12-taos-sql/10-function.md
+++ b/docs/en/12-taos-sql/10-function.md
@@ -945,7 +945,7 @@ MIN(expr)
MODE(expr)
```
-**Description**:The value which has the highest frequency of occurrence. NULL is returned if there are multiple values which have highest frequency of occurrence.
+**Description**:The value which has the highest frequency of occurrence. One random value is returned if there are multiple values which have highest frequency of occurrence.
**Return value type**: Same as the input data
diff --git a/docs/en/14-reference/03-connector/05-go.mdx b/docs/en/14-reference/03-connector/05-go.mdx
index f00e635af9..a33b302a92 100644
--- a/docs/en/14-reference/03-connector/05-go.mdx
+++ b/docs/en/14-reference/03-connector/05-go.mdx
@@ -7,7 +7,6 @@ title: TDengine Go Connector
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-import Preparition from "./_preparation.mdx"
import GoInsert from "../../07-develop/03-insert-data/_go_sql.mdx"
import GoInfluxLine from "../../07-develop/03-insert-data/_go_line.mdx"
import GoOpenTSDBTelnet from "../../07-develop/03-insert-data/_go_opts_telnet.mdx"
@@ -176,6 +175,37 @@ func main() {
}
```
+
+
+_taosRestful_ implements Go's `database/sql/driver` interface via `http client`. You can use the [`database/sql`](https://golang.org/pkg/database/sql/) interface by simply introducing the driver (driver-go minimum version 3.0.2).
+
+Use `taosWS` as `driverName` and use a correct [DSN](#DSN) as `dataSourceName` with the following parameters supported by the DSN.
+
+* `writeTimeout` The timeout to send data via WebSocket.
+* `readTimeout` The timeout to receive response data via WebSocket.
+
+For example:
+
+```go
+package main
+
+import (
+ "database/sql"
+ "fmt"
+
+ _ "github.com/taosdata/driver-go/v3/taosWS"
+)
+
+func main() {
+ var taosUri = "root:taosdata@ws(localhost:6041)/"
+ taos, err := sql.Open("taosWS", taosUri)
+ if err != nil {
+ fmt.Println("failed to connect TDengine, err:", err)
+ return
+ }
+}
+```
+
## Usage examples
@@ -331,7 +361,7 @@ Creates consumer group.
* `func (c *Consumer) Subscribe(topics []string) error`
-Subscribes to a topic.
+Subscribes to topics.
* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
@@ -409,6 +439,30 @@ Close consumer.
Closes the parameter binding.
+### Subscribe via WebSocket
+
+* `func NewConsumer(config *Config) (*Consumer, error)`
+
+ Creates consumer group.
+
+* `func (c *Consumer) Subscribe(topic []string) error`
+
+ Subscribes to topics.
+
+* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
+
+ Polling information.
+
+* `func (c *Consumer) Commit(messageID uint64) error`
+
+ Commit information.
+
+* `func (c *Consumer) Close() error`
+
+ Close consumer.
+
+For a complete example see [GitHub sample file](https://github.com/taosdata/driver-go/blob/3.0/examples/tmqoverws/main.go)
+
## API Reference
Full API see [driver-go documentation](https://pkg.go.dev/github.com/taosdata/driver-go/v3)
diff --git a/docs/en/14-reference/03-connector/_macos_install.mdx b/docs/en/14-reference/03-connector/_macos_install.mdx
index 8813d65869..effabbbebe 100644
--- a/docs/en/14-reference/03-connector/_macos_install.mdx
+++ b/docs/en/14-reference/03-connector/_macos_install.mdx
@@ -2,7 +2,7 @@ import PkgListV3 from "/components/PkgListV3";
1. Download the client installation package
-
+
[All Downloads](../../releases/tdengine)
diff --git a/docs/zh/08-connector/20-go.mdx b/docs/zh/08-connector/20-go.mdx
index 515d1b030b..7a6058db3c 100644
--- a/docs/zh/08-connector/20-go.mdx
+++ b/docs/zh/08-connector/20-go.mdx
@@ -177,6 +177,37 @@ func main() {
}
```
+
+
+_taosWS_ 通过 `WebSocket` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动(driver-go 最低版本 3.0.2)就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。
+
+使用 `taosWS` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数:
+
+* `writeTimeout` 通过 WebSocket 发送数据的超时时间。
+* `readTimeout` 通过 WebSocket 接收响应数据的超时时间。
+
+示例:
+
+```go
+package main
+
+import (
+ "database/sql"
+ "fmt"
+
+ _ "github.com/taosdata/driver-go/v3/taosWS"
+)
+
+func main() {
+ var taosUri = "root:taosdata@ws(localhost:6041)/"
+ taos, err := sql.Open("taosWS", taosUri)
+ if err != nil {
+ fmt.Println("failed to connect TDengine, err:", err)
+ return
+ }
+}
+```
+
## 使用示例
@@ -410,6 +441,30 @@ func main() {
结束参数绑定。
+### 通过 WebSocket 订阅
+
+* `func NewConsumer(config *Config) (*Consumer, error)`
+
+ 创建消费者。
+
+* `func (c *Consumer) Subscribe(topic []string) error`
+
+ 订阅主题。
+
+* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
+
+ 轮询消息。
+
+* `func (c *Consumer) Commit(messageID uint64) error`
+
+ 提交消息。
+
+* `func (c *Consumer) Close() error`
+
+ 关闭消费者。
+
+完整订阅示例参见 [GitHub 示例文件](https://github.com/taosdata/driver-go/blob/3.0/examples/tmqoverws/main.go)
+
## API 参考
全部 API 见 [driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3)
diff --git a/docs/zh/08-connector/_macos_install.mdx b/docs/zh/08-connector/_macos_install.mdx
index 4925ffabcd..081134dfee 100644
--- a/docs/zh/08-connector/_macos_install.mdx
+++ b/docs/zh/08-connector/_macos_install.mdx
@@ -2,7 +2,7 @@ import PkgListV3 from "/components/PkgListV3";
1. 下载客户端安装包
-
+
[所有下载](../../releases/tdengine)
diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md
index 9346c3f763..e7ed74631d 100644
--- a/docs/zh/12-taos-sql/10-function.md
+++ b/docs/zh/12-taos-sql/10-function.md
@@ -946,7 +946,7 @@ MIN(expr)
MODE(expr)
```
-**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,输出NULL。
+**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,则随机输出其中某个值。
**返回数据类型**:与输入数据类型一致。
diff --git a/include/client/taos.h b/include/client/taos.h
index 270b647a77..1182a9c2f7 100644
--- a/include/client/taos.h
+++ b/include/client/taos.h
@@ -198,6 +198,7 @@ DLL_EXPORT const void *taos_get_raw_block(TAOS_RES *res);
DLL_EXPORT int taos_load_table_info(TAOS *taos, const char *tableNameList);
DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision);
+DLL_EXPORT TAOS_RES *taos_schemaless_insert_raw(TAOS* taos, char* lines, int len, int32_t *totalRows, int protocol, int precision);
/* --------------------------TMQ INTERFACE------------------------------- */
diff --git a/include/common/tcommon.h b/include/common/tcommon.h
index eaddf4e983..bb2519bea3 100644
--- a/include/common/tcommon.h
+++ b/include/common/tcommon.h
@@ -44,12 +44,17 @@ enum {
)
// clang-format on
-typedef struct {
+typedef struct SWinKey {
uint64_t groupId;
TSKEY ts;
} SWinKey;
-static inline int sWinKeyCmprImpl(const void* pKey1, const void* pKey2) {
+typedef struct SSessionKey {
+ STimeWindow win;
+ uint64_t groupId;
+} SSessionKey;
+
+static inline int winKeyCmprImpl(const void* pKey1, const void* pKey2) {
SWinKey* pWin1 = (SWinKey*)pKey1;
SWinKey* pWin2 = (SWinKey*)pKey2;
@@ -69,7 +74,7 @@ static inline int sWinKeyCmprImpl(const void* pKey1, const void* pKey2) {
}
static inline int winKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) {
- return sWinKeyCmprImpl(pKey1, pKey2);
+ return winKeyCmprImpl(pKey1, pKey2);
}
typedef struct {
diff --git a/include/libs/stream/streamState.h b/include/libs/stream/streamState.h
index 9445a0baa5..ec68e8ed71 100644
--- a/include/libs/stream/streamState.h
+++ b/include/libs/stream/streamState.h
@@ -25,6 +25,8 @@ extern "C" {
typedef struct SStreamTask SStreamTask;
+typedef bool (*state_key_cmpr_fn)(void* pKey1, void* pKey2);
+
// incremental state storage
typedef struct {
SStreamTask* pOwner;
@@ -32,6 +34,7 @@ typedef struct {
TTB* pStateDb;
TTB* pFuncStateDb;
TTB* pFillStateDb; // todo refactor
+ TTB* pSessionStateDb;
TXN txn;
int32_t number;
} SStreamState;
@@ -57,6 +60,19 @@ int32_t streamStateDel(SStreamState* pState, const SWinKey* key);
int32_t streamStateClear(SStreamState* pState);
void streamStateSetNumber(SStreamState* pState, int32_t number);
+int32_t streamStateSessionAddIfNotExist(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen);
+int32_t streamStateSessionPut(SStreamState* pState, const SSessionKey* key, const void* value, int32_t vLen);
+int32_t streamStateSessionGet(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen);
+int32_t streamStateSessionDel(SStreamState* pState, const SSessionKey* key);
+int32_t streamStateSessionClear(SStreamState* pState);
+int32_t streamStateSessionGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, const void** pVal, int32_t* pVLen);
+int32_t streamStateStateAddIfNotExist(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
+ state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
+
+SStreamStateCur* streamStateSessionSeekKeyNext(SStreamState* pState, const SSessionKey* key);
+SStreamStateCur* streamStateSessionSeekKeyPrev(SStreamState* pState, const SSessionKey* key);
+SStreamStateCur* streamStateSessionGetCur(SStreamState* pState, const SSessionKey* key);
+
int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
int32_t streamStateFillDel(SStreamState* pState, const SWinKey* key);
diff --git a/include/util/tdef.h b/include/util/tdef.h
index d9bb558b74..2103dc928e 100644
--- a/include/util/tdef.h
+++ b/include/util/tdef.h
@@ -498,6 +498,7 @@ enum {
#define MAX_NUM_STR_SIZE 40
#define MAX_META_MSG_IN_BATCH 1048576
+#define MAX_META_BATCH_RSP_SIZE (1 * 1048576 * 1024)
#ifdef __cplusplus
}
diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c
index df717bda23..45d2de4a7a 100644
--- a/source/client/src/clientImpl.c
+++ b/source/client/src/clientImpl.c
@@ -199,7 +199,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
if (tsQueryUseNodeAllocator && !qIsInsertValuesSql((*pRequest)->sqlstr, (*pRequest)->sqlLen)) {
if (TSDB_CODE_SUCCESS !=
nodesCreateAllocator((*pRequest)->requestId, tsQueryNodeChunkSize, &((*pRequest)->allocatorRefId))) {
- tscError("%d failed to create node allocator, reqId:0x%" PRIx64 ", conn:%d, %s", (*pRequest)->self,
+ tscError("%d failed to create node allocator, reqId:0x%" PRIx64 ", conn:%" PRId64 ", %s", (*pRequest)->self,
(*pRequest)->requestId, pTscObj->id, sql);
destroyRequest(*pRequest);
@@ -955,7 +955,12 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQue
switch (pQuery->execMode) {
case QUERY_EXEC_MODE_LOCAL:
if (!pRequest->validateOnly) {
- code = execLocalCmd(pRequest, pQuery);
+ if (NULL == pQuery->pRoot) {
+ terrno = TSDB_CODE_INVALID_PARA;
+ code = terrno;
+ } else {
+ code = execLocalCmd(pRequest, pQuery);
+ }
}
break;
case QUERY_EXEC_MODE_RPC:
@@ -997,7 +1002,7 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQue
handleQueryExecRsp(pRequest);
- if (NULL != pRequest && TSDB_CODE_SUCCESS != code) {
+ if (TSDB_CODE_SUCCESS != code) {
pRequest->code = terrno;
}
@@ -2254,7 +2259,10 @@ void syncQueryFn(void* param, void* res, int32_t code) {
void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly) {
if (sql == NULL || NULL == fp) {
terrno = TSDB_CODE_INVALID_PARA;
- fp(param, NULL, terrno);
+ if (fp) {
+ fp(param, NULL, terrno);
+ }
+
return;
}
diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c
index 6126817ece..286fb85373 100644
--- a/source/client/src/clientMain.c
+++ b/source/client/src/clientMain.c
@@ -944,7 +944,6 @@ void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
if (pResultInfo->completed) {
// it is a local executed query, no need to do async fetch
if (QUERY_EXEC_MODE_LOCAL == pRequest->body.execMode) {
- ASSERT(pResultInfo->numOfRows >= 0);
if (pResultInfo->localResultFetched) {
pResultInfo->numOfRows = 0;
pResultInfo->current = 0;
diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c
index 8680f93f8c..945562ef36 100644
--- a/source/client/src/clientMsgHandler.c
+++ b/source/client/src/clientMsgHandler.c
@@ -292,8 +292,10 @@ int32_t processDropDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
tDeserializeSDropDbRsp(pMsg->pData, pMsg->len, &dropdbRsp);
struct SCatalog* pCatalog = NULL;
- catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
- catalogRemoveDB(pCatalog, dropdbRsp.db, dropdbRsp.uid);
+ int32_t code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
+ if (TSDB_CODE_SUCCESS == code) {
+ catalogRemoveDB(pCatalog, dropdbRsp.db, dropdbRsp.uid);
+ }
}
taosMemoryFree(pMsg->pData);
@@ -397,6 +399,7 @@ static int32_t buildShowVariablesRsp(SArray* pVars, SRetrieveTableRsp** pRsp) {
size_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock);
*pRsp = taosMemoryCalloc(1, rspSize);
if (NULL == *pRsp) {
+ blockDataDestroy(pBlock);
return TSDB_CODE_OUT_OF_MEMORY;
}
diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c
index 5c37822222..2c48eae59f 100644
--- a/source/client/src/clientSml.c
+++ b/source/client/src/clientSml.c
@@ -28,8 +28,8 @@
#define QUOTE '"'
#define SLASH '\\'
-#define JUMP_SPACE(sql) \
- while (*sql != '\0') { \
+#define JUMP_SPACE(sql, sqlEnd) \
+ while (sql < sqlEnd) { \
if (*sql == SPACE) \
sql++; \
else \
@@ -917,16 +917,17 @@ static int32_t smlParseValue(SSmlKv *pVal, SSmlMsgBuf *msg) {
return TSDB_CODE_TSC_INVALID_VALUE;
}
-static int32_t smlParseInfluxString(const char *sql, SSmlLineInfo *elements, SSmlMsgBuf *msg) {
+static int32_t smlParseInfluxString(const char *sql, const char *sqlEnd, SSmlLineInfo *elements, SSmlMsgBuf *msg) {
if (!sql) return TSDB_CODE_SML_INVALID_DATA;
- JUMP_SPACE(sql)
+ JUMP_SPACE(sql, sqlEnd)
if (*sql == COMMA) return TSDB_CODE_SML_INVALID_DATA;
elements->measure = sql;
// parse measure
- while (*sql != '\0') {
+ while (sql < sqlEnd) {
if ((sql != elements->measure) && IS_SLASH_LETTER(sql)) {
- MOVE_FORWARD_ONE(sql, strlen(sql) + 1);
+ MOVE_FORWARD_ONE(sql, sqlEnd - sql);
+ sqlEnd--;
continue;
}
if (IS_COMMA(sql)) {
@@ -950,7 +951,7 @@ static int32_t smlParseInfluxString(const char *sql, SSmlLineInfo *elements, SSm
} else {
if (*sql == COMMA) sql++;
elements->tags = sql;
- while (*sql != '\0') {
+ while (sql < sqlEnd) {
if (IS_SPACE(sql)) {
break;
}
@@ -961,10 +962,10 @@ static int32_t smlParseInfluxString(const char *sql, SSmlLineInfo *elements, SSm
elements->measureTagsLen = sql - elements->measure;
// parse cols
- JUMP_SPACE(sql)
+ JUMP_SPACE(sql, sqlEnd)
elements->cols = sql;
bool isInQuote = false;
- while (*sql != '\0') {
+ while (sql < sqlEnd) {
if (IS_QUOTE(sql)) {
isInQuote = !isInQuote;
}
@@ -984,10 +985,10 @@ static int32_t smlParseInfluxString(const char *sql, SSmlLineInfo *elements, SSm
}
// parse timestamp
- JUMP_SPACE(sql)
+ JUMP_SPACE(sql, sqlEnd)
elements->timestamp = sql;
- while (*sql != '\0') {
- if (*sql == SPACE) {
+ while (sql < sqlEnd) {
+ if (isspace(*sql)) {
break;
}
sql++;
@@ -997,8 +998,8 @@ static int32_t smlParseInfluxString(const char *sql, SSmlLineInfo *elements, SSm
return TSDB_CODE_SUCCESS;
}
-static void smlParseTelnetElement(const char **sql, const char **data, int32_t *len) {
- while (**sql != '\0') {
+static void smlParseTelnetElement(const char **sql, const char *sqlEnd, const char **data, int32_t *len) {
+ while (*sql < sqlEnd) {
if (**sql != SPACE && !(*data)) {
*data = *sql;
} else if (**sql == SPACE && *data) {
@@ -1009,20 +1010,20 @@ static void smlParseTelnetElement(const char **sql, const char **data, int32_t *
}
}
-static int32_t smlParseTelnetTags(const char *data, SArray *cols, char *childTableName, SHashObj *dumplicateKey,
+static int32_t smlParseTelnetTags(const char *data, const char *sqlEnd, SArray *cols, char *childTableName, SHashObj *dumplicateKey,
SSmlMsgBuf *msg) {
if(!cols) return TSDB_CODE_OUT_OF_MEMORY;
const char *sql = data;
size_t childTableNameLen = strlen(tsSmlChildTableName);
- while (*sql != '\0') {
- JUMP_SPACE(sql)
+ while (sql < sqlEnd) {
+ JUMP_SPACE(sql, sqlEnd)
if (*sql == '\0') break;
const char *key = sql;
int32_t keyLen = 0;
// parse key
- while (*sql != '\0') {
+ while (sql < sqlEnd) {
if (*sql == SPACE) {
smlBuildInvalidDataMsg(msg, "invalid data", sql);
return TSDB_CODE_SML_INVALID_DATA;
@@ -1047,7 +1048,7 @@ static int32_t smlParseTelnetTags(const char *data, SArray *cols, char *childTab
// parse value
const char *value = sql;
int32_t valueLen = 0;
- while (*sql != '\0') {
+ while (sql < sqlEnd) {
// parse value
if (*sql == SPACE) {
break;
@@ -1092,11 +1093,11 @@ static int32_t smlParseTelnetTags(const char *data, SArray *cols, char *childTab
}
// format: =[ =]
-static int32_t smlParseTelnetString(SSmlHandle *info, const char *sql, SSmlTableInfo *tinfo, SArray *cols) {
+static int32_t smlParseTelnetString(SSmlHandle *info, const char *sql, const char *sqlEnd, SSmlTableInfo *tinfo, SArray *cols) {
if (!sql) return TSDB_CODE_SML_INVALID_DATA;
// parse metric
- smlParseTelnetElement(&sql, &tinfo->sTableName, &tinfo->sTableNameLen);
+ smlParseTelnetElement(&sql, sqlEnd, &tinfo->sTableName, &tinfo->sTableNameLen);
if (!(tinfo->sTableName) || IS_INVALID_TABLE_LEN(tinfo->sTableNameLen)) {
smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", sql);
return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
@@ -1105,7 +1106,7 @@ static int32_t smlParseTelnetString(SSmlHandle *info, const char *sql, SSmlTable
// parse timestamp
const char *timestamp = NULL;
int32_t tLen = 0;
- smlParseTelnetElement(&sql, ×tamp, &tLen);
+ smlParseTelnetElement(&sql, sqlEnd, ×tamp, &tLen);
if (!timestamp || tLen == 0) {
smlBuildInvalidDataMsg(&info->msgBuf, "invalid timestamp", sql);
return TSDB_CODE_SML_INVALID_DATA;
@@ -1120,7 +1121,7 @@ static int32_t smlParseTelnetString(SSmlHandle *info, const char *sql, SSmlTable
// parse value
const char *value = NULL;
int32_t valueLen = 0;
- smlParseTelnetElement(&sql, &value, &valueLen);
+ smlParseTelnetElement(&sql, sqlEnd, &value, &valueLen);
if (!value || valueLen == 0) {
smlBuildInvalidDataMsg(&info->msgBuf, "invalid value", sql);
return TSDB_CODE_TSC_INVALID_VALUE;
@@ -1138,7 +1139,7 @@ static int32_t smlParseTelnetString(SSmlHandle *info, const char *sql, SSmlTable
}
// parse tags
- ret = smlParseTelnetTags(sql, tinfo->tags, tinfo->childTableName, info->dumplicateKey, &info->msgBuf);
+ ret = smlParseTelnetTags(sql, sqlEnd, tinfo->tags, tinfo->childTableName, info->dumplicateKey, &info->msgBuf);
if (ret != TSDB_CODE_SUCCESS) {
smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", sql);
return ret;
@@ -1371,8 +1372,14 @@ static int32_t smlKvTimeArrayCompare(const void *key1, const void *key2) {
static int32_t smlKvTimeHashCompare(const void *key1, const void *key2) {
SHashObj *s1 = *(SHashObj **)key1;
SHashObj *s2 = *(SHashObj **)key2;
- SSmlKv *kv1 = *(SSmlKv **)taosHashGet(s1, TS, TS_LEN);
- SSmlKv *kv2 = *(SSmlKv **)taosHashGet(s2, TS, TS_LEN);
+ SSmlKv **kv1pp = (SSmlKv **)taosHashGet(s1, TS, TS_LEN);
+ SSmlKv **kv2pp = (SSmlKv **)taosHashGet(s2, TS, TS_LEN);
+ if(!kv1pp || !kv2pp){
+ uError("smlKvTimeHashCompare kv is null");
+ return -1;
+ }
+ SSmlKv *kv1 = *kv1pp;
+ SSmlKv *kv2 = *kv2pp;
if(!kv1 || kv1->type != TSDB_DATA_TYPE_TIMESTAMP){
uError("smlKvTimeHashCompare kv1");
return -1;
@@ -2073,11 +2080,11 @@ static int32_t smlParseJSONString(SSmlHandle *info, cJSON *root, SSmlTableInfo *
}
/************* TSDB_SML_JSON_PROTOCOL function end **************/
-static int32_t smlParseInfluxLine(SSmlHandle *info, const char *sql) {
+static int32_t smlParseInfluxLine(SSmlHandle *info, const char *sql, const int len) {
SSmlLineInfo elements = {0};
uDebug("SML:0x%" PRIx64 " smlParseInfluxLine sql:%s, hello", info->id, sql);
- int ret = smlParseInfluxString(sql, &elements, &info->msgBuf);
+ int ret = smlParseInfluxString(sql, sql + len, &elements, &info->msgBuf);
if (ret != TSDB_CODE_SUCCESS) {
uError("SML:0x%" PRIx64 " smlParseInfluxLine failed", info->id);
return ret;
@@ -2184,7 +2191,7 @@ static int32_t smlParseInfluxLine(SSmlHandle *info, const char *sql) {
return TSDB_CODE_SUCCESS;
}
-static int32_t smlParseTelnetLine(SSmlHandle *info, void *data) {
+static int32_t smlParseTelnetLine(SSmlHandle *info, void *data, const int len) {
int ret = TSDB_CODE_SUCCESS;
SSmlTableInfo *tinfo = smlBuildTableInfo();
if (!tinfo) {
@@ -2198,7 +2205,7 @@ static int32_t smlParseTelnetLine(SSmlHandle *info, void *data) {
}
if (info->protocol == TSDB_SML_TELNET_PROTOCOL) {
- ret = smlParseTelnetString(info, (const char *)data, tinfo, cols);
+ ret = smlParseTelnetString(info, (const char *)data, (char*)data + len, tinfo, cols);
} else if (info->protocol == TSDB_SML_JSON_PROTOCOL) {
ret = smlParseJSONString(info, (cJSON *)data, tinfo, cols);
} else {
@@ -2289,7 +2296,7 @@ static int32_t smlParseJSON(SSmlHandle *info, char *payload) {
for (int32_t i = 0; i < payloadNum; ++i) {
cJSON *dataPoint = (payloadNum == 1 && cJSON_IsObject(root)) ? root : cJSON_GetArrayItem(root, i);
- ret = smlParseTelnetLine(info, dataPoint);
+ ret = smlParseTelnetLine(info, dataPoint, -1);
if (ret != TSDB_CODE_SUCCESS) {
uError("SML:0x%" PRIx64 " Invalid JSON Payload", info->id);
goto end;
@@ -2378,10 +2385,14 @@ static void smlPrintStatisticInfo(SSmlHandle *info) {
info->cost.endTime - info->cost.insertRpcTime, info->cost.endTime - info->cost.parseTime);
}
-static int32_t smlParseLine(SSmlHandle *info, char *lines[], int numLines) {
+static int32_t smlParseLine(SSmlHandle *info, char *lines[], char* rawLine, char* rawLineEnd, int numLines) {
int32_t code = TSDB_CODE_SUCCESS;
if (info->protocol == TSDB_SML_JSON_PROTOCOL) {
- code = smlParseJSON(info, *lines);
+ if(lines){
+ code = smlParseJSON(info, *lines);
+ }else if(rawLine){
+ code = smlParseJSON(info, rawLine);
+ }
if (code != TSDB_CODE_SUCCESS) {
uError("SML:0x%" PRIx64 " smlParseJSON failed:%s", info->id, *lines);
return code;
@@ -2390,28 +2401,46 @@ static int32_t smlParseLine(SSmlHandle *info, char *lines[], int numLines) {
}
for (int32_t i = 0; i < numLines; ++i) {
+ char *tmp = NULL;
+ int len = 0;
+ if(lines){
+ tmp = lines[i];
+ len = strlen(tmp);
+ }else if(rawLine){
+ tmp = rawLine;
+ while(rawLine < rawLineEnd){
+ if(*(rawLine++) == '\n'){
+ break;
+ }
+ len++;
+ }
+ if(info->protocol == TSDB_SML_LINE_PROTOCOL && tmp[0] == '#'){ // this line is comment
+ continue;
+ }
+ }
+
if (info->protocol == TSDB_SML_LINE_PROTOCOL) {
- code = smlParseInfluxLine(info, lines[i]);
+ code = smlParseInfluxLine(info, tmp, len);
} else if (info->protocol == TSDB_SML_TELNET_PROTOCOL) {
- code = smlParseTelnetLine(info, lines[i]);
+ code = smlParseTelnetLine(info, tmp, len);
} else {
ASSERT(0);
}
if (code != TSDB_CODE_SUCCESS) {
- uError("SML:0x%" PRIx64 " smlParseLine failed. line %d : %s", info->id, i, lines[i]);
+ uError("SML:0x%" PRIx64 " smlParseLine failed. line %d : %s", info->id, i, tmp);
return code;
}
}
return code;
}
-static int smlProcess(SSmlHandle *info, char *lines[], int numLines) {
+static int smlProcess(SSmlHandle *info, char *lines[], char* rawLine, char* rawLineEnd, int numLines) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t retryNum = 0;
info->cost.parseTime = taosGetTimestampUs();
- code = smlParseLine(info, lines, numLines);
+ code = smlParseLine(info, lines, rawLine, rawLineEnd, numLines);
if (code != 0) {
uError("SML:0x%" PRIx64 " smlParseLine error : %s", info->id, tstrerror(code));
return code;
@@ -2504,39 +2533,8 @@ static void smlInsertCallback(void *param, void *res, int32_t code) {
smlDestroyInfo(info);
}
-/**
- * taos_schemaless_insert() parse and insert data points into database according to
- * different protocol.
- *
- * @param $lines input array may contain multiple lines, each line indicates a data point.
- * If protocol=2 is used input array should contain single JSON
- * string(e.g. char *lines[] = {"$JSON_string"}). If need to insert
- * multiple data points in JSON format, should include them in $JSON_string
- * as a JSON array.
- * @param $numLines indicates how many data points in $lines.
- * If protocol = 2 is used this param will be ignored as $lines should
- * contain single JSON string.
- * @param $protocol indicates which protocol to use for parsing:
- * 0 - influxDB line protocol
- * 1 - OpenTSDB telnet line protocol
- * 2 - OpenTSDB JSON format protocol
- * @return return zero for successful insertion. Otherwise return none-zero error code of
- * failure reason.
- *
- */
-
-TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision) {
- if (NULL == taos) {
- terrno = TSDB_CODE_TSC_DISCONNECTED;
- return NULL;
- }
-
- SRequestObj *request = (SRequestObj *)createRequest(*(int64_t *)taos, TSDB_SQL_INSERT);
- if (!request) {
- uError("SML:taos_schemaless_insert error request is null");
- return NULL;
- }
+TAOS_RES *taos_schemaless_insert_inner(SRequestObj *request, char *lines[], char *rawLine, char *rawLineEnd, int numLines, int protocol, int precision) {
int batchs = 0;
STscObj *pTscObj = request->pTscObj;
@@ -2560,12 +2558,6 @@ TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int pr
goto end;
}
- if (!lines) {
- request->code = TSDB_CODE_SML_INVALID_DATA;
- smlBuildInvalidDataMsg(&msg, "lines is null", NULL);
- goto end;
- }
-
if (protocol < TSDB_SML_LINE_PROTOCOL || protocol > TSDB_SML_JSON_PROTOCOL) {
request->code = TSDB_CODE_SML_INVALID_PROTOCOL_TYPE;
smlBuildInvalidDataMsg(&msg, "protocol invalidate", NULL);
@@ -2616,15 +2608,28 @@ TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int pr
info->affectedRows = perBatch;
info->pRequest->body.queryFp = smlInsertCallback;
info->pRequest->body.param = info;
- int32_t code = smlProcess(info, lines, perBatch);
- lines += perBatch;
+ int32_t code = smlProcess(info, lines, rawLine, rawLineEnd, perBatch);
+ if(lines){
+ lines += perBatch;
+ }
+ if(rawLine){
+ int num = 0;
+ while(rawLine < rawLineEnd){
+ if(*(rawLine++) == '\n'){
+ num++;
+ }
+ if(num == perBatch){
+ break;
+ }
+ }
+ }
if (code != TSDB_CODE_SUCCESS) {
info->pRequest->body.queryFp(info, req, code);
}
}
tsem_wait(¶ms.sem);
-end:
+ end:
taosThreadSpinDestroy(¶ms.lock);
tsem_destroy(¶ms.sem);
// ((STscObj *)taos)->schemalessType = 0;
@@ -2632,3 +2637,80 @@ end:
uDebug("resultend:%s", request->msgBuf);
return (TAOS_RES *)request;
}
+
+/**
+ * taos_schemaless_insert() parse and insert data points into database according to
+ * different protocol.
+ *
+ * @param $lines input array may contain multiple lines, each line indicates a data point.
+ * If protocol=2 is used input array should contain single JSON
+ * string(e.g. char *lines[] = {"$JSON_string"}). If need to insert
+ * multiple data points in JSON format, should include them in $JSON_string
+ * as a JSON array.
+ * @param $numLines indicates how many data points in $lines.
+ * If protocol = 2 is used this param will be ignored as $lines should
+ * contain single JSON string.
+ * @param $protocol indicates which protocol to use for parsing:
+ * 0 - influxDB line protocol
+ * 1 - OpenTSDB telnet line protocol
+ * 2 - OpenTSDB JSON format protocol
+ * @return return zero for successful insertion. Otherwise return none-zero error code of
+ * failure reason.
+ *
+ */
+
+TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision) {
+ if (NULL == taos) {
+ terrno = TSDB_CODE_TSC_DISCONNECTED;
+ return NULL;
+ }
+
+ SRequestObj *request = (SRequestObj *)createRequest(*(int64_t *)taos, TSDB_SQL_INSERT);
+ if (!request) {
+ uError("SML:taos_schemaless_insert error request is null");
+ return NULL;
+ }
+
+ if (!lines) {
+ SSmlMsgBuf msg = {ERROR_MSG_BUF_DEFAULT_SIZE, request->msgBuf};
+ request->code = TSDB_CODE_SML_INVALID_DATA;
+ smlBuildInvalidDataMsg(&msg, "lines is null", NULL);
+ return (TAOS_RES *)request;
+ }
+
+ return taos_schemaless_insert_inner(request, lines, NULL, NULL, numLines, protocol, precision);
+}
+
+TAOS_RES *taos_schemaless_insert_raw(TAOS* taos, char* lines, int len, int32_t *totalRows, int protocol, int precision){
+ if (NULL == taos) {
+ terrno = TSDB_CODE_TSC_DISCONNECTED;
+ return NULL;
+ }
+
+ SRequestObj *request = (SRequestObj *)createRequest(*(int64_t *)taos, TSDB_SQL_INSERT);
+ if (!request) {
+ uError("SML:taos_schemaless_insert error request is null");
+ return NULL;
+ }
+
+ if (!lines || len <= 0) {
+ SSmlMsgBuf msg = {ERROR_MSG_BUF_DEFAULT_SIZE, request->msgBuf};
+ request->code = TSDB_CODE_SML_INVALID_DATA;
+ smlBuildInvalidDataMsg(&msg, "lines is null", NULL);
+ return (TAOS_RES *)request;
+ }
+
+ int numLines = 0;
+ *totalRows = 0;
+ char *tmp = lines;
+ for(int i = 0; i < len; i++){
+ if(lines[i] == '\n' || i == len - 1){
+ numLines++;
+ if(tmp[0] != '#' || protocol != TSDB_SML_LINE_PROTOCOL){ //ignore comment
+ (*totalRows)++;
+ }
+ tmp = lines + i + 1;
+ }
+ }
+ return taos_schemaless_insert_inner(request, NULL, lines, lines + len, numLines, protocol, precision);
+}
diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c
index bf3fd00f14..81d0d616c9 100644
--- a/source/client/src/clientStmt.c
+++ b/source/client/src/clientStmt.c
@@ -152,7 +152,7 @@ int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags,
pStmt->bInfo.tbType = pTableMeta->tableType;
pStmt->bInfo.boundTags = tags;
pStmt->bInfo.tagsCached = false;
- strcpy(pStmt->bInfo.stbFName, sTableName);
+ tstrncpy(pStmt->bInfo.stbFName, sTableName, sizeof(pStmt->bInfo.stbFName));
return TSDB_CODE_SUCCESS;
}
diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c
index 838b851d6d..0bc33739c6 100644
--- a/source/client/src/clientTmq.c
+++ b/source/client/src/clientTmq.c
@@ -210,6 +210,8 @@ typedef struct {
typedef struct {
SMqCommitCbParamSet* params;
STqOffset* pOffset;
+ /*char topicName[TSDB_TOPIC_FNAME_LEN];*/
+ /*int32_t vgId;*/
} SMqCommitCbParam;
tmq_conf_t* tmq_conf_new() {
@@ -407,6 +409,14 @@ int32_t tmqCommitDone(SMqCommitCbParamSet* pParamSet) {
return 0;
}
+static void tmqCommitRspCountDown(SMqCommitCbParamSet* pParamSet) {
+ int32_t waitingRspNum = atomic_sub_fetch_32(&pParamSet->waitingRspNum, 1);
+ ASSERT(waitingRspNum >= 0);
+ if (waitingRspNum == 0) {
+ tmqCommitDone(pParamSet);
+ }
+}
+
int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) {
SMqCommitCbParam* pParam = (SMqCommitCbParam*)param;
SMqCommitCbParamSet* pParamSet = (SMqCommitCbParamSet*)pParam->params;
@@ -420,18 +430,13 @@ int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) {
#endif
taosMemoryFree(pParam->pOffset);
- if (pBuf->pData) taosMemoryFree(pBuf->pData);
+ taosMemoryFree(pBuf->pData);
/*tscDebug("receive offset commit cb of %s on vgId:%d, offset is %" PRId64, pParam->pOffset->subKey, pParam->->vgId,
* pOffset->version);*/
- // count down waiting rsp
- int32_t waitingRspNum = atomic_sub_fetch_32(&pParamSet->waitingRspNum, 1);
- ASSERT(waitingRspNum >= 0);
+ tmqCommitRspCountDown(pParamSet);
- if (waitingRspNum == 0) {
- tmqCommitDone(pParamSet);
- }
return 0;
}
@@ -591,14 +596,10 @@ FAIL:
return 0;
}
-int32_t tmqCommitInner(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_t async, tmq_commit_cb* userCb,
- void* userParam) {
+static int32_t tmqCommitConsumerImpl(tmq_t* tmq, int8_t automatic, int8_t async, tmq_commit_cb* userCb,
+ void* userParam) {
int32_t code = -1;
- if (msg != NULL) {
- return tmqCommitMsgImpl(tmq, msg, async, userCb, userParam);
- }
-
SMqCommitCbParamSet* pParamSet = taosMemoryCalloc(1, sizeof(SMqCommitCbParamSet));
if (pParamSet == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
@@ -646,33 +647,37 @@ int32_t tmqCommitInner(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_t
}
}
+ // no request is sent
if (pParamSet->totalRspNum == 0) {
tsem_destroy(&pParamSet->rspSem);
taosMemoryFree(pParamSet);
return 0;
}
- int32_t waitingRspNum = atomic_sub_fetch_32(&pParamSet->waitingRspNum, 1);
- ASSERT(waitingRspNum >= 0);
- if (waitingRspNum == 0) {
- tmqCommitDone(pParamSet);
- }
+ // count down since waiting rsp num init as 1
+ tmqCommitRspCountDown(pParamSet);
if (!async) {
tsem_wait(&pParamSet->rspSem);
code = pParamSet->rspErr;
tsem_destroy(&pParamSet->rspSem);
taosMemoryFree(pParamSet);
- }
-
#if 0
- if (!async) {
taosArrayDestroyP(pParamSet->successfulOffsets, taosMemoryFree);
taosArrayDestroyP(pParamSet->failedOffsets, taosMemoryFree);
- }
#endif
+ }
- return 0;
+ return code;
+}
+
+int32_t tmqCommitInner(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_t async, tmq_commit_cb* userCb,
+ void* userParam) {
+ if (msg) {
+ return tmqCommitMsgImpl(tmq, msg, async, userCb, userParam);
+ } else {
+ return tmqCommitConsumerImpl(tmq, automatic, async, userCb, userParam);
+ }
}
void tmqAssignAskEpTask(void* param, void* tmrId) {
diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp
index ab4442eca7..54778e87a7 100644
--- a/source/client/test/smlTest.cpp
+++ b/source/client/test/smlTest.cpp
@@ -44,7 +44,7 @@ TEST(testCase, smlParseInfluxString_Test) {
char *tmp = "\\,st,t1=3,t2=4,t3=t3 c1=3i64,c3=\"passit hello,c1=2\",c2=false,c4=4f64 1626006833639000000 ,32,c=3";
char *sql = (char *)taosMemoryCalloc(256, 1);
memcpy(sql, tmp, strlen(tmp) + 1);
- int ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ int ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_EQ(ret, 0);
ASSERT_EQ(elements.measure, sql);
ASSERT_EQ(elements.measureLen, strlen(",st"));
@@ -63,14 +63,14 @@ TEST(testCase, smlParseInfluxString_Test) {
tmp = "st,t1=3,t2=4,t3=t3 c1=3i64,c3=\"passit hello,c1=2,c2=false,c4=4f64 1626006833639000000";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_NE(ret, 0);
// case 3 false
tmp = "st, t1=3,t2=4,t3=t3 c1=3i64,c3=\"passit hello,c1=2,c2=false,c4=4f64 1626006833639000000";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_EQ(ret, 0);
ASSERT_EQ(elements.cols, sql + elements.measureTagsLen + 1);
ASSERT_EQ(elements.colsLen, strlen("t1=3,t2=4,t3=t3"));
@@ -79,7 +79,7 @@ TEST(testCase, smlParseInfluxString_Test) {
tmp = "st, c1=3i64,c3=\"passit hello,c1=2\",c2=false,c4=4f64 1626006833639000000";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_EQ(ret, 0);
ASSERT_EQ(elements.measure, sql);
ASSERT_EQ(elements.measureLen, strlen("st"));
@@ -98,7 +98,7 @@ TEST(testCase, smlParseInfluxString_Test) {
tmp = " st c1=3i64,c3=\"passit hello,c1=2\",c2=false,c4=4f64 1626006833639000000 ";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_EQ(ret, 0);
ASSERT_EQ(elements.measure, sql + 1);
ASSERT_EQ(elements.measureLen, strlen("st"));
@@ -116,21 +116,21 @@ TEST(testCase, smlParseInfluxString_Test) {
tmp = " st c1=3i64,c3=\"passit hello,c1=2\",c2=false,c4=4f64 ";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_EQ(ret, 0);
// case 7
tmp = " st , ";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_EQ(ret, 0);
// case 8 false
tmp = ", st , ";
memcpy(sql, tmp, strlen(tmp) + 1);
memset(&elements, 0, sizeof(SSmlLineInfo));
- ret = smlParseInfluxString(sql, &elements, &msgBuf);
+ ret = smlParseInfluxString(sql, sql + strlen(sql), &elements, &msgBuf);
ASSERT_NE(ret, 0);
taosMemoryFree(sql);
}
@@ -542,7 +542,7 @@ TEST(testCase, smlParseTelnetLine_error_Test) {
"sys.procs.running 1479496100 42 host= web01",
};
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) {
- int ret = smlParseTelnetLine(info, (void *)sql[i]);
+ int ret = smlParseTelnetLine(info, (void *)sql[i], strlen(sql[i]));
ASSERT_NE(ret, 0);
}
@@ -561,7 +561,7 @@ TEST(testCase, smlParseTelnetLine_diff_type_Test) {
int ret = TSDB_CODE_SUCCESS;
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) {
- ret = smlParseTelnetLine(info, (void *)sql[i]);
+ ret = smlParseTelnetLine(info, (void *)sql[i], strlen(sql[i]));
if (ret != TSDB_CODE_SUCCESS) break;
}
ASSERT_NE(ret, 0);
@@ -617,7 +617,7 @@ TEST(testCase, smlParseTelnetLine_json_error_Test) {
int ret = TSDB_CODE_SUCCESS;
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) {
- ret = smlParseTelnetLine(info, (void *)sql[i]);
+ ret = smlParseTelnetLine(info, (void *)sql[i], strlen(sql[i]));
ASSERT_NE(ret, 0);
}
@@ -653,7 +653,7 @@ TEST(testCase, smlParseTelnetLine_diff_json_type1_Test) {
int ret = TSDB_CODE_SUCCESS;
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) {
- ret = smlParseTelnetLine(info, (void *)sql[i]);
+ ret = smlParseTelnetLine(info, (void *)sql[i], strlen(sql[i]));
if (ret != TSDB_CODE_SUCCESS) break;
}
ASSERT_NE(ret, 0);
@@ -688,7 +688,7 @@ TEST(testCase, smlParseTelnetLine_diff_json_type2_Test) {
};
int ret = TSDB_CODE_SUCCESS;
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) {
- ret = smlParseTelnetLine(info, (void *)sql[i]);
+ ret = smlParseTelnetLine(info, (void *)sql[i], strlen(sql[i]));
if (ret != TSDB_CODE_SUCCESS) break;
}
ASSERT_NE(ret, 0);
@@ -1002,7 +1002,7 @@ TEST(testCase, sml_col_4096_Test) {
int ret = TSDB_CODE_SUCCESS;
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) {
- ret = smlParseInfluxLine(info, sql[i]);
+ ret = smlParseInfluxLine(info, sql[i], strlen(sql[i]));
if (ret != TSDB_CODE_SUCCESS) break;
}
ASSERT_NE(ret, 0);
diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c
index 1028a899b6..62706db980 100644
--- a/source/common/src/tdatablock.c
+++ b/source/common/src/tdatablock.c
@@ -1892,12 +1892,13 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
for (int32_t k = 0; k < colNum; k++) {
SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k);
- void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes);
if (colDataIsNull(pColInfoData, rows, j, NULL) || !pColInfoData->pData) {
len += snprintf(dumpBuf + len, size - len, " %15s |", "NULL");
if (len >= size - 1) return dumpBuf;
continue;
}
+
+ void* var = colDataGetData(pColInfoData, j);
switch (pColInfoData->info.type) {
case TSDB_DATA_TYPE_TIMESTAMP:
memset(pBuf, 0, sizeof(pBuf));
@@ -1926,8 +1927,8 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
if (len >= size - 1) return dumpBuf;
break;
case TSDB_DATA_TYPE_DOUBLE:
- len += snprintf(dumpBuf + len, size - len, " %15lf |", *(double*)var);
- if (len >= size - 1) return dumpBuf;
+ // len += snprintf(dumpBuf + len, size - len, " %15lf |", *(double*)var);
+ // if (len >= size - 1) return dumpBuf;
break;
case TSDB_DATA_TYPE_BOOL:
len += snprintf(dumpBuf + len, size - len, " %15d |", *(bool*)var);
diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c
index 076826ebc2..5a7f149bc6 100644
--- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c
+++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c
@@ -51,6 +51,7 @@ static int32_t dmInitMonitor() {
static bool dmCheckDiskSpace() {
osUpdate();
+ // sufficiency
if (!osDataSpaceSufficient()) {
dWarn("free data disk size: %f GB, not sufficient, expected %f GB at least", (double)tsDataSpace.size.avail / 1024.0 / 1024.0 / 1024.0, (double)tsDataSpace.reserved / 1024.0 / 1024.0 / 1024.0);
}
@@ -60,7 +61,24 @@ static bool dmCheckDiskSpace() {
if (!osTempSpaceSufficient()) {
dWarn("free temp disk size: %f GB, not sufficient, expected %f GB at least", (double)tsTempSpace.size.avail / 1024.0 / 1024.0 / 1024.0, (double)tsTempSpace.reserved / 1024.0 / 1024.0 / 1024.0);
}
- return true;
+ // availability
+ bool ret = true;
+ if (!osDataSpaceAvailable()) {
+ dError("data disk space unavailable, i.e. %s", tsDataDir);
+ terrno = TSDB_CODE_VND_NO_DISKSPACE;
+ ret = false;
+ }
+ if (!osLogSpaceAvailable()) {
+ dError("log disk space unavailable, i.e. %s", tsLogDir);
+ terrno = TSDB_CODE_VND_NO_DISKSPACE;
+ ret = false;
+ }
+ if (!osTempSpaceAvailable()) {
+ dError("temp disk space unavailable, i.e. %s", tsTempDir);
+ terrno = TSDB_CODE_VND_NO_DISKSPACE;
+ ret = false;
+ }
+ return ret;
}
static bool dmCheckDataDirVersion() {
diff --git a/source/dnode/mgmt/test/sut/src/sut.cpp b/source/dnode/mgmt/test/sut/src/sut.cpp
index 699203e8c1..a4d2e46881 100644
--- a/source/dnode/mgmt/test/sut/src/sut.cpp
+++ b/source/dnode/mgmt/test/sut/src/sut.cpp
@@ -43,9 +43,7 @@ void Testbase::InitLog(const char* path) {
}
void Testbase::Init(const char* path, int16_t port) {
-#ifdef _TD_DARWIN_64
osDefaultInit();
-#endif
tsServerPort = port;
strcpy(tsLocalFqdn, "localhost");
snprintf(tsLocalEp, TSDB_EP_LEN, "%s:%u", tsLocalFqdn, tsServerPort);
diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c
index 5fb23b045c..8314601df3 100644
--- a/source/dnode/mnode/impl/src/mndMain.c
+++ b/source/dnode/mnode/impl/src/mndMain.c
@@ -603,22 +603,27 @@ static int32_t mndCheckMnodeState(SRpcMsg *pMsg) {
return 0;
}
if (mndAcquireRpc(pMsg->info.node) == 0) return 0;
+
+ SMnode *pMnode = pMsg->info.node;
+ const char *role = syncGetMyRoleStr(pMnode->syncMgmt.sync);
+ bool restored = syncIsRestoreFinish(pMnode->syncMgmt.sync);
if (pMsg->msgType == TDMT_MND_MQ_TIMER || pMsg->msgType == TDMT_MND_TELEM_TIMER ||
pMsg->msgType == TDMT_MND_TRANS_TIMER || pMsg->msgType == TDMT_MND_TTL_TIMER ||
pMsg->msgType == TDMT_MND_UPTIME_TIMER) {
+ mTrace("timer not process since mnode restored:%d stopped:%d, sync restored:%d role:%s ", pMnode->restored,
+ pMnode->stopped, restored, role);
return -1;
}
- SEpSet epSet = {0};
- SMnode *pMnode = pMsg->info.node;
+ const STraceId *trace = &pMsg->info.traceId;
+ SEpSet epSet = {0};
mndGetMnodeEpSet(pMnode, &epSet);
- const STraceId *trace = &pMsg->info.traceId;
mDebug(
- "msg:%p, failed to check mnode state since %s, mnode restored:%d stopped:%d, sync restored:%d role:%s type:%s "
- "numOfEps:%d inUse:%d",
- pMsg, terrstr(), pMnode->restored, pMnode->stopped, syncIsRestoreFinish(pMnode->syncMgmt.sync),
- syncGetMyRoleStr(pMnode->syncMgmt.sync), TMSG_INFO(pMsg->msgType), epSet.numOfEps, epSet.inUse);
+ "msg:%p, type:%s failed to process since %s, mnode restored:%d stopped:%d, sync restored:%d "
+ "role:%s, redirect numOfEps:%d inUse:%d",
+ pMsg, TMSG_INFO(pMsg->msgType), terrstr(), pMnode->restored, pMnode->stopped, restored, role, epSet.numOfEps,
+ epSet.inUse);
if (epSet.numOfEps > 0) {
for (int32_t i = 0; i < epSet.numOfEps; ++i) {
diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c
index c27241317c..e23b895ebd 100644
--- a/source/dnode/mnode/impl/src/mndMnode.c
+++ b/source/dnode/mnode/impl/src/mndMnode.c
@@ -394,7 +394,6 @@ static int32_t mndCreateMnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode,
if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj) != 0) goto _OVER;
if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj) != 0) goto _OVER;
if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeObj) != 0) goto _OVER;
- if (mndTransAppendNullLog(pTrans) != 0) goto _OVER;
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
code = 0;
@@ -478,7 +477,6 @@ static int32_t mndSetDropMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeO
static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) {
SSdb *pSdb = pMnode->pSdb;
void *pIter = NULL;
- int32_t numOfReplicas = 0;
SDDropMnodeReq dropReq = {0};
SEpSet dropEpSet = {0};
@@ -505,9 +503,8 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode
int32_t mndSetDropMnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) {
if (pObj == NULL) return 0;
- if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) return -1;
if (mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj) != 0) return -1;
- if (mndTransAppendNullLog(pTrans) != 0) return -1;
+ if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) return -1;
return 0;
}
@@ -715,7 +712,8 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
SMnodeObj *pObj = NULL;
ESdbStatus objStatus = 0;
void *pIter = NULL;
- bool hasUpdatingMnode = false;
+ int32_t updatingMnodes = 0;
+ int32_t readyMnodes = 0;
SSyncCfg cfg = {.myIndex = -1};
while (1) {
@@ -723,7 +721,11 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
if (pIter == NULL) break;
if (objStatus == SDB_STATUS_CREATING || objStatus == SDB_STATUS_DROPPING) {
mInfo("vgId:1, has updating mnode:%d, status:%s", pObj->id, sdbStatusName(objStatus));
- hasUpdatingMnode = true;
+ updatingMnodes++;
+ }
+ if (objStatus == SDB_STATUS_READY) {
+ mInfo("vgId:1, has ready mnode:%d, status:%s", pObj->id, sdbStatusName(objStatus));
+ readyMnodes++;
}
if (objStatus == SDB_STATUS_READY || objStatus == SDB_STATUS_CREATING) {
@@ -739,18 +741,25 @@ static void mndReloadSyncConfig(SMnode *pMnode) {
sdbReleaseLock(pSdb, pObj, false);
}
+ if (readyMnodes <= 0 || updatingMnodes <= 0) {
+ mInfo("vgId:1, mnode sync not reconfig since readyMnodes:%d updatingMnodes:%d", readyMnodes, updatingMnodes);
+ return;
+ }
+ // ASSERT(0);
+
if (cfg.myIndex == -1) {
- mInfo("vgId:1, mnode not reload since selfIndex is -1");
+#if 1
+ mInfo("vgId:1, mnode sync not reconfig since selfIndex is -1");
+#else
+ // cannot reconfig because the leader may fail to elect after reboot
+ mInfo("vgId:1, mnode sync not reconfig since selfIndex is -1, do sync stop oper");
+ syncStop(pMnode->syncMgmt.sync);
+#endif
return;
}
- if (!mndGetRestored(pMnode)) {
- mInfo("vgId:1, mnode not reload since restore not finished");
- return;
- }
-
- if (hasUpdatingMnode) {
- mInfo("vgId:1, start to reload mnode sync, replica:%d myIndex:%d", cfg.replicaNum, cfg.myIndex);
+ if (updatingMnodes > 0) {
+ mInfo("vgId:1, mnode sync reconfig, replica:%d myIndex:%d", cfg.replicaNum, cfg.myIndex);
for (int32_t i = 0; i < cfg.replicaNum; ++i) {
SNodeInfo *pNode = &cfg.nodeInfo[i];
mInfo("vgId:1, index:%d, fqdn:%s port:%d", i, pNode->nodeFqdn, pNode->nodePort);
diff --git a/source/dnode/mnode/impl/src/mndQuery.c b/source/dnode/mnode/impl/src/mndQuery.c
index 2e01fadbae..3e4c8005b4 100644
--- a/source/dnode/mnode/impl/src/mndQuery.c
+++ b/source/dnode/mnode/impl/src/mndQuery.c
@@ -90,14 +90,39 @@ int32_t mndProcessBatchMetaMsg(SRpcMsg *pMsg) {
}
for (int32_t i = 0; i < msgNum; ++i) {
+ if (offset >= pMsg->contLen) {
+ mError("offset %d is bigger than contLen %d", offset, pMsg->contLen);
+ terrno = TSDB_CODE_MSG_NOT_PROCESSED;
+ taosArrayDestroy(batchRsp);
+ return -1;
+ }
+
req.msgIdx = ntohl(*(int32_t *)((char *)pMsg->pCont + offset));
offset += sizeof(req.msgIdx);
+ if (offset >= pMsg->contLen) {
+ mError("offset %d is bigger than contLen %d", offset, pMsg->contLen);
+ terrno = TSDB_CODE_MSG_NOT_PROCESSED;
+ taosArrayDestroy(batchRsp);
+ return -1;
+ }
req.msgType = ntohl(*(int32_t *)((char *)pMsg->pCont + offset));
offset += sizeof(req.msgType);
+ if (offset >= pMsg->contLen) {
+ mError("offset %d is bigger than contLen %d", offset, pMsg->contLen);
+ terrno = TSDB_CODE_MSG_NOT_PROCESSED;
+ taosArrayDestroy(batchRsp);
+ return -1;
+ }
req.msgLen = ntohl(*(int32_t *)((char *)pMsg->pCont + offset));
offset += sizeof(req.msgLen);
+ if (offset >= pMsg->contLen) {
+ mError("offset %d is bigger than contLen %d", offset, pMsg->contLen);
+ terrno = TSDB_CODE_MSG_NOT_PROCESSED;
+ taosArrayDestroy(batchRsp);
+ return -1;
+ }
req.msg = (char *)pMsg->pCont + offset;
offset += req.msgLen;
diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c
index 10cfb0a660..8a3179b2a9 100644
--- a/source/dnode/mnode/impl/src/mndStb.c
+++ b/source/dnode/mnode/impl/src/mndStb.c
@@ -2553,12 +2553,17 @@ static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
char rollup[160 + VARSTR_HEADER_SIZE] = {0};
int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
+ char *sep = ", ";
+ int32_t sepLen = strlen(sep);
+ int32_t rollupLen = sizeof(rollup) - 2;
for (int32_t i = 0; i < rollupNum; ++i) {
char *funcName = taosArrayGet(pStb->pFuncs, i);
if (i) {
- strcat(varDataVal(rollup), ", ");
+ strncat(varDataVal(rollup), sep, rollupLen);
+ rollupLen -= sepLen;
}
- strcat(varDataVal(rollup), funcName);
+ strncat(varDataVal(rollup), funcName, rollupLen);
+ rollupLen -= strlen(funcName);
}
varDataSetLen(rollup, strlen(varDataVal(rollup)));
diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c
index 866a3fa8b9..ac95dd2795 100644
--- a/source/dnode/mnode/impl/src/mndSync.c
+++ b/source/dnode/mnode/impl/src/mndSync.c
@@ -293,6 +293,14 @@ int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw, int32_t transId) {
if (code == 0) {
tsem_wait(&pMgmt->syncSem);
+ } else if (code > 0) {
+ mInfo("trans:%d, confirm at once since replica is 1, continue execute", transId);
+ taosWLockLatch(&pMgmt->lock);
+ pMgmt->transId = 0;
+ taosWUnLockLatch(&pMgmt->lock);
+ sdbWriteWithoutFree(pMnode->pSdb, pRaw);
+ sdbSetApplyInfo(pMnode->pSdb, req.info.conn.applyIndex, req.info.conn.applyTerm, SYNC_INDEX_INVALID);
+ code = 0;
} else if (code == -1 && terrno == TSDB_CODE_SYN_NOT_LEADER) {
terrno = TSDB_CODE_APP_NOT_READY;
} else if (code == -1 && terrno == TSDB_CODE_SYN_INTERNAL_ERROR) {
diff --git a/source/dnode/mnode/sdb/inc/sdb.h b/source/dnode/mnode/sdb/inc/sdb.h
index be93bd2f59..a2373a55ce 100644
--- a/source/dnode/mnode/sdb/inc/sdb.h
+++ b/source/dnode/mnode/sdb/inc/sdb.h
@@ -403,6 +403,10 @@ const char *sdbStatusName(ESdbStatus status);
void sdbPrintOper(SSdb *pSdb, SSdbRow *pRow, const char *oper);
int32_t sdbGetIdFromRaw(SSdb *pSdb, SSdbRaw *pRaw);
+void sdbWriteLock(SSdb *pSdb, int32_t type);
+void sdbReadLock(SSdb *pSdb, int32_t type);
+void sdbUnLock(SSdb *pSdb, int32_t type);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/dnode/mnode/sdb/src/sdb.c b/source/dnode/mnode/sdb/src/sdb.c
index 5393c42da3..e73fd28e71 100644
--- a/source/dnode/mnode/sdb/src/sdb.c
+++ b/source/dnode/mnode/sdb/src/sdb.c
@@ -181,3 +181,23 @@ void sdbGetCommitInfo(SSdb *pSdb, int64_t *index, int64_t *term, int64_t *config
pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, *index, *term, *config);
#endif
}
+
+void sdbWriteLock(SSdb *pSdb, int32_t type) {
+ TdThreadRwlock *pLock = &pSdb->locks[type];
+ // mTrace("sdb table:%d start write lock:%p", type, pLock);
+ taosThreadRwlockWrlock(pLock);
+ // mTrace("sdb table:%d stop write lock:%p", type, pLock);
+}
+
+void sdbReadLock(SSdb *pSdb, int32_t type) {
+ TdThreadRwlock *pLock = &pSdb->locks[type];
+ // mTrace("sdb table:%d start read lock:%p", type, pLock);
+ taosThreadRwlockRdlock(pLock);
+ // mTrace("sdb table:%d stop read lock:%p", type, pLock);
+}
+
+void sdbUnLock(SSdb *pSdb, int32_t type) {
+ TdThreadRwlock *pLock = &pSdb->locks[type];
+ // mTrace("sdb table:%d unlock:%p", type, pLock);
+ taosThreadRwlockUnlock(pLock);
+}
diff --git a/source/dnode/mnode/sdb/src/sdbFile.c b/source/dnode/mnode/sdb/src/sdbFile.c
index 18dbea150b..5eedcc545a 100644
--- a/source/dnode/mnode/sdb/src/sdbFile.c
+++ b/source/dnode/mnode/sdb/src/sdbFile.c
@@ -363,9 +363,8 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
mInfo("write %s to sdb file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
- SHashObj *hash = pSdb->hashObjs[i];
- TdThreadRwlock *pLock = &pSdb->locks[i];
- taosThreadRwlockWrlock(pLock);
+ SHashObj *hash = pSdb->hashObjs[i];
+ sdbWriteLock(pSdb, i);
SSdbRow **ppRow = taosHashIterate(hash, NULL);
while (ppRow != NULL) {
@@ -410,7 +409,7 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
sdbFreeRaw(pRaw);
ppRow = taosHashIterate(hash, ppRow);
}
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, i);
}
if (code == 0) {
diff --git a/source/dnode/mnode/sdb/src/sdbHash.c b/source/dnode/mnode/sdb/src/sdbHash.c
index 0fee0fbca1..85e937fcc3 100644
--- a/source/dnode/mnode/sdb/src/sdbHash.c
+++ b/source/dnode/mnode/sdb/src/sdbHash.c
@@ -133,12 +133,12 @@ static int32_t sdbGetkeySize(SSdb *pSdb, ESdbType type, const void *pKey) {
}
static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *pRow, int32_t keySize) {
- TdThreadRwlock *pLock = &pSdb->locks[pRow->type];
- taosThreadRwlockWrlock(pLock);
+ int32_t type = pRow->type;
+ sdbWriteLock(pSdb, type);
SSdbRow *pOldRow = taosHashGet(hash, pRow->pObj, keySize);
if (pOldRow != NULL) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
sdbFreeRow(pSdb, pRow, false);
terrno = TSDB_CODE_SDB_OBJ_ALREADY_THERE;
return terrno;
@@ -149,7 +149,7 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
sdbPrintOper(pSdb, pRow, "insert");
if (taosHashPut(hash, pRow->pObj, keySize, &pRow, sizeof(void *)) != 0) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
sdbFreeRow(pSdb, pRow, false);
terrno = TSDB_CODE_OUT_OF_MEMORY;
return terrno;
@@ -164,12 +164,12 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
taosHashRemove(hash, pRow->pObj, keySize);
sdbFreeRow(pSdb, pRow, false);
terrno = code;
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
return terrno;
}
}
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
if (pSdb->keyTypes[pRow->type] == SDB_KEY_INT32) {
pSdb->maxId[pRow->type] = TMAX(pSdb->maxId[pRow->type], *((int32_t *)pRow->pObj));
@@ -183,26 +183,27 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
}
static int32_t sdbUpdateRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *pNewRow, int32_t keySize) {
- TdThreadRwlock *pLock = &pSdb->locks[pNewRow->type];
- taosThreadRwlockWrlock(pLock);
+ int32_t type = pNewRow->type;
+ sdbWriteLock(pSdb, type);
SSdbRow **ppOldRow = taosHashGet(hash, pNewRow->pObj, keySize);
if (ppOldRow == NULL || *ppOldRow == NULL) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
return sdbInsertRow(pSdb, hash, pRaw, pNewRow, keySize);
}
SSdbRow *pOldRow = *ppOldRow;
pOldRow->status = pRaw->status;
sdbPrintOper(pSdb, pOldRow, "update");
+ sdbUnLock(pSdb, type);
int32_t code = 0;
- SdbUpdateFp updateFp = pSdb->updateFps[pNewRow->type];
+ SdbUpdateFp updateFp = pSdb->updateFps[type];
if (updateFp != NULL) {
code = (*updateFp)(pSdb, pOldRow->pObj, pNewRow->pObj);
}
- taosThreadRwlockUnlock(pLock);
+ // sdbUnLock(pSdb, type);
sdbFreeRow(pSdb, pNewRow, false);
pSdb->tableVer[pOldRow->type]++;
@@ -210,12 +211,12 @@ static int32_t sdbUpdateRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
}
static int32_t sdbDeleteRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *pRow, int32_t keySize) {
- TdThreadRwlock *pLock = &pSdb->locks[pRow->type];
- taosThreadRwlockWrlock(pLock);
+ int32_t type = pRow->type;
+ sdbWriteLock(pSdb, type);
SSdbRow **ppOldRow = taosHashGet(hash, pRow->pObj, keySize);
if (ppOldRow == NULL || *ppOldRow == NULL) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
sdbFreeRow(pSdb, pRow, false);
terrno = TSDB_CODE_SDB_OBJ_NOT_THERE;
return terrno;
@@ -228,7 +229,7 @@ static int32_t sdbDeleteRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
taosHashRemove(hash, pOldRow->pObj, keySize);
pSdb->tableVer[pOldRow->type]++;
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
sdbFreeRow(pSdb, pRow, false);
@@ -282,12 +283,11 @@ void *sdbAcquire(SSdb *pSdb, ESdbType type, const void *pKey) {
void *pRet = NULL;
int32_t keySize = sdbGetkeySize(pSdb, type, pKey);
- TdThreadRwlock *pLock = &pSdb->locks[type];
- taosThreadRwlockRdlock(pLock);
+ sdbReadLock(pSdb, type);
SSdbRow **ppRow = taosHashGet(hash, pKey, keySize);
if (ppRow == NULL || *ppRow == NULL) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
terrno = TSDB_CODE_SDB_OBJ_NOT_THERE;
return NULL;
}
@@ -310,13 +310,13 @@ void *sdbAcquire(SSdb *pSdb, ESdbType type, const void *pKey) {
break;
}
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
return pRet;
}
static void sdbCheckRow(SSdb *pSdb, SSdbRow *pRow) {
- TdThreadRwlock *pLock = &pSdb->locks[pRow->type];
- taosThreadRwlockWrlock(pLock);
+ int32_t type = pRow->type;
+ sdbWriteLock(pSdb, type);
int32_t ref = atomic_sub_fetch_32(&pRow->refCount, 1);
sdbPrintOper(pSdb, pRow, "check");
@@ -324,7 +324,7 @@ static void sdbCheckRow(SSdb *pSdb, SSdbRow *pRow) {
sdbFreeRow(pSdb, pRow, true);
}
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
}
void sdbReleaseLock(SSdb *pSdb, void *pObj, bool lock) {
@@ -333,9 +333,9 @@ void sdbReleaseLock(SSdb *pSdb, void *pObj, bool lock) {
SSdbRow *pRow = (SSdbRow *)((char *)pObj - sizeof(SSdbRow));
if (pRow->type >= SDB_MAX) return;
- TdThreadRwlock *pLock = &pSdb->locks[pRow->type];
+ int32_t type = pRow->type;
if (lock) {
- taosThreadRwlockWrlock(pLock);
+ sdbWriteLock(pSdb, type);
}
int32_t ref = atomic_sub_fetch_32(&pRow->refCount, 1);
@@ -345,7 +345,7 @@ void sdbReleaseLock(SSdb *pSdb, void *pObj, bool lock) {
}
if (lock) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
}
}
@@ -357,8 +357,7 @@ void *sdbFetch(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj) {
SHashObj *hash = sdbGetHash(pSdb, type);
if (hash == NULL) return NULL;
- TdThreadRwlock *pLock = &pSdb->locks[type];
- taosThreadRwlockRdlock(pLock);
+ sdbReadLock(pSdb, type);
SSdbRow **ppRow = taosHashIterate(hash, pIter);
while (ppRow != NULL) {
@@ -373,7 +372,7 @@ void *sdbFetch(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj) {
*ppObj = pRow->pObj;
break;
}
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
return ppRow;
}
@@ -384,9 +383,8 @@ void *sdbFetchAll(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj, ESdbStat
SHashObj *hash = sdbGetHash(pSdb, type);
if (hash == NULL) return NULL;
- TdThreadRwlock *pLock = &pSdb->locks[type];
if (lock) {
- taosThreadRwlockRdlock(pLock);
+ sdbReadLock(pSdb, type);
}
SSdbRow **ppRow = taosHashIterate(hash, pIter);
@@ -404,7 +402,7 @@ void *sdbFetchAll(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj, ESdbStat
break;
}
if (lock) {
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
}
return ppRow;
@@ -416,18 +414,17 @@ void sdbCancelFetch(SSdb *pSdb, void *pIter) {
SHashObj *hash = sdbGetHash(pSdb, pRow->type);
if (hash == NULL) return;
- TdThreadRwlock *pLock = &pSdb->locks[pRow->type];
- taosThreadRwlockRdlock(pLock);
+ int32_t type = pRow->type;
+ sdbReadLock(pSdb, type);
taosHashCancelIterate(hash, pIter);
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
}
void sdbTraverse(SSdb *pSdb, ESdbType type, sdbTraverseFp fp, void *p1, void *p2, void *p3) {
SHashObj *hash = sdbGetHash(pSdb, type);
if (hash == NULL) return;
- TdThreadRwlock *pLock = &pSdb->locks[type];
- taosThreadRwlockRdlock(pLock);
+ sdbReadLock(pSdb, type);
SSdbRow **ppRow = taosHashIterate(hash, NULL);
while (ppRow != NULL) {
@@ -443,17 +440,16 @@ void sdbTraverse(SSdb *pSdb, ESdbType type, sdbTraverseFp fp, void *p1, void *p2
ppRow = taosHashIterate(hash, ppRow);
}
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
}
int32_t sdbGetSize(SSdb *pSdb, ESdbType type) {
SHashObj *hash = sdbGetHash(pSdb, type);
if (hash == NULL) return 0;
- TdThreadRwlock *pLock = &pSdb->locks[type];
- taosThreadRwlockRdlock(pLock);
+ sdbReadLock(pSdb, type);
int32_t size = taosHashGetSize(hash);
- taosThreadRwlockUnlock(pLock);
+ sdbUnLock(pSdb, type);
return size;
}
@@ -465,9 +461,7 @@ int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type) {
if (pSdb->keyTypes[type] != SDB_KEY_INT32) return -1;
int32_t maxId = 0;
-
- TdThreadRwlock *pLock = &pSdb->locks[type];
- taosThreadRwlockRdlock(pLock);
+ sdbReadLock(pSdb, type);
SSdbRow **ppRow = taosHashIterate(hash, NULL);
while (ppRow != NULL) {
@@ -477,8 +471,7 @@ int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type) {
ppRow = taosHashIterate(hash, ppRow);
}
- taosThreadRwlockUnlock(pLock);
-
+ sdbUnLock(pSdb, type);
maxId = TMAX(maxId, pSdb->maxId[type]);
return maxId + 1;
}
diff --git a/source/dnode/vnode/src/inc/sma.h b/source/dnode/vnode/src/inc/sma.h
index dade85b12d..50e3c3a9c1 100644
--- a/source/dnode/vnode/src/inc/sma.h
+++ b/source/dnode/vnode/src/inc/sma.h
@@ -258,6 +258,7 @@ enum {
TD_FTYPE_RSMA_QTASKINFO = 0,
};
+#if 0
struct STFile {
uint8_t state;
STFInfo info;
@@ -287,6 +288,7 @@ int32_t tdUpdateTFileHeader(STFile *pTFile);
void tdUpdateTFileMagic(STFile *pTFile, void *pCksm);
void tdCloseTFile(STFile *pTFile);
void tdDestroyTFile(STFile *pTFile);
+#endif
void tdGetVndFileName(int32_t vgId, const char *pdname, const char *dname, const char *fname, int64_t version,
char *outputName);
diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h
index 69e6cdce9f..7f418439a8 100644
--- a/source/dnode/vnode/src/inc/tq.h
+++ b/source/dnode/vnode/src/inc/tq.h
@@ -149,7 +149,7 @@ int32_t tEncodeSTqHandle(SEncoder* pEncoder, const STqHandle* pHandle);
int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle);
// tqRead
-int32_t tqScan(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* offset);
+int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* offset);
int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset);
int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHead** pHeadWithCkSum);
@@ -181,8 +181,8 @@ int32_t tqOffsetDelete(STqOffsetStore* pStore, const char* subscribeKey)
int32_t tqOffsetCommitFile(STqOffsetStore* pStore);
// tqSink
-void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data);
-void tqTableSink1(SStreamTask* pTask, void* vnode, int64_t ver, void* data);
+void tqSinkToTableMerge(SStreamTask* pTask, void* vnode, int64_t ver, void* data);
+void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* data);
// tqOffset
char* tqOffsetBuildFName(const char* path, int32_t ver);
diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c
index 20e0fcdb5b..2d055acd2f 100644
--- a/source/dnode/vnode/src/meta/metaTable.c
+++ b/source/dnode/vnode/src/meta/metaTable.c
@@ -51,7 +51,7 @@ static int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema
return -1;
}
- strncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
+ tstrncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
pMetaRsp->numOfColumns = pSchema->nCols;
pMetaRsp->tableType = TSDB_NORMAL_TABLE;
pMetaRsp->sversion = pSchema->version;
diff --git a/source/dnode/vnode/src/sma/smaCommit.c b/source/dnode/vnode/src/sma/smaCommit.c
index db5f4c55b9..6168a00815 100644
--- a/source/dnode/vnode/src/sma/smaCommit.c
+++ b/source/dnode/vnode/src/sma/smaCommit.c
@@ -17,14 +17,17 @@
extern SSmaMgmt smaMgmt;
+#if 0
static int32_t tdProcessRSmaSyncPreCommitImpl(SSma *pSma);
static int32_t tdProcessRSmaSyncCommitImpl(SSma *pSma);
static int32_t tdProcessRSmaSyncPostCommitImpl(SSma *pSma);
+#endif
static int32_t tdProcessRSmaAsyncPreCommitImpl(SSma *pSma);
static int32_t tdProcessRSmaAsyncCommitImpl(SSma *pSma);
static int32_t tdProcessRSmaAsyncPostCommitImpl(SSma *pSma);
static int32_t tdUpdateQTaskInfoFiles(SSma *pSma, SRSmaStat *pRSmaStat);
+#if 0
/**
* @brief Only applicable to Rollup SMA
*
@@ -48,6 +51,7 @@ int32_t smaSyncCommit(SSma *pSma) { return tdProcessRSmaSyncCommitImpl(pSma); }
* @return int32_t
*/
int32_t smaSyncPostCommit(SSma *pSma) { return tdProcessRSmaSyncPostCommitImpl(pSma); }
+#endif
/**
* @brief Only applicable to Rollup SMA
@@ -108,6 +112,7 @@ int32_t smaBegin(SSma *pSma) {
return TSDB_CODE_SUCCESS;
}
+#if 0
/**
* @brief pre-commit for rollup sma(sync commit).
* 1) set trigger stat of rsma timer TASK_TRIGGER_STAT_PAUSED.
@@ -169,6 +174,7 @@ static int32_t tdProcessRSmaSyncCommitImpl(SSma *pSma) {
#endif
return TSDB_CODE_SUCCESS;
}
+#endif
// SQTaskFile ======================================================
@@ -230,6 +236,7 @@ static int32_t tdUpdateQTaskInfoFiles(SSma *pSma, SRSmaStat *pStat) {
return TSDB_CODE_SUCCESS;
}
+#if 0
/**
* @brief post-commit for rollup sma
* 1) clean up the outdated qtaskinfo files
@@ -249,6 +256,7 @@ static int32_t tdProcessRSmaSyncPostCommitImpl(SSma *pSma) {
return TSDB_CODE_SUCCESS;
}
+#endif
/**
* @brief Rsma async commit implementation(only do some necessary light weighted task)
diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c
index 722a3f479e..77c5955098 100644
--- a/source/dnode/vnode/src/sma/smaRollup.c
+++ b/source/dnode/vnode/src/sma/smaRollup.c
@@ -15,8 +15,6 @@
#include "sma.h"
-#define RSMA_QTASKINFO_BUFSIZE (32768) // size
-#define RSMA_QTASKINFO_HEAD_LEN (sizeof(int32_t) + sizeof(int8_t) + sizeof(int64_t)) // len + type + suid
#define RSMA_QTASKEXEC_SMOOTH_SIZE (100) // cnt
#define RSMA_SUBMIT_BATCH_SIZE (1024) // cnt
#define RSMA_FETCH_DELAY_MAX (120000) // ms
@@ -48,23 +46,10 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SR
static void tdRSmaFetchTrigger(void *param, void *tmrId);
static int32_t tdRSmaInfoClone(SSma *pSma, SRSmaInfo *pInfo);
static void tdRSmaQTaskInfoFree(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level);
-static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskInfoIter *pIter, STFile *pTFile);
-static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isFinish);
-static int32_t tdRSmaQTaskInfoRestore(SSma *pSma, int8_t type, SRSmaQTaskInfoIter *pIter);
-static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem *infoItem);
static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables);
static int32_t tdRSmaRestoreQTaskInfoReload(SSma *pSma, int8_t type, int64_t qTaskFileVer);
static int32_t tdRSmaRestoreTSDataReload(SSma *pSma);
-static SRSmaInfo *tdGetRSmaInfoByItem(SRSmaInfoItem *pItem) {
- // adapt accordingly if definition of SRSmaInfo update
- SRSmaInfo *pResult = NULL;
- ASSERT(pItem->level == TSDB_RETENTION_L1 || pItem->level == TSDB_RETENTION_L2);
- pResult = (SRSmaInfo *)POINTER_SHIFT(pItem, -(sizeof(SRSmaInfoItem) * (pItem->level - 1) + RSMA_INFO_HEAD_LEN));
- ASSERT(pResult->pTSchema->numOfCols > 1);
- return pResult;
-}
-
struct SRSmaQTaskInfoItem {
int32_t len;
int8_t type;
@@ -104,12 +89,6 @@ void tdRSmaQTaskInfoGetFullPathEx(int32_t vgId, tb_uid_t suid, int8_t level, con
snprintf(outputName + rsmaLen, TSDB_FILENAME_LEN - rsmaLen, "%" PRIi64 "%s%" PRIi8, suid, TD_DIRSEP, level);
}
-static FORCE_INLINE int32_t tdRSmaQTaskInfoContLen(int32_t lenWithHead) {
- return lenWithHead - RSMA_QTASKINFO_HEAD_LEN;
-}
-
-static FORCE_INLINE void tdRSmaQTaskInfoIterDestroy(SRSmaQTaskInfoIter *pIter) { taosMemoryFreeClear(pIter->pBuf); }
-
static void tdRSmaQTaskInfoFree(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level) {
// Note: free/kill may in RC
if (!taskHandle || !(*taskHandle)) return;
@@ -803,6 +782,7 @@ static int32_t tdExecuteRSmaImplAsync(SSma *pSma, const void *pMsg, int32_t inpu
return TSDB_CODE_SUCCESS;
}
+#if 0
static int32_t tdRsmaPrintSubmitReq(SSma *pSma, SSubmitReq *pReq) {
SSubmitMsgIter msgIter = {0};
SSubmitBlkIter blkIter = {0};
@@ -820,6 +800,7 @@ static int32_t tdRsmaPrintSubmitReq(SSma *pSma, SSubmitReq *pReq) {
}
return 0;
}
+#endif
/**
* @brief sync mode
@@ -1189,65 +1170,6 @@ _err:
return TSDB_CODE_FAILED;
}
-static int32_t tdRSmaRestoreQTaskInfoReload(SSma *pSma, int8_t type, int64_t qTaskFileVer) {
- SVnode *pVnode = pSma->pVnode;
- STFile tFile = {0};
- char qTaskInfoFName[TSDB_FILENAME_LEN] = {0};
-
- tdRSmaQTaskInfoGetFileName(TD_VID(pVnode), qTaskFileVer, qTaskInfoFName);
- if (tdInitTFile(&tFile, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFName) < 0) {
- goto _err;
- }
-
- if (!taosCheckExistFile(TD_TFILE_FULL_NAME(&tFile))) {
- if (qTaskFileVer > 0) {
- smaWarn("vgId:%d, restore rsma task %" PRIi8 " for version %" PRIi64 ", not start as %s not exist",
- TD_VID(pVnode), type, qTaskFileVer, TD_TFILE_FULL_NAME(&tFile));
- } else {
- smaDebug("vgId:%d, restore rsma task %" PRIi8 " for version %" PRIi64 ", no need as %s not exist", TD_VID(pVnode),
- type, qTaskFileVer, TD_TFILE_FULL_NAME(&tFile));
- }
- return TSDB_CODE_SUCCESS;
- }
-
- if (tdOpenTFile(&tFile, TD_FILE_READ) < 0) {
- goto _err;
- }
-
- STFInfo tFileInfo = {0};
- if (tdLoadTFileHeader(&tFile, &tFileInfo) < 0) {
- goto _err;
- }
-
- SRSmaQTaskInfoIter fIter = {0};
- if (tdRSmaQTaskInfoIterInit(&fIter, &tFile) < 0) {
- tdRSmaQTaskInfoIterDestroy(&fIter);
- tdCloseTFile(&tFile);
- tdDestroyTFile(&tFile);
- goto _err;
- }
-
- if (tdRSmaQTaskInfoRestore(pSma, type, &fIter) < 0) {
- tdRSmaQTaskInfoIterDestroy(&fIter);
- tdCloseTFile(&tFile);
- tdDestroyTFile(&tFile);
- goto _err;
- }
-
- tdRSmaQTaskInfoIterDestroy(&fIter);
- tdCloseTFile(&tFile);
- tdDestroyTFile(&tFile);
-
- // restored successfully from committed or sync
- smaInfo("vgId:%d, restore rsma task %" PRIi8 " for version %" PRIi64 ", qtaskinfo reload succeed", TD_VID(pVnode),
- type, qTaskFileVer);
- return TSDB_CODE_SUCCESS;
-_err:
- smaError("vgId:%d, restore rsma task %" PRIi8 " for version %" PRIi64 ", qtaskinfo reload failed since %s",
- TD_VID(pVnode), type, qTaskFileVer, terrstr());
- return TSDB_CODE_FAILED;
-}
-
/**
* @brief reload ts data from checkpoint
*
@@ -1270,19 +1192,12 @@ int32_t tdRSmaProcessRestoreImpl(SSma *pSma, int8_t type, int64_t qtaskFileVer)
return TSDB_CODE_SUCCESS;
}
-#if 0
- // step 2: retrieve qtaskinfo items from the persistence file(rsma/qtaskinfo) and restore
- if (tdRSmaRestoreQTaskInfoReload(pSma, type, qtaskFileVer) < 0) {
- goto _err;
- }
-#endif
-
- // step 3: reload ts data from checkpoint
+ // step 2: reload ts data from checkpoint
if (tdRSmaRestoreTSDataReload(pSma) < 0) {
goto _err;
}
- // step 4: open SRSmaFS for qTaskFiles
+ // step 3: open SRSmaFS for qTaskFiles
if (tdRSmaFSOpen(pSma, qtaskFileVer) < 0) {
goto _err;
}
@@ -1295,191 +1210,6 @@ _err:
return TSDB_CODE_FAILED;
}
-/**
- * @brief Restore from SRSmaQTaskInfoItem
- *
- * @param pSma
- * @param pItem
- * @return int32_t
- */
-static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem *pItem) {
- SRSmaInfo *pRSmaInfo = NULL;
- void *qTaskInfo = NULL;
-
- pRSmaInfo = tdAcquireRSmaInfoBySuid(pSma, pItem->suid);
- if (!pRSmaInfo) {
- smaDebug("vgId:%d, no restore as no rsma info for table:%" PRIu64, SMA_VID(pSma), pItem->suid);
- return TSDB_CODE_SUCCESS;
- }
-
- if (pItem->type == TSDB_RETENTION_L1) {
- qTaskInfo = RSMA_INFO_QTASK(pRSmaInfo, 0);
- } else if (pItem->type == TSDB_RETENTION_L2) {
- qTaskInfo = RSMA_INFO_QTASK(pRSmaInfo, 1);
- } else {
- ASSERT(0);
- }
-
- if (!qTaskInfo) {
- tdReleaseRSmaInfo(pSma, pRSmaInfo);
- smaDebug("vgId:%d, no restore as NULL rsma qTaskInfo for table:%" PRIu64, SMA_VID(pSma), pItem->suid);
- return TSDB_CODE_SUCCESS;
- }
-
- if (qDeserializeTaskStatus(qTaskInfo, pItem->qTaskInfo, pItem->len) < 0) {
- tdReleaseRSmaInfo(pSma, pRSmaInfo);
- smaError("vgId:%d, restore rsma task failed for table:%" PRIi64 " level %d since %s", SMA_VID(pSma), pItem->suid,
- pItem->type, terrstr());
- return TSDB_CODE_FAILED;
- }
- smaDebug("vgId:%d, restore rsma task success for table:%" PRIi64 " level %d", SMA_VID(pSma), pItem->suid,
- pItem->type);
-
- tdReleaseRSmaInfo(pSma, pRSmaInfo);
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskInfoIter *pIter, STFile *pTFile) {
- memset(pIter, 0, sizeof(*pIter));
- pIter->pTFile = pTFile;
- pIter->offset = TD_FILE_HEAD_SIZE;
-
- if (tdGetTFileSize(pTFile, &pIter->fsize) < 0) {
- return TSDB_CODE_FAILED;
- }
-
- if ((pIter->fsize - TD_FILE_HEAD_SIZE) < RSMA_QTASKINFO_BUFSIZE) {
- pIter->nAlloc = pIter->fsize - TD_FILE_HEAD_SIZE;
- } else {
- pIter->nAlloc = RSMA_QTASKINFO_BUFSIZE;
- }
-
- if (pIter->nAlloc < TD_FILE_HEAD_SIZE) {
- pIter->nAlloc = TD_FILE_HEAD_SIZE;
- }
-
- pIter->pBuf = taosMemoryMalloc(pIter->nAlloc);
- if (!pIter->pBuf) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
- pIter->qBuf = pIter->pBuf;
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isFinish) {
- STFile *pTFile = pIter->pTFile;
- int64_t nBytes = RSMA_QTASKINFO_BUFSIZE;
-
- if (pIter->offset >= pIter->fsize) {
- *isFinish = true;
- return TSDB_CODE_SUCCESS;
- }
-
- if ((pIter->fsize - pIter->offset) < RSMA_QTASKINFO_BUFSIZE) {
- nBytes = pIter->fsize - pIter->offset;
- }
-
- if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET) < 0) {
- return TSDB_CODE_FAILED;
- }
-
- if (tdReadTFile(pTFile, pIter->pBuf, nBytes) != nBytes) {
- return TSDB_CODE_FAILED;
- }
-
- int32_t infoLen = 0;
- taosDecodeFixedI32(pIter->pBuf, &infoLen);
- if (infoLen > nBytes) {
- if (infoLen <= RSMA_QTASKINFO_BUFSIZE) {
- terrno = TSDB_CODE_RSMA_FILE_CORRUPTED;
- smaError("iterate rsma qtaskinfo file %s failed since %s", TD_TFILE_FULL_NAME(pIter->pTFile), terrstr());
- return TSDB_CODE_FAILED;
- }
- if (pIter->nAlloc < infoLen) {
- pIter->nAlloc = infoLen;
- void *pBuf = taosMemoryRealloc(pIter->pBuf, infoLen);
- if (!pBuf) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
- pIter->pBuf = pBuf;
- }
-
- nBytes = infoLen;
-
- if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET) < 0) {
- return TSDB_CODE_FAILED;
- }
-
- if (tdReadTFile(pTFile, pIter->pBuf, nBytes) != nBytes) {
- return TSDB_CODE_FAILED;
- }
- }
-
- pIter->qBuf = pIter->pBuf;
- pIter->offset += nBytes;
- pIter->nBytes = nBytes;
- pIter->nBufPos = 0;
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tdRSmaQTaskInfoRestore(SSma *pSma, int8_t type, SRSmaQTaskInfoIter *pIter) {
- while (1) {
- // block iter
- bool isFinish = false;
- if (tdRSmaQTaskInfoIterNextBlock(pIter, &isFinish) < 0) {
- return TSDB_CODE_FAILED;
- }
- if (isFinish) {
- return TSDB_CODE_SUCCESS;
- }
-
- // consume the block
- int32_t qTaskInfoLenWithHead = 0;
- pIter->qBuf = taosDecodeFixedI32(pIter->qBuf, &qTaskInfoLenWithHead);
- if (qTaskInfoLenWithHead < RSMA_QTASKINFO_HEAD_LEN) {
- terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
- smaError("vgId:%d, restore rsma task %" PRIi8 " from qtaskinfo file %s failed since %s", SMA_VID(pSma), type,
- TD_TFILE_FULL_NAME(pIter->pTFile), terrstr());
- return TSDB_CODE_FAILED;
- }
-
- while (1) {
- if ((pIter->nBufPos + qTaskInfoLenWithHead) <= pIter->nBytes) {
- SRSmaQTaskInfoItem infoItem = {0};
- pIter->qBuf = taosDecodeFixedI8(pIter->qBuf, &infoItem.type);
- pIter->qBuf = taosDecodeFixedI64(pIter->qBuf, &infoItem.suid);
- infoItem.qTaskInfo = pIter->qBuf;
- infoItem.len = tdRSmaQTaskInfoContLen(qTaskInfoLenWithHead);
- // do the restore job
- smaDebug("vgId:%d, restore rsma task %" PRIi8 " from qtaskinfo file %s offset:%" PRIi64 "\n", SMA_VID(pSma),
- type, TD_TFILE_FULL_NAME(pIter->pTFile), pIter->offset - pIter->nBytes + pIter->nBufPos);
- tdRSmaQTaskInfoItemRestore(pSma, &infoItem);
-
- pIter->qBuf = POINTER_SHIFT(pIter->qBuf, infoItem.len);
- pIter->nBufPos += qTaskInfoLenWithHead;
-
- if ((pIter->nBufPos + RSMA_QTASKINFO_HEAD_LEN) >= pIter->nBytes) {
- // prepare and load next block in the file
- pIter->offset -= (pIter->nBytes - pIter->nBufPos);
- break;
- }
-
- pIter->qBuf = taosDecodeFixedI32(pIter->qBuf, &qTaskInfoLenWithHead);
- continue;
- }
- // prepare and load next block in the file
- pIter->offset -= (pIter->nBytes - pIter->nBufPos);
- break;
- }
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
SSma *pSma = pRSmaStat->pSma;
SVnode *pVnode = pSma->pVnode;
@@ -1523,148 +1253,6 @@ _err:
return TSDB_CODE_FAILED;
}
-#if 0
-int32_t tdRSmaPersistExecImpl(SRSmaStat *pRSmaStat, SHashObj *pInfoHash) {
- SSma *pSma = pRSmaStat->pSma;
- SVnode *pVnode = pSma->pVnode;
- int32_t vid = SMA_VID(pSma);
- int64_t toffset = 0;
- bool isFileCreated = false;
-
- if (taosHashGetSize(pInfoHash) <= 0) {
- return TSDB_CODE_SUCCESS;
- }
-
- void *infoHash = taosHashIterate(pInfoHash, NULL);
- if (!infoHash) {
- return TSDB_CODE_SUCCESS;
- }
-
- int64_t fsMaxVer = tdRSmaFSMaxVer(pSma, pRSmaStat);
- if (pRSmaStat->commitAppliedVer <= fsMaxVer) {
- smaDebug("vgId:%d, rsma persist, no need as applied %" PRIi64 " not larger than fsMaxVer %" PRIi64, vid,
- pRSmaStat->commitAppliedVer, fsMaxVer);
- return TSDB_CODE_SUCCESS;
- }
-
- STFile tFile = {0};
-#if 0
- if (pRSmaStat->commitAppliedVer > 0) {
- char qTaskInfoFName[TSDB_FILENAME_LEN];
- tdRSmaQTaskInfoGetFileName(vid, pRSmaStat->commitAppliedVer, qTaskInfoFName);
- if (tdInitTFile(&tFile, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFName) < 0) {
- smaError("vgId:%d, rsma persist, init %s failed since %s", vid, qTaskInfoFName, terrstr());
- goto _err;
- }
- if (tdCreateTFile(&tFile, true, TD_FTYPE_RSMA_QTASKINFO) < 0) {
- smaError("vgId:%d, rsma persist, create %s failed since %s", vid, TD_TFILE_FULL_NAME(&tFile), terrstr());
- goto _err;
- }
- smaDebug("vgId:%d, rsma, serialize qTaskInfo, file %s created", vid, TD_TFILE_FULL_NAME(&tFile));
-
- isFileCreated = true;
- }
-#endif
-
- while (infoHash) {
- SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)infoHash;
-
- if (RSMA_INFO_IS_DEL(pRSmaInfo)) {
- infoHash = taosHashIterate(pInfoHash, infoHash);
- continue;
- }
-
- for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
-#if 0
- qTaskInfo_t taskInfo = RSMA_INFO_IQTASK(pRSmaInfo, i);
-#endif
- qTaskInfo_t taskInfo = RSMA_INFO_QTASK(pRSmaInfo, i);
- if (!taskInfo) {
- smaDebug("vgId:%d, rsma, table %" PRIi64 " level %d qTaskInfo is NULL", vid, pRSmaInfo->suid, i + 1);
- continue;
- }
-
- char *pOutput = NULL;
- int32_t len = 0;
- int8_t type = (int8_t)(i + 1);
- if (qSerializeTaskStatus(taskInfo, &pOutput, &len) < 0) {
- smaError("vgId:%d, rsma, table %" PRIi64 " level %d serialize qTaskInfo failed since %s", vid, pRSmaInfo->suid,
- i + 1, terrstr());
- goto _err;
- }
- if (!pOutput || len <= 0) {
- smaDebug("vgId:%d, rsma, table %" PRIi64
- " level %d serialize qTaskInfo success but no output(len %d), not persist",
- vid, pRSmaInfo->suid, i + 1, len);
- taosMemoryFreeClear(pOutput);
- continue;
- }
-
- smaDebug("vgId:%d, rsma, table %" PRIi64 " level %d serialize qTaskInfo success with len %d, need persist", vid,
- pRSmaInfo->suid, i + 1, len);
-
- if (!isFileCreated) {
- char qTaskInfoFName[TSDB_FILENAME_LEN];
- tdRSmaQTaskInfoGetFileName(vid, pRSmaStat->commitAppliedVer, qTaskInfoFName);
- if (tdInitTFile(&tFile, tfsGetPrimaryPath(pVnode->pTfs), qTaskInfoFName) < 0) {
- smaError("vgId:%d, rsma persist, init %s failed since %s", vid, qTaskInfoFName, terrstr());
- goto _err;
- }
- if (tdCreateTFile(&tFile, true, TD_FTYPE_RSMA_QTASKINFO) < 0) {
- smaError("vgId:%d, rsma persist, create %s failed since %s", vid, TD_TFILE_FULL_NAME(&tFile), terrstr());
- goto _err;
- }
- smaDebug("vgId:%d, rsma, table %" PRIi64 " serialize qTaskInfo, file %s created", vid, pRSmaInfo->suid,
- TD_TFILE_FULL_NAME(&tFile));
-
- isFileCreated = true;
- }
-
- char tmpBuf[RSMA_QTASKINFO_HEAD_LEN] = {0};
- void *pTmpBuf = &tmpBuf;
- int32_t headLen = 0;
- headLen += taosEncodeFixedI32(&pTmpBuf, len + RSMA_QTASKINFO_HEAD_LEN);
- headLen += taosEncodeFixedI8(&pTmpBuf, type);
- headLen += taosEncodeFixedI64(&pTmpBuf, pRSmaInfo->suid);
-
- ASSERT(headLen <= RSMA_QTASKINFO_HEAD_LEN);
- tdAppendTFile(&tFile, (void *)&tmpBuf, headLen, &toffset);
- smaDebug("vgId:%d, rsma, table %" PRIi64 " level %d head part(len:%d) appended to offset:%" PRIi64, vid,
- pRSmaInfo->suid, i + 1, headLen, toffset);
- tdAppendTFile(&tFile, pOutput, len, &toffset);
- smaDebug("vgId:%d, rsma, table %" PRIi64 " level %d body part len:%d appended to offset:%" PRIi64, vid,
- pRSmaInfo->suid, i + 1, len, toffset);
-
- taosMemoryFree(pOutput);
- }
-
- infoHash = taosHashIterate(pInfoHash, infoHash);
- }
-
- if (isFileCreated) {
- if (tdUpdateTFileHeader(&tFile) < 0) {
- smaError("vgId:%d, rsma, failed to update tfile %s header since %s", vid, TD_TFILE_FULL_NAME(&tFile),
- tstrerror(terrno));
- goto _err;
- } else {
- smaDebug("vgId:%d, rsma, succeed to update tfile %s header", vid, TD_TFILE_FULL_NAME(&tFile));
- }
-
- tdCloseTFile(&tFile);
- tdDestroyTFile(&tFile);
- }
- return TSDB_CODE_SUCCESS;
-_err:
- smaError("vgId:%d, rsma persist failed since %s", vid, terrstr());
- if (isFileCreated) {
- tdRemoveTFile(&tFile);
- tdDestroyTFile(&tFile);
- }
- return TSDB_CODE_FAILED;
-}
-
-#endif
-
/**
* @brief trigger to get rsma result in async mode
*
diff --git a/source/dnode/vnode/src/sma/smaUtil.c b/source/dnode/vnode/src/sma/smaUtil.c
index 6d7b7df1ee..4d09d690d6 100644
--- a/source/dnode/vnode/src/sma/smaUtil.c
+++ b/source/dnode/vnode/src/sma/smaUtil.c
@@ -16,7 +16,7 @@
#include "sma.h"
// smaFileUtil ================
-
+#if 0
#define TD_FILE_STATE_OK 0
#define TD_FILE_STATE_BAD 1
@@ -182,6 +182,8 @@ void tdCloseTFile(STFile *pTFile) {
void tdDestroyTFile(STFile *pTFile) { taosMemoryFreeClear(TD_TFILE_FULL_NAME(pTFile)); }
+#endif
+
void tdGetVndFileName(int32_t vgId, const char *pdname, const char *dname, const char *fname, int64_t version,
char *outputName) {
if (version < 0) {
@@ -221,6 +223,7 @@ void tdGetVndDirName(int32_t vgId, const char *pdname, const char *dname, bool e
}
}
+#if 0
int32_t tdInitTFile(STFile *pTFile, const char *dname, const char *fname) {
TD_TFILE_SET_STATE(pTFile, TD_FILE_STATE_OK);
TD_TFILE_SET_CLOSED(pTFile);
@@ -286,6 +289,8 @@ int32_t tdRemoveTFile(STFile *pTFile) {
return 0;
}
+#endif
+
// smaXXXUtil ================
void *tdAcquireSmaRef(int32_t rsetId, int64_t refId) {
void *pResult = taosAcquireRef(rsetId, refId);
diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c
index 5e1cc15063..6d71496008 100644
--- a/source/dnode/vnode/src/tq/tq.c
+++ b/source/dnode/vnode/src/tq/tq.c
@@ -595,7 +595,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
tqInitTaosxRsp(&taosxRsp, pReq);
if (fetchOffsetNew.type != TMQ_OFFSET__LOG) {
- tqScan(pTq, pHandle, &taosxRsp, &metaRsp, &fetchOffsetNew);
+ tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, &fetchOffsetNew);
if (metaRsp.metaRspLen > 0) {
if (tqSendMetaPollRsp(pTq, pMsg, pReq, &metaRsp) < 0) {
@@ -924,7 +924,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask) {
pTask->smaSink.smaSink = smaHandleRes;
} else if (pTask->outputType == TASK_OUTPUT__TABLE) {
pTask->tbSink.vnode = pTq->pVnode;
- pTask->tbSink.tbSinkFunc = tqTableSink1;
+ pTask->tbSink.tbSinkFunc = tqSinkToTablePipeline;
ASSERT(pTask->tbSink.pSchemaWrapper);
ASSERT(pTask->tbSink.pSchemaWrapper->pSchema);
diff --git a/source/dnode/vnode/src/tq/tqExec.c b/source/dnode/vnode/src/tq/tqExec.c
index 58d051bec1..305ee82982 100644
--- a/source/dnode/vnode/src/tq/tqExec.c
+++ b/source/dnode/vnode/src/tq/tqExec.c
@@ -123,7 +123,7 @@ int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffs
return 0;
}
-int32_t tqScan(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* pOffset) {
+int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* pOffset) {
const STqExecHandle* pExec = &pHandle->execHandle;
qTaskInfo_t task = pExec->task;
diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c
index ab195b1eb3..79d7e27642 100644
--- a/source/dnode/vnode/src/tq/tqSink.c
+++ b/source/dnode/vnode/src/tq/tqSink.c
@@ -284,7 +284,7 @@ SSubmitReq* tqBlockToSubmit(SVnode* pVnode, const SArray* pBlocks, const STSchem
return ret;
}
-void tqTableSink1(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
+void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
const SArray* pBlocks = (const SArray*)data;
SVnode* pVnode = (SVnode*)vnode;
int64_t suid = pTask->tbSink.stbUid;
@@ -528,7 +528,7 @@ void tqTableSink1(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
taosArrayDestroy(tagArray);
}
-void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
+void tqSinkToTableMerge(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
const SArray* pRes = (const SArray*)data;
SVnode* pVnode = (SVnode*)vnode;
SBatchDeleteReq deleteReq = {0};
diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c
index 8c1f858cbb..64df3aa1eb 100644
--- a/source/dnode/vnode/src/vnd/vnodeQuery.c
+++ b/source/dnode/vnode/src/vnd/vnodeQuery.c
@@ -330,6 +330,11 @@ int32_t vnodeGetBatchMeta(SVnode *pVnode, SRpcMsg *pMsg) {
rspSize += sizeof(int32_t);
offset = 0;
+ if (rspSize > MAX_META_BATCH_RSP_SIZE) {
+ code = TSDB_CODE_INVALID_MSG_LEN;
+ goto _exit;
+ }
+
pRsp = rpcMallocCont(rspSize);
if (pRsp == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c
index b960103d94..218a86ed5c 100644
--- a/source/libs/catalog/src/catalog.c
+++ b/source/libs/catalog/src/catalog.c
@@ -302,9 +302,11 @@ int32_t ctgUpdateTbMeta(SCatalog* pCtg, STableMetaRsp* rspMsg, bool syncOp) {
_return:
- taosMemoryFreeClear(output->tbMeta);
- taosMemoryFreeClear(output);
-
+ if (output) {
+ taosMemoryFreeClear(output->tbMeta);
+ taosMemoryFreeClear(output);
+ }
+
CTG_RET(code);
}
diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c
index 1d2e3640a1..93d36bc4b3 100644
--- a/source/libs/catalog/src/ctgAsync.c
+++ b/source/libs/catalog/src/ctgAsync.c
@@ -252,7 +252,7 @@ int32_t ctgInitGetIndexTask(SCtgJob* pJob, int32_t taskIdx, void* param) {
SCtgIndexCtx* ctx = task.taskCtx;
- strcpy(ctx->indexFName, name);
+ tstrncpy(ctx->indexFName, name, sizeof(ctx->indexFName));
taosArrayPush(pJob->pTasks, &task);
@@ -277,7 +277,7 @@ int32_t ctgInitGetUdfTask(SCtgJob* pJob, int32_t taskIdx, void* param) {
SCtgUdfCtx* ctx = task.taskCtx;
- strcpy(ctx->udfName, name);
+ tstrncpy(ctx->udfName, name, sizeof(ctx->udfName));
taosArrayPush(pJob->pTasks, &task);
diff --git a/source/libs/catalog/src/ctgCache.c b/source/libs/catalog/src/ctgCache.c
index b3588898e4..1a7a0057ba 100644
--- a/source/libs/catalog/src/ctgCache.c
+++ b/source/libs/catalog/src/ctgCache.c
@@ -660,7 +660,7 @@ int32_t ctgDropDbCacheEnqueue(SCatalog *pCtg, const char *dbFName, int64_t dbId)
}
msg->pCtg = pCtg;
- strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
+ tstrncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
msg->dbId = dbId;
op->data = msg;
@@ -693,7 +693,7 @@ int32_t ctgDropDbVgroupEnqueue(SCatalog *pCtg, const char *dbFName, bool syncOp)
}
msg->pCtg = pCtg;
- strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
+ tstrncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
op->data = msg;
@@ -721,8 +721,8 @@ int32_t ctgDropStbMetaEnqueue(SCatalog *pCtg, const char *dbFName, int64_t dbId,
}
msg->pCtg = pCtg;
- strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
- strncpy(msg->stbName, stbName, sizeof(msg->stbName));
+ tstrncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
+ tstrncpy(msg->stbName, stbName, sizeof(msg->stbName));
msg->dbId = dbId;
msg->suid = suid;
@@ -751,8 +751,8 @@ int32_t ctgDropTbMetaEnqueue(SCatalog *pCtg, const char *dbFName, int64_t dbId,
}
msg->pCtg = pCtg;
- strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
- strncpy(msg->tbName, tbName, sizeof(msg->tbName));
+ tstrncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
+ tstrncpy(msg->tbName, tbName, sizeof(msg->tbName));
msg->dbId = dbId;
op->data = msg;
@@ -785,7 +785,7 @@ int32_t ctgUpdateVgroupEnqueue(SCatalog *pCtg, const char *dbFName, int64_t dbId
dbFName = p + 1;
}
- strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
+ tstrncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
msg->pCtg = pCtg;
msg->dbId = dbId;
msg->dbInfo = dbInfo;
@@ -817,7 +817,8 @@ int32_t ctgUpdateTbMetaEnqueue(SCatalog *pCtg, STableMetaOutput *output, bool sy
char *p = strchr(output->dbFName, '.');
if (p && IS_SYS_DBNAME(p + 1)) {
- memmove(output->dbFName, p + 1, strlen(p + 1));
+ int32_t len = strlen(p + 1);
+ memmove(output->dbFName, p + 1, len >= TSDB_DB_FNAME_LEN ? TSDB_DB_FNAME_LEN - 1 : len);
}
msg->pCtg = pCtg;
@@ -852,7 +853,7 @@ int32_t ctgUpdateVgEpsetEnqueue(SCatalog *pCtg, char *dbFName, int32_t vgId, SEp
}
msg->pCtg = pCtg;
- strcpy(msg->dbFName, dbFName);
+ tstrncpy(msg->dbFName, dbFName, sizeof(msg->dbFName));
msg->vgId = vgId;
msg->epSet = *pEpSet;
@@ -1215,7 +1216,7 @@ int32_t ctgAddNewDBCache(SCatalog *pCtg, const char *dbFName, uint64_t dbId) {
CTG_CACHE_STAT_INC(numOfDb, 1);
SDbVgVersion vgVersion = {.dbId = newDBCache.dbId, .vgVersion = -1};
- strncpy(vgVersion.dbFName, dbFName, sizeof(vgVersion.dbFName));
+ tstrncpy(vgVersion.dbFName, dbFName, sizeof(vgVersion.dbFName));
ctgDebug("db added to cache, dbFName:%s, dbId:0x%" PRIx64, dbFName, dbId);
@@ -1331,8 +1332,8 @@ int32_t ctgUpdateRentStbVersion(SCatalog *pCtg, char *dbFName, char *tbName, uin
metaRent.smaVer = pCache->pIndex->version;
}
- strcpy(metaRent.dbFName, dbFName);
- strcpy(metaRent.stbName, tbName);
+ tstrncpy(metaRent.dbFName, dbFName, sizeof(metaRent.dbFName));
+ tstrncpy(metaRent.stbName, tbName, sizeof(metaRent.stbName));
CTG_ERR_RET(ctgMetaRentUpdate(&pCtg->stbRent, &metaRent, metaRent.suid, sizeof(SSTableVersion),
ctgStbVersionSortCompare, ctgStbVersionSearchCompare));
@@ -1418,8 +1419,10 @@ int32_t ctgWriteTbMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFNam
ctgDebug("stb 0x%" PRIx64 " updated to cache, dbFName:%s, tbName:%s, tbType:%d", meta->suid, dbFName, tbName,
meta->tableType);
- CTG_ERR_RET(ctgUpdateRentStbVersion(pCtg, dbFName, tbName, dbId, meta->suid, pCache));
-
+ if (pCache) {
+ CTG_ERR_RET(ctgUpdateRentStbVersion(pCtg, dbFName, tbName, dbId, meta->suid, pCache));
+ }
+
return TSDB_CODE_SUCCESS;
}
@@ -1590,7 +1593,7 @@ int32_t ctgOpUpdateVgroup(SCtgCacheOperation *operation) {
dbCache = NULL;
- strncpy(vgVersion.dbFName, dbFName, sizeof(vgVersion.dbFName));
+ tstrncpy(vgVersion.dbFName, dbFName, sizeof(vgVersion.dbFName));
CTG_ERR_JRET(ctgMetaRentUpdate(&msg->pCtg->dbRent, &vgVersion, vgVersion.dbId, sizeof(SDbVgVersion),
ctgDbVgVersionSortCompare, ctgDbVgVersionSearchCompare));
@@ -1680,9 +1683,9 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
if (CTG_IS_META_TABLE(pMeta->metaType) || CTG_IS_META_BOTH(pMeta->metaType)) {
int32_t metaSize = CTG_META_SIZE(pMeta->tbMeta);
- CTG_ERR_JRET(
- ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->tbName, pMeta->tbMeta, metaSize));
+ code = ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->tbName, pMeta->tbMeta, metaSize);
pMeta->tbMeta = NULL;
+ CTG_ERR_JRET(code);
}
if (CTG_IS_META_CTABLE(pMeta->metaType) || CTG_IS_META_BOTH(pMeta->metaType)) {
@@ -1697,10 +1700,8 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
_return:
- if (pMeta) {
- taosMemoryFreeClear(pMeta->tbMeta);
- taosMemoryFreeClear(pMeta);
- }
+ taosMemoryFreeClear(pMeta->tbMeta);
+ taosMemoryFreeClear(pMeta);
taosMemoryFreeClear(msg);
diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c
index 33e5b0e1e4..095d2b093d 100644
--- a/source/libs/command/src/command.c
+++ b/source/libs/command/src/command.c
@@ -361,7 +361,12 @@ int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) {
SArray* pTagVals = NULL;
STag* pTag = (STag*)pCfg->pTags;
- if (pCfg->pTags && tTagIsJson(pTag)) {
+ if (NULL == pCfg->pTags || pCfg->numOfTags <= 0) {
+ qError("tag missed in table cfg, pointer:%p, numOfTags:%d", pCfg->pTags, pCfg->numOfTags);
+ return TSDB_CODE_APP_ERROR;
+ }
+
+ if (tTagIsJson(pTag)) {
char* pJson = parseTagDatatoJson(pTag);
if (pJson) {
*len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s", pJson);
diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h
index fc996a6003..47450328be 100644
--- a/source/libs/executor/inc/executorimpl.h
+++ b/source/libs/executor/inc/executorimpl.h
@@ -53,6 +53,11 @@ typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int
#define NEEDTO_COMPRESS_QUERY(size) ((size) > tsCompressColData ? 1 : 0)
+#define IS_VALID_SESSION_WIN(winInfo) ((winInfo).sessionWin.win.skey > 0)
+#define SET_SESSION_WIN_INVALID(winInfo) ((winInfo).sessionWin.win.skey = INT64_MIN)
+#define IS_INVALID_SESSION_WIN_KEY(winKey) ((winKey).win.skey <= 0)
+#define SET_SESSION_WIN_KEY_INVALID(pWinKey) ((pWinKey)->win.skey = INT64_MIN)
+
enum {
// when this task starts to execute, this status will set
TASK_NOT_COMPLETED = 0x1u,
@@ -434,15 +439,15 @@ typedef struct SCatchSupporter {
} SCatchSupporter;
typedef struct SStreamAggSupporter {
- SHashObj* pResultRows;
- SArray* pCurWins;
- int32_t valueSize;
- int32_t keySize;
- char* pKeyBuf; // window key buffer
- SDiskbasedBuf* pResultBuf; // query result buffer based on blocked-wised disk file
- int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row
- int32_t currentPageId; // buffer page that is active
- SSDataBlock* pScanBlock;
+ int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row
+ SSDataBlock* pScanBlock;
+ SStreamState* pState;
+ int64_t gap; // stream session window gap
+ SqlFunctionCtx* pDummyCtx; // for combine
+ SSHashObj* pResultRows;
+ int32_t stateKeySize;
+ int16_t stateKeyType;
+ SDiskbasedBuf* pResultBuf;
} SStreamAggSupporter;
typedef struct SWindowSupporter {
@@ -736,42 +741,54 @@ typedef struct SSessionAggOperatorInfo {
} SSessionAggOperatorInfo;
typedef struct SResultWindowInfo {
- SResultRowPosition pos;
- STimeWindow win;
- uint64_t groupId;
+ void* pOutputBuf;
+ SSessionKey sessionWin;
bool isOutput;
- bool isClosed;
} SResultWindowInfo;
typedef struct SStateWindowInfo {
SResultWindowInfo winInfo;
- SStateKeys stateKey;
+ SStateKeys* pStateKey;
} SStateWindowInfo;
typedef struct SStreamSessionAggOperatorInfo {
SOptrBasicInfo binfo;
SStreamAggSupporter streamAggSup;
- SExprSupp scalarSupp; // supporter for perform scalar function
+ SExprSupp scalarSupp; // supporter for perform scalar function
SGroupResInfo groupResInfo;
- int64_t gap; // session window gap
int32_t primaryTsIndex; // primary timestamp slot id
int32_t endTsIndex; // window end timestamp slot id
int32_t order; // current SSDataBlock scan order
STimeWindowAggSupp twAggSup;
- SSDataBlock* pWinBlock; // window result
- SqlFunctionCtx* pDummyCtx; // for combine
- SSDataBlock* pDelRes; // delete result
- SSDataBlock* pUpdateRes; // update window
+ SSDataBlock* pWinBlock; // window result
+ SSDataBlock* pDelRes; // delete result
+ SSDataBlock* pUpdateRes; // update window
bool returnUpdate;
- SHashObj* pStDeleted;
+ SSHashObj* pStDeleted;
void* pDelIterator;
- SArray* pChildren; // cache for children's result; final stream operator
- SPhysiNode* pPhyNode; // create new child
+ SArray* pChildren; // cache for children's result; final stream operator
+ SPhysiNode* pPhyNode; // create new child
bool isFinal;
bool ignoreExpiredData;
SHashObj* pGroupIdTbNameMap;
} SStreamSessionAggOperatorInfo;
+typedef struct SStreamStateAggOperatorInfo {
+ SOptrBasicInfo binfo;
+ SStreamAggSupporter streamAggSup;
+ SExprSupp scalarSupp; // supporter for perform scalar function
+ SGroupResInfo groupResInfo;
+ int32_t primaryTsIndex; // primary timestamp slot id
+ STimeWindowAggSupp twAggSup;
+ SColumn stateCol;
+ SSDataBlock* pDelRes;
+ SSHashObj* pSeDeleted;
+ void* pDelIterator;
+ SArray* pChildren; // cache for children's result;
+ bool ignoreExpiredData;
+ SHashObj* pGroupIdTbNameMap;
+} SStreamStateAggOperatorInfo;
+
typedef struct SStreamPartitionOperatorInfo {
SOptrBasicInfo binfo;
SPartitionBySupporter partitionSup;
@@ -834,24 +851,6 @@ typedef struct SStateWindowOperatorInfo {
const SNode* pCondition;
} SStateWindowOperatorInfo;
-typedef struct SStreamStateAggOperatorInfo {
- SOptrBasicInfo binfo;
- SStreamAggSupporter streamAggSup;
- SExprSupp scalarSupp; // supporter for perform scalar function
- SGroupResInfo groupResInfo;
- int32_t primaryTsIndex; // primary timestamp slot id
- int32_t order; // current SSDataBlock scan order
- STimeWindowAggSupp twAggSup;
- SColumn stateCol;
- SqlFunctionCtx* pDummyCtx; // for combine
- SSDataBlock* pDelRes;
- SHashObj* pSeDeleted;
- void* pDelIterator;
- SArray* pChildren; // cache for children's result;
- bool ignoreExpiredData;
- SHashObj* pGroupIdTbNameMap;
-} SStreamStateAggOperatorInfo;
-
typedef struct SSortOperatorInfo {
SOptrBasicInfo binfo;
uint32_t sortBufSize; // max buffer size for in-memory sort
@@ -1064,13 +1063,8 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, TSKEY ekey,
__block_search_fn_t searchFn, STableQueryInfo* item, int32_t order);
int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
-int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlFunctionCtx* pCtx, int32_t numOfOutput,
- int32_t size);
SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int32_t* currentPageId, int32_t interBufSize);
-SResultWindowInfo* getSessionTimeWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId,
- int64_t gap, int32_t* pIndex);
-SResultWindowInfo* getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId,
- int64_t gap, int32_t* pIndex);
+void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, SSessionKey* pKey);
bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap);
bool functionNeedToExecute(SqlFunctionCtx* pCtx);
bool isOverdue(TSKEY ts, STimeWindowAggSupp* pSup);
@@ -1100,6 +1094,9 @@ int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle,
void* destroySqlFunctionCtx(SqlFunctionCtx* pCtx, int32_t numOfOutput);
int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, SStreamState* pState, SSDataBlock* pBlock, SExprSupp* pSup,
SGroupResInfo* pGroupResInfo);
+int32_t saveSessionDiscBuf(SStreamState* pState, SSessionKey* key, void* buf, int32_t size);
+int32_t buildSessionResultDataBlock(SExecTaskInfo* pTaskInfo, SStreamState* pState, SSDataBlock* pBlock,
+ SExprSupp* pSup, SGroupResInfo* pGroupResInfo);
int32_t setOutputBuf(SStreamState* pState, STimeWindow* win, SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx,
int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup);
int32_t releaseOutputBuf(SStreamState* pState, SWinKey* pKey, SResultRow* pResult);
diff --git a/source/libs/executor/src/dataDispatcher.c b/source/libs/executor/src/dataDispatcher.c
index 0b5c8372f1..ffdcf48d48 100644
--- a/source/libs/executor/src/dataDispatcher.c
+++ b/source/libs/executor/src/dataDispatcher.c
@@ -143,9 +143,15 @@ static int32_t getStatus(SDataDispatchHandle* pDispatcher) {
static int32_t putDataBlock(SDataSinkHandle* pHandle, const SInputData* pInput, bool* pContinue) {
SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle;
SDataDispatchBuf* pBuf = taosAllocateQitem(sizeof(SDataDispatchBuf), DEF_QITEM);
- if (NULL == pBuf || !allocBuf(pDispatcher, pInput, pBuf)) {
+ if (NULL == pBuf) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
+
+ if (!allocBuf(pDispatcher, pInput, pBuf)) {
+ taosFreeQitem(pBuf);
+ return TSDB_CODE_QRY_OUT_OF_MEMORY;
+ }
+
toDataCacheEntry(pDispatcher, pInput, pBuf);
taosWriteQitem(pDispatcher->pDataBlocks, pBuf);
*pContinue = (DS_BUF_LOW == updateStatus(pDispatcher) ? true : false);
diff --git a/source/libs/executor/src/dataInserter.c b/source/libs/executor/src/dataInserter.c
index 4c4ba59fa9..ed455e5e75 100644
--- a/source/libs/executor/src/dataInserter.c
+++ b/source/libs/executor/src/dataInserter.c
@@ -323,7 +323,7 @@ int32_t createDataInserter(SDataSinkManager* pManager, const SDataSinkNode* pDat
int32_t code =
tsdbGetTableSchema(inserter->pParam->readHandle->vnode, pInserterNode->tableId, &inserter->pSchema, &suid);
if (code) {
- destroyDataSinker((SDataSinkHandle*)pInserterNode);
+ destroyDataSinker((SDataSinkHandle*)inserter);
return code;
}
diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c
index a7e98527f4..641bcb0c5b 100644
--- a/source/libs/executor/src/executorimpl.c
+++ b/source/libs/executor/src/executorimpl.c
@@ -4192,42 +4192,6 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SArray* pExecInf
return TSDB_CODE_SUCCESS;
}
-int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlFunctionCtx* pCtx, int32_t numOfOutput,
- int32_t size) {
- pSup->currentPageId = -1;
- pSup->resultRowSize = getResultRowSize(pCtx, numOfOutput);
- pSup->keySize = sizeof(int64_t) + sizeof(TSKEY);
- pSup->pKeyBuf = taosMemoryCalloc(1, pSup->keySize);
- _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
- pSup->pResultRows = taosHashInit(1024, hashFn, false, HASH_NO_LOCK);
- if (pSup->pKeyBuf == NULL || pSup->pResultRows == NULL) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
- pSup->valueSize = size;
-
- pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR);
- int32_t pageSize = 4096;
- while (pageSize < pSup->resultRowSize * 4) {
- pageSize <<= 1u;
- }
- // at least four pages need to be in buffer
- int32_t bufSize = 4096 * 256;
- if (bufSize <= pageSize) {
- bufSize = pageSize * 4;
- }
- if (!osTempSpaceAvailable()) {
- terrno = TSDB_CODE_NO_AVAIL_DISK;
- qError("Init stream agg supporter failed since %s", terrstr(terrno));
- return terrno;
- }
- int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, pKey, tsTempDir);
- for (int32_t i = 0; i < numOfOutput; ++i) {
- pCtx[i].saveHandle.pBuf = pSup->pResultBuf;
- }
-
- return code;
-}
-
int32_t setOutputBuf(SStreamState* pState, STimeWindow* win, SResultRow** pResult, int64_t tableGroupId,
SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup) {
SWinKey key = {
@@ -4237,7 +4201,6 @@ int32_t setOutputBuf(SStreamState* pState, STimeWindow* win, SResultRow** pResul
char* value = NULL;
int32_t size = pAggSup->resultRowSize;
- tSimpleHashPut(pAggSup->pResultRowHashTable, &key, sizeof(SWinKey), NULL, 0);
if (streamStateAddIfNotExist(pState, &key, (void**)&value, &size) < 0) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
@@ -4342,3 +4305,82 @@ int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, SStreamState* pStat
blockDataUpdateTsWindow(pBlock, 0);
return TSDB_CODE_SUCCESS;
}
+
+int32_t saveSessionDiscBuf(SStreamState* pState, SSessionKey* key, void* buf, int32_t size) {
+ streamStateSessionPut(pState, key, (const void*)buf, size);
+ releaseOutputBuf(pState, NULL, (SResultRow*)buf);
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t buildSessionResultDataBlock(SExecTaskInfo* pTaskInfo, SStreamState* pState, SSDataBlock* pBlock,
+ SExprSupp* pSup, SGroupResInfo* pGroupResInfo) {
+ SExprInfo* pExprInfo = pSup->pExprInfo;
+ int32_t numOfExprs = pSup->numOfExprs;
+ int32_t* rowEntryOffset = pSup->rowEntryInfoOffset;
+ SqlFunctionCtx* pCtx = pSup->pCtx;
+
+ int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
+
+ for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) {
+ SSessionKey* pKey = taosArrayGet(pGroupResInfo->pRows, i);
+ int32_t size = 0;
+ void* pVal = NULL;
+ int32_t code = streamStateSessionGet(pState, pKey, &pVal, &size);
+ ASSERT(code == 0);
+ SResultRow* pRow = (SResultRow*)pVal;
+ doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset);
+ // no results, continue to check the next one
+ if (pRow->numOfRows == 0) {
+ pGroupResInfo->index += 1;
+ releaseOutputBuf(pState, NULL, pRow);
+ continue;
+ }
+
+ if (pBlock->info.groupId == 0) {
+ pBlock->info.groupId = pKey->groupId;
+ } else {
+ // current value belongs to different group, it can't be packed into one datablock
+ if (pBlock->info.groupId != pKey->groupId) {
+ releaseOutputBuf(pState, NULL, pRow);
+ break;
+ }
+ }
+
+ if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
+ ASSERT(pBlock->info.rows > 0);
+ releaseOutputBuf(pState, NULL, pRow);
+ break;
+ }
+
+ pGroupResInfo->index += 1;
+
+ for (int32_t j = 0; j < numOfExprs; ++j) {
+ int32_t slotId = pExprInfo[j].base.resSchema.slotId;
+
+ pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset);
+ if (pCtx[j].fpSet.finalize) {
+ int32_t code1 = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
+ if (TAOS_FAILED(code1)) {
+ qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code1));
+ T_LONG_JMP(pTaskInfo->env, code1);
+ }
+ } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
+ // do nothing, todo refactor
+ } else {
+ // expand the result into multiple rows. E.g., _wstart, top(k, 20)
+ // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
+ SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
+ char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
+ for (int32_t k = 0; k < pRow->numOfRows; ++k) {
+ colDataAppend(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes);
+ }
+ }
+ }
+
+ pBlock->info.rows += pRow->numOfRows;
+ // saveSessionDiscBuf(pState, pKey, pVal, size);
+ releaseOutputBuf(pState, NULL, pRow);
+ }
+ blockDataUpdateTsWindow(pBlock, 0);
+ return TSDB_CODE_SUCCESS;
+}
\ No newline at end of file
diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c
index 8e1858d8c0..7385e9bb92 100644
--- a/source/libs/executor/src/scanoperator.c
+++ b/source/libs/executor/src/scanoperator.c
@@ -1190,23 +1190,22 @@ static int32_t generateSessionScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSr
SColumnInfoData* pDestGpCol = taosArrayGet(pDestBlock->pDataBlock, GROUPID_COLUMN_INDEX);
SColumnInfoData* pDestCalStartTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
SColumnInfoData* pDestCalEndTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
- int32_t dummy = 0;
int64_t version = pSrcBlock->info.version - 1;
for (int32_t i = 0; i < pSrcBlock->info.rows; i++) {
uint64_t groupId = getGroupIdByData(pInfo, uidCol[i], startData[i], version);
// gap must be 0.
- SResultWindowInfo* pStartWin =
- getCurSessionWindow(pInfo->windowSup.pStreamAggSup, startData[i], endData[i], groupId, 0, &dummy);
- if (!pStartWin) {
+ SSessionKey startWin = {0};
+ getCurSessionWindow(pInfo->windowSup.pStreamAggSup, startData[i], endData[i], groupId, &startWin);
+ if (IS_INVALID_SESSION_WIN_KEY(startWin)) {
// window has been closed.
continue;
}
- SResultWindowInfo* pEndWin =
- getCurSessionWindow(pInfo->windowSup.pStreamAggSup, endData[i], endData[i], groupId, 0, &dummy);
- ASSERT(pEndWin);
- TSKEY ts = INT64_MIN;
- colDataAppend(pDestStartCol, i, (const char*)&pStartWin->win.skey, false);
- colDataAppend(pDestEndCol, i, (const char*)&pEndWin->win.ekey, false);
+ SSessionKey endWin = {0};
+ getCurSessionWindow(pInfo->windowSup.pStreamAggSup, endData[i], endData[i], groupId, &endWin);
+ ASSERT(!IS_INVALID_SESSION_WIN_KEY(endWin));
+ colDataAppend(pDestStartCol, i, (const char*)&startWin.win.skey, false);
+ colDataAppend(pDestEndCol, i, (const char*)&endWin.win.ekey, false);
+
colDataAppendNULL(pDestUidCol, i);
colDataAppend(pDestGpCol, i, (const char*)&groupId, false);
colDataAppendNULL(pDestCalStartTsCol, i);
diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c
index 8b716531e5..e199cf8406 100644
--- a/source/libs/executor/src/tfill.c
+++ b/source/libs/executor/src/tfill.c
@@ -693,7 +693,7 @@ void* destroyStreamFillSupporter(SStreamFillSupporter* pFillSup) {
pFillSup->pAllColInfo = destroyFillColumnInfo(pFillSup->pAllColInfo, pFillSup->numOfFillCols, pFillSup->numOfAllCols);
tSimpleHashCleanup(pFillSup->pResMap);
pFillSup->pResMap = NULL;
- streamStateReleaseBuf(NULL, NULL, pFillSup->cur.pRowVal);
+ releaseOutputBuf(NULL, NULL, (SResultRow*)pFillSup->cur.pRowVal);
pFillSup->cur.pRowVal = NULL;
taosMemoryFree(pFillSup);
@@ -736,7 +736,7 @@ static void resetFillWindow(SResultRowData* pRowData) {
void resetPrevAndNextWindow(SStreamFillSupporter* pFillSup, SStreamState* pState) {
resetFillWindow(&pFillSup->prev);
- streamStateReleaseBuf(NULL, NULL, pFillSup->cur.pRowVal);
+ releaseOutputBuf(NULL, NULL, (SResultRow*)pFillSup->cur.pRowVal);
resetFillWindow(&pFillSup->cur);
resetFillWindow(&pFillSup->next);
resetFillWindow(&pFillSup->nextNext);
diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c
index d99945e7a9..76fddc3982 100644
--- a/source/libs/executor/src/timewindowoperator.c
+++ b/source/libs/executor/src/timewindowoperator.c
@@ -38,8 +38,6 @@ typedef struct SOpenWindowInfo {
uint64_t groupId;
} SOpenWindowInfo;
-static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator);
-
static int64_t* extractTsCol(SSDataBlock* pBlock, const SIntervalAggOperatorInfo* pInfo);
static SResultRowPosition addToOpenWindowList(SResultRowInfo* pResultRowInfo, const SResultRow* pResult,
@@ -828,31 +826,9 @@ int32_t compareResKey(void* pKey, void* data, int32_t index) {
return -1;
}
-static int32_t saveResult(int64_t ts, int32_t pageId, int32_t offset, uint64_t groupId, SArray* pUpdated) {
- int32_t size = taosArrayGetSize(pUpdated);
- SWinKey data = {.ts = ts, .groupId = groupId};
- int32_t index = binarySearchCom(pUpdated, size, &data, TSDB_ORDER_DESC, compareResKey);
- if (index == -1) {
- index = 0;
- } else {
- if (compareResKey(&data, pUpdated, index) > 0) {
- index++;
- } else {
- return TSDB_CODE_SUCCESS;
- }
- }
-
- SResKeyPos* newPos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
- if (newPos == NULL) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
- newPos->groupId = groupId;
- newPos->pos = (SResultRowPosition){.pageId = pageId, .offset = offset};
- *(int64_t*)newPos->key = ts;
- if (taosArrayInsert(pUpdated, index, &newPos) == NULL) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
- return TSDB_CODE_SUCCESS;
+static int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) {
+ winInfo.sessionWin.win.ekey = winInfo.sessionWin.win.skey;
+ return tSimpleHashPut(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo));
}
static int32_t saveWinResult(int64_t ts, int32_t pageId, int32_t offset, uint64_t groupId, SHashObj* pUpdatedMap) {
@@ -874,10 +850,6 @@ static int32_t saveWinResultInfo(TSKEY ts, uint64_t groupId, SHashObj* pUpdatedM
return saveWinResult(ts, -1, -1, groupId, pUpdatedMap);
}
-static int32_t saveResultRow(SResultRow* result, uint64_t groupId, SArray* pUpdated) {
- return saveResult(result->win.skey, result->pageId, result->offset, groupId, pUpdated);
-}
-
static void removeResults(SArray* pWins, SHashObj* pUpdatedMap) {
int32_t size = taosArrayGetSize(pWins);
for (int32_t i = 0; i < size; i++) {
@@ -915,8 +887,8 @@ int32_t compareWinRes(void* pKey, void* data, int32_t index) {
}
static void removeDeleteResults(SHashObj* pUpdatedMap, SArray* pDelWins) {
- taosArraySort(pDelWins, sWinKeyCmprImpl);
- taosArrayRemoveDuplicate(pDelWins, sWinKeyCmprImpl, NULL);
+ taosArraySort(pDelWins, winKeyCmprImpl);
+ taosArrayRemoveDuplicate(pDelWins, winKeyCmprImpl, NULL);
int32_t delSize = taosArrayGetSize(pDelWins);
if (taosHashGetSize(pUpdatedMap) == 0 || delSize == 0) {
return;
@@ -1385,19 +1357,6 @@ static void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf,
releaseBufPage(pResultBuf, bufPage);
}
-static bool doClearWindow(SAggSupporter* pAggSup, SExprSupp* pSup, char* pData, int16_t bytes, uint64_t groupId,
- int32_t numOfOutput) {
- SET_RES_WINDOW_KEY(pAggSup->keyBuf, pData, bytes, groupId);
- SResultRowPosition* p1 =
- (SResultRowPosition*)tSimpleHashGet(pAggSup->pResultRowHashTable, pAggSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
- if (!p1) {
- // window has been closed
- return false;
- }
- doClearWindowImpl(p1, pAggSup->pResultBuf, pSup, numOfOutput);
- return true;
-}
-
static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId) {
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
SWinKey key = {.ts = ts, .groupId = groupId};
@@ -1455,73 +1414,6 @@ static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDa
}
}
-bool doDeleteIntervalWindow(SAggSupporter* pAggSup, TSKEY ts, uint64_t groupId) {
- size_t bytes = sizeof(TSKEY);
- SET_RES_WINDOW_KEY(pAggSup->keyBuf, &ts, bytes, groupId);
- SResultRowPosition* p1 =
- (SResultRowPosition*)tSimpleHashGet(pAggSup->pResultRowHashTable, pAggSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
- if (!p1) {
- // window has been closed
- return false;
- }
- tSimpleHashRemove(pAggSup->pResultRowHashTable, pAggSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
- return true;
-}
-
-static void doDeleteSpecifyIntervalWindow(SAggSupporter* pAggSup, STimeWindowAggSupp* pTwSup, SSDataBlock* pBlock,
- SArray* pDelWins, SInterval* pInterval, SHashObj* pUpdatedMap) {
- SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
- TSKEY* tsStarts = (TSKEY*)pStartCol->pData;
- SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
- TSKEY* tsEnds = (TSKEY*)pEndCol->pData;
- SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
- uint64_t* groupIds = (uint64_t*)pGroupCol->pData;
- int64_t numOfWin = tSimpleHashGetSize(pAggSup->pResultRowHashTable);
- for (int32_t i = 0; i < pBlock->info.rows; i++) {
- TSKEY startTs = TMAX(tsStarts[i], pTwSup->minTs);
- TSKEY endTs = TMIN(tsEnds[i], pTwSup->maxTs);
- SResultRowInfo dumyInfo = {0};
- dumyInfo.cur.pageId = -1;
- STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, startTs, pInterval, TSDB_ORDER_ASC);
- do {
- doDeleteIntervalWindow(pAggSup, win.skey, groupIds[i]);
- SWinKey winRes = {.ts = win.skey, .groupId = groupIds[i]};
- if (pDelWins) {
- taosArrayPush(pDelWins, &winRes);
- }
- if (pUpdatedMap) {
- taosHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey));
- }
- getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
- } while (win.skey <= endTs);
- }
-}
-
-static void doClearWindows(SAggSupporter* pAggSup, SExprSupp* pSup1, SInterval* pInterval, int32_t numOfOutput,
- SSDataBlock* pBlock, SArray* pUpWins) {
- SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
- TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData;
- SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
- TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData;
- SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
- uint64_t* pGpDatas = (uint64_t*)pGpCol->pData;
- for (int32_t i = 0; i < pBlock->info.rows; i++) {
- SResultRowInfo dumyInfo = {0};
- dumyInfo.cur.pageId = -1;
-
- STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC);
- while (win.ekey <= endTsCols[i]) {
- uint64_t winGpId = pGpDatas[i];
- bool res = doClearWindow(pAggSup, pSup1, (char*)&win.skey, sizeof(TSKEY), winGpId, numOfOutput);
- if (pUpWins && res) {
- SWinKey winRes = {.ts = win.skey, .groupId = winGpId};
- taosArrayPush(pUpWins, &winRes);
- }
- getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
- }
- }
-}
-
static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SHashObj* resWins) {
void* pIte = NULL;
size_t keyLen = 0;
@@ -1725,6 +1617,9 @@ static void destroyStateWindowOperatorInfo(void* param) {
cleanupBasicInfo(&pInfo->binfo);
taosMemoryFreeClear(pInfo->stateKey.pData);
cleanupExprSupp(&pInfo->scalarSup);
+ colDataDestroy(&pInfo->twAggSup.timeWindowData);
+ cleanupAggSup(&pInfo->aggSup);
+ cleanupGroupResInfo(&pInfo->groupResInfo);
taosMemoryFreeClear(param);
}
@@ -2920,11 +2815,12 @@ bool hasIntervalWindow(SStreamState* pState, SWinKey* pKey) {
return TSDB_CODE_SUCCESS == streamStateGet(pState, pKey, NULL, 0);
}
-static void rebuildIntervalWindow(SOperatorInfo* pOperator, SExprSupp* pSup, SArray* pWinArray, SHashObj* pUpdatedMap) {
+static void rebuildIntervalWindow(SOperatorInfo* pOperator, SArray* pWinArray, SHashObj* pUpdatedMap) {
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
int32_t size = taosArrayGetSize(pWinArray);
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
+ SExprSupp* pSup = &pOperator->exprSupp;
if (!pInfo->pChildren) {
return;
}
@@ -2932,8 +2828,7 @@ static void rebuildIntervalWindow(SOperatorInfo* pOperator, SExprSupp* pSup, SAr
SWinKey* pWinRes = taosArrayGet(pWinArray, i);
SResultRow* pCurResult = NULL;
STimeWindow parentWin = getFinalTimeWindow(pWinRes->ts, &pInfo->interval);
- if (isDeletedStreamWindow(&parentWin, pWinRes->groupId, pInfo->pState, &pInfo->twAggSup) &&
- isCloseWindow(&parentWin, &pInfo->twAggSup)) {
+ if (isDeletedStreamWindow(&parentWin, pWinRes->groupId, pInfo->pState, &pInfo->twAggSup)) {
continue;
}
@@ -3220,6 +3115,14 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) {
saveWinResultInfo(pResult->win.skey, groupId, pUpdatedMap);
}
+
+ if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
+ SWinKey key = {
+ .ts = pResult->win.skey,
+ .groupId = groupId,
+ };
+ tSimpleHashPut(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey), NULL, 0);
+ }
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
doApplyFunctions(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startPos, forwardRows,
pSDataBlock->info.rows, numOfOutput);
@@ -3335,7 +3238,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
SStreamIntervalOperatorInfo* pChildInfo = pChildOp->info;
SExprSupp* pChildSup = &pChildOp->exprSupp;
doDeleteWindows(pChildOp, &pChildInfo->interval, pBlock, NULL, NULL);
- rebuildIntervalWindow(pOperator, pSup, delWins, pUpdatedMap);
+ rebuildIntervalWindow(pOperator, delWins, pUpdatedMap);
addRetriveWindow(delWins, pInfo);
taosArrayAddAll(pInfo->pDelWins, delWins);
taosArrayDestroy(delWins);
@@ -3561,42 +3464,18 @@ _error:
}
void destroyStreamAggSupporter(SStreamAggSupporter* pSup) {
- taosMemoryFreeClear(pSup->pKeyBuf);
- void** pIte = NULL;
- while ((pIte = taosHashIterate(pSup->pResultRows, pIte)) != NULL) {
- SArray* pWins = (SArray*)(*pIte);
- taosArrayDestroy(pWins);
- }
- taosHashCleanup(pSup->pResultRows);
- destroyDiskbasedBuf(pSup->pResultBuf);
- blockDataDestroy(pSup->pScanBlock);
-}
-
-void destroyStateWinInfo(void* ptr) {
- if (ptr == NULL) {
- return;
- }
- SStateWindowInfo* pWin = (SStateWindowInfo*)ptr;
- taosMemoryFreeClear(pWin->stateKey.pData);
-}
-
-void destroyStateStreamAggSupporter(SStreamAggSupporter* pSup) {
- taosMemoryFreeClear(pSup->pKeyBuf);
- void** pIte = NULL;
- while ((pIte = taosHashIterate(pSup->pResultRows, pIte)) != NULL) {
- SArray* pWins = (SArray*)(*pIte);
- taosArrayDestroyEx(pWins, (FDelete)destroyStateWinInfo);
- }
- taosHashCleanup(pSup->pResultRows);
+ tSimpleHashCleanup(pSup->pResultRows);
destroyDiskbasedBuf(pSup->pResultBuf);
blockDataDestroy(pSup->pScanBlock);
+ taosMemoryFreeClear(pSup->pState);
+ taosMemoryFreeClear(pSup->pDummyCtx);
}
void destroyStreamSessionAggOperatorInfo(void* param) {
SStreamSessionAggOperatorInfo* pInfo = (SStreamSessionAggOperatorInfo*)param;
cleanupBasicInfo(&pInfo->binfo);
destroyStreamAggSupporter(&pInfo->streamAggSup);
- cleanupGroupResInfo(&pInfo->groupResInfo);
+
if (pInfo->pChildren != NULL) {
int32_t size = taosArrayGetSize(pInfo->pChildren);
for (int32_t i = 0; i < size; i++) {
@@ -3610,8 +3489,7 @@ void destroyStreamSessionAggOperatorInfo(void* param) {
blockDataDestroy(pInfo->pDelRes);
blockDataDestroy(pInfo->pWinBlock);
blockDataDestroy(pInfo->pUpdateRes);
- destroySqlFunctionCtx(pInfo->pDummyCtx, 0);
- taosHashCleanup(pInfo->pStDeleted);
+ tSimpleHashCleanup(pInfo->pStDeleted);
taosHashCleanup(pInfo->pGroupIdTbNameMap);
taosMemoryFreeClear(param);
@@ -3640,129 +3518,62 @@ void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t num
}
}
-void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, int64_t gap, int64_t waterMark,
- uint16_t type, int32_t tsColIndex) {
+void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, int64_t waterMark, uint16_t type,
+ int32_t tsColIndex) {
if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION) {
SStreamPartitionOperatorInfo* pScanInfo = downstream->info;
pScanInfo->tsColIndex = tsColIndex;
}
if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
- initDownStream(downstream->pDownstream[0], pAggSup, gap, waterMark, type, tsColIndex);
+ initDownStream(downstream->pDownstream[0], pAggSup, waterMark, type, tsColIndex);
return;
}
SStreamScanInfo* pScanInfo = downstream->info;
- pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = gap, .parentType = type};
+ pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = pAggSup->gap, .parentType = type};
pScanInfo->pUpdateInfo = updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, waterMark);
}
-int32_t initSessionAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlFunctionCtx* pCtx,
- int32_t numOfOutput) {
- return initStreamAggSupporter(pSup, pKey, pCtx, numOfOutput, sizeof(SResultWindowInfo));
-}
-
-SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
- SExecTaskInfo* pTaskInfo) {
- SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
- int32_t numOfCols = 0;
- int32_t code = TSDB_CODE_OUT_OF_MEMORY;
-
- SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo));
- SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
- if (pInfo == NULL || pOperator == NULL) {
- goto _error;
+int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap,
+ SStreamState* pState, int32_t keySize, int16_t keyType) {
+ pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput);
+ pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR);
+ pSup->gap = gap;
+ pSup->stateKeySize = keySize;
+ pSup->stateKeyType = keyType;
+ pSup->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx));
+ if (pSup->pDummyCtx == NULL) {
+ return TSDB_CODE_OUT_OF_MEMORY;
}
- pOperator->pTaskInfo = pTaskInfo;
+ initDummyFunction(pSup->pDummyCtx, pCtx, numOfOutput);
+ pSup->pState = taosMemoryCalloc(1, sizeof(SStreamState));
+ *(pSup->pState) = *pState;
+ streamStateSetNumber(pSup->pState, -1);
- initResultSizeInfo(&pOperator->resultInfo, 4096);
- if (pSessionNode->window.pExprs != NULL) {
- int32_t numOfScalar = 0;
- SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar);
- code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar);
- if (code != TSDB_CODE_SUCCESS) {
- goto _error;
- }
- }
-
- SExprSupp* pSup = &pOperator->exprSupp;
-
- SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols);
- SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
- code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock);
- if (code != TSDB_CODE_SUCCESS) {
- goto _error;
- }
-
- code = initSessionAggSupporter(&pInfo->streamAggSup, "StreamSessionAggOperatorInfo", pSup->pCtx, numOfCols);
- if (code != TSDB_CODE_SUCCESS) {
- goto _error;
- }
-
- pInfo->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfCols, sizeof(SqlFunctionCtx));
- if (pInfo->pDummyCtx == NULL) {
- goto _error;
- }
-
- initDummyFunction(pInfo->pDummyCtx, pSup->pCtx, numOfCols);
- pInfo->twAggSup = (STimeWindowAggSupp){
- .waterMark = pSessionNode->window.watermark,
- .calTrigger = pSessionNode->window.triggerType,
- .maxTs = INT64_MIN,
- .minTs = INT64_MAX,
- };
-
- initResultRowInfo(&pInfo->binfo.resultRowInfo);
- initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
-
- pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
- if (pSessionNode->window.pTsEnd) {
- pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId;
- }
- pInfo->gap = pSessionNode->gap;
- pInfo->binfo.pRes = pResBlock;
- pInfo->order = TSDB_ORDER_ASC;
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
- pInfo->pStDeleted = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
- pInfo->pDelIterator = NULL;
- pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT);
- pInfo->pChildren = NULL;
- pInfo->isFinal = false;
- pInfo->pPhyNode = pPhyNode;
- pInfo->ignoreExpiredData = pSessionNode->window.igExpired;
+ pSup->pResultRows = tSimpleHashInit(32, hashFn);
- pInfo->pGroupIdTbNameMap =
- taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK);
-
- pOperator->name = "StreamSessionWindowAggOperator";
- pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION;
- pOperator->blocking = true;
- pOperator->status = OP_NOT_OPENED;
- pOperator->info = pInfo;
- pOperator->fpSet =
- createOperatorFpSet(operatorDummyOpenFn, doStreamSessionAgg, NULL, NULL, destroyStreamSessionAggOperatorInfo,
- aggEncodeResultRow, aggDecodeResultRow, NULL);
- if (downstream) {
- initDownStream(downstream, &pInfo->streamAggSup, pInfo->gap, pInfo->twAggSup.waterMark, pOperator->operatorType,
- pInfo->primaryTsIndex);
- code = appendDownstream(pOperator, &downstream, 1);
+ int32_t pageSize = 4096;
+ while (pageSize < pSup->resultRowSize * 4) {
+ pageSize <<= 1u;
}
- return pOperator;
-
-_error:
- if (pInfo != NULL) {
- destroyStreamSessionAggOperatorInfo(pInfo);
+ // at least four pages need to be in buffer
+ int32_t bufSize = 4096 * 256;
+ if (bufSize <= pageSize) {
+ bufSize = pageSize * 4;
+ }
+ if (!osTempSpaceAvailable()) {
+ terrno = TSDB_CODE_NO_AVAIL_DISK;
+ qError("Init stream agg supporter failed since %s", terrstr(terrno));
+ return terrno;
+ }
+ int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir);
+ for (int32_t i = 0; i < numOfOutput; ++i) {
+ pCtx[i].saveHandle.pBuf = pSup->pResultBuf;
}
- taosMemoryFreeClear(pOperator);
- pTaskInfo->code = code;
- return NULL;
-}
-
-int64_t getSessionWindowEndkey(void* data, int32_t index) {
- SArray* pWinInfos = (SArray*)data;
- SResultWindowInfo* pWin = taosArrayGet(pWinInfos, index);
- return pWin->win.ekey;
+ return TSDB_CODE_SUCCESS;
}
bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap) {
@@ -3772,305 +3583,243 @@ bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap) {
return false;
}
-bool isInWindow(SResultWindowInfo* pWinInfo, TSKEY ts, int64_t gap) { return isInTimeWindow(&pWinInfo->win, ts, gap); }
-
-static SResultWindowInfo* insertNewSessionWindow(SArray* pWinInfos, TSKEY startTs, TSKEY endTs, int32_t index) {
- SResultWindowInfo win = {
- .pos.offset = -1, .pos.pageId = -1, .win.skey = startTs, .win.ekey = endTs, .isOutput = false};
- return taosArrayInsert(pWinInfos, index, &win);
+bool isInWindow(SResultWindowInfo* pWinInfo, TSKEY ts, int64_t gap) {
+ return isInTimeWindow(&pWinInfo->sessionWin.win, ts, gap);
}
-static SResultWindowInfo* addNewSessionWindow(SArray* pWinInfos, TSKEY startTs, TSKEY endTs) {
- SResultWindowInfo win = {
- .pos.offset = -1, .pos.pageId = -1, .win.skey = startTs, .win.ekey = endTs, .isOutput = false};
- return taosArrayPush(pWinInfos, &win);
+void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId,
+ SSessionKey* pKey) {
+ pKey->win.skey = startTs;
+ pKey->win.ekey = endTs;
+ pKey->groupId = groupId;
+ SStreamStateCur* pCur = streamStateSessionGetCur(pAggSup->pState, pKey);
+ int32_t code = streamStateSessionGetKVByCur(pCur, pKey, NULL, 0);
+ streamStateFreeCur(pCur);
+ if (code != TSDB_CODE_SUCCESS) {
+ SET_SESSION_WIN_KEY_INVALID(pKey);
+ }
}
-SArray* getWinInfos(SStreamAggSupporter* pAggSup, uint64_t groupId) {
- void** ite = taosHashGet(pAggSup->pResultRows, &groupId, sizeof(uint64_t));
- SArray* pWinInfos = NULL;
- if (ite == NULL) {
- pWinInfos = taosArrayInit(1024, pAggSup->valueSize);
- taosHashPut(pAggSup->pResultRows, &groupId, sizeof(uint64_t), &pWinInfos, sizeof(void*));
+bool isInvalidSessionWin(SResultWindowInfo* pWinInfo) { return pWinInfo->sessionWin.win.skey == 0; }
+
+void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId,
+ SResultWindowInfo* pCurWin) {
+ pCurWin->sessionWin.groupId = groupId;
+ pCurWin->sessionWin.win.skey = startTs - pAggSup->gap;
+ pCurWin->sessionWin.win.ekey = endTs + pAggSup->gap;
+ int32_t size = pAggSup->resultRowSize;
+ int32_t code = streamStateSessionAddIfNotExist(pAggSup->pState, &pCurWin->sessionWin, &pCurWin->pOutputBuf, &size);
+ if (code == TSDB_CODE_SUCCESS) {
+ pCurWin->isOutput = true;
} else {
- pWinInfos = *ite;
+ pCurWin->sessionWin.win.skey = startTs;
+ pCurWin->sessionWin.win.ekey = endTs;
}
- return pWinInfos;
}
-// don't add new window
-SResultWindowInfo* getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId,
- int64_t gap, int32_t* pIndex) {
- STimeWindow searchWin = {.skey = startTs, .ekey = endTs};
- SArray* pWinInfos = getWinInfos(pAggSup, groupId);
- pAggSup->pCurWins = pWinInfos;
-
- int32_t size = taosArrayGetSize(pWinInfos);
- if (size == 0) {
- return NULL;
+int32_t getSessionWinBuf(SStreamAggSupporter* pAggSup, SStreamStateCur* pCur, SResultWindowInfo* pWinInfo) {
+ int32_t size = 0;
+ int32_t code = streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, (const void**)&pWinInfo->pOutputBuf, &size);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
}
- // find the first position which is smaller than the key
- int32_t index = binarySearch(pWinInfos, size, startTs, TSDB_ORDER_DESC, getSessionWindowEndkey);
- SResultWindowInfo* pWin = NULL;
- if (index >= 0) {
- pWin = taosArrayGet(pWinInfos, index);
- if (isInWindow(pWin, startTs, gap) || isInTimeWindow(&searchWin, pWin->win.skey, gap)) {
- *pIndex = index;
- return pWin;
- }
- }
-
- if (index + 1 < size) {
- pWin = taosArrayGet(pWinInfos, index + 1);
- if (isInWindow(pWin, startTs, gap) || isInTimeWindow(&searchWin, pWin->win.skey, gap)) {
- *pIndex = index + 1;
- return pWin;
- } else if (endTs != INT64_MIN && isInWindow(pWin, endTs, gap)) {
- *pIndex = index + 1;
- return pWin;
- }
- }
-
- return NULL;
+ streamStateCurNext(pAggSup->pState, pCur);
+ return TSDB_CODE_SUCCESS;
+}
+void saveDeleteInfo(SArray* pWins, SSessionKey key) {
+ // key.win.ekey = key.win.skey;
+ taosArrayPush(pWins, &key);
}
-SResultWindowInfo* getSessionTimeWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId,
- int64_t gap, int32_t* pIndex) {
- SArray* pWinInfos = getWinInfos(pAggSup, groupId);
- pAggSup->pCurWins = pWinInfos;
+void saveDeleteRes(SSHashObj* pStDelete, SSessionKey key) {
+ key.win.ekey = key.win.skey;
+ tSimpleHashPut(pStDelete, &key, sizeof(SSessionKey), NULL, 0);
+}
- int32_t size = taosArrayGetSize(pWinInfos);
- if (size == 0) {
- *pIndex = 0;
- return addNewSessionWindow(pWinInfos, startTs, endTs);
- }
- // find the first position which is smaller than the key
- int32_t index = binarySearch(pWinInfos, size, startTs, TSDB_ORDER_DESC, getSessionWindowEndkey);
- SResultWindowInfo* pWin = NULL;
- if (index >= 0) {
- pWin = taosArrayGet(pWinInfos, index);
- if (isInWindow(pWin, startTs, gap)) {
- *pIndex = index;
- return pWin;
- }
- }
+static void removeSessionResult(SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey key) {
+ key.win.ekey = key.win.skey;
+ tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey));
+ tSimpleHashRemove(pResMap, &key, sizeof(SSessionKey));
+}
- if (index + 1 < size) {
- pWin = taosArrayGet(pWinInfos, index + 1);
- if (isInWindow(pWin, startTs, gap)) {
- *pIndex = index + 1;
- return pWin;
- } else if (endTs != INT64_MIN && isInWindow(pWin, endTs, gap)) {
- *pIndex = index;
- return pWin;
- }
+static void removeSessionResults(SSHashObj* pHashMap, SArray* pWins) {
+ if (tSimpleHashGetSize(pHashMap) == 0) {
+ return;
}
-
- if (index == size - 1) {
- *pIndex = taosArrayGetSize(pWinInfos);
- return addNewSessionWindow(pWinInfos, startTs, endTs);
+ int32_t size = taosArrayGetSize(pWins);
+ for (int32_t i = 0; i < size; i++) {
+ SSessionKey* pWin = taosArrayGet(pWins, i);
+ if (!pWin) continue;
+ SSessionKey key = *pWin;
+ key.win.ekey = key.win.skey;
+ tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey));
}
- *pIndex = index + 1;
- return insertNewSessionWindow(pWinInfos, startTs, endTs, index + 1);
}
int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t groupId,
- int32_t rows, int32_t start, int64_t gap, SHashObj* pStDeleted) {
+ int32_t rows, int32_t start, int64_t gap, SSHashObj* pResultRows, SSHashObj* pStUpdated,
+ SSHashObj* pStDeleted) {
for (int32_t i = start; i < rows; ++i) {
if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap))) {
return i - start;
}
- if (pWinInfo->win.skey > pStartTs[i]) {
+ if (pWinInfo->sessionWin.win.skey > pStartTs[i]) {
if (pStDeleted && pWinInfo->isOutput) {
- SWinKey res = {.ts = pWinInfo->win.skey, .groupId = groupId};
- taosHashPut(pStDeleted, &res, sizeof(SWinKey), &res, sizeof(SWinKey));
- pWinInfo->isOutput = false;
+ saveDeleteRes(pStDeleted, pWinInfo->sessionWin);
}
- pWinInfo->win.skey = pStartTs[i];
+ removeSessionResult(pStUpdated, pResultRows, pWinInfo->sessionWin);
+ pWinInfo->sessionWin.win.skey = pStartTs[i];
}
- pWinInfo->win.ekey = TMAX(pWinInfo->win.ekey, pStartTs[i]);
+ pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pStartTs[i]);
if (pEndTs) {
- pWinInfo->win.ekey = TMAX(pWinInfo->win.ekey, pEndTs[i]);
+ pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pEndTs[i]);
}
}
return rows - start;
}
-static int32_t setWindowOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pResult, SqlFunctionCtx* pCtx,
- uint64_t groupId, int32_t numOfOutput, int32_t* rowEntryInfoOffset,
- SStreamAggSupporter* pAggSup, SExecTaskInfo* pTaskInfo) {
- assert(pWinInfo->win.skey <= pWinInfo->win.ekey);
- // too many time window in query
- int32_t size = taosArrayGetSize(pAggSup->pCurWins);
- if (pTaskInfo->execModel == OPTR_EXEC_MODEL_BATCH && size > MAX_INTERVAL_TIME_WINDOW) {
- T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
- }
-
- if (pWinInfo->pos.pageId == -1) {
- *pResult = getNewResultRow(pAggSup->pResultBuf, &pAggSup->currentPageId, pAggSup->resultRowSize);
- if (*pResult == NULL) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
-
- // add a new result set for a new group
- pWinInfo->pos.pageId = (*pResult)->pageId;
- pWinInfo->pos.offset = (*pResult)->offset;
- } else {
- *pResult = getResultRowByPos(pAggSup->pResultBuf, &pWinInfo->pos, true);
- if (!(*pResult)) {
- qError("getResultRowByPos return NULL, TID:%s", GET_TASKID(pTaskInfo));
- return TSDB_CODE_FAILED;
- }
- }
-
+static int32_t initSessionOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pResult, SqlFunctionCtx* pCtx,
+ int32_t numOfOutput, int32_t* rowEntryInfoOffset) {
+ ASSERT(pWinInfo->sessionWin.win.skey <= pWinInfo->sessionWin.win.ekey);
+ *pResult = (SResultRow*)pWinInfo->pOutputBuf;
// set time window for current result
- (*pResult)->win = pWinInfo->win;
+ (*pResult)->win = pWinInfo->sessionWin.win;
setResultRowInitCtx(*pResult, pCtx, numOfOutput, rowEntryInfoOffset);
return TSDB_CODE_SUCCESS;
}
-static int32_t doOneWindowAggImpl(int32_t tsColId, SOptrBasicInfo* pBinfo, SStreamAggSupporter* pAggSup,
- SColumnInfoData* pTimeWindowData, SSDataBlock* pSDataBlock,
- SResultWindowInfo* pCurWin, SResultRow** pResult, int32_t startIndex, int32_t winRows,
- int32_t numOutput, SOperatorInfo* pOperator) {
+static int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult,
+ int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput,
+ SOperatorInfo* pOperator) {
SExprSupp* pSup = &pOperator->exprSupp;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
-
- SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, tsColId);
- TSKEY* tsCols = (int64_t*)pColDataInfo->pData;
- int32_t code = setWindowOutputBuf(pCurWin, pResult, pSup->pCtx, pSDataBlock->info.groupId, numOutput,
- pSup->rowEntryInfoOffset, pAggSup, pTaskInfo);
+ int32_t code = initSessionOutputBuf(pCurWin, pResult, pSup->pCtx, numOutput, pSup->rowEntryInfoOffset);
if (code != TSDB_CODE_SUCCESS || (*pResult) == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
- updateTimeWindowInfo(pTimeWindowData, &pCurWin->win, false);
- doApplyFunctions(pTaskInfo, pSup->pCtx, pTimeWindowData, startIndex, winRows, pSDataBlock->info.rows, numOutput);
- SFilePage* bufPage = getBufPage(pAggSup->pResultBuf, pCurWin->pos.pageId);
- setBufPageDirty(bufPage, true);
- releaseBufPage(pAggSup->pResultBuf, bufPage);
+ updateTimeWindowInfo(pTimeWindowData, &pCurWin->sessionWin.win, false);
+ doApplyFunctions(pTaskInfo, pSup->pCtx, pTimeWindowData, startIndex, winRows, rows, numOutput);
return TSDB_CODE_SUCCESS;
}
-static int32_t doOneWindowAgg(SStreamSessionAggOperatorInfo* pInfo, SSDataBlock* pSDataBlock,
- SResultWindowInfo* pCurWin, SResultRow** pResult, int32_t startIndex, int32_t winRows,
- int32_t numOutput, SOperatorInfo* pOperator) {
- return doOneWindowAggImpl(pInfo->primaryTsIndex, &pInfo->binfo, &pInfo->streamAggSup, &pInfo->twAggSup.timeWindowData,
- pSDataBlock, pCurWin, pResult, startIndex, winRows, numOutput, pOperator);
+static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) {
+ streamStateSessionDel(pAggSup->pState, pKey);
+ tSimpleHashRemove(pAggSup->pResultRows, pKey, sizeof(SSessionKey));
+ return true;
}
-static int32_t doOneStateWindowAgg(SStreamStateAggOperatorInfo* pInfo, SSDataBlock* pSDataBlock,
- SResultWindowInfo* pCurWin, SResultRow** pResult, int32_t startIndex,
- int32_t winRows, int32_t numOutput, SOperatorInfo* pOperator) {
- return doOneWindowAggImpl(pInfo->primaryTsIndex, &pInfo->binfo, &pInfo->streamAggSup, &pInfo->twAggSup.timeWindowData,
- pSDataBlock, pCurWin, pResult, startIndex, winRows, numOutput, pOperator);
-}
-
-int32_t getNumCompactWindow(SArray* pWinInfos, int32_t startIndex, int64_t gap) {
- SResultWindowInfo* pCurWin = taosArrayGet(pWinInfos, startIndex);
- int32_t size = taosArrayGetSize(pWinInfos);
- // Just look for the window behind StartIndex
- for (int32_t i = startIndex + 1; i < size; i++) {
- SResultWindowInfo* pWinInfo = taosArrayGet(pWinInfos, i);
- if (!isInWindow(pCurWin, pWinInfo->win.skey, gap)) {
- return i - startIndex - 1;
- }
+static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) {
+ void* pVal = tSimpleHashGet(pStUpdated, &pWinInfo->sessionWin, sizeof(SSessionKey));
+ if (pVal) {
+ SResultWindowInfo* pWin = pVal;
+ pWinInfo->isOutput = pWin->isOutput;
}
-
- return size - startIndex - 1;
+ return TSDB_CODE_SUCCESS;
}
-void compactTimeWindow(SStreamSessionAggOperatorInfo* pInfo, int32_t startIndex, int32_t num, uint64_t groupId,
- int32_t numOfOutput, SHashObj* pStUpdated, SHashObj* pStDeleted, SOperatorInfo* pOperator) {
- SExprSupp* pSup = &pOperator->exprSupp;
- SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
-
- SResultWindowInfo* pCurWin = taosArrayGet(pInfo->streamAggSup.pCurWins, startIndex);
- SResultRow* pCurResult = NULL;
- setWindowOutputBuf(pCurWin, &pCurResult, pSup->pCtx, groupId, numOfOutput, pSup->rowEntryInfoOffset,
- &pInfo->streamAggSup, pTaskInfo);
- num += startIndex + 1;
- ASSERT(num <= taosArrayGetSize(pInfo->streamAggSup.pCurWins));
- // Just look for the window behind StartIndex
- for (int32_t i = startIndex + 1; i < num; i++) {
- SResultWindowInfo* pWinInfo = taosArrayGet(pInfo->streamAggSup.pCurWins, i);
- SResultRow* pWinResult = NULL;
- setWindowOutputBuf(pWinInfo, &pWinResult, pInfo->pDummyCtx, groupId, numOfOutput, pSup->rowEntryInfoOffset,
- &pInfo->streamAggSup, pTaskInfo);
- pCurWin->win.ekey = TMAX(pCurWin->win.ekey, pWinInfo->win.ekey);
- updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->win, true);
- compactFunctions(pSup->pCtx, pInfo->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData);
- taosHashRemove(pStUpdated, &pWinInfo->pos, sizeof(SResultRowPosition));
- if (pWinInfo->isOutput && pStDeleted) {
- SWinKey res = {.ts = pWinInfo->win.skey, .groupId = groupId};
- taosHashPut(pStDeleted, &res, sizeof(SWinKey), &res, sizeof(SWinKey));
- pWinInfo->isOutput = false;
- }
- taosArrayRemove(pInfo->streamAggSup.pCurWins, i);
- SFilePage* tmpPage = getBufPage(pInfo->streamAggSup.pResultBuf, pWinInfo->pos.pageId);
- releaseBufPage(pInfo->streamAggSup.pResultBuf, tmpPage);
+SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin,
+ SResultWindowInfo* pNextWin) {
+ SStreamStateCur* pCur = streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->sessionWin);
+ pNextWin->isOutput = true;
+ setSessionWinOutputInfo(pStUpdated, pNextWin);
+ int32_t size = 0;
+ pNextWin->sessionWin = pCurWin->sessionWin;
+ int32_t code = streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, (const void**)&pNextWin->pOutputBuf, &size);
+ if (code != TSDB_CODE_SUCCESS) {
+ SET_SESSION_WIN_INVALID(*pNextWin);
}
- SFilePage* bufPage = getBufPage(pInfo->streamAggSup.pResultBuf, pCurWin->pos.pageId);
- ASSERT(num > 0);
- setBufPageDirty(bufPage, true);
- releaseBufPage(pInfo->streamAggSup.pResultBuf, bufPage);
+ return pCur;
}
-static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SHashObj* pStUpdated,
- SHashObj* pStDeleted, bool hasEndTs) {
+static void compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated,
+ SSHashObj* pStDeleted) {
+ SExprSupp* pSup = &pOperator->exprSupp;
+ SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
+ SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
+ SResultRow* pCurResult = NULL;
+ int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
+ SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
+ initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
+ // Just look for the window behind StartIndex
+ while (1) {
+ SResultWindowInfo winInfo = {0};
+ SStreamStateCur* pCur = getNextSessionWinInfo(pAggSup, pStUpdated, pCurWin, &winInfo);
+ if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap)) {
+ streamStateFreeCur(pCur);
+ break;
+ }
+ SResultRow* pWinResult = NULL;
+ initSessionOutputBuf(&winInfo, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset);
+ pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, winInfo.sessionWin.win.ekey);
+ updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, true);
+ compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData);
+ tSimpleHashRemove(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey));
+ if (winInfo.isOutput && pStDeleted) {
+ saveDeleteRes(pStDeleted, winInfo.sessionWin);
+ }
+ removeSessionResult(pStUpdated, pAggSup->pResultRows, winInfo.sessionWin);
+ doDeleteSessionWindow(pAggSup, &winInfo.sessionWin);
+ streamStateFreeCur(pCur);
+ }
+}
+
+int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo) {
+ saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize);
+ return TSDB_CODE_SUCCESS;
+}
+
+static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pStUpdated,
+ SSHashObj* pStDeleted, bool hasEndTs) {
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
- bool masterScan = true;
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
uint64_t groupId = pSDataBlock->info.groupId;
- int64_t gap = pInfo->gap;
int64_t code = TSDB_CODE_SUCCESS;
+ SResultRow* pResult = NULL;
+ int32_t rows = pSDataBlock->info.rows;
+ int32_t winRows = 0;
- int32_t step = 1;
- bool ascScan = true;
- TSKEY* startTsCols = NULL;
- TSKEY* endTsCols = NULL;
- SResultRow* pResult = NULL;
- int32_t winRows = 0;
-
- ASSERT(pSDataBlock->pDataBlock);
SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
- startTsCols = (int64_t*)pStartTsCol->pData;
+ TSKEY* startTsCols = (int64_t*)pStartTsCol->pData;
SColumnInfoData* pEndTsCol = NULL;
if (hasEndTs) {
pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->endTsIndex);
} else {
pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
}
- endTsCols = (int64_t*)pEndTsCol->pData;
+ TSKEY* endTsCols = (int64_t*)pEndTsCol->pData;
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
- for (int32_t i = 0; i < pSDataBlock->info.rows;) {
+ for (int32_t i = 0; i < rows;) {
if (pInfo->ignoreExpiredData && isOverdue(endTsCols[i], &pInfo->twAggSup)) {
i++;
continue;
}
- int32_t winIndex = 0;
- SResultWindowInfo* pCurWin = getSessionTimeWindow(pAggSup, startTsCols[i], endTsCols[i], groupId, gap, &winIndex);
- winRows = updateSessionWindowInfo(pCurWin, startTsCols, endTsCols, groupId, pSDataBlock->info.rows, i, pInfo->gap,
- pStDeleted);
- code = doOneWindowAgg(pInfo, pSDataBlock, pCurWin, &pResult, i, winRows, numOfOutput, pOperator);
+ SResultWindowInfo winInfo = {0};
+ setSessionOutputBuf(pAggSup, startTsCols[i], endTsCols[i], groupId, &winInfo);
+ setSessionWinOutputInfo(pStUpdated, &winInfo);
+ winRows = updateSessionWindowInfo(&winInfo, startTsCols, endTsCols, groupId, rows, i, pAggSup->gap,
+ pAggSup->pResultRows, pStUpdated, pStDeleted);
+ code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &winInfo, &pResult, i, winRows, rows, numOfOutput,
+ pOperator);
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
+ compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted);
+ saveSessionOutputBuf(pAggSup, &winInfo);
- int32_t winNum = getNumCompactWindow(pAggSup->pCurWins, winIndex, gap);
- if (winNum > 0) {
- compactTimeWindow(pInfo, winIndex, winNum, groupId, numOfOutput, pStUpdated, pStDeleted, pOperator);
- }
- pCurWin->isClosed = false;
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) {
- SWinKey value = {.ts = pCurWin->win.skey, .groupId = groupId};
- code = taosHashPut(pStUpdated, &pCurWin->pos, sizeof(SResultRowPosition), &value, sizeof(SWinKey));
+ code = saveResult(winInfo, pStUpdated);
if (code != TSDB_CODE_SUCCESS) {
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
- pCurWin->isOutput = true;
}
+ if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
+ SSessionKey key = winInfo.sessionWin;
+ key.win.ekey = key.win.skey;
+ tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo));
+ }
+
i += winRows;
}
}
@@ -4084,8 +3833,7 @@ void deleteWindow(SArray* pWinInfos, int32_t index, FDelete fp) {
taosArrayRemove(pWinInfos, index);
}
-static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, int64_t gap, SArray* result,
- FDelete fp) {
+static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) {
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
TSKEY* startDatas = (TSKEY*)pStartTsCol->pData;
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
@@ -4093,85 +3841,70 @@ static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBloc
SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
uint64_t* gpDatas = (uint64_t*)pGroupCol->pData;
for (int32_t i = 0; i < pBlock->info.rows; i++) {
- int32_t winIndex = 0;
- SResultWindowInfo* pCurWin = getCurSessionWindow(pAggSup, startDatas[i], endDatas[i], gpDatas[i], gap, &winIndex);
- if (!pCurWin) {
- continue;
- }
-
- do {
- SResultWindowInfo delWin = *pCurWin;
- deleteWindow(pAggSup->pCurWins, winIndex, fp);
- if (result) {
- delWin.groupId = gpDatas[i];
- taosArrayPush(result, &delWin);
- }
- if (winIndex >= taosArrayGetSize(pAggSup->pCurWins)) {
+ while (1) {
+ SSessionKey curWin = {0};
+ getCurSessionWindow(pAggSup, startDatas[i], endDatas[i], gpDatas[i], &curWin);
+ if (IS_INVALID_SESSION_WIN_KEY(curWin)) {
break;
}
- pCurWin = taosArrayGet(pAggSup->pCurWins, winIndex);
- } while (pCurWin->win.skey <= endDatas[i]);
- }
-}
-
-static void doClearSessionWindows(SStreamAggSupporter* pAggSup, SExprSupp* pSup, SSDataBlock* pBlock, int32_t tsIndex,
- int32_t numOfOutput, int64_t gap, SArray* result) {
- SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, tsIndex);
- TSKEY* tsCols = (TSKEY*)pColDataInfo->pData;
- SColumnInfoData* pGpDataInfo = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
- uint64_t* gpCols = (uint64_t*)pGpDataInfo->pData;
- int32_t step = 0;
- for (int32_t i = 0; i < pBlock->info.rows; i += step) {
- int32_t winIndex = 0;
- SResultWindowInfo* pCurWin = getCurSessionWindow(pAggSup, tsCols[i], INT64_MIN, gpCols[i], gap, &winIndex);
- if (!pCurWin || pCurWin->pos.pageId == -1) {
- // window has been closed.
- step = 1;
- continue;
- }
- step = updateSessionWindowInfo(pCurWin, tsCols, NULL, 0, pBlock->info.rows, i, gap, NULL);
- ASSERT(isInWindow(pCurWin, tsCols[i], gap));
- doClearWindowImpl(&pCurWin->pos, pAggSup->pResultBuf, pSup, numOfOutput);
- if (result) {
- pCurWin->groupId = gpCols[i];
- taosArrayPush(result, pCurWin);
+ doDeleteSessionWindow(pAggSup, &curWin);
+ if (result) {
+ saveDeleteInfo(result, curWin);
+ }
}
}
}
-static int32_t copyUpdateResult(SHashObj* pStUpdated, SArray* pUpdated) {
- void* pData = NULL;
- size_t keyLen = 0;
- while ((pData = taosHashIterate(pStUpdated, pData)) != NULL) {
- void* key = taosHashGetKey(pData, &keyLen);
- ASSERT(keyLen == sizeof(SResultRowPosition));
- SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
- if (pos == NULL) {
- return TSDB_CODE_QRY_OUT_OF_MEMORY;
- }
- pos->groupId = ((SWinKey*)pData)->groupId;
- pos->pos = *(SResultRowPosition*)key;
- *(int64_t*)pos->key = ((SWinKey*)pData)->ts;
- taosArrayPush(pUpdated, &pos);
+static inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) {
+ SSessionKey* pWin1 = (SSessionKey*)pKey1;
+ SSessionKey* pWin2 = (SSessionKey*)pKey2;
+
+ if (pWin1->groupId > pWin2->groupId) {
+ return 1;
+ } else if (pWin1->groupId < pWin2->groupId) {
+ return -1;
}
- taosArraySort(pUpdated, resultrowComparAsc);
+
+ if (pWin1->win.skey > pWin2->win.skey) {
+ return 1;
+ } else if (pWin1->win.skey < pWin2->win.skey) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int32_t copyUpdateResult(SSHashObj* pStUpdated, SArray* pUpdated) {
+ void* pIte = NULL;
+ size_t keyLen = 0;
+ int32_t iter = 0;
+ while ((pIte = tSimpleHashIterate(pStUpdated, pIte, &iter)) != NULL) {
+ void* key = tSimpleHashGetKey(pIte, &keyLen);
+ ASSERT(keyLen == sizeof(SSessionKey));
+ taosArrayPush(pUpdated, key);
+ }
+ taosArraySort(pUpdated, sessionKeyCompareAsc);
return TSDB_CODE_SUCCESS;
}
-void doBuildDeleteDataBlock(SHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite) {
+void doBuildDeleteDataBlock(SSHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite) {
blockDataCleanup(pBlock);
- int32_t size = taosHashGetSize(pStDeleted);
+ int32_t size = tSimpleHashGetSize(pStDeleted);
if (size == 0) {
return;
}
blockDataEnsureCapacity(pBlock, size);
- size_t keyLen = 0;
- while (((*Ite) = taosHashIterate(pStDeleted, *Ite)) != NULL) {
- SWinKey* res = *Ite;
+ size_t keyLen = 0;
+ int32_t iter = 0;
+ while (((*Ite) = tSimpleHashIterate(pStDeleted, *Ite, &iter)) != NULL) {
+ if (pBlock->info.rows + 1 > pBlock->info.capacity) {
+ break;
+ }
+ SSessionKey* res = tSimpleHashGetKey(*Ite, &keyLen);
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
- colDataAppend(pStartTsCol, pBlock->info.rows, (const char*)&res->ts, false);
+ colDataAppend(pStartTsCol, pBlock->info.rows, (const char*)&res->win.skey, false);
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
- colDataAppend(pEndTsCol, pBlock->info.rows, (const char*)&res->ts, false);
+ colDataAppend(pEndTsCol, pBlock->info.rows, (const char*)&res->win.skey, false);
SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX);
colDataAppendNULL(pUidCol, pBlock->info.rows);
SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
@@ -4181,167 +3914,137 @@ void doBuildDeleteDataBlock(SHashObj* pStDeleted, SSDataBlock* pBlock, void** It
SColumnInfoData* pCalEdCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
colDataAppendNULL(pCalEdCol, pBlock->info.rows);
pBlock->info.rows += 1;
- if (pBlock->info.rows + 1 >= pBlock->info.capacity) {
- break;
- }
}
if ((*Ite) == NULL) {
- taosHashClear(pStDeleted);
+ tSimpleHashClear(pStDeleted);
}
}
-static void rebuildTimeWindow(SStreamSessionAggOperatorInfo* pInfo, SArray* pWinArray, int32_t numOfOutput,
- SOperatorInfo* pOperator, SHashObj* pStUpdated) {
- SExprSupp* pSup = &pOperator->exprSupp;
- SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
- int32_t size = taosArrayGetSize(pWinArray);
+static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SSHashObj* pStUpdated) {
+ SExprSupp* pSup = &pOperator->exprSupp;
+ SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
+ int32_t size = taosArrayGetSize(pWinArray);
+ SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
+ SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
+ int32_t numOfOutput = pSup->numOfExprs;
+ int32_t numOfChildren = taosArrayGetSize(pInfo->pChildren);
ASSERT(pInfo->pChildren);
for (int32_t i = 0; i < size; i++) {
- SResultWindowInfo* pParentWin = taosArrayGet(pWinArray, i);
- uint64_t groupId = pParentWin->groupId;
- int32_t numOfChildren = taosArrayGetSize(pInfo->pChildren);
+ SSessionKey* pWinKey = taosArrayGet(pWinArray, i);
+ int32_t num = 0;
+ SResultWindowInfo parentWin = {0};
for (int32_t j = 0; j < numOfChildren; j++) {
SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, j);
SStreamSessionAggOperatorInfo* pChInfo = pChild->info;
- SArray* pChWins = getWinInfos(&pChInfo->streamAggSup, groupId);
- int32_t chWinSize = taosArrayGetSize(pChWins);
- int32_t index = binarySearch(pChWins, chWinSize, pParentWin->win.skey, TSDB_ORDER_DESC, getSessionWindowEndkey);
- if (index < 0) {
- index = 0;
- }
- for (int32_t k = index; k < chWinSize; k++) {
- SResultWindowInfo* pChWin = taosArrayGet(pChWins, k);
- if (pParentWin->win.skey <= pChWin->win.skey && pChWin->win.ekey <= pParentWin->win.ekey) {
- int32_t winIndex = 0;
- SResultWindowInfo* pNewParWin =
- getSessionTimeWindow(&pInfo->streamAggSup, pChWin->win.skey, pChWin->win.ekey, groupId, 0, &winIndex);
- SResultRow* pPareResult = NULL;
- setWindowOutputBuf(pNewParWin, &pPareResult, pSup->pCtx, groupId, numOfOutput, pSup->rowEntryInfoOffset,
- &pInfo->streamAggSup, pTaskInfo);
- SResultRow* pChResult = NULL;
- setWindowOutputBuf(pChWin, &pChResult, pChild->exprSupp.pCtx, groupId, numOfOutput,
- pChild->exprSupp.rowEntryInfoOffset, &pChInfo->streamAggSup, pTaskInfo);
- updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pNewParWin->win, true);
- compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData);
-
- int32_t winNum = getNumCompactWindow(pInfo->streamAggSup.pCurWins, winIndex, pInfo->gap);
- if (winNum > 0) {
- compactTimeWindow(pInfo, winIndex, winNum, groupId, numOfOutput, pStUpdated, NULL, pOperator);
+ SStreamAggSupporter* pChAggSup = &pChInfo->streamAggSup;
+ SStreamStateCur* pCur = streamStateSessionGetCur(pChAggSup->pState, pWinKey);
+ SResultRow* pResult = NULL;
+ SResultRow* pChResult = NULL;
+ while (1) {
+ SResultWindowInfo childWin = {0};
+ childWin.sessionWin = *pWinKey;
+ int32_t code = getSessionWinBuf(pChAggSup, pCur, &childWin);
+ if (code == TSDB_CODE_SUCCESS && pWinKey->win.skey <= childWin.sessionWin.win.skey &&
+ childWin.sessionWin.win.ekey <= pWinKey->win.ekey) {
+ if (num == 0) {
+ setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin);
+ code = initSessionOutputBuf(&parentWin, &pResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
+ if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
+ break;
+ }
}
-
- SFilePage* bufPage = getBufPage(pChInfo->streamAggSup.pResultBuf, pChWin->pos.pageId);
- releaseBufPage(pChInfo->streamAggSup.pResultBuf, bufPage);
-
- bufPage = getBufPage(pInfo->streamAggSup.pResultBuf, pNewParWin->pos.pageId);
- setBufPageDirty(bufPage, true);
- releaseBufPage(pInfo->streamAggSup.pResultBuf, bufPage);
- SWinKey value = {.ts = pNewParWin->win.skey, .groupId = groupId};
- taosHashPut(pStUpdated, &pNewParWin->pos, sizeof(SResultRowPosition), &value, sizeof(SWinKey));
- } else if (!pChWin->isClosed) {
+ num++;
+ updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, true);
+ initSessionOutputBuf(&childWin, &pChResult, pChild->exprSupp.pCtx, numOfOutput,
+ pChild->exprSupp.rowEntryInfoOffset);
+ compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData);
+ compactSessionWindow(pOperator, &parentWin, pStUpdated, NULL);
+ saveResult(parentWin, pStUpdated);
+ } else {
break;
}
}
+ streamStateFreeCur(pCur);
+ }
+ if (num > 0) {
+ saveSessionOutputBuf(pAggSup, &parentWin);
}
}
}
-typedef SResultWindowInfo* (*__get_win_info_)(void*);
-SResultWindowInfo* getResWinForSession(void* pData) { return (SResultWindowInfo*)pData; }
-SResultWindowInfo* getResWinForState(void* pData) { return &((SStateWindowInfo*)pData)->winInfo; }
-
-int32_t closeSessionWindow(SHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SArray* pClosed, __get_win_info_ fn,
- bool delete, FDelete fp) {
- // Todo(liuyao) save window to tdb
- void** pIte = NULL;
- size_t keyLen = 0;
- while ((pIte = taosHashIterate(pHashMap, pIte)) != NULL) {
- uint64_t* pGroupId = taosHashGetKey(pIte, &keyLen);
- SArray* pWins = (SArray*)(*pIte);
- int32_t size = taosArrayGetSize(pWins);
- for (int32_t i = 0; i < size; i++) {
- void* pWin = taosArrayGet(pWins, i);
- SResultWindowInfo* pSeWin = fn(pWin);
- if (isCloseWindow(&pSeWin->win, pTwSup)) {
- if (!pSeWin->isClosed) {
- pSeWin->isClosed = true;
- if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE && pClosed) {
- int32_t code = saveResult(pSeWin->win.skey, pSeWin->pos.pageId, pSeWin->pos.offset, *pGroupId, pClosed);
- if (code != TSDB_CODE_SUCCESS) {
- return code;
- }
- pSeWin->isOutput = true;
- }
- if (delete) {
- deleteWindow(pWins, i, fp);
- i--;
- size = taosArrayGetSize(pWins);
- }
+int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed) {
+ void* pIte = NULL;
+ size_t keyLen = 0;
+ int32_t iter = 0;
+ while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) {
+ SResultWindowInfo* pWinInfo = pIte;
+ if (isCloseWindow(&pWinInfo->sessionWin.win, pTwSup)) {
+ if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE && pClosed) {
+ int32_t code = saveResult(*pWinInfo, pClosed);
+ if (code != TSDB_CODE_SUCCESS) {
+ return code;
}
- continue;
}
- break;
+ tSimpleHashIterateRemove(pHashMap, &pWinInfo->sessionWin, sizeof(SSessionKey), &pIte, &iter);
}
}
return TSDB_CODE_SUCCESS;
}
-static void closeChildSessionWindow(SArray* pChildren, TSKEY maxTs, bool delete, FDelete fp) {
+static void closeChildSessionWindow(SArray* pChildren, TSKEY maxTs) {
int32_t size = taosArrayGetSize(pChildren);
for (int32_t i = 0; i < size; i++) {
SOperatorInfo* pChildOp = taosArrayGetP(pChildren, i);
SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info;
pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs);
- closeSessionWindow(pChInfo->streamAggSup.pResultRows, &pChInfo->twAggSup, NULL, getResWinForSession, delete, fp);
+ closeSessionWindow(pChInfo->streamAggSup.pResultRows, &pChInfo->twAggSup, NULL);
}
}
-int32_t getAllSessionWindow(SHashObj* pHashMap, SArray* pClosed, __get_win_info_ fn) {
- void** pIte = NULL;
- while ((pIte = taosHashIterate(pHashMap, pIte)) != NULL) {
- SArray* pWins = (SArray*)(*pIte);
- int32_t size = taosArrayGetSize(pWins);
- for (int32_t i = 0; i < size; i++) {
- void* pWin = taosArrayGet(pWins, i);
- SResultWindowInfo* pSeWin = fn(pWin);
- if (!pSeWin->isClosed) {
- int32_t code = saveResult(pSeWin->win.skey, pSeWin->pos.pageId, pSeWin->pos.offset, 0, pClosed);
- pSeWin->isOutput = true;
- }
- }
+int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated) {
+ void* pIte = NULL;
+ int32_t iter = 0;
+ while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) {
+ SResultWindowInfo* pWinInfo = *(void**)pIte;
+ saveResult(*pWinInfo, pStUpdated);
}
return TSDB_CODE_SUCCESS;
}
-static void copyDeleteWindowInfo(SArray* pResWins, SHashObj* pStDeleted) {
+static void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) {
int32_t size = taosArrayGetSize(pResWins);
for (int32_t i = 0; i < size; i++) {
- SResultWindowInfo* pWinInfo = taosArrayGet(pResWins, i);
- SWinKey res = {.ts = pWinInfo->win.skey, .groupId = pWinInfo->groupId};
- taosHashPut(pStDeleted, &res, sizeof(SWinKey), &res, sizeof(SWinKey));
+ SSessionKey* pWinKey = taosArrayGet(pResWins, i);
+ if (!pWinKey) continue;
+ SSessionKey winInfo = *pWinKey;
+ winInfo.win.ekey = winInfo.win.skey;
+ tSimpleHashPut(pStDeleted, &winInfo, sizeof(SSessionKey), NULL, 0);
}
}
-static void removeSessionResults(SHashObj* pHashMap, SArray* pWins) {
- int32_t size = taosArrayGetSize(pWins);
- for (int32_t i = 0; i < size; i++) {
- SResultWindowInfo* pWin = taosArrayGet(pWins, i);
- taosHashRemove(pHashMap, &pWin->pos, sizeof(SResultRowPosition));
- }
+void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList) {
+ pGroupResInfo->pRows = pArrayList;
+ pGroupResInfo->index = 0;
+ ASSERT(pGroupResInfo->index <= getNumOfTotalRes(pGroupResInfo));
}
-static void removeSessionDeleteResults(SArray* update, SHashObj* pStDeleted) {
- int32_t size = taosHashGetSize(pStDeleted);
- if (size == 0) {
+void doBuildSessionResult(SOperatorInfo* pOperator, SStreamState* pState, SGroupResInfo* pGroupResInfo,
+ SSDataBlock* pBlock) {
+ SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
+ // set output datablock version
+ pBlock->info.version = pTaskInfo->version;
+
+ blockDataCleanup(pBlock);
+ if (!hasRemainResults(pGroupResInfo)) {
+ taosArrayDestroy(pGroupResInfo->pRows);
+ pGroupResInfo->pRows = NULL;
return;
}
- int32_t num = taosArrayGetSize(update);
- for (int32_t i = 0; i < num; i++) {
- SResKeyPos* pos = taosArrayGetP(update, i);
- SWinKey winKey = {.ts = *(int64_t*)pos->key, .groupId = pos->groupId};
- taosHashRemove(pStDeleted, &winKey, sizeof(SWinKey));
- }
+ // clear the existed group id
+ pBlock->info.groupId = 0;
+ buildSessionResultDataBlock(pTaskInfo, pState, pBlock, &pOperator->exprSupp, pGroupResInfo);
}
static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
@@ -4349,6 +4052,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
SOptrBasicInfo* pBInfo = &pInfo->binfo;
TSKEY maxTs = INT64_MIN;
+ SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
if (pOperator->status == OP_EXEC_DONE) {
return NULL;
} else if (pOperator->status == OP_RES_TO_RETURN) {
@@ -4357,18 +4061,20 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session");
return pInfo->pDelRes;
}
- doBuildStreamResBlock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
- if (pBInfo->pRes->info.rows == 0 || !hasRemainResults(&pInfo->groupResInfo)) {
- doSetOperatorCompleted(pOperator);
+ doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes);
+ if (pBInfo->pRes->info.rows > 0) {
+ printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session");
+ return pBInfo->pRes;
}
- printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session");
- return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
+
+ doSetOperatorCompleted(pOperator);
+ return NULL;
}
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
- SHashObj* pStUpdated = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
+ SSHashObj* pStUpdated = tSimpleHashInit(64, hashFn);
SOperatorInfo* downstream = pOperator->pDownstream[0];
- SArray* pUpdated = taosArrayInit(16, POINTER_BYTES); // SResKeyPos
+ SArray* pUpdated = taosArrayInit(16, sizeof(SSessionKey)); // SResKeyPos
while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
if (pBlock == NULL) {
@@ -4382,38 +4088,25 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
/*printf("\n\n put tbname %s\n\n", pBlock->info.parTbName);*/
}
- if (pBlock->info.type == STREAM_CLEAR) {
- SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
- doClearSessionWindows(&pInfo->streamAggSup, &pOperator->exprSupp, pBlock, START_TS_COLUMN_INDEX,
- pOperator->exprSupp.numOfExprs, 0, pWins);
- if (IS_FINAL_OP(pInfo)) {
- int32_t childIndex = getChildIndex(pBlock);
- SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex);
- SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info;
- doClearSessionWindows(&pChildInfo->streamAggSup, &pChildOp->exprSupp, pBlock, START_TS_COLUMN_INDEX,
- pChildOp->exprSupp.numOfExprs, 0, NULL);
- rebuildTimeWindow(pInfo, pWins, pOperator->exprSupp.numOfExprs, pOperator, pStUpdated);
- }
- taosArrayDestroy(pWins);
- continue;
- } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
- SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
+ if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
+ pBlock->info.type == STREAM_CLEAR) {
+ SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
// gap must be 0
- doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, 0, pWins, NULL);
+ doDeleteTimeWindows(pAggSup, pBlock, pWins);
+ removeSessionResults(pStUpdated, pWins);
if (IS_FINAL_OP(pInfo)) {
int32_t childIndex = getChildIndex(pBlock);
SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex);
SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info;
// gap must be 0
- doDeleteTimeWindows(&pChildInfo->streamAggSup, pBlock, 0, NULL, NULL);
- rebuildTimeWindow(pInfo, pWins, pOperator->exprSupp.numOfExprs, pOperator, pStUpdated);
+ doDeleteTimeWindows(&pChildInfo->streamAggSup, pBlock, NULL);
+ rebuildSessionWindow(pOperator, pWins, pStUpdated);
}
copyDeleteWindowInfo(pWins, pInfo->pStDeleted);
- removeSessionResults(pStUpdated, pWins);
taosArrayDestroy(pWins);
continue;
} else if (pBlock->info.type == STREAM_GET_ALL) {
- getAllSessionWindow(pInfo->streamAggSup.pResultRows, pUpdated, getResWinForSession);
+ getAllSessionWindow(pAggSup->pResultRows, pStUpdated);
continue;
}
@@ -4421,7 +4114,6 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
SExprSupp* pExprSup = &pInfo->scalarSupp;
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
}
- // the pDataBlock are always the same one, no need to call this again
setInputDataBlock(pOperator, pSup->pCtx, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
doStreamSessionAggImpl(pOperator, pBlock, pStUpdated, pInfo->pStDeleted, IS_FINAL_OP(pInfo));
if (IS_FINAL_OP(pInfo)) {
@@ -4448,39 +4140,121 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
// restore the value
pOperator->status = OP_RES_TO_RETURN;
- closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pUpdated, getResWinForSession,
- pInfo->ignoreExpiredData, NULL);
- closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs, pInfo->ignoreExpiredData, NULL);
+ closeSessionWindow(pAggSup->pResultRows, &pInfo->twAggSup, pStUpdated);
+ closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs);
copyUpdateResult(pStUpdated, pUpdated);
- removeSessionDeleteResults(pUpdated, pInfo->pStDeleted);
- taosHashCleanup(pStUpdated);
-
- finalizeUpdatedResult(pSup->numOfExprs, pInfo->streamAggSup.pResultBuf, pUpdated, pSup->rowEntryInfoOffset);
- initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
+ removeSessionResults(pInfo->pStDeleted, pUpdated);
+ tSimpleHashCleanup(pStUpdated);
+ initGroupResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
+
doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
if (pInfo->pDelRes->info.rows > 0) {
printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session");
return pInfo->pDelRes;
}
- doBuildStreamResBlock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
- printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session");
- return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
+
+ doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes);
+ if (pBInfo->pRes->info.rows > 0) {
+ printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session");
+ return pBInfo->pRes;
+ }
+
+ doSetOperatorCompleted(pOperator);
+ return NULL;
+}
+
+SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
+ SExecTaskInfo* pTaskInfo) {
+ SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
+ int32_t numOfCols = 0;
+ int32_t code = TSDB_CODE_OUT_OF_MEMORY;
+ SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo));
+ SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
+ if (pInfo == NULL || pOperator == NULL) {
+ goto _error;
+ }
+
+ pOperator->pTaskInfo = pTaskInfo;
+
+ initResultSizeInfo(&pOperator->resultInfo, 4096);
+ if (pSessionNode->window.pExprs != NULL) {
+ int32_t numOfScalar = 0;
+ SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar);
+ code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar);
+ if (code != TSDB_CODE_SUCCESS) {
+ goto _error;
+ }
+ }
+ SExprSupp* pSup = &pOperator->exprSupp;
+
+ SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols);
+ SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
+ code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock);
+ if (code != TSDB_CODE_SUCCESS) {
+ goto _error;
+ }
+
+ code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap,
+ pTaskInfo->streamInfo.pState, 0, 0);
+ if (code != TSDB_CODE_SUCCESS) {
+ goto _error;
+ }
+
+ pInfo->twAggSup = (STimeWindowAggSupp){
+ .waterMark = pSessionNode->window.watermark,
+ .calTrigger = pSessionNode->window.triggerType,
+ .maxTs = INT64_MIN,
+ .minTs = INT64_MAX,
+ };
+
+ initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
+
+ pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
+ if (pSessionNode->window.pTsEnd) {
+ pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId;
+ }
+ pInfo->binfo.pRes = pResBlock;
+ pInfo->order = TSDB_ORDER_ASC;
+ _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
+ pInfo->pStDeleted = tSimpleHashInit(64, hashFn);
+ pInfo->pDelIterator = NULL;
+ pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT);
+ pInfo->pChildren = NULL;
+ pInfo->isFinal = false;
+ pInfo->pPhyNode = pPhyNode;
+ pInfo->ignoreExpiredData = pSessionNode->window.igExpired;
+ pInfo->pGroupIdTbNameMap =
+ taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK);
+
+ pOperator->name = "StreamSessionWindowAggOperator";
+ pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION;
+ pOperator->blocking = true;
+ pOperator->status = OP_NOT_OPENED;
+ pOperator->info = pInfo;
+ pOperator->fpSet =
+ createOperatorFpSet(operatorDummyOpenFn, doStreamSessionAgg, NULL, NULL, destroyStreamSessionAggOperatorInfo,
+ aggEncodeResultRow, aggDecodeResultRow, NULL);
+ if (downstream) {
+ initDownStream(downstream, &pInfo->streamAggSup, pInfo->twAggSup.waterMark, pOperator->operatorType,
+ pInfo->primaryTsIndex);
+ code = appendDownstream(pOperator, &downstream, 1);
+ }
+ return pOperator;
+
+_error:
+ if (pInfo != NULL) {
+ destroyStreamSessionAggOperatorInfo(pInfo);
+ }
+
+ taosMemoryFreeClear(pOperator);
+ pTaskInfo->code = code;
+ return NULL;
}
static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) {
- void** pIte = NULL;
- while ((pIte = taosHashIterate(pInfo->streamAggSup.pResultRows, pIte)) != NULL) {
- SArray* pWins = (SArray*)(*pIte);
- int32_t size = taosArrayGetSize(pWins);
- for (int32_t i = 0; i < size; i++) {
- SResultWindowInfo* pWin = (SResultWindowInfo*)taosArrayGet(pWins, i);
- pWin->pos.pageId = -1;
- pWin->pos.offset = -1;
- }
- }
- clearDiskbasedBuf(pInfo->streamAggSup.pResultBuf);
- pInfo->streamAggSup.currentPageId = -1;
+ tSimpleHashClear(pInfo->streamAggSup.pResultRows);
+ streamStateSessionClear(pInfo->streamAggSup.pState);
}
static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
@@ -4488,13 +4262,14 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
SOptrBasicInfo* pBInfo = &pInfo->binfo;
TSKEY maxTs = INT64_MIN;
SExprSupp* pSup = &pOperator->exprSupp;
+ SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
if (pOperator->status == OP_EXEC_DONE) {
return NULL;
}
{
- doBuildStreamResBlock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
+ doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes);
if (pBInfo->pRes->info.rows > 0) {
printDataBlock(pBInfo->pRes, "semi session");
return pBInfo->pRes;
@@ -4502,30 +4277,23 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
if (pInfo->pDelRes->info.rows > 0) {
- printDataBlock(pInfo->pDelRes, "semi session");
+ printDataBlock(pInfo->pDelRes, "semi session delete");
return pInfo->pDelRes;
}
- if (pInfo->pUpdateRes->info.rows > 0 && pInfo->returnUpdate) {
- pInfo->returnUpdate = false;
- // process the rest of the data
- printDataBlock(pInfo->pUpdateRes, "semi session");
- return pInfo->pUpdateRes;
- }
-
if (pOperator->status == OP_RES_TO_RETURN) {
clearFunctionContext(&pOperator->exprSupp);
// semi interval operator clear disk buffer
clearStreamSessionOperator(pInfo);
- pOperator->status = OP_EXEC_DONE;
+ doSetOperatorCompleted(pOperator);
return NULL;
}
}
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
- SHashObj* pStUpdated = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
+ SSHashObj* pStUpdated = tSimpleHashInit(64, hashFn);
SOperatorInfo* downstream = pOperator->pDownstream[0];
- SArray* pUpdated = taosArrayInit(16, POINTER_BYTES);
+ SArray* pUpdated = taosArrayInit(16, sizeof(SSessionKey));
while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
if (pBlock == NULL) {
@@ -4541,24 +4309,17 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
/*printf("\n\n put tbname %s\n\n", pBlock->info.parTbName);*/
}
- if (pBlock->info.type == STREAM_CLEAR) {
- SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
- doClearSessionWindows(&pInfo->streamAggSup, pSup, pBlock, START_TS_COLUMN_INDEX, pSup->numOfExprs, 0, pWins);
- removeSessionResults(pStUpdated, pWins);
- taosArrayDestroy(pWins);
- copyDataBlock(pInfo->pUpdateRes, pBlock);
- pInfo->returnUpdate = true;
- break;
- } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
+ if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
+ pBlock->info.type == STREAM_CLEAR) {
// gap must be 0
SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
- doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, 0, pWins, NULL);
- copyDeleteWindowInfo(pWins, pInfo->pStDeleted);
+ doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins);
removeSessionResults(pStUpdated, pWins);
+ copyDeleteWindowInfo(pWins, pInfo->pStDeleted);
taosArrayDestroy(pWins);
break;
} else if (pBlock->info.type == STREAM_GET_ALL) {
- getAllSessionWindow(pInfo->streamAggSup.pResultRows, pUpdated, getResWinForSession);
+ getAllSessionWindow(pInfo->streamAggSup.pResultRows, pStUpdated);
continue;
}
@@ -4576,15 +4337,13 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
pBInfo->pRes->info.watermark = pInfo->twAggSup.maxTs;
copyUpdateResult(pStUpdated, pUpdated);
- removeSessionDeleteResults(pUpdated, pInfo->pStDeleted);
- taosHashCleanup(pStUpdated);
+ removeSessionResults(pInfo->pStDeleted, pUpdated);
+ tSimpleHashCleanup(pStUpdated);
- finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->streamAggSup.pResultBuf, pUpdated,
- pSup->rowEntryInfoOffset);
- initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
+ initGroupResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
- doBuildStreamResBlock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
+ doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes);
if (pBInfo->pRes->info.rows > 0) {
printDataBlock(pBInfo->pRes, "semi session");
return pBInfo->pRes;
@@ -4592,18 +4351,14 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
if (pInfo->pDelRes->info.rows > 0) {
- printDataBlock(pInfo->pDelRes, "semi session");
+ printDataBlock(pInfo->pDelRes, "semi session delete");
return pInfo->pDelRes;
}
- if (pInfo->pUpdateRes->info.rows > 0 && pInfo->returnUpdate) {
- pInfo->returnUpdate = false;
- // process the rest of the data
- printDataBlock(pInfo->pUpdateRes, "semi session");
- return pInfo->pUpdateRes;
- }
-
- pOperator->status = OP_EXEC_DONE;
+ clearFunctionContext(&pOperator->exprSupp);
+ // semi interval operator clear disk buffer
+ clearStreamSessionOperator(pInfo);
+ doSetOperatorCompleted(pOperator);
return NULL;
}
@@ -4636,11 +4391,14 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream
if (numOfChild > 0) {
pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*));
for (int32_t i = 0; i < numOfChild; i++) {
- SOperatorInfo* pChild = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0);
- if (pChild == NULL) {
+ SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0);
+ if (pChildOp == NULL) {
goto _error;
}
- taosArrayPush(pInfo->pChildren, &pChild);
+ SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info;
+ pChInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE;
+ streamStateSetNumber(pChInfo->streamAggSup.pState, i);
+ taosArrayPush(pInfo->pChildren, &pChildOp);
}
}
return pOperator;
@@ -4649,7 +4407,6 @@ _error:
if (pInfo != NULL) {
destroyStreamSessionAggOperatorInfo(pInfo);
}
-
taosMemoryFreeClear(pOperator);
pTaskInfo->code = code;
return NULL;
@@ -4658,7 +4415,7 @@ _error:
void destroyStreamStateOperatorInfo(void* param) {
SStreamStateAggOperatorInfo* pInfo = (SStreamStateAggOperatorInfo*)param;
cleanupBasicInfo(&pInfo->binfo);
- destroyStateStreamAggSupporter(&pInfo->streamAggSup);
+ destroyStreamAggSupporter(&pInfo->streamAggSup);
cleanupGroupResInfo(&pInfo->groupResInfo);
if (pInfo->pChildren != NULL) {
int32_t size = taosArrayGetSize(pInfo->pChildren);
@@ -4671,151 +4428,75 @@ void destroyStreamStateOperatorInfo(void* param) {
}
colDataDestroy(&pInfo->twAggSup.timeWindowData);
blockDataDestroy(pInfo->pDelRes);
- taosHashCleanup(pInfo->pSeDeleted);
+ tSimpleHashCleanup(pInfo->pSeDeleted);
taosHashCleanup(pInfo->pGroupIdTbNameMap);
- destroySqlFunctionCtx(pInfo->pDummyCtx, 0);
-
taosMemoryFreeClear(param);
}
-int64_t getStateWinTsKey(void* data, int32_t index) {
- SStateWindowInfo* pStateWin = taosArrayGet(data, index);
- return pStateWin->winInfo.win.ekey;
-}
-
-SStateWindowInfo* addNewStateWindow(SArray* pWinInfos, TSKEY ts, char* pKeyData, SColumn* pCol) {
- SStateWindowInfo win = {
- .stateKey.bytes = pCol->bytes,
- .stateKey.type = pCol->type,
- .stateKey.pData = taosMemoryCalloc(1, pCol->bytes),
- .winInfo.pos.offset = -1,
- .winInfo.pos.pageId = -1,
- .winInfo.win.skey = ts,
- .winInfo.win.ekey = ts,
- .winInfo.isOutput = false,
- .winInfo.isClosed = false,
- };
- if (IS_VAR_DATA_TYPE(win.stateKey.type)) {
- varDataCopy(win.stateKey.pData, pKeyData);
- } else {
- memcpy(win.stateKey.pData, pKeyData, win.stateKey.bytes);
- }
- return taosArrayPush(pWinInfos, &win);
-}
-
-SStateWindowInfo* insertNewStateWindow(SArray* pWinInfos, TSKEY ts, char* pKeyData, int32_t index, SColumn* pCol) {
- SStateWindowInfo win = {
- .stateKey.bytes = pCol->bytes,
- .stateKey.type = pCol->type,
- .stateKey.pData = taosMemoryCalloc(1, pCol->bytes),
- .winInfo.pos.offset = -1,
- .winInfo.pos.pageId = -1,
- .winInfo.win.skey = ts,
- .winInfo.win.ekey = ts,
- .winInfo.isOutput = false,
- .winInfo.isClosed = false,
- };
- if (IS_VAR_DATA_TYPE(win.stateKey.type)) {
- varDataCopy(win.stateKey.pData, pKeyData);
- } else {
- memcpy(win.stateKey.pData, pKeyData, win.stateKey.bytes);
- }
- return taosArrayInsert(pWinInfos, index, &win);
-}
-
bool isTsInWindow(SStateWindowInfo* pWin, TSKEY ts) {
- if (pWin->winInfo.win.skey <= ts && ts <= pWin->winInfo.win.ekey) {
+ if (pWin->winInfo.sessionWin.win.skey <= ts && ts <= pWin->winInfo.sessionWin.win.ekey) {
return true;
}
return false;
}
bool isEqualStateKey(SStateWindowInfo* pWin, char* pKeyData) {
- return pKeyData && compareVal(pKeyData, &pWin->stateKey);
+ return pKeyData && compareVal(pKeyData, pWin->pStateKey);
}
-SStateWindowInfo* getStateWindowByTs(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, int32_t* pIndex) {
- SArray* pWinInfos = getWinInfos(pAggSup, groupId);
- pAggSup->pCurWins = pWinInfos;
- int32_t size = taosArrayGetSize(pWinInfos);
- int32_t index = binarySearch(pWinInfos, size, ts, TSDB_ORDER_DESC, getStateWinTsKey);
- SStateWindowInfo* pWin = NULL;
- if (index >= 0) {
- pWin = taosArrayGet(pWinInfos, index);
- if (isTsInWindow(pWin, ts)) {
- *pIndex = index;
- return pWin;
- }
- }
-
- if (index + 1 < size) {
- pWin = taosArrayGet(pWinInfos, index + 1);
- if (isTsInWindow(pWin, ts)) {
- *pIndex = index + 1;
- return pWin;
- }
- }
- *pIndex = 0;
- return NULL;
+bool compareStateKey(void* data, void* key) {
+ SStateKeys* stateKey = (SStateKeys*)key;
+ stateKey->pData = (char*)key + sizeof(SStateKeys);
+ return compareVal(data, stateKey);
}
-SStateWindowInfo* getStateWindow(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData,
- SColumn* pCol, int32_t* pIndex) {
- SArray* pWinInfos = getWinInfos(pAggSup, groupId);
- pAggSup->pCurWins = pWinInfos;
- int32_t size = taosArrayGetSize(pWinInfos);
- if (size == 0) {
- *pIndex = 0;
- return addNewStateWindow(pWinInfos, ts, pKeyData, pCol);
- }
- int32_t index = binarySearch(pWinInfos, size, ts, TSDB_ORDER_DESC, getStateWinTsKey);
- SStateWindowInfo* pWin = NULL;
- if (index >= 0) {
- pWin = taosArrayGet(pWinInfos, index);
- if (isTsInWindow(pWin, ts)) {
- *pIndex = index;
- return pWin;
+void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData,
+ SStateWindowInfo* pCurWin, SStateWindowInfo* pNextWin) {
+ int32_t size = pAggSup->resultRowSize;
+ pCurWin->winInfo.sessionWin.groupId = groupId;
+ pCurWin->winInfo.sessionWin.win.skey = ts;
+ pCurWin->winInfo.sessionWin.win.ekey = ts;
+ int32_t code =
+ streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, pKeyData, pAggSup->stateKeySize,
+ compareStateKey, &pCurWin->winInfo.pOutputBuf, &size);
+ pCurWin->pStateKey =
+ (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize));
+ pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys);
+ pCurWin->pStateKey->type = pAggSup->stateKeyType;
+ pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys);
+ pCurWin->pStateKey->isNull = false;
+
+ if (code == TSDB_CODE_SUCCESS) {
+ pCurWin->winInfo.isOutput = true;
+ } else {
+ if (IS_VAR_DATA_TYPE(pAggSup->stateKeyType)) {
+ varDataCopy(pCurWin->pStateKey->pData, pKeyData);
+ } else {
+ memcpy(pCurWin->pStateKey->pData, pKeyData, pCurWin->pStateKey->bytes);
}
}
- if (index + 1 < size) {
- pWin = taosArrayGet(pWinInfos, index + 1);
- if (isTsInWindow(pWin, ts) || isEqualStateKey(pWin, pKeyData)) {
- *pIndex = index + 1;
- return pWin;
- }
+ pNextWin->winInfo.sessionWin = pCurWin->winInfo.sessionWin;
+ pNextWin->winInfo.pOutputBuf = NULL;
+ SStreamStateCur* pCur = streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->winInfo.sessionWin);
+ code = streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, NULL, 0);
+ if (code != TSDB_CODE_SUCCESS) {
+ SET_SESSION_WIN_INVALID(pNextWin->winInfo);
}
-
- if (index >= 0) {
- pWin = taosArrayGet(pWinInfos, index);
- if (isEqualStateKey(pWin, pKeyData)) {
- *pIndex = index;
- return pWin;
- }
- }
-
- if (index == size - 1) {
- *pIndex = taosArrayGetSize(pWinInfos);
- return addNewStateWindow(pWinInfos, ts, pKeyData, pCol);
- }
- *pIndex = index + 1;
- return insertNewStateWindow(pWinInfos, ts, pKeyData, index + 1, pCol);
+ streamStateFreeCur(pCur);
}
-int32_t updateStateWindowInfo(SArray* pWinInfos, int32_t winIndex, TSKEY* pTs, uint64_t groupId,
+int32_t updateStateWindowInfo(SStateWindowInfo* pWinInfo, SStateWindowInfo* pNextWin, TSKEY* pTs, uint64_t groupId,
SColumnInfoData* pKeyCol, int32_t rows, int32_t start, bool* allEqual,
- SHashObj* pSeDeleted) {
+ SSHashObj* pResultRows, SSHashObj* pSeUpdated, SSHashObj* pSeDeleted) {
*allEqual = true;
- SStateWindowInfo* pWinInfo = taosArrayGet(pWinInfos, winIndex);
for (int32_t i = start; i < rows; ++i) {
char* pKeyData = colDataGetData(pKeyCol, i);
if (!isTsInWindow(pWinInfo, pTs[i])) {
if (isEqualStateKey(pWinInfo, pKeyData)) {
- int32_t size = taosArrayGetSize(pWinInfos);
- if (winIndex + 1 < size) {
- SStateWindowInfo* pNextWin = taosArrayGet(pWinInfos, winIndex + 1);
+ if (IS_VALID_SESSION_WIN(pNextWin->winInfo)) {
// ts belongs to the next window
- if (pTs[i] >= pNextWin->winInfo.win.skey) {
+ if (pTs[i] >= pNextWin->winInfo.sessionWin.win.skey) {
return i - start;
}
}
@@ -4823,15 +4504,15 @@ int32_t updateStateWindowInfo(SArray* pWinInfos, int32_t winIndex, TSKEY* pTs, u
return i - start;
}
}
- if (pWinInfo->winInfo.win.skey > pTs[i]) {
+
+ if (pWinInfo->winInfo.sessionWin.win.skey > pTs[i]) {
if (pSeDeleted && pWinInfo->winInfo.isOutput) {
- SWinKey res = {.ts = pWinInfo->winInfo.win.skey, .groupId = groupId};
- taosHashPut(pSeDeleted, &res, sizeof(SWinKey), &res, sizeof(SWinKey));
- pWinInfo->winInfo.isOutput = false;
+ saveDeleteRes(pSeDeleted, pWinInfo->winInfo.sessionWin);
}
- pWinInfo->winInfo.win.skey = pTs[i];
+ removeSessionResult(pSeUpdated, pResultRows, pWinInfo->winInfo.sessionWin);
+ pWinInfo->winInfo.sessionWin.win.skey = pTs[i];
}
- pWinInfo->winInfo.win.ekey = TMAX(pWinInfo->winInfo.win.ekey, pTs[i]);
+ pWinInfo->winInfo.sessionWin.win.ekey = TMAX(pWinInfo->winInfo.sessionWin.win.ekey, pTs[i]);
if (!isEqualStateKey(pWinInfo, pKeyData)) {
*allEqual = false;
}
@@ -4839,36 +4520,13 @@ int32_t updateStateWindowInfo(SArray* pWinInfos, int32_t winIndex, TSKEY* pTs, u
return rows - start;
}
-static void doClearStateWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SHashObj* pSeUpdated,
- SHashObj* pSeDeleted) {
- SColumnInfoData* pTsColInfo = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
- SColumnInfoData* pGroupColInfo = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
- TSKEY* tsCol = (TSKEY*)pTsColInfo->pData;
- bool allEqual = false;
- int32_t step = 1;
- uint64_t* gpCol = (uint64_t*)pGroupColInfo->pData;
- for (int32_t i = 0; i < pBlock->info.rows; i += step) {
- int32_t winIndex = 0;
- SStateWindowInfo* pCurWin = getStateWindowByTs(pAggSup, tsCol[i], gpCol[i], &winIndex);
- if (!pCurWin) {
- continue;
- }
- updateSessionWindowInfo(&pCurWin->winInfo, tsCol, NULL, 0, pBlock->info.rows, i, 0, NULL);
- taosHashRemove(pSeUpdated, &pCurWin->winInfo.pos, sizeof(SResultRowPosition));
- deleteWindow(pAggSup->pCurWins, winIndex, destroyStateWinInfo);
- }
-}
-
-static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SHashObj* pSeUpdated,
- SHashObj* pStDeleted) {
+static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pSeUpdated,
+ SSHashObj* pStDeleted) {
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStreamStateAggOperatorInfo* pInfo = pOperator->info;
- bool masterScan = true;
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
int64_t groupId = pSDataBlock->info.groupId;
int64_t code = TSDB_CODE_SUCCESS;
- int32_t step = 1;
- bool ascScan = true;
TSKEY* tsCols = NULL;
SResultRow* pResult = NULL;
int32_t winRows = 0;
@@ -4880,39 +4538,44 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl
}
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
- blockDataEnsureCapacity(pAggSup->pScanBlock, pSDataBlock->info.rows);
+ int32_t rows = pSDataBlock->info.rows;
+ blockDataEnsureCapacity(pAggSup->pScanBlock, rows);
SColumnInfoData* pKeyColInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->stateCol.slotId);
- for (int32_t i = 0; i < pSDataBlock->info.rows; i += winRows) {
+ for (int32_t i = 0; i < rows; i += winRows) {
if (pInfo->ignoreExpiredData && isOverdue(tsCols[i], &pInfo->twAggSup)) {
i++;
continue;
}
- char* pKeyData = colDataGetData(pKeyColInfo, i);
- int32_t winIndex = 0;
- bool allEqual = true;
- SStateWindowInfo* pCurWin = getStateWindow(pAggSup, tsCols[i], groupId, pKeyData, &pInfo->stateCol, &winIndex);
- winRows = updateStateWindowInfo(pAggSup->pCurWins, winIndex, tsCols, groupId, pKeyColInfo, pSDataBlock->info.rows,
- i, &allEqual, pStDeleted);
+ char* pKeyData = colDataGetData(pKeyColInfo, i);
+ int32_t winIndex = 0;
+ bool allEqual = true;
+ SStateWindowInfo curWin = {0};
+ SStateWindowInfo nextWin = {0};
+ setStateOutputBuf(pAggSup, tsCols[i], groupId, pKeyData, &curWin, &nextWin);
+ setSessionWinOutputInfo(pSeUpdated, &curWin.winInfo);
+ winRows = updateStateWindowInfo(&curWin, &nextWin, tsCols, groupId, pKeyColInfo, rows, i, &allEqual,
+ pAggSup->pResultRows, pSeUpdated, pStDeleted);
if (!allEqual) {
uint64_t uid = 0;
- appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &pCurWin->winInfo.win.skey, &pCurWin->winInfo.win.ekey,
- &uid, &groupId, NULL);
- taosHashRemove(pSeUpdated, &pCurWin->winInfo.pos, sizeof(SResultRowPosition));
- deleteWindow(pAggSup->pCurWins, winIndex, destroyStateWinInfo);
+ appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey,
+ &curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL);
+ tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey));
+ doDeleteSessionWindow(pAggSup, &curWin.winInfo.sessionWin);
+ releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)curWin.winInfo.pOutputBuf);
continue;
}
- code = doOneStateWindowAgg(pInfo, pSDataBlock, &pCurWin->winInfo, &pResult, i, winRows, numOfOutput, pOperator);
+ code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput,
+ pOperator);
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
- pCurWin->winInfo.isClosed = false;
+ saveSessionOutputBuf(pAggSup, &curWin.winInfo);
+
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
- SWinKey value = {.ts = pCurWin->winInfo.win.skey, .groupId = groupId};
- code = taosHashPut(pSeUpdated, &pCurWin->winInfo.pos, sizeof(SResultRowPosition), &value, sizeof(SWinKey));
+ code = saveResult(curWin.winInfo, pSeUpdated);
if (code != TSDB_CODE_SUCCESS) {
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
- pCurWin->winInfo.isOutput = true;
}
}
}
@@ -4929,21 +4592,24 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
if (pOperator->status == OP_RES_TO_RETURN) {
doBuildDeleteDataBlock(pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
if (pInfo->pDelRes->info.rows > 0) {
- printDataBlock(pInfo->pDelRes, "single state");
+ printDataBlock(pInfo->pDelRes, "single state delete");
return pInfo->pDelRes;
}
- doBuildStreamResBlock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
- if (pBInfo->pRes->info.rows == 0 || !hasRemainResults(&pInfo->groupResInfo)) {
- doSetOperatorCompleted(pOperator);
+
+ doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes);
+ if (pBInfo->pRes->info.rows > 0) {
+ printDataBlock(pBInfo->pRes, "single state");
+ return pBInfo->pRes;
}
- printDataBlock(pBInfo->pRes, "single state");
- return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
+
+ doSetOperatorCompleted(pOperator);
+ return NULL;
}
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
- SHashObj* pSeUpdated = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
+ SSHashObj* pSeUpdated = tSimpleHashInit(64, hashFn);
SOperatorInfo* downstream = pOperator->pDownstream[0];
- SArray* pUpdated = taosArrayInit(16, POINTER_BYTES);
+ SArray* pUpdated = taosArrayInit(16, sizeof(SSessionKey));
while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
if (pBlock == NULL) {
@@ -4951,18 +4617,16 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
}
printDataBlock(pBlock, "single state recv");
- if (pBlock->info.type == STREAM_CLEAR) {
- doClearStateWindows(&pInfo->streamAggSup, pBlock, pSeUpdated, pInfo->pSeDeleted);
- continue;
- } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
- SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
- doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, 0, pWins, destroyStateWinInfo);
- copyDeleteWindowInfo(pWins, pInfo->pSeDeleted);
+ if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
+ pBlock->info.type == STREAM_CLEAR) {
+ SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
+ doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins);
removeSessionResults(pSeUpdated, pWins);
+ copyDeleteWindowInfo(pWins, pInfo->pSeDeleted);
taosArrayDestroy(pWins);
continue;
} else if (pBlock->info.type == STREAM_GET_ALL) {
- getAllSessionWindow(pInfo->streamAggSup.pResultRows, pUpdated, getResWinForState);
+ getAllSessionWindow(pInfo->streamAggSup.pResultRows, pSeUpdated);
continue;
}
@@ -4979,28 +4643,27 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
// restore the value
pOperator->status = OP_RES_TO_RETURN;
- closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pUpdated, getResWinForState,
- pInfo->ignoreExpiredData, destroyStateWinInfo);
- // closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs, pInfo->ignoreExpiredData, destroyStateWinInfo);
+ closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pSeUpdated);
copyUpdateResult(pSeUpdated, pUpdated);
- taosHashCleanup(pSeUpdated);
+ removeSessionResults(pInfo->pSeDeleted, pUpdated);
+ tSimpleHashCleanup(pSeUpdated);
- finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->streamAggSup.pResultBuf, pUpdated,
- pSup->rowEntryInfoOffset);
- initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
+ initGroupResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
+
doBuildDeleteDataBlock(pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
if (pInfo->pDelRes->info.rows > 0) {
- printDataBlock(pInfo->pDelRes, "single state");
+ printDataBlock(pInfo->pDelRes, "single state delete");
return pInfo->pDelRes;
}
- doBuildStreamResBlock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
- printDataBlock(pBInfo->pRes, "single state");
- return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
-}
-int32_t initStateAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
- return initStreamAggSupporter(pSup, pKey, pCtx, numOfOutput, sizeof(SStateWindowInfo));
+ doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes);
+ if (pBInfo->pRes->info.rows > 0) {
+ printDataBlock(pBInfo->pRes, "single state");
+ return pBInfo->pRes;
+ }
+ doSetOperatorCompleted(pOperator);
+ return NULL;
}
SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
@@ -5017,11 +4680,6 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
goto _error;
}
- SExprSupp* pSup = &pOperator->exprSupp;
-
- int32_t numOfCols = 0;
- SExprInfo* pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &numOfCols);
-
pInfo->stateCol = extractColumnFromColumnNode(pColNode);
initResultSizeInfo(&pOperator->resultInfo, 4096);
if (pStateNode->window.pExprs != NULL) {
@@ -5033,7 +4691,6 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
}
}
- initResultRowInfo(&pInfo->binfo.resultRowInfo);
pInfo->twAggSup = (STimeWindowAggSupp){
.waterMark = pStateNode->window.watermark,
.calTrigger = pStateNode->window.triggerType,
@@ -5042,27 +4699,25 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
};
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
+ SExprSupp* pSup = &pOperator->exprSupp;
+ int32_t numOfCols = 0;
+ SExprInfo* pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &numOfCols);
SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
-
- code = initStateAggSupporter(&pInfo->streamAggSup, "StreamStateAggOperatorInfo", pSup->pCtx, numOfCols);
+ int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes;
+ int16_t type = pColNode->node.resType.type;
+ code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize,
+ type);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
- pInfo->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfCols, sizeof(SqlFunctionCtx));
- if (pInfo->pDummyCtx == NULL) {
- goto _error;
- }
-
- initDummyFunction(pInfo->pDummyCtx, pSup->pCtx, numOfCols);
pInfo->primaryTsIndex = tsSlotId;
- pInfo->order = TSDB_ORDER_ASC;
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
- pInfo->pSeDeleted = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
+ pInfo->pSeDeleted = tSimpleHashInit(64, hashFn);
pInfo->pDelIterator = NULL;
pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT);
pInfo->pChildren = NULL;
@@ -5079,7 +4734,7 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
pOperator->info = pInfo;
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStreamStateAgg, NULL, NULL,
destroyStreamStateOperatorInfo, aggEncodeResultRow, aggDecodeResultRow, NULL);
- initDownStream(downstream, &pInfo->streamAggSup, 0, pInfo->twAggSup.waterMark, pOperator->operatorType,
+ initDownStream(downstream, &pInfo->streamAggSup, pInfo->twAggSup.waterMark, pOperator->operatorType,
pInfo->primaryTsIndex);
code = appendDownstream(pOperator, &downstream, 1);
if (code != TSDB_CODE_SUCCESS) {
@@ -5616,8 +5271,8 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SMerge
goto _error;
}
- int32_t num = 0;
- SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
+ int32_t num = 0;
+ SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num);
SInterval interval = {.interval = pIntervalPhyNode->interval,
.sliding = pIntervalPhyNode->sliding,
diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c
index 7077a9b780..4dca89944a 100644
--- a/source/libs/function/src/builtinsimpl.c
+++ b/source/libs/function/src/builtinsimpl.c
@@ -2527,6 +2527,8 @@ int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
int32_t start = pInput->startRowIndex;
if (pInfo->algo == APERCT_ALGO_TDIGEST) {
+ buildTDigestInfo(pInfo);
+ tdigestAutoFill(pInfo->pTDigest, COMPRESSION);
for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
@@ -2540,12 +2542,11 @@ int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
tdigestAdd(pInfo->pTDigest, v, w);
}
} else {
- qDebug("%s before add %d elements into histogram, total:%d, numOfEntry:%d, pHisto:%p, elems: %p", __FUNCTION__,
- numOfElems, pInfo->pHisto->numOfElems, pInfo->pHisto->numOfEntries, pInfo->pHisto, pInfo->pHisto->elems);
-
// might be a race condition here that pHisto can be overwritten or setup function
// has not been called, need to relink the buffer pHisto points to.
buildHistogramInfo(pInfo);
+ qDebug("%s before add %d elements into histogram, total:%d, numOfEntry:%d, pHisto:%p, elems: %p", __FUNCTION__,
+ numOfElems, pInfo->pHisto->numOfElems, pInfo->pHisto->numOfEntries, pInfo->pHisto, pInfo->pHisto->elems);
for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
@@ -2579,8 +2580,9 @@ static void apercentileTransferInfo(SAPercentileInfo* pInput, SAPercentileInfo*
buildTDigestInfo(pOutput);
TDigest* pTDigest = pOutput->pTDigest;
+ tdigestAutoFill(pTDigest, COMPRESSION);
- if (pTDigest->num_centroids <= 0) {
+ if (pTDigest->num_centroids <= 0 && pTDigest->num_buffered_pts == 0) {
memcpy(pTDigest, pInput->pTDigest, (size_t)TDIGEST_SIZE(COMPRESSION));
tdigestAutoFill(pTDigest, COMPRESSION);
} else {
@@ -2652,6 +2654,7 @@ int32_t apercentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
if (pInfo->algo == APERCT_ALGO_TDIGEST) {
buildTDigestInfo(pInfo);
+ tdigestAutoFill(pInfo->pTDigest, COMPRESSION);
if (pInfo->pTDigest->size > 0) {
pInfo->result = tdigestQuantile(pInfo->pTDigest, pInfo->percent / 100);
} else { // no need to free
@@ -5356,16 +5359,14 @@ int32_t modeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
int32_t maxCount = 0;
for (int32_t i = 0; i < pInfo->numOfPoints; ++i) {
SModeItem* pItem = (SModeItem*)(pInfo->pItems + i * (sizeof(SModeItem) + pInfo->colBytes));
- if (pItem->count > maxCount) {
+ if (pItem->count >= maxCount) {
maxCount = pItem->count;
resIndex = i;
- } else if (pItem->count == maxCount) {
- resIndex = -1;
}
}
SModeItem* pResItem = (SModeItem*)(pInfo->pItems + resIndex * (sizeof(SModeItem) + pInfo->colBytes));
- colDataAppend(pCol, currentRow, pResItem->data, (resIndex == -1) ? true : false);
+ colDataAppend(pCol, currentRow, pResItem->data, (maxCount == 0) ? true : false);
return pResInfo->numOfRes;
}
diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c
index d6110d9fcd..ccae1f54be 100644
--- a/source/libs/planner/src/planOptimizer.c
+++ b/source/libs/planner/src/planOptimizer.c
@@ -124,8 +124,8 @@ static void optSetParentOrder(SLogicNode* pNode, EOrder order) {
EDealRes scanPathOptHaveNormalColImpl(SNode* pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
- *((bool*)pContext) =
- (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType);
+ *((bool*)pContext) =
+ (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType);
return *((bool*)pContext) ? DEAL_RES_END : DEAL_RES_IGNORE_CHILD;
}
return DEAL_RES_CONTINUE;
@@ -1520,11 +1520,15 @@ static bool partTagsHasIndefRowsSelectFunc(SNodeList* pFuncs) {
return false;
}
-static int32_t partTagsRewriteGroupTagsToFuncs(SNodeList* pGroupTags, SNodeList* pAggFuncs) {
+static int32_t partTagsRewriteGroupTagsToFuncs(SNodeList* pGroupTags, int32_t start, SNodeList* pAggFuncs) {
bool hasIndefRowsSelectFunc = partTagsHasIndefRowsSelectFunc(pAggFuncs);
int32_t code = TSDB_CODE_SUCCESS;
+ int32_t index = 0;
SNode* pNode = NULL;
FOREACH(pNode, pGroupTags) {
+ if (index++ < start) {
+ continue;
+ }
if (hasIndefRowsSelectFunc) {
code = nodesListStrictAppend(pAggFuncs, partTagsCreateWrapperFunc("_select_value", pNode));
} else {
@@ -1559,20 +1563,35 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
}
} else {
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
+ int32_t start = -1;
SNode* pGroupKey = NULL;
FOREACH(pGroupKey, pAgg->pGroupKeys) {
- code = nodesListMakeStrictAppend(
- &pScan->pGroupTags, nodesCloneNode(nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0)));
+ SNode* pGroupExpr = nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0);
+ if (NULL != pScan->pGroupTags) {
+ SNode* pGroupTag = NULL;
+ FOREACH(pGroupTag, pScan->pGroupTags) {
+ if (nodesEqualNode(pGroupTag, pGroupExpr)) {
+ continue;
+ }
+ }
+ }
+ if (start < 0) {
+ start = LIST_LENGTH(pScan->pGroupTags);
+ }
+ code = nodesListMakeStrictAppend(&pScan->pGroupTags, nodesCloneNode(pGroupExpr));
if (TSDB_CODE_SUCCESS != code) {
break;
}
}
NODES_DESTORY_LIST(pAgg->pGroupKeys);
- code = partTagsRewriteGroupTagsToFuncs(pScan->pGroupTags, pAgg->pAggFuncs);
+ if (TSDB_CODE_SUCCESS == code && start >= 0) {
+ code = partTagsRewriteGroupTagsToFuncs(pScan->pGroupTags, start, pAgg->pAggFuncs);
+ }
}
if (TSDB_CODE_SUCCESS == code) {
code = partTagsOptRebuildTbanme(pScan->pGroupTags);
}
+ pCxt->optimized = true;
return code;
}
diff --git a/source/libs/planner/test/planPartByTest.cpp b/source/libs/planner/test/planPartByTest.cpp
index 48ab1e1ac2..3d0467dffe 100644
--- a/source/libs/planner/test/planPartByTest.cpp
+++ b/source/libs/planner/test/planPartByTest.cpp
@@ -61,6 +61,8 @@ TEST_F(PlanPartitionByTest, withGroupBy) {
run("SELECT COUNT(*) FROM t1 PARTITION BY c1 GROUP BY c2");
run("SELECT TBNAME, c1 FROM st1 PARTITION BY TBNAME GROUP BY c1");
+
+ run("SELECT COUNT(*) FROM t1 PARTITION BY TBNAME GROUP BY TBNAME");
}
TEST_F(PlanPartitionByTest, withTimeLineFunc) {
diff --git a/source/libs/qcom/src/queryUtil.c b/source/libs/qcom/src/queryUtil.c
index a917397d02..618f597d72 100644
--- a/source/libs/qcom/src/queryUtil.c
+++ b/source/libs/qcom/src/queryUtil.c
@@ -357,8 +357,7 @@ char* parseTagDatatoJson(void* p) {
for (int j = 0; j < nCols; ++j) {
STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, j);
// json key encode by binary
- memset(tagJsonKey, 0, sizeof(tagJsonKey));
- memcpy(tagJsonKey, pTagVal->pKey, strlen(pTagVal->pKey));
+ tstrncpy(tagJsonKey, pTagVal->pKey, sizeof(tagJsonKey));
// json value
char type = pTagVal->type;
if (type == TSDB_DATA_TYPE_NULL) {
diff --git a/source/libs/qcom/src/querymsg.c b/source/libs/qcom/src/querymsg.c
index a6f26088de..fadd07a9f3 100644
--- a/source/libs/qcom/src/querymsg.c
+++ b/source/libs/qcom/src/querymsg.c
@@ -173,7 +173,7 @@ int32_t queryBuildGetDBCfgMsg(void *input, char **msg, int32_t msgSize, int32_t
}
SDbCfgReq dbCfgReq = {0};
- strcpy(dbCfgReq.db, input);
+ strncpy(dbCfgReq.db, input, sizeof(dbCfgReq.db) - 1);
int32_t bufLen = tSerializeSDbCfgReq(NULL, 0, &dbCfgReq);
void *pBuf = (*mallcFp)(bufLen);
@@ -191,7 +191,7 @@ int32_t queryBuildGetIndexMsg(void *input, char **msg, int32_t msgSize, int32_t
}
SUserIndexReq indexReq = {0};
- strcpy(indexReq.indexFName, input);
+ strncpy(indexReq.indexFName, input, sizeof(indexReq.indexFName) - 1);
int32_t bufLen = tSerializeSUserIndexReq(NULL, 0, &indexReq);
void *pBuf = (*mallcFp)(bufLen);
@@ -233,7 +233,7 @@ int32_t queryBuildGetUserAuthMsg(void *input, char **msg, int32_t msgSize, int32
}
SGetUserAuthReq req = {0};
- strncpy(req.user, input, sizeof(req.user));
+ strncpy(req.user, input, sizeof(req.user) - 1);
int32_t bufLen = tSerializeSGetUserAuthReq(NULL, 0, &req);
void *pBuf = (*mallcFp)(bufLen);
@@ -251,7 +251,7 @@ int32_t queryBuildGetTbIndexMsg(void *input, char **msg, int32_t msgSize, int32_
}
STableIndexReq indexReq = {0};
- strcpy(indexReq.tbFName, input);
+ strncpy(indexReq.tbFName, input, sizeof(indexReq.tbFName) - 1);
int32_t bufLen = tSerializeSTableIndexReq(NULL, 0, &indexReq);
void *pBuf = (*mallcFp)(bufLen);
@@ -271,8 +271,8 @@ int32_t queryBuildGetTbCfgMsg(void *input, char **msg, int32_t msgSize, int32_t
SBuildTableInput *pInput = input;
STableCfgReq cfgReq = {0};
cfgReq.header.vgId = pInput->vgId;
- strncpy(cfgReq.dbFName, pInput->dbFName, sizeof(cfgReq.dbFName));
- strncpy(cfgReq.tbName, pInput->tbName, sizeof(cfgReq.tbName));
+ strncpy(cfgReq.dbFName, pInput->dbFName, sizeof(cfgReq.dbFName) - 1);
+ strncpy(cfgReq.tbName, pInput->tbName, sizeof(cfgReq.tbName) - 1);
int32_t bufLen = tSerializeSTableCfgReq(NULL, 0, &cfgReq);
void *pBuf = (*mallcFp)(bufLen);
diff --git a/source/libs/qworker/src/qwUtil.c b/source/libs/qworker/src/qwUtil.c
index 3038b87930..e9ded9b269 100644
--- a/source/libs/qworker/src/qwUtil.c
+++ b/source/libs/qworker/src/qwUtil.c
@@ -412,7 +412,7 @@ void qwSetHbParam(int64_t refId, SQWHbParam **pParam) {
while (true) {
paramIdx = atomic_load_32(&gQwMgmt.paramIdx);
if (paramIdx == tListLen(gQwMgmt.param)) {
- newParamIdx = 0;
+ newParamIdx = 1;
} else {
newParamIdx = paramIdx + 1;
}
@@ -422,6 +422,10 @@ void qwSetHbParam(int64_t refId, SQWHbParam **pParam) {
}
}
+ if (paramIdx == tListLen(gQwMgmt.param)) {
+ paramIdx = 0;
+ }
+
gQwMgmt.param[paramIdx].qwrId = gQwMgmt.qwRef;
gQwMgmt.param[paramIdx].refId = refId;
diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c
index 0ff40f3b9a..3df16563e2 100644
--- a/source/libs/qworker/src/qworker.c
+++ b/source/libs/qworker/src/qworker.c
@@ -398,7 +398,6 @@ int32_t qwHandlePrePhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inpu
if (QW_EVENT_PROCESSED(ctx, QW_EVENT_DROP)) {
QW_TASK_ELOG("task already dropped at wrong phase %s", qwPhaseStr(phase));
QW_ERR_JRET(TSDB_CODE_QRY_TASK_STATUS_ERROR);
- break;
}
if (QW_EVENT_RECEIVED(ctx, QW_EVENT_DROP)) {
diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c
index 1f09fd4799..cc1949f17d 100644
--- a/source/libs/scalar/src/scalar.c
+++ b/source/libs/scalar/src/scalar.c
@@ -629,6 +629,8 @@ _return:
sclFreeParam(pWhen);
sclFreeParam(pThen);
+ taosMemoryFree(pWhen);
+ taosMemoryFree(pThen);
SCL_RET(code);
}
@@ -664,6 +666,8 @@ int32_t sclWalkWhenList(SScalarCtx *ctx, SNodeList* pList, struct SListCell* pCe
sclFreeParam(pWhen);
sclFreeParam(pThen);
+ taosMemoryFreeClear(pWhen);
+ taosMemoryFreeClear(pThen);
}
if (pElse) {
@@ -688,6 +692,8 @@ _return:
sclFreeParam(pWhen);
sclFreeParam(pThen);
+ taosMemoryFree(pWhen);
+ taosMemoryFree(pThen);
SCL_RET(code);
}
@@ -929,6 +935,10 @@ int32_t sclExecCaseWhen(SCaseWhenNode *node, SScalarCtx *ctx, SScalarParam *outp
sclFreeParam(&comp);
sclFreeParam(pWhen);
sclFreeParam(pThen);
+ taosMemoryFree(pCase);
+ taosMemoryFree(pElse);
+ taosMemoryFree(pWhen);
+ taosMemoryFree(pThen);
return TSDB_CODE_SUCCESS;
@@ -940,6 +950,10 @@ _return:
sclFreeParam(pWhen);
sclFreeParam(pThen);
sclFreeParam(output);
+ taosMemoryFree(pCase);
+ taosMemoryFree(pElse);
+ taosMemoryFree(pWhen);
+ taosMemoryFree(pThen);
SCL_RET(code);
}
diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c
index 22e9fb4305..f089bad04e 100644
--- a/source/libs/scalar/src/sclvector.c
+++ b/source/libs/scalar/src/sclvector.c
@@ -654,7 +654,7 @@ int32_t vectorConvertSingleColImpl(const SScalarParam* pIn, SScalarParam* pOut,
return TSDB_CODE_APP_ERROR;
}
- int32_t rstart = startIndex >= 0 ? startIndex : 0;
+ int32_t rstart = (startIndex >= 0 && startIndex < pIn->numOfRows) ? startIndex : 0;
int32_t rend = numOfRows > 0 ? rstart + numOfRows - 1 : rstart + pIn->numOfRows - 1;
SSclVectorConvCtx cCtx = {pIn, pOut, rstart, rend, pInputCol->info.type, pOutputCol->info.type};
diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c
index c641b88152..b585373b0a 100644
--- a/source/libs/scheduler/src/schTask.c
+++ b/source/libs/scheduler/src/schTask.c
@@ -430,7 +430,8 @@ int32_t schHandleRedirect(SSchJob *pJob, SSchTask *pTask, SDataBuf *pData, int32
if (SCH_IS_DATA_BIND_TASK(pTask)) {
if (NULL == pData->pEpSet) {
SCH_TASK_ELOG("no epset updated while got error %s", tstrerror(rspCode));
- SCH_ERR_JRET(rspCode);
+ code = rspCode;
+ goto _return;
}
}
diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c
index c0ed135d74..6991f00bb7 100644
--- a/source/libs/stream/src/streamState.c
+++ b/source/libs/stream/src/streamState.c
@@ -24,6 +24,40 @@ typedef struct SStateKey {
int64_t opNum;
} SStateKey;
+typedef struct SStateSessionKey {
+ SSessionKey key;
+ int64_t opNum;
+} SStateSessionKey;
+
+static inline int sessionKeyCmpr(const SSessionKey* pWin1, const SSessionKey* pWin2) {
+ if (pWin1->groupId > pWin2->groupId) {
+ return 1;
+ } else if (pWin1->groupId < pWin2->groupId) {
+ return -1;
+ }
+
+ if (pWin1->win.skey > pWin2->win.ekey) {
+ return 1;
+ } else if (pWin1->win.ekey < pWin2->win.skey) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static inline int stateSessionKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) {
+ SStateSessionKey* pWin1 = (SStateSessionKey*)pKey1;
+ SStateSessionKey* pWin2 = (SStateSessionKey*)pKey2;
+
+ if (pWin1->opNum > pWin2->opNum) {
+ return 1;
+ } else if (pWin1->opNum < pWin2->opNum) {
+ return -1;
+ }
+
+ return sessionKeyCmpr(&pWin1->key, &pWin2->key);
+}
+
static inline int stateKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) {
SStateKey* pWin1 = (SStateKey*)pKey1;
SStateKey* pWin2 = (SStateKey*)pKey2;
@@ -79,6 +113,11 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath, int
goto _err;
}
+ if (tdbTbOpen("session.state.db", sizeof(SStateSessionKey), -1, stateSessionKeyCmpr, pState->db,
+ &pState->pSessionStateDb) < 0) {
+ goto _err;
+ }
+
if (tdbTbOpen("func.state.db", sizeof(STupleKey), -1, STupleKeyCmpr, pState->db, &pState->pFuncStateDb) < 0) {
goto _err;
}
@@ -95,6 +134,7 @@ _err:
tdbTbClose(pState->pStateDb);
tdbTbClose(pState->pFuncStateDb);
tdbTbClose(pState->pFillStateDb);
+ tdbTbClose(pState->pSessionStateDb);
tdbClose(pState->db);
taosMemoryFree(pState);
return NULL;
@@ -105,6 +145,7 @@ void streamStateClose(SStreamState* pState) {
tdbTbClose(pState->pStateDb);
tdbTbClose(pState->pFuncStateDb);
tdbTbClose(pState->pFillStateDb);
+ tdbTbClose(pState->pSessionStateDb);
tdbClose(pState->db);
taosMemoryFree(pState);
@@ -241,11 +282,11 @@ SStreamStateCur* streamStateGetCur(SStreamState* pState, const SWinKey* key) {
if (pCur == NULL) return NULL;
tdbTbcOpen(pState->pStateDb, &pCur->pCur, NULL);
- int32_t c;
+ int32_t c = 0;
SStateKey sKey = {.key = *key, .opNum = pState->number};
tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateKey), &c);
if (c != 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
pCur->number = pState->number;
@@ -257,7 +298,7 @@ SStreamStateCur* streamStateFillGetCur(SStreamState* pState, const SWinKey* key)
if (pCur == NULL) return NULL;
tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL);
- int32_t c;
+ int32_t c = 0;
tdbTbcMoveTo(pCur->pCur, key, sizeof(SWinKey), &c);
if (c != 0) {
streamStateFreeCur(pCur);
@@ -348,21 +389,21 @@ SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key
}
pCur->number = pState->number;
if (tdbTbcOpen(pState->pStateDb, &pCur->pCur, NULL) < 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
SStateKey sKey = {.key = *key, .opNum = pState->number};
- int32_t c;
+ int32_t c = 0;
if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateKey), &c) < 0) {
tdbTbcClose(pCur->pCur);
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
if (c > 0) return pCur;
if (tdbTbcMoveToNext(pCur->pCur) < 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
@@ -375,20 +416,20 @@ SStreamStateCur* streamStateFillSeekKeyNext(SStreamState* pState, const SWinKey*
return NULL;
}
if (tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL) < 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
- int32_t c;
+ int32_t c = 0;
if (tdbTbcMoveTo(pCur->pCur, key, sizeof(SWinKey), &c) < 0) {
tdbTbcClose(pCur->pCur);
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
if (c > 0) return pCur;
if (tdbTbcMoveToNext(pCur->pCur) < 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
@@ -401,20 +442,20 @@ SStreamStateCur* streamStateFillSeekKeyPrev(SStreamState* pState, const SWinKey*
return NULL;
}
if (tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL) < 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
- int32_t c;
+ int32_t c = 0;
if (tdbTbcMoveTo(pCur->pCur, key, sizeof(SWinKey), &c) < 0) {
tdbTbcClose(pCur->pCur);
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
if (c < 0) return pCur;
if (tdbTbcMoveToPrev(pCur->pCur) < 0) {
- taosMemoryFree(pCur);
+ streamStateFreeCur(pCur);
return NULL;
}
@@ -445,3 +486,229 @@ void streamStateFreeCur(SStreamStateCur* pCur) {
}
void streamFreeVal(void* val) { tdbFree(val); }
+
+int32_t streamStateSessionPut(SStreamState* pState, const SSessionKey* key, const void* value, int32_t vLen) {
+ SStateSessionKey sKey = {.key = *key, .opNum = pState->number};
+ return tdbTbUpsert(pState->pSessionStateDb, &sKey, sizeof(SStateSessionKey), value, vLen, &pState->txn);
+}
+
+SStreamStateCur* streamStateSessionGetRanomCur(SStreamState* pState, const SSessionKey* key) {
+ SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur));
+ if (pCur == NULL) return NULL;
+ tdbTbcOpen(pState->pSessionStateDb, &pCur->pCur, NULL);
+
+ int32_t c = 0;
+ SStateSessionKey sKey = {.key = *key, .opNum = pState->number};
+ tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c);
+ if (c != 0) {
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+ pCur->number = pState->number;
+ return pCur;
+}
+
+int32_t streamStateSessionGet(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen) {
+ SStreamStateCur* pCur = streamStateSessionGetRanomCur(pState, key);
+ void* tmp = NULL;
+ if (streamStateSessionGetKVByCur(pCur, key, (const void**)&tmp, pVLen) == 0) {
+ *pVal = tdbRealloc(NULL, *pVLen);
+ memcpy(*pVal, tmp, *pVLen);
+ streamStateFreeCur(pCur);
+ return 0;
+ }
+ streamStateFreeCur(pCur);
+ return -1;
+}
+
+int32_t streamStateSessionDel(SStreamState* pState, const SSessionKey* key) {
+ SStateSessionKey sKey = {.key = *key, .opNum = pState->number};
+ return tdbTbDelete(pState->pSessionStateDb, &sKey, sizeof(SStateSessionKey), &pState->txn);
+}
+
+SStreamStateCur* streamStateSessionSeekKeyPrev(SStreamState* pState, const SSessionKey* key) {
+ SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur));
+ if (pCur == NULL) {
+ return NULL;
+ }
+ pCur->number = pState->number;
+ if (tdbTbcOpen(pState->pSessionStateDb, &pCur->pCur, NULL) < 0) {
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+
+ SStateSessionKey sKey = {.key = *key, .opNum = pState->number};
+ int32_t c = 0;
+ if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c) < 0) {
+ tdbTbcClose(pCur->pCur);
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+ if (c > 0) return pCur;
+
+ if (tdbTbcMoveToPrev(pCur->pCur) < 0) {
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+
+ return pCur;
+}
+
+SStreamStateCur* streamStateSessionSeekKeyNext(SStreamState* pState, const SSessionKey* key) {
+ SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur));
+ if (pCur == NULL) {
+ return NULL;
+ }
+ pCur->number = pState->number;
+ if (tdbTbcOpen(pState->pSessionStateDb, &pCur->pCur, NULL) < 0) {
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+
+ SStateSessionKey sKey = {.key = *key, .opNum = pState->number};
+ int32_t c = 0;
+ if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c) < 0) {
+ tdbTbcClose(pCur->pCur);
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+ if (c > 0) return pCur;
+
+ if (tdbTbcMoveToNext(pCur->pCur) < 0) {
+ streamStateFreeCur(pCur);
+ return NULL;
+ }
+
+ return pCur;
+}
+
+int32_t streamStateSessionGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, const void** pVal, int32_t* pVLen) {
+ if (!pCur) {
+ return -1;
+ }
+ const SStateSessionKey* pKTmp = NULL;
+ int32_t kLen;
+ if (tdbTbcGet(pCur->pCur, (const void**)&pKTmp, &kLen, pVal, pVLen) < 0) {
+ return -1;
+ }
+ if (pKTmp->opNum != pCur->number) {
+ return -1;
+ }
+ if (pKey->groupId != 0 && pKey->groupId != pKTmp->key.groupId) {
+ return -1;
+ }
+ *pKey = pKTmp->key;
+ return 0;
+}
+
+int32_t streamStateSessionClear(SStreamState* pState) {
+ SSessionKey key = {.win.skey = 0, .win.ekey = 0, .groupId = 0};
+ streamStateSessionPut(pState, &key, NULL, 0);
+ SStreamStateCur* pCur = streamStateSessionSeekKeyNext(pState, &key);
+ while (1) {
+ SSessionKey delKey = {0};
+ void* buf = NULL;
+ int32_t size = 0;
+ int32_t code = streamStateSessionGetKVByCur(pCur, &delKey, buf, &size);
+ if (code == 0) {
+ memset(buf, 0, size);
+ streamStateSessionPut(pState, &delKey, buf, size);
+ } else {
+ break;
+ }
+ streamStateCurNext(pState, pCur);
+ }
+ streamStateFreeCur(pCur);
+ streamStateSessionDel(pState, &key);
+ return 0;
+}
+
+SStreamStateCur* streamStateSessionGetCur(SStreamState* pState, const SSessionKey* key) {
+ SStreamStateCur* pCur = streamStateSessionGetRanomCur(pState, key);
+ SSessionKey resKey = *key;
+ while (1) {
+ streamStateCurPrev(pState, pCur);
+ SSessionKey tmpKey = *key;
+ int32_t code = streamStateSessionGetKVByCur(pCur, &tmpKey, NULL, 0);
+ if (code == TSDB_CODE_SUCCESS && sessionKeyCmpr(key, &tmpKey) == 0) {
+ resKey = tmpKey;
+ } else {
+ break;
+ }
+ }
+ streamStateFreeCur(pCur);
+ return streamStateSessionGetRanomCur(pState, &resKey);
+}
+
+int32_t streamStateSessionAddIfNotExist(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen) {
+ // todo refactor
+ SStreamStateCur* pCur = streamStateSessionGetCur(pState, key);
+ int32_t size = *pVLen;
+ void* tmp = NULL;
+ *pVal = tdbRealloc(NULL, size);
+ memset(*pVal, 0, size);
+ if (streamStateSessionGetKVByCur(pCur, key, (const void**)&tmp, pVLen) == 0) {
+ memcpy(*pVal, tmp, *pVLen);
+ streamStateFreeCur(pCur);
+ return 0;
+ }
+ streamStateFreeCur(pCur);
+ return 1;
+}
+
+int32_t streamStateStateAddIfNotExist(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
+ state_key_cmpr_fn fn, void** pVal, int32_t* pVLen) {
+ // todo refactor
+ int32_t res = TSDB_CODE_SUCCESS;
+ SSessionKey tmpKey = *key;
+ int32_t valSize = *pVLen;
+ void* tmp = tdbRealloc(NULL, valSize);
+ if (!tmp) {
+ return -1;
+ }
+
+ SStreamStateCur* pCur = streamStateSessionGetRanomCur(pState, key);
+ int32_t code = streamStateSessionGetKVByCur(pCur, key, (const void**)pVal, pVLen);
+ if (code == TSDB_CODE_SUCCESS) {
+ memcpy(tmp, *pVal, valSize);
+ *pVal = tmp;
+ streamStateFreeCur(pCur);
+ return res;
+ }
+ streamStateFreeCur(pCur);
+
+ streamStateSessionPut(pState, key, NULL, 0);
+ pCur = streamStateSessionGetRanomCur(pState, key);
+ streamStateCurPrev(pState, pCur);
+ code = streamStateSessionGetKVByCur(pCur, key, (const void**)pVal, pVLen);
+ if (code == TSDB_CODE_SUCCESS) {
+ void* stateKey = (char*)(*pVal) + (valSize - keyDataLen);
+ if (fn(pKeyData, stateKey) == true) {
+ memcpy(tmp, *pVal, valSize);
+ goto _end;
+ }
+ }
+
+ streamStateFreeCur(pCur);
+ *key = tmpKey;
+ pCur = streamStateSessionSeekKeyNext(pState, key);
+ code = streamStateSessionGetKVByCur(pCur, key, (const void**)pVal, pVLen);
+ if (code == TSDB_CODE_SUCCESS) {
+ void* stateKey = (char*)(*pVal) + (valSize - keyDataLen);
+ if (fn(pKeyData, stateKey) == true) {
+ memcpy(tmp, *pVal, valSize);
+ goto _end;
+ }
+ }
+
+ *key = tmpKey;
+ res = 1;
+ memset(tmp, 0, valSize);
+
+_end:
+
+ *pVal = tmp;
+ streamStateSessionDel(pState, &tmpKey);
+ streamStateFreeCur(pCur);
+ return res;
+}
diff --git a/source/libs/sync/src/syncElection.c b/source/libs/sync/src/syncElection.c
index 375f2e5730..3f13249ce6 100644
--- a/source/libs/sync/src/syncElection.c
+++ b/source/libs/sync/src/syncElection.c
@@ -96,6 +96,19 @@ int32_t syncNodeElect(SSyncNode* pSyncNode) {
syncNodeCandidate2Leader(pSyncNode);
pSyncNode->pVotesGranted->toLeader = true;
return ret;
+ }
+
+ if (pSyncNode->replicaNum == 1) {
+ // only myself, to leader
+ voteGrantedUpdate(pSyncNode->pVotesGranted, pSyncNode);
+ votesRespondUpdate(pSyncNode->pVotesRespond, pSyncNode);
+
+ pSyncNode->quorum = syncUtilQuorum(pSyncNode->pRaftCfg->cfg.replicaNum);
+
+ syncNodeCandidate2Leader(pSyncNode);
+ pSyncNode->pVotesGranted->toLeader = true;
+ return ret;
+
}
switch (pSyncNode->pRaftCfg->snapshotStrategy) {
diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c
index 907eb21f4c..6e4eaa0aaf 100644
--- a/source/libs/sync/src/syncMain.c
+++ b/source/libs/sync/src/syncMain.c
@@ -1891,8 +1891,26 @@ inline bool syncNodeInConfig(SSyncNode* pSyncNode, const SSyncCfg* config) {
return b1;
}
+static bool syncIsConfigChanged(const SSyncCfg* pOldCfg, const SSyncCfg* pNewCfg) {
+ if (pOldCfg->replicaNum != pNewCfg->replicaNum) return true;
+ if (pOldCfg->myIndex != pNewCfg->myIndex) return true;
+ for (int32_t i = 0; i < pOldCfg->replicaNum; ++i) {
+ const SNodeInfo* pOldInfo = &pOldCfg->nodeInfo[i];
+ const SNodeInfo* pNewInfo = &pNewCfg->nodeInfo[i];
+ if (strcmp(pOldInfo->nodeFqdn, pNewInfo->nodeFqdn) != 0) return true;
+ if (pOldInfo->nodePort != pNewInfo->nodePort) return true;
+ }
+
+ return false;
+}
+
void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncIndex lastConfigChangeIndex) {
SSyncCfg oldConfig = pSyncNode->pRaftCfg->cfg;
+ if (!syncIsConfigChanged(&oldConfig, pNewConfig)) {
+ sInfo("vgId:1, sync not reconfig since not changed");
+ return;
+ }
+
pSyncNode->pRaftCfg->cfg = *pNewConfig;
pSyncNode->pRaftCfg->lastConfigIndex = lastConfigChangeIndex;
@@ -2264,7 +2282,7 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) {
void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
- ASSERT(voteGrantedMajority(pSyncNode->pVotesGranted));
+ //ASSERT(voteGrantedMajority(pSyncNode->pVotesGranted));
syncNodeBecomeLeader(pSyncNode, "candidate to leader");
syncNodeLog2("==state change syncNodeCandidate2Leader==", pSyncNode);
@@ -3014,7 +3032,8 @@ static int32_t syncNodeProposeConfigChangeFinish(SSyncNode* ths, SyncReconfigFin
}
bool syncNodeIsOptimizedOneReplica(SSyncNode* ths, SRpcMsg* pMsg) {
- return (ths->replicaNum == 1 && syncUtilUserCommit(pMsg->msgType) && ths->vgId != 1);
+ return (ths->replicaNum == 1 && syncUtilUserCommit(pMsg->msgType));
+ // return (ths->replicaNum == 1 && syncUtilUserCommit(pMsg->msgType) && ths->vgId != 1);
}
int32_t syncNodeCommit(SSyncNode* ths, SyncIndex beginIndex, SyncIndex endIndex, uint64_t flag) {
@@ -3066,7 +3085,8 @@ int32_t syncNodeCommit(SSyncNode* ths, SyncIndex beginIndex, SyncIndex endIndex,
// user commit
if ((ths->pFsm->FpCommitCb != NULL) && syncUtilUserCommit(pEntry->originalRpcType)) {
bool internalExecute = true;
- if ((ths->replicaNum == 1) && ths->restoreFinish && ths->vgId != 1) {
+ if ((ths->replicaNum == 1) && ths->restoreFinish) {
+ // if ((ths->replicaNum == 1) && ths->restoreFinish && ths->vgId != 1) {
internalExecute = false;
}
diff --git a/source/libs/tdb/src/db/tdbBtree.c b/source/libs/tdb/src/db/tdbBtree.c
index 9e17f50dce..8f11fb88a2 100644
--- a/source/libs/tdb/src/db/tdbBtree.c
+++ b/source/libs/tdb/src/db/tdbBtree.c
@@ -1086,6 +1086,7 @@ static int tdbBtreeEncodePayload(SPage *pPage, SCell *pCell, int nHeader, const
// fetch next ofp, a new ofp and make it dirty
ret = tdbFetchOvflPage(&pgno, &nextOfp, pTxn, pBt);
if (ret < 0) {
+ tdbFree(pBuf);
return -1;
}
}
diff --git a/source/libs/tdb/src/db/tdbDb.c b/source/libs/tdb/src/db/tdbDb.c
index 6c01348bc2..a2803d3ecf 100644
--- a/source/libs/tdb/src/db/tdbDb.c
+++ b/source/libs/tdb/src/db/tdbDb.c
@@ -106,7 +106,7 @@ int32_t tdbBegin(TDB *pDb, TXN *pTxn) {
for (pPager = pDb->pgrList; pPager; pPager = pPager->pNext) {
ret = tdbPagerBegin(pPager, pTxn);
if (ret < 0) {
- tdbError("failed to begin pager since %s. dbName:%s, txnId:%d", tstrerror(terrno), pDb->dbName, pTxn->txnId);
+ tdbError("failed to begin pager since %s. dbName:%s, txnId:%ld", tstrerror(terrno), pDb->dbName, pTxn->txnId);
return -1;
}
}
@@ -121,7 +121,7 @@ int32_t tdbCommit(TDB *pDb, TXN *pTxn) {
for (pPager = pDb->pgrList; pPager; pPager = pPager->pNext) {
ret = tdbPagerCommit(pPager, pTxn);
if (ret < 0) {
- tdbError("failed to commit pager since %s. dbName:%s, txnId:%d", tstrerror(terrno), pDb->dbName, pTxn->txnId);
+ tdbError("failed to commit pager since %s. dbName:%s, txnId:%ld", tstrerror(terrno), pDb->dbName, pTxn->txnId);
return -1;
}
}
@@ -136,7 +136,7 @@ int32_t tdbAbort(TDB *pDb, TXN *pTxn) {
for (pPager = pDb->pgrList; pPager; pPager = pPager->pNext) {
ret = tdbPagerAbort(pPager, pTxn);
if (ret < 0) {
- tdbError("failed to abort pager since %s. dbName:%s, txnId:%d", tstrerror(terrno), pDb->dbName, pTxn->txnId);
+ tdbError("failed to abort pager since %s. dbName:%s, txnId:%ld", tstrerror(terrno), pDb->dbName, pTxn->txnId);
return -1;
}
}
diff --git a/source/libs/tdb/src/db/tdbPCache.c b/source/libs/tdb/src/db/tdbPCache.c
index c73ddce74c..732a57639f 100644
--- a/source/libs/tdb/src/db/tdbPCache.c
+++ b/source/libs/tdb/src/db/tdbPCache.c
@@ -268,7 +268,7 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
// 4. Try a create new page
if (!pPage) {
ret = tdbPageCreate(pCache->szPage, &pPage, pTxn->xMalloc, pTxn->xArg);
- if (ret < 0 && pPage != NULL) {
+ if (ret < 0 || pPage == NULL) {
// TODO
ASSERT(0);
return NULL;
diff --git a/source/libs/tdb/src/db/tdbPager.c b/source/libs/tdb/src/db/tdbPager.c
index 57ad2a783a..90332617cd 100644
--- a/source/libs/tdb/src/db/tdbPager.c
+++ b/source/libs/tdb/src/db/tdbPager.c
@@ -541,7 +541,7 @@ static int tdbPagerWritePageToJournal(SPager *pPager, SPage *pPage) {
ret = tdbOsWrite(pPager->jfd, pPage->pData, pPage->pageSize);
if (ret < 0) {
- tdbError("failed to write page data due to %s. file:%s, pageSize:%ld", strerror(errno), pPager->jFileName,
+ tdbError("failed to write page data due to %s. file:%s, pageSize:%d", strerror(errno), pPager->jFileName,
pPage->pageSize);
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
@@ -570,7 +570,7 @@ static int tdbPagerWritePageToDB(SPager *pPager, SPage *pPage) {
ret = tdbOsWrite(pPager->fd, pPage->pData, pPage->pageSize);
if (ret < 0) {
- tdbError("failed to write page data due to %s. file:%s, pageSize:%ld", strerror(errno), pPager->dbFileName,
+ tdbError("failed to write page data due to %s. file:%s, pageSize:%d", strerror(errno), pPager->dbFileName,
pPage->pageSize);
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c
index 279f4dc656..fa22805df2 100644
--- a/source/libs/wal/src/walMeta.c
+++ b/source/libs/wal/src/walMeta.c
@@ -123,8 +123,8 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) {
}
SWalCkHead* logContent = (SWalCkHead*)candidate;
if (walValidHeadCksum(logContent) != 0) {
- wError("vgId:%d, failed to validate checksum of wal entry header. offset:% %" PRId64 ", file:%s",
- ((char*)(logContent)-buf), fnameStr);
+ wWarn("vgId:%d, failed to validate checksum of wal entry header. offset:%" PRId64 ", file:%s", pWal->cfg.vgId,
+ offset + ((char*)(logContent)-buf), fnameStr);
haystack = candidate + 1;
if (firstTrial) {
break;
@@ -162,8 +162,8 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) {
}
if (walValidBodyCksum(logContent) != 0) {
terrno = TSDB_CODE_WAL_CHKSUM_MISMATCH;
- wError("vgId:%d, failed to validate checksum of wal entry body. offset:% %" PRId64 ", file:%s",
- ((char*)(logContent)-buf), fnameStr);
+ wWarn("vgId:%d, failed to validate checksum of wal entry body. offset:%" PRId64 ", file:%s", pWal->cfg.vgId,
+ offset + ((char*)(logContent)-buf), fnameStr);
haystack = candidate + 1;
if (firstTrial) {
break;
@@ -481,6 +481,10 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
continue;
}
+ if (offset != (idxEntry.ver - pFileInfo->firstVer) * sizeof(SWalIdxEntry)) {
+ continue;
+ }
+
if (walReadLogHead(pLogFile, idxEntry.offset, &ckHead) < 0) {
wWarn("vgId:%d, failed to read log file since %s. file:%s, offset:%" PRId64 ", idx entry ver:%" PRId64 "",
pWal->cfg.vgId, terrstr(), fLogNameStr, idxEntry.offset, idxEntry.ver);
@@ -493,6 +497,8 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
}
offset += sizeof(SWalIdxEntry);
+ ASSERT(offset == (idxEntry.ver - pFileInfo->firstVer + 1) * sizeof(SWalIdxEntry));
+
// ftruncate idx file
if (offset < fileSize) {
if (taosFtruncateFile(pIdxFile, offset) < 0) {
diff --git a/source/libs/wal/src/walWrite.c b/source/libs/wal/src/walWrite.c
index 91fa49fce0..0562bbad27 100644
--- a/source/libs/wal/src/walWrite.c
+++ b/source/libs/wal/src/walWrite.c
@@ -410,25 +410,35 @@ END:
static int32_t walWriteIndex(SWal *pWal, int64_t ver, int64_t offset) {
SWalIdxEntry entry = {.ver = ver, .offset = offset};
- int64_t idxOffset = taosLSeekFile(pWal->pIdxFile, 0, SEEK_END);
+ SWalFileInfo *pFileInfo = walGetCurFileInfo(pWal);
+ ASSERT(pFileInfo != NULL);
+ ASSERT(pFileInfo->firstVer >= 0);
+ int64_t idxOffset = (entry.ver - pFileInfo->firstVer) * sizeof(SWalIdxEntry);
wDebug("vgId:%d, write index, index:%" PRId64 ", offset:%" PRId64 ", at %" PRId64, pWal->cfg.vgId, ver, offset,
idxOffset);
+
int64_t size = taosWriteFile(pWal->pIdxFile, &entry, sizeof(SWalIdxEntry));
if (size != sizeof(SWalIdxEntry)) {
+ wError("vgId:%d, failed to write idx entry due to %s. ver:%lld", pWal->cfg.vgId, strerror(errno), ver);
terrno = TAOS_SYSTEM_ERROR(errno);
- // TODO truncate
return -1;
}
+
+ ASSERT(taosLSeekFile(pWal->pIdxFile, 0, SEEK_END) == idxOffset + sizeof(SWalIdxEntry) && "Offset of idx entries misaligned");
return 0;
}
-// TODO gurantee atomicity by truncate failed writing
static FORCE_INLINE int32_t walWriteImpl(SWal *pWal, int64_t index, tmsg_t msgType, SWalSyncInfo syncMeta,
const void *body, int32_t bodyLen) {
int64_t code = 0;
int64_t offset = walGetCurFileOffset(pWal);
+ SWalFileInfo *pFileInfo = walGetCurFileInfo(pWal);
+ ASSERT(pFileInfo != NULL);
+ if (pFileInfo->firstVer == -1) {
+ pFileInfo->firstVer = index;
+ }
pWal->writeHead.head.version = index;
pWal->writeHead.head.bodyLen = bodyLen;
pWal->writeHead.head.msgType = msgType;
@@ -439,11 +449,14 @@ static FORCE_INLINE int32_t walWriteImpl(SWal *pWal, int64_t index, tmsg_t msgTy
pWal->writeHead.cksumHead = walCalcHeadCksum(&pWal->writeHead);
pWal->writeHead.cksumBody = walCalcBodyCksum(body, bodyLen);
-
wDebug("vgId:%d, wal write log %ld, msgType: %s", pWal->cfg.vgId, index, TMSG_INFO(msgType));
+ code = walWriteIndex(pWal, index, offset);
+ if (code < 0) {
+ goto END;
+ }
+
if (taosWriteFile(pWal->pLogFile, &pWal->writeHead, sizeof(SWalCkHead)) != sizeof(SWalCkHead)) {
- // TODO ftruncate
terrno = TAOS_SYSTEM_ERROR(errno);
wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal),
strerror(errno));
@@ -452,7 +465,6 @@ static FORCE_INLINE int32_t walWriteImpl(SWal *pWal, int64_t index, tmsg_t msgTy
}
if (taosWriteFile(pWal->pLogFile, (char *)body, bodyLen) != bodyLen) {
- // TODO ftruncate
terrno = TAOS_SYSTEM_ERROR(errno);
wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal),
strerror(errno));
@@ -460,24 +472,31 @@ static FORCE_INLINE int32_t walWriteImpl(SWal *pWal, int64_t index, tmsg_t msgTy
goto END;
}
- code = walWriteIndex(pWal, index, offset);
- if (code < 0) {
- // TODO ftruncate
- goto END;
- }
-
// set status
if (pWal->vers.firstVer == -1) pWal->vers.firstVer = index;
pWal->vers.lastVer = index;
pWal->totSize += sizeof(SWalCkHead) + bodyLen;
- if (walGetCurFileInfo(pWal)->firstVer == -1) {
- walGetCurFileInfo(pWal)->firstVer = index;
- }
- walGetCurFileInfo(pWal)->lastVer = index;
- walGetCurFileInfo(pWal)->fileSize += sizeof(SWalCkHead) + bodyLen;
+ pFileInfo->lastVer = index;
+ pFileInfo->fileSize += sizeof(SWalCkHead) + bodyLen;
return 0;
+
END:
+ // recover in a reverse order
+ if (taosFtruncateFile(pWal->pLogFile, offset) < 0) {
+ wFatal("vgId:%d, failed to ftruncate logfile to offset:%lld during recovery due to %s", pWal->cfg.vgId, offset,
+ strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ ASSERT(0 && "failed to recover from error");
+ }
+
+ int64_t idxOffset = (index - pFileInfo->firstVer) * sizeof(SWalIdxEntry);
+ if (taosFtruncateFile(pWal->pIdxFile, idxOffset) < 0) {
+ wFatal("vgId:%d, failed to ftruncate idxfile to offset:%lld during recovery due to %s", pWal->cfg.vgId, idxOffset,
+ strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ ASSERT(0 && "failed to recover from error");
+ }
return -1;
}
diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c
index 2e2300ba14..9d97cf7ab2 100644
--- a/source/util/src/tlog.c
+++ b/source/util/src/tlog.c
@@ -443,10 +443,13 @@ static inline int32_t taosBuildLogHead(char *buffer, const char *flags) {
static inline void taosPrintLogImp(ELogLevel level, int32_t dflag, const char *buffer, int32_t len) {
if ((dflag & DEBUG_FILE) && tsLogObj.logHandle && tsLogObj.logHandle->pFile != NULL && osLogSpaceAvailable()) {
taosUpdateLogNums(level);
- if (tsAsyncLog) {
+ if (tsAsyncLog && level != DEBUG_FATAL) {
taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
} else {
taosWriteFile(tsLogObj.logHandle->pFile, buffer, len);
+ if (level == DEBUG_FATAL) {
+ taosFsyncFile(tsLogObj.logHandle->pFile);
+ }
}
if (tsLogObj.maxLines > 0) {
diff --git a/tests/parallel_test/run_case.sh b/tests/parallel_test/run_case.sh
index 58dcb87345..e0b905375a 100755
--- a/tests/parallel_test/run_case.sh
+++ b/tests/parallel_test/run_case.sh
@@ -67,9 +67,13 @@ mkdir -p /var/lib/taos
cd $CONTAINER_TESTDIR/tests/$exec_dir
ulimit -c unlimited
+md5sum /usr/lib/libtaos.so.1
+md5sum /home/TDinternal/debug/build/lib/libtaos.so
$TIMEOUT_CMD $cmd
RET=$?
echo "cmd exit code: $RET"
+md5sum /usr/lib/libtaos.so.1
+md5sum /home/TDinternal/debug/build/lib/libtaos.so
if [ $RET -ne 0 ]; then
pwd
diff --git a/tests/parallel_test/run_container.sh b/tests/parallel_test/run_container.sh
index bb57f238f0..f58aaaf29d 100755
--- a/tests/parallel_test/run_container.sh
+++ b/tests/parallel_test/run_container.sh
@@ -68,12 +68,16 @@ if [ $ent -ne 0 ]; then
CONTAINER_TESTDIR=/home/TDinternal/community
SIM_DIR=/home/TDinternal/sim
REP_MOUNT_PARAM="$INTERNAL_REPDIR:/home/TDinternal"
+ REP_MOUNT_LIB="$INTERNAL_REPDIR/debug/build/lib:/home/TDinternal/debug/build/lib:ro"
+
else
# community edition
REPDIR=$WORKDIR/TDengine
CONTAINER_TESTDIR=/home/TDengine
SIM_DIR=/home/TDengine/sim
REP_MOUNT_PARAM="$REPDIR:/home/TDengine"
+ REP_MOUNT_LIB="$REPDIR/debug/build/lib:/home/TDengine/debug/build/lib:ro"
+
fi
ulimit -c unlimited
@@ -103,6 +107,7 @@ coredump_dir=`cat /proc/sys/kernel/core_pattern | xargs dirname`
docker run \
-v $REP_MOUNT_PARAM \
+ -v $REP_MOUNT_LIB \
-v $MOUNT_DIR \
-v ${SOURCEDIR}:/usr/local/src/ \
-v "$TMP_DIR/thread_volume/$thread_no/sim:${SIM_DIR}" \
diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt
index d8f4a36261..47611a7712 100644
--- a/tests/script/jenkins/basic.txt
+++ b/tests/script/jenkins/basic.txt
@@ -249,12 +249,18 @@
./test.sh -f tsim/stream/windowClose.sim
./test.sh -f tsim/stream/ignoreExpiredData.sim
./test.sh -f tsim/stream/sliding.sim
-#./test.sh -f tsim/stream/partitionbyColumnInterval.sim
+./test.sh -f tsim/stream/partitionbyColumnInterval.sim
#./test.sh -f tsim/stream/partitionbyColumnSession.sim
#./test.sh -f tsim/stream/partitionbyColumnState.sim
#./test.sh -f tsim/stream/deleteInterval.sim
#./test.sh -f tsim/stream/deleteSession.sim
#./test.sh -f tsim/stream/deleteState.sim
+#./test.sh -f tsim/stream/fillIntervalDelete0.sim
+#./test.sh -f tsim/stream/fillIntervalDelete1.sim
+./test.sh -f tsim/stream/fillIntervalLinear.sim
+#./test.sh -f tsim/stream/fillIntervalPartitionBy.sim
+./test.sh -f tsim/stream/fillIntervalPrevNext.sim
+./test.sh -f tsim/stream/fillIntervalValue.sim
# ---- transaction ----
./test.sh -f tsim/trans/lossdata1.sim
diff --git a/tests/script/tsim/parser/like.sim b/tests/script/tsim/parser/like.sim
index 40dcec4080..5cac026b57 100644
--- a/tests/script/tsim/parser/like.sim
+++ b/tests/script/tsim/parser/like.sim
@@ -17,9 +17,9 @@ sql create table $table1 (ts timestamp, b binary(20))
sql create table $table2 (ts timestamp, b binary(20))
sql insert into $table1 values(now, "table_name")
-sql insert into $table1 values(now-1m, "tablexname")
+sql insert into $table1 values(now-3m, "tablexname")
sql insert into $table1 values(now-2m, "tablexxx")
-sql insert into $table1 values(now-2m, "table")
+sql insert into $table1 values(now-1m, "table")
sql select b from $table1
if $rows != 4 then
diff --git a/tests/script/tsim/stream/session0.sim b/tests/script/tsim/stream/session0.sim
index 3e0af354d8..afae8ef5da 100644
--- a/tests/script/tsim/stream/session0.sim
+++ b/tests/script/tsim/stream/session0.sim
@@ -216,12 +216,12 @@ if $data02 != 3.274823935 then
goto loop2
endi
-if $data03 != 1.800000000 then
+if $data03 != 1.500000000 then
print ======$data03
return -1
endi
-if $data04 != 3.350000000 then
+if $data04 != 3.500000000 then
print ======$data04
return -1
endi
diff --git a/tests/script/tsim/stream/session1.sim b/tests/script/tsim/stream/session1.sim
index ab173c5929..ee6eefde26 100644
--- a/tests/script/tsim/stream/session1.sim
+++ b/tests/script/tsim/stream/session1.sim
@@ -5,15 +5,15 @@ sleep 50
sql connect
print =============== create database
-sql create database test vgroups 1
-sql select * from information_schema.ins_databases
+sql create database test vgroups 1;
+sql select * from information_schema.ins_databases;
if $rows != 3 then
return -1
endi
print $data00 $data01 $data02
-sql use test
+sql use test;
sql create table t1(ts timestamp, a int, b int , c int, d double,id int);
diff --git a/tests/script/tsim/stream/state0.sim b/tests/script/tsim/stream/state0.sim
index 877a2877b9..60a50f9560 100644
--- a/tests/script/tsim/stream/state0.sim
+++ b/tests/script/tsim/stream/state0.sim
@@ -349,7 +349,7 @@ endi
if $rows != 3 then
print ====loop4=rows=$rows
-# goto loop4
+ goto loop4
endi
# row 0
diff --git a/tests/script/tsim/stream/triggerSession0.sim b/tests/script/tsim/stream/triggerSession0.sim
index 2ea689ef78..1bef439884 100644
--- a/tests/script/tsim/stream/triggerSession0.sim
+++ b/tests/script/tsim/stream/triggerSession0.sim
@@ -13,7 +13,7 @@ endi
print $data00 $data01 $data02
-sql use test
+sql use test;
sql create table t2(ts timestamp, a int, b int , c int, d double);
sql create stream streams2 trigger window_close into streamt2 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t2 session(ts, 10s);
@@ -58,16 +58,11 @@ endi
sql insert into t2 values(1648791233002,1,2,3,1.0);
sleep 300
sql select * from streamt2;
-if $rows != 1 then
+if $rows != 0 then
print ======$rows
return -1
endi
-if $data01 != 6 then
- print ======$data01
- return -1
-endi
-
sql insert into t2 values(1648791253003,1,2,3,1.0);
sleep 300
sql select * from streamt2;
diff --git a/tools/shell/src/shellCommand.c b/tools/shell/src/shellCommand.c
index 0b26d685fd..c34b22b691 100644
--- a/tools/shell/src/shellCommand.c
+++ b/tools/shell/src/shellCommand.c
@@ -101,11 +101,8 @@ void shellInsertChar(SShellCmd *cmd, char *c, int32_t size) {
/* update the values */
cmd->commandSize += size;
cmd->cursorOffset += size;
- for (int i = 0; i < size; i++) {
- taosMbToWchar(&wc, c + i, size);
- cmd->screenOffset += taosWcharWidth(wc);
- cmd->endOffset += taosWcharWidth(wc);
- }
+ cmd->screenOffset += taosWcharWidth(wc);
+ cmd->endOffset += taosWcharWidth(wc);
#ifdef WINDOWS
#else
shellShowOnScreen(cmd);
diff --git a/utils/test/c/sml_test.c b/utils/test/c/sml_test.c
index b6d8d75ba0..ab520e6638 100644
--- a/utils/test/c/sml_test.c
+++ b/utils/test/c/sml_test.c
@@ -63,6 +63,7 @@ int smlProcess_influx_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
return code;
}
@@ -86,6 +87,8 @@ int smlProcess_telnet_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -99,32 +102,15 @@ int smlProcess_json1_Test() {
taos_free_result(pRes);
const char *sql[] = {
- "["
- " {"
- " \"metric\": \"sys.cpu.nice\","
- " \"timestamp\": 0,"
- " \"value\": 18,"
- " \"tags\": {"
- " \"host\": \"web01\","
- " \"id\": \"t1\","
- " \"dc\": \"lga\""
- " }"
- " },"
- " {"
- " \"metric\": \"sys.cpu.nice\","
- " \"timestamp\": 1662344042,"
- " \"value\": 9,"
- " \"tags\": {"
- " \"host\": \"web02\","
- " \"dc\": \"lga\""
- " }"
- " }"
- "]",};
+ "[{\"metric\":\"sys.cpu.nice\",\"timestamp\":0,\"value\":18,\"tags\":{\"host\":\"web01\",\"id\":\"t1\",\"dc\":\"lga\"}},{\"metric\":\"sys.cpu.nice\",\"timestamp\":1662344042,\"value\":9,\"tags\":{\"host\":\"web02\",\"dc\":\"lga\"}}]"
+ };
pRes = taos_schemaless_insert(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_JSON_PROTOCOL,
TSDB_SML_TIMESTAMP_NANO_SECONDS);
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -138,33 +124,15 @@ int smlProcess_json2_Test() {
taos_free_result(pRes);
const char *sql[] = {
- "{"
- " \"metric\": \"meter_current0\","
- " \"timestamp\": {"
- " \"value\" : 1662344042,"
- " \"type\" : \"s\""
- " },"
- " \"value\": {"
- " \"value\" : 10.3,"
- " \"type\" : \"i64\""
- " },"
- " \"tags\": {"
- " \"groupid\": { "
- " \"value\" : 2,"
- " \"type\" : \"bigint\""
- " },"
- " \"location\": { "
- " \"value\" : \"北京\","
- " \"type\" : \"binary\""
- " },"
- " \"id\": \"d1001\""
- " }"
- "}",};
+ "{\"metric\":\"meter_current0\",\"timestamp\":{\"value\":1662344042,\"type\":\"s\"},\"value\":{\"value\":10.3,\"type\":\"i64\"},\"tags\":{\"groupid\":{\"value\":2,\"type\":\"bigint\"},\"location\":{\"value\":\"北京\",\"type\":\"binary\"},\"id\":\"d1001\"}}"
+ };
pRes = taos_schemaless_insert(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_JSON_PROTOCOL,
TSDB_SML_TIMESTAMP_NANO_SECONDS);
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -178,61 +146,14 @@ int smlProcess_json3_Test() {
taos_free_result(pRes);
const char *sql[] = {
- "{"
- " \"metric\": \"meter_current1\","
- " \"timestamp\": {"
- " \"value\" : 1662344042,"
- " \"type\" : \"s\""
- " },"
- " \"value\": {"
- " \"value\" : 10.3,"
- " \"type\" : \"i64\""
- " },"
- " \"tags\": {"
- " \"t1\": { "
- " \"value\" : 2,"
- " \"type\" : \"bigint\""
- " },"
- " \"t2\": { "
- " \"value\" : 2,"
- " \"type\" : \"int\""
- " },"
- " \"t3\": { "
- " \"value\" : 2,"
- " \"type\" : \"i16\""
- " },"
- " \"t4\": { "
- " \"value\" : 2,"
- " \"type\" : \"i8\""
- " },"
- " \"t5\": { "
- " \"value\" : 2,"
- " \"type\" : \"f32\""
- " },"
- " \"t6\": { "
- " \"value\" : 2,"
- " \"type\" : \"double\""
- " },"
- " \"t7\": { "
- " \"value\" : \"8323\","
- " \"type\" : \"binary\""
- " },"
- " \"t8\": { "
- " \"value\" : \"北京\","
- " \"type\" : \"nchar\""
- " },"
- " \"t9\": { "
- " \"value\" : true,"
- " \"type\" : \"bool\""
- " },"
- " \"id\": \"d1001\""
- " }"
- "}",};
+ "{\"metric\":\"meter_current1\",\"timestamp\":{\"value\":1662344042,\"type\":\"s\"},\"value\":{\"value\":10.3,\"type\":\"i64\"},\"tags\":{\"t1\":{\"value\":2,\"type\":\"bigint\"},\"t2\":{\"value\":2,\"type\":\"int\"},\"t3\":{\"value\":2,\"type\":\"i16\"},\"t4\":{\"value\":2,\"type\":\"i8\"},\"t5\":{\"value\":2,\"type\":\"f32\"},\"t6\":{\"value\":2,\"type\":\"double\"},\"t7\":{\"value\":\"8323\",\"type\":\"binary\"},\"t8\":{\"value\":\"北京\",\"type\":\"nchar\"},\"t9\":{\"value\":true,\"type\":\"bool\"},\"id\":\"d1001\"}}"};
pRes = taos_schemaless_insert(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_JSON_PROTOCOL,
TSDB_SML_TIMESTAMP_NANO_SECONDS);
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -246,52 +167,15 @@ int smlProcess_json4_Test() {
taos_free_result(pRes);
const char *sql[] = {
- "{"
- " \"metric\": \"meter_current2\","
- " \"timestamp\": {"
- " \"value\" : 1662344042000,"
- " \"type\" : \"ms\""
- " },"
- " \"value\": \"ni\","
- " \"tags\": {"
- " \"t1\": { "
- " \"value\" : 20,"
- " \"type\" : \"i64\""
- " },"
- " \"t2\": { "
- " \"value\" : 25,"
- " \"type\" : \"i32\""
- " },"
- " \"t3\": { "
- " \"value\" : 2,"
- " \"type\" : \"smallint\""
- " },"
- " \"t4\": { "
- " \"value\" : 2,"
- " \"type\" : \"tinyint\""
- " },"
- " \"t5\": { "
- " \"value\" : 2,"
- " \"type\" : \"float\""
- " },"
- " \"t6\": { "
- " \"value\" : 0.2,"
- " \"type\" : \"f64\""
- " },"
- " \"t7\": \"nsj\","
- " \"t8\": { "
- " \"value\" : \"北京\","
- " \"type\" : \"nchar\""
- " },"
- " \"t9\": false,"
- " \"id\": \"d1001\""
- " }"
- "}",};
+ "{\"metric\":\"meter_current2\",\"timestamp\":{\"value\":1662344042000,\"type\":\"ms\"},\"value\":\"ni\",\"tags\":{\"t1\":{\"value\":20,\"type\":\"i64\"},\"t2\":{\"value\":25,\"type\":\"i32\"},\"t3\":{\"value\":2,\"type\":\"smallint\"},\"t4\":{\"value\":2,\"type\":\"tinyint\"},\"t5\":{\"value\":2,\"type\":\"float\"},\"t6\":{\"value\":0.2,\"type\":\"f64\"},\"t7\":\"nsj\",\"t8\":{\"value\":\"北京\",\"type\":\"nchar\"},\"t9\":false,\"id\":\"d1001\"}}"
+ };
pRes = taos_schemaless_insert(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_JSON_PROTOCOL,
TSDB_SML_TIMESTAMP_NANO_SECONDS);
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -313,6 +197,8 @@ int sml_TD15662_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -333,6 +219,8 @@ int sml_TD15742_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -362,6 +250,8 @@ int sml_16384_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -781,6 +671,8 @@ int sml_oom_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -825,6 +717,8 @@ int sml_16368_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -862,6 +756,8 @@ int sml_dup_time_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -1068,6 +964,8 @@ int sml_16960_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
int code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
+
return code;
}
@@ -1097,6 +995,7 @@ int sml_add_tag_col_Test() {
printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
code = taos_errno(pRes);
taos_free_result(pRes);
+ taos_close(taos);
return code;
}
@@ -1151,6 +1050,36 @@ int smlProcess_18784_Test() {
rowIndex++;
}
taos_free_result(pRes);
+ taos_close(taos);
+
+ return code;
+}
+
+int sml_19221_Test() {
+ TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
+
+ TAOS_RES *pRes = taos_query(taos, "create database if not exists sml_db schemaless 1");
+ taos_free_result(pRes);
+
+ const char *sql[] = {
+ "qelhxo,id=pnnqhsa,t0=t,t1=127i8 c11=L\"ncharColValue\",c0=t,c1=127i8 1626006833639000000\nqelhxo,id=pnnhsa,t0=t,t1=127i8 c11=L\"ncharColValue\",c0=t,c1=127i8 1626006833639000000\n#comment\nqelhxo,id=pnqhsa,t0=t,t1=127i8 c11=L\"ncharColValue\",c0=t,c1=127i8 1626006833639000000",
+ };
+
+ pRes = taos_query(taos, "use sml_db");
+ taos_free_result(pRes);
+
+ char* tmp = (char*)taosMemoryCalloc(1024, 1);
+ memcpy(tmp, sql[0], strlen(sql[0]));
+ *(char*)(tmp+44) = 0;
+ int32_t totalRows = 0;
+ pRes = taos_schemaless_insert_raw(taos, tmp, strlen(sql[0]), &totalRows, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS);
+
+ ASSERT(totalRows == 3);
+ printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
+ int code = taos_errno(pRes);
+ taos_free_result(pRes);
+ taos_close(taos);
+ taosMemoryFree(tmp);
return code;
}
@@ -1187,5 +1116,7 @@ int main(int argc, char *argv[]) {
ASSERT(!ret);
ret = smlProcess_18784_Test();
ASSERT(!ret);
+ ret = sml_19221_Test();
+ ASSERT(!ret);
return ret;
}
diff --git a/utils/test/c/tmqDemo.c b/utils/test/c/tmqDemo.c
index 784b45c92b..d105b50579 100644
--- a/utils/test/c/tmqDemo.c
+++ b/utils/test/c/tmqDemo.c
@@ -130,15 +130,15 @@ void parseArgument(int32_t argc, char* argv[]) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-d") == 0) {
- strcpy(g_stConfInfo.dbName, argv[++i]);
+ tstrncpy(g_stConfInfo.dbName, argv[++i], sizeof(g_stConfInfo.dbName));
} else if (strcmp(argv[i], "-c") == 0) {
- strcpy(configDir, argv[++i]);
+ tstrncpy(configDir, argv[++i], PATH_MAX);
} else if (strcmp(argv[i], "-s") == 0) {
- strcpy(g_stConfInfo.stbName, argv[++i]);
+ tstrncpy(g_stConfInfo.stbName, argv[++i], sizeof(g_stConfInfo.stbName));
} else if (strcmp(argv[i], "-w") == 0) {
- strcpy(g_stConfInfo.vnodeWalPath, argv[++i]);
+ tstrncpy(g_stConfInfo.vnodeWalPath, argv[++i], sizeof(g_stConfInfo.vnodeWalPath));
} else if (strcmp(argv[i], "-f") == 0) {
- strcpy(g_stConfInfo.resultFileName, argv[++i]);
+ tstrncpy(g_stConfInfo.resultFileName, argv[++i], sizeof(g_stConfInfo.resultFileName));
} else if (strcmp(argv[i], "-t") == 0) {
g_stConfInfo.numOfThreads = atoi(argv[++i]);
} else if (strcmp(argv[i], "-n") == 0) {
diff --git a/utils/test/c/tmqSim.c b/utils/test/c/tmqSim.c
index d36fe0855a..25e83363ee 100644
--- a/utils/test/c/tmqSim.c
+++ b/utils/test/c/tmqSim.c
@@ -949,7 +949,7 @@ void parseConsumeInfo() {
token = strtok(g_stConfInfo.stThreads[i].topicString, delim);
while (token != NULL) {
// printf("%s\n", token );
- strcpy(g_stConfInfo.stThreads[i].topics[g_stConfInfo.stThreads[i].numOfTopic], token);
+ tstrncpy(g_stConfInfo.stThreads[i].topics[g_stConfInfo.stThreads[i].numOfTopic], token, sizeof(g_stConfInfo.stThreads[i].topics[g_stConfInfo.stThreads[i].numOfTopic]));
ltrim(g_stConfInfo.stThreads[i].topics[g_stConfInfo.stThreads[i].numOfTopic]);
// printf("%s\n", g_stConfInfo.topics[g_stConfInfo.numOfTopic]);
g_stConfInfo.stThreads[i].numOfTopic++;
diff --git a/utils/tsim/src/simExe.c b/utils/tsim/src/simExe.c
index 4fe5fdf672..6f693cf015 100644
--- a/utils/tsim/src/simExe.c
+++ b/utils/tsim/src/simExe.c
@@ -37,6 +37,7 @@ void simLogSql(char *sql, bool useSharp) {
taosFsyncFile(pFile);
}
+#if 0
char *simParseArbitratorName(char *varName) {
static char hostName[140];
#ifdef WINDOWS
@@ -47,6 +48,7 @@ char *simParseArbitratorName(char *varName) {
#endif
return hostName;
}
+#endif
char *simParseHostName(char *varName) {
static char hostName[140];
@@ -102,9 +104,11 @@ char *simGetVariable(SScript *script, char *varName, int32_t varLen) {
return simParseHostName(varName);
}
+#if 0
if (strncmp(varName, "arbitrator", 10) == 0) {
return simParseArbitratorName(varName);
}
+#endif
if (strncmp(varName, "error", varLen) == 0) return script->error;
@@ -883,6 +887,7 @@ bool simExecuteSqlSlowCmd(SScript *script, char *rest) {
return simExecuteSqlImpCmd(script, rest, isSlow);
}
+#if 0
bool simExecuteRestfulCmd(SScript *script, char *rest) {
TdFilePtr pFile = NULL;
char filename[256];
@@ -924,6 +929,7 @@ bool simExecuteRestfulCmd(SScript *script, char *rest) {
return simExecuteSystemCmd(script, cmd);
}
+#endif
bool simExecuteSqlErrorCmd(SScript *script, char *rest) {
char buf[3000];
@@ -981,6 +987,7 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) {
return false;
}
+#if 0
bool simExecuteLineInsertCmd(SScript *script, char *rest) {
char buf[TSDB_MAX_BINARY_LEN] = {0};
@@ -1037,3 +1044,4 @@ bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) {
return true;
}
}
+#endif
\ No newline at end of file
diff --git a/utils/tsim/src/simParse.c b/utils/tsim/src/simParse.c
index 14be10bc8a..ae523edfc4 100644
--- a/utils/tsim/src/simParse.c
+++ b/utils/tsim/src/simParse.c
@@ -501,6 +501,7 @@ bool simParseEndwCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
return true;
}
+#if 0
bool simParseSwitchCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
char *token;
int32_t tokenLen;
@@ -647,6 +648,7 @@ bool simParseContinueCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
numOfLines++;
return true;
}
+#endif
bool simParsePrintCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
@@ -715,6 +717,7 @@ bool simParseSqlErrorCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
return true;
}
+#if 0
bool simParseSqlSlowCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
simParseSqlCmd(rest, pCmd, lineNum);
cmdLine[numOfLines - 1].cmdno = SIM_CMD_SQL_SLOW;
@@ -726,6 +729,7 @@ bool simParseRestfulCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
cmdLine[numOfLines - 1].cmdno = SIM_CMD_RESTFUL;
return true;
}
+#endif
bool simParseSystemCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
@@ -838,6 +842,7 @@ bool simParseRunBackCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
return true;
}
+#if 0
bool simParseLineInsertCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
int32_t expLen;
@@ -869,6 +874,7 @@ bool simParseLineInsertErrorCmd(char *rest, SCommand *pCmd, int32_t lineNum) {
numOfLines++;
return true;
}
+#endif
void simInitsimCmdList() {
int32_t cmdno;
@@ -930,6 +936,7 @@ void simInitsimCmdList() {
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
+#if 0
cmdno = SIM_CMD_SWITCH;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "switch");
@@ -977,6 +984,7 @@ void simInitsimCmdList() {
simCmdList[cmdno].parseCmd = simParseEndsCmd;
simCmdList[cmdno].executeCmd = NULL;
simAddCmdIntoHash(&(simCmdList[cmdno]));
+#endif
cmdno = SIM_CMD_SLEEP;
simCmdList[cmdno].cmdno = cmdno;
@@ -1050,6 +1058,7 @@ void simInitsimCmdList() {
simCmdList[cmdno].executeCmd = simExecuteSqlErrorCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
+#if 0
cmdno = SIM_CMD_SQL_SLOW;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "sql_slow");
@@ -1065,6 +1074,7 @@ void simInitsimCmdList() {
simCmdList[cmdno].parseCmd = simParseRestfulCmd;
simCmdList[cmdno].executeCmd = simExecuteRestfulCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
+#endif
/* test is only an internal command */
cmdno = SIM_CMD_TEST;
@@ -1082,6 +1092,7 @@ void simInitsimCmdList() {
simCmdList[cmdno].executeCmd = simExecuteReturnCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
+#if 0
cmdno = SIM_CMD_LINE_INSERT;
simCmdList[cmdno].cmdno = cmdno;
strcpy(simCmdList[cmdno].name, "line_insert");
@@ -1097,4 +1108,5 @@ void simInitsimCmdList() {
simCmdList[cmdno].parseCmd = simParseLineInsertErrorCmd;
simCmdList[cmdno].executeCmd = simExecuteLineInsertErrorCmd;
simAddCmdIntoHash(&(simCmdList[cmdno]));
+#endif
}